gpt4 book ai didi

javascript - d3.js水平条形图问题

转载 作者:行者123 更新时间:2023-12-01 08:30:15 27 4
gpt4 key购买 nike

我是 d3 库的新手,正在尝试使用 d3 库的一些图表。我可以使用 d3.js 库制作水平条形图,但我遇到了一些问题。

目前我遇到了麻烦,因为 x 轴上的最后一个值被裁剪。我不想在图表中添加右边距。我想在 x 轴上显示最后一个带有勾号的标签。

我在下面的屏幕截图中突出显示了裁剪后的值:

Bar chart Screenshot

要进行调试,请引用以下代码:

const margin = {
top: 30,
right: 0,
bottom: 10,
left: 100
};
const width= 1180;
const data = [{
name: 'A',
value: 2
},
{
name: 'B',
value: 20
},
{
name: 'C',
value: 15
},
{
name: 'D',
value: 8
},
{
name: 'E',
value: 1
}
];
const barHeight = 20;
const yMax = d3.max(data, d => d.value);

const height =
Math.ceil((data.length + 0.1) * barHeight) + margin.top + margin.bottom;
const x = d3
.scaleLinear()
.domain([0, yMax < 10 ? 10 : yMax])
.range([margin.left, width - margin.right])
.nice();
const y = d3
.scaleBand()
.domain(d3.range(data.length))
.range([margin.top, height - margin.bottom])
.padding(0.1);

const format = x.tickFormat(10, data.format);
const svg = d3.select('body').append('svg').attr('viewBox', [0, 0, width, height]);
const xAxis = g =>
g
.attr('class', 'chartxAxisText')
.attr('transform', `translate(0,${margin.top})`)
.call(d3.axisTop(x))

.call(g => g.select('.domain').remove());
const yAxis = g =>
g
.attr('class', 'chartyAxisText')
.attr('transform', `translate(${margin.left},0)`)
.call(
d3
.axisLeft(y)
.tickFormat(i => data[i].name)
.tickSizeOuter(0)
);

svg
.append('g')
.selectAll('rect')
.data(data)
.enter().append('rect')
.attr('x', x(0))
.attr('y', (d, i) => y(i))
.attr('width', d => x(d.value) - x(0))
.attr('height', y.bandwidth())
.attr('class', 'chartbar')

svg
.append('g')
.attr('class', 'chartbarTextWrap')
.selectAll('text')
.data(data)
.enter().append('text')
.attr('x', d => x(d.value) - 4)
.attr('y', (d, i) => y(i) + y.bandwidth() / 2)
.attr('dy', '0.35em')
.text(d => format(d.value))
.attr('class', 'chartbarText');

svg.append('g').call(xAxis);

svg.append('g').call(yAxis);
.chartbarTextWrap {
font-size: 14px;
font-weight: 700;
letter-spacing: 1px;
fill: #fff;
text-anchor: end;
pointer-events: none;
}
.chartbar {
fill: red;
}
.chartxAxisText, .chartyAxisText {
font-family: "Roboto", sans-serif;
font-size: 16px;
font-weight: 400;
letter-spacing: 1px;
color: #424242;
}
.chartxAxisText, .chartyAxisText {

font-size: 16px;
font-weight: 400;
color: #424242;
}
svg {
width:1180px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

<html>
<body></body>
</html>

最佳答案

在图表右侧添加一个小边距确实是最简单的解决方案。

如果您确实不想要它,您可以将x轴文本标签向右对齐:

.chartxAxisText {
text-anchor: end;
}

这在下面的片段中得到了证明。

const margin = {
top: 30,
right: 0,
bottom: 10,
left: 100
};
const width= 1180;
const data = [{
name: 'A',
value: 2
},
{
name: 'B',
value: 20
},
{
name: 'C',
value: 15
},
{
name: 'D',
value: 8
},
{
name: 'E',
value: 1
}
];
const barHeight = 20;
const yMax = d3.max(data, d => d.value);

const height =
Math.ceil((data.length + 0.1) * barHeight) + margin.top + margin.bottom;
const x = d3
.scaleLinear()
.domain([0, yMax < 10 ? 10 : yMax])
.range([margin.left, width - margin.right]);
const y = d3
.scaleBand()
.domain(d3.range(data.length))
.range([margin.top, height - margin.bottom])
.padding(0.1);

const format = x.tickFormat(10, data.format);
const svg = d3.select('body').append('svg').attr('viewBox', [0, 0, width, height]);
const xAxis = g =>
g
.attr('class', 'chartxAxisText')
.attr('transform', `translate(0,${margin.top})`)
.call(d3.axisTop(x))

.call(g => g.select('.domain').remove());
const yAxis = g =>
g
.attr('class', 'chartyAxisText')
.attr('transform', `translate(${margin.left},0)`)
.call(
d3
.axisLeft(y)
.tickFormat(i => data[i].name)
.tickSizeOuter(0)
);

svg
.append('g')
.selectAll('rect')
.data(data)
.enter().append('rect')
.attr('x', x(0))
.attr('y', (d, i) => y(i))
.attr('width', d => x(d.value) - x(0))
.attr('height', y.bandwidth())
.attr('class', 'chartbar')

svg
.append('g')
.attr('class', 'chartbarTextWrap')
.selectAll('text')
.data(data)
.enter().append('text')
.attr('x', d => x(d.value) - 4)
.attr('y', (d, i) => y(i) + y.bandwidth() / 2)
.attr('dy', '0.35em')
.text(d => format(d.value))
.attr('class', 'chartbarText');

svg.append('g').call(xAxis);

svg.append('g').call(yAxis);
.chartbarTextWrap {
font-size: 14px;
font-weight: 700;
letter-spacing: 1px;
fill: #fff;
text-anchor: end;
pointer-events: none;
}
.chartbar {
fill: red;
}
.chartxAxisText, .chartyAxisText {
font-family: "Roboto", sans-serif;
font-size: 16px;
font-weight: 400;
letter-spacing: 1px;
color: #424242;
}
.chartxAxisText {
text-anchor: end;
}
svg {
width:1180px
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

<html>
<body></body>
</html>

另一种选择是保留所有标签不变,仅将最后一个标签向左对齐。这也可以在 CSS 中完成,规则如下:

.chartxAxisText text:last-child {
text-anchor: end;
}

关于javascript - d3.js水平条形图问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61224958/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com