使用Highcharts动态绘制点图

时间:2016-07-11 18:19:14

标签: graph highcharts

如何动态绘制表中的点?该表有两列专用于x和y坐标,另外一列用于持续时间。

实施例

说我有下面的表格。 Date和Effort列将组成折线图的x,y坐标(Timestamp,Effort)。此折线图将具有基于Timestamp和Effort列的累计总数的数据点。 “持续时间”列将确定条目对折线图的数据点的影响时间。因此,基于此表,我想要一个折线图,其中坐标列在数据点下。

时间戳工作时间
4/13/2016 12:13:12.15 10 100
4/13/2016 12:13:12.80 12 100
2016年4月13日12:13:13.15 30 100
2016年4月13日12:13:13.80 50 100

数据-点数:
(2016年4月13日12:13:12.15,10)
(2016年4月13日12:13:12.80,22)
(2016年4月13日12:13:13.15,42)
(2016年4月13日12:13:13.80,80)

2 个答案:

答案 0 :(得分:1)

One of the Highcharts demos shows precisely how you can accomplish this using a static HTML table: http://www.highcharts.com/demo/column-parsed.

I've created a fiddle using your sample data and plotted it as a line chart, per your requirement: http://jsfiddle.net/brightmatrix/qgvkp0t0/

Your data table would be coded similar to the following:

<table id="datatable">
  <thead>
    <tr>
      <th>Time</th>
      <th>Effort</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>4/13/2016 12:13:12.15</th>
      <td>10</td>
    </tr>
    <tr>
      <th>4/13/2016 12:13:12.80</th>
      <td>22</td>
    </tr>
    <tr>
      <th>4/13/2016 12:13:13.15</th>
      <td>42</td>
    </tr>
    <tr>
      <th>4/13/2016 12:13:13.80</th>
      <td>80</td>
    </tr>
  </tbody>
</table>

You would then create your chart using the following code. Note the data attribute that calls to your HTML table's ID:

$(function () {
  $('#container').highcharts({
    data: {
      table: 'datatable'
    },
    chart: {
      type: 'line'
    },
    title: {
      text: 'Data extracted from a HTML table in the page'
    },
    xAxis: {
      type: 'category'
    },
    yAxis: {
      allowDecimals: false,
      title: {
        text: 'Units'
      }
    },
    tooltip: {
      formatter: function () {
        return '<b>' + this.series.name + '</b><br/>' + this.point.y;
      }
    }
  });
});

One thing to note: without any modifications, your timestamp data would be read into your x-axis as a datetime type. This would leave you with empty points for those dates or times in between.

In my example, I explicitly set the x-axis type to category, so that there is exactly one plot on the chart for each data point.

Now, to get the x-axis labels to appear in a more readable format, you can explore the xAxis.labels.formatter attribute (http://api.highcharts.com/highcharts#xAxis.labels.formatter) and the Highcharts.dateFormat() function (http://api.highcharts.com/highcharts#Highcharts.dateFormat).

Update (July 13, 2016): I've been able to solve the original poster's requirement of adding cumulative points based on data in an HTML table, but not the removal of dates that are older than the current data point's duration. My modifications are below.

In order to take the data from an HTML table and work with it prior to plotting the chart, I used the data.columns attribute (see http://api.highcharts.com/highcharts#data.columns).

Before your chart options are declared, I wrote this code to go through the HTML table and add the content to arrays.

  // read through the HTML table and calculate cumulative effort
  // solution inspired by:
  // 1. http://stackoverflow.com/questions/3248869/how-do-i-get-data-from-a-data-table-in-javascript
  // 2. http://stackoverflow.com/questions/10057226/how-to-get-html-table-td-cell-value-by-javascript

  // set the series name as the default; this is the first entry read by data.columns
  var seriesTime = ['Time'];
  var seriesEffort = ['Effort'];
  var seriesDuration = ['Duration'];

  var table = document.getElementById('datatable');
  var noRows = table.rows.length;

    // go through the table and assign values to the series arrays
  // start with the second row (r = 1) to omit the table's header
  for (var r = 1; r < noRows; r++) {
    seriesTime.push(Date.parse(table.rows[r].cells[0].innerHTML));
    seriesEffort.push(parseInt(table.rows[r].cells[1].innerHTML));
    seriesDuration.push(parseInt(table.rows[r].cells[2].innerHTML));
  }

I then use those arrays as follows:

data: {
  // refer to demo link at: http://api.highcharts.com/highcharts#data.columns
  columns: [
    seriesTime,         // categories
    seriesEffort        // first series
  ]
},

The way this works is that the first item expected in these arrays is the series name, which is why I have as the default value when the arrays are first declared.

Now, once you have the data in arrays, you would need to run through them to calculate your cumulative totals and subtract those whose duration has passed. Unfortunately, I wasn't successful on the duration piece. Here's what I wrote in my fiddle:

    // next, go through the series arrays and tally up the cumulative totals based on duration
  for (var t = 2; t < seriesTime.length; t++) {

    seriesEffort[t]+=seriesEffort[t-1];

    for (var e = 1; e < seriesEffort.length; e++) {
        if (seriesTime[e] < seriesTime[t] - seriesDuration[t]) {        // NOTE: this is where I'm getting stuck
        seriesEffort[t]-=seriesEffort[e];
      } else {
        //seriesEffort[t]+=seriesEffort[e];
      }

    }
  }

I hope this gets you closer to your solution. I apologize that I couldn't get this 100% mocked up for you.

答案 1 :(得分:0)

我最终预处理了数据。首先,我将所有数据点累积到系列中。接下来,我使用durations更新了datetime x值。最后,我减去了x值小于累积数据点x值的每个y值。