web-dev-qa-db-ja.com

1つのhtmlページに複数のd3.jsチャートを表示する

貼り付けたd3.jsコード here があります。

同じページに複数のグラフを表示しようとしています。 d3.jsコードは同じですが。 1つをdata1.jsonから、もう1つをdata2.jsonから言います。以下は私を悩ませているスニペットです。

<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 + ")");

SO herehereherehere の異なる回答に従ってまたは ここ 、解決策は次のいずれかであるようです:

  • 別の変数名を使用して、svg1、svg2 ..などのsvgを保持します。
  • ここ に記載されている方法を使用します。

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

方法2では空白のページが表示されるため、機能しません。

これを解決する方法。構文を正しく取得していないと思います。

9
kingmakerking

同じページで複数のSVGを使用してもまったく問題ありません。次に例を示します。

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>
7

現在行っているように、すべてのコードを繰り返す必要はありません。 自分を繰り返さないでください

簡単な代替策は、すべてのD3コードを、2つのパラメーターselectorおよびurlを持つ関数にラップすることです。

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

次に、その関数draw内で、SVGの位置を設定します。

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

そして、あなたがデータを取得するURL:

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

その後、引数を変えてdraw関数を2回呼び出すだけです。

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

ここにデモがありますので、よく読んで動作を確認してください。

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>
3
Gerardo Furtado

2つのグラフが同じコードを使用している場合、それを実行するための最もd3のような方法は、

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

次に、新しく追加された各svgにjson1とjson2をバインドし、その後に続くすべてのコードを両方に対して実行します。

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
Ryan Lee Simms