Amcharts - 计算和绘制变化率

Amcharts - Calculate & plot rate of change

我在折线图上有一组值,如下所示

数据跨越多年。上图中的输出是从数据库中查询出来的f a SQL。我面临的挑战是在同一张图表上同时表示页面点击的实际数量和增长率。

我将点击次数绘制为柱形图,点击次数是左侧的 Y 轴。我之前创建了一个多线图和线与列的组合。所以,也可以为此创建一个。但是,有没有一种方法可以让 amcharts 计算变化率,而不必将其提取为 SQL 查询的另一个字段?

我希望看到 amcharts 在右侧绘制一个沿 Y 轴变化率的折线图。也非常感谢处理此问题的任何其他想法。

剩下的拼图

在上图中,“#EVENT”和"EVENT # - GROWTH RATE"都显示相同的值。我怎样才能让 "EVENT # - GROWTH RATE" 实际显示百分比变化(根据附图为 69%)而不是数值?

以上输出来自 firebug 跟踪。如图所示,2 个图表在 2 个不同的值轴上具有相同的 "value" 图,其中一个启用了百分比。

您可以为此创建一个单独的图表和值轴。值轴有一个 属性 recalculateToPercents,当设置为 true 时,将重新计算绝对值以改变百分比。

因此您将拥有一个像现在一样的常规图表,以及一个单独的 graph/value 轴二重奏来显示动态。

我认为一个工作示例可能更好地说明这一点:

var chart = AmCharts.makeChart("chartdiv", {
  "type": "serial",
  "theme": "light",
  "dataDateFormat": "YYYY-MM-DD",
  "valueAxes": [{
    "id": "v1",
    "position": "left",
    "minimum": 0,
    "maximum": 100
  }, {
    "id": "v2",
    "gridAlpha": 0,
    "position": "left",
    "offset": 60,
    "recalculateToPercents": true
  }],
  "graphs": [{
    "id": "g1",
    "bullet": "round",
    "lineThickness": 2,
    "title": "Absolute values",
    "valueField": "value",
    "valueAxis": "v1"
  }, {
    "id": "g1",
    "bullet": "round",
    "lineThickness": 2,
    "title": "Change values",
    "valueField": "value",
    "valueAxis": "v2",
    "showBalloon": false
  }],
  "legend": {
    "valueText": ""
  },
  "chartCursor": {
    "valueLineEnabled": true,
    "valueLineBalloonEnabled": true,
    "cursorAlpha": 1,
    "cursorColor": "#258cbb",
    "limitToGraph": "g1",
    "valueLineAlpha": 0.2
  },
  "categoryField": "date",
  "categoryAxis": {
    "parseDates": true
  },
  "dataProvider": [ {
    "date": "2013-01-02",
    "value": 67
  }, {
    "date": "2013-01-03",
    "value": 64
  }, {
    "date": "2013-01-04",
    "value": 66
  }, {
    "date": "2013-01-05",
    "value": 60
  }, {
    "date": "2013-01-06",
    "value": 63
  }, {
    "date": "2013-01-07",
    "value": 61
  }, {
    "date": "2013-01-08",
    "value": 60
  }, {
    "date": "2013-01-09",
    "value": 65
  }, {
    "date": "2013-01-10",
    "value": 75
  }, {
    "date": "2013-01-11",
    "value": 77
  }, {
    "date": "2013-01-12",
    "value": 78
  }, {
    "date": "2013-01-13",
    "value": 70
  }, {
    "date": "2013-01-14",
    "value": 70
  }, {
    "date": "2013-01-15",
    "value": 73
  }, {
    "date": "2013-01-16",
    "value": 71
  }, {
    "date": "2013-01-17",
    "value": 74
  }, {
    "date": "2013-01-18",
    "value": 78
  }, {
    "date": "2013-01-19",
    "value": 85
  }, {
    "date": "2013-01-20",
    "value": 82
  }, {
    "date": "2013-01-21",
    "value": 83
  }, {
    "date": "2013-01-22",
    "value": 88
  }, {
    "date": "2013-01-23",
    "value": 85
  }, {
    "date": "2013-01-24",
    "value": 85
  }, {
    "date": "2013-01-25",
    "value": 80
  }, {
    "date": "2013-01-26",
    "value": 87
  }, {
    "date": "2013-01-27",
    "value": 84
  }, {
    "date": "2013-01-28",
    "value": 83
  }, {
    "date": "2013-01-29",
    "value": 84
  }, {
    "date": "2013-01-30",
    "value": 81
  }]
});
<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/themes/light.js"></script>
<div id="chartdiv" style="width: 100%; height: 300px;"></div>

您会注意到两个图表使用相同的 valueField


上述解决方案将计算第一个值的变化。

如果您需要根据任何先前的数据点计算更改,则需要 pre-process 数据。

我们可以使用AmCharts.addInitHandler()方法来指定在图表初始化之前调用的自定义函数,因此我们可以对其进行一些last-minute修改和计算。

下面的解决方案将使用它在图表中查找专有设置 recalculate,并将自动重新计算其绝对数据值以更改百分比。

不用说,如果您的数据至少包含一个零值,这将不起作用,因为无法计算从零开始的百分比变化。

AmCharts.addInitHandler(function(chart) {
  
  // look for graphs that need to be recalculated
  var graphs = [];
  for(var i = 0; i < chart.graphs.length; i++) {
    var graph = chart.graphs[i];
    if (graph.recalculate === true) {
      graph.originalValueField = graph.valueField;
      graph.valueField = graph.valueField + "Change";
      graphs.push(graph);
    }
  }
  
  // calculate the data
  var prev = [];
  for(var i = 0; i < chart.dataProvider.length; i++) {
    var dp = chart.dataProvider[i];
 
    for(var g = 0; g < graphs.length; g++) {
      var graph = graphs[g];
            
      // ignore empty data points
      if(isNaN(dp[graph.originalValueField]))
        continue;
      
      // handle first data point
      if(prev[g] === undefined) {
        prev[g] = dp[graph.originalValueField];
      }
      
      // calculate the change
      var change = dp[graph.originalValueField] - prev[0];
      dp[graph.valueField] = Math.round( change / prev[0] * 10000) / 100;
      
      // assign previous value
      prev[g] = dp[graph.originalValueField];
        
    }
  }
  
  console.log(chart.dataProvider);
  
}, ["serial"]);

var chart = AmCharts.makeChart("chartdiv", {
  "type": "serial",
  "theme": "light",
  "dataDateFormat": "YYYY-MM-DD",
  "valueAxes": [{
    "id": "v1",
    "position": "left"
  }, {
    "id": "v2",
    "gridAlpha": 0,
    "position": "left",
    "offset": 60,
    "unit": "%"
  }],
  "graphs": [{
    "id": "g1",
    "bullet": "round",
    "lineThickness": 2,
    "title": "Absolute values",
    "valueField": "value",
    "valueAxis": "v1"
  }, {
    "id": "g2",
    "bullet": "round",
    "lineThickness": 2,
    "title": "Change values",
    "valueField": "value",
    "valueAxis": "v2",
    "recalculate": true,
    "balloonText": "[[value]]%"
  }],
  "legend": {
    "valueText": ""
  },
  "chartCursor": {
    "valueLineEnabled": true,
    "valueLineBalloonEnabled": true,
    "cursorAlpha": 1,
    "cursorColor": "#258cbb",
    "limitToGraph": "g1",
    "valueLineAlpha": 0.2
  },
  "categoryField": "date",
  "categoryAxis": {
    "parseDates": true
  },
  "dataProvider": [ {
    "date": "2013-01-02",
    "value": 67
  }, {
    "date": "2013-01-03",
    "value": 64
  }, {
    "date": "2013-01-04",
    "value": 66
  }, {
    "date": "2013-01-05",
    "value": 60
  }, {
    "date": "2013-01-06",
    "value": 63
  }, {
    "date": "2013-01-07",
    "value": 61
  }, {
    "date": "2013-01-08",
    "value": 60
  }, {
    "date": "2013-01-09",
    "value": 65
  }, {
    "date": "2013-01-10",
    "value": 75
  }, {
    "date": "2013-01-11",
    "value": 77
  }, {
    "date": "2013-01-12",
    "value": 78
  }, {
    "date": "2013-01-13",
    "value": 70
  }, {
    "date": "2013-01-14",
    "value": 70
  }, {
    "date": "2013-01-15",
    "value": 73
  }, {
    "date": "2013-01-16",
    "value": 71
  }, {
    "date": "2013-01-17",
    "value": 74
  }, {
    "date": "2013-01-18",
    "value": 78
  }, {
    "date": "2013-01-19",
    "value": 85
  }, {
    "date": "2013-01-20",
    "value": 82
  }, {
    "date": "2013-01-21",
    "value": 83
  }, {
    "date": "2013-01-22",
    "value": 88
  }, {
    "date": "2013-01-23",
    "value": 85
  }, {
    "date": "2013-01-24",
    "value": 85
  }, {
    "date": "2013-01-25",
    "value": 80
  }, {
    "date": "2013-01-26",
    "value": 87
  }, {
    "date": "2013-01-27",
    "value": 84
  }, {
    "date": "2013-01-28",
    "value": 83
  }, {
    "date": "2013-01-29",
    "value": 84
  }, {
    "date": "2013-01-30",
    "value": 81
  }]
});
<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/themes/light.js"></script>
<div id="chartdiv" style="width: 100%; height: 300px;"></div>