2016-10-02 47 views
1

AmChartsの株価チャートにajax経由で非同期に読み込まれた複数のデータセットを使用しています。AmCharts株価チャート複数のデータセットの日付範囲が正しくありません

残念ながら、チャート全体の日付範囲のように見えます。これは、「From」および「To」が、すべてのDataSetsの配列に追加された最初のものからのみ設定されることを意味します。あなたはそのデータ・セット-2は、すべての3から最大終了日を持って見ることができる上記の例では

<script id="data-set-1" type="application/json"> 
     [ 
      {"date": "2016-10-02T10:00:00", "value": 23.8}, 
      {"date": "2016-10-02T10:05:00", "value": 16.8}, 
      {"date": "2016-10-02T10:10:00", "value": 20.5} 
     ] 
</script> 
<!-- This dataset has max end date from all 3 datasets --> 
<script id="data-set-2" type="application/json"> 
     [ 
      {"date": "2016-10-02T10:00:00", "value": 15.2}, 
      {"date": "2016-10-02T10:05:00", "value": 21.4}, 
      {"date": "2016-10-02T10:15:00", "value": 18.1} 
     ] 
</script> 
<!-- This dataset has min start date from all 3 datasets --> 
<script id="data-set-3" type="application/json"> 
     [ 
      {"date": "2016-10-02T09:55:00", "value": 12.4}, 
      {"date": "2016-10-02T10:00:00", "value": 17.7}, 
      {"date": "2016-10-02T10:05:00", "value": 14.6} 
     ] 
</script> 

あなたは3つのデータセットを持ち、それらのそれぞれが全く異なる開始日と終了日を持つことができるような状況を想像してみてデータセットとデータセット3は、3つのデータセットすべてから最小開始日を持ちます。

最終結果:

<!DOCTYPE html> 
 
<html> 
 
<head> 
 
    <title>AmCharts multiple datasets min-max date range issue</title> 
 
    <meta charset="utf-8" /> 
 
    <style type="text/css"> 
 
     #chartdiv { 
 
      width: 100%; 
 
      height: 500px; 
 
     } 
 
    </style> 
 
    <script id="data-set-1" type="application/json"> 
 
      [ 
 
       {"date": "2016-10-02T10:00:00", "value": 23.8}, 
 
       {"date": "2016-10-02T10:05:00", "value": 16.8}, 
 
       {"date": "2016-10-02T10:10:00", "value": 20.5} 
 
      ] 
 
    </script> 
 
    <!-- This dataset has max end date from all 3 datasets --> 
 
    <script id="data-set-2" type="application/json"> 
 
      [ 
 
       {"date": "2016-10-02T10:00:00", "value": 15.2}, 
 
       {"date": "2016-10-02T10:05:00", "value": 21.4}, 
 
       {"date": "2016-10-02T10:15:00", "value": 18.1} 
 
      ] 
 
    </script> 
 
    <!-- This dataset has min start date from all 3 datasets --> 
 
    <script id="data-set-3" type="application/json"> 
 
      [ 
 
       {"date": "2016-10-02T09:55:00", "value": 12.4}, 
 
       {"date": "2016-10-02T10:00:00", "value": 17.7}, 
 
       {"date": "2016-10-02T10:05:00", "value": 14.6} 
 
      ] 
 
    </script> 
 
    <link rel="stylesheet" href="https://www.amcharts.com/lib/3/plugins/export/export.css" type="text/css" media="all" /> 
 
</head> 
 
<body> 
 
    <div id="chartdiv"></div> 
 
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script> 
 
    <script src="https://www.amcharts.com/lib/3/amcharts.js"></script> 
 
    <script src="https://www.amcharts.com/lib/3/serial.js"></script> 
 
    <script src="https://www.amcharts.com/lib/3/amstock.js"></script> 
 
    <script src="https://www.amcharts.com/lib/3/plugins/export/export.min.js"></script> 
 
    <script type="text/javascript"> 
 

 
     $(document).ready(function() { 
 
      AmCharts.useUTC = true; // this will prevent adding timezone hours to ech date 
 

 
      var chart = AmCharts.makeChart("chartdiv", { 
 
       "pathToImages": "http://cdn.amcharts.com/lib/3/images/", 
 
       "type": "stock", 
 
       "theme": "light", 
 
       "categoryAxesSettings": { 
 
        "minPeriod": "mm" // precision to minutes 
 
       }, 
 

 
       "dataSets": [], // empty, we will add each based on single sensor 
 

 
       "panels": [{ 
 
        "recalculateToPercents": "never", // show value on scale not percent 
 
        "showCategoryAxis": true, 
 
        "title": "", 
 
        "percentHeight": 70, 
 

 
        "stockGraphs": [{ // generic config for all lines 
 
         "id": "g1", 
 
         "connect": true, // show gaps in data 
 
         "comparable": true, // must be true to disable/enable each dataset 
 
         "compareField": "value", 
 
         "valueField": "value", 
 
         "type": "smoothedLine", 
 
         "lineThickness": 2, 
 
         "bullet": "round" 
 
        }], 
 

 
        "stockLegend": { 
 
         "periodValueTextRegular": "[[value.close]]" // what will be shown at top legend 
 
        } 
 
       }], 
 

 
       "chartScrollbarSettings": { 
 
        "graph": "g1", 
 
        "usePeriod": "10mm", 
 
        "position": "top" 
 
       }, 
 

 
       "chartCursorSettings": { 
 
        "valueBalloonsEnabled": true 
 
       }, 
 

 
       "periodSelector": { 
 
        "fromText": "", 
 
        "toText": "", 
 
        "periodsText": "", 
 
        "position": "top", 
 
        "dateFormat": "YYYY-MM-DD JJ:NN", 
 
        "inputFieldWidth": 150, 
 
        "periods": [{ 
 
         "period": "hh", 
 
         "count": 1, 
 
         "label": "1 H", 
 
         "selected": true 
 
        }, { 
 
         "period": "hh", 
 
         "count": 8, 
 
         "label": "8 H" 
 
        }, { 
 
         "period": "DD", 
 
         "count": 1, 
 
         "label": "1 D" 
 
        }, { 
 
         "period": "DD", 
 
         "count": 10, 
 
         "label": "10 D" 
 
        }, { 
 
         "period": "MM", 
 
         "selected": true, 
 
         "count": 1, 
 
         "label": "1 M" 
 
        }, { 
 
         "period": "YYYY", 
 
         "count": 1, 
 
         "label": "1 Y" 
 
        }, { 
 
         "period": "YTD", 
 
         "label": "YTD" 
 
        }, { 
 
         "period": "MAX", 
 
         "label": "MAX" 
 
        }] 
 

 
       }, 
 

 
       "panelsSettings": { 
 
        "usePrefixes": true 
 
       }, 
 

 
       "export": { 
 
        "enabled": true, 
 
        "exportTitles": true, 
 
        "libs": { 
 
         "path": "http://www.amcharts.com/lib/3/plugins/export/libs/" 
 
        }, 
 
        "position": "bottom-right" 
 
       } 
 
      }); 
 

 
      for (var i = 1; i <= 3; i++) { 
 
       var dataset = new AmCharts.DataSet(); 
 
       dataset.compared = true; 
 
       dataset.title = "DataSet " + i; 
 
       dataset.categoryField = "date"; 
 
       dataset.fieldMappings = JSON.parse('[{"fromField": "value", "toField": "value"}]'); 
 

 
       var data = JSON.parse($("#data-set-" + i).html()); 
 
       dataset.dataProvider = data; 
 
       chart.dataSets.push(dataset); 
 
       chart.validateData(); 
 
      } 
 
     }); 
 
    </script> 
 
</body> 
 
</html>

あなたは全体のグラフは、データ・セット1は、チャートは、日付・セット2点表示されていないから、日付範囲に切り捨てられることを確認でき:

{"date": "2016-10-02T10:15:00", "value": 18.1} 

と、日付・セット3点表示されない:

{"date": "2016-10-02T09:55:00", "value": 12.4} 

私は運なしで入力「を」「から」ハックしようとした:すべてのデータセットからの最小値と最大日付のルックアップするために、チャートを強制していないだけで最初からする方法を

chart.addListener("init", 
    function (e) { 
     //e.chart.startDate = moment("2016-10-01 00:00"); 
     //e.chart.endDate = moment("2016-10-03 00:00"); 
    }); 

任意のアイデア1つはDataSetsの配列に追加されましたか?

答えて

1

株価チャートは、選択した主なデータセットの日付の範囲を常に使用し、その範囲内に収まらない比較データセットのデータポイントは無視します。

さらに、タイムスタンプに直接一致しないデータポイントは無視されます。

明白な解決策は、比較データセットのものと重複するメインデータセットに「空の」データポイントを追加することによって、すべてのデータセットのデータを同期させることです。

私は、データが生成されるサーバー側でそれを行うのは不都合に不便で非効率的かもしれないことは知っています。

幸いにも、私たちはそれを行うクライアント側ラッパーを実装できます。

私はここにあなたの例を更新:

<!DOCTYPE html> 
 
<html> 
 
<head> 
 
    <title>AmCharts multiple datasets min-max date range issue</title> 
 
    <meta charset="utf-8" /> 
 
    <style type="text/css"> 
 
     #chartdiv { 
 
      width: 100%; 
 
      height: 500px; 
 
     } 
 
    </style> 
 
    
 
    <script id="data-set-1" type="application/json"> 
 
      [ 
 
       {"date": "2016-10-02T10:00:00", "value": 23.8}, 
 
       {"date": "2016-10-02T10:05:00", "value": 16.8}, 
 
       {"date": "2016-10-02T10:10:00", "value": 20.5} 
 
      ] 
 
    </script> 
 
    <!-- This dataset has max end date from all 3 datasets --> 
 
    <script id="data-set-2" type="application/json"> 
 
      [ 
 
       {"date": "2016-10-02T10:00:00", "value": 15.2}, 
 
       {"date": "2016-10-02T10:05:00", "value": 21.4}, 
 
       {"date": "2016-10-02T10:15:00", "value": 18.1} 
 
      ] 
 
    </script> 
 
    <!-- This dataset has min start date from all 3 datasets --> 
 
    <script id="data-set-3" type="application/json"> 
 
      [ 
 
       {"date": "2016-10-02T09:55:00", "value": 12.4}, 
 
       {"date": "2016-10-02T10:00:00", "value": 17.7}, 
 
       {"date": "2016-10-02T10:05:00", "value": 14.6} 
 
      ] 
 
    </script> 
 
    <link rel="stylesheet" href="https://www.amcharts.com/lib/3/plugins/export/export.css" type="text/css" media="all" /> 
 
</head> 
 
<body> 
 
    <div id="chartdiv"></div> 
 
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.1/jquery.min.js"></script> 
 
    <script src="https://www.amcharts.com/lib/3/amcharts.js"></script> 
 
    <script src="https://www.amcharts.com/lib/3/serial.js"></script> 
 
    <script src="https://www.amcharts.com/lib/3/amstock.js"></script> 
 
    <script src="https://www.amcharts.com/lib/3/plugins/export/export.min.js"></script> 
 
    <script type="text/javascript"> 
 
     function syncDataTimestamps(chart) { 
 

 
      // check if plugin is enabled 
 
      if (chart.syncDataTimestamps !== true) 
 
      return; 
 

 
      // go thorugh all data sets and collect all the different timestamps 
 
      var dates = {}; 
 
      for (var i = 0; i < chart.dataSets.length; i++) { 
 
      var ds = chart.dataSets[i]; 
 
      for (var x = 0; x < ds.dataProvider.length; x++) { 
 
       var date = ds.dataProvider[x][ds.categoryField]; 
 
       if (!(date instanceof Date)) 
 
       date = new Date(date); 
 
       if (dates[date.getTime()] === undefined) 
 
       dates[date.getTime()] = {}; 
 
       dates[date.getTime()][i] = ds.dataProvider[x]; 
 
      } 
 
      } 
 
      
 
      // iterate through data sets again and fill in the blanks 
 
      for (var i = 0; i < chart.dataSets.length; i++) { 
 
      var ds = chart.dataSets[i]; 
 
      var dp = []; 
 
      for (var ts in dates) { 
 
       if (!dates.hasOwnProperty(ts)) 
 
       continue; 
 
       var row = dates[ts]; 
 
       if (row[i] === undefined) { 
 
       row[i] = {}; 
 
       var d = new Date(); 
 
       d.setTime(ts); 
 
       row[i][ds.categoryField] = d; 
 
       } 
 
       dp.push(row[i]); 
 
      } 
 
      dp.sort(function(a,b){ 
 
       return new Date(a[ds.categoryField]) - new Date(b[ds.categoryField]); 
 
      }); 
 
      ds.dataProvider = dp; 
 
      } 
 

 
     }; 
 

 
     $(document).ready(function() { 
 
      AmCharts.useUTC = true; // this will prevent adding timezone hours to ech date 
 

 
      var chart = AmCharts.makeChart("chartdiv", { 
 
       "type": "stock", 
 
       "theme": "light", 
 
       "categoryAxesSettings": { 
 
        "minPeriod": "mm" // precision to minutes 
 
       }, 
 

 
       "syncDataTimestamps": true, 
 
       "dataSets": [], // empty, we will add each based on single sensor 
 

 
       "panels": [{ 
 
        "recalculateToPercents": "never", // show value on scale not percent 
 
        "showCategoryAxis": true, 
 
        "title": "", 
 
        "percentHeight": 70, 
 

 
        "stockGraphs": [{ // generic config for all lines 
 
         "id": "g1", 
 
         "connect": true, // show gaps in data 
 
         "comparable": true, // must be true to disable/enable each dataset 
 
         "compareField": "value", 
 
         "valueField": "value", 
 
         "type": "smoothedLine", 
 
         "lineThickness": 2, 
 
         "bullet": "round" 
 
        }], 
 

 
        "stockLegend": { 
 
         "periodValueTextRegular": "[[value.close]]" // what will be shown at top legend 
 
        } 
 
       }], 
 

 
       "chartScrollbarSettings": { 
 
        "graph": "g1", 
 
        "usePeriod": "10mm", 
 
        "position": "top" 
 
       }, 
 

 
       "chartCursorSettings": { 
 
        "valueBalloonsEnabled": true 
 
       }, 
 

 
       "periodSelector": { 
 
        "fromText": "", 
 
        "toText": "", 
 
        "periodsText": "", 
 
        "position": "top", 
 
        "dateFormat": "YYYY-MM-DD JJ:NN", 
 
        "inputFieldWidth": 150, 
 
        "periods": [{ 
 
         "period": "hh", 
 
         "count": 1, 
 
         "label": "1 H", 
 
         "selected": true 
 
        }, { 
 
         "period": "hh", 
 
         "count": 8, 
 
         "label": "8 H" 
 
        }, { 
 
         "period": "DD", 
 
         "count": 1, 
 
         "label": "1 D" 
 
        }, { 
 
         "period": "DD", 
 
         "count": 10, 
 
         "label": "10 D" 
 
        }, { 
 
         "period": "MM", 
 
         "selected": true, 
 
         "count": 1, 
 
         "label": "1 M" 
 
        }, { 
 
         "period": "YYYY", 
 
         "count": 1, 
 
         "label": "1 Y" 
 
        }, { 
 
         "period": "YTD", 
 
         "label": "YTD" 
 
        }, { 
 
         "period": "MAX", 
 
         "label": "MAX" 
 
        }] 
 

 
       }, 
 

 
       "panelsSettings": { 
 
        "usePrefixes": true 
 
       }, 
 

 
       "export": { 
 
        "enabled": true, 
 
        "exportTitles": true, 
 
        "libs": { 
 
         "path": "http://www.amcharts.com/lib/3/plugins/export/libs/" 
 
        }, 
 
        "position": "bottom-right" 
 
       } 
 
      }); 
 

 
      for (var i = 1; i <= 3; i++) { 
 
       var dataset = new AmCharts.DataSet(); 
 
       dataset.compared = true; 
 
       dataset.title = "DataSet " + i; 
 
       dataset.categoryField = "date"; 
 
       dataset.fieldMappings = JSON.parse('[{"fromField": "value", "toField": "value"}]'); 
 

 
       var data = JSON.parse($("#data-set-" + i).html()); 
 
       dataset.dataProvider = data; 
 
       chart.dataSets.push(dataset); 
 
      } 
 

 
      syncDataTimestamps(chart); 
 
      chart.validateData(); 
 
     }); 
 
    </script> 
 
</body> 
 
</html>

を、私はまた、ループの外にvalidateData()呼び出しを移動することに注意してください、それは一度だけ呼び出されるのではなく、不必要に三回してください。

+0

多くのデータがある場合のパフォーマンスはどうですか? –

+0

数百から数千のデータポイントについて、追加の処理オーバーヘッドが顕著な違いを生じてはならないと思います。数十万、数十万の場合、時間がかかることがあります。しかし、実際のデータで試してみるだけで、正確な数値を見積もるのは難しいです。 – martynasma

+0

今のところ十分です。スタートアップで大規模に使用すると、私は質問を更新したり、回答を追加したりします。ありがとう。 –

関連する問題