/* * Copyright 2022 Nightingale Team * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ import * as React from 'react'; import { useEffect, useRef, FunctionComponent } from 'react'; import _ from 'lodash'; import * as d3 from 'd3'; import { useSize } from 'ahooks'; import { renderFn } from './render'; import { IPanel, IHexbinStyles } from '../../../types'; import getCalculatedValuesBySeries from '../../utils/getCalculatedValuesBySeries'; import { getColorScaleLinearDomain } from './utils'; import './style.less'; interface HoneyCombProps { values: IPanel; series: any[]; } const Hexbin: FunctionComponent<HoneyCombProps> = (props) => { const { values, series } = props; const { custom = {}, options } = values; const { calc, colorRange = [], reverseColorOrder = false, colorDomainAuto, colorDomain } = custom as IHexbinStyles; const groupEl = useRef<SVGGElement>(null); const svgEl = useRef<HTMLDivElement>(null); const svgSize = useSize(svgEl); useEffect(() => { const calculatedValues = getCalculatedValuesBySeries( series, calc, { util: options?.standardOptions?.util, decimals: options?.standardOptions?.decimals, }, options?.valueMappings, ); const colorScales = d3 .scaleLinear() .domain(getColorScaleLinearDomain(calculatedValues, colorDomainAuto, colorDomain)) .range(reverseColorOrder ? _.reverse(_.slice(colorRange)) : colorRange); if (svgSize?.width && svgSize?.height) { const renderProps = { width: svgSize?.width, height: svgSize?.height, parentGroupEl: groupEl.current, }; const data = _.map(calculatedValues, (item) => { return { ...item, value: item.text, color: item.color || colorScales(item.stat) || '#3399CC', }; }); d3.select(groupEl.current).selectAll('*').remove(); if (data.length) { renderFn(data, renderProps); } } }, [JSON.stringify(series), JSON.stringify(options), svgSize?.width, svgSize?.height, calc, colorRange, reverseColorOrder, colorDomainAuto, colorDomain]); return ( <div ref={svgEl} style={{ width: '100%', height: '100%' }}> <svg style={{ width: '100%', height: '100%' }}> <g ref={groupEl} /> </svg> </div> ); }; export default Hexbin;