使用高图表动态绘制点图



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

假设我有下面显示的表格。"日期"和"工作量"列将构成折线图的 x,y 坐标(时间戳、工作量)。此折线图将包含基于"时间戳"和"工作量"列中的累积总计的数据点。"持续时间"列将确定条目对折线图的数据点产生影响的时间长度。因此,根据此表,我想要一个折线图,其中包含"数据点"下列出的坐标。

时间戳工作量持续时间
4/13/2016 12:13:12.15    10     100
4/13/2016 12:13:12.80    12     100
4/13/2016 12:13:13.15    30     100
2016/4/13 12:13:13.80 50 100

数据点:
(4/13/2016 12:13:12.15, 10)
(4/13/2016 12:13:12.80, 22)
(4/13/2016 12:13:13.15, 42)
(4/13/2016 12:13:13.80, 80)

其中一个

Highcharts演示精确地展示了如何使用静态HTML表实现此目的:http://www.highcharts.com/demo/column-parsed。

我使用您的示例数据创建了一个小提琴,并根据您的要求将其绘制为折线图:http://jsfiddle.net/brightmatrix/qgvkp0t0/

您的数据表的编码将类似于以下内容:

<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>

然后,您将使用以下代码创建图表。请注意调用 HTML 表 ID 的 data 属性:

$(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;
      }
    }
  });
});

需要注意的一点是:无需任何修改,时间戳数据将作为datetime类型读取到 x 轴中。这会给您之间的日期或时间留下空点。

在我的示例中,我显式将 x 轴类型设置为 category ,以便图表上每个数据点只有一个图。

现在,要使 x 轴标签以更易读的格式显示,您可以浏览xAxis.labels.formatter属性 (http://api.highcharts.com/highcharts#xAxis.labels.formatter) 和Highcharts.dateFormat()函数 (http://api.highcharts.com/highcharts#Highcharts.dateFormat)。

更新(2016 年 7 月 13 日):我已经能够解决原始海报的要求,即根据 HTML 表中的数据添加累积点,但不能删除早于当前数据点持续时间的日期。我的修改如下。

为了在绘制图表之前从 HTML 表中获取数据并使用它,我使用了 data.columns 属性(请参阅 http://api.highcharts.com/highcharts#data.columns)。

在声明图表选项之前,我编写了此代码来浏览 HTML 表并将内容添加到数组中。

  // 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));
  }

然后,我按如下方式使用这些数组:

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

其工作方式是这些数组中预期的第一项是系列名称,这就是为什么我在首次声明数组时将默认值作为默认值的原因。

现在,一旦数据在数组中,您需要运行它们来计算累积总数并减去持续时间已过的数据。不幸的是,我在持续时间部分没有成功。这是我在小提琴中写的:

    // 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];
      }
    }
  }

我希望这能让您更接近您的解决方案。很抱歉,我无法为您 100% 模拟这个。

我最终预处理了数据。首先,我将所有数据点累积到序列中。接下来,我用持续时间更新了日期时间 x 值。最后,我减去 x 值小于累积数据点的 x 值的每个单独的 y 值。

最新更新