gpt4 book ai didi

javascript - 在调整大小时重新创建 D3 多线图表(响应式)

转载 作者:行者123 更新时间:2023-12-03 00:39:02 26 4
gpt4 key购买 nike

为了获得响应式 D3 多线图表,我添加了调整大小函数,但尽管调用了该函数,但它似乎不起作用:

  var data = [{
Date: "2016-10-10",
ValueOne: 1,
ValueTwo: 0
}, {
Date: "2016-10-17",
ValueOne: 23,
ValueTwo: 2
}, {
Date: "2016-10-24",
ValueOne: 32,
ValueTwo: 17
}, {
Date: "2016-10-31",
ValueOne: 57,
ValueTwo: 40
}, {
Date: "2016-11-07",
ValueOne: 74,
ValueTwo: 56
}];


var margin = {top: 10, right: 50, bottom: 100, left: 50},
// Set default width and height
widther = (window.innerWidth),
width = widther - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;


// Determine current size, which determines vars
function set_vars() {

var width = window.innerWidth - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;

}

function drawGraphic() {

var svg = d3.select('#charts')
.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 + ")");

//Parses date for correct time format
var formatTime = d3.timeFormat("%Y-%m-%d");

data.forEach(function(d) {
d.Date = new Date(d.Date)
});

var valueOneData = data.map(function(d) {
return {
date: d.Date,
value: d.ValueOne
}
});

var valueTwoData = data.map(function(d) {
return {
date: d.Date,
value: d.ValueTwo
}
});

var xScale = d3.scaleTime()
.range([0, width])
.domain(d3.extent(data, function(d) {
return d.Date
}));

var yScale = d3.scaleLinear()
.range([height, 0])
.domain([0, d3.max(data, function(d) {
return d.ValueOne
}) * 1.05]);

var lineGenerator = d3.line()
.x(function(d) {
return xScale(d.date)
})
.y(function(d) {
return yScale(d.value)
});

var gX = svg.append("g")
.attr("transform", `translate(0,${height})`)
.call(d3.axisBottom(xScale).tickFormat(function(d) {
return formatTime(d)
}).tickValues(data.map(function(d) {
return d.Date
})))
.selectAll("text")
.style("text-anchor", "end")
.attr("transform", "rotate(-65)")
.attr("y", 4)
.attr("x", -10)
.attr("dy", ".35em");

var gY = svg.append("g")
.call(d3.axisLeft(yScale));

var valueOneLine = svg.append("path")
.datum(valueOneData)
.attr("d", lineGenerator)
.style("fill", "none")
.style("stroke", "#124");

var valueTwoLine = svg.append("path")
.datum(valueTwoData)
.attr("d", lineGenerator)
.style("fill", "none")
.style("stroke", "#c7003b");

//RESPONSIVENESS ATTEMPT NO1
d3.select(window).on("resize", resized);

}

//Resize function
function resized() {
d3.select("svg").remove();
set_vars();
drawGraphic();
console.log("FUNCTION IS BEING CALLED")
}

set_vars();
drawGraphic();

//RESPONSIVENESS ATTEMPT NO2
window.addEventListener("resize", function(){ d3.select("svg").remove(); set_vars(); drawGraphic(); });
<script src="https://d3js.org/d3.v4.min.js"></script>
<div id="charts"></div>

在代码片段中,我尝试了两种方法来做到这一点。它们都不能从头开始重新创建图表。同样的问题也适用于此 jsfiddle .

最佳答案

问题在于每次调整窗口大小时都会解析数据。

由于数据中的日期是第一次解析,因此每次调用parseDate(d.date)都会失败,因为它已经被解析为有效的日期日期。你明白了吗?

因此,移动解析代码,使其仅执行一次:

// parse data just once
data.forEach(function(d) {
d.date = parseDate(d.date);
d.value = +d.value;
});

fiddle 链接:https://jsfiddle.net/a5rqt0L1/

建议:我觉得这不是制作响应式图表的正确方法,即删除 SVG 并重新附加到正文,并多次完成所有配置。我的做法如下:

  1. 解析数据,附加 svg 的初始高度和宽度,附加 X、Y 轴仅一次,但将 drawBars(用于绘制实际条形)移动到单独的函数它将使用 d3 自己的进入、退出和更新选择逻辑。
  2. 在调整窗口大小时,只需更改 SVG 的高度和宽度,通过 .call(xAxis)... 重新渲染轴,然后调用 drawBars 函数即可。

希望这有帮助。

关于javascript - 在调整大小时重新创建 D3 多线图表(响应式),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53538658/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com