好的,对于以下代码,我的x行函数返回NaN。我不知道为什么。我尝试将时间值更改为1到9并使用线性比例,我已将它们转换为时间(它仅用于概念证明,因此可以暂时调整值),并尝试将它们作为“新日期” ',没有运气。
我做错了什么?为什么X总是NaN?
其中一个记录数据点的示例:
x:d是:2015-06-01 x(新日期(d.Period))是NaN y:d是65.54347826086956
jQuery(document).ready(function ($) {
var margin = {top: 20, right: 30, bottom: 40, left: 50},
width = 300 - margin.left - margin.right,
height = 150 - margin.top - margin.bottom;
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient('bottom');
var yAxis = d3.svg.axis()
.scale(y)
.orient('left');
var color = d3.scale.category10();
var line = d3.svg.line()
.x(function(d) {console.log('d is : ', d.Period,' x(new Date(d.Period)) is ', x(new Date(d.Period))); return x(new Date(d.Period)); })
.y(function(d) {console.log('y:d is ', y(d.Value)); return y(d.Value); })
var svg = d3.select("#pipeline-chart-render")
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
// This separates the data into the lines we want, although the data is stored
// In the same original object.
var keys = color.domain(d3.keys(data[0].values[0]).filter(function(key) {
if (key === 'Amount'
|| key === 'Quantity') {
return key
}
}));
// This returns the data into two separate objects which can be graphed.
// In this case, Amount and Quantity.
var datasets = color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {Period: d.values[0].Time, Value: +d.values[0][name]};
})
};
});
console.log('datasets is: ', datasets);
// set the minYDomainValue to zero instead of letting it be a lingering magic number.
var minDomainValue = 0
// x.domain([
// minDomainValue,
// d3.max(datasets, function(c) { return d3.max(c.values, function(v) { console.log(v); return v.Time }); })
// ])
x.domain(d3.extent(datasets, function(d) { console.log(d); return new Date(d.values[0].Time); }));
y.domain([
minDomainValue,
// d3.min(datasets, function(c) { return d3.min(c.values, function(v) { return v.Time; }); }),
d3.max(datasets, function(c) { return d3.max(c.values, function(v) { return v.Value; }); })
])
// Append the x-axis class and move axis around.
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
// Append the y-axis class.
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
var dataset = svg.selectAll('.pipeline')
.data(datasets);
console.log(dataset);
dataset.enter()
.append('g')
.attr('class', 'pipeline');
dataset.append('path')
.attr('class', 'line')
.attr('d', function(d) { return line(d.values); })
.attr("data-legend",function(d) { return d.name})
.style("stroke", function(d) { return color(d.name); })
dataset.exit().remove()
});
var data = [
{
key: 1,
values: [
{
Amount: 33,
Quantity: 22,
Time: '2015-01-01'
}
]
},
{
key: 2,
values: [
{
Amount: 52,
Quantity: 20,
Time: '2015-02-01'
}
]
},
{
key: 3,
values: [
{
Amount: 63,
Quantity: 30,
Time: '2015-03-01'
}
]
},
{
key: 4,
values: [
{
Amount: 92,
Quantity: 60,
Time: '2015-04-01'
}
]
},
{
key: 5,
values: [
{
Amount: 50,
Quantity: 29,
Time: '2015-05-01'
}
]
},
{
key: 6,
values: [
{
Amount: 53,
Quantity: 25,
Time: '2015-06-01'
}
]
},
{
key: 7,
values: [
{
Amount: 46,
Quantity: 12,
Time: '2015-07-01'
}
]
},
{
key: 8,
values: [
{
Amount: 52,
Quantity: 15,
Time: '2015-08-01'
}
]
},
{
key: 9,
values: [
{
Amount: 55,
Quantity: 20,
Time: '2015-09-01'
}
]
}
]
// var formatTime = function(date) {
// var formatter = d3.time.format("%Y-%m").parse;
// return formatter(date);
// }
答案 0 :(得分:1)
要回答您的具体问题,您未正确设置x域名,我建议您:
var minDate = d3.min(datasets, function(d0){
return d3.min(d0.values, function(d1){
return d1.Period;
})
}),
maxDate = d3.max(datasets, function(d0){
return d3.max(d0.values, function(d1){
return d1.Period;
})
});
x.domain([minDate, maxDate]);
为了实现这一目标,请接受我的下一个建议并停止new Date(
疯狂,只要强迫你的时间从一开始就过去。我强烈建议您使用generator expression而不是尝试自我转换:
var tP = d3.time.format("%Y-%m-%d");
// This returns the data into two separate objects which can be graphed.
// In this case, Amount and Quantity.
var datasets = color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {
Period: tP.parse(d.values[0].Time), //<-- just convert once!
Value: +d.values[0][name]
};
})
};
});
然后将您的行功能简化为:
var line = d3.svg.line()
.x(function(d) {
return x(d.Period);
})
.y(function(d) {
return y(d.Value);
});
完整代码:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
</head>
<body>
<svg id="pipeline-chart-render"></div>
<script>
var data = [{
key: 1,
values: [{
Amount: 33,
Quantity: 22,
Time: '2015-01-01'
}]
}, {
key: 2,
values: [{
Amount: 52,
Quantity: 20,
Time: '2015-02-01'
}]
}, {
key: 3,
values: [{
Amount: 63,
Quantity: 30,
Time: '2015-03-01'
}]
}, {
key: 4,
values: [{
Amount: 92,
Quantity: 60,
Time: '2015-04-01'
}]
}, {
key: 5,
values: [{
Amount: 50,
Quantity: 29,
Time: '2015-05-01'
}]
}, {
key: 6,
values: [{
Amount: 53,
Quantity: 25,
Time: '2015-06-01'
}]
}, {
key: 7,
values: [{
Amount: 46,
Quantity: 12,
Time: '2015-07-01'
}]
}, {
key: 8,
values: [{
Amount: 52,
Quantity: 15,
Time: '2015-08-01'
}]
}, {
key: 9,
values: [{
Amount: 55,
Quantity: 20,
Time: '2015-09-01'
}]
}]
var margin = {
top: 20,
right: 30,
bottom: 40,
left: 50
},
width = 300 - margin.left - margin.right,
height = 150 - margin.top - margin.bottom;
var tP = d3.time.format("%Y-%m-%d");
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var xAxis = d3.svg.axis()
.scale(x)
.orient('bottom');
var yAxis = d3.svg.axis()
.scale(y)
.orient('left');
var color = d3.scale.category10();
var line = d3.svg.line()
.x(function(d) {
console.log('d is : ', d.Period, ' x(new Date(d.Period)) is ', x(d.Period));
return x(d.Period);
})
.y(function(d) {
console.log('y:d is ', y(d.Value));
return y(d.Value);
})
var svg = d3.select("#pipeline-chart-render")
.attr('width', width + margin.left + margin.right)
.attr('height', height + margin.top + margin.bottom)
.append('g')
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
// This separates the data into the lines we want, although the data is stored
// In the same original object.
var keys = color.domain(d3.keys(data[0].values[0]).filter(function(key) {
if (key === 'Amount' || key === 'Quantity') {
return key
}
}));
// This returns the data into two separate objects which can be graphed.
// In this case, Amount and Quantity.
var datasets = color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {
Period: tP.parse(d.values[0].Time),
Value: +d.values[0][name]
};
})
};
});
// set the minYDomainValue to zero instead of letting it be a lingering magic number.
var minDomainValue = 0;
var minDate = d3.min(datasets, function(d0){
return d3.min(d0.values, function(d1){
return d1.Period;
})
}),
maxDate = d3.max(datasets, function(d0){
return d3.max(d0.values, function(d1){
return d1.Period;
})
});
x.domain([minDate, maxDate]);
y.domain([
minDomainValue,
// d3.min(datasets, function(c) { return d3.min(c.values, function(v) { return v.Time; }); }),
d3.max(datasets, function(c) {
return d3.max(c.values, function(v) {
return v.Value;
});
})
])
// Append the x-axis class and move axis around.
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
// Append the y-axis class.
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
var dataset = svg.selectAll('.pipeline')
.data(datasets);
console.log(dataset);
dataset.enter()
.append('g')
.attr('class', 'pipeline');
dataset.append('path')
.attr('class', 'line')
.attr('d', function(d) {
return line(d.values);
})
.attr("data-legend", function(d) {
return d.name
})
.style("stroke", function(d) {
return color(d.name);
})
dataset.exit().remove()
</script>
</body>
</html>
&#13;