我有两个问题,我正在努力理解或解决我的以下d3代码(显示最简单的问题版本)。背景是我试图从csv文件绘制线条(在末尾粘贴的整个内容和在下面运行的完整代码)。前两行(用于说明csv的格式)是:
date,cust,prod,units
2012-04-01,team1,A,34
基本上有客户(team1,team2,team3)购买产品单元(A,B,C,D)。我正在尝试绘制按产品(A,B,C,D)过滤的折线图。这个单独工作。但是,由于每个产品(A,B,C,D)的单位和日期范围不同,我首先尝试将我的范围固定为最大日期范围和最大销售量。当我这样做时,轴看起来正确但图形不会被绘制。如果我只使用过滤后的数据,图表就可以正常工作。我错过了什么?我没有在控制台中看到任何JS错误。我的下一个目标是添加和删除图表(通过复选框)而无需重新绘制任何内容,最简单的方法是什么?
<!DOCTYPE html>
<meta charset="utf-8">
<style> /* set the CSS */
#line1 {
fill: none;
stroke: steelblue;
stroke-width: 1px;
}
</style>
<div id="customer">
<input class="custCB" type="checkbox" id="D_CB" name="cust" value="D" enabled onclick="showGraph('D')"> D<br>
<input class="custCB" type="checkbox" id="C_cb" name="cust" value="C" enabled onclick="showGraph('C')"> C<br>
<input class="custCB" type="checkbox" id="B_cb" name="cust" value="B" enabled onclick="showGraph('B')"> B<br>
<input class="custCB" type="checkbox" id="A_cb" name="cust" value="A" enabled onclick="showGraph('A')"> A<br>
</div>
<body>
<!-- load the d3.js library -->
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
showGraph("D");
function showGraph(prod_name) {
var mydomain = 5000;
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
// parse the date / time
var parseTime = d3.timeParse("%Y-%m-%d");
// set the ranges
var x = d3.scaleTime().range([0, width]);
var y = d3.scaleLinear().domain([mydomain, 0]).range([height, 0]);
//console.log(y);
// define the 1st line
var valueline = d3.line()
.x(function (d) {
return x(d.date);
})
.y(function (d) {
return y(d.units);
});
d3.select("svg").remove();
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("id", "parentgroup")
.attr("transform",
"translate(" + margin.left + "," + margin.top + ")");
// Get the data
d3.csv("test2.csv", function (error, tdata) {
if (error) throw error;
data = tdata.filter(e=> e.prod===prod_name);
//_data = data.filter(e=> e.cust==="team2");
//console.log("__data_", _data);
// format the data
console.log("data:", data);
data.forEach(function (d) {
d.date = parseTime(d.date);
d.units = parseInt(d.units);
});
tdata.forEach(function (d) {
d.date = parseTime(d.date);
d.units = parseInt(d.units);
});
x.domain(d3.extent(tdata, function (d) {
console.log(d.date);
return d.date;
}));
//console.log("data", data);
var m = d3.max(tdata, function (d) {
console.log(d.units);
var m = parseInt(d.units);
return m;
});
console.log("Max:", m);
y.domain([0, m]);
console.log("tdata:", tdata);
//console.log("data:", data);
svg.append("path")
.data([data])
.attr("id", "line1")
.attr("d", valueline);
//console.log("DATA", data);
svg.selectAll(".point")
.data(data)
.enter()
.append("circle")
.attr("class", "point")
.attr("cx", function (d) {
return x(d.date);
})
.attr("cy", function (d) {
return y(d.units);
})
.attr("r", 4)
.on("mouseover", function (d) {
console.log(d.units)
});
svg.append("g")
.attr("id", "xaxis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// Add the Y Axis
svg.append("g")
.attr("id", "yaxis")
.call(d3.axisLeft(y));
});
}
</script>
</body>
test2.csv
date,cust,prod,units
2012-04-01,team1,A,34
2012-04-02,team1,B,45
2012-04-03,team2,D,67
2012-04-04,team1,A,78
2012-04-05,team3,C,89
2012-04-06,team2,D,99
2012-04-07,team2,A,101
2012-04-08,team3,A,122
2012-04-09,team1,C,134
2012-04-10,team1,C,160
2012-04-11,team2,C,180
2012-04-12,team2,D,210
2012-04-13,team3,D,223
2012-04-14,team1,D,229
2012-04-15,team1,D,241
2012-04-16,team2,D,258
2012-04-17,team2,C,350
2012-04-18,team3,D,305
2012-04-19,team3,B,335
2012-04-20,team2,B,375
2012-04-21,team3,D,345
2012-04-22,team1,A,534
2012-04-23,team1,C,578
2012-04-24,team2,A,590
2012-04-25,team1,B,601
2012-04-26,team3,B,387
2012-04-27,team2,C,613
2012-04-28,team2,D,645
2012-04-29,team3,D,410
2012-04-30,team1,A,612
2012-05-01,team2,A,670
2012-05-02,team3,A,657
2012-05-03,team1,A,690
2012-05-04,team3,A,709
2012-05-05,team2,C,690
2012-05-06,team3,B,740
2012-05-07,team1,A,1000
答案 0 :(得分:1)
此代码段存在问题:
data.forEach(function (d) {
d.date = parseTime(d.date);
d.units = parseInt(d.units);
});
tdata.forEach(function (d) {
d.date = parseTime(d.date);
d.units = parseInt(d.units);
});
tdata
和data
是将引用保存到相同对象的数组。所以第二个forEach
然后作用于相同的对象,parseTime
失败。只是做:
tdata.forEach(function(d) {
d.date = parseTime(d.date);
d.units = parseInt(d.units);
});
var data = tdata.filter(e => e.prod === prod_name);