具有日期时间的多值轴

时间:2016-12-21 11:54:12

标签: javascript amcharts

我是AmCharts.js的新人。我想创建一个具有多个值轴的图表,该图表表示根据日期时间(最多几小时或更长时间)(不是日期),一个产品在不同网站上出现的价格。

所以我需要绘制多行不相互依赖的图表。所以当我的一个是空值时,仍然会绘制第二行的值。

每个产品都可能有不同的出现次数,因此我无法硬编码颜色和数据集的其他属性。

我找到的最好的方法之一是 AmStockChart ,因为可以绘制多行。但是存在多个问题。其中之一是它需要“比较”一行到另一行,所以如果没有datetime xxx的值,则不会显示此日期时间的line2的值。

日期时间可能不同(一行是12.01 13:00,另一行是14:00等)。

这是我的解决方案,由于必须进行比较,因此无法正常工作。

JSON是:{'web_name':[[[year,month,day,hour...],price],[[[year,month....}

<script>
    var lines = [];
    var dataSets = [];

    generateChartData();

    function generateChartData() {
        var google_chart_json = JSON;
        var loopcounter = -1;
        $.each(google_chart_json, function (key, val) {
            var line = [];
            loopcounter = loopcounter + 1;

            $.each(val, function (_, scan) {
                var year = scan[0][0];
                var month = scan[0][1];
                var day = scan[0][2];
                var hour = scan[0][3];
                var minute = scan[0][4];
                var price = scan[1];

                var data = {
                    'date': new Date(year, month - 1, day, hour, minute),
                    'value': price
                };
                line.push(data);
            });
            line.sort(function (lhs, rhs) {
                return lhs.date.getTime() - rhs.date.getTime();
            });

            lines.push([key, line]);
        });
        console.log('LINES');
        console.log(lines);


        $.each(lines, function (_, name_line) {
            var dict = {
                'title': name_line[0],
                "fieldMappings": [{
                    "fromField": "value",
                    "toField": "value"
                }],
                "dataProvider": name_line[1],
                "categoryField": "date"
            };
            dataSets.push(dict);
        });
    }
    console.log(dataSets)
    var chart = AmCharts.makeChart("chartdiv", {
        "allLabels": [
            {
                "text": "Free label",
                "bold": true,
                "x": 20,
                "y": 20
            }
        ],
        categoryAxesSettings: {
            minPeriod: "hh",//(at least that is not grouped)
            groupToPeriods: ["DD", "WW", "MM"]//(Data will be grouped by day,week and month)
        },
        "type": "stock",
        "theme": "light",
        "dataSets": dataSets,

        "panels": [{
            "showCategoryAxis": false,
            "title": "Value",
            "percentHeight": 70,

            "stockGraphs": [{
                "id": "g1",
                "valueField": "value",
                "comparable": true,
                "compareField": "value",
                "balloonText": "[[date]][[title]]:<b>[[value]]</b>",
                "compareGraphBalloonText": "[[title]]:<b>[[value]]</b>"
            }],
            "stockLegend": {
                "periodValueTextComparing": "[[percents.value.close]]%",
                "periodValueTextRegular": "[[value.close]]"
            }
        }],

        {#https://docs.amcharts.com/javascriptcharts/ChartScrollbar#}
        "chartScrollbarSettings": {
            "graph": "g1",
            "color": "#333333"
        },

        "chartCursorSettings": {
            "valueBalloonsEnabled": true,
            "fullWidth": true,
            "cursorAlpha": 0.1,
            "valueLineBalloonEnabled": true,
            "valueLineEnabled": true,
            "valueLineAlpha": 0.5
        },

        "periodSelector": {
            "position": "left",
            "periods": [{
                "period": "MM",
                "selected": true,
                "count": 1,
                "label": "1 month"
            }, {
                "period": "YYYY",
                "count": 1,
                "label": "1 year"
            }, {
                "period": "YTD",
                "label": "YTD"
            }, {
                "period": "MAX",
                "label": "MAX"
            }]
        },

        "dataSetSelector": {
            "position": "left",
        },

        "export": {
            "enabled": true
        }
    });
    chart.panelsSettings.recalculateToPercents = "never";
</script>

当我为值设置相同的日期时间时,它会显示行。但是当每个值具有不同的日期时间时,除了第一行之外它什么也没有显示:

enter image description here

另一个解决方案(Line chart FiddleJS)有硬编码的线路,我不能这样做,因为它们的数量不同。但主要问题是它们有自己的价值轴。

你能告诉我在我的代码中做了什么来实现不比较多线图和允许不同值和线的不同日期时间吗?或者如果你知道 - 推荐一些可以做到这一点的amchart?

1 个答案:

答案 0 :(得分:1)

比较要求每个日期/时间必须匹配,或者它不会显示每个点,正如您所注意到的那样。在AmCharts知识库中,有demo实现了一个迷你插件,可以在初始化图表之前同步数据中的时间戳:

/**
 * amCharts plugin: sync timestamps of the data sets
 * ---------------
 * Will work only if syncDataTimestamps is set to true in chart config
 */
AmCharts.addInitHandler(function(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 (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;
  }

}, ["stock"]);

只需在图表代码之前添加它,并在图表配置的顶层将自定义syncDataTimestamps属性设置为true,它将在初始化时运行。