最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Display multiple d3.js charts in a single html page - Stack Overflow

programmeradmin2浏览0评论

I have the the d3.js code which is pasted here.

I am trying to display more than one graphs in the same page. Though the d3.js code is same. Say one from data1.json and the other from data2.json. Following is the snippet which is bothering me.

<svg width="960" height="960"></svg>

<script src=".v4.min.js"></script>
<script>
var svg2 = d3.select("svg"),
    margin = 20,
    diameter = +svg2.attr("width"),
    g = svg2.append("g").attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")");

As per different answers in SO here, here, here, here or here, the solution seems to be one of the following:

  • Use different variable name to hold svgs such as svg1, svg2.. etc.. which I have done.
  • Use a method as described here.

       var chart1 = d3.select("#area1")
           .append("svg")
    

Method two is not working for me, as it shows blank page.

How to resolve this. I am sure that I am not getting the syntax correctly.

I have the the d3.js code which is pasted here.

I am trying to display more than one graphs in the same page. Though the d3.js code is same. Say one from data1.json and the other from data2.json. Following is the snippet which is bothering me.

<svg width="960" height="960"></svg>

<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var svg2 = d3.select("svg"),
    margin = 20,
    diameter = +svg2.attr("width"),
    g = svg2.append("g").attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")");

As per different answers in SO here, here, here, here or here, the solution seems to be one of the following:

  • Use different variable name to hold svgs such as svg1, svg2.. etc.. which I have done.
  • Use a method as described here.

       var chart1 = d3.select("#area1")
           .append("svg")
    

Method two is not working for me, as it shows blank page.

How to resolve this. I am sure that I am not getting the syntax correctly.

Share Improve this question asked Jan 30, 2017 at 16:09 kingmakerkingkingmakerking 2,0893 gold badges29 silver badges46 bronze badges 1
  • You seem to be using one svg for multiple graphs (you only have one svg element)? Method two - do you have a html element with an id="area1"? Have you checked your developers console for any errors? – Craicerjack Commented Jan 30, 2017 at 16:16
Add a comment  | 

3 Answers 3

Reset to default 13

There's no problem at all using multiple SVGs on the same page. Here's an example:

var svg1 = d3.select("#svg1");
svg1.append("circle")
       .attr("cx",100)
       .attr("cy", 100)
       .attr("r", 90)
       .attr("fill", "red");
var svg2 = d3.select("#svg2");
svg2.append("circle")
       .attr("cx",100)
       .attr("cy", 100)
       .attr("r", 90)
       .attr("fill", "blue");
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg width="200" height="200" id="svg1"></svg>
<svg width="200" height="200" id="svg2"></svg>

There is no need for repeating all the code, as you're doing right now. Don't repeat yourself.

An easy alternative is wrapping all your D3 code in a function that has two parameters, selector and url:

function draw(selector, url){
    //code here
};

Then, inside that function draw, you set the position of your SVG:

var svg = d3.select(selector).append("svg")...

And the URL you get the data:

d3.json(ulr, function(error, root) {...

After that, just call the draw function twice, with different arguments:

draw(selector1, url1);
draw(selector2, url2);

Here is a demo, read it carefully to see how it works:

draw("#svg1", "#data1");
draw("#svg2", "#data2");

function draw(selector, url){

var data = d3.csvParse(d3.select(url).text())

var width = 500,
    height = 150;

var svg = d3.select(selector)
    .append("svg")
    .attr("width", width)
    .attr("height", height);

var xScale = d3.scalePoint()
    .domain(data.map(function(d) {
        return d.name
    }))
    .range([50, width - 50])
    .padding(0.5);

var yScale = d3.scaleLinear()
    .domain([0, d3.max(data, function(d) {
        return d.value
    }) * 1.1])
    .range([height - 20, 6]);

var line = d3.line()
	.x(function(d){ return xScale(d.name)})
	.y(function(d){ return yScale(d.value)});
	
svg.append("path")
	.attr("d", line(data))
	.attr("stroke", "teal")
	.attr("stroke-width", "2")
	.attr("fill", "none");

var xAxis = d3.axisBottom(xScale);
var yAxis = d3.axisLeft(yScale);

svg.append("g").attr("transform", "translate(0,130)")
    .attr("class", "xAxis")
    .call(xAxis);

svg.append("g")
    .attr("transform", "translate(50,0)")
    .attr("class", "yAxis")
    .call(yAxis);

}
pre {
display: none;
}
<script src="https://d3js.org/d3.v4.min.js"></script>
<div>First SVG</div>
<div id="svg1"></div>
<div>Second SVG</div>
<div id="svg2"></div>
<pre id="data1">name,value
foo,8
bar,1
baz,7
foobar,9
foobaz,4</pre>
<pre id="data2">name,value
foo,1
bar,2
baz,3
foobar,9
foobaz,8</pre>

If the two charts use the same code, I think the most d3-like way to go about it would be

var width = 960,
    height = 960,
    margin = 30;

var svgs = d3.select('#area1')
    .selectAll('svg')
    .data([json1, json2])
    .enter()
    .append('svg')
    .attr('width', width)
    .attr('height', height)

svgs.append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
    .each(function(d) {console.log(d)}) // will log json1, then json2

You'll then have json1 and json2 bound to each of the newly appended svgs, and all code that follows will be done to both.

var width = 200,
    height = 100,
    margin = 30;

var svgs = d3.select('#area1')
    .selectAll('svg')
    .data([{text:'thing1'}, {text:'thing2'}])
    .enter()
    .append('svg')
    .attr('width', width)
    .attr('height', height);

svgs.append("text")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
    .text(function(d) {return d.text});
<script src="https://d3js.org/d3.v4.js"></script>
<div id='area1'></div>

发布评论

评论列表(0)

  1. 暂无评论