ChartJS의 선 그래프에서 임계 값 이상이되면 색상을 변경하고 싶습니다.

11599 단어 chart.js

하고 싶은 일


  • ChartJS를 사용하여 선 그래프를 작성하고 싶습니다.
  • 일정한 값을 넘으면 선의 색을 바꾸고 싶다

  • 이런 요망을 살짝 듣고, 어떻게든 실현할 수 없을까.
    라고 생각했으므로, 고리 눌러서 해 보았습니다.

    데이터 세트를 넣을 때,
    「임계치 미만은 청색」 「역치 이상은 적색」이라고 하는 데이터를 나누는 방법도 물론 있습니다만
    「어느 값 이상의 선」만을 바꾸고 싶다는 섬세한 부분에 대응할 수 없었기 때문에 시행착오해 보았습니다.

    정책


  • 그리기 후 이벤트 얻기
  • 대상 그래프의 Canvas를 픽셀 마다 취득
  • 픽셀의 위치와 색상을 결정하고 다시 씁니다

  • 내용



    Canvas의 선 그래프 부분을 덮어쓰는 함수를 준비해 둡니다.
    const overwriteCanvas = function () {
      console.log("overwriteCanvas");
      const targetCanvas = document.getElementById("targetCanvas");
      const targetCanvasContext = targetCanvas.getContext('2d');
      const {width, height} = targetCanvas;
      const mainImgData = targetCanvasContext.getImageData(0, 0, width, height);
      const mainData = mainImgData.data;
      //Canvasの各ピクセル毎をみて、色を塗り替える。
      for (let i = 0, len = width * height; i < len; i++) {
        // 高さ180pxから305pxまでの範囲で色を変える
        if (width * 180 < i && i < width * 305) {
          const p = i * 4;
          // RGB(54, 162, 235)を RGB(255, 99, 132) (赤) に変える。
          if (mainData[p] === 54 && mainData[p + 1] === 162 && mainData[p + 2] === 235) {
            mainData[p] = 255;
            mainData[p + 1] = 99;
            mainData[p + 2] = 132;
          }
        }
      }
      targetCanvasContext.putImageData(mainImgData, 0, 0);
    }
    

    그런데, 이런 함수를 준비했지만 「언제 움직일까」가 문제입니다. . .
    window.addEventListener('load', () => {
      const ctx = document.getElementById('targetCanvas').getContext('2d');
      window.myLine = new Chart(ctx, config);
      overoverwriteCanvas();
    });
    

    와 같이 움직여도 ChartJS 측의 드로잉 타이밍을 취할 수 없고, 준비한 함수 쪽이 빨리 끝나 버립니다.

    Promise에서 할까 → 안 되었어요.
    파란색에서 빨간색으로 바뀌지만,
    호버하면 그래프가 갱신되어 색이 돌아 버리는 현상이 일어났습니다.

    묘화 후의 타이밍을 잡을 수 없는 한 안 되는 것인가....

    그런 가운데, 업데이트 등의 출처을 읽으면 ...
    afterUpdate 라고 하는, 수상한 녀석이, 난카 있다. . . !
    한층 더 읽어 가면, afterRender 라고 하는 바로 솔레한 물건까지 있습니다. . .

    확실히, 문서 을 읽으면...쓰고 있네요.
    하지만 Plugin은 추측할 수 없어요. (폰코츠)

    라는 일로!

    ChartJS config를 설정합니다.
    const config = {
      type: 'line',
      data: {}, // 割愛
      options: {
        responsive: false,
        title: {},    // 割愛
        tooltips: {}, // 割愛
        hover: {},    // 割愛
        scales: {}    // 割愛
      },
      plugins: [{
        // 更新後のイベント
        afterUpdate: function () {
          console.log('afterUpdate');
          overwriteCanvas();
        },
        // 描画後のイベント
        afterRender: function() {
          console.log('afterRender');
          overwriteCanvas();
        }
      }]
    }
    



    약간 러그는 있지만, 그렇게 할 수있었습니다.
    호버했을 때의 거동은 이쪽.


    유, 용서해 주시겠습니까?

    소스의 전체는 코코 에 둡니다.

    할 수없는 일



    완성된 것 같아서, 할 수 없는 부분이 있습니다.
    실은 가로폭을 고정하고 있었기 때문에, 반응적인 대응은 되어 있지 않습니다.
      overwriteCanvas = function () {
          // ... 中略
          if (width * 180 < i && i < width * 305) {
    

    이 if 문은 Canvas의 크기가 고정되어 있다고 가정합니다.
    본래는 화면 resize 이벤트에 따라 계산하지 않으면 이칸 부분이었습니다.

    계산 방법이 지금 모르기 때문에 포기하고 있습니다. 미안해.

    참고문헌



    [그림] HTML5 Canvas 저것 - 레이어, 마스크(ImageData), 전체 화면에서 빠져있는 포인트

    좋은 웹페이지 즐겨찾기