d3 Workaround for svg transform in chrome - javascript

I've created an inner dimension to cut off plotting in d3. Here is the code:
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var nestedSVG = svg.append('svg')
.attr("width", innerWidth)
.attr("height", innerHeight)
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
This works fine in firefox. But I've learned that chrome does not support svg transforms like this (and it isn't working in chrome). Is there a workaround so that I can transform nestedSVG?

You can set x and y attributes on your nested SVG to create a translation of coordinates.
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height);
var nestedSVG = svg.append('svg')
.attr("width", innerWidth)
.attr("height", innerHeight)
.attr("x", margin.left)
.attr("y", margin.top);
For more complicated transforms, you would use a parent or child <g> element and transform that, as you mentioned in comments to your previous question.

Related

D3 Zoom TypeError: t.apply is not a function

Currently, i'm trying to implement a zoom function to my data visualization. Sometimes an error occurs "d3.min.js:1 Uncaught TypeError: t.apply is not a function" when i try to zoom or to move the svg element. It looks like an internal error within d3 library.
var height = $("#content").height();
var width = $("#content").width();
var svg = d3.select("#content").append("svg")
.attr("width", width)
.attr("height", height)
.attr("class", "svg_canvas")
.append("g")
.call(d3.behavior.zoom().scaleExtent([1, 8]).on("zoom", zoom))
.attr("transform", "translate(" + (width / 2.0) + "," + (height /2.0 )+ ")")
.append("g")
.attr("class", "interaction_group");
zoom_layer = svg;
//Overlay for zooming
svg.append("rect")
.attr("class", "overlay")
.attr("width", width)
.attr("height", height)
.attr("transform", "translate(" + (-width / 2.0) + "," + -(height/2.0 ) + ")");
The event handler "zoom" is really basic:
function zoom() {
zoom_layer.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
The implementation was realized with the latest D3.js V3 version.
Firstly, declare your zoom behavior:
var myZoomBehavior=d3.behavior.zoom().scaleExtent([1, 8]).on("zoom", zoom)
Then call it to the svg root:
var svg = d3.select("#content").append("svg")
.attr("width", width)
.attr("height", height)
.attr("class", "svg_canvas").call(myZoomBehavior)
Then create the zoomable g with the same variable name as in your zoom function:
var zoom_layer=svg.append("g")

d3.js zoom without overflow

I have a force directed graph with fixed nodes. I have allowed zoom in the graph :
var force = d3.layout.force()
.on("tick", tick);
var zoom = d3.behavior.zoom()
.scaleExtent([0, 50])
.on("zoom", zoomed);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.call(zoom);
var graphGroup = svg.append("g")
.attr("height", graphHeight)
.attr("width", graphWidth)
.attr("class", "graph-group")
.attr("transform", "translate(" + margin + "," + margin + ")");
graphGroup.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("height", graphHeight)
.attr("class", "graph-limit")
.attr("width", graphWidth);
...
function zoomed() {
graphContainer.attr("transform", "translate(" + t + ")scale(" + d3.event.scale + ")");
}
I would like to limit the zoom (scale and translation) of the graph within the rectangle with class "graph-limit".
I've tried to put overflow:hidden in style, but without success.
Any idea ?
EDIT :
Here a jsfiddle
http://jsfiddle.net/Lxc43v8d/20/
This is how you can do it.
Use clip path with dimension exactly same as that off the rectangle:
//make a clip path
svg.append("defs").append("svg:clipPath")
.attr("id", "clip")
.append("svg:rect")
.attr("id", "clip-rect")
.attr("x", 0)
.attr("y", 0)
.attr("height", graphHeight)
.attr("width", graphWidth);
To the group which holds the rectangle all nodes and links add the clip path like this
var graphGroup = svg.append("g")
.attr("clip-path", "url(#clip)")//add the clip path
.attr("height", graphHeight)
.attr("width", graphWidth)
.attr("class", "graph-group");
Working code here
Hope this helps!

How do i add a clip path for my graph ?

I have this fiddle : http://jsfiddle.net/q0ubpmwj/5/
I have been trying to mess around with the clip path so the graph doesnt go outside the axis but i cant seem to get it to work.
Heres a bit of the clip path code i have used but it doesnt seem to work :/
var svg = viewer.append("svg").attr('id', 'viewerPins')
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var clip = viewer.append("defs").append("svg:clipPath")
.attr("id", "clip")
.append("svg:rect")
.attr("id", "clip-rect")
.attr("x", "0")
.attr("y", "0").attr("width", width)
.attr("height", height);
var chartBody = svg.append("g")
.attr("clip-path", "url(#clip)")
//.call(zoom)
;
You appending the defs outside of the svg:
viewer.append("defs").append("svg:clipPath")
should be
svg.append("defs").append("svg:clipPath")

How to append a rectangle in SVG/3Djs?

Here is a part of code I got from some example:
svg = d3.select("body")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")").on("click", click)
;
And here is what I am trying to do based on some other example:
var rect = svg.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("height", height)
.attr("width", width)
.style("fill", '#000');
rect.on("click", click);
Click works, but I cannot known where th clickable zone is located, it is not covering my chart, but is somewhere in a corner of it. So I tried to give it a colour (black in this case), but still it stay invisible.
I have also tried
var rect = svg.append("rect")
.attr("x", margin.left)
.attr("y", margin.top)
.attr("height", height + margin.top + margin.bottom)
.attr("width", width + margin.left + margin.right)
.style("fill", '#000');
rect.on("click", click);
No better result.
Questions:
How can I give my rectangle a colour so that I can know where it is
on the page?
How can I have my rectangle match the whole SVG?
EDIT: I have just realised that "onclick" works because it is also attached to the "g" , but I am still interested in the answers.
You have given it a colour, #000 i.e. black.
The trouble is here
svg = d3.select("body")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")").on("click", click)
;
The svg variable is not the <svg> element, because of chaining it's the <g> element, which has a transform on it so the rect is transformed.

Is this approach right of making a heatmap matrix

I need a heatmap matrix like this,
Now I tried using D3.js, I am able to make matrix and also made it zoomable too, but now I am stuck at adding Notes to rectangles as SVG doesn't supports it.
Am I on right track or can I use Div and jQuery instead to develop this heatmap, I visited hundreds of plugins but non satisfies my needs.
Proper matrix - http://jsfiddle.net/nhe613kt/49/
Trying adding Notes with one rectangle - http://jsfiddle.net/nhe613kt/60
Can I use any other plugin or simple HTML ?
var width = 600,
height = 600;
var margin = {top: -5, right: -5, bottom: -5, left: -5};
var zoom = d3.behavior.zoom()
.scaleExtent([1, 15])
.on("zoom", zoomed);
var svgContainer = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.style("background-color", "black")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.right + ")")
.call(zoom);
var zoomed = function () {
svgContainer.attr("transform", "translate("+ d3.event.translate + ")scale(" + d3.event.scale + ")");
};
var zoom = d3.behavior.zoom()
.scaleExtent([1, 8])
.on("zoom", zoomed)
.size([width, height]);
svgContainer.call(zoom);
var rectangle1 = svgContainer.append("rect")
.attr("x", 0)
.attr("y", 0)
.attr("width", 100)
.attr("height", 100)
.attr("fill", "red")
.append("text")
.text("Hahaha");
You need to configure the text node properly:
svgContainer.append("text")
.attr("x", 10)
.attr("y", 20)
.attr("fill", "blue")
.text("Hahaha");
Otherwise, it might be outside of the visible are (y=0 is a common mistake; the Y coordinate moves the baseline of the text, not the top-right corner). Also without a color, the text will inherit one from the parent.
Demo: http://jsfiddle.net/nhe613kt/65/

Categories

Resources