标记节点导致 D3JS 中的缩放故障
Labelling nodes in causes zooming glitch in D3JS
我是 d3js 的新手,在缩放方面遇到了一些问题。
在网上玩了一些示例代码后,我能够制作一个只有圆圈的时间轴,轴可以放大和缩小。但是,当我尝试向这些圈子添加标签时,缩放功能要么停止工作,要么这些圈子更新了它们的位置,但旧的圈子永远不会离开时间轴。因此,我怀疑我的问题与退出选择有关,无法识别要删除的 g 元素(我将圆圈和标签元素存储在一起)。
阅读文档和一些选择教程后,我仍然无法确定导致问题的原因。请参阅下面的代码或 example fiddle:
var ex_chart = example();
var data = [];
data.push({
date: new Date(2016, 01, 07),
event: "School"
});
data.push({
date: new Date(2016, 01, 17),
event: "Lunch"
});
data.push({
date: new Date(2016, 01, 01),
event: "Movies"
});
data.push({
date: new Date(2016, 01, 30),
event: "Birthday"
});
d3.select('#chart')
.append("svg").attr("width", window.innerWidth).attr("height", window.innerHeight)
.datum(data).call(ex_chart);
function example() {
var svg;
var margin = {
top: 10,
bottom: 10,
left: 10,
right: 10
};
var width = 500;
var height = 50;
var xaxis = d3.svg.axis();
var yaxis = d3.svg.axis();
var xscale = d3.time.scale();
var yscale = d3.scale.linear();
var xyzoom = d3.behavior.zoom()
.x(xscale)
.on("zoom", draw);
function chart(selection) {
selection.each(function(data) {
svg = d3.select(this).selectAll('svg').data([data]);
svg.enter().append('svg');
var g = svg.append('g')
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
g.append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width - margin.left - margin.right)
.attr("height", height - margin.top - margin.bottom);
g.append("svg:rect")
.attr("class", "border")
.attr("width", width - margin.left - margin.right)
.attr("height", height - margin.top - margin.bottom)
.style("stroke", "black")
.style("fill", "none");
g.append("g").attr("class", "x axis")
.attr("transform", "translate(" + 0 + "," + (height - margin.top - margin.bottom) + ")");
g.append("g")
.attr("class", "scatter")
.attr("clip-path", "url(#clip)");
g
.append("svg:rect")
.attr("class", "zoom xy box")
.attr("width", width - margin.left - margin.right)
.attr("height", height - margin.top - margin.bottom)
.style("visibility", "hidden")
.attr("pointer-events", "all")
.call(xyzoom);
var mindate = new Date(2016, 01, 1),
maxdate = new Date(2016, 01, 31);
xscale.domain([mindate, maxdate])
.range([0, width - margin.left - margin.right]);
xaxis.scale(xscale)
.orient('bottom')
.tickPadding(10);
svg.select('g.x.axis').call(xaxis);
svg.select('g.y.axis').call(yaxis);
draw();
});
return chart;
}
function update() {
var gs = svg.select("g.scatter");
var container = gs.selectAll("g")
.data(function(d) {
return d;
});
var gnode = container.enter().append("g");
gnode.append("circle")
.attr("class", "points")
.style("fill", "steelblue")
.attr("cx", function(d) {
return xscale(d.date);
})
.attr("cy", 10)
.attr("r", 10);
gnode.append("text")
.attr("dx", function(d) {
return xscale(d.date)
})
.attr("dy", 5)
.text(function(d) {
return d.event[0]
});
container.exit().remove();
}
function zoom_update() {
xyzoom = d3.behavior.zoom()
.x(xscale)
.on("zoom", draw);
svg.select('rect.zoom.xy.box').call(xyzoom);
}
function draw() {
update();
zoom_update();
};
return chart;
}
解决了!更新 x 坐标的责任应该交给更新选择,但发布的代码中没有此功能。例如:
container.selectAll("circle") .attr("cx", function(d) {
return xscale(d.date);
更新功能需要。如果有更好的解决方案,请告诉我
我是 d3js 的新手,在缩放方面遇到了一些问题。
在网上玩了一些示例代码后,我能够制作一个只有圆圈的时间轴,轴可以放大和缩小。但是,当我尝试向这些圈子添加标签时,缩放功能要么停止工作,要么这些圈子更新了它们的位置,但旧的圈子永远不会离开时间轴。因此,我怀疑我的问题与退出选择有关,无法识别要删除的 g 元素(我将圆圈和标签元素存储在一起)。
阅读文档和一些选择教程后,我仍然无法确定导致问题的原因。请参阅下面的代码或 example fiddle:
var ex_chart = example();
var data = [];
data.push({
date: new Date(2016, 01, 07),
event: "School"
});
data.push({
date: new Date(2016, 01, 17),
event: "Lunch"
});
data.push({
date: new Date(2016, 01, 01),
event: "Movies"
});
data.push({
date: new Date(2016, 01, 30),
event: "Birthday"
});
d3.select('#chart')
.append("svg").attr("width", window.innerWidth).attr("height", window.innerHeight)
.datum(data).call(ex_chart);
function example() {
var svg;
var margin = {
top: 10,
bottom: 10,
left: 10,
right: 10
};
var width = 500;
var height = 50;
var xaxis = d3.svg.axis();
var yaxis = d3.svg.axis();
var xscale = d3.time.scale();
var yscale = d3.scale.linear();
var xyzoom = d3.behavior.zoom()
.x(xscale)
.on("zoom", draw);
function chart(selection) {
selection.each(function(data) {
svg = d3.select(this).selectAll('svg').data([data]);
svg.enter().append('svg');
var g = svg.append('g')
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
g.append("defs").append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width - margin.left - margin.right)
.attr("height", height - margin.top - margin.bottom);
g.append("svg:rect")
.attr("class", "border")
.attr("width", width - margin.left - margin.right)
.attr("height", height - margin.top - margin.bottom)
.style("stroke", "black")
.style("fill", "none");
g.append("g").attr("class", "x axis")
.attr("transform", "translate(" + 0 + "," + (height - margin.top - margin.bottom) + ")");
g.append("g")
.attr("class", "scatter")
.attr("clip-path", "url(#clip)");
g
.append("svg:rect")
.attr("class", "zoom xy box")
.attr("width", width - margin.left - margin.right)
.attr("height", height - margin.top - margin.bottom)
.style("visibility", "hidden")
.attr("pointer-events", "all")
.call(xyzoom);
var mindate = new Date(2016, 01, 1),
maxdate = new Date(2016, 01, 31);
xscale.domain([mindate, maxdate])
.range([0, width - margin.left - margin.right]);
xaxis.scale(xscale)
.orient('bottom')
.tickPadding(10);
svg.select('g.x.axis').call(xaxis);
svg.select('g.y.axis').call(yaxis);
draw();
});
return chart;
}
function update() {
var gs = svg.select("g.scatter");
var container = gs.selectAll("g")
.data(function(d) {
return d;
});
var gnode = container.enter().append("g");
gnode.append("circle")
.attr("class", "points")
.style("fill", "steelblue")
.attr("cx", function(d) {
return xscale(d.date);
})
.attr("cy", 10)
.attr("r", 10);
gnode.append("text")
.attr("dx", function(d) {
return xscale(d.date)
})
.attr("dy", 5)
.text(function(d) {
return d.event[0]
});
container.exit().remove();
}
function zoom_update() {
xyzoom = d3.behavior.zoom()
.x(xscale)
.on("zoom", draw);
svg.select('rect.zoom.xy.box').call(xyzoom);
}
function draw() {
update();
zoom_update();
};
return chart;
}
解决了!更新 x 坐标的责任应该交给更新选择,但发布的代码中没有此功能。例如:
container.selectAll("circle") .attr("cx", function(d) {
return xscale(d.date);
更新功能需要。如果有更好的解决方案,请告诉我