d3.js: 缩放拖拽失败
d3.js: zoom and drag failure
我正在使用 d3.js,但我遇到了问题。当我放大 SVG 时,不相称。另外,拖动后,我制作的 SVG 的处理;进一步漂流。我正在提供必要的代码。我该怎么做才能修复此代码?
代码:
/* Tünelin bütün elemanları için bir dizi oluşturuldu
Daha sonra her ayrı eleman için dizi oluşturulup,
datalar bu doğrultuda çekilecektir.
*/
var tunnelElements = new Array();
tunnelElements = [{ "x": 0, "y": 0, "radius": 10, "color" : "green" },
{ "x": 25, "y": 25, "radius": 10, "color" : "green"},
{ "x": 50, "y": 50, "radius": 10, "color" : "green" },
{ "x": 75, "y": 75, "radius": 10, "color" : "green"},
{ "x": 100, "y": 100, "radius": 10, "color" : "green" },
{ "x": 125, "y": 125, "radius": 10, "color" : "green" },
{ "x": 62.5, "y": 62.5, "radius": 10, "color" : "red" },
{ "x": 0, "y": 125, "radius": 10, "color" : "purple" },
{ "x": 25, "y": 100, "radius": 10, "color" : "purple" },
{ "x": 50, "y": 75, "radius": 10, "color" : "purple" },
{ "x": 75, "y": 50, "radius": 10, "color" : "purple" },
{ "x": 100, "y": 25, "radius": 10, "color" : "purple" },
{ "x": 125, "y": 0, "radius": 10, "color" : "purple" }];
/* Tünel elemanları datadan çekilip circles dizisine
kopyalanmaktadır.
*/
var circles = []
for (var i = 0; i < tunnelElements.length; i++) {
circles[i] = tunnelElements[i];
};
console.log(circles);
var width = 719, height = 262;
var X = d3.scale.linear()
var Y = d3.scale.linear()
/* Semantic zoom için zoom değişkeni oluşturuldu */
var zoom = d3.behavior.zoom()
.x(X).y(Y)
.scaleExtent([1, 10])
.on("zoom", zoomed);
/* Alternatif zoom
.on("zoom", function () {
circle.attr("transform", transform)
});
*/
/* Elementler svg olarak oluşturuldu */
var svg = d3.select("#d3")
.append("svg")
.attr("width", width)
.attr("height", height)
.call(zoom);
/* Road background çağırdık */
var road = svg.selectAll("image").data([0]);
road.enter()
.append("svg:image")
.attr("xlink:href", "http://ahmetates.com.tr/road.svg")
.attr("width", width)
.attr("height", height);
var circle;
/* Bütün elemenlar seçilip transform fonksiyonu
sayesinde drag and drop özelliği kazandı */
circle = svg.selectAll("circle")
.data(circles)
.enter().append("circle")
.attr("transform", transform);
var drag = d3.behavior.drag()
.origin(function(d) { return d; })
.on("dragstart", dragstarted)
.on("drag", dragged)
.on("dragend", dragended);
/* Fonksiyonlar */
function zoomed() {
road.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
circle.attr("transform", transform)
}
function transform(d) {
return "translate("+X(d.x)+", "+Y(d.y)+")";
}
function generateit(){
var circles = svg.selectAll("circle");
var json_circles = JSON.stringify(circles.data());
d3.select("#console").html('tunnelElements = '+json_circles+';');
}
d3.select("#exportit").on("click", generateit);
var circleAttributes = circle
.attr("cx", function (d) { return d.x; })
.attr("cy", function (d) { return d.y; })
.attr("r", function (d) { return d.radius; })
.style("fill", function(d) { return d.color; })
.call(drag);
function dragstarted(d) {
d3.event.sourceEvent.stopPropagation();
d3.select(this).classed("dragging", true);
}
function dragged(d) {
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);
}
#d3 svg{
margin:30px;
padding:10px;
border:1px solid #333;
width: 100%;
height: auto;
}
.line{
stroke-width: 3px;
}
#exportit {
background:#000;
cursor:pointer;
color:#fff;
width:45px;
padding:2px 4px;
}
<script src="http://d3js.org/d3.v3.min.js"></script>
<div id="exportit">Export</div>
<div id="d3"></div>
<div id="console"></div>
编辑:
好像问题没有解释清楚。第一个问题可以这样追溯:拖动任何圆圈,然后拖动背景,你会看到被拖动的圆圈移动到随机位置。第二个问题是缩放,你可以跟踪放大和缩小,然后你可以看到圆圈的位置根据背景变化。
您应该创建一个主组,然后在其中添加您想要缩放和拖动的所有组件。
像这样:
var maingroup = svg.append("g").call(zoom);
//add road and circles in this maingroup
//drag events on circle as you had done no change in that.
这是一个工作 fiddle 这应该更清楚:
http://jsfiddle.net/cyril123/ow8r5n6f/3/
我正在使用 d3.js,但我遇到了问题。当我放大 SVG 时,不相称。另外,拖动后,我制作的 SVG 的处理;进一步漂流。我正在提供必要的代码。我该怎么做才能修复此代码?
代码:
/* Tünelin bütün elemanları için bir dizi oluşturuldu
Daha sonra her ayrı eleman için dizi oluşturulup,
datalar bu doğrultuda çekilecektir.
*/
var tunnelElements = new Array();
tunnelElements = [{ "x": 0, "y": 0, "radius": 10, "color" : "green" },
{ "x": 25, "y": 25, "radius": 10, "color" : "green"},
{ "x": 50, "y": 50, "radius": 10, "color" : "green" },
{ "x": 75, "y": 75, "radius": 10, "color" : "green"},
{ "x": 100, "y": 100, "radius": 10, "color" : "green" },
{ "x": 125, "y": 125, "radius": 10, "color" : "green" },
{ "x": 62.5, "y": 62.5, "radius": 10, "color" : "red" },
{ "x": 0, "y": 125, "radius": 10, "color" : "purple" },
{ "x": 25, "y": 100, "radius": 10, "color" : "purple" },
{ "x": 50, "y": 75, "radius": 10, "color" : "purple" },
{ "x": 75, "y": 50, "radius": 10, "color" : "purple" },
{ "x": 100, "y": 25, "radius": 10, "color" : "purple" },
{ "x": 125, "y": 0, "radius": 10, "color" : "purple" }];
/* Tünel elemanları datadan çekilip circles dizisine
kopyalanmaktadır.
*/
var circles = []
for (var i = 0; i < tunnelElements.length; i++) {
circles[i] = tunnelElements[i];
};
console.log(circles);
var width = 719, height = 262;
var X = d3.scale.linear()
var Y = d3.scale.linear()
/* Semantic zoom için zoom değişkeni oluşturuldu */
var zoom = d3.behavior.zoom()
.x(X).y(Y)
.scaleExtent([1, 10])
.on("zoom", zoomed);
/* Alternatif zoom
.on("zoom", function () {
circle.attr("transform", transform)
});
*/
/* Elementler svg olarak oluşturuldu */
var svg = d3.select("#d3")
.append("svg")
.attr("width", width)
.attr("height", height)
.call(zoom);
/* Road background çağırdık */
var road = svg.selectAll("image").data([0]);
road.enter()
.append("svg:image")
.attr("xlink:href", "http://ahmetates.com.tr/road.svg")
.attr("width", width)
.attr("height", height);
var circle;
/* Bütün elemenlar seçilip transform fonksiyonu
sayesinde drag and drop özelliği kazandı */
circle = svg.selectAll("circle")
.data(circles)
.enter().append("circle")
.attr("transform", transform);
var drag = d3.behavior.drag()
.origin(function(d) { return d; })
.on("dragstart", dragstarted)
.on("drag", dragged)
.on("dragend", dragended);
/* Fonksiyonlar */
function zoomed() {
road.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
circle.attr("transform", transform)
}
function transform(d) {
return "translate("+X(d.x)+", "+Y(d.y)+")";
}
function generateit(){
var circles = svg.selectAll("circle");
var json_circles = JSON.stringify(circles.data());
d3.select("#console").html('tunnelElements = '+json_circles+';');
}
d3.select("#exportit").on("click", generateit);
var circleAttributes = circle
.attr("cx", function (d) { return d.x; })
.attr("cy", function (d) { return d.y; })
.attr("r", function (d) { return d.radius; })
.style("fill", function(d) { return d.color; })
.call(drag);
function dragstarted(d) {
d3.event.sourceEvent.stopPropagation();
d3.select(this).classed("dragging", true);
}
function dragged(d) {
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);
}
#d3 svg{
margin:30px;
padding:10px;
border:1px solid #333;
width: 100%;
height: auto;
}
.line{
stroke-width: 3px;
}
#exportit {
background:#000;
cursor:pointer;
color:#fff;
width:45px;
padding:2px 4px;
}
<script src="http://d3js.org/d3.v3.min.js"></script>
<div id="exportit">Export</div>
<div id="d3"></div>
<div id="console"></div>
编辑:
好像问题没有解释清楚。第一个问题可以这样追溯:拖动任何圆圈,然后拖动背景,你会看到被拖动的圆圈移动到随机位置。第二个问题是缩放,你可以跟踪放大和缩小,然后你可以看到圆圈的位置根据背景变化。
您应该创建一个主组,然后在其中添加您想要缩放和拖动的所有组件。
像这样:
var maingroup = svg.append("g").call(zoom);
//add road and circles in this maingroup
//drag events on circle as you had done no change in that.
这是一个工作 fiddle 这应该更清楚: http://jsfiddle.net/cyril123/ow8r5n6f/3/