import { orderBy, maxBy, minBy } from 'lodash'; import { SeriesData } from './dataset'; /** * 平滑采样算法 * @description 为了能够使用category type 的 x轴,需要坐标均匀的数据,但是真实数据很难刚好卡在step上,所以我们需要做linear插值补充点,然后再通过scatter散点得到step相近点的坐标 * @param data [xdim, ydim, ...][] * @param smoothWeight * @param dataZoom 图表的缩放情况 */ export const smoothData = ( data: SeriesData[], smoothWeight: number, dataZoom: { startValue: number | undefined; endValue: number | undefined }, ) => { const range = [10, 200]; // 最大点数和最小点数 const sv = [ // specialValues minBy(data, '[0]'), // left maxBy(data, '[1]'), // top maxBy(data, '[0]'), // right minBy(data, '[1]'), // bottom ]; const orderedData = orderBy( data.filter( (o) => (dataZoom.startValue !== undefined && o[0] >= dataZoom.startValue && dataZoom.endValue !== undefined && o[0] <= dataZoom.endValue) || sv.includes(o), ), '[0]', 'asc', ); const xMax = dataZoom.endValue === undefined ? orderedData[orderedData.length - 1][0] : dataZoom.endValue; const xMin = dataZoom.startValue === undefined ? orderedData[0][0] : dataZoom.startValue; const step = Math.round( (xMax - xMin) / ((range[1] - range[0]) * (1 - smoothWeight) + range[0]), ); const res: SeriesData[] = []; let x = xMin; orderedData.forEach((o, i) => { if (sv.includes(o)) { res.push(o); return; } if (o[0] >= x) { res.push(o); x += step; } }); return res; };