Google 可视化 - 在事件 table 排序时,将特定行保留为第一个可见记录?
Google Visualization - On event table sort, keep specific row as first visible record?
当用户单击 header 进行排序时,我希望标记为 "Grand Total" 的行保留在可见的第一行。
我可以按如下方式捕获 table 排序事件:
google.visualization.events.addListener(table.getChart(), 'sort', function() {
console.log('User clicked to sort.');
};
但我不知道如何才能将总行移回第一条记录。
我怎样才能做到这一点?感谢您的提示。
工作示例:(起始代码)
google.charts.load('current', {
'packages': ['corechart', 'table', 'gauge', 'controls', 'charteditor']
});
$(document).ready(function() {
renderChart_onPageLoad();
});
function renderChart_onPageLoad() {
google.charts.setOnLoadCallback(function() {
drawDashboard();
});
}
function drawDashboard() {
var data = google.visualization.arrayToDataTable([
['Name', 'RoolNumber', 'Gender', 'Age', 'Donuts eaten'],
['Michael', 1, 'Male', 12, 5],
['Elisa', 2, 'Female', 20, 7],
['Robert', 3, 'Male', 7, 3],
['John', 4, 'Male', 54, 2],
['Jessica', 5, 'Female', 22, 6],
['Aaron', 6, 'Male', 3, 1],
['Margareth', 7, 'Female', 42, 8],
['Miranda', 8, 'Female', 33, 6]
]);
var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard'));
var categoryPicker = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'categoryPicker',
options: {
filterColumnLabel: 'Gender',
ui: {
labelStacking: 'vertical',
allowTyping: false,
allowMultiple: false
}
}
});
var proxyTable = new google.visualization.ChartWrapper({
chartType: 'Table',
containerId: 'proxyTable',
options: {
width: '500px'
}
});
var table = new google.visualization.ChartWrapper({
chartType: 'Table',
containerId: 'table',
options: {
width: '500px'
}
});
dashboard.bind([categoryPicker], [proxyTable]);
dashboard.draw(data);
google.visualization.events.addListener(dashboard, 'ready', function() {
redrawChart();
});
function redrawChart() {
var sourceData = proxyTable.getDataTable();
var dataResults = sourceData.toDataTable().clone();
var group = google.visualization.data.group(sourceData, [{
// we need a key column to group on, but since we want all rows grouped into 1,
// then it needs a constant value
column: 0,
type: 'number',
modifier: function() {
return 1;
}
}], [{
column: 1,
id: 'SumRool',
label: 'SumRool',
type: 'number',
aggregation: google.visualization.data.sum
}, {
column: 3,
id: 'SumAge',
label: 'SumAge',
type: 'number',
aggregation: google.visualization.data.sum
}, {
// get the average age
column: 4,
id: 'SumEaten',
label: 'SumEaten',
type: 'number',
aggregation: google.visualization.data.sum
}]);
dataResults.insertRows(0, [
['Grand Total', group.getValue(0, 1), null, group.getValue(0, 2), group.getValue(0, 3)],
]);
//Set dataTable
table.setDataTable(dataResults);
table.draw();
// table sort event
google.visualization.events.addListener(table.getChart(), 'sort', function() {
console.log('User clicked header to sort.');
//When a user clicks the header and resorts the table I want the row labeled "Grand Total" to stay as the first row visible.
});
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard">
<div id="categoryPicker"></div><br />
<div id="proxyTable" style='display:none;'></div>
<div id="table"></div><br /><br />
</div>
为了完成,我们需要手动控制排序顺序。
首先,在 table 图表上设置排序选项。
var table = new google.visualization.ChartWrapper({
chartType: 'Table',
containerId: 'table',
options: {
sort: 'event', // <-- set sort to 'event'
width: '500px'
}
});
接下来,我们需要在绘制图表之前分配事件侦听器。
首先,我们必须等待包装器准备好,
然后将排序事件分配给图表。
但我们只想这样做一次,因此 --> addOneTimeListener
google.visualization.events.addOneTimeListener(table, 'ready', function() {
google.visualization.events.addListener(table.getChart(), 'sort', function(sender) {
排序事件接收发生排序的列和方向的属性。 (sender
)
我们将使用这些属性从数据 table.
中获取排序后的行
之后,我们找到总计行的索引,将其从排序顺序中删除,
然后将其添加回第一个索引。
// table sort event
google.visualization.events.addOneTimeListener(table, 'ready', function() {
google.visualization.events.addListener(table.getChart(), 'sort', function(sender) {
// sort data table according to sort properties
var tableData = table.getDataTable();
var sortIndexes = tableData.getSortedRows({column: sender.column, desc: !sender.ascending});
// find grand total row
var grandTotal = tableData.getFilteredRows([{
column: 0,
value: 'Grand Total'
}]);
if (grandTotal.length > 0) {
// find grand total in sort
var grandTotalSort = sortIndexes.indexOf(grandTotal[0]);
// remove grand total from sort
sortIndexes.splice(grandTotalSort, 1);
// add grand total as first index
sortIndexes.unshift(grandTotal[0]);
// set table sort arrow
table.setOption('sortAscending', sender.ascending);
table.setOption('sortColumn', sender.column);
// set table view
table.setView({rows: sortIndexes});
// re-draw table
table.draw();
}
});
});
请参阅以下工作片段...
google.charts.load('current', {
'packages': ['corechart', 'table', 'gauge', 'controls', 'charteditor']
});
$(document).ready(function() {
renderChart_onPageLoad();
});
function renderChart_onPageLoad() {
google.charts.setOnLoadCallback(function() {
drawDashboard();
});
}
function drawDashboard() {
var data = google.visualization.arrayToDataTable([
['Name', 'RoolNumber', 'Gender', 'Age', 'Donuts eaten'],
['Michael', 1, 'Male', 12, 5],
['Elisa', 2, 'Female', 20, 7],
['Robert', 3, 'Male', 7, 3],
['John', 4, 'Male', 54, 2],
['Jessica', 5, 'Female', 22, 6],
['Aaron', 6, 'Male', 3, 1],
['Margareth', 7, 'Female', 42, 8],
['Miranda', 8, 'Female', 33, 6]
]);
var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard'));
var categoryPicker = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'categoryPicker',
options: {
filterColumnLabel: 'Gender',
ui: {
labelStacking: 'vertical',
allowTyping: false,
allowMultiple: false
}
}
});
var proxyTable = new google.visualization.ChartWrapper({
chartType: 'Table',
containerId: 'proxyTable',
options: {
width: '500px'
}
});
var table = new google.visualization.ChartWrapper({
chartType: 'Table',
containerId: 'table',
options: {
sort: 'event',
width: '500px'
}
});
// table sort event
// Moved this listener to main drawDashboard() because having this in redrawChart() was adding a new listener every time someone filtered categoryPicker.
google.visualization.events.addOneTimeListener(table, 'ready', function() {
google.visualization.events.addListener(table.getChart(), 'sort', function(sender) {
// sort data table according to sort properties
var tableData = table.getDataTable();
var sortIndexes = tableData.getSortedRows({column: sender.column, desc: !sender.ascending});
// find grand total row
var grandTotal = tableData.getFilteredRows([{
column: 0,
value: 'Grand Total'
}]);
if (grandTotal.length > 0) {
// find grand total in sort
var grandTotalSort = sortIndexes.indexOf(grandTotal[0]);
// remove grand total from sort
sortIndexes.splice(grandTotalSort, 1);
// add grand total as first index
sortIndexes.unshift(grandTotal[0]);
// set table sort arrow
table.setOption('sortAscending', sender.ascending);
table.setOption('sortColumn', sender.column);
// set table view
table.setView({rows: sortIndexes});
// re-draw table
table.draw();
}
});
});
dashboard.bind([categoryPicker], [proxyTable]);
dashboard.draw(data);
google.visualization.events.addListener(dashboard, 'ready', function() {
redrawChart();
});
function redrawChart() {
var sourceData = proxyTable.getDataTable();
var dataResults = sourceData.toDataTable().clone();
var group = google.visualization.data.group(sourceData, [{
// we need a key column to group on, but since we want all rows grouped into 1,
// then it needs a constant value
column: 0,
type: 'number',
modifier: function() {
return 1;
}
}], [{
column: 1,
id: 'SumRool',
label: 'SumRool',
type: 'number',
aggregation: google.visualization.data.sum
}, {
column: 3,
id: 'SumAge',
label: 'SumAge',
type: 'number',
aggregation: google.visualization.data.sum
}, {
// get the average age
column: 4,
id: 'SumEaten',
label: 'SumEaten',
type: 'number',
aggregation: google.visualization.data.sum
}]);
dataResults.insertRows(0, [
['Grand Total', group.getValue(0, 1), null, group.getValue(0, 2), group.getValue(0, 3)],
]);
//Reset view to clear any user sorting initiated by event listener table.getChart(), 'sort'
table.setView(null);
//Set dataTable
table.setDataTable(dataResults);
table.draw();
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard">
<div id="categoryPicker"></div><br />
<div id="proxyTable" style='display:none;'></div>
<div id="table"></div><br /><br />
</div>
当用户单击 header 进行排序时,我希望标记为 "Grand Total" 的行保留在可见的第一行。
我可以按如下方式捕获 table 排序事件:
google.visualization.events.addListener(table.getChart(), 'sort', function() {
console.log('User clicked to sort.');
};
但我不知道如何才能将总行移回第一条记录。
我怎样才能做到这一点?感谢您的提示。
工作示例:(起始代码)
google.charts.load('current', {
'packages': ['corechart', 'table', 'gauge', 'controls', 'charteditor']
});
$(document).ready(function() {
renderChart_onPageLoad();
});
function renderChart_onPageLoad() {
google.charts.setOnLoadCallback(function() {
drawDashboard();
});
}
function drawDashboard() {
var data = google.visualization.arrayToDataTable([
['Name', 'RoolNumber', 'Gender', 'Age', 'Donuts eaten'],
['Michael', 1, 'Male', 12, 5],
['Elisa', 2, 'Female', 20, 7],
['Robert', 3, 'Male', 7, 3],
['John', 4, 'Male', 54, 2],
['Jessica', 5, 'Female', 22, 6],
['Aaron', 6, 'Male', 3, 1],
['Margareth', 7, 'Female', 42, 8],
['Miranda', 8, 'Female', 33, 6]
]);
var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard'));
var categoryPicker = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'categoryPicker',
options: {
filterColumnLabel: 'Gender',
ui: {
labelStacking: 'vertical',
allowTyping: false,
allowMultiple: false
}
}
});
var proxyTable = new google.visualization.ChartWrapper({
chartType: 'Table',
containerId: 'proxyTable',
options: {
width: '500px'
}
});
var table = new google.visualization.ChartWrapper({
chartType: 'Table',
containerId: 'table',
options: {
width: '500px'
}
});
dashboard.bind([categoryPicker], [proxyTable]);
dashboard.draw(data);
google.visualization.events.addListener(dashboard, 'ready', function() {
redrawChart();
});
function redrawChart() {
var sourceData = proxyTable.getDataTable();
var dataResults = sourceData.toDataTable().clone();
var group = google.visualization.data.group(sourceData, [{
// we need a key column to group on, but since we want all rows grouped into 1,
// then it needs a constant value
column: 0,
type: 'number',
modifier: function() {
return 1;
}
}], [{
column: 1,
id: 'SumRool',
label: 'SumRool',
type: 'number',
aggregation: google.visualization.data.sum
}, {
column: 3,
id: 'SumAge',
label: 'SumAge',
type: 'number',
aggregation: google.visualization.data.sum
}, {
// get the average age
column: 4,
id: 'SumEaten',
label: 'SumEaten',
type: 'number',
aggregation: google.visualization.data.sum
}]);
dataResults.insertRows(0, [
['Grand Total', group.getValue(0, 1), null, group.getValue(0, 2), group.getValue(0, 3)],
]);
//Set dataTable
table.setDataTable(dataResults);
table.draw();
// table sort event
google.visualization.events.addListener(table.getChart(), 'sort', function() {
console.log('User clicked header to sort.');
//When a user clicks the header and resorts the table I want the row labeled "Grand Total" to stay as the first row visible.
});
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard">
<div id="categoryPicker"></div><br />
<div id="proxyTable" style='display:none;'></div>
<div id="table"></div><br /><br />
</div>
为了完成,我们需要手动控制排序顺序。
首先,在 table 图表上设置排序选项。
var table = new google.visualization.ChartWrapper({
chartType: 'Table',
containerId: 'table',
options: {
sort: 'event', // <-- set sort to 'event'
width: '500px'
}
});
接下来,我们需要在绘制图表之前分配事件侦听器。
首先,我们必须等待包装器准备好,
然后将排序事件分配给图表。
但我们只想这样做一次,因此 --> addOneTimeListener
google.visualization.events.addOneTimeListener(table, 'ready', function() {
google.visualization.events.addListener(table.getChart(), 'sort', function(sender) {
排序事件接收发生排序的列和方向的属性。 (sender
)
我们将使用这些属性从数据 table.
中获取排序后的行
之后,我们找到总计行的索引,将其从排序顺序中删除,
然后将其添加回第一个索引。
// table sort event
google.visualization.events.addOneTimeListener(table, 'ready', function() {
google.visualization.events.addListener(table.getChart(), 'sort', function(sender) {
// sort data table according to sort properties
var tableData = table.getDataTable();
var sortIndexes = tableData.getSortedRows({column: sender.column, desc: !sender.ascending});
// find grand total row
var grandTotal = tableData.getFilteredRows([{
column: 0,
value: 'Grand Total'
}]);
if (grandTotal.length > 0) {
// find grand total in sort
var grandTotalSort = sortIndexes.indexOf(grandTotal[0]);
// remove grand total from sort
sortIndexes.splice(grandTotalSort, 1);
// add grand total as first index
sortIndexes.unshift(grandTotal[0]);
// set table sort arrow
table.setOption('sortAscending', sender.ascending);
table.setOption('sortColumn', sender.column);
// set table view
table.setView({rows: sortIndexes});
// re-draw table
table.draw();
}
});
});
请参阅以下工作片段...
google.charts.load('current', {
'packages': ['corechart', 'table', 'gauge', 'controls', 'charteditor']
});
$(document).ready(function() {
renderChart_onPageLoad();
});
function renderChart_onPageLoad() {
google.charts.setOnLoadCallback(function() {
drawDashboard();
});
}
function drawDashboard() {
var data = google.visualization.arrayToDataTable([
['Name', 'RoolNumber', 'Gender', 'Age', 'Donuts eaten'],
['Michael', 1, 'Male', 12, 5],
['Elisa', 2, 'Female', 20, 7],
['Robert', 3, 'Male', 7, 3],
['John', 4, 'Male', 54, 2],
['Jessica', 5, 'Female', 22, 6],
['Aaron', 6, 'Male', 3, 1],
['Margareth', 7, 'Female', 42, 8],
['Miranda', 8, 'Female', 33, 6]
]);
var dashboard = new google.visualization.Dashboard(document.getElementById('dashboard'));
var categoryPicker = new google.visualization.ControlWrapper({
controlType: 'CategoryFilter',
containerId: 'categoryPicker',
options: {
filterColumnLabel: 'Gender',
ui: {
labelStacking: 'vertical',
allowTyping: false,
allowMultiple: false
}
}
});
var proxyTable = new google.visualization.ChartWrapper({
chartType: 'Table',
containerId: 'proxyTable',
options: {
width: '500px'
}
});
var table = new google.visualization.ChartWrapper({
chartType: 'Table',
containerId: 'table',
options: {
sort: 'event',
width: '500px'
}
});
// table sort event
// Moved this listener to main drawDashboard() because having this in redrawChart() was adding a new listener every time someone filtered categoryPicker.
google.visualization.events.addOneTimeListener(table, 'ready', function() {
google.visualization.events.addListener(table.getChart(), 'sort', function(sender) {
// sort data table according to sort properties
var tableData = table.getDataTable();
var sortIndexes = tableData.getSortedRows({column: sender.column, desc: !sender.ascending});
// find grand total row
var grandTotal = tableData.getFilteredRows([{
column: 0,
value: 'Grand Total'
}]);
if (grandTotal.length > 0) {
// find grand total in sort
var grandTotalSort = sortIndexes.indexOf(grandTotal[0]);
// remove grand total from sort
sortIndexes.splice(grandTotalSort, 1);
// add grand total as first index
sortIndexes.unshift(grandTotal[0]);
// set table sort arrow
table.setOption('sortAscending', sender.ascending);
table.setOption('sortColumn', sender.column);
// set table view
table.setView({rows: sortIndexes});
// re-draw table
table.draw();
}
});
});
dashboard.bind([categoryPicker], [proxyTable]);
dashboard.draw(data);
google.visualization.events.addListener(dashboard, 'ready', function() {
redrawChart();
});
function redrawChart() {
var sourceData = proxyTable.getDataTable();
var dataResults = sourceData.toDataTable().clone();
var group = google.visualization.data.group(sourceData, [{
// we need a key column to group on, but since we want all rows grouped into 1,
// then it needs a constant value
column: 0,
type: 'number',
modifier: function() {
return 1;
}
}], [{
column: 1,
id: 'SumRool',
label: 'SumRool',
type: 'number',
aggregation: google.visualization.data.sum
}, {
column: 3,
id: 'SumAge',
label: 'SumAge',
type: 'number',
aggregation: google.visualization.data.sum
}, {
// get the average age
column: 4,
id: 'SumEaten',
label: 'SumEaten',
type: 'number',
aggregation: google.visualization.data.sum
}]);
dataResults.insertRows(0, [
['Grand Total', group.getValue(0, 1), null, group.getValue(0, 2), group.getValue(0, 3)],
]);
//Reset view to clear any user sorting initiated by event listener table.getChart(), 'sort'
table.setView(null);
//Set dataTable
table.setDataTable(dataResults);
table.draw();
}
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://www.gstatic.com/charts/loader.js"></script>
<div id="dashboard">
<div id="categoryPicker"></div><br />
<div id="proxyTable" style='display:none;'></div>
<div id="table"></div><br /><br />
</div>