Google 图表 DateFormatter 不显示格式化值

Google Charts DateFormatter not displaying formatted values

所以我目前正在尝试解决 Google 图表的问题。我正在绘制一个图表,该图表在 Y 轴上显示数值,在 X 轴上显示日期。我希望日期根据指定的时区进行调整。为此,我使用 Google 图表中的 DateFormatter 对象,提供模式和时区,如下所示:

var dateFormatter = new google.visualization.DateFormat({
                timeZone: _timeZone, //timezone
                pattern: $scope.selectedResolution.pattern
            });

pattern 属性接收一个包含格式字符串的字符串,timeZone 接收一个表示时区偏移小时数的值(例如,-4、-5 等)。

我像这样格式化图表值:

dateFormatter.format($scope.data, 0);

因为“0”列是我的约会对象所在的列。

然后我画图表,标准的东西:

 chart = new google.visualization.ComboChart(document.getElementById(chart_name));

                    //generateTicks($scope.data, options);

                    chart.draw($scope.data, options);

问题是,X 轴中显示的值无论如何都没有格式化,无论是格式还是时区。

Problem Showcase

正如您在上图中看到的那样,X 轴在本应显示“15:00”的地方显示“13:00”,在这种特殊情况下。

我还去检查了我正在提供给图表的数据,看看格式化程序是否真的对数据本身做了任何工作并且它似乎工作正常:

Chart Data

此外,这是我的图表选项供参考:

var series = {}, firstSerie, row, title, tempRows = [];

            // Create the data table
            series[0] = {targetAxisIndex: 0, color: '#3182BD'};
            series[1] = {color: '#FF7F00', type: 'line'};

            options = {
                tooltip: {isHtml: true},
                titleTextStyle: {fontSize: 12, bold: false},
                isStacked: false,
                backgroundColor: 'transparent',
                legend: {position: 'none'},
                height: 300,
                pointSize: 1,
                series: series,
                vAxes: {
                    // Adds titles to each axis.
                    0: {
                        textStyle: {color: $scope.widgetOptions.text_color || '#333333'},
                        format: $scope.vLabel === '%' ? '#\'%\'' : generateVerticalAxisPattern() + $filter('trustedHtml')($scope.vLabel),
                        minValue: 0,
                        gridlines: {
                            color: 'transparent'
                        }
                    }
                },
                hAxis: {
                    //title: graphLegend,
                    textStyle: {color: $scope.widgetOptions.text_color || '#333333'},
                    titleTextStyle: {color: $scope.widgetOptions.text_color || '#333333'},
                    viewWindows: {
                        min: moment().subtract(24, 'hours'),
                        max: moment()
                    },
                    gridlines: {
                        color: 'transparent',
                        units: {
                            hours: {format: ['HH:mm', 'ha']}
                        },
                        count: -1
                    },
                    minorGridlines: {
                        count: 0
                    }
                },
                vAxis: {
                    viewWindowMode: 'maximized',
                    viewWindow: {
                        min: $scope.widgetOptions.lower_limit
                    }
                },
                animation: {
                    duration: 500,
                    easing: 'out'
                }
            };

所以,有人知道发生了什么事吗?顺便说一句,我正在与 angularjs 合作。 提前致谢

format方法,如下,只格式化数据,不格式化图表或图表坐标轴。

dateFormatter.format($scope.data, 0);

基本上,上面的内容用于在悬停数据点时在工具提示中显示正确的格式。

要格式化轴,您通常会设置 format 配置选项。

hAxis: {
  format: $scope.selectedResolution.pattern
}

但是,在这种情况下,由于您正在更改时区,
您需要在 x 轴上提供自定义刻度。

您可以根据 table 行数据构建一个报价数组,
使用格式化程序中的 formatValue 方法。

var ticks = [];
for (var i = 0; i < $scope.data.getNumberOfRows(); i++) {
  var dateValue = $scope.data.getValue(i, 0);
  ticks.push({
    v: dateValue,
    f: dateFormatter.formatValue(dateValue)
  });
}

// then add above to ticks to options...

hAxis: {
  ticks: ticks
}

每个刻度都需要是一个对象,
具有 v: 的属性,
f: 用于格式化值。

以上套路唯一的问题,
它假定您要为数据 table.

中的每一行显示一个勾号

如果您没有足够的空间来展示它们,
您需要找出自己的算法来显示正确的刻度数。

编辑

另一种方法是在数据中查找最小和最大日期 table,
使用数据 table 方法 getColumnRange
然后在特定持续时间后构建每个刻度。

例如,在最小日期和最大日期之间沿轴每四个小时显示一个刻度...

  const FOUR_HOURS = (1000 * 60 * 60 * 4);
  var ticks = [];
  var dateRange = $scope.data.getColumnRange(0);
  for (var i = dateRange.min.getTime(); i <= dateRange.max.getTime(); i = i + FOUR_HOURS) {
    var dateValue = new Date(i);
    ticks.push({
      v: dateValue,
      f: dateFormatter.formatValue(dateValue)
    });
  }