首页 文章

使用Highcharts动态绘制点图

提问于
浏览
1

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

示例

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

Timestamp        Effort  Duration
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

Data-Points:
(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 回答

  • 1

    其中一个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>
    ' + 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%嘲笑你 .

  • 0

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

相关问题