как сделать так, чтобы выбранные данные выделялись на графике js? - PullRequest
0 голосов
/ 18 апреля 2020

const data = [65, 0, 80, 81, 56, 85, 40];

new Chart(document.getElementById("myChart"), {
  type: 'line',
  plugins: [{
    afterDraw: chart => {
      var ctx = chart.chart.ctx;
      var xAxis = chart.scales['x-axis-0'];
      var yAxis = chart.scales['y-axis-0'];
      xAxis.ticks.forEach((value, index) => {
        var x = xAxis.getPixelForTick(index);
        var yTop = yAxis.getPixelForValue(data[index]);
        ctx.save();
        ctx.strokeStyle = '#aaaaaa';
        ctx.beginPath();
        ctx.moveTo(x, yAxis.bottom);
        ctx.lineTo(x, yTop);
        ctx.stroke();
        ctx.restore();
      });
    }
  }],
  data: {
    labels: ["January", "February", "March", "April", "May", "June", "July"],
    datasets: [{
      label: "My First dataset",
      data: data,
      fill: false
    }]
  },
  options: {
    legend: {
      display: false
    },
    scales: {
      yAxes: [{
        gridLines: {
          display: false
        }
      }],
      xAxes: [{
        gridLines: {
          display: false
        }
      }]
    }
  }
});
<div style="width: 75%">
  <canvas id="myChart"></canvas>
</div>
<script src='https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.5.0/Chart.js'></script>

enter image description here

Я добавил свои фрагменты кода и приложение для лучшего понимания. Посмотрите, пожалуйста, и дайте мне знать, как сделать так, чтобы выбранные данные были выделены и сделать верхнюю метку (5,5 Кб), как на скриншоте. Заранее спасибо.

1 Ответ

0 голосов
/ 18 апреля 2020

В опциях диаграммы я определил обработчик события onClick, который записывает индекс выбранной точки данных (selIndex) и обновляет диаграмму. Он также перезаписывает метку в выбранном индексе пустой строкой, поскольку мы собираемся нарисовать эту метку самостоятельно, используя указанный стиль c.

onClick: event => {
  var element = lineChart.getElementAtEvent(event);      
  if (element.length > 0) {
    selIndex = element[0]._index;
    lineChart.data.labels = labels.map((l, i) => i == selIndex ? '' : l),
    lineChart.update(data);
  }
}, 

Записанный selIndex используется внутри Plugin Core API afterDraw перехватывает, чтобы нарисовать окружность вокруг выбранной точки данных и нарисовать текст для значения и метки.

if (index == selIndex) {

  // draw circle
  ctx.beginPath();
  ctx.lineWidth = 3;
  ctx.strokeStyle = "#53b300";
  ctx.arc(x, yTop, 8, 0, 2 * Math.PI);
  ctx.stroke();

  // draw text for value and label
  ctx.textAlign = 'center';
  ctx.font = "18px Arial";
  ctx.fillStyle = "#53b300";
  ctx.fillText(data[index] + 'k', x, yTop - 15);
  ctx.fillText(labels[index], x, yAxis.bottom + 22);
}    

Пожалуйста, запустите исправленный код ниже и нажмите на отдельные Данные указывают, чтобы увидеть, как это работает. Я предварительно выбрал одну точку данных. Если при запуске не нужно выбирать точку данных, просто внесите следующие изменения в код: let selIndex = -1 ;.

const labels = ["January", "February", "March", "April", "May", "June", "July"];
const data = [65, 0, 80, 81, 56, 85, 40];
let selIndex = 2;

const lineChart = new Chart(document.getElementById('myChart'), {
  type: 'line',
  plugins: [{
    afterDraw: chart => {
      var ctx = chart.chart.ctx;
      var xAxis = chart.scales['x-axis-0'];
      var yAxis = chart.scales['y-axis-0'];
      xAxis.ticks.forEach((value, index) => {
        var x = xAxis.getPixelForTick(index);
        var yTop = yAxis.getPixelForValue(data[index]);
        ctx.save();
        ctx.strokeStyle = '#aaaaaa';
        ctx.beginPath();
        ctx.moveTo(x, yAxis.bottom);
        ctx.lineTo(x, yTop);
        ctx.stroke();        
        if (index == selIndex) {
        
          // draw circle
          ctx.beginPath();
          ctx.lineWidth = 3;
          ctx.strokeStyle = "#53b300";
          ctx.arc(x, yTop, 8, 0, 2 * Math.PI);
          ctx.stroke();
        
          // draw text for value and label
          ctx.textAlign = 'center';
          ctx.font = "18px Arial";
          ctx.fillStyle = "#53b300";
          ctx.fillText(data[index] + 'k', x, yTop - 15);
          ctx.fillText(labels[index], x, yAxis.bottom + 22);
        }
        ctx.restore();
      });
    }
  }],
  data: {
    labels: labels.map((l, i) => i == selIndex ? '' : l),
    datasets: [{
      label: "My First dataset",
      data: data,
      fill: false
    }]
  },
  options: {
    layout: {
      padding: {
        top: 25,
        right: 25
      }
    },
    legend: {
      display: false
    },
    tooltips: {
      enabled: false
    },
    onClick: event => {
      var element = lineChart.getElementAtEvent(event);      
      if (element.length > 0) {
        selIndex = element[0]._index;
        lineChart.data.labels = labels.map((l, i) => i == selIndex ? '' : l),
        lineChart.update(data);
      }
    },
    scales: {
      yAxes: [{
        gridLines: {
          display: false
        }
      }],
      xAxes: [{
        gridLines: {
          display: false
        }
      }]
    }
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.3/Chart.min.js"></script>
<div style="width: 75%">
  <canvas id="myChart" height="120"></canvas>
</div>
...