Google 图表仪表板 - 将 ControlWrapper 中的 'ChartRangeFilter' 视图设置为 ChartWrapper
Google Charts Dashboard - Set 'ChartRangeFilter' view in ControlWrapper as ChartWrapper
我试图在多线图 Google 图表中表示一个月中每个工作日的 24 小时数据。
如果我在没有自定义视图的情况下在 ChartWrapper 中正常设置数据,那么它会在连续的月份之间产生间隔,因为每个月的数据只会在一天的 24 小时内存在。
到目前为止,我已经能够根据主 ChartWrapper 的要求使用自定义视图(如 string)来表示它,但无法在 ControlWrapper 中设置与它相同的视图不允许在视图中输入 string。这里使用的时间戳格式 (MM yy HH:mm) 不是常规格式。
示例图表数据-
var data = [
["Date", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
[new Date("2019-09-01T12:25:00.000Z"), 0, 0, 0, 0, 0, 0, 0],
[new Date("2019-09-01T12:20:00.000Z"), 0, 0, 0, 0, 0, 0, 0],
[new Date("2019-09-01T12:30:00.000Z"), 0, 2, 0, 0, 0, 0, 0],
[new Date("2019-10-30T00:00:00.000Z"), 0, 1, 0, 0, 0, 0, 0],
[new Date("2019-10-30T00:05:00.000Z"), 0, 2, 0, 0, 0, 0, 0],
[new Date("2019-10-30T00:10:00.000Z"), 0, 7, 0, 0, 0, 0, 0],
[new Date("2019-10-30T12:50:00.000Z"), 0, 5, 0, 0, 0, 0, 0],
[new Date("2019-11-01T12:55:00.000Z"), 0, 0, 0, 0, 0, 0, 0],
[new Date("2019-11-01T14:00:00.000Z"), 0, 5, 0, 0, 0, 0, 0],
[new Date("2019-11-01T14:05:00.000Z"), 0, 4, 0, 0, 0, 0, 0],
[new Date("2019-11-01T14:10:00.000Z"), 0, 2, 0, 0, 0, 0, 0],
[new Date("2019-11-01T14:15:00.000Z"), 0, 8, 0, 0, 0, 0, 0],
[new Date("2019-11-01T14:20:00.000Z"), 0, 2, 0, 0, 0, 0, 0]]
ChartWrapper 的自定义视图-
var formatDate = new google.visualization.DateFormat({
pattern: 'MMM yy'
});
var formatMonth = new google.visualization.DateFormat({
pattern: 'MMM'
});
var formatTime = new google.visualization.DateFormat({
pattern: 'HH:mm'
});
var view = new google.visualization.DataView(chart_data);
view.setColumns([{
calc: function(dt, row) {
var rowDate1 = formatDate.formatValue(dt.getValue(row, 0));
var rowDate2 = null;
if (row > 0) {
rowDate2 = formatDate.formatValue(dt.getValue(row - 1, 0));
}
if (rowDate1 === rowDate2) {
rowDate1 = formatMonth.formatValue(dt.getValue(row, 0)) + ' ' + formatTime.formatValue(dt.getValue(row - 1, 0));
}
return rowDate1;
},
label: chart_data.getColumnLabel(0),
type: 'string'
}, 1, 2, 3, 4, 5, 6, 7]);
当前图表视图-
代码link:https://jsfiddle.net/namangupta/9ghfLx51/35/
我想要的基本上是在 ControlWrapper 上表示数据,因为它在 ChartWrapper 上显示,没有月份之间的间隙。
如您所见,范围过滤器仅适用于连续轴(数字、日期等...)
要更正此问题,并在图表的工具提示中仍然显示自定义日期格式,
我们将更改 x-axis.
的视图列
为简单起见,我们将使用数据 table 行索引作为 x-axis 值。
这将为我们提供所需的连续轴。
我们会将格式化值设置为自定义日期格式。
return {v: row, f: rowDate1}; // <-- set both value and formatted value
视图栏...
calc: function(dt, row) {
var rowDate1 = formatDate.formatValue(dt.getValue(row, 0));
var rowDate2 = null;
if (row > 0) {
rowDate2 = formatDate.formatValue(dt.getValue(row - 1, 0));
}
if (rowDate1 === rowDate2) {
rowDate1 = formatMonth.formatValue(dt.getValue(row, 0)) + ' ' + formatTime.formatValue(dt.getValue(row - 1, 0));
}
return {v: row, f: rowDate1}; // <-- set both value and formatted value
},
我们将使用视图来设置范围过滤器的最小值/最大值...
var dateRange = view.getColumnRange(0);
var mindate = dateRange.min;
var maxdate = dateRange.max;
并使用视图绘制仪表板...
// draw the dashboard
dash.draw(view);
查看工作 fiddle...
https://jsfiddle.net/WhiteHat/9kceva14/1/
注意:在您发布的 fiddle 中,google 图表被加载了两次。只需要一个加载语句,见上文fiddle...
编辑
格式化x-axis标签,我们可以使用相同的方法,
通过同时提供值 (v:
) 和格式化值 (f:
),
使用选项 --> ticks
然而,这确实意味着我们必须手动构建刻度。
所以你必须想出显示所需标签数量的算法。
在此示例中,我对数据视图中的计算列使用了相同的函数。
我已经为该函数命名,re-used 它用于图表刻度。
对于控件,我只使用月份名称,当它发生变化时。
然而,第一个月的名字没有出现。
我猜只是没有空间。可能需要使用月中或其他日期。
var view = new google.visualization.DataView(chart_data);
view.setColumns([{
calc: formatAxis,
label: chart_data.getColumnLabel(0),
type: 'number'
}, 1, 2, 3, 4, 5, 6, 7]);
var ticksChart = [];
var ticksControl = [];
var monthTick;
var monthName = null;
for (var i = 0; i < chart_data.getNumberOfRows(); i++) {
// chart ticks
ticksChart.push(formatAxis(chart_data, i));
// control ticks
monthTick = formatMonth.formatValue(chart_data.getValue(i, 0));
if (monthTick !== monthName) {
monthName = monthTick;
ticksControl.push({v: i, f: monthName});
}
}
function formatAxis(dt, row) {
var rowDate1 = formatDate.formatValue(dt.getValue(row, 0));
var rowDate2 = null;
if (row > 0) {
rowDate2 = formatDate.formatValue(dt.getValue(row - 1, 0));
}
if (rowDate1 === rowDate2) {
rowDate1 = formatMonth.formatValue(dt.getValue(row, 0)) + ' ' + formatTime.formatValue(dt.getValue(row - 1, 0));
}
return {v: row, f: rowDate1};
}
查看图表和控件上的 ticks
选项,例如
hAxis: {
textStyle: {
color: '#ffffff',
},
ticks: ticksControl
}
查看以下工作 fiddle...
https://jsfiddle.net/WhiteHat/9kceva14/3/
编辑 2
因为我们本质上是 hard-coding x-axis 标签,
当我们拖动范围过滤器手柄时,图表的 x-axis 范围不会动态变化。
为了解决这个问题,我们可以在范围过滤器上监听 'statechange'
事件,
获取过滤器的状态,并调整图表上的 viewWindow
选项。
这将随着范围过滤器的变化调整图表上的可见范围。
每当我们更改图表的选项或数据时,
我们还必须 re-draw 图表才能使更改生效。
google.visualization.events.addListener(rangeFilter, 'statechange', onStateChange);
function onStateChange() {
var filterState = rangeFilter.getState();
chart.setOption('hAxis.viewWindow', {
min: filterState.range.start,
max: filterState.range.end
});
chart.draw();
}
查看以下工作 fiddle...
https://jsfiddle.net/WhiteHat/9kceva14/5/
我试图在多线图 Google 图表中表示一个月中每个工作日的 24 小时数据。
如果我在没有自定义视图的情况下在 ChartWrapper 中正常设置数据,那么它会在连续的月份之间产生间隔,因为每个月的数据只会在一天的 24 小时内存在。 到目前为止,我已经能够根据主 ChartWrapper 的要求使用自定义视图(如 string)来表示它,但无法在 ControlWrapper 中设置与它相同的视图不允许在视图中输入 string。这里使用的时间戳格式 (MM yy HH:mm) 不是常规格式。
示例图表数据-
var data = [
["Date", "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
[new Date("2019-09-01T12:25:00.000Z"), 0, 0, 0, 0, 0, 0, 0],
[new Date("2019-09-01T12:20:00.000Z"), 0, 0, 0, 0, 0, 0, 0],
[new Date("2019-09-01T12:30:00.000Z"), 0, 2, 0, 0, 0, 0, 0],
[new Date("2019-10-30T00:00:00.000Z"), 0, 1, 0, 0, 0, 0, 0],
[new Date("2019-10-30T00:05:00.000Z"), 0, 2, 0, 0, 0, 0, 0],
[new Date("2019-10-30T00:10:00.000Z"), 0, 7, 0, 0, 0, 0, 0],
[new Date("2019-10-30T12:50:00.000Z"), 0, 5, 0, 0, 0, 0, 0],
[new Date("2019-11-01T12:55:00.000Z"), 0, 0, 0, 0, 0, 0, 0],
[new Date("2019-11-01T14:00:00.000Z"), 0, 5, 0, 0, 0, 0, 0],
[new Date("2019-11-01T14:05:00.000Z"), 0, 4, 0, 0, 0, 0, 0],
[new Date("2019-11-01T14:10:00.000Z"), 0, 2, 0, 0, 0, 0, 0],
[new Date("2019-11-01T14:15:00.000Z"), 0, 8, 0, 0, 0, 0, 0],
[new Date("2019-11-01T14:20:00.000Z"), 0, 2, 0, 0, 0, 0, 0]]
ChartWrapper 的自定义视图-
var formatDate = new google.visualization.DateFormat({
pattern: 'MMM yy'
});
var formatMonth = new google.visualization.DateFormat({
pattern: 'MMM'
});
var formatTime = new google.visualization.DateFormat({
pattern: 'HH:mm'
});
var view = new google.visualization.DataView(chart_data);
view.setColumns([{
calc: function(dt, row) {
var rowDate1 = formatDate.formatValue(dt.getValue(row, 0));
var rowDate2 = null;
if (row > 0) {
rowDate2 = formatDate.formatValue(dt.getValue(row - 1, 0));
}
if (rowDate1 === rowDate2) {
rowDate1 = formatMonth.formatValue(dt.getValue(row, 0)) + ' ' + formatTime.formatValue(dt.getValue(row - 1, 0));
}
return rowDate1;
},
label: chart_data.getColumnLabel(0),
type: 'string'
}, 1, 2, 3, 4, 5, 6, 7]);
当前图表视图-
代码link:https://jsfiddle.net/namangupta/9ghfLx51/35/
我想要的基本上是在 ControlWrapper 上表示数据,因为它在 ChartWrapper 上显示,没有月份之间的间隙。
如您所见,范围过滤器仅适用于连续轴(数字、日期等...)
要更正此问题,并在图表的工具提示中仍然显示自定义日期格式,
我们将更改 x-axis.
为简单起见,我们将使用数据 table 行索引作为 x-axis 值。
这将为我们提供所需的连续轴。
我们会将格式化值设置为自定义日期格式。
return {v: row, f: rowDate1}; // <-- set both value and formatted value
视图栏...
calc: function(dt, row) {
var rowDate1 = formatDate.formatValue(dt.getValue(row, 0));
var rowDate2 = null;
if (row > 0) {
rowDate2 = formatDate.formatValue(dt.getValue(row - 1, 0));
}
if (rowDate1 === rowDate2) {
rowDate1 = formatMonth.formatValue(dt.getValue(row, 0)) + ' ' + formatTime.formatValue(dt.getValue(row - 1, 0));
}
return {v: row, f: rowDate1}; // <-- set both value and formatted value
},
我们将使用视图来设置范围过滤器的最小值/最大值...
var dateRange = view.getColumnRange(0);
var mindate = dateRange.min;
var maxdate = dateRange.max;
并使用视图绘制仪表板...
// draw the dashboard
dash.draw(view);
查看工作 fiddle...
https://jsfiddle.net/WhiteHat/9kceva14/1/
注意:在您发布的 fiddle 中,google 图表被加载了两次。只需要一个加载语句,见上文fiddle...
编辑
格式化x-axis标签,我们可以使用相同的方法,
通过同时提供值 (v:
) 和格式化值 (f:
),
使用选项 --> ticks
然而,这确实意味着我们必须手动构建刻度。
所以你必须想出显示所需标签数量的算法。
在此示例中,我对数据视图中的计算列使用了相同的函数。
我已经为该函数命名,re-used 它用于图表刻度。
对于控件,我只使用月份名称,当它发生变化时。
然而,第一个月的名字没有出现。
我猜只是没有空间。可能需要使用月中或其他日期。
var view = new google.visualization.DataView(chart_data);
view.setColumns([{
calc: formatAxis,
label: chart_data.getColumnLabel(0),
type: 'number'
}, 1, 2, 3, 4, 5, 6, 7]);
var ticksChart = [];
var ticksControl = [];
var monthTick;
var monthName = null;
for (var i = 0; i < chart_data.getNumberOfRows(); i++) {
// chart ticks
ticksChart.push(formatAxis(chart_data, i));
// control ticks
monthTick = formatMonth.formatValue(chart_data.getValue(i, 0));
if (monthTick !== monthName) {
monthName = monthTick;
ticksControl.push({v: i, f: monthName});
}
}
function formatAxis(dt, row) {
var rowDate1 = formatDate.formatValue(dt.getValue(row, 0));
var rowDate2 = null;
if (row > 0) {
rowDate2 = formatDate.formatValue(dt.getValue(row - 1, 0));
}
if (rowDate1 === rowDate2) {
rowDate1 = formatMonth.formatValue(dt.getValue(row, 0)) + ' ' + formatTime.formatValue(dt.getValue(row - 1, 0));
}
return {v: row, f: rowDate1};
}
查看图表和控件上的 ticks
选项,例如
hAxis: {
textStyle: {
color: '#ffffff',
},
ticks: ticksControl
}
查看以下工作 fiddle...
https://jsfiddle.net/WhiteHat/9kceva14/3/
编辑 2
因为我们本质上是 hard-coding x-axis 标签,
当我们拖动范围过滤器手柄时,图表的 x-axis 范围不会动态变化。
为了解决这个问题,我们可以在范围过滤器上监听 'statechange'
事件,
获取过滤器的状态,并调整图表上的 viewWindow
选项。
这将随着范围过滤器的变化调整图表上的可见范围。
每当我们更改图表的选项或数据时,
我们还必须 re-draw 图表才能使更改生效。
google.visualization.events.addListener(rangeFilter, 'statechange', onStateChange);
function onStateChange() {
var filterState = rangeFilter.getState();
chart.setOption('hAxis.viewWindow', {
min: filterState.range.start,
max: filterState.range.end
});
chart.draw();
}
查看以下工作 fiddle...
https://jsfiddle.net/WhiteHat/9kceva14/5/