Google图表仪表板-在ControlWrapper中将“ ChartRangeFilter”视图设置为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],[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]);

当前图表视图-

enter image description here

代码链接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/

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...