d3 objects do not render within svg bounds on IE10 - svg

As shown in the image, a circle drawn with center at 0,0 displays correctly on chrome, but on IE10 it overflows the SVG bounds. What do I need to do to get this to render correctly on IE?
Here is the code:
<body>
<div id="chart1">
</div>
<script>
var width = 50,height = 50;
var SVGmap = d3.select("#chart1")
.append("svg")
.attr("width", width)
.attr("height", height);
var g = SVGmap.append("g");
g.append("circle")
.style("stroke", "gray")
.style("fill", "red")
.attr("r", 40)
.attr("cx", 0)
.attr("cy", 0)
</script>
</body>

Thanks Robert. Adding .attr("overflow", "hidden") to the SVG Element solves this.

Related

Draw circles using D3

The following code is supoosed to draw five circles next to each other
<head>
<script type='text/javascript' src='jquery-2.0.3.min.js'></script>
<script type='text/javascript' src='knockout-2.3.0.js'></script>
<script type='text/javascript' src='knockout-2.3.0.js'></script>
<script type='text/javascript' src='knockout-2.3.0.js'></script>
<script src="bootstrap.min.js"></script>
<!-- Bootstrap -->
<link href="bootstrap.min.css" rel="stylesheet" media="screen">
<link href="sticky-footer.css" rel="stylesheet">
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
</head>
<body>
<div id="viz"></div>
<script type="text/javascript">
var dataset = [],
i = 0;
for(i=0; i<5; i++){
dataset.push(Math.round(Math.random()*100));
}
var sampleSVG = d3.select("#viz")
.append("svg")
.attr("width", 400)
.attr("height", 400);
sampleSVG.selectAll("circle")
.data(dataset)
.enter().append("circle")
.style("stroke", "gray")
.style("fill", "black")
.attr("height", 40)
.attr("width", 75)
.attr("x", 50)
.attr("y", 20);
</script>
</html>
It is not really my code I just copied it from this website
http://christopheviau.com/d3_tutorial/
The problem is that this code does not draw any circle.
Although that when I try to use the chrome's tool inspect element, I find that the circles are there but they are not visible.
I thought that the reason is the white colour of the circles although the stroke is not.
However changing the colour was not really useful.
And the problem is that Dreamweaver is not really helping as it does for HTML or JavaScript for example.
Any suggestions for the solution of this issue, or any recommendation for the editor ?
It looks like you took an example that generated rectangles and changed it to circles but circles don't have x, y, height and width attributes, they have cx, cy and radius attributes instead.
sampleSVG.selectAll("circle")
.data(dataset)
.enter().append("circle")
.style("stroke", "gray")
.style("fill", "black")
.attr("r", 40)
.attr("cx", 50)
.attr("cy", 20);
Will draw multiple circles one on top of another.
#Robert Longson
Thank Robert Longson
And if you want to avoid the interlapping between the circles
Here is the code
<script type="text/javascript">
var dataset = [],
i = 0;
for(i=0; i<5; i++){
dataset.push(Math.round(Math.random()*100));
}
var sampleSVG = d3.select("#viz")
.append("svg")
.attr("width", 500)
.attr("height", 300);
sampleSVG.selectAll("circle")
.data(dataset)
.enter().append("circle")
.style("stroke", "gray")
.style("fill", "white")
.attr("r", 40)
.attr("cx", function(d, i){return 50 + (i*80)})
.attr("cy", 120);
</script>

How to use D3 selectAll with multiple class names

I'm experimenting with using multiple class names for SVG elements so that (hopefully) I could select a subset of them using selectAll and "parts" of the class name. Unfortunately nothing I've tried works and I haven't found an example online. The code below demonstrates what I'm trying to do with a simple example of four circles. Two circles have class name "mYc 101" and two circles have class name "mYc 202". selectAll(".mYc") gives all four circles. What if I want only the circles with class name "mYc 101"? Can this be done? How? Thanks times infinity!!
<!DOCTYPE html>
<meta charset="utf-8">
<body>
<div id="my_div"></div>
<script src="http://d3js.org/d3.v3.min.js"></script>
<script>
var m_div = d3.select("#my_div");
var m_svg = m_div.append("svg");
var g = m_svg.append("g");
g.append("circle")
.attr("class", "mYc 101")
.attr("cx", 100)
.attr("cy", 100)
.attr("r", 50)
.attr("style", "stroke: green; stroke-width: 8; fill: #000000");
g.append("circle")
.attr("class", "mYc 101")
.attr("cx", 300)
.attr("cy", 100)
.attr("r", 50)
.attr("style", "stroke: green; stroke-width: 8; fill: #000000");
g.append("circle")
.attr("class", "mYc 202")
.attr("cx", 100)
.attr("cy", 300)
.attr("r", 50)
.attr("style", "stroke: blue; stroke-width: 8; fill: #000000");
g.append("circle")
.attr("class", "mYc 202")
.attr("cx", 300)
.attr("cy", 300)
.attr("r", 50)
.attr("style", "stroke: blue; stroke-width: 8; fill: #000000");
// This selects all four circles
var list = d3.selectAll(".mYc");
// But if I want to select only class "mYc 101", none of these work.
// In fact they all give an error.
// var list1 = d3.selectAll(".mYc 101");
// var list1 = d3.selectAll(".mYc .101");
// var list1 = d3.selectAll(".mYc.101");
// var list1 = d3.selectAll(".mYc,.101");
// var list1 = d3.selectAll(".101");
</script>
</body>
The most D3 way to do this would be to chain the selectors using the filter method:
var list1 = d3.selectAll(".mYc").filter(".101");
This won't work though because class names cannot start with a number. So you have to rename to something like "a101" and then you can do
var list1 = d3.selectAll(".mYc").filter(".a101");
See this fiddle.
Another way I have found to do this is to select both classes at the same time as a single string, for example:
var list1 = d3.selectAll(".mYc.a101")
It won't work if you add in a space in between, or add a comma in between (which selects things that have either class instead).

SVG zoom issue in IE10 (expand more than SVG size)

Making map with d3.js with zoom option like here: http://bl.ocks.org/mbostock/4699541. While testing in IE10 found that map expands to whole page when it is zoomed. I tried to add extra <div>, but it didn't work. Any idea how to fix this?
Now I have such code:
var mapWidth = 500,
mapHeight = 260;
var projection = d3.geo.albersUsa()
.scale(550)
.translate([mapWidth / 2, mapHeight / 2]);
var path = d3.geo.path()
.projection(projection);
var svgDiv = d3.select("body").append("div")
.attr("width", mapWidth)
.attr("height", mapHeight)
.attr("class", "svgDiv");
var svgMap = svgDiv.append("svg")
.attr("width", mapWidth)
.attr("height", mapHeight);
var svgBack = svgMap.append("rect")
.attr("width", mapWidth)
.attr("height", mapHeight)
.attr("pointer-events", "all")
.style("fill", "none")
.on("click", reset);
Adding .attr("overflow", "hidden") to SVG solve issue and no need in using <div>.
Working code looks so:
var mapWidth = 500,
mapHeight = 260;
var projection = d3.geo.albersUsa()
.scale(550)
.translate([mapWidth / 2, mapHeight / 2]);
var path = d3.geo.path()
.projection(projection);
var svgMap = d3.select("body").append("svg")
.attr("overflow", "hidden")
.attr("width", mapWidth)
.attr("height", mapHeight);
var svgBack = svgMap.append("rect")
.attr("width", mapWidth)
.attr("height", mapHeight)
.attr("pointer-events", "all")
.style("fill", "none")
.on("click", reset);

Drawing text inside D3 rect element?

I have code here and I need to add text into the rect element on the right of all the hexagons and have it act like a paragraph inside of a div with a given height and width and have it wrap properly. Here is the jsfiddle. and the code that draws the rect is below:
http://jsfiddle.net/2nykc/
var infoRect = svgContainer.append("rect");
var infoRectAttr = infoRect.attr("x", function(){
return infoDivX;
})
.attr("y", function(){
return infoDivY;
})
.attr("width", function(){
return infoDivWidth;
})
.attr("height", function(){
return infoDivHeight;
})
.style("fill", "rgb(30,180,134)")
.style("stroke", "black")
.style("stroke-width", 3)
.attr("id", "infoRect");

d3.js - Zoom and Center on Click - Map scales, points do not

I'm adapting the zoomable and clickable map found http://bl.ocks.org/mbostock/2206340 at to plot some points and do some other things. Right now, I'm trying to make it such that on the zoom and click actions, the plotted points also move / honor the zoom. I'm not sure what in the code here is wrong, since I seem to be calling the red.circle and blue.circle objects in the zoom + click -- can anyone identify the issue? Thanks! data.csv is formatted as follows:
lon_0,lat_0,lon_1,lat_1
-122.1430195,37.4418834,-122.415278,37.778643
-122.1430195,37.4418834,-122.40815,37.785034
-122.4194155,37.7749295,-122.4330827,37.7851673
-122.4194155,37.7749295,-122.4330827,37.7851673
-118.4911912,34.0194543,-118.3672828,33.9164666
-121.8374777,39.7284944,-121.8498415,39.7241178
-115.172816,36.114646,-115.078011,36.1586877
and here is the d3.js script.
.background {
fill: none;
pointer-events: all;
}
#states path {
fill: #aaa;
stroke: #fff;
stroke-width: 1.5px;
}
#states path:hover {
stroke: white;
}
</style>
<body>
<script>
var width = 1920/2,
height = 1000/2;
var projection = d3.geo.albersUsa()
.scale(width)
.translate([width / 2, height / 2]);
var path = d3.geo.path()
.projection(projection);
var zoom = d3.behavior.zoom()
.translate(projection.translate())
.scale(projection.scale())
.scaleExtent([height, 50 * height])
.on("zoom", zoom);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.attr("style", "stroke:black; stroke-width:2px");
var states = svg.append("g")
.attr("id", "states")
.call(zoom);
var dataset = [];
states.append("rect")
.attr("class", "background")
.attr("width", width)
.attr("height", height);
d3.json("us-states.json", function(json) {
states.selectAll("path")
.data(json.features)
.enter().append("path")
.attr("d", path)
.on("click", click);
d3.csv("data.csv", function(data) {
states.selectAll(".blue.circle")
.data(data)
.enter()
.append("circle")
.attr("cx", function(d) {
return projection([d["lon_0"], d["lat_0"] ])[0];
})
.attr("cy", function(d) {
return projection([d["lon_0"],d["lat_0"] ])[1];
})
.attr("r", 5)
.attr("class", "blue circle")
.style("fill", "blue");
states.selectAll(".red.circle")
.data(data)
.enter()
.append("circle")
.attr("cx", function(d) {
return projection([+d["lon_1"], +d["lat_1"] ])[0];
})
.attr("cy", function(d) {
return projection([+d["lon_1"],+d["lat_1"] ])[1];
})
.attr("r", 5)
.attr("class", "red circle")
.style("fill", "red");
});
});
function click(d) {
var centroid = path.centroid(d),
translate = projection.translate();
projection.translate([
translate[0] - centroid[0] + width / 2,
translate[1] - centroid[1] + height / 2
]);
zoom.translate(projection.translate());
states.selectAll("path").transition()
.duration(1000)
.attr("d", path);
states.selectAll("red.circle").transition()
.duration(1000)
.attr("d", circle);
states.selectAll("blue.circle").transition()
.duration(1000)
.attr("d", circle);
}
function zoom() {
projection.translate(d3.event.translate).scale(d3.event.scale);
states.selectAll("path").attr("d", path);
states.selectAll("red.circle").attr("d", path);
states.selectAll("blue.circle").attr("d",path);
}
</script>
you're setting the co-ordinates of the circles when you load the map, so when you click the zoom function, your circles are displayed but are not using the same co-ordinates - i think - it will help if you can create a http://bl.ocks.org to see this.
perhaps this could be of help http://bl.ocks.org/nkhine/3150901 only UK, US and Afganistan works, but i am basically re-projecting the secondary map to fit the new zoom level.

Resources