Chart.js根据选择显示数据

u7up0aaq  于 2024-01-07  发布在  Chart.js
关注(0)|答案(2)|浏览(178)

我正在寻找一个解决方案,以显示基于你在图表内悬停的一些数据。这里是我的jsfiddle和我想要的演示。gif image
我希望我已经把一切都说清楚了,提前感谢!

const chart = document.getElementById('chart');

new Chart(chart, {
  type: 'doughnut',
  data: {
    labels: ['Bitcoin', 'Ethereum', 'Litecoin', 'Tether'],
    datasets: [{
      data: [50, 30, 10, 10],
      backgroundColor: [
        'orange',
        'purple',
        'darkblue',
        'green'
      ],
      borderWidth: 2,
    }]
  },
  options: {
    responsive: false,
    cutout: '72%',
    plugins: {
      legend: {
        display: false,
      },
    },
  }
});
.chart-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
}

.chart-balance {
  position: absolute;
}
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

<div class="chart-wrap">
  <canvas id="chart" class="kz-relative kz-index-10" width="224" height="224"></canvas>
  <div class="chart-balance">
    <p class="chart-asset-type">Ethereum</p>
    <h5 class="chart-asset-value">$1,000</h5>
  </div>
</div>
hmtdttj4

hmtdttj41#

您可以使用onHover钩子来更新HTML

const chart = document.getElementById('chart');

new Chart(chart, {
  type: 'doughnut',
  data: {
    labels: ['Bitcoin', 'Ethereum', 'Litecoin', 'Tether'],
    datasets: [{
      data: [50, 30, 10, 10],
      backgroundColor: [
        'orange',
        'purple',
        'darkblue',
        'green'
      ],
      borderWidth: 2,
    }]
  },
  options: {
    responsive: false,
    onHover: (evt, activeEls) => {
      if (activeEls.length === 0)
        return;

      const label = document.getElementsByClassName("chart-asset-type")[0];
      const value = document.getElementsByClassName("chart-asset-value")[0];

      label.innerHTML = evt.chart.data.labels[activeEls[0].index];
      value.innerHTML = evt.chart.data.datasets[activeEls[0].datasetIndex].data[activeEls[0].index];
    },
    cutout: '72%',
    plugins: {
      legend: {
        display: false,
      },
    },
  }
});
.chart-wrap {
  display: flex;
  align-items: center;
  justify-content: center;
}

.chart-balance {
  position: absolute;
}
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

<div class="chart-wrap">
  <canvas id="chart" class="kz-relative kz-index-10" width="224" height="224"></canvas>
  <div class="chart-balance">
    <p class="chart-asset-type">Ethereum</p>
    <h5 class="chart-asset-value">$1,000</h5>
  </div>
</div>
oewdyzsn

oewdyzsn2#

Chart.js的问题是它创建了一个画布,你不能用外部JavaScript代码来操作这些元素。我真的不知道是否有可能的配置来模拟你在Chart.js中想要的东西,因为我对它知之甚少。无论如何,我设法用Plotly库做到了这一点。有了它,我用圆形图表做了一部分工作,之后,我们在HTML中有SVG元素。2有了这个,我可以操纵默认的工具提示值,使它出现在自定义元素的中心。
完整的代码在那里,但我建议您查看Plotly文档,如果您不了解MutationObserver

// https://cdn.jsdelivr.net/npm/[email protected]/plotly.min.js

const data = {
    labels: ["Bitcoin", "Ethereum", "Litecoin", "Tether"],
    values: [50, 30, 10, 10],
    name: "",
    hoverinfo: "label+percent+name",
    hole: 0.65,
    type: "pie",
    marker: {
        colors: ["orange", "purple", "darkblue", "green"],
        line: {
            color: "white",
            width: 4
        }
    }
}

const layout = {
    paper_bgcolor: "transparent",
    height: 550,
    width: 550,
    showlegend: false
}

const chartElement = document.querySelector("#chart"),
    chartLabelElement = document.querySelector(".chart-label"),
    chartValueElement = document.querySelector(".chart-value")

chartLabelElement.textContent = data.labels[0]
chartValueElement.textContent = data.values[0]

Plotly.newPlot(chartElement, [data], layout).then(() => {
    observeTooltip()
})

function observeTooltip() {
    window.MutationObserver = window.MutationObserver ||
    window.WebKitMutationObserver || window.MozMutationObserver

    const observer = new MutationObserver(mutations => {
        const tooltipElement = chartElement.querySelector(".hovertext")

        if (tooltipElement) {
            tooltipElement.remove()

            const textElements = tooltipElement.querySelectorAll("tspan")

            const label = textElements[0].textContent.trim(),
                value = textElements[1].textContent.trim()

            chartLabelElement.textContent = label
            chartValueElement.textContent = value
        }
    })

    observer.observe(chartElement, {
        childList: true,
        subtree: true
    })
}
.modebar-container {
  display: none;
}

#chart {
  width: fit-content;
  margin: 0 auto;
}

#chart path.surface:hover {
  cursor: pointer;
  filter: opacity(0.7);
}

#chart .hovertext {
  display: none;
}

.chart-block {
  position: relative;
}

.chart-center {
  position: absolute;
  top: 0;
  width: 0;
  height: 100%;
  width: 100%;

  display: flex;
  flex-wrap: nowrap;
  justify-content: center;
  align-items: center;
  
  text-align: center;
  font-family: "Segoe UI", sans-serif;
}

.chart-label {
  color: #555;
  font-size: 18px;
  font-weight: 700;
}

.chart-value {
  color: #000;
  font-size: 48px;
  font-weight: 700;
}
<script src="https://cdn.jsdelivr.net/npm/[email protected]/plotly.min.js"></script>
<div class="chart-block">
    <div class="chart-center">
        <div>
            <div class="chart-label"></div>
            <div class="chart-value"></div>
        </div>
    </div>
    <div id="chart"></div>
</div>

相关问题