I've just started using D3 V4 and I'm having trouble getting a pan and zoom function working. The problem is that I want the initial scale value to be something over than 1 so I set this using
zoom.scaleTo(svg, 2);
However as soon as I pan or zoom the scale resets back to 1.
Here's an example of this behavior on JSFiddle, what am I doing wrong?
JSFiddle
Here's the problem:
var svg = d3.select("body").append("svg")
.attr("width", 600)
.attr("height", 600)
.call(zoom)
.append("g");
You are assigning the group element instead of the svg element to the variable svg.
The zoom is correctly applied to the svg element, but then when you call zoom.scaleTo(svg, 2) you are zooming the group element, not the svg element.
This can be fixed by first creating and assigning the svg element to the svg variable and only then creating and assigning the group element.
var svg = d3.select("body").append("svg")
.attr("width", 600)
.attr("height", 600)
.call(zoom);
var mainContainer = svg.append("g");
Here's the fixed JSFiddle: https://jsfiddle.net/skgktrcu/2/
Related
Having problems using images as nodes in a force-directed graph. Everything I've looked at so far seems to be v3 code and I haven't been able to get any images at all so far, whether using xlink:href or svg:image or both.
What's the right way to use an img as a node with v4?
Here's what I'm trying, and a jsfiddle.
As you can see in the CSS, I'm trying to get images from a spritesheet for each node.
var defs = d3.append("svg:defs");
defs.append("svg:pattern")
.attr("width", 48)
.attr("height", 48)
//.attr("patternUnits", "userSpaceOnUse")
.append("svg:image")
.attr("xlink:href", "http://placekitten.com/g/48/48")
.attr("width", 48)
.attr("height", 48)
.attr("x", 0)
.attr("y", 0);
var nodesDrawn = svg
.selectAll("node")
.data(nodesData)
.enter()
.append("g")
//.append("xhtml:i")
.append('circle')
.attr('r', 10);
The problems so far:
There is no d3.append in D3. You probably meant svg.append.
Set the width and the height of the <pattern> to 1.
Set an ID to the <pattern> and use that to fill the circles.
Here are the code with that changes (I'm increasing the circles' radii, so you can better see the image): https://jsfiddle.net/ppk23hnz/
By the way, none of those changes are related to D3 version: they are the same in v3.x and v4.x.
PS: Don't mix jQuery and D3. you don't need that (and it's quite disturbing).
I am using a set of sliders to generate an SVG image in d3. Whenever a slider changes, my corresponding SVG image should change.
To generate my SVG, I'm using the following code -
function build_svg(json_data) {
d3.select(".col-sm-6").select("svg").remove();
var svg = d3.select(".col-sm-6").append("svg")
.attr("width", diameter)
.attr("height", diameter)
.attr("class", "bubble");
d3.json(json_data, function(error, data) {
// Some logic to populate variable "svg"
}
}
The function build_svg is called whenever I want to put a new set of JSON data.
Unfortunately, every time I move my slider, I see a flickering image and I don't observe a smooth transition between the SVG images. What would be the best way to build this animation?
It is quite straight forward to implement responsive SVG elements like below.
<div id="chartId"/>
var svg = d3.select("#chartId")
.append("svg")
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", "0 0 600 400");
svg.append("rect")
.attr("fill","blue")
.attr("x", 10)
.attr("y", 10)
.attr("width", 500)
.attr("height", 500);
JSFIDDLE
The following takes place when the window size is shrank.
Before shrinking
After shrinking
As can be seen the rect angle is horizontally and vertically responsive.
But, how can I implement an SVG element that is only horizontally responsive and the following takes place?
One option would be to redraw the SVG element every time the window size is changed, but I would like know if there is more sophisticated solution available.
The preserveAspectRatio attribute determines the scaling and alignment used to fit the viewBox in the svg. When preserveAspectRatio = "xMinYMin meet", content is scaled uniformly (i.e. horizontal and vertical scaled at same ratio). When preserveAspectRatio = "none", content is scaled non-uniformly. In your code, change...
.attr("preserveAspectRatio", "xMinYMin meet")
to...
.attr("preserveAspectRatio", "none")
Some time ago, I was quite into the responsive D3, I am a bit sluggish now, but here is an answer anyway. And it is not so sophisticated. Just put '%' for the width dimension of your svg, and a fixed one for the height.
Do mind that when using '%', the actual dimensions are in function of those of the parent element. You need to take this into account.
Here is the code i took from your fiddle and adjusted it:
var svg = d3.select("#chartId")
.append("svg")
.attr("width", "100%")
.attr("height", "200");
svg.append("rect")
.attr("fill","blue")
.attr("x", 10)
.attr("y", 10)
.attr("width", '100%')
.attr("height", '100%');
It works, i tried it, but I am just not sure if it really is what you want...
I am creating a visualization with d3.js:
http://bl.ocks.org/EE2dev/raw/cd904f10097b9921f1cc/
In that code I create an SVG element and set the size with this line:
var chart = d3.select("body")
.append("div").attr("class", "chart")
.append("svg")
.attr("width", outerWidth) // outerWidth = 960
.attr("height", outerHeight) // outerHeight = 500
.append("g")
.attr("class", "margin")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
Testing the code in Chrome, everything works fine, the SVG has the desired size of (960, 500). When I open this site in Firefox, however, the SVG element is created with a different size, appearantly depending on the actual browser window size, e.g. (634, 856) in the case below.
How do I fix this behaviour to set the SVG to the desired fixed size for Firefox?
I tried several things, including wrapping a div around and/or following ideas I found elsewhere
SVG only shown partially in Firefox
http://tympanus.net/codrops/2014/08/19/making-svgs-responsive-with-css/
But I didn't find a way to fix this problem for me that worked:(
Any help would be greatly appreciated!
outerWidth and outerHeight are browsers Window properties. It is curious problem that these properties could be overwritten in Chrome but not in Firefox (FF API). So when you set
outerWidth = 960;
then outerWidth is changed to 960 in Chrome. In the case of Firefox it is current window width and it can not be changed by the client script.
So rename outerWidth and outerHeight and it should be working.
svgWidth = 960;
svgHeight = 500;
...
.append("svg")
.attr("width", svgWidth)
.attr("height", svgHeight)
I'm attempting to add a legend to a graph, and I want to append it to my chart div. Right now I'm using the following code, which appends the legend to the "body". I would like to instead append it to my "chart" div, so that I can create a footer after my legend. Right now the HTML page is processed first, and then my d3 javascript file gets run and therefore the legend gets placed below my footer. Thank you in advance.
// Create the svg drawing canvas...
var canvas = d3.select("body")
.append("svg:svg")
.attr("width", 300)//canvasWidth)
.attr("height", 300);//canvasHeight);
The following works, like I pointed out in the comment.
var canvas = d3.select("#chart")
.append("svg:svg")
.attr("width", 300)//canvasWidth)
.attr("height", 300);//canvasHeight);
Cheers :)