我想重现一个动画多系列折线图。
代码如下,
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 12px Helvetica;
}
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
.line {
fill: none;
stroke: steelblue;
stroke-width: 2px;
}
</style>
<body>
<script src="https://d3js.org/d3.v3.js"></script>
<script>
var margin = {top: 20, right: 50, bottom: 30, left: 50},
width = 630 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
var parseDate = d3.time.format("%Y-%m-%d").parse;
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.category10();
var xAxis = d3.svg.axis()
.scale(x)
.ticks(5)
.innerTickSize(15)
.outerTickSize(0)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.tickFormat(function(d) { return d + "%";})
.ticks(5)
.innerTickSize(15)
.outerTickSize(0)
.orient("left");
var line = d3.svg.line()
.interpolate("basis")
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.price); });
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
d3.csv('http://localhost:8000/Desktop/Dat/data.csv', function(error, data) {
color.domain(d3.keys(data[0]).filter(function(key) { return key !== "date"; }));
data.forEach(function(d) {
d.date = parseDate(d.date);
});
var companies = color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {date: d.date, price: +d[name]};
})
};
});
x.domain(d3.extent(data, function(d) { return d.date; }));
y.domain([
d3.min(companies, function(c) { return d3.min(c.values, function(v) { return v.price; }); }),
d3.max(companies, function(c) { return d3.max(c.values, function(v) { return v.price; }); })
]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
svg.append("line")
.attr(
{
"class":"horizontalGrid",
"x1" : 0,
"x2" : width,
"y1" : y(0),
"y2" : y(0),
"fill" : "none",
"shape-rendering" : "crispEdges",
"stroke" : "black",
"stroke-width" : "1px",
"stroke-dasharray": ("3, 3")
});
var company = svg.selectAll(".company")
.data(companies)
.enter().append("g")
.attr("class", "company");
var path = svg.selectAll(".company").append("path")
.attr("class", "line")
.attr("d", function(d) { return line(d.values); })
.style("stroke", function(d) { if (d.name == "Airbus")
{return "rgb(000,255,000)"}
else {return "#000";}
});
//var totalLength = path.node().getTotalLength();
/*
console.log(path);
console.log(path.node());
console.log(path[0][0]);
console.log(path[0][1]);
*/
var totalLength = [path[0][0].getTotalLength(), path[0][1].getTotalLength()];
console.log(totalLength);
d3.select(path[0][0])
.attr("stroke-dasharray", totalLength[0] + " " + totalLength[0] )
.attr("stroke-dashoffset", totalLength[0])
.transition()
.duration(15000)
.ease("linear")
.attr("stroke-dashoffset", 0);
d3.select(path[0][1])
.attr("stroke-dasharray", totalLength[1] + " " + totalLength[1] )
.attr("stroke-dashoffset", totalLength[1])
.transition()
.duration(15000)
.ease("linear")
.attr("stroke-dashoffset", 0);
});
</script>
使用此处的数据,效果良好https://www.kaggle.com/dataset/465051e62819ab5a9903eb1658c33492adc374f4075504f10c24307505cb4e55
注意:这是这个例子的复制品http://bl.ocks.org/atmccann/8966400
我想要使用该数据来再现相同的图表<www.kaggle.com/dataset/43c2b3bb5741cb8ebdcedf4fcef4fcd73beb72513d17a29cb081025d41176c7>
我得到了这个:
Error: <path> attribute d: Expected number, "MNaN,344.43863848…".
我试图格式化我的第二个数据,使其与第一个数据完全相似,即将第一个数据重命名为"Airbus"one_answers"Boeing"列,但仍不断出现错误。
添加了带有伪数据集的代码。数据集的形状与您指定的形状相似。您只需要按照您给出的示例中显示的方式使用它。
你需要做的两个改变:
-
更改日期解析。替换为以下行:
var parseDate = d3.time.format("%d/%m/%Y").parse
-
使用不同的逻辑着色,因为我们有更多的国家数据。
var path = svg.selectAll(".company").append("path") .attr("class", "line") .attr("d", function(d) { return line(d.values); }) .style("stroke", function(d) { return color(d.name) });
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 12px Helvetica;
}
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.x.axis path {
display: none;
}
.line {
fill: none;
stroke: steelblue;
stroke-width: 2px;
}
</style>
<body>
<script src="https://d3js.org/d3.v3.js"></script>
<script>
var margin = {
top: 20,
right: 50,
bottom: 30,
left: 50
},
width = 630 - margin.left - margin.right,
height = 400 - margin.top - margin.bottom;
debugger;
var parseDate = d3.time.format("%d/%m/%Y").parse;
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.category10();
var xAxis = d3.svg.axis()
.scale(x)
.ticks(5)
.innerTickSize(15)
.outerTickSize(0)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(y)
.tickFormat(function(d) {
return d + "%";
})
.ticks(5)
.innerTickSize(15)
.outerTickSize(0)
.orient("left");
var line = d3.svg.line()
.interpolate("basis")
.x(function(d) {
return x(d.date);
})
.y(function(d) {
return y(d.price);
});
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
data = [{
date: '1/31/1995',
Austria: '23',
Belgium: '14',
Bulgaria: '-96',
},
{
date: '1/31/1996',
Austria: '-23',
Belgium: '114',
Bulgaria: '50',
},
{
date: '1/31/1997',
Austria: '27',
Belgium: '-14',
Bulgaria: '96',
},
]
color.domain(d3.keys(data[0]).filter(function(key) {
return key !== "date";
}));
data.forEach(function(d) {
d.date = parseDate(d.date);
});
var companies = color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {
date: d.date,
price: +d[name]
};
})
};
});
x.domain(d3.extent(data, function(d) {
return d.date;
}));
y.domain([
d3.min(companies, function(c) {
return d3.min(c.values, function(v) {
return v.price;
});
}),
d3.max(companies, function(c) {
return d3.max(c.values, function(v) {
return v.price;
});
})
]);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis);
svg.append("g")
.attr("class", "y axis")
.call(yAxis);
svg.append("line")
.attr({
"class": "horizontalGrid",
"x1": 0,
"x2": width,
"y1": y(0),
"y2": y(0),
"fill": "none",
"shape-rendering": "crispEdges",
"stroke": "black",
"stroke-width": "1px",
"stroke-dasharray": ("3, 3")
});
var company = svg.selectAll(".company")
.data(companies)
.enter().append("g")
.attr("class", "company");
var path = svg.selectAll(".company").append("path")
.attr("class", "line")
.attr("d", function(d) {
return line(d.values);
})
.style("stroke", function(d) {
return color(d.name)
});
var totalLength = path.node().getTotalLength();
d3.select(path[0][0])
.attr("stroke-dasharray", totalLength[0] + " " + totalLength[0])
.attr("stroke-dashoffset", totalLength[0])
.transition()
.duration(5000)
.ease("linear")
.attr("stroke-dashoffset", 0);
d3.select(path[0][1])
.attr("stroke-dasharray", totalLength[1] + " " + totalLength[1])
.attr("stroke-dashoffset", totalLength[1])
.transition()
.duration(5000)
.ease("linear")
.attr("stroke-dashoffset", 0);
</script>