How do I make the d3 zoomable treemap responsive? - svg

I'm trying to create a responsive version of the zoomable treemap example. What needs to be added so that the treemap resizes with the window?
When I try to change treemap.size() in an update method on $(window).resize(), nothing seems to happen.
I'm setting the svg to style="width: 100%; height: 100%" and the svg resizes, but the layout of the treemap does not. I also tried using viewbox and preserveAspectRatio per this answer and the treemap looks initially correct, however the zooming functionality no longer works correctly because the treemap layout doesn't know its correct size.

One way to handle this is as Lars Kotthoff told you can redraw the treemap.
For that first you should specify the width and height parameters as your graph containers width and height before that you should specify container width and height in percentage. And wrap the zoomable map drwing script inside a function (Let's call it as zoomabletreemap())
Then you should call the zoomabletreemap() function for the window resize event using JavaScript. Before calling the javascript you should remove the old graph also.
$(window).resize(function () {
var div = document.getElementById("my-svg-div"); //id of the div we are appending to the chart container to contain the svg
div.parentNode.removeChild(div);
ZoomableTreeMap();
});
Here is the working example for the same I explained above

Related

FabricJS Resize filters with canvas zoom

The default behavior of fabricJS resizefilters makes images look great as long as the zoom level is set to 1.0. This means images with a resizefilter look pixelated when zoomed in, as well as when exporting the canvas with a multiplier. Is there a way for resizefilters to take into account the current canvas zoom level or toDataURL multiplier?
https://jsfiddle.net/melchiar/mh9ba4pz/
fabric.Image.fromURL(imageData, function(img) {
img.set({
left: 10,
top: 10
}).scale(0.5);
img.resizeFilter = new fabric.Image.filters.Resize({
resizeType: 'hermite'
});
img.applyResizeFilters();
canvas.add(img);
});
Hi i have seen your question on the issue tracker too, as of now there is no simple way to obtain it with the resize filter.
The only way to make it non pixellated is to remove at export time the resizeFilter and add one resizeFilter in the normal filter chain with a precalculated ratio.
This is actually a bug.
issue tracker: https://github.com/fabricjs/fabric.js/issues/5071
Just an update on this question, this issue was a bug that was fixed with Version 2.3.4. Using a resizefilter will now apply resizing based on the current zoom level, and works with toDataURL multipliers as well.

fabricjs call to canvas.toDataURL() resizes the dimensions of the canvas

I'm using fabricjs 1.7.17 and have seen this issue below on IE Edge, Chrome and Firefox.
where the canvas is being set with a width and height in HTML of 768px.
Within my fabricjs canvas init I've got:
editor.canvas = new fabric.Canvas('editor')
editor.canvas.setDimensions({
width: 1080,
height: 1080,
allowTouchScrolling: false,
backgroundColor: 'rgba(55, 55, 55, .33)',
rotationCursor: 'url(/static/img/rotate.cur) 10 10, crosshair'
}, {backstoreOnly: true})
The problem is when you call the editor.canvas.toDataURL() method the size of the goes from 768px to 1080px
If you call the browser's native canvas.toDataURL() method there isn't a jump in size.
Anyone bump into this and have a possible fix?
Here's a simplified jsfiddle:
https://jsfiddle.net/m8dhmbtu/23/
Click on the "Native Canvas.toDataURL()" and you'll get the results to console.log and there will be no change to the displayed canvas in the preview window.
Click on the "Fabricjs canvas.toDataURL()" and you'll also get the results (the same) to console.log however; you'll also get a jump in the size of the in the preview window...this is what I'm trying to prevent.
I think the problem is actually a bug.
You set the canvas to 1080 for backstore dimension only, meaning that the canvas will be sized but the css will be left untouched.
A dataurl will reset the canvas after the process to fix it back in case the export to data url had a multiplier.
while this can be fixed at least for the non multiplied situations, a proper fix is needed.
The proper fix consist in setting backstore only during export so that the css does not get touched.
A better fix would be to do not touch the original canvas and create one on the fly just for exporting.
please go on official fabricjs repository and open an issue for this.

In D3.js How to draw a map with full screen width?

I created a geo map(world map).I try to stretch my map based on screen width.svg don't support width:100% so that i created a parent div width:100% for svg.
Sample Code
<div id="world-placeholder" style="width:100%;height:100%;">
// svg part goes here
</div>
Also, I tried svg attribute like viewBox and preserveAspectRatio.But Still i can't able to create.
I added my fiddle link below so kindly take a look and help me.
Fiddle Link - http://jsfiddle.net/acvefmhz/1/
Map is working fine.But i need show my map as a full screen(Need to stretch full window)
var width = window.innerWidth,
height = window.innerHeight;
http://jsfiddle.net/acvefmhz/4/

Scale an SVG (in Dart) using viewBox doesn't work

I recently started working with Google Dart (www.dartlang.org) and playing with SVG.
I am trying to scale a generated SVG to fit into a <div> using a viewBox.
People on StackOverflow already gave me a lot of help.
I am now able to scale paths like this: Dart create and transform an SVG path
But is seems that viewBox is made for scale-to-fit and using it would save me from scaling all paths in the svg separately. That is why I want to use a viewBox.
I tried the following:
// get bounding box of the created svg
Rect bb = path.getBBox();
// create a viewBox for the svg to fit in the div
var viewBox = svg.viewBox.baseVal
..x = bb.x
..y = bb.y
..width = bb.width
..height = bb.height;
// center the image inside the div
svg.preserveAspectRatio.baseVal
..meetOrSlice = PreserveAspectRatio.SVG_MEETORSLICE_MEET
..align = PreserveAspectRatio.SVG_PRESERVEASPECTRATIO_XMIDYMID;
But no scaling happens.
How would I solve this?
While writing this question and retrying to make sure I tried anything before asking here, I found the following solution.
It seems like Dartium (Chrome with a native Dart VM) has a bug (issue 12224) where changes to the viewBox are not reflected directly.
Adding the following code after changes to the viewBox forces Dartium to somehow resize to the requested size:
// add an empty ```<g>``` element to force svg resize
SvgElement g = new SvgElement.tag('g');
svg.append(g);

ImageOverlay and Rectangle Z index issue

I have a function that adds an imageOverlay and a semitransparent Rectangle on top of that image (so as to tint the image, and draw a keyline around it).
activeUserImage = new L.imageOverlay(imageUrl, imageBounds).addTo(map);
activeUserTile = new L.rectangle(imageBounds, {stroke: true, color: "#ffffff", opacity:1, weight: 1, fillColor: "#003572", fillOpacity: 0.7, clickable:true}).addTo(map);
this works great, but then I want to remove the image and rectangle with:
map.removeLayer(activeUserImage);
map.removeLayer(activeUserTile);
This seems to work well...
However when I try and add a second Image & Rectangle (using the same function) the rectangle SVG is being rendered underneath the image, so I don't see the colored overlay.
This seems to be because the element is being left behind from the first creation, and then when the image is being added a second time it appears in front of the SVG.
Q:
Is this a bug? Should the SVG element not be cleared too?
Can I adjust z-index of the image or SVG on creation?
should i be containing to rectangle in a different layer to the images? How?
Many Thanks
OK, so the Leaflet bringToFront() method didn't work, but instead I have used a bit of JQuery to force the same approach.
svgObj = $('.leaflet-overlay-pane svg');
svgObj.css('z-index', 9999);
This works, but still feels like a hack... however if (?) there is a bug in LEaflet, then maybe this will have to do???
Any better ideas?
The bringToFront() function alows you to bring layer to the top.
Search it in the docs.

Resources