问题描述
我正在使用d3.js实现多线系列图表,并且尝试从输入的数据中绘制dateTime时遇到指向我的x轴的错误.错误:属性d:预期数字,"MNaN,376.88020650…."
这是我的职责
var数据= [{"Brand":"Toyota",计数":1800,"Time":"2017-04-02 16"},{"Brand":"Toyota",计数":1172,"Time":"2017-04-02 17"},{"Brand":"Toyota",计数":2000,"Time":"2017-04-02 18"},{品牌":本田",计数":8765,"Time":"2017-04-02 16"},{品牌":本田",计数":3445,"Time":"2017-04-02 17"},{品牌":本田",计数":1232,时间":"2017-04-02 18"}]var dataGroup = d3.nest()//按Brand将数据分组的d3方法.key(function(d){return d.Brand;}).entries(data);console.log(JSON.stringify(dataGroup));//var color = d3.scale.category10();var vis = d3.select(#visualisation"),宽度= 1000,身高= 500,保证金= {最高:50右:20底部:50,左:50},xScale = d3.scaleLinear().range([MARGINS.left,WIDTH-MARGINS.right]).domain([d3.min(data,function(d){返回d.Time;}),d3.max(数据,函数(d){返回d.Time;})]),yScale = d3.scaleLinear().range([HEIGHT-MARGINS.top,MARGINS.bottom]).domain([d3.min(data,function(d){返回d.Count;}),d3.max(数据,函数(d){返回d.Count;})]),xAxis = d3.axisBottom().scale(xScale),yAxis = d3.axisLeft().scale(yScale)vis.append("svg:g").attr("class","x轴").attr("transform","translate(0," +(HEIGHT-MARGINS.bottom)+)").call(xAxis);vis.append("svg:g").attr("class","y轴").attr("transform","translate(" +(MARGINS.left)+,0)").call(yAxis);var lineGen = d3.line().x(function(d){返回xScale(d.Time);}).y(function(d){返回yScale(d.Count);}).curve(d3.curveBasis);dataGroup.forEach(function(d,i){//遍历dataGroup并为每个品牌创建折线图vis.append('svg:path').attr('d',lineGen(d.values)).attr('stroke',function(d,j){返回"hsl("+ Math.random()* 360 +",100%,50%);//图表上每个品牌线的颜色随机}).attr('stroke-width',2).attr('id','line _'+ d.key).attr('fill','none');lSpace = WIDTH/dataGroup.length;//根据品牌数量定义图例空间vis.append("text").attr("x",(lSpace/2)+ i * lSpace).attr("y",HEIGHT).style(填充",黑色").attr("class","legend").on('click',function(){var active = d.active吗?假:真;var opacity =活动?0:1;d3.select(#line_" + d.key).style("opacity",opacity);d.active =活动;}).text(d.key);});
我的日期采用yyyy-mm-dd HH格式,例如,我要完成的操作是
- 时间":"2017-04-02 16"在x轴上转换为"4月2日",并且仅将小时(HH)显示为工具提示...等等
这是jsfiddle链接 https://jsfiddle.net/rsov2s2s/任何帮助表示赞赏.
在您的数据对象中, Time
只是一个字符串.因此,您必须解析为实际日期:
data.forEach(function(d){d.Time = d3.timeParse(%Y-%m-%d%H")(d.Time)});
在此函数中, d3.timeParse
使用%Y-%m-%d%H"
作为说明符,它与字符串的结构匹配./p>
之后,不要忘记将xScale从 scaleLinear
更改为 scaleTime
.
这是您的代码,仅包含那些更改:
var data = [{"Brand":"Toyota",计数":1800,时间":"2017-04-02 16"},{"Brand":"Toyota",计数":1172,时间":"2017-04-02 17"},{"Brand":"Toyota",计数":2000,时间":"2017-04-02 18"},{品牌":本田",计数":8765,时间":"2017-04-02 16"},{品牌":本田",计数":3445,时间":"2017-04-02 17"},{品牌":本田",计数":1232,时间":"2017-04-02 18"}];data.forEach(function(d){d.Time = d3.timeParse(%Y-%m-%d%H")(d.Time)});var dataGroup = d3.nest()//按Brand将数据分组的d3方法.key(function(d){返回d.Brand;}).entries(data);//var color = d3.scale.category10();var vis = d3.select(#visualisation"),宽度= 1000,身高= 500,保证金= {最高:50右:20底部:50,左:50},xScale = d3.scaleTime().range([MARGINS.left,WIDTH-MARGINS.right]).domain([d3.min(data,function(d){返回d.Time;}),d3.max(数据,函数(d){返回d.Time;})]),yScale = d3.scaleLinear().range([HEIGHT-MARGINS.top,MARGINS.bottom]).domain([d3.min(data,function(d){返回d.Count;}),d3.max(数据,函数(d){返回d.Count;})]),xAxis = d3.axisBottom().scale(xScale),yAxis = d3.axisLeft().scale(yScale)vis.append("svg:g").attr("class","x轴").attr("transform","translate(0," +(HEIGHT-MARGINS.bottom)+)").call(xAxis);vis.append("svg:g").attr("class","y轴").attr("transform","translate(" +(MARGINS.left)+,0)").call(yAxis);var lineGen = d3.line().x(function(d){返回xScale(d.Time);}).y(function(d){返回yScale(d.Count);}).curve(d3.curveBasis);dataGroup.forEach(function(d,i){//遍历dataGroup并为每个品牌创建折线图vis.append('svg:path').attr('d',lineGen(d.values)).attr('stroke',function(d,j){返回"hsl("+ Math.random()* 360 +",100%,50%);//图表上每个品牌线的颜色随机}).attr('stroke-width',2).attr('id','line_'+ d.key).attr('fill','none');lSpace = WIDTH/dataGroup.length;//根据品牌数量定义图例空间vis.append("text").attr("x",(lSpace/2)+ i * lSpace).attr("y",HEIGHT).style(填充",黑色").attr("class","legend").on('click',function(){var active = d.active吗?假:真;var opacity =活动?0:1;d3.select(#line_" + d.key).style("opacity",opacity);d.active =活动;}).text(d.key);});
.axis路径{填充:无;中风:#777;形状渲染:crissEdges;}.axis文字{字体家族:Lato;font-size:13px;}.传奇 {font-size:14px;font-weight:粗体;光标:指针;
< title> D3测试</title>< script src ="https://d3js.org/d3.v4.js"></script><身体>< svg id ="visualisation" width ="1000" height ="600"></svg>< script src ="InitChart.js"></script></body>
I am implementing a multi-line series chart using d3.js and I am getting an error pointing to my x-axis when trying to plot my dateTime from the data coming in. "Error: attribute d: Expected number, "MNaN,376.88020650…"."
Here is my function
var data = [{
"Brand": "Toyota",
"Count": 1800,
"Time": "2017-04-02 16"},
{
"Brand": "Toyota",
"Count": 1172,
"Time": "2017-04-02 17"},
{
"Brand": "Toyota",
"Count": 2000,
"Time": "2017-04-02 18"},
{
"Brand": "Honda",
"Count": 8765,
"Time": "2017-04-02 16"},
{
"Brand": "Honda",
"Count": 3445,
"Time": "2017-04-02 17"},
{
"Brand": "Honda",
"Count": 1232,
"Time": "2017-04-02 18"}
]
var dataGroup = d3.nest() //d3 method that groups data by Brand
.key(function(d) {return d.Brand;})
.entries(data);
console.log(JSON.stringify(dataGroup));
//var color = d3.scale.category10();
var vis = d3.select("#visualisation"),
WIDTH = 1000,
HEIGHT = 500,
MARGINS = {
top: 50,
right: 20,
bottom: 50,
left: 50
},
xScale = d3.scaleLinear().range([MARGINS.left, WIDTH - MARGINS.right]).domain([d3.min(data, function(d) { //set up x-axis based on data
return d.Time;
}), d3.max(data, function(d) {
return d.Time;
})]),
yScale = d3.scaleLinear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([d3.min(data, function(d) { //set up y-axis based on data
return d.Count;
}), d3.max(data, function(d) {
return d.Count;
})]),
xAxis = d3.axisBottom()
.scale(xScale),
yAxis = d3.axisLeft()
.scale(yScale)
vis.append("svg:g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (HEIGHT - MARGINS.bottom) + ")")
.call(xAxis);
vis.append("svg:g")
.attr("class", "y axis")
.attr("transform", "translate(" + (MARGINS.left) + ",0)")
.call(yAxis);
var lineGen = d3.line()
.x(function(d) {
return xScale(d.Time);
})
.y(function(d) {
return yScale(d.Count);
})
.curve(d3.curveBasis);
dataGroup.forEach(function(d,i) { //iterate over the dataGroup and create line graph for each brand
vis.append('svg:path')
.attr('d', lineGen(d.values))
.attr('stroke', function(d,j) {
return "hsl(" + Math.random() * 360 + ",100%,50%)"; //random color for each brand line on graph
})
.attr('stroke-width', 2)
.attr('id', 'line_'+d.key)
.attr('fill', 'none');
lSpace = WIDTH/dataGroup.length; //define the legend space based on number of brands
vis.append("text")
.attr("x", (lSpace/2)+i*lSpace)
.attr("y", HEIGHT)
.style("fill", "black")
.attr("class","legend")
.on('click',function(){
var active = d.active ? false : true;
var opacity = active ? 0 : 1;
d3.select("#line_" + d.key).style("opacity", opacity);
d.active = active;
})
.text(d.key);
});
My dates are in yyyy-mm-dd HH format and what I am trying to accomplish is this for example:
- "Time": "2017-04-02 16" converted to 'April 02' on the x axis and have the hour (HH) just displayed as a tool tip...etc
Here is a jsfiddle link https://jsfiddle.net/rsov2s2s/Any help is appreciated.
In your data objects, Time
is only a string. Thus, you`ll have to parse it into an actual date:
data.forEach(function(d){
d.Time = d3.timeParse("%Y-%m-%d %H")(d.Time)
});
In this function, d3.timeParse
uses "%Y-%m-%d %H"
as a specifier, which matches the structure of your strings.
After that, don't forget to change the xScale from scaleLinear
to scaleTime
.
Here is your code with those changes only:
var data = [{
"Brand": "Toyota",
"Count": 1800,
"Time": "2017-04-02 16"
}, {
"Brand": "Toyota",
"Count": 1172,
"Time": "2017-04-02 17"
}, {
"Brand": "Toyota",
"Count": 2000,
"Time": "2017-04-02 18"
}, {
"Brand": "Honda",
"Count": 8765,
"Time": "2017-04-02 16"
}, {
"Brand": "Honda",
"Count": 3445,
"Time": "2017-04-02 17"
}, {
"Brand": "Honda",
"Count": 1232,
"Time": "2017-04-02 18"
}];
data.forEach(function(d) {
d.Time = d3.timeParse("%Y-%m-%d %H")(d.Time)
});
var dataGroup = d3.nest() //d3 method that groups data by Brand
.key(function(d) {
return d.Brand;
})
.entries(data);
//var color = d3.scale.category10();
var vis = d3.select("#visualisation"),
WIDTH = 1000,
HEIGHT = 500,
MARGINS = {
top: 50,
right: 20,
bottom: 50,
left: 50
},
xScale = d3.scaleTime().range([MARGINS.left, WIDTH - MARGINS.right]).domain([d3.min(data, function(d) { //set up x-axis based on data
return d.Time;
}), d3.max(data, function(d) {
return d.Time;
})]),
yScale = d3.scaleLinear().range([HEIGHT - MARGINS.top, MARGINS.bottom]).domain([d3.min(data, function(d) { //set up y-axis based on data
return d.Count;
}), d3.max(data, function(d) {
return d.Count;
})]),
xAxis = d3.axisBottom()
.scale(xScale),
yAxis = d3.axisLeft()
.scale(yScale)
vis.append("svg:g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (HEIGHT - MARGINS.bottom) + ")")
.call(xAxis);
vis.append("svg:g")
.attr("class", "y axis")
.attr("transform", "translate(" + (MARGINS.left) + ",0)")
.call(yAxis);
var lineGen = d3.line()
.x(function(d) {
return xScale(d.Time);
})
.y(function(d) {
return yScale(d.Count);
})
.curve(d3.curveBasis);
dataGroup.forEach(function(d, i) { //iterate over the dataGroup and create line graph for each brand
vis.append('svg:path')
.attr('d', lineGen(d.values))
.attr('stroke', function(d, j) {
return "hsl(" + Math.random() * 360 + ",100%,50%)"; //random color for each brand line on graph
})
.attr('stroke-width', 2)
.attr('id', 'line_' + d.key)
.attr('fill', 'none');
lSpace = WIDTH / dataGroup.length; //define the legend space based on number of brands
vis.append("text")
.attr("x", (lSpace / 2) + i * lSpace)
.attr("y", HEIGHT)
.style("fill", "black")
.attr("class", "legend")
.on('click', function() {
var active = d.active ? false : true;
var opacity = active ? 0 : 1;
d3.select("#line_" + d.key).style("opacity", opacity);
d.active = active;
})
.text(d.key);
});
.axis path {
fill: none;
stroke: #777;
shape-rendering: crispEdges;
}
.axis text {
font-family: Lato;
font-size: 13px;
}
.legend {
font-size: 14px;
font-weight: bold;
cursor: pointer;
<title>D3 Test</title>
<script src="https://d3js.org/d3.v4.js"></script>
<body>
<svg id="visualisation" width="1000" height="600"></svg>
<script src="InitChart.js"></script>
</body>
这篇关于d3错误在x轴折线图上显示日期时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!