在不同的值上透视 Google DataTable
Pivot Google DataTable on distinct values
我有一个 Google 数据表,格式如下:
+----------+-------+--------+
| time | label | values |
+----------+-------+--------+
| 12345678 | foo | 100 |
| 12345678 | bar | 200 |
| 12345700 | foo | 150 |
| 12345700 | bar | 350 |
... ... ...
我需要创建一个折线图,每个不同 "label",时间在 X 轴上,值在 Y 轴上。
据我所知,这要求数据表采用以下格式:
+----------+-----+-----+
| time | foo | bar |
+----------+-----+-----+
| 12345678 | 100 | 200 |
| 12345700 | 150 | 350 |
... ... ...
我要么需要一种将 DataTable 旋转成这种形状的方法,要么需要一种在不修改原始 DataTable 的情况下绘制我想要的折线图的方法。
附录
我可以很容易地创建这种形状的数据表,如下所示:
var newDataTable = new google.visualization.DataTable();
newDataTable.addColumn("number", "time");
var distinctLabels = oldDataTable.getDistinctValues(1);
for (var i = 0; i < distinctLabels.length; i++)
{
newDataTable.addColumn("number", distinctLabels[i]);
}
但是接下来的挑战是填充这个 table。由于新 table 中单行的数据存在于第一个 table 的多行中,我不能简单地遍历旧 table 的每一行调用 .addRow()
到新的table
我可以利用散列table或其他一些复杂的结构来解析数据并使用它,但是:
- 这似乎是一个有更简单解决方案的问题
- 我想要最好的性能,因为每次有人与页面上的 UI 元素交互时都需要重新绘制此折线图
首先,您可以创建一个 DataView
,其中包含每个不同标签的列
然后使用group()
方法按时间戳聚合标签列
请参阅以下工作片段...
google.charts.load('current', {
callback: drawChart,
packages: ['corechart', 'table']
});
function drawChart() {
var data = google.visualization.arrayToDataTable([
['time', 'label', 'value'],
['12345678', 'foo', 100],
['12345678', 'bar', 200],
['12345700', 'foo', 150],
['12345700', 'bar', 350],
]);
var aggColumns = [];
var viewColumns = [0];
var distinctLabels = data.getDistinctValues(1);
distinctLabels.forEach(function (label, index) {
viewColumns.push({
calc: function (dt, row) {
if (dt.getValue(row, 1) === label) {
return dt.getValue(row, 2);
}
return null;
},
type: 'number',
label: label
});
aggColumns.push({
column: index + 1,
aggregation: google.visualization.data.sum,
type: 'number'
});
});
var view = new google.visualization.DataView(data);
view.setColumns(viewColumns);
var groupData = google.visualization.data.group(
view,
[0],
aggColumns
);
var chart = new google.visualization.LineChart(document.getElementById('chart'));
chart.draw(groupData);
var table = new google.visualization.Table(document.getElementById('table'));
table.draw(groupData);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart"></div>
<div id="table"></div>
我有一个 Google 数据表,格式如下:
+----------+-------+--------+
| time | label | values |
+----------+-------+--------+
| 12345678 | foo | 100 |
| 12345678 | bar | 200 |
| 12345700 | foo | 150 |
| 12345700 | bar | 350 |
... ... ...
我需要创建一个折线图,每个不同 "label",时间在 X 轴上,值在 Y 轴上。
据我所知,这要求数据表采用以下格式:
+----------+-----+-----+
| time | foo | bar |
+----------+-----+-----+
| 12345678 | 100 | 200 |
| 12345700 | 150 | 350 |
... ... ...
我要么需要一种将 DataTable 旋转成这种形状的方法,要么需要一种在不修改原始 DataTable 的情况下绘制我想要的折线图的方法。
附录
我可以很容易地创建这种形状的数据表,如下所示:
var newDataTable = new google.visualization.DataTable();
newDataTable.addColumn("number", "time");
var distinctLabels = oldDataTable.getDistinctValues(1);
for (var i = 0; i < distinctLabels.length; i++)
{
newDataTable.addColumn("number", distinctLabels[i]);
}
但是接下来的挑战是填充这个 table。由于新 table 中单行的数据存在于第一个 table 的多行中,我不能简单地遍历旧 table 的每一行调用 .addRow()
到新的table
我可以利用散列table或其他一些复杂的结构来解析数据并使用它,但是:
- 这似乎是一个有更简单解决方案的问题
- 我想要最好的性能,因为每次有人与页面上的 UI 元素交互时都需要重新绘制此折线图
首先,您可以创建一个 DataView
,其中包含每个不同标签的列
然后使用group()
方法按时间戳聚合标签列
请参阅以下工作片段...
google.charts.load('current', {
callback: drawChart,
packages: ['corechart', 'table']
});
function drawChart() {
var data = google.visualization.arrayToDataTable([
['time', 'label', 'value'],
['12345678', 'foo', 100],
['12345678', 'bar', 200],
['12345700', 'foo', 150],
['12345700', 'bar', 350],
]);
var aggColumns = [];
var viewColumns = [0];
var distinctLabels = data.getDistinctValues(1);
distinctLabels.forEach(function (label, index) {
viewColumns.push({
calc: function (dt, row) {
if (dt.getValue(row, 1) === label) {
return dt.getValue(row, 2);
}
return null;
},
type: 'number',
label: label
});
aggColumns.push({
column: index + 1,
aggregation: google.visualization.data.sum,
type: 'number'
});
});
var view = new google.visualization.DataView(data);
view.setColumns(viewColumns);
var groupData = google.visualization.data.group(
view,
[0],
aggColumns
);
var chart = new google.visualization.LineChart(document.getElementById('chart'));
chart.draw(groupData);
var table = new google.visualization.Table(document.getElementById('table'));
table.draw(groupData);
}
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="chart"></div>
<div id="table"></div>