import { Geometry } from '@antv/g2'; import { get, isString } from '@antv/util'; import { animation, annotation, interaction, scale, theme } from '../../adaptor/common'; import { interval } from '../../adaptor/geometries'; import { AXIS_META_CONFIG_KEYS } from '../../constant'; import { Params } from '../../core/adaptor'; import { deepAssign, flow, pick, renderGaugeStatistic } from '../../utils'; import { DEFAULT_COLOR, INDICATEOR_VIEW_ID, PERCENT, RANGE_TYPE, RANGE_VALUE, RANGE_VIEW_ID } from './constants'; import { GaugeOptions } from './types'; import { getIndicatorData, getRangeData } from './utils'; /** * geometry 处理 * @param params */ function geometry(params: Params): Params { const { chart, options } = params; const { percent, range, radius, innerRadius, startAngle, endAngle, axis, indicator, gaugeStyle, type, meter } = options; const { color, width: rangeWidth } = range; // 指标 & 指针 // 如果开启在应用 if (indicator) { const indicatorData = getIndicatorData(percent); const v1 = chart.createView({ id: INDICATEOR_VIEW_ID }); v1.data(indicatorData); v1.point() .position(`${PERCENT}*1`) .shape(indicator.shape || 'gauge-indicator') // 传入指针的样式到自定义 shape 中 .customInfo({ defaultColor: chart.getTheme().defaultColor, indicator, }); v1.coordinate('polar', { startAngle, endAngle, radius: innerRadius * radius, // 外部的 innerRadius * radius = 这里的 radius }); v1.axis(PERCENT, axis); // 一部分应用到 scale 中 v1.scale(PERCENT, pick(axis, AXIS_META_CONFIG_KEYS)); } // 辅助 range // [{ range: 1, type: '0', percent: 原始进度百分比 }] const rangeData = getRangeData(percent, options.range); const v2 = chart.createView({ id: RANGE_VIEW_ID }); v2.data(rangeData); const rangeColor = isString(color) ? [color, DEFAULT_COLOR] : color; const { ext } = interval({ chart: v2, options: { xField: '1', yField: RANGE_VALUE, seriesField: RANGE_TYPE, rawFields: [PERCENT], isStack: true, interval: { color: rangeColor, style: gaugeStyle, shape: type === 'meter' ? 'meter-gauge' : null, }, args: { zIndexReversed: true, sortZIndex: true, }, minColumnWidth: rangeWidth, maxColumnWidth: rangeWidth, }, }); const geometry = ext.geometry as Geometry; // 传入到自定义 shape 中 geometry.customInfo({ meter }); v2.coordinate('polar', { innerRadius, radius, startAngle, endAngle, }).transpose(); return params; } /** * meta 配置 * @param params */ function meta(params: Params): Params { return flow( scale({ range: { min: 0, max: 1, maxLimit: 1, minLimit: 0, }, [PERCENT]: {}, }) )(params); } /** * 统计指标文档 * @param params */ function statistic(params: Params, updated?: boolean): Params { const { chart, options } = params; const { statistic, percent } = options; // 先清空标注,再重新渲染 chart.getController('annotation').clear(true); if (statistic) { const { content: contentOption } = statistic; let transformContent; // 当设置 content 的时候,设置默认样式 if (contentOption) { transformContent = deepAssign( {}, { content: `${(percent * 100).toFixed(2)}%`, style: { opacity: 0.75, fontSize: '30px', lineHeight: 1, textAlign: 'center', color: 'rgba(44,53,66,0.85)', }, }, contentOption ); } renderGaugeStatistic(chart, { statistic: { ...statistic, content: transformContent } }, { percent }); } if (updated) { chart.render(true); } return params; } /** * tooltip 配置 */ function tooltip(params: Params): Params { const { chart, options } = params; const { tooltip } = options; if (tooltip) { chart.tooltip( deepAssign( { showTitle: false, showMarkers: false, containerTpl: '
', domStyles: { 'g2-tooltip': { padding: '4px 8px', fontSize: '10px', }, }, customContent: (x: string, data: any[]) => { const percent = get(data, [0, 'data', PERCENT], 0); return `${(percent * 100).toFixed(2)}%`; }, }, tooltip ) ); } else { // 默认,不展示 tooltip chart.tooltip(false); } return params; } /** * other 配置 * @param params */ function other(params: Params): Params { const { chart } = params; chart.legend(false); return params; } /** * 对外暴露的 adaptor */ export { statistic }; /** * 图适配器 * @param chart * @param options */ export function adaptor(params: Params) { // flow 的方式处理所有的配置到 G2 API return flow( theme, // animation 配置必须在 createView 之前,不然无法让子 View 生效 animation, geometry, meta, tooltip, statistic, interaction, annotation(), other // ... 其他的 adaptor flow )(params); }