| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411 |
- /**
- * 系列数据处理函数
- *
- * 从 u-charts 核心库搬迁的系列数据处理相关函数
- * 用于处理图表系列数据的填充、合并、颜色设置等操作
- */
- // 类型定义
- export interface SeriesItem {
- data: (number | null)[] | number[] | { value: number }[];
- name: string;
- color?: string;
- index?: number;
- linearIndex?: number;
- type?: string;
- show?: boolean;
- pointShape?: string;
- legendShape?: string;
- formatter?: (item: any, titleText: string, index: number, opts: ChartOptions) => string;
- style?: string;
- disableLegend?: boolean;
- connectNulls?: boolean;
- [key: string]: any;
- }
- export interface ChartOptions {
- type: string;
- categories?: string[];
- extra?: ChartExtraOptions;
- xAxis?: XAxisOptions;
- yAxis?: YAxisOptions;
- area: number[];
- width: number;
- height: number;
- pix: number;
- enableScroll?: boolean;
- chartData?: ChartData;
- background?: string;
- fontColor?: string;
- _scrollDistance_?: number;
- series?: any[];
- tooltip?: any;
- dataLabel?: boolean;
- title?: any;
- subtitle?: any;
- dataPointShapeType?: string;
- legend?: any;
- [key: string]: any;
- }
- export interface ChartExtraOptions {
- bar?: BarOptions;
- column?: ColumnOptions;
- tooltip?: TooltipOptions;
- mount?: MountOptions;
- [key: string]: any;
- }
- export interface BarOptions {
- type?: string;
- [key: string]: any;
- }
- export interface ColumnOptions {
- type?: 'group' | 'stack' | 'meter';
- width?: number;
- meterBorder?: number;
- meterFillColor?: string;
- barBorderCircle?: boolean;
- barBorderRadius?: number[];
- seriesGap?: number;
- linearType?: string;
- linearOpacity?: number;
- customColor?: string[];
- colorStop?: number;
- labelPosition?: string;
- borderWidth?: number;
- widthRatio?: number;
- [key: string]: any;
- }
- export interface TooltipOptions {
- legendShape?: string;
- [key: string]: any;
- }
- export interface MountOptions {
- widthRatio?: number;
- type?: 'bar' | 'triangle' | 'mount' | 'sharp';
- [key: string]: any;
- }
- export interface XAxisOptions {
- lineHeight?: number;
- marginTop?: number;
- fontSize?: number;
- disabled?: boolean;
- rotateLabel?: boolean;
- rotateAngle?: number;
- scrollShow?: boolean;
- boundaryGap?: string;
- itemCount?: number;
- splitNumber?: number;
- formatter?: (item: any, index: number, opts: ChartOptions) => string;
- [key: string]: any;
- }
- export interface YAxisOptions {
- fontSize?: number;
- disabled?: boolean;
- data?: YAxisDataItem[];
- formatter?: (val: number, index: number, opts: ChartOptions) => string;
- tofix?: number;
- unit?: string;
- min?: number;
- max?: number;
- [key: string]: any;
- }
- export interface YAxisDataItem {
- type?: string;
- disabled?: boolean;
- formatter?: (val: any, index: number, opts: ChartOptions) => string;
- categories?: string[];
- tofix?: number;
- unit?: string;
- min?: number;
- max?: number;
- position?: string;
- calibration?: boolean;
- fontSize?: number;
- textAlign?: string;
- axisLineColor?: string;
- fontColor?: string;
- axisLine?: boolean;
- titleFontSize?: number;
- title?: string;
- titleFontColor?: string;
- titleOffsetX?: number;
- titleOffsetY?: number;
- }
- export interface ChartData {
- calPoints?: any[][];
- xAxisPoints?: number[];
- eachSpacing?: number;
- [key: string]: any;
- }
- export interface UChartsConfig {
- version: string;
- color: string[];
- linearColor: string[];
- yAxisWidth: number;
- xAxisHeight: number;
- padding: number[];
- rotate: boolean;
- fontSize: number;
- fontColor: string;
- dataPointShape: string[];
- pieChartLinePadding: number;
- pieChartTextPadding: number;
- titleFontSize: number;
- subtitleFontSize: number;
- radarLabelTextMargin: number;
- toolTipBackground?: string;
- toolTipOpacity?: number;
- _pieTextMaxLength_?: number;
- _xAxisTextAngle_?: number;
- }
- export interface DataRange {
- minRange: number;
- maxRange: number;
- }
- /**
- * 修复饼图系列数据
- * 处理饼图的百分比和累计值
- *
- * @param series - 系列数据数组
- * @param opts - 图表配置选项
- * @param config - uCharts配置对象
- * @returns 修复后的系列数据数组
- */
- export function fixPieSeries(
- series: SeriesItem[],
- opts: ChartOptions,
- config: UChartsConfig
- ): SeriesItem[] {
- const pieSeriesArr: SeriesItem[] = [];
- if (series.length > 0 && series[0].data.constructor.toString().indexOf('Array') > -1) {
- (opts as any)._pieSeries_ = series;
- const oldseries = series[0].data as any[];
- for (let i = 0; i < oldseries.length; i++) {
- oldseries[i].formatter = series[0].formatter;
- oldseries[i].data = oldseries[i].value;
- pieSeriesArr.push(oldseries[i]);
- }
- opts.series = pieSeriesArr;
- } else {
- return series;
- }
- return pieSeriesArr;
- }
- /**
- * 填充系列数据
- * 确保所有系列数据都有完整的属性配置
- *
- * @param series - 系列数据数组
- * @param opts - 图表配置选项
- * @param config - uCharts配置对象
- * @returns 填充后的系列数据数组
- */
- export function fillSeries(
- series: SeriesItem[],
- opts: ChartOptions,
- config: UChartsConfig
- ): SeriesItem[] {
- let index = 0;
- for (let i = 0; i < series.length; i++) {
- const item = series[i];
- if (!item.color) {
- item.color = config.color[index];
- index = (index + 1) % config.color.length;
- }
- if (!item.linearIndex) {
- item.linearIndex = i;
- }
- if (!item.index) {
- item.index = 0;
- }
- if (!item.type) {
- item.type = opts.type;
- }
- if (typeof item.show === "undefined") {
- item.show = true;
- }
- if (!item.type) {
- item.type = opts.type;
- }
- if (!item.pointShape) {
- item.pointShape = "circle";
- }
- if (!item.legendShape) {
- switch (item.type) {
- case 'line':
- item.legendShape = "line";
- break;
- case 'column':
- case 'bar':
- item.legendShape = "rect";
- break;
- case 'area':
- case 'mount':
- item.legendShape = "triangle";
- break;
- default:
- item.legendShape = "circle";
- }
- }
- }
- return series;
- }
- /**
- * 填充自定义颜色
- * 为系列数据设置自定义颜色或使用默认渐变色
- *
- * @param linearType - 线性类型 ('custom' 或其他)
- * @param customColor - 自定义颜色数组
- * @param series - 系列数据数组
- * @param config - uCharts配置对象
- * @returns 颜色数组
- */
- export function fillCustomColor(
- linearType: string,
- customColor: string[],
- series: SeriesItem[],
- config: UChartsConfig
- ): string[] {
- let newcolor = customColor || [];
- if (linearType == 'custom' && newcolor.length == 0) {
- newcolor = config.linearColor;
- }
- if (linearType == 'custom' && newcolor.length < series.length) {
- const chazhi = series.length - newcolor.length;
- for (let i = 0; i < chazhi; i++) {
- newcolor.push(config.linearColor[(i + 1) % config.linearColor.length]);
- }
- }
- return newcolor;
- }
- /**
- * 获取数据范围
- * 计算最小值和最大值的范围
- *
- * @param minData - 最小数据值
- * @param maxData - 最大数据值
- * @returns 数据范围对象
- */
- export function getDataRange(minData: number, maxData: number): DataRange {
- let limit = 0;
- const range = maxData - minData;
- if (range >= 10000) {
- limit = 1000;
- } else if (range >= 1000) {
- limit = 100;
- } else if (range >= 100) {
- limit = 10;
- } else if (range >= 10) {
- limit = 5;
- } else if (range >= 1) {
- limit = 1;
- } else if (range >= 0.1) {
- limit = 0.1;
- } else if (range >= 0.01) {
- limit = 0.01;
- } else if (range >= 0.001) {
- limit = 0.001;
- } else if (range >= 0.0001) {
- limit = 0.0001;
- } else if (range >= 0.00001) {
- limit = 0.00001;
- } else {
- limit = 0.000001;
- }
- return {
- minRange: findRange(minData, 'lower', limit),
- maxRange: findRange(maxData, 'upper', limit)
- };
- }
- /**
- * 查找范围边界
- * 根据类型和限制查找合适的边界值
- *
- * @param num - 数值
- * @param type - 类型 ('upper' 或 'lower')
- * @param limit - 限制值
- * @returns 边界值
- */
- function findRange(num: number, type: 'upper' | 'lower', limit: number): number {
- if (isNaN(num)) {
- throw new Error('[uCharts] series数据需为Number格式');
- }
- limit = limit || 10;
- type = type ? type : 'upper';
- let multiple = 1;
- while (limit < 1) {
- limit *= 10;
- multiple *= 10;
- }
- if (type === 'upper') {
- num = Math.ceil(num * multiple);
- } else {
- num = Math.floor(num * multiple);
- }
- while (num % limit !== 0) {
- if (type === 'upper') {
- if (num == num + 1) {
- break;
- }
- num++;
- } else {
- num--;
- }
- }
- return num / multiple;
- }
- /**
- * 数据合并
- * 合并多个系列的数据
- *
- * @param series - 系列数据数组
- * @returns 合并后的数据数组
- */
- export function dataCombine(series: SeriesItem[]): (number | null)[] {
- return series.reduce(function(a, b) {
- return (a.data ? a.data : a).concat(b.data);
- }, [] as any);
- }
- /**
- * 堆叠数据合并
- * 处理堆叠图表的数据合并
- *
- * @param series - 系列数据数组
- * @param len - 数据长度
- * @returns 合并后的数据数组
- */
- export function dataCombineStack(
- series: SeriesItem[],
- len: number
- ): (number | null)[] {
- const sum = new Array(len);
- for (let j = 0; j < sum.length; j++) {
- sum[j] = 0;
- }
- for (let i = 0; i < series.length; i++) {
- for (let j = 0; j < sum.length; j++) {
- sum[j] += (series[i].data as number[])[j];
- }
- }
- return series.reduce(function(a, b) {
- return (a.data ? a.data : a).concat(b.data).concat(sum);
- }, [] as any);
- }
|