Internet Explorer Scaling not working properly - javascript

I have a map created with d3. I set it to have the width of the parent div (with id map) and height with a ratio of 5/9 to to the width. The viewBox has been set to "0 0 width height".
Here is the setup:
var width = $("#map").width(),
height = width * 500 / 900,
active = d3.select(null);
var projection = d3.geo.albersUsa()
.scale(width)
.translate([width / 2, height / 2]);
var path = d3.geo.path()
.projection(projection);
projection = d3.geo.albersUsa()
.scale(width)
.translate([width / 2, height / 2]);
path = d3.geo.path()
.projection(projection);
svg = d3.select("#map").append("svg")
.attr("width", "100%")
.attr("height", "100%")
.attr("viewBox", "0 0 " + width + " " + height)
g = svg.append("g");
Here is how it looks like in Chrome:
But it looks like this in IE:
The scaling is completely messed up. I believe it has to do with the viewBox. Could someone explain how to solve this issue?
Thanks!

The problem you are having is that height: "100%" is handled differently by Chrome and IE. You have smartly set your height variable to be based on your width and aspect ratio, but to take advantage of this, you'll need to use these values when setting the dimensions of your svg as well as the viewBox:
var svg = d3.select("#map").append("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", "0 0 " + width + " " + height);

Related

How to make SVG responsive in D3 with viewbox?

I have noticed that in various examples, an SVG is responsive (changes size in response to changes in window size) and sometimes it is not responsive when using viewbox / preserveAspectRatio.
Here is a very simple example. I am using viewbox and preseverAspectiRatio on the SVG element like every other example, but yet, it is not responsive, why?
<html>
<meta charset="utf-8">
<body>
<div id ="chart"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
<script>
var svgContainer = d3.select("#chart")
.append("svg")
.attr("width", 200)
.attr("height", 200)
.attr("viewBox", "0 0 100 100")
.attr("preserveAspectRatio", "xMinYMin meet")
//Draw the Circle
var circle = svgContainer.append("circle")
.attr("cx", 50)
.attr("cy", 50)
.attr("r", 50);
</script>
</body>
</html>
Currently your svg is not resize because you have specified a fixed with for the svg container of 200x200.
var svgContainer = d3.select("#chart")
.append("svg")
.attr("width", 200) // setting fixed width
.attr("height", 200) // setting fixed width
One solution is to change these to percentages, which will rescale to the size of its parent.
var svgContainer = d3.select("#chart")
.append("svg")
.attr("width", '100%') // percent width
.attr("height", 100%) // percent height
Another possible solution is to use the Window#resize event, and change the size of the svg based on the changes.
window.addEventListener('resize', function () {
// select svg and resize accordingly
});
I should add that in chrome you can use ResizeObserver to watch for changes to the svg parents size, and resize the svg accordingly from that.
const resizeOb = new ResizeObserver((entries: any[]) => {
for (const entry of entries) {
const cr = entry.contentRect;
const width = cr.width; // parent width
const height = cr.height; // parent height
// resize svg
}
});
this.resizeOb.observe(svgParentElement);

How to resize d3 map

I have this map in d3 consisting of a chart and map:
I define a few global variables:
var chartWidth = window.innerWidth * 0.425,
chartHeight = 473,
leftPadding = 35,
rightPadding = 2,
topBottomPadding = 5,
innerWidth = chartWidth - leftPadding - rightPadding,
innerHeight = chartHeight - topBottomPadding * 2,
translate = "translate(" + leftPadding + "," + topBottomPadding + ")";
Here's the map:
//set up the map
function setMap(){
var width = window.innerWidth * 0.55, //dimensions
height = 580; //dimensions
//create new svg container for the map
var map = d3.select("body")
.append("svg")
.attr("class", "map")
.attr("width", width)
.attr("height", height);
And a linked chart:
function setChart(csvData, colorScale, attribute){
var expressed = attribute
//create a second svg element to hold the bar chart
var chart = d3.select("body")
.append("svg")
.attr("width", chartWidth)
.attr("height", chartHeight)
//assign class
.attr("class", "chart");
//create a rectangle for chart background fill
var chartBackground = chart.append("rect")
.attr("class", "chartBackground")
.attr("width", innerWidth)
.attr("height", innerHeight)
.attr("transform", translate);
}
I'm trying to make the map (the map itself and the associated chart, both are appended to 'map' canvas) responsive, so it will resize when window is resized. I've inserted the following code in the setMap function with no luck, hoping to re-class the 'map' on re-size:
d3.select("map")
.append("div")
.classed("svg-container", true) //container class to make it responsive
.append("svg")
//responsive SVG needs these 2 attributes and no width and height attr
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", "0 0 " + width + " " + height)
//class to make it responsive
.classed("svg-content-responsive", true);
What can I try to achieve this?

D3js - Reposition tree graph in viewbox

I have used viewbox to enable my tree graph to be able to resized based on the browser window size. However, I could not position the tree to be at the center of the view box. I have tried to apply transform-translate attribute to the graph, the position remain unchanged. What attribute/changes do I have to apply to position the tree graph? Below, the first image is the current output. Image two shows the desired output. I have attached the initialisation code for the tree graph.
var margin = { top: 40, right: 120, bottom: 20, left: 120 };
var width = 700 - margin.right - margin.left;
var height = 500 - margin.top - margin.bottom;
var i = 0, duration = 750;
var tree = d3.layout.tree()
.nodeSize([110,110])
var diagonal = d3.svg.diagonal()
.projection(function (d) { return [d.x, d.y]; });
var svg = d3.select(treeContainerDom)
.append("div")
.classed("svg-container", true) //container class to make it responsive
.append("svg")
//responsive SVG needs these 2 attributes and no width and height attr
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", "-50 0 1000 1000")
//.attr("viewBox", "0 0 "+width+" "+height)
//class to make it responsive
.classed("svg-content-responsive", true)
.call(zm = d3.behavior.zoom().scaleExtent([0.5,2]).on("zoom", redraw)).append("g");

Strange behavior of Bootstrap Accordion Expand Height with D3 Graph

I have a circle packing layout of D3 within a bootstrap accordion (where all the tabs are expanded on load). I have tried to allow for a responsive layout by using the following:
var vis = d3.select("#Vis_container").insert("svg:svg", "h2")
.attr("width", '100%')
.attr("height", '100%')
.attr('viewBox', '0 0 ' + w + ' ' + h)
.attr('preserveAspectRatio', 'xMinYMin')
.append("svg:g")
.attr("transform", "translate(" + 0 + "," + 0 + ")");
If you collapse the tab that contains the D3 layout and expand it again, the svg's height is fine, but the container it is in does not resize correctly i.e. not enough height is provided for the entire layout to show.
Note: I used the container's width as its height as well, due to the height not being available on load.
var w = $('#Vis_container').width(),
h = $('#Vis_container').width()
Can anyone help me to correct the height of the container / accordion when the tab is expanded again?
See the fiddle here: http://jsfiddle.net/Sim1/sLMC2/7/
I am offering this as an alternative. Here is the FIDDLE.
Basically, I gave an initial (and hopefully reasonable) value for width and height, and then added code to re-size after that, if desired. May this will help.
var vis = d3.select("#Vis_container")
.insert("svg:svg", "h2")
.attr("width", h)
.attr("height", w)
...
var chart = $("#Vis_container>svg"),
aspect = chart.width() / chart.height(),
container = chart.parent();
$(window).on("resize", function() {
var targetWidth = container.width();
chart.attr("width", targetWidth);
chart.attr("height", Math.round(targetWidth / aspect));
}).trigger("resize");

d3.js scale donut chart in resize event

I drew my chart with two dimensions to the width of the window:
var width = (window.innerWidth < 1280) ? 400 : 600,
height = (window.innerWidth < 1280) ? 400 : 500,
radius = Math.min(width, height) / 2;
var arc = d3.svg.arc().innerRadius(radius).outerRadius(radius - 10),
arcFinal = d3.svg.arc().innerRadius(radius - 100).outerRadius(radius - 10),
arcHover = d3.svg.arc().innerRadius(radius - 100).outerRadius(radius);
var svg = d3.select("#chart").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("id", "pie")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");}
What is the best way to update this function in resize event?
Ok, I fixed by adding:
...
var svg = d3.select("#chart").append("svg")
.attr("width", width)
.attr("height", height)
.attr("viewBox", "0, 0, " + width + ", " + height)
.attr("preserveAspectRatio", "xMinYMin")
...
Then I updated the width and height on resize event

Categories