我正在创建一个时间轴折线图,显示5或6个不同的线条,并希望能够放大和滚动(一旦缩放)。我使用了一些使用面积图的例子,但出于某种原因,当我第一次缩放时,我的折线图向右跳转,我将一些数据丢失到右边(我无法滚动查看它或在缩放时看到它完全出局)。当我缩放或滚动时,线条也会出现在y轴上。
我已将其复制到JSFiddle(see here),并使用我图表中其中一行的数据集。一旦使用缩放功能,为什么线条会向右跳?如何阻止线出现在y轴上?
如果你想在这里阅读,那么这是我的版本的JS:
function drawTimeline() {
var margin = {top: 10, right: 0, bottom: 50, left: 60}
var width = d3.select('#timeline').node().getBoundingClientRect().width/3*2;
var height = 300;
var svg = d3.select("#timeline").append("svg")
.attr("width", width)
.attr("height", height+margin.top+margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.attr("width", width - margin.left - margin.right)
.call(d3.zoom()
// .extent()
.scaleExtent([1, 10])
.translateExtent([[0, -Infinity], [width - margin.left - margin.right, Infinity]])
.on("zoom", zoom)
);
var view = svg.append("rect")
.attr("class", "view")
.attr("width", width - margin.left - margin.right)
.attr("height", height)
.attr("fill", "white");
var x = d3.scaleTime()
.domain([
d3.min(poll_data[0].avgpolls, function(p) { return p.date; }),
d3.max(poll_data[0].avgpolls, function(p) { return p.date; })
])
.range([0, width - margin.left - margin.right]);
var y = d3.scaleLinear()
.domain([50, 0])
.range([0, height]);
var xAxis = d3.axisBottom(x);
var yAxis = d3.axisLeft(y);
var gX = svg.append("g")
.attr("class", "axis xaxis")
.attr("transform", "translate(0," + height + ")")
.call(d3.axisBottom(x));
var gY = svg.append("g")
.attr("class", "axis yaxis")
.call(yAxis);
//All lines are drawn in the same way (x and y points)
var line = d3.line()
.x(function(d) { return x(d.date); })
.y(function(d) { return y(d.poll); });
//selectAll allows us to create and manipulate multiple groups at once
var party = svg.selectAll(".party")
.data(poll_data)
.enter()
.append("g")
.attr("class", "party");
//Add path to every country group at once
var pollPaths = party.append("path")
.attr("class", "line")
.attr("d", function(d) { return line(d.avgpolls); })
.attr("fill", "none")
.attr("stroke-width", 2)
.style("stroke", function(d) { return returnPartyColour(d.party); });
function zoom() {
console.log("zooming: " + d3.event.transform);
var new_x = d3.event.transform.rescaleX(x);
gX.call(d3.axisBottom(new_x));
//view.attr("transform", d3.event.transform);
//Redraw lines
//pollPaths.select(".line").attr("d", function(d) { return line(d.avgpolls); });
var newline = d3.line()
.x(function(d) { return new_x(d.date); })
.y(function(d) { return y(d.poll); });
pollPaths.attr("d", function(d) { return line(d.avgpolls); });
}
}
数据在我的版本中格式如下,但不是JSFiddle:
poll_data = [
{
'party' : 'Party 1',
'avgpolls' : [
{'date' : new Date(year, month, day), 'poll' : 0, },
],
]
由于
答案 0 :(得分:1)
解决这些问题需要两件事。
线条在缩放时跳跃的原因是因为未设置缩放范围。这已设置并且translateExtent的值已更新:
d3.zoom()
.scaleExtent([1, 10])
.translateExtent([[0, 0], [width - margin.left - margin.right, Infinity]])
.extent([[0, 0], [width - margin.left - margin.right, height]])
.on("zoom", zoom)
要防止路径溢出剪切路径。在创建svg之后,在添加其他元素之前,我添加了一个剪辑路径,如下所示:
svg.append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
//Same dimensions as the area for the lines to appear
.attr("width", width - margin.left - margin.right)
.attr("height", height);
然后必须将其添加到每条路径中。
var pollPaths = party.append("path")
...
.attr("clip-path", "url(#clip)");
最初的JSFiddle已updated反映这些变化。