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/