2016年3月18日金曜日

【TypeScript/JavaScript】d3.jsでグラフを作ろう(棒グラフ)

TypeScript及びJavaScriptを使って、グラフ作成する方法で、d3.jsを使う方法があります。
前回に続いて、グラフのつくり方を纏めてみました。

(1)データ
キー(label/value)と値(labelに対する値/valueに対する値)に値を設定したJsonデータを作成します。

            var res = [
                { label: "利益", value:  7943546 }
                , { label: "損失", value: 19508020 }
            ];



(2)線データ(ステップライン)の作成
idは、HTMLファイルdivタグ要素とします。
idにsvg要素を追加します。
widthは幅、marginは余白、heightは高さを表します。
svg要素を作成して、g要素を追加します。

                var svg = d3.select(id).append("svg")
                    .attr({
                        width: width,
                        height: height
                    })
                    .append("g")
                    .attr("transform", "translate(" + 200 + "," + 100 + ")");

taransformは位置を指定します。

棒(四角=rect)を定義します。
rectにクラス定義(bar)をして、CSSで色など属性を与えます。
               var rec = this.svg.selectAll(".bar")
                    .data(data)
                    .enter().append("rect")
                    .attr("class", "bar")
                    .attr("x", function (d) { return x(d.label); })
                    .attr("width", x.rangeBand())
                    .attr("style", "fill:" + barcolor)
                    .attr("style", "stroke:black")
                    .attr("y", function (d) { return height; })
                    .attr("height", function (d) {
                        return height - y(d.value);
                    })
                    .append("title")
                    .text(function (d) { return d.value.toLocaleString(); })
                    ;
                this.svg.selectAll("rect").attr("height", 0);



svg要素に棒グラフアニメーション(下から上に伸びる)定義します。
2秒間アニメーションを設定します。(transiton,durationを使用する)
                this.svg.selectAll("rect")
                    .transition().duration(2000)
                    .delay(function (d, i) {
                        return i * 300;
                    })
                    .attr("y", function (d) {
                        return y(d.value);
                    })
                    .attr("height", function (d) {
                        return height - y(d.value);
                    });

(2) 軸
d3.scale.ordinal() ・・・domain の配列の n 番目の値が、 range の配列の n 番目の値に対応
  ※こちらのサイトを一読すると理解しやすいです。
  http://blog.livedoor.jp/kamikaze_cyclone/archives/34197135.html
d3.scale.linear() ・・・ リニアスケールを設定
を使って、スケール定義します。

スケール定義することで、height/width内にデータが収まるように、スケールできるようになります。
            var x = d3.scale.ordinal().rangeRoundBands([0, width], 0.3);
            var y = d3.scale.linear().range([height, 0]);


 d3.svg.axis()を使って、軸を作成して、スケールとリンクさせます。
ticksで刻みも定義します。

            var xAxis = d3.svg.axis()
                .scale(x)
                .orient("bottom");
            var yAxis = d3.svg.axis()
                .ticks(5) // 軸のチックの数。
                .scale(y)
                .orient("left"); 

x,yの範囲を定義します。

           x.domain(data.map(function (d) { return d.label; }));
            var dmax = d3.max(data, function (d) { return d.value; });
            var no = String(dmax).length;
            var unit = Math.pow(10, no - 1);
            var res = Math.floor(dmax / unit);
            dmax = (res + 1) * unit;
            y.domain([0, dmax]);
            y.range([height, 0]);


X軸、y軸を追加します。
 classはaxisにして、CSSファイルに軸の属性定義を行います。
            this.svg.append("g")
                .attr("class", "axis")
                .attr("transform", "translate(0," + height + ")")
                .call(xAxis);
            this.svg.append("g")
                .attr("class", "axis")
                .call(yAxis);

横方向のグリッド間隔を自動生成します。
attrにて、属性定義を行います。
            var ts = height / (res + 1);
            var rangeY = d3.range(0, height, ts);
            this.svg.selectAll("line.y")
                .data(rangeY)
                .enter()
                .append("line")
                .attr("x1", 0).attr("y1", function (d, i) {
                    return d;
                })
                .attr("x2", width).attr("y2", function (d, i) { return d; });

            this.svg.selectAll("line")
                .attr("stroke", "black")
                .attr("stroke-width", 1)
                .attr("stroke-dasharray", "1, 3")
                .attr("shape-rendering", "crispEdges");

(4) 情報表示 
値棒グラフ上表示します。
クラスはbarvalとして、属性をCSSファイルで定義します。

            this.svg.selectAll(".barval")
                .data(data)
                .enter().append("text")
                .attr("class", "barval")
                .attr("x", function (d) {
                    return x(d.label) + 5;
                })
                .attr("y", function (d) {
                    return y(d.value) - 2;
                })
                .text(function (d) {
                    return d.value.toLocaleString();
                });



on("mouseover")で、円弧をbrawon色にして、infoクラス定義したg要素を表示させて、
そのg要素に情報表示させます。

on("mouseout")で色をbarcolorで定義した色に戻します。
            this.svg.selectAll("rect")
                .on("mouseover", function (d, i) {
                    d3.select(this).attr("style", "cursor:pointer");
                    d3.select(this).attr("style", "fill:brown");
                    d3.select(this).attr("style", "stroke:black");                
       .on("mouseout", function (d, i) {
                    var color = barcolor;
                    var rec = d3.select(id).select("svg");
                    d3.select(this).attr("style", "fill:" + color);
                    d3.select(this).attr("style", "stroke:black");
                });





0 件のコメント:

コメントを投稿