本文介绍: 当我们结合 React 使用 highCharts 库时,存在一些特殊自定义的情况,比如针对 Tooltip 定制化样式。当然 highCharts 也提供了配置自定义 tooltip 的 formatter 方法,可以支持 html 元素。但是并不够灵活,对于配置复杂样式或组件复用情况下,并不友好。因此寻求新的思路,以下便是社区常用的一个方法,在此记录。该实现方式最基本的原理是采用 React 的方法,在指定的元素下渲染子元素。
前言
当我们结合 React 使用 highCharts 库时,存在一些特殊自定义的情况,比如针对 Tooltip 定制化样式。当然 highCharts 也提供了配置自定义 tooltip 的 formatter 方法,可以支持 html 元素。但是并不够灵活,对于配置复杂样式或组件复用情况下,并不友好。因此寻求新的思路,以下便是社区常用的一个方法,在此记录。
实现
Tooltip 组件封装
import {
Chart,
TooltipFormatterCallbackFunction,
TooltipFormatterContextObject,
} from 'highcharts';
import { useEffect, useRef, useState } from 'react';
import ReactDOM from 'react-dom';
const generateTooltipId = (chartId: number) =>
`highcharts-custom-tooltip-${chartId}`;
interface Props {
chart: Chart | null;
children(formatterContext: TooltipFormatterContextObject): JSX.Element;
}
export const Tooltip = ({ chart, children }: Props) => {
const isInit = useRef(false);
const [context, setContext] = useState<TooltipFormatterContextObject | null>(
null
);
useEffect(() => {
if (chart) {
const formatter: TooltipFormatterCallbackFunction = function () {
// Ensures that tooltip DOM container is rendered before React portal is created.
if (!isInit.current) {
isInit.current = true;
setTimeout(() => {
chart.tooltip.refresh.apply(chart.tooltip, [
this.points ? this.points.map(({ point }) => point) : this.point,
]);
chart.tooltip.hide(0);
});
}
setContext(this);
return `<div id="${generateTooltipId(chart.index)}"></div>`;
};
chart.update({
tooltip: {
formatter,
useHTML: true,
},
});
}
}, [chart]);
const node = chart && document.getElementById(generateTooltipId(chart.index));
return node && context
? ReactDOM.createPortal(children(context), node)
: null;
};
调用方式
import React, { useState, useCallback } from "react";
import Highcharts, { Chart as HighchartsChart } from "highcharts";
import HighchartsReact from "highcharts-react-official";
import { Tooltip } from "./Tooltip";
const options = {
title: {
text: "Custom tooltip as React component"
},
series: [
{
type: "line",
data: [1, 22424242424, 3, 4, 5, 123123132]
}
],
tooltip: {
useHTML: true
}
};
export const Chart = () => {
const [chart, setChart] = useState<HighchartsChart | null>(null);
const callback = useCallback((chart: HighchartsChart) => {
setChart(chart);
}, []);
return (
<>
<HighchartsReact
highcharts={Highcharts}
options={options}
callback={callback}
/>
<Tooltip chart={chart}>
{(formatterContext) => {
const { x, y } = formatterContext;
return (
<>
<div>x: {x}</div>
<div>y: {y}</div>
<br />
<button onClick={() => alert(`x: ${x}, y: ${y}`)}>Action</button>
</>
);
}}
</Tooltip>
</>
);
};
{
points
point
series
x
y
}
这些字段在自定义 tooltip 组件时可以传参到组件中获取每个 point 的值。
除了 x,y 值外,可以自定义字段,在 series.keys 配置项中,配置如下:
keys: [
'x',
'y',
'custom.A',
'custom.B',
'custom.C',
],
data:[[1, 2, 'A1', 'B1', 'C1'], [1, 2, 'A2', 'B2', 'C2']]
其值便可以在 formatterContext.point.options.custom.A
及 formatterContext.point.options.custom.B
等方式获取。
总结
该实现方式最基本的原理是采用 React 的 createPortal
方法,在指定的元素下渲染子元素。可以理解为类似纯 js 的 getElementById('id').html(children(context))
。
原文地址:https://blog.csdn.net/GuoJiangweigege/article/details/134735506
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_23652.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。