问题描述
我试图在多行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],[new Date("2019-09-01T12:20:00.000Z"),[new Date("2019-09-01T12:30:00.000Z"),2,[new Date("2019-10-30T00:00:00.000Z"),1,[new Date("2019-10-30T00:05:00.000Z"),[new Date("2019-10-30T00:10:00.000Z"),7,[new Date("2019-10-30T12:50:00.000Z"),5,[new Date("2019-11-01T12:55:00.000Z"),[new Date("2019-11-01T14:00:00.000Z"),[new Date("2019-11-01T14:05:00.000Z"),4,[new Date("2019-11-01T14:10:00.000Z"),[new Date("2019-11-01T14:15:00.000Z"),8,[new Date("2019-11-01T14:20:00.000Z"),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'
},3,6,7]);
代码链接:https://jsfiddle.net/namangupta/9ghfLx51/35/
我想要的基本上是代表ControlWrapper上的数据,如ChartWrapper上所示,而月份之间没有间隔。
解决方法
如您所见,范围过滤器仅适用于连续轴(数字,日期等)
要更正此问题,并仍在图表的工具提示中显示自定义日期格式,
我们将更改x轴的视图列。
为简单起见,我们将数据表行索引用作x轴值。
这将使我们获得所需的连续轴。
并将格式值设置为自定义日期格式。
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);
请参阅工作小提琴...
https://jsfiddle.net/WhiteHat/9kceva14/1/
注意:在您发布的小提琴中,谷歌图表两次被加载。只需要一个load语句,请参见上面的小提琴...
编辑
要设置x轴标签的格式,我们可以使用相同的方法,
通过提供值(v:
)和格式化值(f:
),
使用选项-> ticks
但是,这确实意味着我们必须手动构建刻度线。
因此您必须提出一种显示所需标签数量的算法。
在此示例中,我对数据视图上的计算列使用了相同的功能。
我已经命名了该函数,并将其重新用于图表刻度。
对于控件,当它更改时,我仅使用月份名称。
但是,第一个月的名字没有出现。
我猜那里根本没有房间。可能需要使用该月中旬的日期。
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,f: rowDate1};
}
请参见图表和控件上的ticks
选项,例如
hAxis: {
textStyle: {
color: '#ffffff',},ticks: ticksControl
}
请参阅以下工作提琴...
https://jsfiddle.net/WhiteHat/9kceva14/3/
编辑2
因为我们本质上是对x轴标签进行硬编码,
拖动范围过滤器手柄时,图表的x轴范围不会动态变化。
要解决此问题,我们可以在范围过滤器上监听'statechange'
事件,
获取过滤器的状态,然后调整图表上的viewWindow
选项。
这将在范围过滤器更改时调整图表上的可见范围。
每当我们更改图表的选项或数据时,
我们还必须重新绘制图表以使更改生效。
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();
}
请参阅以下工作提琴...
https://jsfiddle.net/WhiteHat/9kceva14/5/