图表 JS 工具提示标签间隔为 spaceBetween

问题描述 投票:0回答:1

我有一个堆叠条形图,其中工具提示显示标签:$value&我希望将其设置为空格,以便标签向左对齐,$value向右对齐,从而允许所有数值对齐。例如:

Label 1:     $10,000
Label 2:     $50,000
Label 3:    $100,000

这是计算器。只需按下复合按钮即可显示图表。

https://youthful-euclid-784d05.netlify.app

ChartJS 选项:

    // Configuration options go here
  options: {
    responsive: true,
    maintainAspectRatio: true,
    legend: {
      display: true,
      position: "bottom"
    },
    scales: {
      xAxes: [{
        ticks: {
          fontSize: 16,
          fontFamily: "Roboto Condensed"
        },
        
        gridLines: {
          display: false,
        },
        scaleLabel: {
          display: true,
          labelString: 'Year',
          fontSize: 16,
          fontFamily: "Roboto Condensed"
        },
        stacked: true,
      }],

      yAxes: [{

        
        stacked: true,
        ticks: {
          maxTicksLimit: 5,
          beginAtZero: true,
          fontSize: 12,
          fontFamily: "Roboto Condensed",
          
        
          callback: function (value, index, values) {
            if (parseInt(value) >= 1000) {
              return (
                numeral(value).format("$0a")
                // "$" + value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",")
              );
            } else {
              // return "$" + value;
            }
          },
        },
      }, ],
    },
    legend: {
      display: true,
      labels : {
          fontSize: 14,
          fontFamily: "Roboto Condensed",
         
      },
      
    },
    chart: {

    },
    tooltips: {
      // displayColors: false,
      yAlign: "bottom",

      callbacks: {
        title: function (tooltip, data) {
          return `After ${tooltip[0].label} Years`;
          },

                    label: function(tooltipItems, data) { 
                        return `    ${data.datasets[tooltipItems.datasetIndex].label}:  ${formatCurrency(tooltipItems.value)}`;
                    },
                    
                      },
      
          // bodyAlign: "center",
          titleFontSize: 15,
          titleMarginBottom: 10,
          bodySpacing: 10,
          bodyFontSize: 12,
          mode: "x",
          xPadding: 10,
          yPadding: 10,
         
      // bodySpacing: "5"
    },
  }
javascript charts tooltip
1个回答
0
投票

我唯一能想到的就是创建一个自定义工具提示。然后您就可以完全控制样式和数据。 我不确定 100% 您希望最终结果如何,但我将在此处添加示例,该示例将涵盖您创建自己的工具提示所需了解的所有内容。 (以下图表 js 文档:https://www.chartjs.org/docs/latest/samples/tooltip/html.html

首先,选项对象如下所示:

options: {
...   
  plugins: {
    tooltip: {
      enabled: false,
      position: "nearest",
      external: (a) => externalTooltipHandler(a),
      },
   },
 ...
}

现在这就是

externalTooltipHandler
函数的样子。

首先我们需要创建一个辅助函数来获取工具提示元素, 在这里,我们尝试获取工具提示元素,并检查是否存在,如果不存在,我们将创建一个工具提示元素并为其添加一些样式。并返回工具提示元素。 (我们将在内部调用这个函数

externalTooltipHandler

const getOrCreateTooltip = (chart) => {
    let tooltipEl = chart.canvas.parentNode.querySelector("div");

    if (!tooltipEl) {
      tooltipEl = document.createElement("div");
      tooltipEl.style.background = "rgba(0, 0, 0, 0.7)";
      tooltipEl.style.borderRadius = "3px";
      tooltipEl.style.color = "white";
      tooltipEl.style.opacity = 1;
      tooltipEl.style.pointerEvents = "none";
      tooltipEl.style.position = "absolute";
      tooltipEl.style.transform = "translate(-50%, 0)";
      tooltipEl.style.transition = "all .1s ease";

      const table = document.createElement("table");
      table.style.margin = "0px";

      tooltipEl.appendChild(table);
      chart.canvas.parentNode.appendChild(tooltipEl);
    }

    return tooltipEl;
  };

now

externalTooltipHandler
- 在这里我们将从参数、图表信息和工具提示信息中获取信息。我们将从上面的函数中获取工具提示元素,我们将循环遍历标题和正文 - 以便生成每个元素并为其设置样式。 我会尝试用代码中的注释来分解它。 *注意根元素是一个表,这就是为什么我使用 tr、th 和 td 在上面的函数中,您可以看到它创建了一个表格元素。如果您更容易设计样式,您可以随意使用 div。

const externalTooltipHandler = (context) => {
    // Tooltip Element
    const { chart, tooltip } = context;
    // ---- Getting the tooltip element ----//
    const tooltipEl = getOrCreateTooltip(chart);

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

    // Set Text
    if (tooltip.body) {
      const titleLines = tooltip.title || [];
      const bodyLines = tooltip.body.map((b) => b.lines);
      // ---- Creating the label head ----//
      const toolTipTitle = document.createElement("tr");
      // ---- Looping through headers and generating the child element ----//
      titleLines.forEach((title) => {
        // ---- inserting the label text to the child element and appenidng ----//
        const parent = document.createElement("th");
        const text = document.createTextNode(title);
        parent.appendChild(text);
        toolTipTitle.appendChild(parent);
      });

      // ---- Creating the parent for the label and value - # of votes: 12 ----//
      const colorLabelAndDataParent = document.createElement("tr");

      // ---- Looping to create for each label and value ----//
      bodyLines.forEach((body, i) => {
        const colors = tooltip.labelColors[i];
        // this will create the color before the label.
        const colorDiv = document.createElement("div");
        colorDiv.style.background = colors.backgroundColor;
        colorDiv.style.marginRight = "10px";
        colorDiv.style.height = "10px";
        colorDiv.style.width = "10px";
        colorDiv.style.borderRadius = "50%";
        colorDiv.style.display = "inline-block";

        const labelParent = document.createElement("td");
        const valueParent = document.createElement("td");

        labelParent.style.textAlign = "left";
        valueParent.style.textAlign = "right";
        // ---- Splitting the body by : to get the label and the value seperatly ----//
        const label = document.createTextNode(body[0].split(":")[0]);
        const value = document.createTextNode(body[0].split(":")[1]);

        labelParent.appendChild(colorDiv);
        labelParent.appendChild(label);
        valueParent.appendChild(value); // adding color

        colorLabelAndDataParent.appendChild(labelParent);
        colorLabelAndDataParent.appendChild(valueParent);
      });
      // ---- Notice the root element is a table, that why im using tr, th and td ----//
      const tableRoot = tooltipEl.querySelector("table");

      // Remove old children
      while (tableRoot.firstChild) {
        tableRoot.firstChild.remove();
      }
      tableRoot.style.width = "150px";
      tableRoot.style.color = "white";
      // Add new children
      tableRoot.appendChild(toolTipTitle);
      tableRoot.appendChild(colorLabelAndDataParent);
    }
    // ---- Styling for position, i left it here from the docs ---- ///
    const { offsetLeft: positionX, offsetTop: positionY } = chart.canvas;

    // Display, position, and set styles for font
    tooltipEl.style.opacity = 1;
    tooltipEl.style.left = positionX + tooltip.caretX + "px";
    tooltipEl.style.top = positionY + tooltip.caretY + "px";
    tooltipEl.style.font = tooltip.options.bodyFont.string;
    tooltipEl.style.padding =
      tooltip.options.padding + "px " + tooltip.options.padding + "px";
  };

基本上按照这个示例,您可以按照自己的意愿设计和自定义它。

这是codesandbox中的示例:https://codesandbox.io/p/sandbox/strange-https-39zdhy

© www.soinside.com 2019 - 2024. All rights reserved.