かずきのBlog@hatena

日本マイクロソフトに勤めています。XAML + C#の組み合わせをメインに、たまにASP.NETやJavaなどの.NET系以外のことも書いています。掲載内容は個人の見解であり、所属する企業を代表するものではありません。

x軸のラベルに改行を入れたい

まぁそんなこともあるってことで。

元データがyyyyMMddHHmmssみたいなデータでこれを…

MM/dd
HH:mm

みたいにラベルに表示したいってときです。ぐぐったらstackoverflowに答えが。もとのラベル決して、tspanでテキスト区切って座標の調整が必要みたいです。

ということで、TypeScriptのプロジェクト作ってd3をNuGetで入れて以下のコードをapp.tsに追加して実行!

/// <reference path="scripts/typings/d3/d3.d.ts" />
class Data {
    constructor(public date: string, public value: number) { }
}

window.onload = () => {
    var layout = {
        width: 500,
        height: 500,
        padding: 50,
    };

    var org = d3.range(0, 10, 1).map(v => new Data("200010011010", 0 | Math.random() * 100));
    var data = org.map((d, i) => { return { id: i, data: d } });

    var xScale = d3.scale.linear().domain([0, 9]).range([layout.padding, 500]);
    var yScale = d3.scale.linear().domain([0, 100]).range([layout.height, layout.padding]);

    var xAxis = d3.svg.axis().scale(xScale).orient("bottom");
    var yAxis = d3.svg.axis().scale(yScale).orient("left");

    var svg = d3.select("#content")
        .append("svg")
        .attr("width", layout.width)
        .attr("height", layout.height);

    // 軸を作成
    svg.append("g")
        .attr("class", "axis x")
        .call(xAxis)
        .attr("transform", "translate(0, " + layout.width + ")");
    svg.append("g")
        .attr("class", "axis")
        .call(yAxis)
        .attr("transform", "translate(" + layout.padding + ", 0)");

    // 点をうつ
    svg.selectAll("circle")
        .data(data)
        .enter()
        .append("circle")
        .attr("cx", d => xScale(d.id))
        .attr("cy", d => yScale(d.data.value))
        .attr("fill", "steelblue")
        .attr("r", 3);

    // ここから下が今回のポイント
    // 全てのx軸のテキストに対して処理をする
    svg.selectAll("g.axis.x text")
        // thisが現在の要素なのでfunctionにする
        .each(function (v, index) {
            var textElement = d3.select(this);
            // データからもとになるテキストを取得してばらす
            var str = data[index].data.date;
            var month = str.substr(4, 2);
            var day = str.substr(6, 2);
            var hour = str.substr(8, 2);
            var min = str.substr(10, 2);
            // 一行目のデータ
            var dateText = month + "/" + day;
            // 二行目のデータ
            var timeText = hour + ":" + min;

            // 元のテキストを削除して
            textElement.text("");
            // 一行目のデータを追加して
            textElement.append("tspan").text(dateText);
            // 二行目のデータを追加する。位置は微調整が必要
            textElement.append("tspan")
                .attr("x", 0)
                .attr("dy", 10)
                .text(timeText);
        });
};

実行すると、X軸のラベル改行されてる。ふむ。もうちょい楽にやりたいね…。

f:id:okazuki:20140224004248j:plain