【问题标题】:How to transition line graph in d3.js ver4 when triggered by selection from dropdown list当从下拉列表中选择触发时如何在 d3.js ver4 中转换折线图
【发布时间】:2017-11-12 01:39:19
【问题描述】:

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

更一般地说,我不确定我是否以最佳方式构建此结构。例如,update() 函数真的应该封装在 d3.json() 方法中吗?

如果重要的话,我的数据将由 Django 视图返回,该视图发送带有 all 学校数据的 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));
	}
});

【问题讨论】:

    标签: javascript django d3.js transition


    【解决方案1】:

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

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

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

    或者,您可以先解析一次数据,然后再不用担心。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-25
      • 2015-06-24
      • 2019-06-24
      • 1970-01-01
      • 1970-01-01
      • 2016-07-19
      • 1970-01-01
      相关资源
      最近更新 更多