Chart.js: разный размер набора данных

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

Очевидно, что в одном наборе данных 7 точек данных, в другом - 168.

Мне не удалось найти пример или задокументированный вариант, который позволил бы это сделать. Конечно - я могу настроить практически все, что касается внешнего вида, но когда дело доходит до размера данных, ожидается, что оба набора данных будут иметь столько точек данных, сколько меток.

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

Возможно ли это с Chart.js?


person Perlator    schedule 03.04.2017    source источник
comment
Вы представляете линейный график с двумя линиями (одна для дневной, а другая для часовой)? Или комбинированный график, где дневной график - это гистограмма, а часовой - линия?   -  person jordanwillis    schedule 04.04.2017
comment
Я думал о двух линиях, где дневная, как ожидается, будет более гладкой, потому что она в основном интерполирована всего на 7 пунктов, а часовая линия будет иметь 168 пунктов. Это было бы идеально, поскольку у меня уже есть дневная линия, и я хотел проверить, как почасовая линия будет выглядеть визуально.   -  person Perlator    schedule 05.04.2017
comment
Очень просто перейти от комбо к простой строке. Я обновил свой ответ другим примером. Надеюсь, это полностью ответит на ваш исходный вопрос.   -  person jordanwillis    schedule 06.04.2017
comment
Это 100% решение. Спасибо.   -  person Perlator    schedule 07.04.2017


Ответы (2)


То, что вы описываете, на самом деле возможно с помощью chart.js, если хотя бы один из ваших наборов данных может быть выражен с помощью альтернативного набор данных точечной диаграммы. Позвольте мне показать вам пример, в котором я показываю среднее значение за день в виде столбцов, а среднее значение за час в виде строки (иначе, смешанный тип диаграммы).

Сначала настройте гистограмму с метками для каждого дня недели и укажите среднесуточные значения для данных в качестве первого набора данных.

Затем создайте другой набор данных, но установите для его свойства type значение 'line'. Поскольку мы хотим использовать другую ось X и другой набор меток, вы должны выражать свои данные, используя нотацию {x: 0, y: 2}. Это позволит вам обойти шкалу от использования меток, определенных выше.

Наконец, в конфигурации options.scales определите 2 шкалы xAxes и свяжите 2-й набор данных со 2-й шкалой оси X (также установите для свойства display значение false, чтобы вы не видели никакой 2-й масштаб).

В итоге вы получите конфигурацию диаграммы, которая выглядит следующим образом.

var ctx = document.getElementById("canvas").getContext("2d");
var myChart = new Chart(ctx, {
  type: 'bar',
  data: {
    labels: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
    datasets: [{
      type: 'bar',
      label: 'Daily Avg',
      backgroundColor: chartColors.red,
      data: dailyAvgData,
      borderColor: 'white',
      borderWidth: 2
    }, {
      type: 'line',
      label: 'Hourly Avg',
      borderColor: chartColors.green,
      backgroundColor: chartColors.green,
      borderWidth: 1,
      fill: false,
      pointRadius: 0,
      xAxisID: 'x-axis-2',
      data: hourlyAvgData
    }]
  },
  options: {
    responsive: true,
    title: {
      display: true,
      text: 'Chart.js - Combo Chart With Multiple Scales (X Axis)'
    },
    tooltips: {
      mode: 'nearest',
      intersect: true
    },
    scales: {
      xAxes: [{}, {
        id: 'x-axis-2',
        type: 'linear',
        position: 'bottom',
        display: false,
      }],
      yAxes: [{
        ticks: {
          min: 0,
          max: 50
        }
      }]
    }
  }
});

Вы можете увидеть это в действии на этом codepen.

Вот еще один пример, но вместо использования комбинированного графика (дневной - это столбцы, часовой - это линия), оба графика - это линии. Подход точно такой же, за исключением того, что тип диаграммы изменен с bar на line.

Обратите внимание: в этой версии я скорректировал дневную среднюю линию на единицу, чтобы точки отображались в «конце дня». Предыдущий пример показывал среднесуточное значение в начале каждого дня (что технически неверно).

Вот пример кода, демонстрирующий линейную версию диаграммы.

person jordanwillis    schedule 04.04.2017

Попав сюда после поиска того, как реализовать скользящую среднюю в Chart.js, я изо всех сил пытался полностью понять ответ @jordanwillis, так что, возможно, это может быть полезно и для кого-то другого.

Основная идея заключается в том, что вы можете назначить формат данных (для каждого набора данных в datasets) так, чтобы компонент y представлял значение серии, а x - это ключевой момент, ИМХО - соответствовал метке (в уникальном, общем labels массив, который будет общей осью x для всех серий (т.е. наборов данных), где вы хотите построить эту конкретную точку.

Итак, мой пример для скользящей средней N (скажем, 7-дневной скользящей средней) и общего асимметричного сдвига S между 0 и N-1 (например, 3) будет

var valuesMean7 = movingAverage(7, 3, ydata, xlabels);

где я определил:

function movingAverage(N, shift, values, labels) {
    var NN = values.length;
    var valuesMean = [];
    rightShift = N - shift - 1;
    for (let i = shift; i < NN - rightShift; i++) {
        var mean = 0;
        for (let j = i - shift; j < i - shift + N; j++) {
            mean += values[j];
        }
        mean = mean / N;
        valuesMean.push({
            x: labels[i],
            y: mean
            });
    }
    return valuesMean;
}
person Giulio    schedule 07.03.2021