dashBoardComponent.config.ts 7.45 KB
import { EChartsOption } from 'echarts';
import { fontSize } from '../../detail/config/util';
import { Gradient, visualOptionField } from '../../detail/config/visualOptions';
import { DataComponentRecord, DataSource, GradientInfo } from '/@/api/dataBoard/model';
import { isArray } from '/@/utils/is';
import { buildUUID } from '/@/utils/uuid';

export type InstrumentComponentType = 'instrument-component-1' | 'instrument-component-2';

export type GradientKey =
  | visualOptionField.FIRST_PHASE_COLOR
  | visualOptionField.FIRST_PHASE_VALUE
  | visualOptionField.SECOND_PHASE_COLOR
  | visualOptionField.SECOND_PHASE_VALUE
  | visualOptionField.THIRD_PHASE_COLOR
  | visualOptionField.THIRD_PHASE_VALUE;

export interface GradientInfoRecord {
  key: Gradient;
  value: number;
  color: string;
}

export interface DashBoardValue {
  id: string;
  unit?: string;
  name?: string;
  updateTime?: string;
  value?: number;
  valueColor?: string;
  gradientInfo?: GradientInfoRecord[];
}

export interface DashboardComponentLayout {
  chartOption: EChartsOption;
  componentType: InstrumentComponentType;
}

export const instrumentComponent1 = (params?: { value: number; unit: string }): EChartsOption => {
  const { value = 10, unit = '°C' } = params || {};
  return {
    series: [
      {
        type: 'gauge',
        center: ['50%', '60%'],
        startAngle: 200,
        endAngle: -20,
        min: 0,
        max: 100,
        splitNumber: 10,
        itemStyle: {
          color: '#FFAB91',
        },
        progress: {
          show: true,
          width: 30,
        },
        pointer: {
          show: false,
        },
        axisLine: {
          lineStyle: {
            width: 30,
          },
        },
        axisTick: {
          distance: -35,
          splitNumber: 5,
          lineStyle: {
            width: 2,
            color: '#999',
          },
        },
        splitLine: {
          distance: -45,
          length: 14,
          lineStyle: {
            width: 3,
            color: '#999',
          },
        },
        axisLabel: {
          distance: -5,
          color: '#999',
          // fontSize: 20,
        },
        anchor: {
          show: false,
        },
        title: {
          show: false,
        },
        detail: {
          valueAnimation: true,
          width: '60%',
          lineHeight: 30,
          borderRadius: 8,
          offsetCenter: [0, '-15%'],
          // fontSize: 16,
          fontWeight: 'bolder',
          formatter: `{value} ${unit}`,
          color: 'inherit',
        },
        data: [
          {
            value: value,
          },
        ],
      },
      {
        type: 'gauge',
        center: ['50%', '60%'],
        startAngle: 200,
        endAngle: -20,
        min: 0,
        max: 100,
        itemStyle: {
          color: '#FD7347',
        },
        progress: {
          show: true,
          width: 8,
        },
        pointer: {
          show: false,
        },
        axisLine: {
          show: false,
        },
        axisTick: {
          show: false,
        },
        splitLine: {
          show: false,
        },
        axisLabel: {
          show: false,
        },
        detail: {
          show: false,
        },
        data: [
          {
            value: value,
          },
        ],
      },
    ],
  };
};

export const instrumentComponent2 = (params?: {
  gradient: GradientInfo[];
  value: number;
  unit: string;
}): EChartsOption => {
  const { gradient = [], value = 0, unit = 'km/h' } = params || {};
  const firstRecord = getGradient(Gradient.FIRST, gradient);
  const secondRecord = getGradient(Gradient.SECOND, gradient);
  const thirdRecord = getGradient(Gradient.THIRD, gradient);

  let max = thirdRecord?.value || secondRecord?.value || firstRecord?.value || 70;
  max = Number(1 + Array(String(max).length).fill(0).join(''));

  const firstGradient = firstRecord?.value ? firstRecord.value / max : 0.3;
  const secondGradient = secondRecord?.value ? secondRecord.value / max : 0.7;
  // const thirdGradient = thirdRecord?.value ? thirdRecord.value / max : 1;

  return {
    series: [
      {
        type: 'gauge',
        min: 0,
        max,
        axisLine: {
          lineStyle: {
            width: 20,
            color: [
              [firstGradient, firstRecord?.color || '#67e0e3'],
              [secondGradient, secondRecord?.color || '#37a2da'],
              [1, thirdRecord?.color || '#fd666d'],
            ],
          },
        },
        pointer: {
          itemStyle: {
            color: 'inherit',
          },
        },
        axisTick: {
          distance: -30,
          length: 8,
          splitNumber: max / 100,
          lineStyle: {
            color: '#fff',
            width: 2,
          },
        },
        splitLine: {
          distance: -10,
          length: 30,
          lineStyle: {
            color: '#fff',
            width: 4,
          },
        },
        axisLabel: {
          color: 'inherit',
          distance: 5,
          fontSize: 6,
        },
        detail: {
          valueAnimation: true,
          formatter: `{value} ${unit}`,
          color: 'inherit',
          fontSize: 14,
        },
        data: [
          {
            value: value,
          },
        ],
      },
    ],
  };
};

export const getGradient = (key: Gradient, record: GradientInfo[] = []) => {
  if (!isArray(record)) return;
  return record.find((item) => item.key === key);
};

export const update_instrument_1_font = (radio: number) => {
  const basicFontSize = fontSize({ radio, basic: 10, max: 20 });
  return {
    series: [
      {
        axisLabel: {
          fontSize: basicFontSize,
        },
        detail: {
          fontSize: basicFontSize,
        },
      },
    ],
  } as EChartsOption;
};

export const update_instrument_2_font = (radio: number) => {
  const axisLabelFontSize = fontSize({ radio, basic: 10, max: 18 });
  return {
    series: [
      {
        axisLabel: {
          fontSize: axisLabelFontSize,
        },
        detail: {
          fontSize: axisLabelFontSize,
        },
      },
    ],
  } as EChartsOption;
};

export const update_instrument_1_value = (value) => {
  return {
    series: [
      {
        data: [{ value }],
      },
      {
        data: [{ value }],
      },
    ],
  } as EChartsOption;
};

export const update_instrument_2_value = (value) => {
  return {
    series: [
      {
        data: [{ value }],
      },
    ],
  } as EChartsOption;
};

function setGradientInfo(dataSource: DataSource) {
  const componentInfo = dataSource.componentInfo;
  return instrumentComponent2({
    unit: componentInfo.unit,
    value: 0,
    gradient: componentInfo.gradientInfo,
  });
}

export const transformDashboardComponentConfig = (
  config: DashboardComponentLayout,
  record: DataComponentRecord,
  dataSourceRecord: DataSource
) => {
  let chartOption = config.chartOption;
  if (config.componentType === 'instrument-component-2') {
    chartOption = setGradientInfo(dataSourceRecord);
  }
  return {
    layout: {
      chartOption: chartOption,
      componentType: config.componentType,
    } as DashboardComponentLayout,
    value: {
      id: buildUUID(),
      name: dataSourceRecord.attributeRename || dataSourceRecord.attribute,
      value: dataSourceRecord.componentInfo.value,
      unit: dataSourceRecord.componentInfo.unit,
      updateTime: dataSourceRecord.componentInfo.updateTime,
      fontColor: dataSourceRecord.componentInfo.fontColor,
      gradientInfo: dataSourceRecord.componentInfo.gradientInfo,
    },
  };
};