ChartJS / MomentJS - 无法删除弃用警告。 firefox/opera 中未显示图表

ChartJS / MomentJS - Unable to remove deprecation warning. Graph not showing in firefox/opera

所以浏览器抛出

关于错误使用 momentJS 的警告。

Deprecation warning: value provided is not in a recognized ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non ISO date formats are discouraged and will be removed in an upcoming major release. Please refer to http://momentjs.com/guides/#/warnings/js-date/ for more info.
Arguments: 
[0] _isAMomentObject: true, _isUTC: false, _useUTC: false, _l: undefined, _i: 12.30, _f: false, _strict: undefined, _locale: [object Object]
Error 

所以我查看了我的代码

data: {
  labels: ['01.01', '02.01', '03.01', '04.01', '05.01', '06.01', '07.01', '08.01', '09.01', '10.01', '11.01', '12.01'],
  datasets: createChatterData(data, this)
},

并读到在处理非 iso 字符串时我应该提供一种格式。

labels: [moment('01.01', 'MM.DD'), moment('02.01', 'MM.DD'), ...];

好的,删除了第一个弃用。

但我的数据集数据还包含日期

    dataset.data.pushObject({
        x: moment(datum).format('MM.DD'),
        y: parseInt(moment(datum).format('YYYY'))
    });

所以我尝试了不同的变体(预修改的模糊日期时间)

x: moment(date, 'YYYY.MM.DD').format('MM.DD') 

x: moment(date, 'MM.DD')

但我的图表不再正确映射。

在 chrome 中工作的 codepen 图表示例:http://codepen.io/kristjanrein/pen/wJrQLE 在 firefox/opera

中不显示

我在这里看到了几个问题。

1) 由于您希望 X 轴为时间刻度,因此您应该将 X 数据值保留为 moment 对象。您当前的实现是从日期字符串创建一个 moment 对象,然后将其格式化回字符串。当您这样做时,chart.js 然后获取字符串并在构建图表时尝试在内部创建一个 moment 对象。

因此,最好将数据保存为 DateMoment 对象,并使用时间刻度配置属性来确定数据在图表上的显示方式。这避免了 chart.js 必须构造 moment 对象并猜测字符串格式。

2) 当您使用 Chart.Scatter 时,您正在使用 pre-2.0 的方式创建图表。相反,您应该使用新样式 (new Chart()) 并传入 type 属性.

这是您代码的修改版本,它不会导致浏览器警告,并且可以在 Chrome 和 Firefox 中运行(我没有在 Opera 中测试)。

var getData = function() {
  var dummyDataset = [
    '2007-11-09T00:00:00.000Z',
    '2006-08-04T00:00:00.000Z',
    '2006-08-06T00:00:00.000Z',
    '2008-01-10T00:00:00.000Z'
  ];

  return dummyDataset.map(function(datum) {
    var myMoment = moment(datum);

    return {
      x: myMoment,
      y: parseInt(myMoment.format('YYYY')),
    };
  });
};

var ctx = document.getElementById("chart1").getContext("2d");
var myScatter = new Chart(ctx, {
  type: 'line',
  data: {
    datasets: [{
      label: "My First dataset",
      borderColor: 'rgb(255, 99, 132)',
      fill: false,
      pointRadius: 4,
      pointHoverRadius: 8,
      showLine: false,
      data: getData()
    }]
  },
  options: {
    responsive: true,
    title: {
      display: true,
      text: 'Random Data'
    },
    legend: {
      display: true,
      labels: {
        fontSize: 10,
        boxWidth: 20
      }
    },
    elements: {
      point: {
        pointStyle: 'rect'
      }
    },
    hover: {
      mode: 'nearest'
    },
    scales: {
      xAxes: [{
        type: 'time',
        position: 'bottom',
        scaleLabel: {
          display: true,
          labelString: 'Months'
        },
        time: {
          unit: 'month',
          displayFormats: {
            month: 'MM'
          },
        }
      }],
      yAxes: [ {
        type: 'linear',
        ticks: {
          min: 2005,
          max: 2015,
          stepSize: 1
        },
        scaleLabel: {
          display: true,
          labelString: 'Year'
        }
      }]
    }
  }
});

您可以在此 forked codepen.

看到它的实际效果

要记住的另一件事是,因为您的数据跨越多年,您会在 X 轴上看到重复的月份。请记住,时间刻度用于绘制日期,因此即使您只显示月份,具有相同月份但不同年份的数据点也不会绘制在同一位置。

如果您实际上只想在 X 轴上显示月份 string/number 值,那么您根本不应该使用 time 刻度,而是使用 linear 刻度。然后,当您构建数据值时,您将从数据中提取月份(与您已经为 Y 值所做的相同)。

var getData = function() {
  var dummyDataset = [
    '2007-11-09T00:00:00.000Z',
    '2006-08-04T00:00:00.000Z',
    '2006-08-06T00:00:00.000Z',
    '2008-01-10T00:00:00.000Z'
  ];

  return dummyDataset.map(function(datum) {
    var myMoment = moment(datum);

    return {
      x: parseInt(myMoment.format('MM')),
      y: parseInt(myMoment.format('YYYY')),
    };
  });
};

所以除了乔丹的回答 我从

更改了标签和 x 轴
['01.01', '02.01', ...] to [1,2,...]

来自类型:'time' to type: 'linear'

并使其不仅按月而且按天映射。我不得不制作日期对象来更正浮点数。 05.20 到 5.66

const date = datum.key;
const day = parseInt(moment(date).format('DD')) / 30 * 100;
const fullDate = parseFloat(moment(date).format('MM') + '.' + Math.round(day))
// 05.10 would be 5.3 (10 of 30 is 33%)
{
   x: fullDate, 
   y: parseInt(moment(date).format('YYYY')) 
   date: date, // for tooltip
   count: count  // for tooltip
 }

而且我还必须更正我的工具提示

 callbacks: {
   title: function([tooltipItem], data) {
     const tooltipInfo = getTooltip(tooltipItem, data.datasets);

     return tooltipInfo.date;
   },

   label: function(tooltipItem, data) {
     const tooltipInfo = getTooltip(tooltipItem, data.datasets);

     return i18n.t('chart.count') + ': ' + tooltipInfo.count;
   },
 }

相应的工具提示数据集

function getTooltip(tooltipItem, datasets) {
    return datasets[tooltipItem.datasetIndex].data.find(datum => {
        return datum.x === tooltipItem.xLabel && datum.y === tooltipItem.yLabel;
    });
}