I am attempting to fill a div with an svg image using D3.js. So far I have been able to center my image and watch it scale as I grow and shrink the browser window. However when attempting to dynamically find the bounding box of image I can only find the top,left properties of the canvas and the width of all the space no just my original image.
Here is a basic mock up of my problem:
http://jsfiddle.net/wnwfn/79/
d3.select("#svgEmbed").append("image")
.attr("xlink:href","http://www.clipartkid.com/images/32/square-clip-art-black-and-white-clipart-panda-free-clipart-images-UkJ6sF-clipart.png")
.attr("width", "100%")
.attr("height", "100%")
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.3.12/d3.min.js"></script>
<p>
<svg id="svgEmbed" height="100%" width="100%" ></svg>
</p>
So my question is how can I find the top left position of the square image in this example? I've had a play using the .offset(), .getBBox() but I can't seem to get the values I am looking for.
Your approach isn't going to work. By setting the image width/height to 100%, the image element will always be positioned at [0,0]. If you know the pixel size of how you want the image to display, you can do something like this:
var imgSize = 150;
var img = d3.select("#svgEmbed")
.append("image")
.attr("xlink:href", "http://www.clipartkid.com/images/32/square-clip-art-black-and-white-clipart-panda-free-clipart-images-UkJ6sF-clipart.png")
.attr("x", "50%")
.attr("width", imgSize)
.attr("height", imgSize)
.attr("transform", "translate(" + (-imgSize / 2) + ", 0)");
d3.select(window).on("resize", function(){
console.log(img.node().getBBox());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<p>
<svg id="svgEmbed" height="100%" width="100%"></svg>
</p>
Related
I have text, and I used a bbox to be able to add a rectangle to match the size of the text.
When I draw the rectangle it is the correct size, but the rectangle is on top of my text.
Is there a way to put the rectangle under the text?
You can use D3's insert to place the <rect> before the <text> in the SVG structure. For example:
svg.insert("rect", "text")
.attr("x", bbox.x)
.attr("y", bbox.y)
.attr("width", bbox.width)
.attr("height", bbox.height)
.attr('class',"rectFillBox")
.attr('fill','white')
.attr("fill-opacity", 0.5);
Can I use d3 force to cluster nodes in the corner of a screen? I don't want them to be in a clustered in a circle. Something
like this.
Try adding a "transform" attribute to your container element.
Here's a working example forked from Mike Bostock's Cluster Force Layout example:
https://jsfiddle.net/cmilneil/gpzavdqe/
The relevant bit of code is here. I'm adding a new g element and translating it into the corner of the containing svg element:
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append('g')
.attr('transform','translate(' + width/2 + ',' + -height/2 + ')' );
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
I have set up a clip path on a D3.js zoomable focus and context graph, but have a slight problem. http://nestoria.darkgreener.com/v2/
The clip path is cutting off some circles from the edge of the focus graph - you'll see that the top and right-hand circles are only half there!
It works well on zoom, though, as you'll see if you click and drag the context graph.
So I'm not sure how to create a clip path that doesn't cut off the edges of these circles. This is my code:
focus.append("defs")
.append("clipPath")
.attr("id", "clip")
.append("rect")
.attr("width", width - 200)
.attr("height", height);
var focus_dots = focus
.selectAll(".dot")
.data(mydata[j].data);
focus_dots.enter()
.append("circle")
.attr("clip-path", "url(#clip)");
Any ideas? Your help would be very much appreciated as I'm completely baffled about what to do here!
If you don't want the clipping to not be applied when hovering you can use a stylerule like this:
circle:hover { clip-path: none; }
I had the same problem and got around it using
.attr("transform", "translate(0,-20)")
.attr("height", height+20)
The Idea is a bit hacky, but if you simply move the clipping window up and add the same amount to its height, it should show (in the above case) 20px more on top. (same for left side; concerning the right and bottom side: simply add some pixels to hight/width).
I've used "transform",and the circles were cut to quarter.So use cx and cy instead, problem solved..
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));
}