我有一组带有来自用户的上传数据的对象。现在我尝试更改此数组,以便获取chart.js上传图的数据集。
理念是把所有的日子(我从来不知道有多少天),当天每小时上传的数量,并将其放入我的图表的对象数组中。一切都运行得很好,除了我没有每天每小时上传一个上传阵列,看起来一直都是相同的。
根据我的示例变量Uploads
,我应该得到两个具有不同数据数组的对象,但它们是相同的。
谁能告诉我哪里弄错了?
//my sample Data
let Uploads = [{
user: 'user1',
files: [{
uploadToServerTime: '21:12:2018 09:15:00'
}]
}, {
user: 'user2',
files: [{
uploadToServerTime: '22:12:2018 10:17:00'
}]
}, {
user: 'user3',
files: [{
uploadToServerTime: '22:12:2018 09:14:00'
}]
}]
//the hourlyUpload Array has a length of 24 for each hour of the day
let hourlyUpload = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
let dailyUploadtemp = [];
let dailyUpload = [];
let hour;
let day;
let uploadMoment;
for (let x of Uploads) {
if (x.hasOwnProperty('files')) {
for (let y of x.files) {
if (y.hasOwnProperty('uploadToServerTime')) {
uploadMoment = moment(y.uploadToServerTime, ['DD.MM.YYYY HH:mm:ss']);
day = uploadMoment.format('DD.MM.YYYY');
dailyUploadtemp.push({
label: day,
data: hourlyUpload
})
}
}
}
}
dailyUpload = _.uniqBy(dailyUploadtemp, 'label');
//now I have an array of Objects with a set of empty hours for each day an upload has taken place
for (let x of Uploads) {
if (x.hasOwnProperty('files')) {
for (let y of x.files) {
if (y.hasOwnProperty('uploadToServerTime')) {
uploadMoment = moment(y.uploadToServerTime, ['DD.MM.YYYY HH:mm:ss']);
hour = uploadMoment.format('H');
day = uploadMoment.format('DD.MM.YYYY');
for (let z of dailyUpload) {
if (z.label === day) {
//here is something wrong. The Amount is added to every data, not only to z.data
z.data[hour] = (z.data[hour] + 1);
}
}
}
}
}
}
let ctx = document.getElementById("myChart").getContext("2d");
let myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ['00:00','01:00','02:00','03:00','04:00','05:00','06:00','07:00','08:00','09:00','10:00','11:00','12:00','13:00','14:00','15:00','16:00','17:00','18:00','19:00', '20:00','21:00','22:00','23:00'],
datasets: dailyUpload
},
options: {
//responsive: false,
animation: {
duration: 1000,
easing: 'easeOutQuad'
},
scales: {
xAxes: [{
type: 'time',
time: {
parser: "HH:mm",
unit: 'hour',
unitStepSize: 1,
displayFormats: {
'minute': 'HH:mm',
'hour': 'HH:mm',
min: '00:00',
max: '23:59'
}
}
}]
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<p>There should be two different lines, but I only get two lines with the same datapoints</p>
<canvas id="myChart" width="800" height="400"></canvas>
PS:我很清楚这些循环可以更优雅或更快地解决,但它以这种方式工作,如果我一步一步地这样做,我就更容易理解我在做什么。
答案 0 :(得分:2)
您的问题在这里:
dailyUploadtemp.push({
label: day,
data: hourlyUpload
})
dailyUploadtemp
是一个对象,其data
属性是对hourlyUpload
数组的引用。
您的每个对象都有对同一个数组的引用。因此,如果您要更新此阵列,则修改会反映在所有dailyUpload
个对象中。
您可以在data
对象中创建dailyUploadTemp
属性时克隆数组来解决此问题。
一种方法是使用Array.prototype.slice:
dailyUploadtemp.push({
label: day,
data: hourlyUpload.slice()
})
//my sample Data
let Uploads = [{
user: 'user1',
files: [{
uploadToServerTime: '21:12:2018 09:15:00'
}]
}, {
user: 'user2',
files: [{
uploadToServerTime: '22:12:2018 10:17:00'
}]
}, {
user: 'user3',
files: [{
uploadToServerTime: '22:12:2018 09:14:00'
}]
}]
//the hourlyUpload Array has a length of 24 for each hour of the day
let hourlyUpload = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
let dailyUploadtemp = [];
let dailyUpload = [];
let hour;
let day;
let uploadMoment;
for (let x of Uploads) {
if (x.hasOwnProperty('files')) {
for (let y of x.files) {
if (y.hasOwnProperty('uploadToServerTime')) {
uploadMoment = moment(y.uploadToServerTime, ['DD.MM.YYYY HH:mm:ss']);
day = uploadMoment.format('DD.MM.YYYY');
dailyUploadtemp.push({
label: day,
data: hourlyUpload.slice()
})
}
}
}
}
dailyUpload = _.uniqBy(dailyUploadtemp, 'label');
//now I have an array of Objects with a set of empty hours for each day an upload has taken place
for (let x of Uploads) {
if (x.hasOwnProperty('files')) {
for (let y of x.files) {
if (y.hasOwnProperty('uploadToServerTime')) {
uploadMoment = moment(y.uploadToServerTime, ['DD.MM.YYYY HH:mm:ss']);
hour = uploadMoment.format('H');
day = uploadMoment.format('DD.MM.YYYY');
for (let z of dailyUpload) {
if (z.label === day) {
//here is something wrong. The Amount is added to every data, not only to z.data
z.data[hour] = (z.data[hour] + 1);
}
}
}
}
}
}
let ctx = document.getElementById("myChart").getContext("2d");
let myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ['00:00','01:00','02:00','03:00','04:00','05:00','06:00','07:00','08:00','09:00','10:00','11:00','12:00','13:00','14:00','15:00','16:00','17:00','18:00','19:00', '20:00','21:00','22:00','23:00'],
datasets: dailyUpload
},
options: {
//responsive: false,
animation: {
duration: 1000,
easing: 'easeOutQuad'
},
scales: {
xAxes: [{
type: 'time',
time: {
parser: "HH:mm",
unit: 'hour',
unitStepSize: 1,
displayFormats: {
'minute': 'HH:mm',
'hour': 'HH:mm',
min: '00:00',
max: '23:59'
}
}
}]
}
}
});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>
<p>There should be two different lines, but I only get two lines with the same datapoints</p>
<canvas id="myChart" width="800" height="400"></canvas>
&#13;