2017-08-19 17 views
0

ラジオボタンをクリックするとdata1.jsonまたはdata2.jsonが表示される棒グラフがあります。d3棒グラフ要素数が異なる場合のティックの棒グラフの整列

data1.jsonには9個の要素があり、data2.jsonには4個の要素があります。

質問1:データのオブジェクトやバーの数にかかわらず、棒が常にティックの中央にくるように設定するにはどうすればよいですか?

質問2: x軸をどのようにして期待できるところまで下げることができますか?私はこれが些細なことを知っているが、私は多くの方法を試した。

質問3:私は確信して「の値が」

newdata.foreach(function(d) { 
     d.value = +d.value; 
    }) 

を使用して数ですが、私が期待するように私は「NEWDATA」を反復することはできていないようしたいと思います。

これはgithub heregh-pages demo hereです。

index.htmlファイル

<!DOCTYPE html> 
<meta charset="utf-8"> 
<style> 
    .bar { 
    fill: steelblue; 
    } 
    .bar:hover { 
    fill: brown; 
    } 
    .axis text { 
    font: 10px sans-serif; 
    } 
    .axis path, 
    .axis line { 
    fill: none; 
    stroke: #000; 
    shape-rendering: crispEdges; 
    } 
</style> 

<body> 
    <form> 
    <input type="radio" name="inputsrc" id="defaultInput" value="default" checked=""><label for="defaultInput">data1.json</label> 
    <input type="radio" name="inputsrc" id="updateInput" value="post"><label for="updateInput">data2.json</label> 
    </form> 
    <svg id="d3newbie-chart" width="600" height="400"> 
    </svg> 
    <script src="https://d3js.org/d3.v4.min.js"></script> 

    <script type="text/javascript"> 
    var outerWidth = 600, 
     outerHeight = 400; 
    var margin = { 
     top: 40, 
     right: 30, 
     bottom: 30, 
     left: 80 
     }, 
     width = outerWidth - margin.left - margin.right, 
     height = outerHeight - margin.top - margin.bottom; 
    var x = d3.scaleBand() 
     .range([0, width]); 
    var y = d3.scaleLinear() 
     .range([height, 0]); 
    var xAxis = d3.axisBottom(x); 
    var yAxis = d3.axisLeft(y) 
     .ticks(10, "%"); 
    var chart = d3.select("#d3newbie-chart") 
     .attr("width", outerWidth) 
     .attr("height", outerHeight) 
     .append("g") 
     .attr("transform", "translate(" + margin.left + "," + margin.top + ")") 
    // x-axis 
    chart.append("g") 
     .attr("class", "x axis") 
     .attr("transform", "translate(0," + height + ")") 
     .call(xAxis); 

    function defaultFunction() { 
     d3.json("data1.json", function(error, newdata) { 
     if (error) throw error; 
     data = newdata; 
     // newdata.foreach(function(d) { 
     // d.value = +d.value; 
     // }) 
     update(); 
     }); 
    } 
    function updateFunction() { 
     d3.json("data2.json", function(error, newdata) { 
     if (error) throw error; 
     data = newdata; 
     update(); 
     }); 
    } 
    function update(err, newdata) { 
     y.domain([0, d3.max(data, function(d) { 
     return d.value; 
     })]); 
     x.domain(data.map(function(d) { 
     return d.name 
     })); 
     // x-axis 
     chart.select(".x.axis").remove(); 
     chart.append("g") 
     .attr("class", "x axis") 
     .call(xAxis) 
     .append("text") 
     .attr("transform", "rotate(-90)") 
     .attr("y", 6) 
     .attr("dy", ".71em") 
     .style("text-anchor", "end") 
     .text("Frequency"); 
     // y-axis 
     chart.select(".y.axis").remove(); 
     chart.append("g") 
     .attr("class", "y axis") 
     .call(yAxis) 
     .append("text") 
     .attr("transform", "rotate(-90)") 
     .attr("y", 6) 
     .attr("dy", ".71em") 
     .style("text-anchor", "end") 
     .text("Frequency"); 
     var bar = chart.selectAll(".bar") 
     .data(data, function(d) { 
      return d.name; 
     }); 
     // new data: 
     bar.enter().append("rect") 
     .attr("class", "bar") 
     .attr("x", function(d) { 
      return x(d.name); 
     }) 
     .attr("y", function(d) { 
      return y(d.value); 
     }) 
     .attr("height", function(d) { 
      return height - y(d.value); 
     }) 
     .attr("width", 20); 
     // removed data: 
     bar.exit().remove(); 
     // updated data: 
     bar.transition() 
     .duration(750) 
     .attr("y", function(d) { 
      return y(d.value); 
     }) 
     .attr("height", function(d) { 
      return height - y(d.value); 
     }); 
    }; 
    document.getElementById("defaultInput") 
     .onclick = defaultFunction; 
    document.getElementById("updateInput") 
     .onclick = updateFunction; 
    defaultFunction(); 
    </script> 
</body> 

答えて

1

更新コード:https://jsfiddle.net/5j2nw238/2/

質問1:バーの幅はsvgの幅だけでなく、あなたのために与えられた値によって決定されますscaleBandファンクションpaddingInner,paddingOuterなどがあります。

https://github.com/d3/d3-scale/blob/master/README.md#band-scales

これらのパラメータを記述した画像を見てみましょう。ポイントは、.attr("width", 20);のようにバーの幅をハードコードしないで、代わりにscaleBandを操作して希望の外観を見つけることです。

質問2:

あなたはコード

chart.append("g") 
    .attr("class", "x axis") 
    .attr("transform", "translate(0," + height + ")") 
    .call(xAxis); 

で正しくこれをしなかった。しかし、その後の更新時に、あなたは軸を削除して、再度変換を適用しませんでした。軸を削除して再作成する代わりに、軸スケールを新しいドメインで更新し、chart.select(".x.axis").call(xAxis)を実行するだけです。これは、データ駆動の方法でd3の考え方に沿ったものになります。データを変更し、D3でDOMを処理させます。

質問3:

関数名がforEach、ないforeachです。また、値が文字列であることを確認したいとしますが、変数の前に+演算子を置くと、文字列ではなく数値に変換されます。

+0

鮮やかな回答、ありがとうございます。私は完全に今質問2と3を理解しています。私は実際には、データが数字に変換される文字列であることを保証しています。質問1に取り組むのに少し時間がかかります。github repoはこれらの変更を反映するようになりました。もう一度ありがとう –

+0

私は値が文字列になるように言いました。文字列を数値にしたいという意味です。 –

+0

私はあなたがgithubからjsonを引っ張ったのを見ます、私はそれが可能であることを知らなかった。非常に便利!私はjsonを導入する方法を知らなかったので、私はjsfiddleを設定しませんでした。素晴らしい、ありがとう、もう一度! –

関連する問題