UNPKG

@alicloud/cloud-charts

Version:

![](https://img.shields.io/npm/v/@alicloud/cloud-charts?color=%23ff8200)

269 lines (230 loc) 10.6 kB
import React, { useState, useEffect, useRef } from 'react'; import { PrefixName } from '../../../constants'; import themes from '../../../themes'; import { filterLegend, highlightLegend, clearHighlight } from '../../../common/chartRefs'; import WidgetsTooltip from '../../../common/Tooltip'; import LegendMarker from '../../../common/LegendMarker'; import "./index.css"; var prefix = PrefixName + "-foldable-legend"; export default function FolableLegend(_ref) { var config = _ref.config, chart = _ref.chart, _ref$legendItems = _ref.legendItems, legendItems = _ref$legendItems === void 0 ? [] : _ref$legendItems; // @ts-ignore var widgetsCtx = chart.widgetsCtx; // 是否需要折叠 var _useState = useState(false), foldable = _useState[0], setFoldable = _useState[1]; // 当前是否折叠 var _useState2 = useState(true), folded = _useState2[0], setFolded = _useState2[1]; // 显示的元素个数 var _useState3 = useState(0), num = _useState3[0], setNum = _useState3[1]; var contentRef = useRef(null); // legendItems的缓存,用于比较是否变化 var itemsCache = useRef([]); var containerWidth = widgetsCtx === null || widgetsCtx === void 0 ? void 0 : widgetsCtx.size[0]; var containerHeight = (widgetsCtx === null || widgetsCtx === void 0 ? void 0 : widgetsCtx.size[1]) || 200; var _useState4 = useState(''), activedItem = _useState4[0], setActivedItem = _useState4[1]; var _useState5 = useState([]), filteredItems = _useState5[0], setFilteredItems = _useState5[1]; var legendField = (widgetsCtx === null || widgetsCtx === void 0 ? void 0 : widgetsCtx.legendField) || 'type'; // legend items变化时,重新计算legend useEffect(function () { var _itemsCache$current, _itemsCache$current2; // 深比较legend items的数量与名称是否改变 if (((_itemsCache$current = itemsCache.current) === null || _itemsCache$current === void 0 ? void 0 : _itemsCache$current.length) !== (legendItems === null || legendItems === void 0 ? void 0 : legendItems.length) || (_itemsCache$current2 = itemsCache.current) !== null && _itemsCache$current2 !== void 0 && _itemsCache$current2.some(function (item, index) { return item.name !== legendItems[index].name; })) { handleFold(); setFilteredItems([]); itemsCache.current = legendItems; } }, [legendItems]); // 图表尺寸变化时,修改legend尺寸,重新变成折叠状 useEffect(function () { handleFold(); }, [containerHeight, containerWidth, config]); useEffect(function () { setFilteredItems([]); }, [config]); // 点击高亮legend useEffect(function () { filterLegend(chart, function (value) { return !filteredItems.includes(value); }, legendField); }, [filteredItems]); // hover高亮legend var activeItem = function activeItem(itemName) { highlightLegend(chart, function (value) { return value === itemName; }, legendField); }; // 清除高亮 var clearActive = function clearActive() { clearHighlight(chart); }; useEffect(function () { clearActive(); if (activedItem) { activeItem(activedItem); } }, [activedItem]); var renderItem = function renderItem(item) { var name = item.name, marker = item.marker; var id = item.id || name; return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", { className: prefix + "-marker", onClick: function onClick(event) { if (filteredItems.includes(id)) { setFilteredItems(function (pre) { return pre.filter(function (filteredItem) { return filteredItem !== id; }); }); } else if (filteredItems.length !== legendItems.length - 1) { setFilteredItems(function (pre) { return [].concat(pre, [id]); }); clearActive(); } else { setFilteredItems([]); } event.stopPropagation(); } }, /*#__PURE__*/React.createElement(LegendMarker, { marker: marker, disable: filteredItems.includes(id) })), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(LegendName, { name: name, style: { maxWidth: containerWidth - 16 - 16 - 4 // fontWeight: activedItem === id ? 500 : 'normal', // color: // activedItem === id ? themes['widgets-legend-text-highlight'] : themes['widgets-legend-text-normal'], } }))); }; // 判断是否需要折叠及折叠的元素个数 useEffect(function () { var _contentRef$current; if (!(contentRef !== null && contentRef !== void 0 && contentRef.current)) { return; } setFoldable((contentRef === null || contentRef === void 0 ? void 0 : (_contentRef$current = contentRef.current) === null || _contentRef$current === void 0 ? void 0 : _contentRef$current.scrollHeight) !== 20); var childrenNodes = contentRef.current.children; var index = 0; for (index = 0; index < childrenNodes.length; index++) { if (childrenNodes[index].offsetTop >= 20) { break; } } setNum(index); }, [containerWidth, legendItems]); // 展开所有items var handleUnfold = function handleUnfold() { var _contentRef$current2; // 图表高度缩小 var chartDom = widgetsCtx === null || widgetsCtx === void 0 ? void 0 : widgetsCtx.chartDom; var height = containerHeight - Math.min(contentRef === null || contentRef === void 0 ? void 0 : (_contentRef$current2 = contentRef.current) === null || _contentRef$current2 === void 0 ? void 0 : _contentRef$current2.scrollHeight, containerHeight * 0.3); // @ts-ignore chartDom.style.height = height + "px"; chart.changeSize(containerWidth, height); setFolded(false); }; // 折叠当前items var handleFold = function handleFold() { // 图表高度恢复 var chartDom = widgetsCtx === null || widgetsCtx === void 0 ? void 0 : widgetsCtx.chartDom; if (chartDom) { var height = containerHeight - 20; // @ts-ignore chartDom.style.height = height + "px"; chart.changeSize(containerWidth, height); // 滚动到最上方 if (contentRef.current) { contentRef.current.scrollTop = 0; } setFolded(true); } }; return /*#__PURE__*/React.createElement("div", { className: prefix + "-container" }, /*#__PURE__*/React.createElement("div", { ref: contentRef, className: prefix + "-content", style: { maxHeight: folded ? 20 : containerHeight * 0.3, overflowY: !folded ? 'auto' : 'hidden' } }, legendItems.map(function (item) { var id = item.id || item.name; return /*#__PURE__*/React.createElement("div", { key: id, className: prefix + "-item", style: { color: !filteredItems.includes(id) ? activedItem === id ? themes['widgets-legend-text-highlight'] : themes['widgets-legend-text-normal'] : themes['widgets-color-disable'] }, onMouseEnter: function onMouseEnter() { if (!filteredItems.includes(id)) { setActivedItem(id); } }, onMouseLeave: function onMouseLeave() { if (!filteredItems.includes(id)) { setActivedItem(''); } }, onClick: function onClick() { if ((filteredItems === null || filteredItems === void 0 ? void 0 : filteredItems.length) === (legendItems === null || legendItems === void 0 ? void 0 : legendItems.length) - 1 && !filteredItems.includes(id)) { setFilteredItems([]); } else { setFilteredItems(legendItems.map(function (item) { return item.id || item.name; }).filter(function (legendName) { return legendName !== id; })); } } }, renderItem(item)); })), foldable && folded && /*#__PURE__*/React.createElement("div", { className: prefix + "-more", onClick: handleUnfold }, /*#__PURE__*/React.createElement("div", { className: prefix + "-name", style: { color: themes['widgets-color-text-1'] } }, "+", (legendItems === null || legendItems === void 0 ? void 0 : legendItems.length) - num), /*#__PURE__*/React.createElement("svg", { fill: "none", width: "8.149999618530273", height: "8.487500190734863", viewBox: "0 0 8.149999618530273 8.487500190734863" }, /*#__PURE__*/React.createElement("g", { transform: "matrix(0,1,-1,0,8.149999618530273,-8.149999618530273)" }, /*#__PURE__*/React.createElement("path", { d: "M8.812499618530273,8.15L12.887499618530274,4.075L8.812499618530273,0L8.149999618530273,0.6625L11.562499618530273,4.075L8.149999618530273,7.4875L8.812499618530273,8.15ZM15.312499618530273,4.075L11.899999618530273,7.4875L12.562499618530273,8.15L16.637499618530274,4.075L12.562499618530273,0L11.899999618530273,0.6625L15.312499618530273,4.075Z", fill: themes['widgets-color-text-2'] })))), !folded && /*#__PURE__*/React.createElement("div", { className: prefix + "-fold", onClick: handleFold }, /*#__PURE__*/React.createElement("svg", { fill: "none", width: "8.149999618530273", height: "8.487500190734863", viewBox: "0 0 8.149999618530273 8.487500190734863" }, /*#__PURE__*/React.createElement("g", { transform: "matrix(0,-1,-1,0,16.637499809265137,16.637499809265137)" }, /*#__PURE__*/React.createElement("path", { d: "M8.812499618530273,16.637500190734862L12.887499618530274,12.562500190734863L8.812499618530273,8.487500190734863L8.149999618530273,9.150000190734863L11.562499618530273,12.562500190734863L8.149999618530273,15.975000190734864L8.812499618530273,16.637500190734862ZM15.312499618530273,12.562500190734863L11.899999618530273,15.975000190734864L12.562499618530273,16.637500190734862L16.637499618530274,12.562500190734863L12.562499618530273,8.487500190734863L11.899999618530273,9.150000190734863L15.312499618530273,12.562500190734863Z", fill: themes['widgets-color-text-2'] }))))); } function LegendName(_ref2) { var _ref2$name = _ref2.name, name = _ref2$name === void 0 ? '' : _ref2$name, _ref2$style = _ref2.style, style = _ref2$style === void 0 ? {} : _ref2$style; var ref = useRef(null); return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", { className: prefix + "-name", style: style, ref: ref }, name), /*#__PURE__*/React.createElement(WidgetsTooltip, { ref: ref, content: name })); }