我有两种看起来像这样的不同车辆的MPG数据:
var data = [{
"dateAdded": "2017-01-01T16:21:52.921Z",
"mpg": 25.361,
"vehicle": "car"
}, {
"dateAdded": "2017-10-17T11:05:10.280Z",
"mpg": 17.788,
"vehicle": "truck"
}, ...]
我正在尝试制作D3 JS线图,并在同一图上为每个车辆使用不同的线路。相关代码如下。请参阅此处的JSFIDDLE。
var d3svg = d3.select('svg');
var margin = {
top: 20,
right: 20,
bottom: 50,
left: 60
};
var width = +d3svg.attr('width') - margin.left - margin.right;
var height = +d3svg.attr('height') - margin.top - margin.bottom;
// massage the data
data = data.map(function (d) {
return {
vehicle: d.vehicle,
dateAdded: new Date(d.dateAdded),
mpg: d.mpg
};
});
console.log(data);
// scales
var xScale = d3.scaleTime().rangeRound([0, width]);
var yScale = d3.scaleLinear().rangeRound([height, 0]);
// create line for car
var carLine = d3.line()
.x(function(d) { if (d.vehicle.toLowerCase().indexOf('car') > -1) return xScale(d.dateAdded); })
.y(function(d) { if (d.vehicle.toLowerCase().indexOf('car') > -1) return yScale(d.mpg); });
// create line for truck
var truckLine = d3.line()
.x(function(d) { if (d.vehicle.toLowerCase().indexOf('truck') > -1) return xScale(d.dateAdded); })
.y(function(d) { if (d.vehicle.toLowerCase().indexOf('truck') > -1) return yScale(d.mpg); });
// set the domain
xScale.domain(d3.extent(data, function(d) { return d.dateAdded; }));
yScale.domain(d3.extent(data, function(d) { return d.mpg; })).nice();
// create the outer g tag
var g = d3svg.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
// add the x-axis
var xAxis = d3.axisBottom(xScale)
.ticks(d3.timeMonth.every(1))
.tickFormat(d3.timeFormat('%Y-%m'));
g.append('g')
.attr('class', 'axis axis-x')
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);
// add the y-axis
var yAxis = d3.axisLeft(yScale)
.tickFormat(d3.format('.1f'));
g.append('g')
.attr('class', 'axis axis-y')
.call(yAxis);
// add the paths that represent the data
g.append('path')
.datum(data)
.attr('fill', 'none')
.attr('class', 'line line-car')
.attr('stroke-linejoin', 'round')
.attr('stroke-linecap', 'round')
.attr('stroke-width', 1.5)
.attr('d', carLine);
g.append('path')
.datum(data)
.attr('fill', 'none')
.attr('class', 'line line-truck')
.attr('stroke-linejoin', 'round')
.attr('stroke-linecap', 'round')
.attr('stroke-width', 1.5)
.attr('d', truckLine);
我可以用两个车辆的数据中的一个图形,但是如何将两者都放在同一图上?
,而不是为每辆车创建一个线路发生器,而这将不起作用,而是创建一个线生成器...
var line = d3.line()
.x(function(d) {
return xScale(d.dateAdded)
})
.y(function(d) {
return yScale(d.mpg)
});
...并将每个车辆的数据分开:
var carData = data.filter(function(d) {
return d.vehicle === "car"
});
var truckData = data.filter(function(d) {
return d.vehicle === "truck"
});
另外,别忘了设置路径的笔触。
这是您的代码和这些更改:
var data = [{
"dateAdded": "2017-01-01T16:21:52.921Z",
"mpg": 25.361,
"vehicle": "car"
}, {
"dateAdded": "2017-02-25T04:43:00.853Z",
"mpg": 27.45,
"vehicle": "car"
}, {
"dateAdded": "2017-02-28T22:00:22.253Z",
"mpg": 29.245,
"vehicle": "car"
}, {
"dateAdded": "2017-03-01T01:39:27.160Z",
"mpg": 23.981,
"vehicle": "car"
}, {
"dateAdded": "2017-03-25T19:50:13.226Z",
"mpg": 26.293,
"vehicle": "car"
}, {
"dateAdded": "2017-04-06T00:37:33.324Z",
"mpg": 30.148,
"vehicle": "car"
}, {
"dateAdded": "2017-04-27T02:16:09.503Z",
"mpg": 23.178,
"vehicle": "car"
}, {
"dateAdded": "2017-04-27T22:15:35.137Z",
"mpg": 32.362,
"vehicle": "car"
}, {
"dateAdded": "2017-06-05T19:24:16.413Z",
"mpg": 23.561,
"vehicle": "car"
}, {
"dateAdded": "2017-06-09T14:05:22.063Z",
"mpg": 33.38,
"vehicle": "car"
}, {
"dateAdded": "2017-06-16T03:12:01.137Z",
"mpg": 23.41,
"vehicle": "car"
}, {
"dateAdded": "2017-06-24T17:47:26.489Z",
"mpg": 32.44,
"vehicle": "car"
}, {
"dateAdded": "2017-07-02T10:27:31.963Z",
"mpg": 25.122,
"vehicle": "car"
}, {
"dateAdded": "2017-07-02T13:24:26.660Z",
"mpg": 22.021,
"vehicle": "car"
}, {
"dateAdded": "2017-07-09T02:54:02.107Z",
"mpg": 33.559,
"vehicle": "car"
}, {
"dateAdded": "2017-07-11T15:42:05.969Z",
"mpg": 30.502,
"vehicle": "car"
}, {
"dateAdded": "2017-07-20T07:08:34.474Z",
"mpg": 24.176,
"vehicle": "car"
}, {
"dateAdded": "2017-07-29T00:21:18.809Z",
"mpg": 23.633,
"vehicle": "car"
}, {
"dateAdded": "2017-08-26T11:44:02.211Z",
"mpg": 31.796,
"vehicle": "car"
}, {
"dateAdded": "2017-08-29T05:16:20.148Z",
"mpg": 26.962,
"vehicle": "car"
}, {
"dateAdded": "2017-09-01T15:56:22.616Z",
"mpg": 33.726,
"vehicle": "car"
}, {
"dateAdded": "2017-09-14T06:16:04.025Z",
"mpg": 25.916,
"vehicle": "car"
}, {
"dateAdded": "2017-09-21T13:09:23.471Z",
"mpg": 27.461,
"vehicle": "car"
}, {
"dateAdded": "2017-09-28T06:40:38.405Z",
"mpg": 29.424,
"vehicle": "car"
}, {
"dateAdded": "2017-10-12T15:03:14.717Z",
"mpg": 32.77,
"vehicle": "car"
}, {
"dateAdded": "2017-10-17T11:05:10.280Z",
"mpg": 17.788,
"vehicle": "truck"
}, {
"dateAdded": "2017-11-01T17:51:15.741Z",
"mpg": 23.392,
"vehicle": "car"
}, {
"dateAdded": "2017-11-02T18:45:57.081Z",
"mpg": 20.296,
"vehicle": "truck"
}, {
"dateAdded": "2017-11-21T09:07:29.754Z",
"mpg": 18.263,
"vehicle": "truck"
}, {
"dateAdded": "2017-11-25T12:39:35.312Z",
"mpg": 28.573,
"vehicle": "car"
}, {
"dateAdded": "2017-11-29T21:56:35.318Z",
"mpg": 19.746,
"vehicle": "truck"
}, {
"dateAdded": "2017-12-18T20:28:27.678Z",
"mpg": 20.992,
"vehicle": "truck"
}, {
"dateAdded": "2017-12-29T07:56:07.098Z",
"mpg": 15.433,
"vehicle": "truck"
}, {
"dateAdded": "2018-01-14T08:30:54.303Z",
"mpg": 25.375,
"vehicle": "car"
}, {
"dateAdded": "2018-01-17T21:27:47.570Z",
"mpg": 16.602,
"vehicle": "truck"
}, {
"dateAdded": "2018-01-23T18:55:03.076Z",
"mpg": 29.325,
"vehicle": "car"
}, {
"dateAdded": "2018-01-23T22:15:50.318Z",
"mpg": 15.516,
"vehicle": "truck"
}, {
"dateAdded": "2018-02-02T03:04:19.458Z",
"mpg": 27.97,
"vehicle": "car"
}, {
"dateAdded": "2018-02-11T08:23:55.474Z",
"mpg": 17.973,
"vehicle": "truck"
}, {
"dateAdded": "2018-02-14T13:46:43.398Z",
"mpg": 20.791,
"vehicle": "truck"
}];
var d3svg = d3.select('svg');
var margin = {
top: 20,
right: 20,
bottom: 50,
left: 60
};
var width = +d3svg.attr('width') - margin.left - margin.right;
var height = +d3svg.attr('height') - margin.top - margin.bottom;
// massage the data
data = data.map(function(d) {
return {
vehicle: d.vehicle,
dateAdded: new Date(d.dateAdded),
mpg: d.mpg
};
});
// scales
var xScale = d3.scaleTime().rangeRound([0, width]);
var yScale = d3.scaleLinear().rangeRound([height, 0]);
// create line for car
var line = d3.line()
.x(function(d) {
return xScale(d.dateAdded)
})
.y(function(d) {
return yScale(d.mpg)
});
// set the domain
xScale.domain(d3.extent(data, function(d) {
return d.dateAdded;
}));
yScale.domain(d3.extent(data, function(d) {
return d.mpg;
})).nice();
var carData = data.filter(function(d) {
return d.vehicle === "car"
});
var truckData = data.filter(function(d) {
return d.vehicle === "truck"
});
// create the outer g tag
var g = d3svg.append('g')
.attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');
// add the x-axis
var xAxis = d3.axisBottom(xScale)
.ticks(d3.timeMonth.every(1))
.tickFormat(d3.timeFormat('%Y-%m'));
g.append('g')
.attr('class', 'axis axis-x')
.attr('transform', 'translate(0,' + height + ')')
.call(xAxis);
// add the y-axis
var yAxis = d3.axisLeft(yScale)
.tickFormat(d3.format('.1f'));
g.append('g')
.attr('class', 'axis axis-y')
.call(yAxis);
// add the paths that represent the data
g.append('path')
.datum(carData)
.attr('fill', 'none')
.attr('class', 'line line-car')
.attr('stroke-linejoin', 'round')
.attr('stroke-linecap', 'round')
.attr('stroke-width', 1.5)
.attr("stroke", "blue")
.attr('d', line);
g.append('path')
.datum(truckData)
.attr('fill', 'none')
.attr('class', 'line line-truck')
.attr('stroke-linejoin', 'round')
.attr('stroke-linecap', 'round')
.attr('stroke-width', 1.5)
.attr("stroke", "red")
.attr('d', line);
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg width="900" height="600"></svg>