Programatic zoom in D3 - javascript

Using the code pattern here, I want to programmatically achieve semantic zooming (in or out). I'm unsure how to get the proper x, y, and scaleExtent terms that are augmented via the zoom:
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.call(d3.behavior.zoom().x(x).y(y).scaleExtent([1, 8]).on("zoom", zoom));
See JSfiddle here. The zoomIn and zoomOut functions should simulate the mousewheel events centered in the SVG.
Here's a solution based on the answer below: http://jsbin.com/dociwuvacu/1

I believe I successfully updated your fiddle, but in case not, here is the type of code you would need:
function zoomIn() {
zoomer.scale(zoomer.scale()+.1);
zoomer.event(svg);
}
function zoomOut() {
zoomer.scale(zoomer.scale()-.1);
zoomer.event(svg);
}

Related

Using D3 zoom in JavaFX Webview

I have a JavaFX Webview which renders a graph (using D3). I want to implement the 'zoom on mouse scroll' on this graph in the JavaFX application (when the mouse is hovered on top of the webview). I was able to do it successfully on a web-browser using the following d3 js code
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.call(d3.behavior.zoom().on("zoom", zoomHandler))
.append('g');
function zoomHandler() {
svg.attr("transform",
"translate(" + d3.event.translate + ")"
+ " scale(" + d3.event.scale + ")");
}
but if I do something similar inside the JavaFX application's WebView, the graph is rendered initially in the WebView but on scroll, just disappears and only reappears if I bring back the mouse scroll to the initial position (when the application was started)
The following code is how I use WebView to render the graph
final URL urlLoadMainGraph = getClass().getResource("html/MainGraph.html");
weMainGraph.load(urlLoadMainGraph.toExternalForm());
Is there something wrong on what is being done ?
Thanks
I cannot provide a solution, but i have the same problem.
The problem is, that you have not specified any scale.
JavaFX is just jumping from the minimum to the maximum scale of the zoom with one "tip" on the mousewheel :(. if you specify it in a certain range, it could work out for you. Use this for example to zoom a little bit outside.
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height).call(d3.behavior.zoom().scaleExtent([0.75, 1]);
best so far... hoping for anwsers!
(PS: i couldnt comment... thats why this kind of answer.
There seems to be a bug in your zoomhandler code example. You might want to start with a handler like the following and go on from there:
function zoomHandler() {
alert('zoom');
}
Here is a more detailed d3 zoom example:
http://bl.ocks.org/mbostock/3892919
And here is a JavaFx wrapper for D3 that also contains a working zoom example:
https://github.com/stefaneidelloth/javafx-d3
https://github.com/stefaneidelloth/javafx-d3/blob/master/javafx-d3-demo/src/main/java/com/github/javafxd3/demo/client/democases/behaviors/ZoomDemo.java

d3.js network diagram zoom

I have probably a relativly simple question.
Here is my simple diagram enter link description here
And I would love to implement zooming in and out functionality, using the behaviour descibed here
enter link description here. But I cant make it work, maybe You would spot the problem.
Thanks for Your time.
The whole zooming in functionality seems to be handled with this assignment and function:
svg = d3.select("body").append("svg").attr("width", width).attr("height", height)
.call(d3.behavior.zoom().x(x).y(y).scaleExtent([1, 8]).on("zoom", zoom));
function zoom() {
svg.clearRect(0, 0, width, height);
}
The code you have tried for zooming is used for canvas. You can use transform attribute for zooming in svg.
You can put the whole graph in a (group) element and apply transform attribute to element.
svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height)
.call(d3.behavior.zoom().x(x).y(y).scaleExtent([1, 8]).on("zoom", zoom))
.append("g");
function zoom() {
svg.attr("transform","translate("+ d3.event.translate+") scale("+d3.event.scale+")");
}
Here is the fiddle

D3.js and dragdealer JS

I am using dragdealer JS with D3.js. What i am doing is that when You drag the slider made by dragdealer JS the elements made by D3.js will move like a picture slider.
Here is the code which which i wrote : code.
Now there are two problems with this code:
1) This code is working in FireFox but not in Chrome & IE 10?
2) How to configure the slider so that on one slide, only one tile will move into the view and only one will move out?
The number of tiles or rectangles are not fixed. There can be any number of tiles depending on the user.
Code:
var width = 4000,
height = 200,
margin = 2,
nRect = 20,
rectWidth = (width - (nRect - 1) * margin) / nRect,
svg = d3.select('#chart').append('svg')
.attr('width', width);
var data = d3.range(nRect),
posScale = d3.scale.linear()
.domain(d3.extent(data))
.range([0, width - rectWidth]);
console.log(rectWidth)
svg.selectAll('rect')
.data(data)
.enter()
.append('rect')
.attr('x', posScale)
.attr('width', rectWidth)
.attr('height', height);
function redraw(x)
{
svg.transition()
.ease("linear")
.attr("transform", "translate(" + -(x*rectWidth) + ")" );
console.log(-(x*rectWidth));
}
var step = nRect/2;
new Dragdealer('magnifier',
{
steps: step,
snap: true,
animationCallback: function(x, y)
{ console.log(x*10)
redraw(x*step);
}
});
i am trying to devise a way so that the value of steps will change according to the number of tiles.
Please help me.
You had a few problems that I've fixed here: http://jsfiddle.net/SqKZv/1/
In Chrome your svg element needed the height property set
In Chrome/IE, it doesn't appear that you can apply the transform attribute to your SVG element, I'm actually surprised this works in FireFox. I wrapped all of your rect elements in a g element and transformed that.
D3 does dragging very well by itself, so you don't need Dragdealer to do this. In addition to d3.behavior.drag, you can check out d3.svg.brush, specifically these examples of snapping to get what you want:
Brush Snapping http://bl.ocks.org/mbostock/6232537
Brush Snapping II http://bl.ocks.org/mbostock/6232620
You may also want to try out the new D3 feature called brush: https://github.com/mbostock/d3/wiki/SVG-Controls
Here is an example I made using brush to implement a similar feature as you mentioned.
https://github.com/CSE512-14W/a3-chaoyu-aniket

How to unregister zoom behavior of SVG element in d3.js

I have register the zoom behavior with element, now I want to toggle between zoom-able and not zoom-able, does anyone know how to unregister the zoom behavior of SVG element ?
var svg = d3.select("#topology-div")
.append("svg")
.attr("class", "topology-map")
.attr("width", data.width)
.attr("height", data.height)
.call(zoom); // <<-- I want unregister zoom later
do you mean like:
svgElement.call(d3.behavior.zoom().on("zoom"); //deactivate zoom behavior

d3 click coordinates are relative to page not svg - how to translate them (Chrome error)

When an event is in play, d3.event.x gives the position of the x coordinate of the mouse click, but relative to the entire HTML doc. I tried using jQuery's $('svg').position() to get the actual position of the svg but this return blatantly fallacious values.
Is there some easy way to find the position of an svg relative to the page that I am overlooking? I am using Chrome, by the way, in case the jQuery problem is an obscure browser error.
EDIT: I checked this in firefox and $('svg').position() returns the correct coordinates. ?!?
Instead of using d3.event, which is the browser's native event, use d3.mouse to get the coordinates relative to some container. For example:
var svg = d3.select("body").append("svg")
.attr("width", 960)
.attr("height", 500);
var rect = svg.append("rect")
.attr("width", "100%")
.attr("height", "100%")
.on("mousemove", mousemove);
function mousemove(d, i) {
console.log(d3.mouse(this));
}

Categories

Resources