D3 相同的刻度在 y 轴上显示两次
D3 same ticks being showed twice on y axis
在 y 轴上多次显示相同的刻度值(在本例中为 1M)。我认为问题不在于我如何使用 yAxisTickFormat
格式化刻度。我做错了什么?
export const yAxisTickFormat = (d) => {
//Logic to reduce big numbers
const limits = [1000000, 10000, 1000];
const shorteners = ['M', 'K', 'K'];
for (let i in limits) {
if (d > limits[i]) {
return (d / limits[i]).toFixed() + shorteners[i];
}
}
return d;
};
const maxValue = storeData.dataset.reduce((maxAll, item) => {
return item.values.reduce((maxItem, val) =>
Math.max(maxItem, val.value), maxAll);
}, 0);
const yScale = d3.scaleLinear().range([-120, height - 200]);
yScale.domain([maxValue, 0]);
const yAxis = d3
.axisLeft()
.scale(yScale)
.tickFormat((d) => (d === 0 ? null : '£') + yAxisTickFormat(d))
.ticks(5)
.tickSize(-width, barMargin, 0)
.tickPadding(10);
相反,问题出在数字格式上。您传递的 1400000
和 1200000
将转换为 1M。尝试通过将参数传递给 .toFixed
方法
来在逗号后添加几个数字
export const yAxisTickFormat = (d) => {
//Logic to reduce big numbers
const limits = [1000000, 10000, 1000];
const shorteners = ['M', 'K', 'K'];
for (let i in limits) {
if (d > limits[i]) {
return (d / limits[i]).toFixed(1) + shorteners[i];
}
}
return d;
};
这会将您的数字相应地转换为 1.4m 和 1.2m。
这是一个更正确的 yAxisTickFormat
(使用代码片段测试):
const yAxisTickFormat = (d) => {
let limit = Math.pow(10, 12);
const shorteners = ["T", "B", "M", "K"];
for (let i = 0; i < shorteners.length; i++) {
if (d >= limit) {
const zeroPad = Math.floor(d / limit) === d / limit;
return '£ ' + (d / limit).toFixed(zeroPad ? 0 : 1) + ' ' + shorteners[i];
}
limit /= 1000;
}
return d;
};
const svg = d3.select('svg');
const ranges = [5000, 2000000, 4000000000, 3500000000000];
ranges.forEach((range, index) => {
const yScale = d3.scaleLinear().domain([range, 0]).range([0,300]);
const yAxis = d3
.axisLeft()
.scale(yScale)
.tickFormat((d) => yAxisTickFormat(d))
.ticks(10);
svg.append('g').attr('transform', `translate(${50 + index * 100},50)`).call(yAxis);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="400" height="400"/>
在 y 轴上多次显示相同的刻度值(在本例中为 1M)。我认为问题不在于我如何使用 yAxisTickFormat
格式化刻度。我做错了什么?
export const yAxisTickFormat = (d) => {
//Logic to reduce big numbers
const limits = [1000000, 10000, 1000];
const shorteners = ['M', 'K', 'K'];
for (let i in limits) {
if (d > limits[i]) {
return (d / limits[i]).toFixed() + shorteners[i];
}
}
return d;
};
const maxValue = storeData.dataset.reduce((maxAll, item) => {
return item.values.reduce((maxItem, val) =>
Math.max(maxItem, val.value), maxAll);
}, 0);
const yScale = d3.scaleLinear().range([-120, height - 200]);
yScale.domain([maxValue, 0]);
const yAxis = d3
.axisLeft()
.scale(yScale)
.tickFormat((d) => (d === 0 ? null : '£') + yAxisTickFormat(d))
.ticks(5)
.tickSize(-width, barMargin, 0)
.tickPadding(10);
相反,问题出在数字格式上。您传递的 1400000
和 1200000
将转换为 1M。尝试通过将参数传递给 .toFixed
方法
export const yAxisTickFormat = (d) => {
//Logic to reduce big numbers
const limits = [1000000, 10000, 1000];
const shorteners = ['M', 'K', 'K'];
for (let i in limits) {
if (d > limits[i]) {
return (d / limits[i]).toFixed(1) + shorteners[i];
}
}
return d;
};
这会将您的数字相应地转换为 1.4m 和 1.2m。
这是一个更正确的 yAxisTickFormat
(使用代码片段测试):
const yAxisTickFormat = (d) => {
let limit = Math.pow(10, 12);
const shorteners = ["T", "B", "M", "K"];
for (let i = 0; i < shorteners.length; i++) {
if (d >= limit) {
const zeroPad = Math.floor(d / limit) === d / limit;
return '£ ' + (d / limit).toFixed(zeroPad ? 0 : 1) + ' ' + shorteners[i];
}
limit /= 1000;
}
return d;
};
const svg = d3.select('svg');
const ranges = [5000, 2000000, 4000000000, 3500000000000];
ranges.forEach((range, index) => {
const yScale = d3.scaleLinear().domain([range, 0]).range([0,300]);
const yAxis = d3
.axisLeft()
.scale(yScale)
.tickFormat((d) => yAxisTickFormat(d))
.ticks(10);
svg.append('g').attr('transform', `translate(${50 + index * 100},50)`).call(yAxis);
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<svg width="400" height="400"/>