web-dev-qa-db-ja.com

c3js›時系列x値が等間隔ではない

グラフの値に割り当てられたラベルに問題があります。

グラフは時系列です。 c3jsの「columns」プロパティを使用して値を追加します。

純粋なタイムスタンプ(秒単位)を使用し、label.formatを使用してそれらを文字列に変換します。

ただし、これが発生します。

https://drive.google.com/file/d/0B9GDftIYQFIVb2Z3N2JfS2pzVjg/view?usp=sharing

スペースが均等に分散されていないことがわかるように、10月18日から21日、25日から28日、11月1日から4日から7日の間は、わずか2日ですが、他のすべての日は3日です。

これは何が原因ですか?

均等に間隔を空けたい(同じ日数)。

ここにコードのjfiddleがあります:http://jsfiddle.net/ok1k6yjo/

var array_times = [1414540800, 1414627200];
var array_values = [67, 66.22];

var labelWeight = 'weight in kg';

var window_period = (30 * 24 * 3600); // last 30 days

var today = Math.floor(new Date(2014,10,20,0,0,0,0).getTime() / 1000);
var timeEnd = today;
var timeStart = today - window_period;

var toShowTime = [1414540800, 1414627200];
var toShowValues = [67, 66.22];


var minT = Math.min.apply(null, array_times),
    maxT = Math.max.apply(null, array_times.concat(today));

var minV = Math.min.apply(null, array_values),
    maxV = Math.max.apply(null, array_values);

function dateToString(e) {
    var date = new Date(e * 1000);
    return date.toDateString().substring(4);
}


var chart = c3.generate({
    bindto: '#chart',
    data: {
        x: 'times',
        columns: [
            ['times'].concat(toShowTime), 
            [labelWeight].concat(toShowValues)],
        labels: {
            format: {
                y: d3.format('.2')
            }
        },
        type: 'scatter'
    },
    point: {
        r: 6
    },
    legend: {
        show: false
    },
    grid: {
        x: {
            show: true
        },
        y: {
            show: true
        }
    },
    axis: {
        x: {
            label: {
                text: 'Time [days]'
            },
            type: 'timeseries',
            tick: {
                fit: false,
                //count: 29,
                rotate: -75,
                multiline: false,
                format: function (e, d) {
                    return dateToString(e);
                }
            },
            height: 100
        },
        y: {
            label: {
                text: 'Weight [kg]',
                position: 'outer',
                min: minV - 10,
                max: maxV + 10
            },
            tick: {
                format: function (e, d) {
                    return parseFloat(e).toFixed(2);
                }
            },
        }
    }
});

chart.axis.range({min: {x:timeStart, y:minV-10}, max: {x:timeEnd, y:maxV+10}});

わずかな違いは、開始日が異なるためです。

同様の問題を抱えた別のフィドルがあります。http://jsfiddle.net/hfznh45w/5/

var d = (24 * 3600); // last 30 days


//var array_times = [1414540800-8*d, 1414540800-d, 1414540800, 1414627200, 1414627200 + d, 1414627200 + 2 * d, 1414627200 + 3 * d];
//var array_values = [61, 60, 67, 66.22, 68, 68, 68];

var array_times = [];
var array_values = [];

for (var i = -8; i < 30; i++) {
    array_times.Push(1414540800 + (i * d));
    array_values.Push(60 + i);
}

console.log(array_times);
console.log(array_values);

var labelWeight = 'weight in kg';

var window_period = (30 * 24 * 3600); // last 30 days

var today = Math.floor(new Date(2014, 10, 20, 0, 0, 0, 0).getTime() / 1000);
var timeEnd = today;
var timeStart = today - window_period;


var minT = Math.min.apply(null, array_times),
    maxT = Math.max.apply(null, array_times.concat(today));

var minV = Math.min.apply(null, array_values),
    maxV = Math.max.apply(null, array_values);

function dateToString(e) {
    var date = new Date(e * 1000);
    return date.toDateString().substring(4);
}


var chart = c3.generate({
    bindto: '#chart',
    data: {
        x: 'times',
        columns: [
            ['times'].concat(array_times), [labelWeight].concat(array_values)],
        labels: {
            format: {
                y: d3.format('.2')
            }
        },
        type: 'scatter'
    },
    point: {
        r: 6
    },
    legend: {
        show: false
    },
    grid: {
        x: {
            show: true
        },
        y: {
            show: true
        }
    },
    axis: {
        x: {
            padding: {
                left: 0,
                right: 0,
            },
            label: {
                text: 'Time [days]'
            },
            type: 'timeseries',
            tick: {
                fit: false,
                rotate: -75,
                multiline: false,
                format: function (e, d) {
                    return dateToString(e);
                }
            },
            height: 100
        },
        y: {
            padding: {
                top: 0,
                bottom: 0
            },
            label: {
                text: 'Weight [kg]',
                position: 'outer',
                min: minV - 10,
                max: maxV + 10
            },
            tick: {
                format: function (e, d) {
                    return parseFloat(e).toFixed(2);
                }
            }
        }
    }
});

chart.axis.range({
    min: {
        x: timeStart,
        y: minV - 10
    },
    max: {
        x: timeEnd,
        y: maxV + 10
    }
});

どんな手がかり/修正も大歓迎です。ありがとう!

11
2dvisio

c3jsを使用すると、x軸に表示される目盛りを指定できます。

Axis/x/tickの下にこれを追加しました-

values: [1413936000, 1414195200,1414454400,1414713600,1414972800,1415232000],

Epochコンバーター を使用して3日間隔で日付を変換しました。

これが解決策のリファレンスです。

グリッド線がこれらの3日の目盛りと一致しない場合にのみ、n番目の目盛りごとに新しい日にプッシュされていたと推測できます。したがって、問題が発生します。または、 グリッドラインを手動で に配置することもできます。

これがx軸のコードです。

        x: {
            label: {
                text: 'Time [days]'
            },
            type: 'timeseries',
            tick: {
                values: [1413936000, 1414195200,1414454400,1414713600,1414972800,1415232000],
                fit: false,
                //count: 29,
                rotate: -75,
                multiline: false,
                format: function (e, d) {
                    return dateToString(e);
                }
            },
            height: 100
        },
10
JasTonAChair

Tick.fitをfalseに設定すると、データポイントのx値に従ってティックを配置できます。

http://c3js.org/reference.html#axis-x-tick-fit

axis: {
  x: {
    tick: {
      fit: true
    }
  }
}

これが公式サイトのサンプルです http://c3js.org/samples/axes_x_tick_fit.html

5
gasolin

私は提案されたすべての答えを試しましたが、どれも私が望むものを私に与えませんでした。最も近いのはParthaの答えでしたが、グラフの種類としてcategoryを選択すると、グラフの左右に見苦しいパディングが作成されます。

私にとって最も効果的な解決策は、グラフからラベルを除外し、代わりにindexedグラフを使用することでした。そこから、format関数を使用して、各インデックスを適切な日付に手動でフォーマットします。

元の投稿者のコードの簡略版は次のとおりです。

var d = (30 * 24 * 3600); // last 30 days

var array_times = [1414540800, 1414627200, 1414627200 + d, 1414627200 + 2 * d, 1414627200 + 3 * d, 1456528117];
var array_values = [67, 66.22, 68, 68, 68, 77];

var labelWeight = 'weight in kg';

var window_period = (30 * 24 * 3600); // last 30 days


function dateToString(e) {
    var date = new Date(e * 1000);
    return date.toDateString().substring(4);
}


var chart = c3.generate({
    bindto: '#chart',
    data: {
        columns: [
          // Notice that I removed the datetimes from here
          [labelWeight].concat(array_values)
        ],
        type: 'area'
    },
    point: {
        r: 6
    },
    legend: {
        show: false
    },
    grid: {
        x: {
            show: true
        },
        y: {
            show: true
        }
    },
    axis: {
        x: {
            label: {
                text: 'Time [days]'
            },
            type: 'indexed',
            tick: {
                rotate: 90,
                // I reference array_times manually here to 
                // convert the index to a user-friendly label 
                format: function (index) {
                    return dateToString(array_times[index]);
                }
            }
        }
    }
});

ワーキングフィドル: http://jsfiddle.net/uop61zLc/1/

2

私も問題に直面しました。これが私が解決した方法です。 x軸を時系列ではなくカテゴリとして使用し、対応する目盛り形式を操作して、時系列であるかのように見せます。

確率を単純化して一般的にしました。

問題(不規則な間隔):

var chart = c3.generate({
            data: {
                x: 'xtime',
                xFormat: '%Y-%m-%d-%H-%M-%S',
                columns: [
                    ['xtime', '2015-05-20-05-10-13', '2015-05-20-05-11-13', '2015-05-21-06-10-13'],
                    ['value', 30, 50, 20]
                ]
            },
            size: {
                height: 300,
                width: 600
            },
            axis: {
                x: {
                    type: 'timeseries',
                    // type: 'category',
                    tick: {
                        // format: function(x) {
                        //     var dateSubs = this.api.categories()[x].split('-'),
                        //         newDate = new Date(dateSubs[0], dateSubs[1], dateSubs[2], dateSubs[3], dateSubs[4], dateSubs[5], 0);
                        //
                        //     return newDate.toLocaleString();
                        // }

                         format: '%e-%b-%Y %H:%M'
                    }
                }
            }
        });
    <link href="https://rawgit.com/masayuki0812/c3/master/c3.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.js"></script>
    <script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>

<div id="chart"></div>

解決 :

var chart = c3.generate({
            data: {
                x: 'xtime',
                xFormat: '%Y-%m-%d-%H-%M-%S',
                columns: [
                    ['xtime', '2015-05-20-05-10-13', '2015-05-20-05-11-13', '2015-05-21-06-10-13'],
                    ['value', 30, 50, 20]
                ]
            },
            size: {
                height: 300,
                width: 600
            },
            axis: {
                x: {
                    // type: 'timeseries',
                    type: 'category',
                    tick: {
                        format: function(x) {
                            var dateSubs = this.api.categories()[x].split('-'),
                                newDate = new Date(dateSubs[0], dateSubs[1], dateSubs[2], dateSubs[3], dateSubs[4], dateSubs[5], 0);
                        
                            return newDate.toLocaleString();
                        }

                         // format: '%e-%b-%Y %H:%M'
                    }
                }
            }
        });
<link href="https://rawgit.com/masayuki0812/c3/master/c3.css" rel="stylesheet"/>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.js"></script>
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>

<div id="chart"></div>
0
Partha