gpt4 book ai didi

javascript - 如何在具有不规则数据结构的React(vanilla)中使用D3的时间尺度?

转载 作者:行者123 更新时间:2023-11-27 22:50:11 25 4
gpt4 key购买 nike

我的目标是创建一个多线图(绘制特定立法区随时间推移的特定犯罪数量的图表)。 y 轴是犯罪数量,x 轴是日期(间隔一周),每行代表一种犯罪类型。

数据是一个对象数组,已针对某个地区进行过滤并按日期排序:

[
{
count: "4",
date: "2015-09-23",
district: 12,
to_timestamp: "2015-09-24T00:00:00.000Z",
type: "MOTOR VEHICLE THEFT"
},
{
count: "13",
date: "2015-09-23",
district: 12,
to_timestamp: "2015-09-24T00:00:00.000Z",
type: "BURGLARY"
},
...
{
count: "3",
date: "2016-03-23",
district: 12,
to_timestamp: "2016-03-24T00:00:00.000Z",
type: "BURGLARY"
}
]

我的React组件如下:

const Line = React.createClass({

propTypes: {
path: React.PropTypes.string.isRequired,
stroke: React.PropTypes.string,
fill: React.PropTypes.string,
strokeWidth: React.PropTypes.number
},

getDefaultProps() {
return {
stroke: 'blue',
fill: 'none',
strokeWidth: 3
};
},

render() {
let { path, stroke, fill, strokeWidth } = this.props;
return (
<path
d={path}
fill={fill}
stroke={stroke}
strokeWidth={strokeWidth}
/>
);
}

});

const DataSeries = React.createClass({

propTypes: {
colors: React.PropTypes.func,
data: React.PropTypes.array,
interpolationType: React.PropTypes.string,
xScale: React.PropTypes.func,
yScale: React.PropTypes.func
},

getDefaultProps() {
return {
data: [],
interpolationType: 'basis',
colors: d3.scale.category10()
};
},

render() {
let { data, colors, xScale, yScale, interpolationType } = this.props;

let line = d3.svg.line()
.interpolate(interpolationType)
.x((d) => { return xScale(d.to_timestamp); })
.y((d) => { return yScale(d.count); });

let dataGroup = d3.nest()
.key(function(d) {
return d.type;
})
.entries(data);

let lines = dataGroup.map((series, id) => {
return (
<Line
path={line(series.values)}
stroke={colors(id)}
key={id}
/>
);
});

return (
<g>
<g>{lines}</g>
</g>
);
}

});

const LineChart = React.createClass({

propTypes: {
width: React.PropTypes.number,
height: React.PropTypes.number,
data: React.PropTypes.array.isRequired
},

getDefaultProps(){
return {
width: 600,
height: 300
}
},

render() {
let { width, height, data } = this.props;

let xScale = d3.time.scale()
.domain([new Date('2015-09-24T00:00:00.000Z'), new Date('2016-03-24T00:00:00.000Z')])
.range([0, width]);

let yScale = d3.scale.linear()
.domain([d3.min(data, function(d) {
return d.count;
}), d3.max(data, function(d) {
return d.count;
})])
.range([height, 10]);

console.log(data);

return (
<svg width={width} height={height}>
<DataSeries
xScale={xScale}
yScale={yScale}
data={data}
width={width}
height={height}
/>
</svg>
);
}

});

我相信问题出在 xScaleyScale LineChart 上的变量成分。首先,我对第一个和最后一个日期进行硬编码,而不是使用 x.min()y.min() ,但这两种方法都不起作用。

一个额外的问题是,在给定日期可能不一定有给定犯罪的数据点;也就是说,没有明确注册 count: 0 的数据点。我收到的错误是:

Error: <path> attribute d: Expected number, "MNaN,191.25LNaN,1…".

作为引用,我一直在遵循这两个指南: http://code.tutsplus.com/tutorials/building-a-multi-line-chart-using-d3js--cms-22935 http://blog.bigbinary.com/2016/02/04/using-d3-js-with-react-js.html

最佳答案

当您提供日期的字符串表示形式时,时间刻度需要日期对象。

试试这个:

let line = d3.svg.line()
.interpolate(interpolationType)
.x((d) => { return xScale(new Date(d.to_timestamp)); })
.y((d) => { return yScale(d.count); });

或者更好地转换您的数据:

data.forEach(d => d.to_timestamp = new Date(d.to_timestamp));

关于javascript - 如何在具有不规则数据结构的React(vanilla)中使用D3的时间尺度?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38116635/

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