D3.js: what is 'g' in .append("g") D3.js code? - javascript

I am new to D3.js, started learning today only
I looked the the donut example and found this code
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
I searched for documentation, but did not understood what .append("g") is appending
Is it even D3 specific?
Looking for guidance here

It appends a 'g' element to the SVG. g element is used to group SVG shapes together, so no it's not d3 specific.

I came here from a d3 learning curve as well. As already pointed out this is not specific to d3, it is specific to svg attributes. Here is a really good tutorial explaining the advantages of svg:g (grouping).
It is not that different from the use case of "grouping" in graphical drawings such
as ones you would do in a powerpoint presentation.
http://tutorials.jenkov.com/svg/g-element.html
As pointed in above link: to translate you need to use translate(x,y):
The <g>-element doesn't have x and y attributes. To move the contents
of a <g>-element you can only do so using the transform attribute,
using the "translate" function, like this: transform="translate(x,y)".

Related

d3js Star Chart - responsive legend

I am working on a d3.js chart - This current model creates a legend segment as a g element. I'd like to ensure the legend stacks below if there is not enough room in the container.
//desktop - ample space
//mobile - not enough space
I've cleaned up the legend part -- you able to clean up the code base and add some more comments here. One of the old features I had - is if there wasn't enough room in the chart the legend stacks underneath - like responsive design - I used to create 2 svg parts but apparently with d3 it should only be 1 svg - http://jsfiddle.net/h066yn5u/13/
see if the chart can be more dynamic with different sizes - I think I had to add a padding of 10 to the radius to give it a little gap between the edges.. maybe though its a case of adding a transform on the svg itself to add that padding
var arcchart = chart.append("g")
.attr("class", "starchart")
.attr("transform", "translate("+(r+10)+"," + h / 2 + ")");
var legend = chart.append("g")
.attr("class", "legend")
.attr("transform", "translate(" + ((r + 10) * 2) + "," + (h / 4) + ")");
a version where it splits the chart into two svgs
http://jsfiddle.net/h066yn5u/14/
There are multiple ways to solve this issue.
Split into 2 svg containers: d3.js is not bound to just one svg container. You can split up the legend and the chart into 2 seperate svg containers and let the HTML handle the flow of the page
Use foreignObject: If you don't want to do that. You can try to use tag. Remember, that this is not supported by ie11 (and edge either afaik)
Calculate everything by hand: calculate the width of your legend (and including text), the width of the chart and get the available width for your whole container. If the whole container width is too small, push the legend below and of course adjust the svg height and width accordingly.

Trying to analyse why this transition is not happening

I have the following adapted d3.js visual and I'm unable to work out why the transition does not fire. The ars should rotate around to different sizes when the radio button is clicked.
It seems that clicking the radio button is changing the titles of the arc (if I hover the cursor over each)
Is this section of code to blame?
// check if svg group already exists
var svg = d3.select("#sunGroup");
if (svg.empty()) {
var svg = d3.select("#sunBurst")
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr({
'transform': "translate(" + width / 2 + "," + height * .52 + ")",
id: "sunGroup"
});
}
Here is the full (not) working example:
https://plnkr.co/edit/hpvREU?p=preview
This is the transition I'm trying to hold onto: plnkr.co/edit/NnQUAp?p=preview
What I trying to do is move the logic at line 128 (starting d3.selectAll("input").on("change", function change() {...) out of this function
An easy fix to your problem is to remove all children of the SVG whenever you switch data types:
d3.select("#sunBurst").selectAll('*').remove()
That way, you are binding the new data to new elements. You can also remove the svg.empty() and d3.select('#sunGroup') code. This simple fix lets you switch between pie charts, and is in the spirit of the code you currently have. Here's the users pie chart.
However, this may not be the best way to do what you're trying to achieve. As a reference, see Mike Bostock's General Update Pattern series (link is to first in the series) for how to update your SVG.

Implementing multiple D3 layout on same page

I tried to add multiple D3 graphs on same page i.e. Pie Chart, Bar Graph and a tree layout using different data in either CSV or JSON format. But I am not able to implement all of these 3 graphs on the same page. When I link more than 1 layout on a same page, I get a blank page.
I tried to append each chart in a different div using following HTML and JS
HTML
<div id="piediv"></div>
<div id="bardiv"></div>
<div id="treediv"></div>
JS
var svg = d3.select("#piediv").append("svg")
var svg = d3.select("#bardiv").append("svg")
var svg = d3.select("#treediv").append("svg")
All of the JS lines above are in their respective individual JS files viz. pie.js, bar.js and tree.js
First of all i suggest you to declare svg variables with a different names.
I made a fiddle for you with a similar problem; more in details, I have created two donut charts in the same page in this way:
I have created two different <div> with two different ids
<div id="chart"></div>
<div id="chart2"></div>
and I also created two different svgs (with different name)
var svg = d3.select("#chart").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var svg2 = d3.select("#chart2").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
Check the fiddle for more details
Let me know.

Adding text to the center of a D3 Donut Graph

Fiddle
I am trying to insert basically a label to the center of a donut graph using D3. I was able to work with an existing code I found and manipulate it so all the slices of the graph mesh in the middle to appear like there is a label there, but I think it'd be a better idea just to figure out how to make it a more permanent home in the center. I am very new to JS and D3.
Any help is grealty appreciated.
Thank you
This is currently the code that is falsifying a label being in the center.
svg.selectAll("text").data(pie(data)).enter()
.append("text")
.attr("class","label1")
.attr("transform", function(d) {
var dist=radius-120;
var winkel=(d.startAngle+d.endAngle)/2;
var x=dist*Math.sin(winkel)-4;
var y=-dist*Math.cos(winkel)-4;
return "translate(" + x + "," + y + ")";
})
You can simplify your code quite a bit. Since you are already centering the pie chart:
var svg = d3.select("#svgContent").append("svg")
.attr("width",width)
.attr("height",height)
.append("g")
.attr("transform","translate("+width/2+","+height/2+")");
You can just add the text as follows:
svg.append("text")
.attr("text-anchor", "middle")
.text("$" + totalValue);
Note that since you are only adding one <text>, you don't need to bind any data to it, and can pass .text(...) a value directly instead of a function.

d3 Nested SVG plots differently in firefox than in Chrome

I've seen versions of this question but they haven't helped me to solve this issue. I am using d3 with a nested svg, 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 + ")");
The nestedSVG makes an inner height/width so that some plots get cutoff appropriately. This works perfectly in firefox, but not in Chrome. When I scroll over nestedSVG in firebug it shows the appropriate dimensions, but when I scroll over nestedSVG in javascript console in chrome the dimensions are altered. This results in the plots being different. Any clue as to why this is happening?
The ability to set a transform on an <svg> element is new in SVG 2 and is not yet widely supported. Firefox does support it, IE does not currently, not sure about other UAs.

Categories