我正在尝试制作一个简单的网络应用/信息中心,显示从下拉列表中选择的特定学校的简单折线图。当您尝试切换回已经选择的学校时,它目前正常工作,除了。当发生这种情况时,线条会消失。我可以将数据打印到控制台。
更一般地说,我不确定我是以最好的方式构建这个。例如,update()函数是否真的包含在d3.json()方法中?
如果重要的话,我的数据是由Django视图返回的,该视图发送带有所有学校数据的JsonResponse(即对d3进行特定学校的数据过滤,而不是Django。再次,是这是接近这个的正确方法吗?)
// set the dimensions and margins of the graph
var margin = {top: 20, right: 20, bottom: 30, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var parseDate = d3.timeParse("%Y-%y"); // for dates like "2016-17"
// set the ranges
var x = d3.scaleTime().range([0, width]);
var y = d3.scaleLinear().range([height, 0]);
// define the line
var projection_line = d3.line()
.x(function(d) { return x(d.year_short_format); })
.y(function(d) { return y(d.projection); });
// append the svg object to the graph div
var svg = d3.select("#graph").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 + ")");
// get the json url
var url = "{% url "schoolview:all_schools_enrollments_by_school_and_year" %}";
d3.json(url, function(error, dataInput) {
if (error) throw error;
// when a new school is selected, trigger update
d3.selectAll("#school_select").on("change", update);
var school_index = document.getElementById('school_select').selectedIndex;
var selected_school = document.getElementById('school_select')[school_index].value;
// filter data to the selected school
data = dataInput.filter(function (d) { return d.school_name == selected_school });
// format the data
data.forEach(function(d) {
d.year_short_format = parseDate(d.year_short_format);
});
// scale the domain of the data
x.domain(d3.extent(data, function(d) { return d.year_short_format; }));
y.domain([0, d3.max(data, function(d) { return d.projection; })])
// append the line path
svg.append("path")
.data([data])
.attr("class", "line")
.attr("d", projection_line)
// append the x-axis
svg.append("g")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
// append the y-axis
svg.append("g")
.call(d3.axisLeft(y));
function update() {
var school_index = document.getElementById('school_select').selectedIndex;
var selected_school = document.getElementById('school_select')[school_index].value;
// filter data to the selected school
data = dataInput.filter(function (d) { return d.school_name == selected_school });
console.log(data);
// format the data
data.forEach(function(d) {
d.year_short_format = parseDate(d.year_short_format);
});
var svg = d3.select("#graph").transition();
// append the line path
svg.select(".line")
.duration(750)
.attr("d", projection_line(data));
// append the x-axis
svg.select(".x.axis") // change the x axis
.duration(750)
.call(d3.axisBottom(x));
// append the y-axis
svg.select(".y.axis") // change the x axis
.duration(750)
.call(d3.axisBottom(y));
}
});
答案 0 :(得分:0)
我想通了,所以对于遇到类似问题的人来说:
在update()
函数中,我再次解析每个数据对象的日期字段。但是,在第一次显示数据时,该字段已经被解析和覆盖 - 错误来自将已经解析的字段传递给我的parseDate()
函数。因此解决方案是:在解析数据时,不要覆盖该字段。
// format the data
data.forEach(function(d) {
d.parsed_date = parseDate(d.year_short_format);
});
或者,您可以在最初解析数据,然后再不用担心它。