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
对象。
因此,最好将数据保存为 Date
或 Moment
对象,并使用时间刻度配置属性来确定数据在图表上的显示方式。这避免了 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;
});
}
所以浏览器抛出
关于错误使用 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
对象。
因此,最好将数据保存为 Date
或 Moment
对象,并使用时间刻度配置属性来确定数据在图表上的显示方式。这避免了 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;
});
}