UNPKG

@alicloud/cloud-charts

Version:

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

356 lines (345 loc) 20 kB
import _extends from "@babel/runtime/helpers/extends"; import React, { useState, useEffect, useMemo, useRef } from 'react'; import themes from '../../../themes'; import { PrefixName } from '../../../constants'; import { getStatistics, filterLegend, highlightLegend, clearHighlight } from '../../../common/chartRefs'; import { getItemData } from '../../../common/rectLegend'; import { customFormatter, getFormatConfig } from '../../../common/common'; import WidgetsTooltip from '../../../common/Tooltip'; import LegendMarker from '../../../common/LegendMarker'; import { getText } from '../../../ChartProvider'; import { calcTextWidth } from '../../../common/ellipsisLabel'; import "./index.css"; var prefix = PrefixName + "-table-legend"; export default function TableLegend(_ref) { var _config$table2, _config$table2$custom, _widgetsCtx$legendSiz, _widgetsCtx$legendSiz2, _widgetsCtx$props$con, _widgetsCtx$props, _config$table4, _config$table6, _config$table8, _config$table9, _config$table10, _config$table11, _config$table12; 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 hoverable = config.hoverable, clickable = config.clickable, itemName = config.itemName, useReverseChecked = config.useReverseChecked; var _useState = useState(''), activedItem = _useState[0], setActivedItem = _useState[1]; var _useState2 = useState([]), filteredItems = _useState2[0], setFilteredItems = _useState2[1]; var legendField = (widgetsCtx === null || widgetsCtx === void 0 ? void 0 : widgetsCtx.legendField) || 'type'; var position = config.position.split('-')[0]; var statistics = useMemo(function () { var _config$table; return (config === null || config === void 0 ? void 0 : (_config$table = config.table) === null || _config$table === void 0 ? void 0 : _config$table.statistics) || []; }, [config === null || config === void 0 ? void 0 : config.table]); // 目前暂时对多重圆环进行特殊处理,待规则统一梳理后,整理数据类型 var dataType = widgetsCtx.chartName === 'G2MultiPie' ? 'treeNode' : 'common'; var statisticsRes = useMemo(function () { return getStatistics(chart, statistics, legendField, dataType); }, [chart, statistics, config, legendItems]); var updateItems = useMemo(function () { var newItems = legendItems; if (dataType === 'treeNode') { var _chart$options$data, _chart$options, _filterData$filter, _filterData$filter2; var filterData = [].concat((_chart$options$data = chart === null || chart === void 0 ? void 0 : (_chart$options = chart.options) === null || _chart$options === void 0 ? void 0 : _chart$options.data) !== null && _chart$options$data !== void 0 ? _chart$options$data : []); var firstDepthCount = (_filterData$filter = filterData.filter(function (sub) { return sub.depth === 1; })) === null || _filterData$filter === void 0 ? void 0 : _filterData$filter.length; var secondDepthCount = (_filterData$filter2 = filterData.filter(function (sub) { return sub.depth === 2; })) === null || _filterData$filter2 === void 0 ? void 0 : _filterData$filter2.length; // 增加特殊逻辑,如果目前包含2层以上,则只展示第一层数据 if (firstDepthCount > 0 && secondDepthCount > 0) { filterData = filterData.filter(function (sub) { return sub.depth === 1; }); } var filterDataIdList = filterData.map(function (sub) { return sub.id; }); newItems = newItems.filter(function (item) { return filterDataIdList.includes(item.id); }); newItems.map(function (item) { var _ref2, _filterData$idx$value, _filterData$idx, _filterData$idx2; var idx = filterData.findIndex(function (sub) { return sub.id === item.id; }); if (typeof item.marker === 'object') { var _filterData$idx$color; item.marker.dataFill = (_filterData$idx$color = filterData[idx].color) !== null && _filterData$idx$color !== void 0 ? _filterData$idx$color : null; } item.data = (_ref2 = (_filterData$idx$value = (_filterData$idx = filterData[idx]) === null || _filterData$idx === void 0 ? void 0 : _filterData$idx.value) !== null && _filterData$idx$value !== void 0 ? _filterData$idx$value : (_filterData$idx2 = filterData[idx]) === null || _filterData$idx2 === void 0 ? void 0 : _filterData$idx2.rawValue) !== null && _ref2 !== void 0 ? _ref2 : null; }); legendItems.sort(function (a, b) { return b.data - a.data; }); } return newItems; }, [legendItems]); // 表格列数 var columns = ((statistics === null || statistics === void 0 ? void 0 : statistics.length) || 0) + ((config === null || config === void 0 ? void 0 : (_config$table2 = config.table) === null || _config$table2 === void 0 ? void 0 : (_config$table2$custom = _config$table2.custom) === null || _config$table2$custom === void 0 ? void 0 : _config$table2$custom.length) || 0); // legend宽高 var legendWidth = widgetsCtx === null || widgetsCtx === void 0 ? void 0 : (_widgetsCtx$legendSiz = widgetsCtx.legendSize) === null || _widgetsCtx$legendSiz === void 0 ? void 0 : _widgetsCtx$legendSiz[0]; var legendHeight = widgetsCtx === null || widgetsCtx === void 0 ? void 0 : (_widgetsCtx$legendSiz2 = widgetsCtx.legendSize) === null || _widgetsCtx$legendSiz2 === void 0 ? void 0 : _widgetsCtx$legendSiz2[1]; useEffect(function () { setFilteredItems([]); }, [config]); useEffect(function () { filterLegend(chart, function (value) { return !filteredItems.includes(value); }, legendField); }, [filteredItems]); 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 chartConfig = (_widgetsCtx$props$con = widgetsCtx === null || widgetsCtx === void 0 ? void 0 : (_widgetsCtx$props = widgetsCtx.props) === null || _widgetsCtx$props === void 0 ? void 0 : _widgetsCtx$props.config) !== null && _widgetsCtx$props$con !== void 0 ? _widgetsCtx$props$con : {}; var formatConfig = useMemo(function () { return getFormatConfig(chartConfig); }, [chartConfig]); // id -> 统计值的最终展示值 映射表 var valueMap = useMemo(function () { var newMap = {}; // console.log('updateItems', updateItems, statisticsRes); updateItems.map(function (legendItem, index) { var _legendItem$id, _config$table3; var name = legendItem.name; var id = (_legendItem$id = legendItem.id) !== null && _legendItem$id !== void 0 ? _legendItem$id : name; statistics === null || statistics === void 0 ? void 0 : statistics.forEach(function (statistic) { var _statisticsRes$id; var value = (_statisticsRes$id = statisticsRes[id]) === null || _statisticsRes$id === void 0 ? void 0 : _statisticsRes$id[statistic]; if (value || value === 0) { if (config !== null && config !== void 0 && config.valueFormatter && typeof (config === null || config === void 0 ? void 0 : config.valueFormatter) === 'function') { value = config === null || config === void 0 ? void 0 : config.valueFormatter(value, legendItem, index); } else { // value = formatValue(value, config?.decimal); var customValueFormatter = null; if (Array.isArray(formatConfig)) { // 双轴 // @ts-ignore var dataGroup = getItemData(name, widgetsCtx === null || widgetsCtx === void 0 ? void 0 : widgetsCtx.rawData, config === null || config === void 0 ? void 0 : config.dataType, widgetsCtx === null || widgetsCtx === void 0 ? void 0 : widgetsCtx.data); customValueFormatter = (dataGroup === null || dataGroup === void 0 ? void 0 : dataGroup.yAxis) === 1 ? customFormatter(formatConfig[1]) : customFormatter(formatConfig[0]); } else { // 单轴 customValueFormatter = customFormatter(formatConfig); } if (customValueFormatter) { value = customValueFormatter(value); } else { value = formatValue(value, config === null || config === void 0 ? void 0 : config.decimal); } } } else { value = '-'; } if (!(id in newMap)) { newMap[id] = {}; } newMap[id][statistic] = value; }); ((config === null || config === void 0 ? void 0 : (_config$table3 = config.table) === null || _config$table3 === void 0 ? void 0 : _config$table3.custom) || []).forEach(function (customItem, index) { var _customItem$value; var title = customItem.title || "custom" + index; var value = typeof (customItem === null || customItem === void 0 ? void 0 : customItem.value) === 'function' ? customItem.value(_extends({}, legendItem, statisticsRes[id])) : (_customItem$value = customItem === null || customItem === void 0 ? void 0 : customItem.value) !== null && _customItem$value !== void 0 ? _customItem$value : ''; if (!(id in newMap)) { newMap[id] = {}; } newMap[id][title] = value; }); }); return newMap; }, [updateItems, statistics, statisticsRes, config, formatConfig]); // 根据每列的标题和数值计算每列的宽度 var widthMap = useMemo(function () { var newMap = {}; Object.keys(valueMap).forEach(function (id) { var statisticMap = valueMap[id]; Object.keys(statisticMap).forEach(function (statistic) { var value = statisticMap[statistic].toString(); if (!(statistic in newMap) || newMap[statistic] < value.length) { newMap[statistic] = value; } }); }); Object.keys(newMap).forEach(function (statistic) { // 最小值40 newMap[statistic] = Math.max(Math.ceil(calcTextWidth(newMap[statistic])), 40); }); return newMap; }, [valueMap, config === null || config === void 0 ? void 0 : (_config$table4 = config.table) === null || _config$table4 === void 0 ? void 0 : _config$table4.custom]); // 表格布局 var gridTemplate = useMemo(function () { var _config$table5, _updateItems$length; var res = columns > 0 ? ['8px minmax(80px, 40%)'].concat(statistics.map(function (statistic) { return "minmax(" + widthMap[statistic] + "px, " + 60 / columns + "%)"; }), ((config === null || config === void 0 ? void 0 : (_config$table5 = config.table) === null || _config$table5 === void 0 ? void 0 : _config$table5.custom) || []).map(function (customItem, index) { return "minmax(" + widthMap[customItem.title || "custom" + index] + "px, " + 60 / columns + "%)"; })).join(' 8px ') : '8px minmax(min(80px, 30%), 100%)'; // 当有纵向滚动条时,需要给加一列 if ((((_updateItems$length = updateItems === null || updateItems === void 0 ? void 0 : updateItems.length) !== null && _updateItems$length !== void 0 ? _updateItems$length : 0) + 1) * 20 > legendHeight) { res += ' 8px'; } return res; }, [widthMap, statistics, config === null || config === void 0 ? void 0 : (_config$table6 = config.table) === null || _config$table6 === void 0 ? void 0 : _config$table6.custom, columns, updateItems === null || updateItems === void 0 ? void 0 : updateItems.legnth, legendHeight]); // 表格最小宽度 var tableMinWidth = useMemo(function () { var _config$table7, _updateItems$length2; var res = 10 + 8 + 80; statistics.forEach(function (statistic) { res += 8 + widthMap[statistic]; }); ((config === null || config === void 0 ? void 0 : (_config$table7 = config.table) === null || _config$table7 === void 0 ? void 0 : _config$table7.columns) || []).forEach(function (customItem, index) { res += 8 + widthMap[customItem.title || "custom" + index]; }); if ((((_updateItems$length2 = updateItems === null || updateItems === void 0 ? void 0 : updateItems.length) !== null && _updateItems$length2 !== void 0 ? _updateItems$length2 : 0) + 1) * 20 > legendHeight) { res += 8; } return res; }, [widthMap, statistics, config === null || config === void 0 ? void 0 : (_config$table8 = config.table) === null || _config$table8 === void 0 ? void 0 : _config$table8.custom, columns, updateItems, legendHeight]); return /*#__PURE__*/React.createElement("table", { className: prefix + "-container", style: _extends({ paddingLeft: position === 'right' ? 10 : 0, minWidth: tableMinWidth }, config === null || config === void 0 ? void 0 : (_config$table9 = config.table) === null || _config$table9 === void 0 ? void 0 : _config$table9.style) }, columns > 0 && !(config !== null && config !== void 0 && (_config$table10 = config.table) !== null && _config$table10 !== void 0 && _config$table10.hideTitle) && /*#__PURE__*/React.createElement("thead", { className: prefix + "-thead" }, /*#__PURE__*/React.createElement("tr", { className: prefix + "-tr " + prefix + "-legend-title", style: { gridTemplateColumns: gridTemplate } }, /*#__PURE__*/React.createElement("th", null), /*#__PURE__*/React.createElement("th", null), statistics === null || statistics === void 0 ? void 0 : statistics.map(function (statistic) { var _widgetsCtx$context; return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("th", null), /*#__PURE__*/React.createElement("th", { key: statistic }, getText(statistic, widgetsCtx === null || widgetsCtx === void 0 ? void 0 : widgetsCtx.language, widgetsCtx === null || widgetsCtx === void 0 ? void 0 : (_widgetsCtx$context = widgetsCtx.context) === null || _widgetsCtx$context === void 0 ? void 0 : _widgetsCtx$context.locale))); }), ((config === null || config === void 0 ? void 0 : (_config$table11 = config.table) === null || _config$table11 === void 0 ? void 0 : _config$table11.custom) || []).map(function (customItem, index) { var _customItem$title; return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("th", null), /*#__PURE__*/React.createElement("th", { key: "custom" + index }, (_customItem$title = customItem === null || customItem === void 0 ? void 0 : customItem.title) !== null && _customItem$title !== void 0 ? _customItem$title : '')); }))), /*#__PURE__*/React.createElement("tbody", { className: prefix + "-tbody", style: { height: "calc(100% - " + (columns > 0 && !(config !== null && config !== void 0 && (_config$table12 = config.table) !== null && _config$table12 !== void 0 && _config$table12.hideTitle) ? 20 : 0) + "px)", // 有横向滚动条时,需要加个padding paddingBottom: legendWidth < tableMinWidth ? 4 : 0 } }, updateItems.map(function (legendItem, index) { var _legendItem$id2, _config$table13; var name = legendItem.name, marker = legendItem.marker; var id = (_legendItem$id2 = legendItem.id) !== null && _legendItem$id2 !== void 0 ? _legendItem$id2 : name; if (itemName) { var _itemName$formatter; name = itemName === null || itemName === void 0 ? void 0 : (_itemName$formatter = itemName.formatter) === null || _itemName$formatter === void 0 ? void 0 : _itemName$formatter.call(itemName, name, index, legendItem); } return /*#__PURE__*/React.createElement("tr", { key: id, className: prefix + "-tr " + prefix + "-legend-item " + (clickable ? 'pointer' : ''), style: { gridTemplateColumns: gridTemplate, color: !filteredItems.includes(id) ? activedItem === id ? themes['widgets-legend-text-highlight'] : themes['widgets-legend-text-normal'] : themes['widgets-color-disable'] }, onMouseEnter: function onMouseEnter() { if (hoverable && !filteredItems.includes(id)) { setActivedItem(id); } }, onMouseLeave: function onMouseLeave() { if (hoverable && !filteredItems.includes(id)) { setActivedItem(''); } }, onClick: function onClick(event) { // 是否按Control var hasControl = event.ctrlKey || event.metaKey; if (clickable) { if (!useReverseChecked && !hasControl || useReverseChecked && hasControl) { // 正选 if ((filteredItems === null || filteredItems === void 0 ? void 0 : filteredItems.length) === (updateItems === null || updateItems === void 0 ? void 0 : updateItems.length) - 1 && !filteredItems.includes(id)) { setFilteredItems([]); } else { setFilteredItems(updateItems.map(function (item) { return item.id || item.name; }).filter(function (legendName) { return legendName !== id; })); } } else { // 反选 if ((filteredItems === null || filteredItems === void 0 ? void 0 : filteredItems.length) === (updateItems === null || updateItems === void 0 ? void 0 : updateItems.length) - 1 && !filteredItems.includes(id)) { setFilteredItems([]); } else if (filteredItems.includes(id)) { setFilteredItems(function (pre) { return pre.filter(function (p) { return p !== id; }); }); } else { setFilteredItems(function (pre) { return [].concat(pre, [id]); }); } } } } }, /*#__PURE__*/React.createElement("td", { className: prefix + "-marker" }, /*#__PURE__*/React.createElement(LegendMarker, { marker: marker, disable: filteredItems.includes(id), item: legendItem })), /*#__PURE__*/React.createElement("td", null, /*#__PURE__*/React.createElement(LegendName, { name: name })), statistics === null || statistics === void 0 ? void 0 : statistics.map(function (statistic) { var _valueMap$id; var value = valueMap === null || valueMap === void 0 ? void 0 : (_valueMap$id = valueMap[id]) === null || _valueMap$id === void 0 ? void 0 : _valueMap$id[statistic]; return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("td", null), /*#__PURE__*/React.createElement("td", { className: prefix + "-statistics", key: statistic }, value)); }), ((config === null || config === void 0 ? void 0 : (_config$table13 = config.table) === null || _config$table13 === void 0 ? void 0 : _config$table13.custom) || []).map(function (customItem, index) { var value = valueMap[id][(customItem === null || customItem === void 0 ? void 0 : customItem.title) || "custom" + index]; return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("td", null), /*#__PURE__*/React.createElement("td", { className: prefix + "-statistics", key: "custom" + index }, value)); })); }))); } function LegendName(_ref3) { var _ref3$name = _ref3.name, name = _ref3$name === void 0 ? '' : _ref3$name; var ref = useRef(null); return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", { ref: ref, className: prefix + "-name" }, name), /*#__PURE__*/React.createElement(WidgetsTooltip, { ref: ref, content: name })); } /** 格式化数字 */ function formatValue(value, digits) { if (digits === void 0) { digits = 3; } return typeof value === 'number' ? value.toFixed(digits) : value.slice(0, digits + 2); }