使用更新功能重绘图形时出错
Error in redrawing graph with update function
我目前正在尝试在每次移动滑块时重新绘制和更新我的图表,这会将我的数据集过滤到该年份范围内。不幸的是,事情没有正常进行,我不确定我的错误在哪里。
当我尝试 运行 我的代码时出现此错误:
Error: Invalid value for <rect> attribute y="NaN"
Error: Invalid value for <rect> attribute height="NaN"
我完全迷路了,非常感谢任何帮助。
Link 我的 fiddle: http://jsfiddle.net/vyab4kcf/11/
你不应该这样做...
request_data = data;
而这一行指的是全局 year
而它应该是本地参数 sexYear
var yearData = data.filter(function (element) { return element.YEAR == year });
应该是
var yearData = data.filter(function (element) { return element.YEAR == sexYear });
此外,尝试 change
事件以及 input
以便它在 IE 中工作...
d3.select("#sexYear").on("change", function () {
update(+this.value);
});
this.value
在这里未定义,因为更新是用全局 this
context
调用的
function update(sexYear) {
console.log(this.value);
你应该阅读这两行并思考他们在做什么...
var ageNames = d3.keys(yearData[0]).filter(function (key) { return key !== "CAUSE"; });
var ageNames = d3.keys(yearData[0]).filter(function (key) { return key !== "YEAR"; });
我保证不是你想的那样
ageNames
是一个非常容易混淆的名称,例如应该是 seriesNames
。然后你可以这样实现...
var notSeriesNames = ['CAUSE', 'YEAR']
//...
var seriesNames = d3.keys(yearData[0]).filter(function (key) {
return notSeriesNames.every(function (e, i, i) { return key != e })
});
最后,您需要修复 UPDATE、ENTER、EXIT 结构。这是所有固定的功能...
window.onload = function () {
console.clear();
var margin = { top: 10, right: 10, bottom: 35, left: 30 },
width = 400 - margin.left - margin.right,
height = 150 - margin.top - margin.bottom;
var x0 = d3.scale.ordinal()
.rangeRoundBands([0, width], 0.1);
var x1 = d3.scale.ordinal();
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.ordinal()
.range(["#FD8C25", "#99ABC4"]);
var xAxis = d3.svg.axis()
.scale(x0)
.orient("bottom");
var year = 1979;
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(d3.format(".2s"));
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 + ")");
var request_data = d3.csv("http://www.sfu.ca/~gdwang/Sex.csv", function (error, data) {
d3.select("#sexYear").on("change", function () {
update(+this.value);
});
d3.select("#sexYear").on("input", function () {
update(+this.value);
});
update(year);
// update the year
function update(sexYear) {
var notSeriesNames = ['CAUSE', 'YEAR', 'series']
console.log('update ', sexYear);
// adjust the text on the year slider
d3.select("#sexYear-value").text(sexYear);
d3.select("#sexYear").property("value", sexYear);
var yearData = data.filter(function (element) { return element.YEAR == sexYear });
var seriesNames = d3.keys(yearData[0]).filter(function (key) {
return notSeriesNames.every(function (element, idnex, array) {
return key != element
})
});
yearData.forEach(function (d) {
d.series = seriesNames.map(function (name) { return { name: name, value: +d[name] }; });
});
x0.domain(yearData.map(function (d) { return d.CAUSE; }));
x1.domain(seriesNames).rangeRoundBands([0, x0.rangeBand()]);
y.domain([0, d3.max(yearData, function (d) { return d3.max(d.series, function (d) { return d.value; }); })]);
//Cause groups
//UPDATE
var causeUpdate = svg.selectAll(".CAUSE")
.data(yearData),
//ENTER ****native d3 SIDE EFFECT**** enter selection is added to update selection
causeEnter = causeUpdate.enter().append("g")
.attr("class", "CAUSE")
.attr("transform", function (d) { return "translate(" + x0(d.CAUSE) + ",0)"; }),
//EXIT
causeExit = causeUpdate.exit().remove(),
//Series groups
//UPDATE
seriesUpdate = causeUpdate.selectAll("rect")
.data(function (d) {
return d.series;
});
//ENTER ****native d3 SIDE EFFECT**** enter selection is added to update selection
seriesUpdate.enter().append("rect")
//UPDATE + ENTER
seriesUpdate.attr("width", x1.rangeBand())
.style("fill", function (d) {
return color(d.name);
})
.transition()
.attr("x", function (d) {
return x1(d.name);
})
.attr("y", function (d) {
return y(d.value);
})
.attr("height", function (d) {
return height - y(d.value);
})
//EXIT
seriesUpdate.exit().remove()
}
//draw the bars
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll('text')
.attr('transform', 'rotate(-15)')
.style('text-anchor', 'end');
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Potential Years Lost");
d3.selectAll(".tick > text")
.style("font-size", 6);
})
};
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.bar {
fill: steelblue;
}
.x.axis path {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="sexYear" style="display: inline-block; width: 200px; text-align: right">
Year = <span id="sexYear-value">…</span>
</label>
<input type="range" min="1979" max="1999" id="sexYear">
我目前正在尝试在每次移动滑块时重新绘制和更新我的图表,这会将我的数据集过滤到该年份范围内。不幸的是,事情没有正常进行,我不确定我的错误在哪里。
当我尝试 运行 我的代码时出现此错误:
Error: Invalid value for <rect> attribute y="NaN"
Error: Invalid value for <rect> attribute height="NaN"
我完全迷路了,非常感谢任何帮助。
Link 我的 fiddle: http://jsfiddle.net/vyab4kcf/11/
你不应该这样做...
request_data = data;
而这一行指的是全局 year
而它应该是本地参数 sexYear
var yearData = data.filter(function (element) { return element.YEAR == year });
应该是
var yearData = data.filter(function (element) { return element.YEAR == sexYear });
此外,尝试 change
事件以及 input
以便它在 IE 中工作...
d3.select("#sexYear").on("change", function () {
update(+this.value);
});
this.value
在这里未定义,因为更新是用全局 this
context
function update(sexYear) {
console.log(this.value);
你应该阅读这两行并思考他们在做什么...
var ageNames = d3.keys(yearData[0]).filter(function (key) { return key !== "CAUSE"; });
var ageNames = d3.keys(yearData[0]).filter(function (key) { return key !== "YEAR"; });
我保证不是你想的那样
ageNames
是一个非常容易混淆的名称,例如应该是 seriesNames
。然后你可以这样实现...
var notSeriesNames = ['CAUSE', 'YEAR']
//...
var seriesNames = d3.keys(yearData[0]).filter(function (key) {
return notSeriesNames.every(function (e, i, i) { return key != e })
});
最后,您需要修复 UPDATE、ENTER、EXIT 结构。这是所有固定的功能...
window.onload = function () {
console.clear();
var margin = { top: 10, right: 10, bottom: 35, left: 30 },
width = 400 - margin.left - margin.right,
height = 150 - margin.top - margin.bottom;
var x0 = d3.scale.ordinal()
.rangeRoundBands([0, width], 0.1);
var x1 = d3.scale.ordinal();
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.ordinal()
.range(["#FD8C25", "#99ABC4"]);
var xAxis = d3.svg.axis()
.scale(x0)
.orient("bottom");
var year = 1979;
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.tickFormat(d3.format(".2s"));
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 + ")");
var request_data = d3.csv("http://www.sfu.ca/~gdwang/Sex.csv", function (error, data) {
d3.select("#sexYear").on("change", function () {
update(+this.value);
});
d3.select("#sexYear").on("input", function () {
update(+this.value);
});
update(year);
// update the year
function update(sexYear) {
var notSeriesNames = ['CAUSE', 'YEAR', 'series']
console.log('update ', sexYear);
// adjust the text on the year slider
d3.select("#sexYear-value").text(sexYear);
d3.select("#sexYear").property("value", sexYear);
var yearData = data.filter(function (element) { return element.YEAR == sexYear });
var seriesNames = d3.keys(yearData[0]).filter(function (key) {
return notSeriesNames.every(function (element, idnex, array) {
return key != element
})
});
yearData.forEach(function (d) {
d.series = seriesNames.map(function (name) { return { name: name, value: +d[name] }; });
});
x0.domain(yearData.map(function (d) { return d.CAUSE; }));
x1.domain(seriesNames).rangeRoundBands([0, x0.rangeBand()]);
y.domain([0, d3.max(yearData, function (d) { return d3.max(d.series, function (d) { return d.value; }); })]);
//Cause groups
//UPDATE
var causeUpdate = svg.selectAll(".CAUSE")
.data(yearData),
//ENTER ****native d3 SIDE EFFECT**** enter selection is added to update selection
causeEnter = causeUpdate.enter().append("g")
.attr("class", "CAUSE")
.attr("transform", function (d) { return "translate(" + x0(d.CAUSE) + ",0)"; }),
//EXIT
causeExit = causeUpdate.exit().remove(),
//Series groups
//UPDATE
seriesUpdate = causeUpdate.selectAll("rect")
.data(function (d) {
return d.series;
});
//ENTER ****native d3 SIDE EFFECT**** enter selection is added to update selection
seriesUpdate.enter().append("rect")
//UPDATE + ENTER
seriesUpdate.attr("width", x1.rangeBand())
.style("fill", function (d) {
return color(d.name);
})
.transition()
.attr("x", function (d) {
return x1(d.name);
})
.attr("y", function (d) {
return y(d.value);
})
.attr("height", function (d) {
return height - y(d.value);
})
//EXIT
seriesUpdate.exit().remove()
}
//draw the bars
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis)
.selectAll('text')
.attr('transform', 'rotate(-15)')
.style('text-anchor', 'end');
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", ".71em")
.style("text-anchor", "end")
.text("Potential Years Lost");
d3.selectAll(".tick > text")
.style("font-size", 6);
})
};
body {
font: 10px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.bar {
fill: steelblue;
}
.x.axis path {
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label for="sexYear" style="display: inline-block; width: 200px; text-align: right">
Year = <span id="sexYear-value">…</span>
</label>
<input type="range" min="1979" max="1999" id="sexYear">