我正在使用React,D3和moment.js来构建可重复使用的折线图组件,该组件可以随时间跟踪值。
我很难使刻度线对齐正确。我目前正在使用动量并将所有内容转换为时间戳,并依赖于线性刻度,但我对其他可能有效的解决方案持开放态度!
另一个问题是x轴上的刻度线重复了一个日期,而省略了另一个。我的假设是,这一切都与之相关。
我有以下数据集:
let time = [
{"id": 1, "date": "06/14/2019", "total": 1},
{"id": 2, "date": "06/15/2019", "total": 4},
{"id": 3, "date": "06/16/2019", "total": 8},
{"id": 4, "date": "06/17/2019", "total": 4}
];
这是我相关的React组件代码:
import * as d3 from 'd3';
import moment from 'moment';
const LineChart = props => {
const margin = 20;
const h = props.height - 2 * margin;
const w = props.width - 2 * margin;
const yFormat = d3.format(".2");
const data = props.data;
const x = d3.scaleLinear()
.domain(d3.extent(data, d => moment(d.date, 'MM/DD/YYYY').format('X')))
.range([margin, w]);
// debug
// console.log(moment("06/14/2019", 'MM/DD/YYYY').format('X'));
// console.log(moment("06/16/2019", 'MM/DD/YYYY').format('X'));
// console.log(x(moment("06/14/2019", 'MM/DD/YYYY').format('X')));
// console.log(x(moment("06/16/2019", 'MM/DD/YYYY').format('X')));
const y = d3.scaleLinear()
.domain([0, d3.max(data, d => d.total)])
.range([h, margin]);
const line = d3.line()
.x(d => x(moment(d.date, 'MM/DD/YYYY').format('X')))
.y(d => y(d.total));
const xTicks = x.ticks(props.data.length).map(d => (
x(d) >= margin && x(d) <= w ?
<g transform={`translate(${x(d)},${h + margin})`} key={x(d)}>
<text>{moment(d*1000).format('YYYY/MM/DD')}</text>
<line x1='0' x2='0' y1='0' y2='5' transform="translate(0,-20)"/>
</g>
: null
));
我的渲染功能:
return (
<svg width={props.width} height={props.height}>
<line className="axis" x1={margin} x2={w} y1={h} y2={h} />
<line className="axis" x1={margin} x2={margin} y1={margin} y2={h} />
<path className="line" d={line(data)} ref={ref} />
<g className="axis-labels">
{xTicks}
</g>
<g className="axis-labels">
{yTicks}
</g>
</svg>
);
};
这给我留下了如下折线图: