Frontend/React

[React Chart] 리액트 chart.js tooltip custom 하기

전예방 2023. 4. 24. 22:50

chart.js tooltip custom 하기

 

기본 공식문서

https://react-chartjs-2.js.org/

 

react-chartjs-2 | react-chartjs-2

React components for Chart.js

react-chartjs-2.js.org

https://www.chartjs.org/

 

Chart.js

Simple yet flexible JavaScript charting library for the modern web

www.chartjs.org

 

참고한 공식문서 부분 발췌

https://www.chartjs.org/docs/latest/configuration/tooltip.html#external-custom-tooltips

 

Tooltip | Chart.js

Namespace: options.plugins.tooltip, the global options for the chart tooltips is defined in Chart.defaults.plugins.tooltip. Name Type Default Description enabled boolean true Are on-canvas tooltips enabled? external function null See external tooltip secti

www.chartjs.org

https://www.chartjs.org/docs/latest/samples/tooltip/html.html

 

External HTML Tooltip | Chart.js

This sample shows how to use the external tooltip functionality to generate an HTML tooltip. const config = { type: 'line', data: data, options: { interaction: { mode: 'index', intersect: false, }, plugins: { title: { display: true, text: 'Chart.js Line Ch

www.chartjs.org

https://yeon22.github.io/Chartjs-kr/docs/latest/configuration/tooltip.html

 

툴팁 · Chart.js 문서

results matching "" No results matching ""

yeon22.github.io

한글 번역본

 

해당 부분을 참고하면된다.

 

caret이 아마도 말풍선 꼬리를 뜻하는 것 같다.

function customTooltips(tooltipModel) {
  // Tooltip Element
  var tooltipEl = document.getElementById("chartjs-tooltip");

  const yAlign = tooltipModel.yAlign;
  const xAlign = tooltipModel.xAlign;

  // Create element on first render
  if (!tooltipEl) {
    tooltipEl = document.createElement("div");
    tooltipEl.id = "chartjs-tooltip";
    tooltipEl.innerHTML = "<table></table>";
    document.body.appendChild(tooltipEl);
  }

  // Hide if no tooltip
  if (tooltipModel.opacity === 0) {
    tooltipEl.style.opacity = 0;
    return;
  }

  // Set caret Position
  tooltipEl.classList.remove("top", "bottom", "center", "left", "right");
  if (tooltipModel.yAlign || tooltipModel.xAlign) {
    tooltipEl.classList.add(tooltipModel.yAlign);
    tooltipEl.classList.add(tooltipModel.xAlign);
  }

  // Set Text
  if (tooltipModel.body) {
    var titleLines = tooltipModel.title || [];
    var bodyLines = tooltipModel.body.map((bodyItem) => {
      return bodyItem.lines;
    });

    var innerHtml = "<thead>";

    titleLines.forEach(function (title) {
      innerHtml += '<tr><th><div class="mb-1">' + title + "</div></th></tr>";
    });
    innerHtml += "</thead><tbody>";

    bodyLines.forEach((body, i) => {
      var colors = tooltipModel.labelColors[i];
      // var style = 'background-color:' + colors.borderColor
      var style =
        "background-color:" + this._chart.data.datasets[i].borderColor;
      var value = tooltipModel.dataPoints[i].value;
      var label = this._chart.data.datasets[i].label;

      style += "; border-color:" + colors.borderColor;
      style += "; border-color:" + this._chart.data.datasets[i].borderColor;
      style += "; border-width: 2px";

      var span =
        '<span class="chartjs-tooltip-key" style="' + style + '"></span>';

      innerHtml += `<tr><td> ${span} $${value}K </td></tr>`;
    });
    innerHtml += "</tbody>";

    var tableRoot = tooltipEl.querySelector("table");
    tableRoot.innerHTML = innerHtml;
  }

  // Tooltip height and width
  const { height, width } = tooltipEl.getBoundingClientRect();

  // Chart canvas positions
  const positionY = this._chart.canvas.offsetTop;
  const positionX = this._chart.canvas.offsetLeft;

  // Carets
  const caretY = tooltipModel.caretY;
  const caretX = tooltipModel.caretX;

  // Final coordinates
  let top = positionY + caretY - height;
  let left = positionX + caretX - width / 2;
  let space = 8; // This for making space between the caret and the element.

  // yAlign could be: `top`, `bottom`, `center`
  if (yAlign === "top") {
    top += height + space;
  } else if (yAlign === "center") {
    top += height / 2;
  } else if (yAlign === "bottom") {
    top -= space;
  }
  // xAlign could be: `left`, `center`, `right`
  if (xAlign === "left") {
    left = left + width / 2 - tooltipModel.xPadding - space / 2;
    if (yAlign === "center") {
      left = left + space * 2;
    }
  } else if (xAlign === "right") {
    left -= width / 2;
    if (yAlign === "center") {
      left = left - space;
    } else {
      left += space;
    }
  }

  // Display, position, and set styles for font
  tooltipEl.style.opacity = 1;

  // Left and right
  tooltipEl.style.top = `${top}px`;
  tooltipEl.style.left = `${left}px`;

  // Font
  tooltipEl.style.fontFamily = tooltipModel._bodyFontFamily;
  tooltipEl.style.fontSize = tooltipModel.bodyFontSize + "px";
  tooltipEl.style.fontStyle = tooltipModel._bodyFontStyle;

  // Paddings
  tooltipEl.style.padding =
    tooltipModel.yPadding + "px " + tooltipModel.xPadding + "px";
}

 

 

   const option: any = {
    responsive: true,
    maintainAspectRatio: false,
    plugins: {
      tooltip: {
        enabled: false,
        external: function(context  : any) {
        	// 여기에 커스텀하면된다.
        }
      },
    },
  };

 

'Frontend/React'의 다른글

  • 현재글 [React Chart] 리액트 chart.js tooltip custom 하기

관련글