我正在d3中绘制多线图,并且几乎所有设置都已完成。我现在唯一要做的就是动态转换图表的x轴,使其沿y轴与值0对齐。之所以要这样做,是因为我正在处理负值,为了便于阅读,将x轴设置为0会更好。我在这里找到了类似的问题(move x axis to coordinate (0,0) on the chart with d3.js),我确实尝试过代码行
this.svg.append('g')
.attr('class', 'axis')
.attr('transform', 'translate(0,' + (this.yScale(0)) + ')')
.call(xAxis);
但是它在我的图表中不起作用。我还要补充一点,我将根据用户选择的选择选项的值更新y轴,所以我的猜测是,一旦发生这种情况,我还必须更新x轴。换句话说,定位必须是动态的。
这是我到目前为止所拥有的:
const dimensions = {
width: window.innerWidth * 0.6,
height: 400,
margin: {
top: 15,
right: 15,
bottom: 40,
left: 60,
},
};
dimensions.boundedWidth =
dimensions.width - dimensions.margin.left - dimensions.margin.right;
dimensions.boundedHeight =
dimensions.height - dimensions.margin.top - dimensions.margin.bottom;
// 4 - draw our canvas
const wrapper = d3
.select('#wrapper')
.append('svg')
.attr('width', dimensions.width)
.attr('height', dimensions.height);
// 5 - create our bounding box
const bounds = wrapper
.append('g')
.style(
'transform',
`translate(${dimensions.margin.left}px, ${dimensions.margin.top}px)`
);
// 6 - create our scales
const yScale = d3
.scaleLinear()
.domain(d3.extent(data, yAccessor))
.range([dimensions.boundedHeight, 0])
.nice();
const xScale = d3
.scaleTime()
.domain(d3.extent(data, xAccessor))
.range([0, dimensions.boundedWidth])
.nice();
// 9 - create our Y axis
const yAxisGenerator = d3
.axisLeft()
.scale(yScale)
.tickFormat(formatTick);
function formatTick(tick) {
const valueGuide = tick;
// get the las value of the y axis and add a % to it
// https://observablehq.com/@d3/styled-axes
return this.parentNode.nextSibling ? `\xa0${valueGuide}` : `%${valueGuide}`;
}
const yAxis = bounds
.append('g')
.attr('class', 'yaxis')
.call(yAxisGenerator);
// 10 - create our X axis
const xAxisGenerator = d3
.axisBottom()
.scale(xScale)
.tickFormat(d3.timeFormat('%m/%d'));
const xAxis = bounds
.append('g')
.attr('class', 'xaxis')
.style('transform', `translateY(${dimensions.boundedHeigh}px)`)
.call(xAxisGenerator.ticks(d3.timeDay.every(4)));
以及更新y轴的部分:
yScale.domain(d3.extent(minMax)).nice();
bounds
.selectAll('.yaxis')
.transition()
.duration(1000)
.ease(d3.easeLinear)
.call(yAxisGenerator);