d3 ignore SVG on selectAll - javascript

Still learning d3.js.
I would like to ignore the selection of an SVG panel when using .selectAll("svg").
I am building a visualization comprising four SVG panels. The top SVG panel is used to display header/title information for the visualization.
var svgHeader = d3.select("body")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", 100)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.append("g");
The next two SVG panels are dynamically created using a range of two numbers representing two years.
var svg = d3.select("body")
.selectAll("svg")
.data(d3.range(2012, 2013))
.enter().append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", 200)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.append("g");
The final SVG contains detail information as the user interacts with the visualization.
Problem: I want to exclude the first SVG panel from the .selectAll("svg") which is used to create the two middle panels. I would like to dynamically build SVG panels and have them locate underneath the previously created header SVG.
Is there any way to exclude the header SVG when dynamically creating the middle panels?

I think the best way you should be going about this is taking advantage of classes and adding an appropriate class to the different svgs and then selecting based on the class rather than the svg. This way you know what each of the svgs represent and you can easily reference them.'
var svgHeader = d3.select("body")
.append("svg")
.attr("class", "svgHeader")
.attr("width", width + margin.left + margin.right)
.attr("height", 100)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.append("g");
And then the other two you add a different class name
var svg = d3.select("body")
.selectAll("svg")
.data(d3.range(2012, 2013))
.enter().append("svg")
.attr("class", "data")
.attr("width", width + margin.left + margin.right)
.attr("height", 200)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.append("g");
Now you can do d3.selectAll("svg.data") and select only svg elements with the class data

Alternatively, you can embed your svg elements in different divs. Assuming you have a div whose id is 'center-div' the following snippet returns you only the svgs contained in it.
d3.selectAll("#center-div svg")
Please also consider that you can append whatever DOM element via d3, so divs can be dinamically generated.

Related

SVG not displaying correctly in D3.js dataviz

In this datavisualization, I have a curious problem : my svg is not correctly aligned with the whole container.
I'm using a viewbox:
var svg = d3.select("#viz")
.attr("viewBox", [
margin.left,
margin.top,
(width+margin.left),
(height+margin.bottom)
].join(" "))
.append("svg")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
Does anyone have any idea why?

SVG element produced by JavaScript script jumps out from the div

I have created GANTT chart using D3 Gannt Chart (http://bl.ocks.org/dk8996/5449641). I embed it to an div that I wish to position as following:
<div id="gantt" class="container">
<div id="gantt-deep">
<script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="js/lib/gantt-chart-d3v2.js"></script>
<script type="text/javascript" src="js/gantt.js"></script>
</div>
</div>
The problem is that when I run the code the SVG created by the script jumps out of the div as seen in the following code when looked in Firefox:
<div id="gantt" class="container">
<div id="gantt-deep">
<script src="http://d3js.org/d3.v3.min.js" type="text/javascript">
<script src="js/lib/gantt-chart-d3v2.js" type="text/javascript">
<script src="js/gantt.js" type="text/javascript">
</div>
</div>
<svg class="chart" width="990" height="490">
<g class="gantt-chart" width="990" height="490" transform="translate(150, 20)">
</svg>
My question is how do I position that svg element that is created?
In gnatt-chart-d3v2.js that was included in the example you provided there's the following line:
var svg = d3.select("body")
.append("svg")
.attr("class", "chart")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("class", "gantt-chart")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("transform", "translate(" + margin.left + ", " + margin.top + ")");
From what I can tell this appends an svg element to the body. That's why the svg "jumps" out of your div - because it is appended to the body, not inserted where you include the script tags.
A possible solution to this would be to change "body" to whatever element you want to append the svg to, in your case it would be #gantt-deep, as you want to target the div with id gantt-deep.
This is a one-time solution, because it modifies the source code which doesn't allow for inserting an svg wherever. If you need another chart then you'd have to pass in a parameter to that gnatt function to indicate where you want it.
Actually, here's the modified version of gnatt-chart-d3v2.js:
// some code here
function gantt(tasks, element) { // modified this line
initTimeDomain();
initAxis();
var svg = d3.select(element) // modified this line
.append("svg")
.attr("class", "chart")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("class", "gantt-chart")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.attr("transform", "translate(" + margin.left + ", " + margin.top + ")");
// leave the rest untouched
And then when you initiate the chart call the function with another parameter, for instance gantt(tasks, "#gantt-deep");
I didn't test this, but it should work.

D3 updating data on box plot without removing previous SVG first

I'm following the box plot on this page Box Plot Link. In this example it reads in the box plot values from a data file. I'm trying to add a button that will read in new data from another data file and update the box plot.
Here's the code they use to first create the box plot.
var svg = d3.select("#viz").selectAll("svg")
.data(data)
.enter().append("svg")
.attr("class", "box")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.bottom + margin.top)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(chart.duration(1000));
and this to update the box plots every second
setInterval(function() {
svg.datum(randomize).call(chart.duration(1000));
}, 2000);
When I click on the update button it calls my snippet here:
var svg = d3.select("#viz").selectAll("svg")
.data(data)
.enter().append("svg")
.attr("class", "box")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.bottom + margin.top)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.call(chart.duration(1000));
However this won't update my boxplot. If I want the box plot to change, I have to first remove the box plot SVG first
d3.selectAll('svg').remove();
But I'd like to have an transition rather than new box plots. Why do I have to remove the previous SVG first? Any help?
So I made the following changes to the update of the data
var svg = d3.select("#viz").selectAll("svg").data(data)
svg.call(chart.duration(duration));
svg.enter().append("svg")
.attr("class", "box")
.attr("id", function (d, i) {
return "box_" + i;
})
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.bottom + margin.top)
.append("g")
.attr("id", function (d, i) {
return "g_" + i;
})
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(chart.duration(duration))
svg.exit().remove();
and there is actually some bugs with that box.js code that needs to be fixed which I found about here:
D3 Datum Update Boxplot

Loading d3 bullet chart into a span

I'm attempting to load a d3.js bullet chart into an existing svg object:
<span id='element'><svg class="elm_12"></svg></span>
and in the js:
var svg = d3.select(elementid)
.data(data)
.enter().append("svg")
.attr("class", "bullet")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(chart);
I assume I can't add an svg element to an existing svg element. Any thoughts on the best way to accomplish this?
I was going to place this as a comment but there are simply too many code statements. What about this:
<span id='element'></span>
...
var svg = d3.select("#element")
.append("svg")
.attr("class", "bullet")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
svg
.data(data)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(chart);
Actually, this was enough for me to figure it out - THANK YOU.
var svg = d3.select(elementid)
.data(data)
.enter()
.append("svg")
.attr("class", "bullet")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.call(chart);

Set background for d3.js collabsible tree

I create a collabsible tree like in this example (http://bl.ocks.org/mbostock/4339083). I tried to change the background color of the SVG. Therefor I use a "rect" element before inserting the "g" element:
svg = d3.select("#"+targetDIVName).append("svg")
.attr("width", width + margin.right + margin.left)
.attr("height", height + margin.top + margin.bottom)
.attr("id", "svg_graph")
.append("rect")
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", "green") //for example
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
With this method the graph is hidden. Is there any solution to set the "rect" element as background and get the graph visible?
Thank You
SVG elements are drawn in the order in which they are added. So if you want the rect to be in the background, add it as the first element after creating the SVG.
To get a solid background colour, you could alternatively use the viewport-fill attribute, which is not supported by all browsers though.

Categories