我正在使用此示例http://bl.ocks.org/mbostock/6123708
在这里我想在其中附加带有矩形(或任何形状)的g(组)标签,它应该是可拖动的,并且不希望松散svg的缩放和平移功能。
这是我的jsfiddle
拖动矩形时。由于缩放行为,整个svg正在平移。 所以如何拖动rect。用g标签。
var margin = {top: -5, right: -5, bottom: -5, left: -5},
width = 1260 - margin.left - margin.right,
height = 700 - margin.top - margin.bottom;
var zoom = d3.behavior.zoom()
.scaleExtent([1, 10])
.on("zoom", zoomed);
var drag = d3.behavior.drag()
.origin(function(d) { return d; })
//.inertia(true)
.on("dragstart", dragstarted)
.on("drag", dragged)
.on("dragend", dragended);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("id","my_svg")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.right + ")")
.call(zoom);
var rect = svg.append("rect")
.attr("width", width)
.attr("height", height)
.style("fill", "none")
.style("pointer-events", "all");
var x = d3.scale.linear()
.domain([-width / 2, width / 2])
.range([0, width]);
var y = d3.scale.linear()
.domain([-height / 2, height / 2])
.range([height, 0]);
var container = svg.append("g");
container.append("g")
.attr("class", "x axis")
.selectAll("line")
.data(d3.range(-1000, width, 10))
.enter().append("line")
.attr("x1", function(d) { return d; })
.attr("y1", -1000)
.attr("x2", function(d) { return d; })
.attr("y2", height);
container.append("g")
.attr("class", "y axis")
.selectAll("line")
.data(d3.range(-1000, height, 10))
.enter().append("line")
.attr("x1", -1000)
.attr("y1", function(d) { return d; })
.attr("x2", width)
.attr("y2", function(d) { return d; });
d3.tsv("https://dl.dropboxusercontent.com/u/14652161/dots.tsv", dottype, function(error, dots) {
dot = container.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.right + ")")
.attr("class", "dot")
.selectAll("circle")
.data(dots)
.enter().append("circle")
.attr("r", 5)
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; })
.call(drag);
});
// Add a new group to the canvas
var newGroup = container.append("svg:g")
.attr("transform", "translate(10, 10)")
.attr("id", "mygroup");
//add rect to the new group
var rect1 = newGroup.append("svg:rect")
.attr("rx", 6)
.attr("ry", 6)
.attr("x", 5/2)
.attr("y", 5/2)
.attr("id", "rect")
.attr("width", 250)
.attr("height", 125)
.style("fill", 'white')
.style("stroke", d3.scale.category20c())
.style('stroke-width', 5);
//drag the new group
var drag1 = d3.behavior.drag()
.origin(function() {
var t = d3.select(this);
console.log(this);
return {x: t.attr("x") + d3.transform(t.attr("transform")).translate[0],
y: t.attr("y") + d3.transform(t.attr("transform")).translate[1]};
})
.on("drag", function(d,i) {
//d3.event.sourceEvent.stopPropagation();
d3.select(this).attr("transform", function(d,i){
return "translate(" + [ d3.event.x,d3.event.y ] + ")"
})
});
newGroup.call(drag1);
d3.select("#zoomin").on("click", zoomIn);
d3.select("#zoomout").on("click", zoomOut);
function dottype(d) {
d.x = +d.x;
d.y = +d.y;
return d;
}
function zoomed() {
//console.log(d3.event.translate);
container.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
//container.attr("transform", "scale(" + d3.event.scale + ")");
}
function dragstarted(d) {
d3.event.sourceEvent.stopPropagation();
d3.select(this).classed("dragging", true);
}
function dragged(d) {
//console.log(d);
//console.log(this);
d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y);
}
function dragended(d) {
d3.select(this).classed("dragging", false);
}
var scale = 1;
function zoomIn() {
var svg = d3.select("body").select("svg");
var container = svg.select("g");
var h = svg.attr("height"), w = svg.attr("width");
// Note: works only on the <g> element and not on the <svg> element
// which is a common mistake
scale = scale + 0.1;
container.attr("transform",
"translate(" + w/2 + ", " + h/2 + ") " +
"scale(" + scale + ") " +
"translate(" + (-w/2) + ", " + (-h/2) + ")");
}
function zoomOut() {
var svg = d3.select("body").select("svg");
var container = svg.select("g");
var h = svg.attr("height"), w = svg.attr("width");
// Note: works only on the <g> element and not on the <svg> element
// which is a common mistake
scale = scale - 0.1;
container.attr("transform",
"translate(" + w/2 + ", " + h/2 + ") " +
"scale(" + scale + ") " +
"translate(" + (-w/2) + ", " + (-h/2) + ")");
}
答案 0 :(得分:0)
您必须stopPropagation
sourceEvent
dragstart
拖动行为事件才能使其正常工作。
//drag the new group
var drag1 = d3.behavior.drag()
.origin(function() {
var t = d3.select(this);
return {
x: t.attr("x") + d3.transform(t.attr("transform")).translate[0],
y: t.attr("y") + d3.transform(t.attr("transform")).translate[1]
};
})
.on("dragstart", function() { //Newly added code
d3.event.sourceEvent.stopPropagation();
})
.on("drag", function(d, i) {
d3.select(this).attr("transform", function(d, i) {
return "translate(" + [d3.event.x, d3.event.y] + ")"
})
});
以下是工作代码段。
var margin = {
top: -5,
right: -5,
bottom: -5,
left: -5
},
width = 1260 - margin.left - margin.right,
height = 700 - margin.top - margin.bottom;
var zoom = d3.behavior.zoom()
.scaleExtent([1, 10])
.on("zoom", zoomed);
var drag = d3.behavior.drag()
.origin(function(d) {
return d;
})
//.inertia(true)
.on("dragstart", dragstarted)
.on("drag", dragged)
.on("dragend", dragended);
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("id", "my_svg")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.right + ")")
.call(zoom);
var rect = svg.append("rect")
.attr("width", width)
.attr("height", height)
.style("fill", "none")
.style("pointer-events", "all");
var x = d3.scale.linear()
.domain([-width / 2, width / 2])
.range([0, width]);
var y = d3.scale.linear()
.domain([-height / 2, height / 2])
.range([height, 0]);
var container = svg.append("g");
container.append("g")
.attr("class", "x axis")
.selectAll("line")
.data(d3.range(-1000, width, 10))
.enter().append("line")
.attr("x1", function(d) {
return d;
})
.attr("y1", -1000)
.attr("x2", function(d) {
return d;
})
.attr("y2", height);
container.append("g")
.attr("class", "y axis")
.selectAll("line")
.data(d3.range(-1000, height, 10))
.enter().append("line")
.attr("x1", -1000)
.attr("y1", function(d) {
return d;
})
.attr("x2", width)
.attr("y2", function(d) {
return d;
});
d3.tsv("https://dl.dropboxusercontent.com/u/14652161/dots.tsv", dottype, function(error, dots) {
dot = container.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.right + ")")
.attr("class", "dot")
.selectAll("circle")
.data(dots)
.enter().append("circle")
.attr("r", 5)
.attr("cx", function(d) {
return d.x;
})
.attr("cy", function(d) {
return d.y;
})
.call(drag);
});
// Add a new group to the canvas
var group = container.append("svg:g")
.attr("transform", "translate(10, 10)")
.attr("id", "mygroup");
//add rect to the new group
var rect1 = group.append("svg:rect")
.attr("rx", 6)
.attr("ry", 6)
.attr("x", 5 / 2)
.attr("y", 5 / 2)
.attr("id", "rect")
.attr("width", 250)
.attr("height", 125)
.style("fill", 'white')
.style("stroke", d3.scale.category20c())
.style('stroke-width', 5);
//drag the new group
var drag1 = d3.behavior.drag()
.origin(function() {
var t = d3.select(this);
console.log(this);
return {
x: t.attr("x") + d3.transform(t.attr("transform")).translate[0],
y: t.attr("y") + d3.transform(t.attr("transform")).translate[1]
};
})
.on("dragstart", function() {
d3.event.sourceEvent.stopPropagation();
})
.on("drag", function(d, i) {
d3.select(this).attr("transform", function(d, i) {
return "translate(" + [d3.event.x, d3.event.y] + ")"
})
});
group.call(drag1);
d3.select("#zoomin").on("click", zoomIn);
d3.select("#zoomout").on("click", zoomOut);
function dottype(d) {
d.x = +d.x;
d.y = +d.y;
return d;
}
function zoomed() {
//console.log(d3.event.translate);
container.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
//container.attr("transform", "scale(" + d3.event.scale + ")");
}
function dragstarted(d) {
d3.event.sourceEvent.stopPropagation();
d3.select(this).classed("dragging", true);
}
function dragged(d) {
//console.log(d);
//console.log(this);
d3.select(this).attr("cx", d.x = d3.event.x).attr("cy", d.y = d3.event.y);
}
function dragended(d) {
d3.select(this).classed("dragging", false);
}
var scale = 1;
function zoomIn() {
var svg = d3.select("body").select("svg");
var container = svg.select("g");
var h = svg.attr("height"),
w = svg.attr("width");
// Note: works only on the <g> element and not on the <svg> element
// which is a common mistake
scale = scale + 0.1;
container.attr("transform",
"translate(" + w / 2 + ", " + h / 2 + ") " +
"scale(" + scale + ") " +
"translate(" + (-w / 2) + ", " + (-h / 2) + ")");
}
function zoomOut() {
var svg = d3.select("body").select("svg");
var container = svg.select("g");
var h = svg.attr("height"),
w = svg.attr("width");
// Note: works only on the <g> element and not on the <svg> element
// which is a common mistake
scale = scale - 0.1;
container.attr("transform",
"translate(" + w / 2 + ", " + h / 2 + ") " +
"scale(" + scale + ") " +
"translate(" + (-w / 2) + ", " + (-h / 2) + ")");
}
.dot circle {
fill: lightsteelblue;
stroke: steelblue;
stroke-width: 1.5px;
}
.dot circle.dragging {
fill: red;
stroke: brown;
}
.axis line {
fill: none;
stroke: #ddd;
shape-rendering: crispEdges;
vector-effect: non-scaling-stroke;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<body>
<button id="zoomin">Zoom In</button>
<button id="zoomout">Zoom Out</button>
</body>