当从下拉列表中选择触发时,如何在d3.js ver4中转换折线图

时间:2017-06-09 23:25:07

标签: javascript django d3.js transition

我正在尝试制作一个简单的网络应用/信息中心,显示从下拉列表中选择的特定学校的简单折线图。当您尝试切换回已经选择的学校时,它目前正常工作,除了。当发生这种情况时,线条会消失。我可以将数据打印到控制台。

更一般地说,我不确定我是以最好的方式构建这个。例如,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));
	}
});

1 个答案:

答案 0 :(得分:0)

我想通了,所以对于遇到类似问题的人来说:

update()函数中,我再次解析每个数据对象的日期字段。但是,在第一次显示数据时,该字段已经被解析和覆盖 - 错误来自将已经解析的字段传递给我的parseDate()函数。因此解决方案是:在解析数据时,不要覆盖该字段。

// format the data
data.forEach(function(d) {
    d.parsed_date = parseDate(d.year_short_format);
});

或者,您可以在最初解析数据,然后再不用担心它。