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.
Related
I have a script, that works fine and create a chord diagram I need.
But now I want to create the same .svg file on another div but with different matrix.
Should I duplicate the same script for a new svg, or I can do in more efficient way?
You can find my code here.
Now my .Js script use drawChordWithMatrix(matrix_T1_T2) to show chord on div with id chart
What should I do to run drawChordWithMatrix(matrix_T2_T3) on id chart1
One way i can think is
1) Move the SVG creation into the drawChordWithMatrix
So you need to pass the id to which you need to attach the SVG.
something like this function drawChordWithMatrix(matrix, id), and you create your SVG in the function like this.
var svg = d3.select(id).append("svg")//selecting on basis of ID.
.attr("width", (width + margin.left + margin.right))
.attr("height", (height + margin.top + margin.bottom));
2) Next move all functions like fade, fadeOnChord , etc.. into the drawChordWithMatrix so that they all have the same scope.
working code here
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.
Is there any way to shrink my SVG graphic to fit the printing page, while leaving the web version of the graphic as it is? Or am I wasting my time?
I can only use FF at the moment but of course a cross-browser approach is even better...
Is there a CSS version of viewBox that I can put in a media
query?
Is there an onPrint event in js where I could apply
viewBox?
Any other approach - javascript, css, jquery, d3 all
welcome.
Googling suggests "no" to 1 & 2 but many of the posts are old.
Latest approach:
var svg = d3.select("div#matrix").append("svg")
.attr("width", 1000)
.attr("height", 1000)
//.attr("viewBox","0 0 500 500") - I don't want to apply this to the webpage SVG - this is just for testing
//.attr("preserveAspectRatio","xMinYMin meet")
.attr("id","matrixSVG")
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
Once the text labels are added to the graphic I resize the container elements for the webpage:
var svgWidth = margin.left+margin.right+(cellSize*horizNodes.length);
var svgHeight = margin.top+margin.bottom+(cellSize*vertNodes.length);
d3.select("svg#matrixSVG").attr("width",svgWidth).attr("height",svgHeight);
d3.select("div#matrix").style("width",svgWidth+"px").style("height",svgHeight+"px");
CSS:
#media print {
svg#matrixSVG {
width: 175mm; //this is the max size to fit US letter and A4
height: 245mm;
}
}
Thanks for any help
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.
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)".