Как поставить метки на 4 точки дня? - PullRequest
0 голосов
/ 26 мая 2020

Этот вопрос состоит из двух частей (два способа решения)

Я хочу создать диаграмму, которая отображает данные за 24 часа, не начиная с полуночи, и с отметками (и соответствующей сеткой) в четыре стороны света дня.

Меня не волнует, будет ли ось x «временем» или чем-то еще, главное, чтобы это выглядело нормально. Я видел диаграмму категорий с произвольно смещенными метками, но я могу воспроизвести это только с одной точкой данных на метку, а для этого требуется несколько точек данных между метками. Если я помечу все точки данных, я не знаю, как пропустить такие метки, что будут видны только «0:00», «6:00», «12: 00» и «18: 00».

Это должно выглядеть так:

enter image description here

Вот как далеко я продвинулся:

function generateData() {
  function randomNumber(min, max) {
return Math.random() * (max - min) + min;
  }

  function randomPoint(date) {
return {
  t: date.valueOf(),
  y: randomNumber(0, 100)
};
  }

  var date = moment("2000-01-01T"+"08:30");
  var now = moment();
  var data = [];
  while (data.length <=48) {
data.push(randomPoint(date));
date = date.clone().add(30, 'minute')
  }
  return data;
}

var cfg = {
  data: {
datasets: [{
  label: 'CHRT - Chart.js Corporation',
  backgroundColor: 'red',
  borderColor: 'red',
  data: generateData(),
  type: 'line',
  pointRadius: 0,
  fill: false,
  lineTension: 0,
  borderWidth: 2
}]
  },
  options: {
scales: {
  xAxes: [{
    type: 'time',
    time: {
      round: 'minute',
      unit: 'minute',
      stepSize: 360,
      displayFormats: {
        minute: 'kk:mm'
      }
    }
  }],
  yAxes: [{
    gridLines: {
      drawBorder: false
    }
  }]
},
tooltips: {
  intersect: false,
  mode: 'index'
}
  }
};
var chart = new Chart('chart1', cfg);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="chart1" height="60"></canvas>

Проблема в том, что первый тик находится в 08:30, а не в 12:00.

Я пытался установить min значение оси, но это либо смещает часть данных из поля зрения (min: moment("2000-01-01T12:00")), либо создает пробел перед началом данных (min: moment("2000-01-01T06:00")), оба из которых недопустимы.

function generateData() {
  function randomNumber(min, max) {
return Math.random() * (max - min) + min;
  }

  function randomPoint(date) {
return {
  t: date.valueOf(),
  y: randomNumber(0, 100)
};
  }

  var date = moment("2000-01-01T"+"08:30");
  var now = moment();
  var data = [];
  while (data.length <=48) {
data.push(randomPoint(date));
date = date.clone().add(30, 'minute')
  }
  return data;
}

var cfg = {
  data: {
datasets: [{
  label: 'CHRT - Chart.js Corporation',
  backgroundColor: 'red',
  borderColor: 'red',
  data: generateData(),
  type: 'line',
  pointRadius: 0,
  fill: false,
  lineTension: 0,
  borderWidth: 2
}]
  },
  options: {
scales: {
  xAxes: [{
    type: 'time',
    time: {
      round: 'minute',
      unit: 'minute',
      stepSize: 360,
      displayFormats: {
        minute: 'kk:mm'
      }
    },
    ticks: {
      min: moment("2000-01-01T06:00"),
    }
  }],
  yAxes: [{
    gridLines: {
      drawBorder: false
    }
  }]
},
tooltips: {
  intersect: false,
  mode: 'index'
}
  }
};
var chart = new Chart('chart1', cfg);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<canvas id="chart1" height="60"></canvas>

1 Ответ

0 голосов
/ 27 мая 2020

Мне потребовалось некоторое время, но я думаю, что получил ответ.

Вы можете определить отметки с помощью и отобразить их с помощью options.scales.xAxes[0].ticks.source = 'labels', но самым сложным было получить следующую временную метку 0:00 , 6:00, 12:00 или 18:00. Поэтому код первой метки довольно сложен. Если вы хотите что-то узнать, просто дайте мне знать, и я могу это объяснить.

Должен работать в любое время, когда вы захотите.

Полный код (то же, что и JSBin с предварительным просмотром здесь) :

let data = {
  datasets: [{
    label: 'CHRT - Chart.js Corporation',
    backgroundColor: 'red',
    borderColor: 'red',
    type: 'line',
    pointRadius: 0,
    pointHoverRadius: 0,
    fill: false,
    lineTension: 0,
    borderWidth: 2,
    data: []
  }]
}

function randomNumber(min, max) {
  return Math.round(Math.random() * (max - min) + min)
}

// temp variable for data.datasets[0].data
let datasetData = []

// Fill first dataset
datasetData[0] = {
  x: moment("2000-01-01T08:30"),
  y: randomNumber(0, 100)
}

// Fill remaining datasets
for (let i = 1; i < 48; i++) {
  datasetData[i] = {
    x: moment(datasetData[i-1].x).add(30, 'minutes'),
    y: randomNumber(0, 100)
  }
}

data.datasets[0].data = datasetData

// Fill first label
data.labels = [
  moment(datasetData[0].x).hour(moment(datasetData[0].x).hour() + (6 - moment(datasetData[0].x).hour() % 6) % 6).minutes(0)
]

// Fill remaining labels
for (let i = 1; i < 4; i++) {
  data.labels.push(moment(data.labels[i-1]).add(6, 'hours'))
}

let options = {
  responsive: true,
  scales: {
    xAxes: [{
      type: 'time',
      time: {
        unit: 'hour',
        displayFormats: {
          hour: 'kk:mm'
        }
      },
      ticks: {
        source: 'labels'
      }
    }],
    yAxes: [{
      gridLines: {
        drawBorder: false
      }
    }]
  },
  tooltips: {
    intersect: false,
    mode: 'index',
    callbacks: {
      title: function(tooltipItem, data) {
        return moment(tooltipItem[0].label).format('YYYY-MM-DD, HH:mm')
      }
    }
  }
}

let chart = new Chart('chart1', {
  type: 'line',
  data: data,
  options: options
});
...