Как я могу отобразить фиксированные метки на оси X, имея данные на этой оси? - PullRequest
0 голосов
/ 18 октября 2018

Я только начал использовать Chart.js, и у меня возникла проблема.

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

enter image description here

Это мой текущий график, на Y-axis у меня есть возможные оценки (для экзаменов студентов), начиная от 1 to 6.

На X-axis У меня есть возможные Очки, которые можно получить на данном экзамене.

Теперь все становится сложнее, этот график обновляется на основе входных данных и выбора раскрывающегося списка.

Оценки (Ось Y) может иметь 5 типов приращений: Integer, Halves, Quarters, Decimal and Hundredths

Это выбирается с раскрывающимся списком, значение по умолчанию - Quarters, что означает, что с Quarters выбран мой массив чисел для оценок будет выглядеть:

grades = [1, 1.25, 1.50, 1.75, 2....., 5.75, 6]

между тем с выбранным Hundredths это будет выглядеть следующим образом:

grades = [1, 1.01, 1.02, 1.03, .... 5.97, 5.98, 5.99, 6]

И для каждого класса требуется определенное количество Баллов (ось X) для достиженияЭто.Необходимые баллы рассчитываются по формуле, которую я вставил в функцию:

mySecretFormula(grades: Array<Number>) {
    grades.forEach(g => {
    const currentPoints = g * mySecretFormula;

    this.points.push(currentPoints);
}

, поэтому в основном я передаю свои оценки в этой функции, и она возвращает еще один массив чисел с таким же количеством элементов (как каждыйоценка соответствует баллу) Например,

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

grades = [1, 2, 3, 4, 5, 6]

результат, который я получу за свои оценки, будет:

scores = [0, 5, 10, 15, 25, 30] 

если максимальные баллы были установлены на 30 (максимальный балл определен на входе)

Затем, наконец, я использовал chart.js для отображения моих данных следующим образом:

this.canvas.data.labels = this.points;
this.canvas.data.datasets[0].data = this.grades;
this.canvas.update();

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

Допустим, он работает, но он далек от оптимального.

ЧтоЯ хочу достичь просто.

Это должно выглядеть следующим образом:

enter image description here

Вот как выглядит график, когда я выбираюЦелые оценки, так что всего 6 разных классов и 6 диразличные оценки.

Я хочу, чтобы диаграмма всегда выглядела так, независимо от выбранного приращения, поэтому всегда 5 или 6 линий сетки и всегда одинаковые отметки для оси X.

Тогда, если текущим выбранным шагом является Integer, у меня будет только 6 пересечений, но если бы я поменял местами на Десятичные или Сотые, поэтому с большим количеством пересечений график выглядит именно так, НО, когда вы наводите курсор на линиис помощью мыши я получу всплывающую подсказку для каждого действительного пересечения.

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

enter image description here

(игнорируйте округление, забыли округлить их до 2 десятичных знаков), так как вы видите, как изменяются отметки, изменяется ширина сетки и высота всего графика.

Но пересеченияработать правильно, если я наведу указатель мыши вдоль линии, я получу всплывающую подсказку для каждой точки для этих пар:

десятичных приращений, равных:

grades = [1, 1.1, 1.2,1,3, 1,4, ...5.9, 6] баллов = [0, 0,7, 1,4, 2,1, 2,8, .... 34,3, 35]

, поэтому для достижения того же результата НО с графиком, который всегда одинаков, всегдаодинаковые отметки, высота и ширина, потому что диапазон оценок и баллов всегда будет одинаковым, но в зависимости от выбранного приращения может быть от как минимум 6 пересечений (целых) до более 500 пересечений (сотых)!

Надеюсь, я дал понять, большое спасибо

Редактировать: удалось с вашей помощью добавить настраиваемую подсказку в 2 строки с этим:

afterBody: function([tooltipItem], data): any {
                            const multistringText = ["Points: " + tooltipItem.xLabel];
                            multistringText.push("Grade: " + tooltipItem.yLabel);

                            return multistringText;
                        }

работаетотлично, но как мне теперь удалить исходную строку всплывающей подсказки над ней?посмотрите на изображение, над моей 2-х строчной пользовательской подсказкой. У меня есть еще одна строка, которую я хочу скрыть!

enter image description here

И, наконец, всегда смотрю на это изображение,Как я могу сделать линии сетки на оси X одинаковой ширины?Как видите, первые 4 больше, чем последние!Я хочу, чтобы они всегда были одинаковой ширины!спасибо

1 Ответ

0 голосов
/ 18 октября 2018

Я советую преобразовать вашу диаграмму в xy диаграмму, установить параметры оси и настроить подсказки

var ctx = document.getElementById("myChart").getContext('2d');
var precision = 0;
var data = getData();

var myChart = new Chart(ctx, {
  type:"scatter",
    data: {
        datasets: [{
            label: 'grades',
            data: data,
            fill: false,
            pointRadius: 0,
            pointHitRadius: 3
        }]
    },
    options: {
        scales: {
            yAxes: [{
                ticks: {
                    beginAtZero:true,
                    max:6
                }
            }],
            xAxes: [{
                ticks: {
                    beginAtZero:true,
                    max:35,
                    stepSize: 1,
                    callback: function(value){
                      if (value < 5){
                        return value;
                      } else {
                        if (value% 5 === 0){
                          return value;
                        }
                      }
                    }
                }
            }]
        },
        tooltips: {
            callbacks: {
                label: function(tooltipItem, data) {
                    var label = [
                    'X: ' + tooltipItem.xLabel.toFixed(precision),
                    'Y: ' + tooltipItem.yLabel.toFixed(precision)
                    ];
                    return label;
                }
            }
        }
    }
});

function getData(){
  var step = 10**-precision;
  var arr = [];
  for (var i=0; i<=6; i+=step){
    arr.push({y: i, x: 35*i/6})
  }
  return arr;
}

setTimeout(function(){
    precision = 1;
    myChart.data.datasets[0].data = getData();
    myChart.update();

}, 2000)
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.6.0/Chart.js"></script>
<canvas id="myChart" width="100" height="100"></canvas>
...