1

誰でも助けることができますか?私のデータは、2 つのドロップダウン リストから選択された値によってフィルター処理されています。次に、これらの同じ値の 1 日あたりの平均値を取得するために、ネスト/ロールアップされています。以下のコードで「問題の解析エラー」が発生します。フィルター関数とネスト関数の両方が正しいデータを返していますが、このデータを折れ線グラフに適用して更新しようとすると問題が発生しますか?

    d3.select("#parameterType").on("change", function() 
    {   
    d3.select("#dateTimeTaken").on("change", function()
    {   
    var selectedParameter = document.getElementById("parameterType").value;
    var selectedMonth = document.getElementById("dateTimeTaken").value;

    //filter data by selected parameter and month    
    var selectedData = data.filter(function(d) { 
      return d.parameterType == selectedParameter  &&
      +d.dateTimeTaken.getMonth() == (selectedMonth - 1);});

    console.log(selectedData);//returning correct data

    //get average reading for each day within selected month 
    var newdata = d3.nest()
        .key(function(d) {return d3.time.day(d.dateTimeTaken);})    
        .sortKeys(d3.ascending)
        .rollup(function(d) 
        {
            return {
            mean: d3.mean(selectedData, function(d) {return +d.reading;})};
        })
    .entries(selectedData);
    console.log(newdata);//returning correct data

    //UPDATE GRAPH

    //not returning correct max values?     
    x.domain(d3.extent(newdata, function(d) { return d.key; }));
    y.domain([0, d3.max(newdata, function(d) { return d.values; })]);

    svg.select("path.line")
        .attr( "d", line(newdata));

    svg.select(".x.axis")
        .transition()
        .duration(750)
        .ease("linear")
        .call(xAxis);

    svg.select(".y.axis")
        .transition()
        .duration(750)
        .ease("linear")
        .call(yAxis);
4

1 に答える 1

2

あなたが投稿したコードには、上記の問題を引き起こす2つの問題があります。どちらの問題も、データがどのようにネストされ、D3 でロールアップされるかについての誤解から生じているようです。

説明

var newdata = d3.nest()
    .key(function(d) {return d.dateTimeTaken;})    
    .sortKeys(d3.ascending)
    .entries(data);

これは、次の種類のオブジェクトを変換します。

var data = [{
    parameterType: 'a',
    dateTimeTaken: '2013-01-01 12:00:00',
    reading: 100
}, {
    parameterType: 'a',
    dateTimeTaken: '2013-01-02 12:00:01',
    reading: 101
}];

に:

[
    {
        "key": "2013-01-01 12:00:00",
        "values": [
            {
                "parameterType": "a",
                "dateTimeTaken": "2013-01-01 12:00:00",
                "reading": 100
            }
        ]
    },
    {
        "key": "2013-01-02 12:00:01",
        "values": [
            {
                "parameterType": "a",
                "dateTimeTaken": "2013-01-02 12:00:01",
                "reading": 101
            }
        ]
    }
]

フィールドは、元のvaluesデータ エントリをまとめて蓄積する配列です。 次に、 rollupは、 だったであろう配列を引数として取り、valuesこれらから集計メトリックを計算し (meanあなたの場合) 、キーの配列の代わりにそれを配置しますvalues

あなたのrollup機能:

//AVERAGE READING FOR EACH DAY WITHIN SELECTED MONTH FOR SELECTED PARAMETER
// ...

 .rollup(function(d) {
    return {mean:d3.mean(selectedData, function(d) {return +d.reading;})};})

引数を完全に無視します。私はそれが読むべきだと思います:

 .rollup(function(d) {
    return {mean:d3.mean(d, function(d_) {return +d_.reading;})};})

結果の配列は次のようになります。

[
    {
        "key": "2013-01-01 12:00:00",
        "values": {
            "mean": 100
        }
    },
    {
        "key": "2013-01-02 12:00:01",
        "values": {
            "mean": 101
        }
    }
]

キーのvalues内部には、mean. y軸の範囲は次のように計算します。

y.domain([0, d3.max(newdata, function(d) { return d.values; })]);

最大値が正しくない理由は、d3 に の最大値を計算するように要求しているためobjectsですvalues。このような操作の結果は明確に定義されていません。代わりに、次の最大値を要求する必要がありますvalues.mean

y.domain([0, d3.max(newdata, function(d) { return d.values.mean; })]);

これは機能し、次の jsFiddle に示すように正しい結果が生成されます: http://jsfiddle.net/XLNeP/

結論

これは、ネスティングとロールパスを正しく機能させる方法についてでした。次に、他のいくつかの問題に対処します。line変数には次のアクセサーがあります。

var line = d3.svg.line()
.x(function(d) { return x(d.dateTimeTaken); })
    .y(function(d) { return y(d.reading); });

これは、呼び出し時に完全に機能します。

svg.append("path")
    .attr("class", "line")
    .attr("d", line(data)); 

ただし、newdataは上に示した形式でkeyありvalues、最上位に and があり、dateTimeTakenorはありませんreading。したがって、フィルタリングされてデータ構造が保持されるを使用することをお勧めしselectedDataます。dataただし、別の線を描画する場合 (たとえば を使用) は、別のアクセサーをmean使用して新しい線ジェネレーターを定義する必要があります。d3.svg.line()

于 2013-03-10T14:10:21.270 に答える