1

d3.jsで作業して、カテゴリ別の時系列データを表示するための良い方法を探しています。データ値は同時に発生することはできず、等間隔ではないため、次のようなデータを使用しています。

location = [[time1: home], [time4: work], [time5: cafe], [time7: home]]

等々。私の理想的な結果のグラフは、エボルストリップと呼ばれるもののようなものです。このチャートを表示する1つの方法は、カテゴリに対応するバーの色(「ホーム」など)の可変幅のバーを含む時系列チャートです。

誰かが私を正しい方向に向けることができますか?どうもありがとう!

4

1 に答える 1

1

そのため、独自の d3.js ソリューションを作成することになりました。

時間ディメンションには d3.time.scale スケールを使用し、次に d3.scale.category20 スケールを使用してカテゴリの色を指定しました。次に、カテゴリ データを時間軸上で開始時間ごとに同じ高さの四角形としてプロットし、d3.time.scale スケールを使用して、各四角形の適切なビン幅を計算しました。

再利用可能なコンポーネント ( http://bost.ocks.org/mike/chart/のパターンに従う) の例を以下に示します。

function timeSeriesCategorical() {
    var w = 860,
        h = 70,
        margin = {top: 20, right: 80, bottom: 30, left: 50},
        width = w - margin.left - margin.right,
        height = h - margin.top - margin.bottom;
    var xValue = function(d) { return d[0]; },
        yValue = function(d) { return d[1]; };
    var yDomain = null;
    var xScale = d3.time.scale()
        .range([0, width]);
    var yScale = d3.scale.category20();
    var xAxis = d3.svg.axis()
        .scale(xScale)
        .tickSubdivide(1)
        .tickSize(-height)
        .orient('bottom');
    var yAxis = d3.svg.axis()
        .scale(yScale)
        .ticks(5)
        .orient('left');
    var binwidth = 20;

    function chart(selection) {
        selection.each(function(data) {

            // convert data to standard representation
            data = data.map(function(d, i) {
                return [xValue.call(data, d, i), yValue.call(data, d, i)];
                //return d;
            });

            // scale the x and y domains based on the actual data
            xScale.domain(d3.extent(data, function(d) { return d[0]; }));
            if (!yDomain) {
                yScale.domain(d3.extent(data, function(d) { return d[1]; }));
            } else {
                yScale.domain(yDomain);
            }

            // compute binwidths for TODO better comment
            // d looks like {timestamp, category}
            data.forEach(function(d, i) {
                if (data[i+1]) {
                    w_current = xScale(data[i][0]);
                    w_next = xScale(data[i+1][0]);
                    binwidth = w_next - w_current;
                }
                d.binwidth = binwidth;
            });

            // create chart space as svg
            // note: 'this' el should not contain svg already
            var svg = d3.select(this).append('svg').data(data);

            // external dimensions
            svg.attr('width', w)
                .attr('height', h);

            // internal dimensions
            svg = svg.append('g')
                .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')');

            // x axis
            svg.append('g')
                .attr('class', 'x axis')
                .attr('transform', 'translate(0,' + height + ')')
                .call(xAxis);

            // TODO bars legend

            // bars
            svg.selectAll('rect')
                .data(data)
              .enter().append('rect')
                .attr('x', function(d, i) { return xScale(d[0]); })
                .attr('width', function(d, i) { return d.binwidth; })
                .attr('height', height)
                .attr('fill', function(d, i) { return yScale(d[1]); })
                .attr('stroke', function(d, i) { return yScale(d[1]); });

        });
    }

    chart.x = function(_) {
        if (!arguments.length) return xValue;
        xValue = _;
        return chart;
    };

    chart.y = function(_) {
        if (!arguments.length) return yValue;
        yValue = _;
        return chart;
    };

    chart.yDomain = function(_) {
        if (!arguments.length) return yDomain;
        yDomain = _;
        return chart;
    };

    return chart;
}

そして、次のようなもので呼び出すことができます:

d3.csv('./data.csv', function(data) {
     var chartActivity = timeSeriesCategorical()
        .x(function(d) { return d.when; })
        .y(function(d) { return d.activity; })
        .yDomain([0,1]);
     d3.select('#chart-activity')
        .datum(data)
        .call(chartActivity);
});

うまくいけば、これは誰かに役立ちます! これが作成されたプロジェクトはhttps://github.com/interaction-design-lab/stress-sense-portalにあります

于 2013-02-15T15:52:34.183 に答える