Showing
70 changed files
with
3411 additions
and
2 deletions
| 1 | +import cloneDeep from 'lodash-es/cloneDeep'; | |
| 2 | +import { LateralNumericalControlConfig } from '.'; | |
| 3 | +import { | |
| 4 | + ConfigType, | |
| 5 | + CreateComponentType, | |
| 6 | + PublicComponentOptions, | |
| 7 | + PublicPresetOptions, | |
| 8 | +} from '/@/views/visual/packages/index.type'; | |
| 9 | +import { PublicConfigClass, componentInitConfig } from '/@/views/visual/packages/publicConfig'; | |
| 10 | +import { ComponentConfigFieldEnum } from '../../../enum'; | |
| 11 | + | |
| 12 | +export const option: PublicPresetOptions = { | |
| 13 | + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, | |
| 14 | + [ComponentConfigFieldEnum.CONTROL_BAR_COLOR]: '#0072ff', | |
| 15 | + [ComponentConfigFieldEnum.FONT_COLOR]: '#000000', | |
| 16 | +}; | |
| 17 | + | |
| 18 | +export default class Config extends PublicConfigClass implements CreateComponentType { | |
| 19 | + public key: string = LateralNumericalControlConfig.key; | |
| 20 | + | |
| 21 | + public attr = { ...componentInitConfig }; | |
| 22 | + | |
| 23 | + public componentConfig: ConfigType = cloneDeep(LateralNumericalControlConfig); | |
| 24 | + | |
| 25 | + public persetOption = cloneDeep(option); | |
| 26 | + | |
| 27 | + public option: PublicComponentOptions; | |
| 28 | + | |
| 29 | + constructor(option: PublicComponentOptions) { | |
| 30 | + super(); | |
| 31 | + this.option = { ...option }; | |
| 32 | + } | |
| 33 | +} | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum'; | |
| 3 | + import { useForm, BasicForm } from '/@/components/Form'; | |
| 4 | + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 5 | + import { option } from './config'; | |
| 6 | + | |
| 7 | + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({ | |
| 8 | + schemas: [ | |
| 9 | + { | |
| 10 | + field: ComponentConfigFieldEnum.CONTROL_BAR_COLOR, | |
| 11 | + label: '控制栏背景色', | |
| 12 | + component: 'ColorPicker', | |
| 13 | + changeEvent: 'update:value', | |
| 14 | + defaultValue: option.controlBarColor, | |
| 15 | + }, | |
| 16 | + { | |
| 17 | + field: ComponentConfigFieldEnum.FONT_COLOR, | |
| 18 | + label: '数值字体颜色', | |
| 19 | + component: 'ColorPicker', | |
| 20 | + changeEvent: 'update:value', | |
| 21 | + defaultValue: option.fontColor, | |
| 22 | + }, | |
| 23 | + { | |
| 24 | + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME, | |
| 25 | + label: '显示设备名称', | |
| 26 | + component: 'Checkbox', | |
| 27 | + defaultValue: option.showDeviceName, | |
| 28 | + }, | |
| 29 | + ], | |
| 30 | + showActionButtonGroup: false, | |
| 31 | + labelWidth: 120, | |
| 32 | + baseColProps: { | |
| 33 | + span: 12, | |
| 34 | + }, | |
| 35 | + }); | |
| 36 | + | |
| 37 | + const getFormValues = () => { | |
| 38 | + return getFieldsValue(); | |
| 39 | + }; | |
| 40 | + | |
| 41 | + const setFormValues = (data: Recordable) => { | |
| 42 | + return setFieldsValue(data); | |
| 43 | + }; | |
| 44 | + | |
| 45 | + defineExpose({ | |
| 46 | + getFormValues, | |
| 47 | + setFormValues, | |
| 48 | + resetFormValues: resetFields, | |
| 49 | + } as PublicFormInstaceType); | |
| 50 | +</script> | |
| 51 | + | |
| 52 | +<template> | |
| 53 | + <BasicForm @register="register" /> | |
| 54 | +</template> | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { CreateComponentType } from '/@/views/visual/packages/index.type'; | |
| 3 | + import { BasicForm, useForm } from '/@/components/Form'; | |
| 4 | + import { | |
| 5 | + PublicComponentValueType, | |
| 6 | + PublicFormInstaceType, | |
| 7 | + } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 8 | + import { | |
| 9 | + CommonDataSourceBindValueType, | |
| 10 | + commonDataSourceSchemas, | |
| 11 | + } from '../../../config/common.config'; | |
| 12 | + import { DataSource } from '/@/views/visual/palette/types'; | |
| 13 | + | |
| 14 | + defineProps<{ | |
| 15 | + values: PublicComponentValueType; | |
| 16 | + componentConfig: CreateComponentType; | |
| 17 | + }>(); | |
| 18 | + | |
| 19 | + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({ | |
| 20 | + labelWidth: 0, | |
| 21 | + showActionButtonGroup: false, | |
| 22 | + layout: 'horizontal', | |
| 23 | + labelCol: { span: 0 }, | |
| 24 | + schemas: commonDataSourceSchemas(), | |
| 25 | + }); | |
| 26 | + | |
| 27 | + const getFormValues = () => { | |
| 28 | + let value = getFieldsValue() as CommonDataSourceBindValueType; | |
| 29 | + value = { | |
| 30 | + ...value, | |
| 31 | + customCommand: { | |
| 32 | + transportType: value.transportType, | |
| 33 | + service: value.service, | |
| 34 | + command: value.command, | |
| 35 | + commandType: value.commandType, | |
| 36 | + }, | |
| 37 | + }; | |
| 38 | + return value; | |
| 39 | + }; | |
| 40 | + | |
| 41 | + const setFormValues = (record: DataSource) => { | |
| 42 | + const { customCommand } = record; | |
| 43 | + return setFieldsValue({ | |
| 44 | + ...record, | |
| 45 | + transportType: customCommand?.transportType, | |
| 46 | + service: customCommand?.service, | |
| 47 | + command: customCommand?.command, | |
| 48 | + commandType: customCommand?.commandType, | |
| 49 | + } as unknown as Partial<CommonDataSourceBindValueType>); | |
| 50 | + }; | |
| 51 | + | |
| 52 | + defineExpose({ | |
| 53 | + getFormValues, | |
| 54 | + setFormValues, | |
| 55 | + validate, | |
| 56 | + resetFormValues: resetFields, | |
| 57 | + } as PublicFormInstaceType); | |
| 58 | +</script> | |
| 59 | + | |
| 60 | +<template> | |
| 61 | + <BasicForm @register="register" /> | |
| 62 | +</template> | ... | ... |
| 1 | +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys'; | |
| 2 | +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type'; | |
| 3 | + | |
| 4 | +const componentKeys = useComponentKeys('LateralNumericalControl'); | |
| 5 | + | |
| 6 | +export const LateralNumericalControlConfig: ConfigType = { | |
| 7 | + ...componentKeys, | |
| 8 | + title: '控制组件1', | |
| 9 | + package: PackagesCategoryEnum.CONTROL, | |
| 10 | +}; | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { ComponentPropsConfigType, DataFetchUpdateFn } from '/@/views/visual/packages/index.type'; | |
| 3 | + import { option } from './config'; | |
| 4 | + import { useDataFetch } from '/@/views/visual/packages/hook/useSocket'; | |
| 5 | + import { Slider } from 'ant-design-vue'; | |
| 6 | + import { computed, ref } from 'vue'; | |
| 7 | + import { useComponentScale } from '../../../hook/useComponentScale'; | |
| 8 | + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName'; | |
| 9 | + | |
| 10 | + const props = defineProps<{ | |
| 11 | + config: ComponentPropsConfigType<typeof option>; | |
| 12 | + }>(); | |
| 13 | + | |
| 14 | + const sliderValue = ref<number>(33); | |
| 15 | + const sMin = ref<number>(0); | |
| 16 | + const sMax = ref<number>(100); | |
| 17 | + | |
| 18 | + const getDesign = computed(() => { | |
| 19 | + const { option, persetOption } = props.config; | |
| 20 | + const { componentInfo, attribute, attributeRename } = option; | |
| 21 | + const { controlBarColor: persetControlBarColor, fonColor: persetFontColor } = | |
| 22 | + persetOption || {}; | |
| 23 | + const { controlBarColor, fontColor } = componentInfo || {}; | |
| 24 | + return { | |
| 25 | + attribute: attributeRename || attribute, | |
| 26 | + controlBarColor: controlBarColor ?? persetControlBarColor, | |
| 27 | + fontColor: fontColor ?? persetFontColor, | |
| 28 | + }; | |
| 29 | + }); | |
| 30 | + | |
| 31 | + const handleChange = async () => {}; | |
| 32 | + | |
| 33 | + const updateFn: DataFetchUpdateFn = () => { | |
| 34 | + // console.log(message, 'message', attribute, 'attribute'); | |
| 35 | + }; | |
| 36 | + | |
| 37 | + useDataFetch(props, updateFn); | |
| 38 | + const { getScale } = useComponentScale(props); | |
| 39 | +</script> | |
| 40 | + | |
| 41 | +<template> | |
| 42 | + <main class="w-full h-full flex flex-col justify-center"> | |
| 43 | + <DeviceName :config="config" class="text-center" /> | |
| 44 | + <main :style="getScale"> | |
| 45 | + <div class="flex flex-col ml-11 mr-11"> | |
| 46 | + <span | |
| 47 | + :style="{ color: getDesign.fontColor }" | |
| 48 | + class="font-bold text-xl mt-3 truncate text-center" | |
| 49 | + >{{ sliderValue }}</span | |
| 50 | + > | |
| 51 | + <Slider | |
| 52 | + :style="{ '--slider-color': getDesign.controlBarColor }" | |
| 53 | + class="no-drag" | |
| 54 | + v-model:value="sliderValue" | |
| 55 | + :min="sMin" | |
| 56 | + :max="sMax" | |
| 57 | + @change="handleChange" | |
| 58 | + /> | |
| 59 | + | |
| 60 | + <span | |
| 61 | + :style="{ color: getDesign.fontColor }" | |
| 62 | + class="mt-3 truncate font-bold text-xs text-center" | |
| 63 | + > | |
| 64 | + {{ getDesign.attribute || '设备1' }} | |
| 65 | + </span> | |
| 66 | + </div> | |
| 67 | + </main> | |
| 68 | + </main> | |
| 69 | +</template> | |
| 70 | +<style lang="less" scoped> | |
| 71 | + :deep(.ant-slider-track) { | |
| 72 | + background: var(--slider-color) !important; | |
| 73 | + } | |
| 74 | +</style> | ... | ... |
| 1 | +import cloneDeep from 'lodash-es/cloneDeep'; | |
| 2 | +import { SwitchListConfig } from '.'; | |
| 3 | +import { | |
| 4 | + ConfigType, | |
| 5 | + CreateComponentType, | |
| 6 | + PublicComponentOptions, | |
| 7 | + PublicPresetOptions, | |
| 8 | +} from '/@/views/visual/packages/index.type'; | |
| 9 | +import { PublicConfigClass, componentInitConfig } from '/@/views/visual/packages/publicConfig'; | |
| 10 | +import { ComponentConfigFieldEnum } from '../../../enum'; | |
| 11 | + | |
| 12 | +export const option: PublicPresetOptions = { | |
| 13 | + multipleDataSourceComponent: true, | |
| 14 | + [ComponentConfigFieldEnum.ICON]: 'shuiwen', | |
| 15 | + [ComponentConfigFieldEnum.ICON_COLOR]: '#377DFF', | |
| 16 | + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, | |
| 17 | +}; | |
| 18 | + | |
| 19 | +export default class Config extends PublicConfigClass implements CreateComponentType { | |
| 20 | + public key: string = SwitchListConfig.key; | |
| 21 | + | |
| 22 | + public attr = { ...componentInitConfig }; | |
| 23 | + | |
| 24 | + public componentConfig: ConfigType = cloneDeep(SwitchListConfig); | |
| 25 | + | |
| 26 | + public persetOption = cloneDeep(option); | |
| 27 | + | |
| 28 | + public option: PublicComponentOptions; | |
| 29 | + | |
| 30 | + constructor(option: PublicComponentOptions) { | |
| 31 | + super(); | |
| 32 | + this.option = { ...option }; | |
| 33 | + } | |
| 34 | +} | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum'; | |
| 3 | + import { useForm, BasicForm } from '/@/components/Form'; | |
| 4 | + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 5 | + import { option } from './config'; | |
| 6 | + | |
| 7 | + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({ | |
| 8 | + schemas: [ | |
| 9 | + { | |
| 10 | + field: ComponentConfigFieldEnum.ICON_COLOR, | |
| 11 | + label: '图标颜色', | |
| 12 | + component: 'ColorPicker', | |
| 13 | + changeEvent: 'update:value', | |
| 14 | + defaultValue: option.iconColor, | |
| 15 | + }, | |
| 16 | + { | |
| 17 | + field: ComponentConfigFieldEnum.ICON, | |
| 18 | + label: '图标', | |
| 19 | + component: 'IconDrawer', | |
| 20 | + changeEvent: 'update:value', | |
| 21 | + defaultValue: option.icon, | |
| 22 | + componentProps({ formModel }) { | |
| 23 | + const color = formModel[ComponentConfigFieldEnum.ICON_COLOR]; | |
| 24 | + return { | |
| 25 | + color, | |
| 26 | + }; | |
| 27 | + }, | |
| 28 | + }, | |
| 29 | + { | |
| 30 | + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME, | |
| 31 | + label: '显示设备名称', | |
| 32 | + component: 'Checkbox', | |
| 33 | + defaultValue: option.showDeviceName, | |
| 34 | + }, | |
| 35 | + ], | |
| 36 | + showActionButtonGroup: false, | |
| 37 | + labelWidth: 120, | |
| 38 | + baseColProps: { | |
| 39 | + span: 12, | |
| 40 | + }, | |
| 41 | + }); | |
| 42 | + | |
| 43 | + const getFormValues = () => { | |
| 44 | + return getFieldsValue(); | |
| 45 | + }; | |
| 46 | + | |
| 47 | + const setFormValues = (data: Recordable) => { | |
| 48 | + return setFieldsValue(data); | |
| 49 | + }; | |
| 50 | + | |
| 51 | + defineExpose({ | |
| 52 | + getFormValues, | |
| 53 | + setFormValues, | |
| 54 | + resetFormValues: resetFields, | |
| 55 | + } as PublicFormInstaceType); | |
| 56 | +</script> | |
| 57 | + | |
| 58 | +<template> | |
| 59 | + <BasicForm @register="register" /> | |
| 60 | +</template> | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { CreateComponentType } from '/@/views/visual/packages/index.type'; | |
| 3 | + import { BasicForm, useForm } from '/@/components/Form'; | |
| 4 | + import { | |
| 5 | + PublicComponentValueType, | |
| 6 | + PublicFormInstaceType, | |
| 7 | + } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 8 | + import { | |
| 9 | + CommonDataSourceBindValueType, | |
| 10 | + commonDataSourceSchemas, | |
| 11 | + } from '../../../config/common.config'; | |
| 12 | + import { DataSource } from '/@/views/visual/palette/types'; | |
| 13 | + | |
| 14 | + defineProps<{ | |
| 15 | + values: PublicComponentValueType; | |
| 16 | + componentConfig: CreateComponentType; | |
| 17 | + }>(); | |
| 18 | + | |
| 19 | + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({ | |
| 20 | + labelWidth: 0, | |
| 21 | + showActionButtonGroup: false, | |
| 22 | + layout: 'horizontal', | |
| 23 | + labelCol: { span: 0 }, | |
| 24 | + schemas: commonDataSourceSchemas(), | |
| 25 | + }); | |
| 26 | + | |
| 27 | + const getFormValues = () => { | |
| 28 | + let value = getFieldsValue() as CommonDataSourceBindValueType; | |
| 29 | + value = { | |
| 30 | + ...value, | |
| 31 | + customCommand: { | |
| 32 | + transportType: value.transportType, | |
| 33 | + service: value.service, | |
| 34 | + command: value.command, | |
| 35 | + commandType: value.commandType, | |
| 36 | + }, | |
| 37 | + }; | |
| 38 | + return value; | |
| 39 | + }; | |
| 40 | + | |
| 41 | + const setFormValues = (record: DataSource) => { | |
| 42 | + const { customCommand } = record; | |
| 43 | + return setFieldsValue({ | |
| 44 | + ...record, | |
| 45 | + transportType: customCommand?.transportType, | |
| 46 | + service: customCommand?.service, | |
| 47 | + command: customCommand?.command, | |
| 48 | + commandType: customCommand?.commandType, | |
| 49 | + } as unknown as Partial<CommonDataSourceBindValueType>); | |
| 50 | + }; | |
| 51 | + | |
| 52 | + defineExpose({ | |
| 53 | + getFormValues, | |
| 54 | + setFormValues, | |
| 55 | + validate, | |
| 56 | + resetFormValues: resetFields, | |
| 57 | + } as PublicFormInstaceType); | |
| 58 | +</script> | |
| 59 | + | |
| 60 | +<template> | |
| 61 | + <BasicForm @register="register" /> | |
| 62 | +</template> | ... | ... |
| 1 | +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys'; | |
| 2 | +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type'; | |
| 3 | + | |
| 4 | +const componentKeys = useComponentKeys('SwitchList'); | |
| 5 | + | |
| 6 | +export const SwitchListConfig: ConfigType = { | |
| 7 | + ...componentKeys, | |
| 8 | + title: '开关量控制列表', | |
| 9 | + package: PackagesCategoryEnum.CONTROL, | |
| 10 | +}; | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { | |
| 3 | + ComponentPropsConfigType, | |
| 4 | + MultipleDataFetchUpdateFn, | |
| 5 | + } from '/@/views/visual/packages/index.type'; | |
| 6 | + import { option } from './config'; | |
| 7 | + import { useMultipleDataFetch } from '/@/views/visual/packages/hook/useSocket'; | |
| 8 | + import { SvgIcon } from '/@/components/Icon'; | |
| 9 | + import { Switch } from 'ant-design-vue'; | |
| 10 | + import { computed, ref } from 'vue'; | |
| 11 | + import { useComponentScale } from '../../../hook/useComponentScale'; | |
| 12 | + import { useSendCommand } from '../../../hook/useSendCommand'; | |
| 13 | + import { unref } from 'vue'; | |
| 14 | + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName'; | |
| 15 | + | |
| 16 | + const props = defineProps<{ | |
| 17 | + config: ComponentPropsConfigType<typeof option>; | |
| 18 | + }>(); | |
| 19 | + | |
| 20 | + const checked = ref(false); | |
| 21 | + | |
| 22 | + const svgList = ref<any>([ | |
| 23 | + { | |
| 24 | + value: 26.2, | |
| 25 | + name: 'wendu', | |
| 26 | + icon: 'zongfushe', | |
| 27 | + unit: 'kw', | |
| 28 | + iconColor: '#367BFF', | |
| 29 | + fontColor: '#357CFB', | |
| 30 | + checked: false, | |
| 31 | + id: 0, | |
| 32 | + }, | |
| 33 | + { | |
| 34 | + value: 53.7, | |
| 35 | + name: 'shidu', | |
| 36 | + icon: 'guangzhaoqiangdu', | |
| 37 | + unit: '℃', | |
| 38 | + iconColor: '#FFA000', | |
| 39 | + fontColor: '#FFA000', | |
| 40 | + checked: true, | |
| 41 | + id: 1, | |
| 42 | + }, | |
| 43 | + ]); | |
| 44 | + | |
| 45 | + const getDesign = computed(() => { | |
| 46 | + const { persetOption = {}, option } = props.config; | |
| 47 | + const { dataSource = [] } = option || {}; | |
| 48 | + const { | |
| 49 | + unit: persetUnit, | |
| 50 | + fontColor: persetFontColor, | |
| 51 | + icon: persetIcon, | |
| 52 | + iconColor: persetIconColor, | |
| 53 | + } = persetOption || {}; | |
| 54 | + return { | |
| 55 | + dataSource: dataSource.map((item) => { | |
| 56 | + const { fontColor, icon, iconColor, unit } = item.componentInfo; | |
| 57 | + const { attribute, attributeRename } = item; | |
| 58 | + return { | |
| 59 | + unit: unit ?? persetUnit, | |
| 60 | + fontColor: fontColor ?? persetFontColor, | |
| 61 | + icon: icon ?? persetIcon, | |
| 62 | + iconColor: iconColor ?? persetIconColor, | |
| 63 | + attribute: attribute || attributeRename, | |
| 64 | + attributeRename, | |
| 65 | + }; | |
| 66 | + }), | |
| 67 | + }; | |
| 68 | + }); | |
| 69 | + | |
| 70 | + const { sendCommand, loading } = useSendCommand(); | |
| 71 | + const handleChange = async (index: number) => { | |
| 72 | + const flag = await sendCommand(props.config.option, unref(checked)); | |
| 73 | + if (!flag) svgList[index].checked = !svgList[index].checked; | |
| 74 | + }; | |
| 75 | + | |
| 76 | + const updateFn: MultipleDataFetchUpdateFn = (message) => { | |
| 77 | + const { data = {} } = message; | |
| 78 | + const { dataSource } = unref(getDesign); | |
| 79 | + svgList.value.length = 0; | |
| 80 | + svgList.value = dataSource.map((item) => { | |
| 81 | + const { icon, iconColor, unit, fontColor, attribute } = item || {}; | |
| 82 | + const [latest] = data[attribute] || []; | |
| 83 | + const [_timespan, value] = latest || []; | |
| 84 | + return { | |
| 85 | + value: Number(value), | |
| 86 | + name: attribute, | |
| 87 | + icon, | |
| 88 | + unit, | |
| 89 | + iconColor, | |
| 90 | + fontColor, | |
| 91 | + }; | |
| 92 | + }); | |
| 93 | + }; | |
| 94 | + | |
| 95 | + useMultipleDataFetch(props, updateFn); | |
| 96 | + const { getRatio } = useComponentScale(props); | |
| 97 | +</script> | |
| 98 | + | |
| 99 | +<template> | |
| 100 | + <main class="w-full h-full flex flex-col justify-evenly items-center"> | |
| 101 | + <DeviceName :config="config" /> | |
| 102 | + <div | |
| 103 | + style="width: 86%" | |
| 104 | + v-for="(item, index) in svgList" | |
| 105 | + :key="item.id" | |
| 106 | + class="flex justify-between items-center" | |
| 107 | + > | |
| 108 | + <div class="flex items-center"> | |
| 109 | + <SvgIcon | |
| 110 | + :name="item.icon!" | |
| 111 | + prefix="iconfont" | |
| 112 | + :size="getRatio ? 30 * getRatio : 30" | |
| 113 | + :style="{ color: item.iconColor }" | |
| 114 | + /> | |
| 115 | + | |
| 116 | + <div class="text-gray-500 text-lg truncate ml-6">{{ item.attribute || '温度' }}</div> | |
| 117 | + </div> | |
| 118 | + | |
| 119 | + <Switch v-model:checked="item.checked" :loading="loading" @change="handleChange(index)" /> | |
| 120 | + </div> | |
| 121 | + </main> | |
| 122 | +</template> | ... | ... |
| 1 | 1 | import { ControlComponentSlidingSwitchConfig } from './ControlComponentSlidingSwitch'; |
| 2 | 2 | import { ControlComponentSwitchWithIconConfig } from './ControlComponentSwitchWithIcon'; |
| 3 | 3 | import { ControlComponentToggleSwitchConfig } from './ControlComponentToggleSwitch'; |
| 4 | +import { LateralNumericalControlConfig } from './LateralNumericalControl'; | |
| 5 | +// import { SwitchListConfig } from './SwitchList'; | |
| 4 | 6 | |
| 5 | 7 | export const ControlList = [ |
| 6 | 8 | ControlComponentSwitchWithIconConfig, |
| 7 | 9 | ControlComponentSlidingSwitchConfig, |
| 8 | 10 | ControlComponentToggleSwitchConfig, |
| 11 | + LateralNumericalControlConfig, | |
| 12 | + // SwitchListConfig, | |
| 9 | 13 | ]; | ... | ... |
| ... | ... | @@ -32,7 +32,6 @@ |
| 32 | 32 | } = persetOption || {}; |
| 33 | 33 | const { unit, fontColor, pointerColor, gradientInfo, progressBarCircle, instrumentPanelColor } = |
| 34 | 34 | componentInfo || {}; |
| 35 | - console.log(option, 'unit'); | |
| 36 | 35 | return { |
| 37 | 36 | unit: unit ?? presetUnit, |
| 38 | 37 | fontColor: fontColor ?? presetFontColor, | ... | ... |
| 1 | +import cloneDeep from 'lodash-es/cloneDeep'; | |
| 2 | +import { StatisticsComponent1Config } from '.'; | |
| 3 | +import { | |
| 4 | + ConfigType, | |
| 5 | + CreateComponentType, | |
| 6 | + PublicComponentOptions, | |
| 7 | + PublicPresetOptions, | |
| 8 | +} from '../../../index.type'; | |
| 9 | +import { PublicConfigClass, componentInitConfig } from '../../../publicConfig'; | |
| 10 | +import { ComponentConfigFieldEnum } from '../../../enum'; | |
| 11 | + | |
| 12 | +export enum Gradient { | |
| 13 | + FIRST = 'first', | |
| 14 | + SECOND = 'second', | |
| 15 | +} | |
| 16 | +export enum GradientColor { | |
| 17 | + FIRST = '#07ffd6', | |
| 18 | + SECOND = '#5eff10', | |
| 19 | +} | |
| 20 | +export const option: PublicPresetOptions = { | |
| 21 | + multipleDataSourceComponent: true, | |
| 22 | + [ComponentConfigFieldEnum.FONT_COLOR]: '#FD7347', | |
| 23 | + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, | |
| 24 | + [ComponentConfigFieldEnum.UNIT]: '℃', | |
| 25 | +}; | |
| 26 | + | |
| 27 | +export default class Config extends PublicConfigClass implements CreateComponentType { | |
| 28 | + public key: string = StatisticsComponent1Config.key; | |
| 29 | + | |
| 30 | + public attr = { ...componentInitConfig }; | |
| 31 | + | |
| 32 | + public componentConfig: ConfigType = cloneDeep(StatisticsComponent1Config); | |
| 33 | + | |
| 34 | + public persetOption = cloneDeep(option); | |
| 35 | + | |
| 36 | + public option: PublicComponentOptions; | |
| 37 | + | |
| 38 | + constructor(option: PublicComponentOptions) { | |
| 39 | + super(); | |
| 40 | + this.option = { ...option }; | |
| 41 | + } | |
| 42 | +} | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { ComponentConfigFieldEnum } from '../../../enum'; | |
| 3 | + import { option } from './config'; | |
| 4 | + import { useForm, BasicForm } from '/@/components/Form'; | |
| 5 | + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 6 | + import { ComponentInfo } from '/@/views/visual/palette/types'; | |
| 7 | + | |
| 8 | + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({ | |
| 9 | + schemas: [ | |
| 10 | + { | |
| 11 | + field: ComponentConfigFieldEnum.FONT_COLOR, | |
| 12 | + label: '数值字体颜色', | |
| 13 | + component: 'ColorPicker', | |
| 14 | + changeEvent: 'update:value', | |
| 15 | + defaultValue: option.fontColor, | |
| 16 | + }, | |
| 17 | + { | |
| 18 | + field: ComponentConfigFieldEnum.UNIT, | |
| 19 | + label: '数值单位', | |
| 20 | + component: 'Input', | |
| 21 | + defaultValue: option.unit, | |
| 22 | + }, | |
| 23 | + { | |
| 24 | + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME, | |
| 25 | + label: '显示设备名称', | |
| 26 | + component: 'Checkbox', | |
| 27 | + defaultValue: option.showDeviceName, | |
| 28 | + }, | |
| 29 | + ], | |
| 30 | + showActionButtonGroup: false, | |
| 31 | + labelWidth: 120, | |
| 32 | + baseColProps: { | |
| 33 | + span: 12, | |
| 34 | + }, | |
| 35 | + }); | |
| 36 | + | |
| 37 | + const getFormValues = () => { | |
| 38 | + // return getFieldsValue(); | |
| 39 | + const item = getFieldsValue(); | |
| 40 | + return { | |
| 41 | + fontColor: item[ComponentConfigFieldEnum.FONT_COLOR], | |
| 42 | + unit: item[ComponentConfigFieldEnum.UNIT], | |
| 43 | + showDeviceName: item[ComponentConfigFieldEnum.SHOW_DEVICE_NAME], | |
| 44 | + } as ComponentInfo; | |
| 45 | + }; | |
| 46 | + | |
| 47 | + const setFormValues = (data: Recordable) => { | |
| 48 | + // return setFieldsValue(data); | |
| 49 | + const { unit, fontColor, showDeviceName } = data; | |
| 50 | + | |
| 51 | + const value = { | |
| 52 | + [ComponentConfigFieldEnum.UNIT]: unit, | |
| 53 | + [ComponentConfigFieldEnum.FONT_COLOR]: fontColor, | |
| 54 | + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: showDeviceName, | |
| 55 | + }; | |
| 56 | + return setFieldsValue(value); | |
| 57 | + }; | |
| 58 | + | |
| 59 | + defineExpose({ | |
| 60 | + getFormValues, | |
| 61 | + setFormValues, | |
| 62 | + resetFormValues: resetFields, | |
| 63 | + } as PublicFormInstaceType); | |
| 64 | +</script> | |
| 65 | + | |
| 66 | +<template> | |
| 67 | + <BasicForm @register="register" /> | |
| 68 | +</template> | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { commonDataSourceSchemas } from '../../../config/common.config'; | |
| 3 | + import { CreateComponentType } from '../../../index.type'; | |
| 4 | + import { BasicForm, useForm } from '/@/components/Form'; | |
| 5 | + import { | |
| 6 | + PublicComponentValueType, | |
| 7 | + PublicFormInstaceType, | |
| 8 | + } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 9 | + | |
| 10 | + defineProps<{ | |
| 11 | + values: PublicComponentValueType; | |
| 12 | + componentConfig: CreateComponentType; | |
| 13 | + }>(); | |
| 14 | + | |
| 15 | + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({ | |
| 16 | + labelWidth: 0, | |
| 17 | + showActionButtonGroup: false, | |
| 18 | + layout: 'horizontal', | |
| 19 | + labelCol: { span: 0 }, | |
| 20 | + schemas: commonDataSourceSchemas(), | |
| 21 | + }); | |
| 22 | + | |
| 23 | + const getFormValues = () => { | |
| 24 | + return getFieldsValue(); | |
| 25 | + }; | |
| 26 | + | |
| 27 | + const setFormValues = (record: Recordable) => { | |
| 28 | + return setFieldsValue(record); | |
| 29 | + }; | |
| 30 | + | |
| 31 | + defineExpose({ | |
| 32 | + getFormValues, | |
| 33 | + setFormValues, | |
| 34 | + validate, | |
| 35 | + resetFormValues: resetFields, | |
| 36 | + } as PublicFormInstaceType); | |
| 37 | +</script> | |
| 38 | + | |
| 39 | +<template> | |
| 40 | + <BasicForm @register="register" /> | |
| 41 | +</template> | ... | ... |
| 1 | +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys'; | |
| 2 | +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type'; | |
| 3 | + | |
| 4 | +const componentKeys = useComponentKeys('StatisticsComponent1'); | |
| 5 | + | |
| 6 | +export const StatisticsComponent1Config: ConfigType = { | |
| 7 | + ...componentKeys, | |
| 8 | + title: '饼图', | |
| 9 | + package: PackagesCategoryEnum.STATISTICS, | |
| 10 | +}; | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { EChartsOption, SeriesOption, ECharts, init } from 'echarts'; | |
| 3 | + import { unref, ref, onMounted, computed, nextTick } from 'vue'; | |
| 4 | + import { useMultipleDataFetch } from '../../../hook/useSocket'; | |
| 5 | + import { ComponentPropsConfigType, MultipleDataFetchUpdateFn } from '../../../index.type'; | |
| 6 | + import { option } from './config'; | |
| 7 | + import { UpdateTime } from '/@/views/visual/commonComponents/UpdateTime'; | |
| 8 | + import { useComponentScale } from '../../../hook/useComponentScale'; | |
| 9 | + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName'; | |
| 10 | + | |
| 11 | + const props = defineProps<{ | |
| 12 | + config: ComponentPropsConfigType<typeof option>; | |
| 13 | + }>(); | |
| 14 | + | |
| 15 | + const chartRefEl = ref<Nullable<HTMLDivElement>>(null); | |
| 16 | + | |
| 17 | + const chartInstance = ref<Nullable<ECharts>>(null); | |
| 18 | + | |
| 19 | + const time = ref<Nullable<number>>(null); | |
| 20 | + | |
| 21 | + const getDesign = computed(() => { | |
| 22 | + const { persetOption, option } = props.config; | |
| 23 | + const { dataSource = [] } = option || {}; | |
| 24 | + const { unit: presetUnit, fontColor: presetFontColor } = persetOption || {}; | |
| 25 | + return { | |
| 26 | + dataSource: dataSource?.map((item) => { | |
| 27 | + const { unit, fontColor } = item.componentInfo || {}; | |
| 28 | + const { attribute, attributeRename } = item; | |
| 29 | + return { | |
| 30 | + unit: unit ?? presetUnit, | |
| 31 | + fontColor: fontColor ?? presetFontColor, | |
| 32 | + attribute, | |
| 33 | + attributeRename, | |
| 34 | + }; | |
| 35 | + }), | |
| 36 | + }; | |
| 37 | + }); | |
| 38 | + | |
| 39 | + const options = (): EChartsOption => { | |
| 40 | + // getStageColor(gradientInfo); | |
| 41 | + return { | |
| 42 | + tooltip: { | |
| 43 | + trigger: 'item', | |
| 44 | + }, | |
| 45 | + legend: { | |
| 46 | + top: '5%', | |
| 47 | + left: 'center', | |
| 48 | + textStyle: { | |
| 49 | + fontSize: unref(getRatio) ? 14 * unref(getRatio) : 14, | |
| 50 | + }, | |
| 51 | + }, | |
| 52 | + series: [ | |
| 53 | + { | |
| 54 | + name: '', | |
| 55 | + type: 'pie', | |
| 56 | + radius: ['%', '70%'], | |
| 57 | + center: ['50%', '65%'], | |
| 58 | + avoidLabelOverlap: false, | |
| 59 | + itemStyle: { | |
| 60 | + borderRadius: 4, | |
| 61 | + borderColor: '#fff', | |
| 62 | + borderWidth: 2, | |
| 63 | + }, | |
| 64 | + label: { | |
| 65 | + show: false, | |
| 66 | + position: 'center', | |
| 67 | + }, | |
| 68 | + labelLine: { | |
| 69 | + show: false, | |
| 70 | + }, | |
| 71 | + data: [ | |
| 72 | + { value: 1048, name: '数据1' }, | |
| 73 | + { value: 735, name: '数据2' }, | |
| 74 | + { value: 580, name: '数据3' }, | |
| 75 | + ], | |
| 76 | + }, | |
| 77 | + ], | |
| 78 | + }; | |
| 79 | + }; | |
| 80 | + | |
| 81 | + const initial = () => { | |
| 82 | + chartInstance.value = init(unref(chartRefEl)! as HTMLElement); | |
| 83 | + chartInstance.value.setOption(options()); | |
| 84 | + }; | |
| 85 | + | |
| 86 | + // const randomFn = () => { | |
| 87 | + // useIntervalFn(() => { | |
| 88 | + // const value = (Math.random() * 100).toFixed(0); | |
| 89 | + // unref(chartInstance)?.setOption({ | |
| 90 | + // series: [{ data: [{ value }] }, { data: [{ value }] }], | |
| 91 | + // } as EChartsOption); | |
| 92 | + // }, 3000); | |
| 93 | + // }; | |
| 94 | + | |
| 95 | + const updateChart = (data: SeriesOption['data']) => { | |
| 96 | + unref(chartInstance)?.setOption({ | |
| 97 | + series: [{ data }], | |
| 98 | + // color: unref(list).map((item) => item.title.color), | |
| 99 | + } as EChartsOption); | |
| 100 | + }; | |
| 101 | + | |
| 102 | + const updateFn: MultipleDataFetchUpdateFn = (message) => { | |
| 103 | + const { data = {} } = message; | |
| 104 | + const { dataSource } = unref(getDesign); | |
| 105 | + const series = dataSource.map((item) => { | |
| 106 | + const { attribute, attributeRename, fontColor, unit } = item; | |
| 107 | + const [latest] = data[attribute] || []; | |
| 108 | + const [_timespan, value] = latest || []; | |
| 109 | + | |
| 110 | + return { | |
| 111 | + value, | |
| 112 | + name: attributeRename ?? attribute, | |
| 113 | + itemStyle: { color: fontColor }, | |
| 114 | + tooltip: { | |
| 115 | + valueFormatter(value) { | |
| 116 | + return `${value} ${unit ?? ''}`; | |
| 117 | + }, | |
| 118 | + }, | |
| 119 | + } as SeriesOption['data']; | |
| 120 | + }); | |
| 121 | + updateChart(series); | |
| 122 | + }; | |
| 123 | + | |
| 124 | + useMultipleDataFetch(props, updateFn); | |
| 125 | + | |
| 126 | + onMounted(() => { | |
| 127 | + initial(); | |
| 128 | + // !props.config.option.uuid && randomFn(); | |
| 129 | + !props.config.option.uuid; | |
| 130 | + }); | |
| 131 | + | |
| 132 | + const resize = async () => { | |
| 133 | + await nextTick(); | |
| 134 | + | |
| 135 | + // 修改echarts大小 | |
| 136 | + unref(chartInstance)?.setOption({ | |
| 137 | + legend: { | |
| 138 | + textStyle: { | |
| 139 | + fontSize: 14 * unref(getRatio), | |
| 140 | + }, | |
| 141 | + }, | |
| 142 | + } as EChartsOption); | |
| 143 | + unref(chartInstance)?.resize(); | |
| 144 | + }; | |
| 145 | + | |
| 146 | + const { getRatio } = useComponentScale(props, resize); | |
| 147 | +</script> | |
| 148 | + | |
| 149 | +<template> | |
| 150 | + <main class="w-full h-full flex flex-col justify-center items-center"> | |
| 151 | + <DeviceName :config="config" /> | |
| 152 | + <div ref="chartRefEl" class="flex-1 w-full h-full"> </div> | |
| 153 | + <UpdateTime :time="time" /> | |
| 154 | + </main> | |
| 155 | +</template> | ... | ... |
| 1 | +import cloneDeep from 'lodash-es/cloneDeep'; | |
| 2 | +import { StatisticsComponent2Config } from '.'; | |
| 3 | +import { | |
| 4 | + ConfigType, | |
| 5 | + CreateComponentType, | |
| 6 | + PublicComponentOptions, | |
| 7 | + PublicPresetOptions, | |
| 8 | +} from '../../../index.type'; | |
| 9 | +import { PublicConfigClass, componentInitConfig } from '../../../publicConfig'; | |
| 10 | +import { ComponentConfigFieldEnum } from '../../../enum'; | |
| 11 | + | |
| 12 | +export enum Gradient { | |
| 13 | + FIRST = 'first', | |
| 14 | + SECOND = 'second', | |
| 15 | +} | |
| 16 | +export enum GradientColor { | |
| 17 | + FIRST = '#07ffd6', | |
| 18 | + SECOND = '#5eff10', | |
| 19 | +} | |
| 20 | +export const option: PublicPresetOptions = { | |
| 21 | + multipleDataSourceComponent: true, | |
| 22 | + [ComponentConfigFieldEnum.FONT_COLOR]: '#FD7347', | |
| 23 | + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, | |
| 24 | + [ComponentConfigFieldEnum.UNIT]: '℃', | |
| 25 | +}; | |
| 26 | + | |
| 27 | +export default class Config extends PublicConfigClass implements CreateComponentType { | |
| 28 | + public key: string = StatisticsComponent2Config.key; | |
| 29 | + | |
| 30 | + public attr = { ...componentInitConfig }; | |
| 31 | + | |
| 32 | + public componentConfig: ConfigType = cloneDeep(StatisticsComponent2Config); | |
| 33 | + | |
| 34 | + public persetOption = cloneDeep(option); | |
| 35 | + | |
| 36 | + public option: PublicComponentOptions; | |
| 37 | + | |
| 38 | + constructor(option: PublicComponentOptions) { | |
| 39 | + super(); | |
| 40 | + this.option = { ...option }; | |
| 41 | + } | |
| 42 | +} | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { ComponentConfigFieldEnum } from '../../../enum'; | |
| 3 | + import { option } from './config'; | |
| 4 | + import { useForm, BasicForm } from '/@/components/Form'; | |
| 5 | + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 6 | + import { ComponentInfo } from '/@/views/visual/palette/types'; | |
| 7 | + | |
| 8 | + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({ | |
| 9 | + schemas: [ | |
| 10 | + { | |
| 11 | + field: ComponentConfigFieldEnum.FONT_COLOR, | |
| 12 | + label: '数值字体颜色', | |
| 13 | + component: 'ColorPicker', | |
| 14 | + changeEvent: 'update:value', | |
| 15 | + defaultValue: option.fontColor, | |
| 16 | + }, | |
| 17 | + { | |
| 18 | + field: ComponentConfigFieldEnum.UNIT, | |
| 19 | + label: '数值单位', | |
| 20 | + component: 'Input', | |
| 21 | + defaultValue: option.unit, | |
| 22 | + }, | |
| 23 | + { | |
| 24 | + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME, | |
| 25 | + label: '显示设备名称', | |
| 26 | + component: 'Checkbox', | |
| 27 | + defaultValue: option.showDeviceName, | |
| 28 | + }, | |
| 29 | + ], | |
| 30 | + showActionButtonGroup: false, | |
| 31 | + labelWidth: 120, | |
| 32 | + baseColProps: { | |
| 33 | + span: 12, | |
| 34 | + }, | |
| 35 | + }); | |
| 36 | + | |
| 37 | + const getFormValues = () => { | |
| 38 | + // return getFieldsValue(); | |
| 39 | + const item = getFieldsValue(); | |
| 40 | + return { | |
| 41 | + fontColor: item[ComponentConfigFieldEnum.FONT_COLOR], | |
| 42 | + unit: item[ComponentConfigFieldEnum.UNIT], | |
| 43 | + showDeviceName: item[ComponentConfigFieldEnum.SHOW_DEVICE_NAME], | |
| 44 | + } as ComponentInfo; | |
| 45 | + }; | |
| 46 | + | |
| 47 | + const setFormValues = (data: Recordable) => { | |
| 48 | + // return setFieldsValue(data); | |
| 49 | + const { unit, fontColor, showDeviceName } = data; | |
| 50 | + | |
| 51 | + const value = { | |
| 52 | + [ComponentConfigFieldEnum.UNIT]: unit, | |
| 53 | + [ComponentConfigFieldEnum.FONT_COLOR]: fontColor, | |
| 54 | + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: showDeviceName, | |
| 55 | + }; | |
| 56 | + return setFieldsValue(value); | |
| 57 | + }; | |
| 58 | + | |
| 59 | + defineExpose({ | |
| 60 | + getFormValues, | |
| 61 | + setFormValues, | |
| 62 | + resetFormValues: resetFields, | |
| 63 | + } as PublicFormInstaceType); | |
| 64 | +</script> | |
| 65 | + | |
| 66 | +<template> | |
| 67 | + <BasicForm @register="register" /> | |
| 68 | +</template> | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { commonDataSourceSchemas } from '../../../config/common.config'; | |
| 3 | + import { CreateComponentType } from '../../../index.type'; | |
| 4 | + import { BasicForm, useForm } from '/@/components/Form'; | |
| 5 | + import { | |
| 6 | + PublicComponentValueType, | |
| 7 | + PublicFormInstaceType, | |
| 8 | + } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 9 | + | |
| 10 | + defineProps<{ | |
| 11 | + values: PublicComponentValueType; | |
| 12 | + componentConfig: CreateComponentType; | |
| 13 | + }>(); | |
| 14 | + | |
| 15 | + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({ | |
| 16 | + labelWidth: 0, | |
| 17 | + showActionButtonGroup: false, | |
| 18 | + layout: 'horizontal', | |
| 19 | + labelCol: { span: 0 }, | |
| 20 | + schemas: commonDataSourceSchemas(), | |
| 21 | + }); | |
| 22 | + | |
| 23 | + const getFormValues = () => { | |
| 24 | + return getFieldsValue(); | |
| 25 | + }; | |
| 26 | + | |
| 27 | + const setFormValues = (record: Recordable) => { | |
| 28 | + return setFieldsValue(record); | |
| 29 | + }; | |
| 30 | + | |
| 31 | + defineExpose({ | |
| 32 | + getFormValues, | |
| 33 | + setFormValues, | |
| 34 | + validate, | |
| 35 | + resetFormValues: resetFields, | |
| 36 | + } as PublicFormInstaceType); | |
| 37 | +</script> | |
| 38 | + | |
| 39 | +<template> | |
| 40 | + <BasicForm @register="register" /> | |
| 41 | +</template> | ... | ... |
| 1 | +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys'; | |
| 2 | +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type'; | |
| 3 | + | |
| 4 | +const componentKeys = useComponentKeys('StatisticsComponent2'); | |
| 5 | + | |
| 6 | +export const StatisticsComponent2Config: ConfigType = { | |
| 7 | + ...componentKeys, | |
| 8 | + title: '半环形图', | |
| 9 | + package: PackagesCategoryEnum.STATISTICS, | |
| 10 | +}; | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { EChartsOption, SeriesOption, ECharts, init } from 'echarts'; | |
| 3 | + import { unref, ref, onMounted, computed, nextTick } from 'vue'; | |
| 4 | + import { useMultipleDataFetch } from '../../../hook/useSocket'; | |
| 5 | + import { ComponentPropsConfigType, MultipleDataFetchUpdateFn } from '../../../index.type'; | |
| 6 | + import { option } from './config'; | |
| 7 | + import { UpdateTime } from '/@/views/visual/commonComponents/UpdateTime'; | |
| 8 | + import { useComponentScale } from '../../../hook/useComponentScale'; | |
| 9 | + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName'; | |
| 10 | + | |
| 11 | + const props = defineProps<{ | |
| 12 | + config: ComponentPropsConfigType<typeof option>; | |
| 13 | + }>(); | |
| 14 | + | |
| 15 | + const chartRefEl = ref<Nullable<HTMLDivElement>>(null); | |
| 16 | + | |
| 17 | + const chartInstance = ref<Nullable<ECharts>>(null); | |
| 18 | + | |
| 19 | + const time = ref<Nullable<number>>(null); | |
| 20 | + | |
| 21 | + const getDesign = computed(() => { | |
| 22 | + const { persetOption, option } = props.config; | |
| 23 | + const { dataSource = [] } = option || {}; | |
| 24 | + const { unit: presetUnit, fontColor: presetFontColor } = persetOption || {}; | |
| 25 | + return { | |
| 26 | + dataSource: dataSource?.map((item) => { | |
| 27 | + const { unit, fontColor } = item.componentInfo || {}; | |
| 28 | + const { attribute, attributeRename } = item; | |
| 29 | + return { | |
| 30 | + unit: unit ?? presetUnit, | |
| 31 | + fontColor: fontColor ?? presetFontColor, | |
| 32 | + attribute, | |
| 33 | + attributeRename, | |
| 34 | + }; | |
| 35 | + }), | |
| 36 | + }; | |
| 37 | + }); | |
| 38 | + | |
| 39 | + const options = (): EChartsOption => { | |
| 40 | + // getStageColor(gradientInfo); | |
| 41 | + return { | |
| 42 | + tooltip: { | |
| 43 | + trigger: 'item', | |
| 44 | + }, | |
| 45 | + legend: { | |
| 46 | + top: '5%', | |
| 47 | + left: 'center', | |
| 48 | + selectedMode: false, | |
| 49 | + textStyle: { | |
| 50 | + fontSize: unref(getRatio) ? 14 * unref(getRatio) : 14, | |
| 51 | + }, | |
| 52 | + }, | |
| 53 | + series: [ | |
| 54 | + { | |
| 55 | + type: 'pie', | |
| 56 | + radius: ['40%', '70%'], | |
| 57 | + center: ['50%', '70%'], | |
| 58 | + // adjust the start angle | |
| 59 | + startAngle: 180, | |
| 60 | + label: { | |
| 61 | + show: false, | |
| 62 | + }, | |
| 63 | + itemStyle: { | |
| 64 | + borderRadius: 4, | |
| 65 | + borderColor: '#fff', | |
| 66 | + borderWidth: 2, | |
| 67 | + }, | |
| 68 | + data: [ | |
| 69 | + { value: 1048, name: '数据1' }, | |
| 70 | + { value: 735, name: '数据2' }, | |
| 71 | + { | |
| 72 | + value: 1048 + 735, | |
| 73 | + itemStyle: { | |
| 74 | + color: 'none', | |
| 75 | + decal: { | |
| 76 | + symbol: 'none', | |
| 77 | + }, | |
| 78 | + }, | |
| 79 | + label: { | |
| 80 | + show: false, | |
| 81 | + }, | |
| 82 | + }, | |
| 83 | + ], | |
| 84 | + }, | |
| 85 | + ], | |
| 86 | + }; | |
| 87 | + }; | |
| 88 | + | |
| 89 | + const initial = () => { | |
| 90 | + chartInstance.value = init(unref(chartRefEl)! as HTMLElement); | |
| 91 | + chartInstance.value.setOption(options()); | |
| 92 | + }; | |
| 93 | + | |
| 94 | + // const randomFn = () => { | |
| 95 | + // useIntervalFn(() => { | |
| 96 | + // const value = (Math.random() * 100).toFixed(0); | |
| 97 | + // unref(chartInstance)?.setOption({ | |
| 98 | + // series: [{ data: [{ value }] }, { data: [{ value }] }], | |
| 99 | + // } as EChartsOption); | |
| 100 | + // }, 3000); | |
| 101 | + // }; | |
| 102 | + | |
| 103 | + const updateChart = (data: SeriesOption['data']) => { | |
| 104 | + unref(chartInstance)?.setOption({ | |
| 105 | + series: [{ data }], | |
| 106 | + // color: unref(list).map((item) => item.title.color), | |
| 107 | + } as EChartsOption); | |
| 108 | + }; | |
| 109 | + | |
| 110 | + const updateFn: MultipleDataFetchUpdateFn = (message) => { | |
| 111 | + const { data = {} } = message; | |
| 112 | + const { dataSource } = unref(getDesign); | |
| 113 | + const series = dataSource.map((item) => { | |
| 114 | + const { attribute, attributeRename, fontColor, unit } = item; | |
| 115 | + const [latest] = data[attribute] || []; | |
| 116 | + const [_timespan, value] = latest || []; | |
| 117 | + | |
| 118 | + return { | |
| 119 | + value, | |
| 120 | + name: attributeRename ?? attribute, | |
| 121 | + itemStyle: { color: fontColor }, | |
| 122 | + tooltip: { | |
| 123 | + valueFormatter(value) { | |
| 124 | + return `${value} ${unit ?? ''}`; | |
| 125 | + }, | |
| 126 | + }, | |
| 127 | + } as SeriesOption['data']; | |
| 128 | + }); | |
| 129 | + // if (series.length > 1) { | |
| 130 | + series.push({ | |
| 131 | + value: series.reduce((total: number, current: any) => total + Number(current.value), 0), | |
| 132 | + itemStyle: { | |
| 133 | + color: 'none', | |
| 134 | + decal: { | |
| 135 | + symbol: 'none', | |
| 136 | + }, | |
| 137 | + }, | |
| 138 | + label: { | |
| 139 | + show: false, | |
| 140 | + }, | |
| 141 | + }); | |
| 142 | + // } | |
| 143 | + // console.log(message, 'message', series, 'series', sum); | |
| 144 | + updateChart(series); | |
| 145 | + }; | |
| 146 | + | |
| 147 | + useMultipleDataFetch(props, updateFn); | |
| 148 | + | |
| 149 | + onMounted(() => { | |
| 150 | + initial(); | |
| 151 | + // !props.config.option.uuid && randomFn(); | |
| 152 | + !props.config.option.uuid; | |
| 153 | + }); | |
| 154 | + | |
| 155 | + const resize = async () => { | |
| 156 | + await nextTick(); | |
| 157 | + | |
| 158 | + // 修改echarts大小 | |
| 159 | + unref(chartInstance)?.setOption({ | |
| 160 | + legend: { | |
| 161 | + textStyle: { | |
| 162 | + fontSize: 14 * unref(getRatio), | |
| 163 | + }, | |
| 164 | + }, | |
| 165 | + } as EChartsOption); | |
| 166 | + unref(chartInstance)?.resize(); | |
| 167 | + }; | |
| 168 | + | |
| 169 | + const { getRatio } = useComponentScale(props, resize); | |
| 170 | +</script> | |
| 171 | + | |
| 172 | +<template> | |
| 173 | + <main class="w-full h-full flex flex-col justify-center items-center"> | |
| 174 | + <DeviceName :config="config" /> | |
| 175 | + <div ref="chartRefEl" class="flex-1 w-full h-full"> </div> | |
| 176 | + <UpdateTime :time="time" /> | |
| 177 | + </main> | |
| 178 | +</template> | ... | ... |
| 1 | +import cloneDeep from 'lodash-es/cloneDeep'; | |
| 2 | +import { StatisticsComponent3Config } from '.'; | |
| 3 | +import { | |
| 4 | + ConfigType, | |
| 5 | + CreateComponentType, | |
| 6 | + PublicComponentOptions, | |
| 7 | + PublicPresetOptions, | |
| 8 | +} from '../../../index.type'; | |
| 9 | +import { PublicConfigClass, componentInitConfig } from '../../../publicConfig'; | |
| 10 | +import { ComponentConfigFieldEnum } from '../../../enum'; | |
| 11 | + | |
| 12 | +export enum Gradient { | |
| 13 | + FIRST = 'first', | |
| 14 | + SECOND = 'second', | |
| 15 | +} | |
| 16 | +export enum GradientColor { | |
| 17 | + FIRST = '#07ffd6', | |
| 18 | + SECOND = '#5eff10', | |
| 19 | +} | |
| 20 | +export const option: PublicPresetOptions = { | |
| 21 | + multipleDataSourceComponent: true, | |
| 22 | + [ComponentConfigFieldEnum.FONT_COLOR]: '#FD7347', | |
| 23 | + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, | |
| 24 | + [ComponentConfigFieldEnum.UNIT]: '℃', | |
| 25 | +}; | |
| 26 | + | |
| 27 | +export default class Config extends PublicConfigClass implements CreateComponentType { | |
| 28 | + public key: string = StatisticsComponent3Config.key; | |
| 29 | + | |
| 30 | + public attr = { ...componentInitConfig }; | |
| 31 | + | |
| 32 | + public componentConfig: ConfigType = cloneDeep(StatisticsComponent3Config); | |
| 33 | + | |
| 34 | + public persetOption = cloneDeep(option); | |
| 35 | + | |
| 36 | + public option: PublicComponentOptions; | |
| 37 | + | |
| 38 | + constructor(option: PublicComponentOptions) { | |
| 39 | + super(); | |
| 40 | + this.option = { ...option }; | |
| 41 | + } | |
| 42 | +} | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { ComponentConfigFieldEnum } from '../../../enum'; | |
| 3 | + import { option } from './config'; | |
| 4 | + import { useForm, BasicForm } from '/@/components/Form'; | |
| 5 | + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 6 | + import { ComponentInfo } from '/@/views/visual/palette/types'; | |
| 7 | + | |
| 8 | + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({ | |
| 9 | + schemas: [ | |
| 10 | + { | |
| 11 | + field: ComponentConfigFieldEnum.FONT_COLOR, | |
| 12 | + label: '数值字体颜色', | |
| 13 | + component: 'ColorPicker', | |
| 14 | + changeEvent: 'update:value', | |
| 15 | + defaultValue: option.fontColor, | |
| 16 | + }, | |
| 17 | + { | |
| 18 | + field: ComponentConfigFieldEnum.UNIT, | |
| 19 | + label: '数值单位', | |
| 20 | + component: 'Input', | |
| 21 | + defaultValue: option.unit, | |
| 22 | + }, | |
| 23 | + { | |
| 24 | + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME, | |
| 25 | + label: '显示设备名称', | |
| 26 | + component: 'Checkbox', | |
| 27 | + defaultValue: option.showDeviceName, | |
| 28 | + }, | |
| 29 | + ], | |
| 30 | + showActionButtonGroup: false, | |
| 31 | + labelWidth: 120, | |
| 32 | + baseColProps: { | |
| 33 | + span: 12, | |
| 34 | + }, | |
| 35 | + }); | |
| 36 | + | |
| 37 | + const getFormValues = () => { | |
| 38 | + // return getFieldsValue(); | |
| 39 | + const item = getFieldsValue(); | |
| 40 | + return { | |
| 41 | + fontColor: item[ComponentConfigFieldEnum.FONT_COLOR], | |
| 42 | + unit: item[ComponentConfigFieldEnum.UNIT], | |
| 43 | + showDeviceName: item[ComponentConfigFieldEnum.SHOW_DEVICE_NAME], | |
| 44 | + } as ComponentInfo; | |
| 45 | + }; | |
| 46 | + | |
| 47 | + const setFormValues = (data: Recordable) => { | |
| 48 | + // return setFieldsValue(data); | |
| 49 | + const { unit, fontColor, showDeviceName } = data; | |
| 50 | + | |
| 51 | + const value = { | |
| 52 | + [ComponentConfigFieldEnum.UNIT]: unit, | |
| 53 | + [ComponentConfigFieldEnum.FONT_COLOR]: fontColor, | |
| 54 | + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: showDeviceName, | |
| 55 | + }; | |
| 56 | + return setFieldsValue(value); | |
| 57 | + }; | |
| 58 | + | |
| 59 | + defineExpose({ | |
| 60 | + getFormValues, | |
| 61 | + setFormValues, | |
| 62 | + resetFormValues: resetFields, | |
| 63 | + } as PublicFormInstaceType); | |
| 64 | +</script> | |
| 65 | + | |
| 66 | +<template> | |
| 67 | + <BasicForm @register="register" /> | |
| 68 | +</template> | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { commonDataSourceSchemas } from '../../../config/common.config'; | |
| 3 | + import { CreateComponentType } from '../../../index.type'; | |
| 4 | + import { BasicForm, useForm } from '/@/components/Form'; | |
| 5 | + import { | |
| 6 | + PublicComponentValueType, | |
| 7 | + PublicFormInstaceType, | |
| 8 | + } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 9 | + | |
| 10 | + defineProps<{ | |
| 11 | + values: PublicComponentValueType; | |
| 12 | + componentConfig: CreateComponentType; | |
| 13 | + }>(); | |
| 14 | + | |
| 15 | + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({ | |
| 16 | + labelWidth: 0, | |
| 17 | + showActionButtonGroup: false, | |
| 18 | + layout: 'horizontal', | |
| 19 | + labelCol: { span: 0 }, | |
| 20 | + schemas: commonDataSourceSchemas(), | |
| 21 | + }); | |
| 22 | + | |
| 23 | + const getFormValues = () => { | |
| 24 | + return getFieldsValue(); | |
| 25 | + }; | |
| 26 | + | |
| 27 | + const setFormValues = (record: Recordable) => { | |
| 28 | + return setFieldsValue(record); | |
| 29 | + }; | |
| 30 | + | |
| 31 | + defineExpose({ | |
| 32 | + getFormValues, | |
| 33 | + setFormValues, | |
| 34 | + validate, | |
| 35 | + resetFormValues: resetFields, | |
| 36 | + } as PublicFormInstaceType); | |
| 37 | +</script> | |
| 38 | + | |
| 39 | +<template> | |
| 40 | + <BasicForm @register="register" /> | |
| 41 | +</template> | ... | ... |
| 1 | +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys'; | |
| 2 | +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type'; | |
| 3 | + | |
| 4 | +const componentKeys = useComponentKeys('StatisticsComponent3'); | |
| 5 | + | |
| 6 | +export const StatisticsComponent3Config: ConfigType = { | |
| 7 | + ...componentKeys, | |
| 8 | + title: '横柱状图', | |
| 9 | + package: PackagesCategoryEnum.STATISTICS, | |
| 10 | +}; | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { EChartsOption, SeriesOption, ECharts, init } from 'echarts'; | |
| 3 | + import { unref, ref, onMounted, computed, nextTick } from 'vue'; | |
| 4 | + import { useMultipleDataFetch } from '../../../hook/useSocket'; | |
| 5 | + import { ComponentPropsConfigType, MultipleDataFetchUpdateFn } from '../../../index.type'; | |
| 6 | + import { option } from './config'; | |
| 7 | + import { UpdateTime } from '/@/views/visual/commonComponents/UpdateTime'; | |
| 8 | + import { useComponentScale } from '../../../hook/useComponentScale'; | |
| 9 | + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName'; | |
| 10 | + | |
| 11 | + const props = defineProps<{ | |
| 12 | + config: ComponentPropsConfigType<typeof option>; | |
| 13 | + }>(); | |
| 14 | + | |
| 15 | + const chartRefEl = ref<Nullable<HTMLDivElement>>(null); | |
| 16 | + | |
| 17 | + const chartInstance = ref<Nullable<ECharts>>(null); | |
| 18 | + | |
| 19 | + const time = ref<Nullable<number>>(null); | |
| 20 | + | |
| 21 | + const getDesign = computed(() => { | |
| 22 | + const { persetOption, option } = props.config; | |
| 23 | + const { dataSource = [] } = option || {}; | |
| 24 | + const { unit: presetUnit, fontColor: presetFontColor } = persetOption || {}; | |
| 25 | + return { | |
| 26 | + dataSource: dataSource?.map((item) => { | |
| 27 | + const { unit, fontColor } = item.componentInfo || {}; | |
| 28 | + const { attribute, attributeRename } = item; | |
| 29 | + return { | |
| 30 | + unit: unit ?? presetUnit, | |
| 31 | + fontColor: fontColor ?? presetFontColor, | |
| 32 | + attribute, | |
| 33 | + attributeRename, | |
| 34 | + }; | |
| 35 | + }), | |
| 36 | + }; | |
| 37 | + }); | |
| 38 | + const seriesList = [ | |
| 39 | + { value: 120, name: '123', itemStyle: { color: '#02E5F0' } }, | |
| 40 | + { value: 150, name: '456', itemStyle: { color: '#028CF0' } }, | |
| 41 | + { value: 40, name: '789', itemStyle: { color: '#F09202' } }, | |
| 42 | + ]; | |
| 43 | + const data = ['温度', '湿度', '温度1']; | |
| 44 | + const options = (): EChartsOption => { | |
| 45 | + // getStageColor(gradientInfo); | |
| 46 | + return { | |
| 47 | + color: ['#3398DB'], | |
| 48 | + tooltip: { | |
| 49 | + // 提示框 | |
| 50 | + trigger: 'axis', | |
| 51 | + axisPointer: { | |
| 52 | + type: 'shadow', | |
| 53 | + }, | |
| 54 | + }, | |
| 55 | + xAxis: { | |
| 56 | + type: 'category', | |
| 57 | + data: data, | |
| 58 | + axisTick: { | |
| 59 | + alignWithLabel: true, | |
| 60 | + }, | |
| 61 | + axisPointer: { | |
| 62 | + type: 'line', | |
| 63 | + }, | |
| 64 | + }, | |
| 65 | + grid: { | |
| 66 | + top: '15%', | |
| 67 | + left: '20%', | |
| 68 | + bottom: '15%', | |
| 69 | + }, | |
| 70 | + yAxis: { | |
| 71 | + type: 'value', | |
| 72 | + }, | |
| 73 | + series: [ | |
| 74 | + { | |
| 75 | + name: '', | |
| 76 | + type: 'bar', | |
| 77 | + barWidth: '60%', | |
| 78 | + data: seriesList, | |
| 79 | + }, | |
| 80 | + ], | |
| 81 | + }; | |
| 82 | + }; | |
| 83 | + | |
| 84 | + const initial = () => { | |
| 85 | + chartInstance.value = init(unref(chartRefEl)! as HTMLElement); | |
| 86 | + chartInstance.value.setOption(options()); | |
| 87 | + }; | |
| 88 | + | |
| 89 | + // const randomFn = () => { | |
| 90 | + // useIntervalFn(() => { | |
| 91 | + // const value = (Math.random() * 100).toFixed(0); | |
| 92 | + // unref(chartInstance)?.setOption({ | |
| 93 | + // series: [{ data: [{ value }] }, { data: [{ value }] }], | |
| 94 | + // } as EChartsOption); | |
| 95 | + // }, 3000); | |
| 96 | + // }; | |
| 97 | + | |
| 98 | + const updateChart = (data: SeriesOption['data'], xAxisData) => { | |
| 99 | + unref(chartInstance)?.setOption({ | |
| 100 | + series: [{ data }], | |
| 101 | + xAxis: { data: xAxisData }, | |
| 102 | + // color: unref(list).map((item) => item.title.color), | |
| 103 | + } as EChartsOption); | |
| 104 | + }; | |
| 105 | + | |
| 106 | + const updateFn: MultipleDataFetchUpdateFn = (message) => { | |
| 107 | + const { data = {} } = message; | |
| 108 | + const { dataSource } = unref(getDesign); | |
| 109 | + const series = dataSource.map((item) => { | |
| 110 | + const { attribute, attributeRename, fontColor, unit } = item; | |
| 111 | + const [latest] = data[attribute] || []; | |
| 112 | + const [_timespan, value] = latest || []; | |
| 113 | + | |
| 114 | + return { | |
| 115 | + value, | |
| 116 | + name: attributeRename ?? attribute, | |
| 117 | + itemStyle: { color: fontColor }, | |
| 118 | + tooltip: { | |
| 119 | + valueFormatter(value) { | |
| 120 | + return `${value} ${unit ?? ''}`; | |
| 121 | + }, | |
| 122 | + }, | |
| 123 | + } as SeriesOption['data']; | |
| 124 | + }); | |
| 125 | + const xAxisData = series.map((item) => { | |
| 126 | + const { name } = item as any; | |
| 127 | + return name; | |
| 128 | + }); | |
| 129 | + // } | |
| 130 | + // console.log(message, 'message', series, 'series', sum); | |
| 131 | + updateChart(series, xAxisData); | |
| 132 | + }; | |
| 133 | + | |
| 134 | + useMultipleDataFetch(props, updateFn); | |
| 135 | + | |
| 136 | + onMounted(() => { | |
| 137 | + initial(); | |
| 138 | + // !props.config.option.uuid && randomFn(); | |
| 139 | + !props.config.option.uuid; | |
| 140 | + }); | |
| 141 | + | |
| 142 | + const resize = async () => { | |
| 143 | + await nextTick(); | |
| 144 | + | |
| 145 | + // 修改echarts大小 | |
| 146 | + unref(chartInstance)?.setOption({ | |
| 147 | + legend: { | |
| 148 | + textStyle: { | |
| 149 | + fontSize: 14 * unref(getRatio), | |
| 150 | + }, | |
| 151 | + }, | |
| 152 | + } as EChartsOption); | |
| 153 | + unref(chartInstance)?.resize(); | |
| 154 | + }; | |
| 155 | + | |
| 156 | + const { getRatio } = useComponentScale(props, resize); | |
| 157 | +</script> | |
| 158 | + | |
| 159 | +<template> | |
| 160 | + <main class="w-full h-full flex flex-col justify-center items-center"> | |
| 161 | + <DeviceName :config="config" /> | |
| 162 | + <div ref="chartRefEl" class="flex-1 w-full h-full"> </div> | |
| 163 | + <UpdateTime :time="time" /> | |
| 164 | + </main> | |
| 165 | +</template> | ... | ... |
| 1 | +import cloneDeep from 'lodash-es/cloneDeep'; | |
| 2 | +import { StatisticsComponent4Config } from '.'; | |
| 3 | +import { | |
| 4 | + ConfigType, | |
| 5 | + CreateComponentType, | |
| 6 | + PublicComponentOptions, | |
| 7 | + PublicPresetOptions, | |
| 8 | +} from '../../../index.type'; | |
| 9 | +import { PublicConfigClass, componentInitConfig } from '../../../publicConfig'; | |
| 10 | +import { ComponentConfigFieldEnum } from '../../../enum'; | |
| 11 | + | |
| 12 | +export enum Gradient { | |
| 13 | + FIRST = 'first', | |
| 14 | + SECOND = 'second', | |
| 15 | +} | |
| 16 | +export enum GradientColor { | |
| 17 | + FIRST = '#07ffd6', | |
| 18 | + SECOND = '#5eff10', | |
| 19 | +} | |
| 20 | +export const option: PublicPresetOptions = { | |
| 21 | + multipleDataSourceComponent: true, | |
| 22 | + [ComponentConfigFieldEnum.FONT_COLOR]: '#FD7347', | |
| 23 | + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, | |
| 24 | + [ComponentConfigFieldEnum.UNIT]: '℃', | |
| 25 | +}; | |
| 26 | + | |
| 27 | +export default class Config extends PublicConfigClass implements CreateComponentType { | |
| 28 | + public key: string = StatisticsComponent4Config.key; | |
| 29 | + | |
| 30 | + public attr = { ...componentInitConfig }; | |
| 31 | + | |
| 32 | + public componentConfig: ConfigType = cloneDeep(StatisticsComponent4Config); | |
| 33 | + | |
| 34 | + public persetOption = cloneDeep(option); | |
| 35 | + | |
| 36 | + public option: PublicComponentOptions; | |
| 37 | + | |
| 38 | + constructor(option: PublicComponentOptions) { | |
| 39 | + super(); | |
| 40 | + this.option = { ...option }; | |
| 41 | + } | |
| 42 | +} | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { ComponentConfigFieldEnum } from '../../../enum'; | |
| 3 | + import { option } from './config'; | |
| 4 | + import { useForm, BasicForm } from '/@/components/Form'; | |
| 5 | + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 6 | + import { ComponentInfo } from '/@/views/visual/palette/types'; | |
| 7 | + | |
| 8 | + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({ | |
| 9 | + schemas: [ | |
| 10 | + { | |
| 11 | + field: ComponentConfigFieldEnum.FONT_COLOR, | |
| 12 | + label: '数值字体颜色', | |
| 13 | + component: 'ColorPicker', | |
| 14 | + changeEvent: 'update:value', | |
| 15 | + defaultValue: option.fontColor, | |
| 16 | + }, | |
| 17 | + { | |
| 18 | + field: ComponentConfigFieldEnum.UNIT, | |
| 19 | + label: '数值单位', | |
| 20 | + component: 'Input', | |
| 21 | + defaultValue: option.unit, | |
| 22 | + }, | |
| 23 | + { | |
| 24 | + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME, | |
| 25 | + label: '显示设备名称', | |
| 26 | + component: 'Checkbox', | |
| 27 | + defaultValue: option.showDeviceName, | |
| 28 | + }, | |
| 29 | + ], | |
| 30 | + showActionButtonGroup: false, | |
| 31 | + labelWidth: 120, | |
| 32 | + baseColProps: { | |
| 33 | + span: 12, | |
| 34 | + }, | |
| 35 | + }); | |
| 36 | + | |
| 37 | + const getFormValues = () => { | |
| 38 | + // return getFieldsValue(); | |
| 39 | + const item = getFieldsValue(); | |
| 40 | + return { | |
| 41 | + fontColor: item[ComponentConfigFieldEnum.FONT_COLOR], | |
| 42 | + unit: item[ComponentConfigFieldEnum.UNIT], | |
| 43 | + showDeviceName: item[ComponentConfigFieldEnum.SHOW_DEVICE_NAME], | |
| 44 | + } as ComponentInfo; | |
| 45 | + }; | |
| 46 | + | |
| 47 | + const setFormValues = (data: Recordable) => { | |
| 48 | + // return setFieldsValue(data); | |
| 49 | + const { unit, fontColor, showDeviceName } = data; | |
| 50 | + | |
| 51 | + const value = { | |
| 52 | + [ComponentConfigFieldEnum.UNIT]: unit, | |
| 53 | + [ComponentConfigFieldEnum.FONT_COLOR]: fontColor, | |
| 54 | + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: showDeviceName, | |
| 55 | + }; | |
| 56 | + return setFieldsValue(value); | |
| 57 | + }; | |
| 58 | + | |
| 59 | + defineExpose({ | |
| 60 | + getFormValues, | |
| 61 | + setFormValues, | |
| 62 | + resetFormValues: resetFields, | |
| 63 | + } as PublicFormInstaceType); | |
| 64 | +</script> | |
| 65 | + | |
| 66 | +<template> | |
| 67 | + <BasicForm @register="register" /> | |
| 68 | +</template> | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { commonDataSourceSchemas } from '../../../config/common.config'; | |
| 3 | + import { CreateComponentType } from '../../../index.type'; | |
| 4 | + import { BasicForm, useForm } from '/@/components/Form'; | |
| 5 | + import { | |
| 6 | + PublicComponentValueType, | |
| 7 | + PublicFormInstaceType, | |
| 8 | + } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 9 | + | |
| 10 | + defineProps<{ | |
| 11 | + values: PublicComponentValueType; | |
| 12 | + componentConfig: CreateComponentType; | |
| 13 | + }>(); | |
| 14 | + | |
| 15 | + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({ | |
| 16 | + labelWidth: 0, | |
| 17 | + showActionButtonGroup: false, | |
| 18 | + layout: 'horizontal', | |
| 19 | + labelCol: { span: 0 }, | |
| 20 | + schemas: commonDataSourceSchemas(), | |
| 21 | + }); | |
| 22 | + | |
| 23 | + const getFormValues = () => { | |
| 24 | + return getFieldsValue(); | |
| 25 | + }; | |
| 26 | + | |
| 27 | + const setFormValues = (record: Recordable) => { | |
| 28 | + return setFieldsValue(record); | |
| 29 | + }; | |
| 30 | + | |
| 31 | + defineExpose({ | |
| 32 | + getFormValues, | |
| 33 | + setFormValues, | |
| 34 | + validate, | |
| 35 | + resetFormValues: resetFields, | |
| 36 | + } as PublicFormInstaceType); | |
| 37 | +</script> | |
| 38 | + | |
| 39 | +<template> | |
| 40 | + <BasicForm @register="register" /> | |
| 41 | +</template> | ... | ... |
| 1 | +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys'; | |
| 2 | +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type'; | |
| 3 | + | |
| 4 | +const componentKeys = useComponentKeys('StatisticsComponent4'); | |
| 5 | + | |
| 6 | +export const StatisticsComponent4Config: ConfigType = { | |
| 7 | + ...componentKeys, | |
| 8 | + title: '竖柱状图', | |
| 9 | + package: PackagesCategoryEnum.STATISTICS, | |
| 10 | +}; | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { EChartsOption, SeriesOption, ECharts, init } from 'echarts'; | |
| 3 | + import { unref, ref, onMounted, computed, nextTick } from 'vue'; | |
| 4 | + import { useMultipleDataFetch } from '../../../hook/useSocket'; | |
| 5 | + import { ComponentPropsConfigType, MultipleDataFetchUpdateFn } from '../../../index.type'; | |
| 6 | + import { option } from './config'; | |
| 7 | + import { UpdateTime } from '/@/views/visual/commonComponents/UpdateTime'; | |
| 8 | + import { useComponentScale } from '../../../hook/useComponentScale'; | |
| 9 | + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName'; | |
| 10 | + | |
| 11 | + const props = defineProps<{ | |
| 12 | + config: ComponentPropsConfigType<typeof option>; | |
| 13 | + }>(); | |
| 14 | + | |
| 15 | + const chartRefEl = ref<Nullable<HTMLDivElement>>(null); | |
| 16 | + | |
| 17 | + const chartInstance = ref<Nullable<ECharts>>(null); | |
| 18 | + | |
| 19 | + const time = ref<Nullable<number>>(null); | |
| 20 | + | |
| 21 | + const getDesign = computed(() => { | |
| 22 | + const { persetOption, option } = props.config; | |
| 23 | + const { dataSource = [] } = option || {}; | |
| 24 | + const { unit: presetUnit, fontColor: presetFontColor } = persetOption || {}; | |
| 25 | + return { | |
| 26 | + dataSource: dataSource?.map((item) => { | |
| 27 | + const { unit, fontColor } = item.componentInfo || {}; | |
| 28 | + const { attribute, attributeRename } = item; | |
| 29 | + return { | |
| 30 | + unit: unit ?? presetUnit, | |
| 31 | + fontColor: fontColor ?? presetFontColor, | |
| 32 | + attribute, | |
| 33 | + attributeRename, | |
| 34 | + }; | |
| 35 | + }), | |
| 36 | + }; | |
| 37 | + }); | |
| 38 | + const seriesList = [ | |
| 39 | + { value: 120, name: '123', itemStyle: { color: '#02E5F0' } }, | |
| 40 | + { value: 150, name: '456', itemStyle: { color: '#028CF0' } }, | |
| 41 | + { value: 40, name: '789', itemStyle: { color: '#F09202' } }, | |
| 42 | + ]; | |
| 43 | + const data = ['温度', '湿度', '温度1']; | |
| 44 | + const options = (): EChartsOption => { | |
| 45 | + // getStageColor(gradientInfo); | |
| 46 | + return { | |
| 47 | + color: ['#3398DB'], | |
| 48 | + tooltip: { | |
| 49 | + // 提示框 | |
| 50 | + trigger: 'axis', | |
| 51 | + axisPointer: { | |
| 52 | + type: 'shadow', | |
| 53 | + }, | |
| 54 | + }, | |
| 55 | + xAxis: { | |
| 56 | + type: 'value', | |
| 57 | + }, | |
| 58 | + yAxis: { | |
| 59 | + type: 'category', | |
| 60 | + data: data, | |
| 61 | + axisTick: { | |
| 62 | + alignWithLabel: true, | |
| 63 | + }, | |
| 64 | + axisPointer: { | |
| 65 | + type: 'line', | |
| 66 | + }, | |
| 67 | + }, | |
| 68 | + grid: { | |
| 69 | + top: '15%', | |
| 70 | + left: '28%', | |
| 71 | + bottom: '15%', | |
| 72 | + }, | |
| 73 | + series: [ | |
| 74 | + { | |
| 75 | + name: '', | |
| 76 | + type: 'bar', | |
| 77 | + barWidth: '60%', | |
| 78 | + data: seriesList, | |
| 79 | + }, | |
| 80 | + ], | |
| 81 | + }; | |
| 82 | + }; | |
| 83 | + | |
| 84 | + const initial = () => { | |
| 85 | + chartInstance.value = init(unref(chartRefEl)! as HTMLElement); | |
| 86 | + chartInstance.value.setOption(options()); | |
| 87 | + }; | |
| 88 | + | |
| 89 | + // const randomFn = () => { | |
| 90 | + // useIntervalFn(() => { | |
| 91 | + // const value = (Math.random() * 100).toFixed(0); | |
| 92 | + // unref(chartInstance)?.setOption({ | |
| 93 | + // series: [{ data: [{ value }] }, { data: [{ value }] }], | |
| 94 | + // } as EChartsOption); | |
| 95 | + // }, 3000); | |
| 96 | + // }; | |
| 97 | + | |
| 98 | + const updateChart = (data: SeriesOption['data'], yAxisData) => { | |
| 99 | + unref(chartInstance)?.setOption({ | |
| 100 | + series: [{ data }], | |
| 101 | + yAxis: { data: yAxisData }, | |
| 102 | + // color: unref(list).map((item) => item.title.color), | |
| 103 | + } as EChartsOption); | |
| 104 | + }; | |
| 105 | + | |
| 106 | + const updateFn: MultipleDataFetchUpdateFn = (message) => { | |
| 107 | + const { data = {} } = message; | |
| 108 | + const { dataSource } = unref(getDesign); | |
| 109 | + const series = dataSource.map((item) => { | |
| 110 | + const { attribute, attributeRename, fontColor, unit } = item; | |
| 111 | + const [latest] = data[attribute] || []; | |
| 112 | + const [_timespan, value] = latest || []; | |
| 113 | + | |
| 114 | + return { | |
| 115 | + value, | |
| 116 | + name: attributeRename ?? attribute, | |
| 117 | + itemStyle: { color: fontColor }, | |
| 118 | + tooltip: { | |
| 119 | + valueFormatter(value) { | |
| 120 | + return `${value} ${unit ?? ''}`; | |
| 121 | + }, | |
| 122 | + }, | |
| 123 | + } as SeriesOption['data']; | |
| 124 | + }); | |
| 125 | + const yAxisData = series.map((item) => { | |
| 126 | + const { name } = item as any; | |
| 127 | + return name; | |
| 128 | + }); | |
| 129 | + // } | |
| 130 | + // console.log(message, 'message', series, 'series', sum); | |
| 131 | + updateChart(series, yAxisData); | |
| 132 | + }; | |
| 133 | + | |
| 134 | + useMultipleDataFetch(props, updateFn); | |
| 135 | + | |
| 136 | + onMounted(() => { | |
| 137 | + initial(); | |
| 138 | + // !props.config.option.uuid && randomFn(); | |
| 139 | + !props.config.option.uuid; | |
| 140 | + }); | |
| 141 | + | |
| 142 | + const resize = async () => { | |
| 143 | + await nextTick(); | |
| 144 | + | |
| 145 | + // 修改echarts大小 | |
| 146 | + unref(chartInstance)?.setOption({ | |
| 147 | + legend: { | |
| 148 | + textStyle: { | |
| 149 | + fontSize: 14 * unref(getRatio), | |
| 150 | + }, | |
| 151 | + }, | |
| 152 | + } as EChartsOption); | |
| 153 | + unref(chartInstance)?.resize(); | |
| 154 | + }; | |
| 155 | + | |
| 156 | + const { getRatio } = useComponentScale(props, resize); | |
| 157 | +</script> | |
| 158 | + | |
| 159 | +<template> | |
| 160 | + <main class="w-full h-full flex flex-col justify-center items-center"> | |
| 161 | + <DeviceName :config="config" /> | |
| 162 | + <div ref="chartRefEl" class="flex-1 w-full h-full"> </div> | |
| 163 | + <UpdateTime :time="time" /> | |
| 164 | + </main> | |
| 165 | +</template> | ... | ... |
| 1 | +import cloneDeep from 'lodash-es/cloneDeep'; | |
| 2 | +import { StatisticsComponent5Config } from '.'; | |
| 3 | +import { | |
| 4 | + ConfigType, | |
| 5 | + CreateComponentType, | |
| 6 | + PublicComponentOptions, | |
| 7 | + PublicPresetOptions, | |
| 8 | +} from '../../../index.type'; | |
| 9 | +import { PublicConfigClass, componentInitConfig } from '../../../publicConfig'; | |
| 10 | +import { ComponentConfigFieldEnum } from '../../../enum'; | |
| 11 | + | |
| 12 | +export enum Gradient { | |
| 13 | + FIRST = 'first', | |
| 14 | + SECOND = 'second', | |
| 15 | +} | |
| 16 | +export enum GradientColor { | |
| 17 | + FIRST = '#07ffd6', | |
| 18 | + SECOND = '#5eff10', | |
| 19 | +} | |
| 20 | +export const option: PublicPresetOptions = { | |
| 21 | + multipleDataSourceComponent: true, | |
| 22 | + [ComponentConfigFieldEnum.FONT_COLOR]: '#FD7347', | |
| 23 | + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, | |
| 24 | + [ComponentConfigFieldEnum.UNIT]: '℃', | |
| 25 | +}; | |
| 26 | + | |
| 27 | +export default class Config extends PublicConfigClass implements CreateComponentType { | |
| 28 | + public key: string = StatisticsComponent5Config.key; | |
| 29 | + | |
| 30 | + public attr = { ...componentInitConfig }; | |
| 31 | + | |
| 32 | + public componentConfig: ConfigType = cloneDeep(StatisticsComponent5Config); | |
| 33 | + | |
| 34 | + public persetOption = cloneDeep(option); | |
| 35 | + | |
| 36 | + public option: PublicComponentOptions; | |
| 37 | + | |
| 38 | + constructor(option: PublicComponentOptions) { | |
| 39 | + super(); | |
| 40 | + this.option = { ...option }; | |
| 41 | + } | |
| 42 | +} | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { ComponentConfigFieldEnum } from '../../../enum'; | |
| 3 | + import { option } from './config'; | |
| 4 | + import { useForm, BasicForm } from '/@/components/Form'; | |
| 5 | + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 6 | + import { ComponentInfo } from '/@/views/visual/palette/types'; | |
| 7 | + | |
| 8 | + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({ | |
| 9 | + schemas: [ | |
| 10 | + { | |
| 11 | + field: ComponentConfigFieldEnum.FONT_COLOR, | |
| 12 | + label: '数值字体颜色', | |
| 13 | + component: 'ColorPicker', | |
| 14 | + changeEvent: 'update:value', | |
| 15 | + defaultValue: option.fontColor, | |
| 16 | + }, | |
| 17 | + { | |
| 18 | + field: ComponentConfigFieldEnum.UNIT, | |
| 19 | + label: '数值单位', | |
| 20 | + component: 'Input', | |
| 21 | + defaultValue: option.unit, | |
| 22 | + }, | |
| 23 | + { | |
| 24 | + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME, | |
| 25 | + label: '显示设备名称', | |
| 26 | + component: 'Checkbox', | |
| 27 | + defaultValue: option.showDeviceName, | |
| 28 | + }, | |
| 29 | + ], | |
| 30 | + showActionButtonGroup: false, | |
| 31 | + labelWidth: 120, | |
| 32 | + baseColProps: { | |
| 33 | + span: 12, | |
| 34 | + }, | |
| 35 | + }); | |
| 36 | + | |
| 37 | + const getFormValues = () => { | |
| 38 | + // return getFieldsValue(); | |
| 39 | + const item = getFieldsValue(); | |
| 40 | + return { | |
| 41 | + fontColor: item[ComponentConfigFieldEnum.FONT_COLOR], | |
| 42 | + unit: item[ComponentConfigFieldEnum.UNIT], | |
| 43 | + showDeviceName: item[ComponentConfigFieldEnum.SHOW_DEVICE_NAME], | |
| 44 | + } as ComponentInfo; | |
| 45 | + }; | |
| 46 | + | |
| 47 | + const setFormValues = (data: Recordable) => { | |
| 48 | + // return setFieldsValue(data); | |
| 49 | + const { unit, fontColor, showDeviceName } = data; | |
| 50 | + | |
| 51 | + const value = { | |
| 52 | + [ComponentConfigFieldEnum.UNIT]: unit, | |
| 53 | + [ComponentConfigFieldEnum.FONT_COLOR]: fontColor, | |
| 54 | + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: showDeviceName, | |
| 55 | + }; | |
| 56 | + return setFieldsValue(value); | |
| 57 | + }; | |
| 58 | + | |
| 59 | + defineExpose({ | |
| 60 | + getFormValues, | |
| 61 | + setFormValues, | |
| 62 | + resetFormValues: resetFields, | |
| 63 | + } as PublicFormInstaceType); | |
| 64 | +</script> | |
| 65 | + | |
| 66 | +<template> | |
| 67 | + <BasicForm @register="register" /> | |
| 68 | +</template> | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { commonDataSourceSchemas } from '../../../config/common.config'; | |
| 3 | + import { CreateComponentType } from '../../../index.type'; | |
| 4 | + import { BasicForm, useForm } from '/@/components/Form'; | |
| 5 | + import { | |
| 6 | + PublicComponentValueType, | |
| 7 | + PublicFormInstaceType, | |
| 8 | + } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 9 | + | |
| 10 | + defineProps<{ | |
| 11 | + values: PublicComponentValueType; | |
| 12 | + componentConfig: CreateComponentType; | |
| 13 | + }>(); | |
| 14 | + | |
| 15 | + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({ | |
| 16 | + labelWidth: 0, | |
| 17 | + showActionButtonGroup: false, | |
| 18 | + layout: 'horizontal', | |
| 19 | + labelCol: { span: 0 }, | |
| 20 | + schemas: commonDataSourceSchemas(), | |
| 21 | + }); | |
| 22 | + | |
| 23 | + const getFormValues = () => { | |
| 24 | + return getFieldsValue(); | |
| 25 | + }; | |
| 26 | + | |
| 27 | + const setFormValues = (record: Recordable) => { | |
| 28 | + return setFieldsValue(record); | |
| 29 | + }; | |
| 30 | + | |
| 31 | + defineExpose({ | |
| 32 | + getFormValues, | |
| 33 | + setFormValues, | |
| 34 | + validate, | |
| 35 | + resetFormValues: resetFields, | |
| 36 | + } as PublicFormInstaceType); | |
| 37 | +</script> | |
| 38 | + | |
| 39 | +<template> | |
| 40 | + <BasicForm @register="register" /> | |
| 41 | +</template> | ... | ... |
| 1 | +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys'; | |
| 2 | +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type'; | |
| 3 | + | |
| 4 | +const componentKeys = useComponentKeys('StatisticsComponent5'); | |
| 5 | + | |
| 6 | +export const StatisticsComponent5Config: ConfigType = { | |
| 7 | + ...componentKeys, | |
| 8 | + title: '实时数据表格', | |
| 9 | + package: PackagesCategoryEnum.STATISTICS, | |
| 10 | +}; | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { reactive, ref } from 'vue'; | |
| 3 | + import { useMultipleDataFetch } from '../../../hook/useSocket'; | |
| 4 | + import { ComponentPropsConfigType, MultipleDataFetchUpdateFn } from '../../../index.type'; | |
| 5 | + import { option } from './config'; | |
| 6 | + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName'; | |
| 7 | + import { BasicTable, useTable, BasicColumn } from '/@/components/Table'; | |
| 8 | + | |
| 9 | + const props = defineProps<{ | |
| 10 | + config: ComponentPropsConfigType<typeof option>; | |
| 11 | + }>(); | |
| 12 | + | |
| 13 | + const realTimeList = ref<any>([ | |
| 14 | + { attribute: '测试', price: 2, time: '2023-06-29' }, | |
| 15 | + { attribute: '测试1', price: 21, time: '2023-06-29' }, | |
| 16 | + { attribute: '测试2', price: 213, time: '2023-06-29' }, | |
| 17 | + ]); | |
| 18 | + const realTimeColumn = reactive<BasicColumn[]>([ | |
| 19 | + { title: '属性', dataIndex: 'attribute', width: 80, ellipsis: true }, | |
| 20 | + { title: '值', dataIndex: 'price', width: 80, ellipsis: true }, | |
| 21 | + { title: '时间', dataIndex: 'time', width: 80, ellipsis: true }, | |
| 22 | + ]); | |
| 23 | + | |
| 24 | + const [registerTable] = useTable({ | |
| 25 | + showIndexColumn: false, | |
| 26 | + showTableSetting: false, | |
| 27 | + dataSource: realTimeList, | |
| 28 | + canResize: true, | |
| 29 | + maxHeight: 144, | |
| 30 | + size: 'small', | |
| 31 | + // columns: [{ title: '属性', dataIndex: 'attribute', width: 80 }], | |
| 32 | + columns: realTimeColumn as any, | |
| 33 | + }); | |
| 34 | + | |
| 35 | + // const getDesign = computed(() => { | |
| 36 | + // const { persetOption, option } = props.config; | |
| 37 | + // clearInterval; | |
| 38 | + // return {}; | |
| 39 | + // }); | |
| 40 | + | |
| 41 | + // const randomFn = () => { | |
| 42 | + // useIntervalFn(() => { | |
| 43 | + // const value = (Math.random() * 100).toFixed(0); | |
| 44 | + // unref(chartInstance)?.setOption({ | |
| 45 | + // series: [{ data: [{ value }] }, { data: [{ value }] }], | |
| 46 | + // } as EChartsOption); | |
| 47 | + // }, 3000); | |
| 48 | + // }; | |
| 49 | + | |
| 50 | + const updateFn: MultipleDataFetchUpdateFn = () => {}; | |
| 51 | + | |
| 52 | + useMultipleDataFetch(props, updateFn); | |
| 53 | + | |
| 54 | + // const { getRatio } = useComponentScale(props); | |
| 55 | +</script> | |
| 56 | + | |
| 57 | +<template> | |
| 58 | + <main class="flex flex-col justify-center items-center"> | |
| 59 | + <DeviceName :config="config" /> | |
| 60 | + <div> | |
| 61 | + <!-- <PageWrapper> --> | |
| 62 | + <BasicTable @register="registerTable" /> | |
| 63 | + <!-- </PageWrapper> --> | |
| 64 | + </div> | |
| 65 | + </main> | |
| 66 | +</template> | ... | ... |
| 1 | +import cloneDeep from 'lodash-es/cloneDeep'; | |
| 2 | +import { StatisticsComponent6Config } from '.'; | |
| 3 | +import { | |
| 4 | + ConfigType, | |
| 5 | + CreateComponentType, | |
| 6 | + PublicComponentOptions, | |
| 7 | + PublicPresetOptions, | |
| 8 | +} from '../../../index.type'; | |
| 9 | +import { PublicConfigClass, componentInitConfig } from '../../../publicConfig'; | |
| 10 | +import { ComponentConfigFieldEnum } from '../../../enum'; | |
| 11 | + | |
| 12 | +export enum Gradient { | |
| 13 | + FIRST = 'first', | |
| 14 | + SECOND = 'second', | |
| 15 | +} | |
| 16 | +export enum GradientColor { | |
| 17 | + FIRST = '#07ffd6', | |
| 18 | + SECOND = '#5eff10', | |
| 19 | +} | |
| 20 | +export const option: PublicPresetOptions = { | |
| 21 | + multipleDataSourceComponent: true, | |
| 22 | + [ComponentConfigFieldEnum.FONT_COLOR]: '#FD7347', | |
| 23 | + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, | |
| 24 | + [ComponentConfigFieldEnum.UNIT]: '℃', | |
| 25 | +}; | |
| 26 | + | |
| 27 | +export default class Config extends PublicConfigClass implements CreateComponentType { | |
| 28 | + public key: string = StatisticsComponent6Config.key; | |
| 29 | + | |
| 30 | + public attr = { ...componentInitConfig }; | |
| 31 | + | |
| 32 | + public componentConfig: ConfigType = cloneDeep(StatisticsComponent6Config); | |
| 33 | + | |
| 34 | + public persetOption = cloneDeep(option); | |
| 35 | + | |
| 36 | + public option: PublicComponentOptions; | |
| 37 | + | |
| 38 | + constructor(option: PublicComponentOptions) { | |
| 39 | + super(); | |
| 40 | + this.option = { ...option }; | |
| 41 | + } | |
| 42 | +} | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { ComponentConfigFieldEnum } from '../../../enum'; | |
| 3 | + import { option } from './config'; | |
| 4 | + import { useForm, BasicForm } from '/@/components/Form'; | |
| 5 | + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 6 | + import { ComponentInfo } from '/@/views/visual/palette/types'; | |
| 7 | + | |
| 8 | + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({ | |
| 9 | + schemas: [ | |
| 10 | + { | |
| 11 | + field: ComponentConfigFieldEnum.FONT_COLOR, | |
| 12 | + label: '数值字体颜色', | |
| 13 | + component: 'ColorPicker', | |
| 14 | + changeEvent: 'update:value', | |
| 15 | + defaultValue: option.fontColor, | |
| 16 | + }, | |
| 17 | + { | |
| 18 | + field: ComponentConfigFieldEnum.UNIT, | |
| 19 | + label: '数值单位', | |
| 20 | + component: 'Input', | |
| 21 | + defaultValue: option.unit, | |
| 22 | + }, | |
| 23 | + { | |
| 24 | + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME, | |
| 25 | + label: '显示设备名称', | |
| 26 | + component: 'Checkbox', | |
| 27 | + defaultValue: option.showDeviceName, | |
| 28 | + }, | |
| 29 | + ], | |
| 30 | + showActionButtonGroup: false, | |
| 31 | + labelWidth: 120, | |
| 32 | + baseColProps: { | |
| 33 | + span: 12, | |
| 34 | + }, | |
| 35 | + }); | |
| 36 | + | |
| 37 | + const getFormValues = () => { | |
| 38 | + // return getFieldsValue(); | |
| 39 | + const item = getFieldsValue(); | |
| 40 | + return { | |
| 41 | + fontColor: item[ComponentConfigFieldEnum.FONT_COLOR], | |
| 42 | + unit: item[ComponentConfigFieldEnum.UNIT], | |
| 43 | + showDeviceName: item[ComponentConfigFieldEnum.SHOW_DEVICE_NAME], | |
| 44 | + } as ComponentInfo; | |
| 45 | + }; | |
| 46 | + | |
| 47 | + const setFormValues = (data: Recordable) => { | |
| 48 | + // return setFieldsValue(data); | |
| 49 | + const { unit, fontColor, showDeviceName } = data; | |
| 50 | + | |
| 51 | + const value = { | |
| 52 | + [ComponentConfigFieldEnum.UNIT]: unit, | |
| 53 | + [ComponentConfigFieldEnum.FONT_COLOR]: fontColor, | |
| 54 | + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: showDeviceName, | |
| 55 | + }; | |
| 56 | + return setFieldsValue(value); | |
| 57 | + }; | |
| 58 | + | |
| 59 | + defineExpose({ | |
| 60 | + getFormValues, | |
| 61 | + setFormValues, | |
| 62 | + resetFormValues: resetFields, | |
| 63 | + } as PublicFormInstaceType); | |
| 64 | +</script> | |
| 65 | + | |
| 66 | +<template> | |
| 67 | + <BasicForm @register="register" /> | |
| 68 | +</template> | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { commonDataSourceSchemas } from '../../../config/common.config'; | |
| 3 | + import { CreateComponentType } from '../../../index.type'; | |
| 4 | + import { BasicForm, useForm } from '/@/components/Form'; | |
| 5 | + import { | |
| 6 | + PublicComponentValueType, | |
| 7 | + PublicFormInstaceType, | |
| 8 | + } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 9 | + | |
| 10 | + defineProps<{ | |
| 11 | + values: PublicComponentValueType; | |
| 12 | + componentConfig: CreateComponentType; | |
| 13 | + }>(); | |
| 14 | + | |
| 15 | + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({ | |
| 16 | + labelWidth: 0, | |
| 17 | + showActionButtonGroup: false, | |
| 18 | + layout: 'horizontal', | |
| 19 | + labelCol: { span: 0 }, | |
| 20 | + schemas: commonDataSourceSchemas(), | |
| 21 | + }); | |
| 22 | + | |
| 23 | + const getFormValues = () => { | |
| 24 | + return getFieldsValue(); | |
| 25 | + }; | |
| 26 | + | |
| 27 | + const setFormValues = (record: Recordable) => { | |
| 28 | + return setFieldsValue(record); | |
| 29 | + }; | |
| 30 | + | |
| 31 | + defineExpose({ | |
| 32 | + getFormValues, | |
| 33 | + setFormValues, | |
| 34 | + validate, | |
| 35 | + resetFormValues: resetFields, | |
| 36 | + } as PublicFormInstaceType); | |
| 37 | +</script> | |
| 38 | + | |
| 39 | +<template> | |
| 40 | + <BasicForm @register="register" /> | |
| 41 | +</template> | ... | ... |
| 1 | +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys'; | |
| 2 | +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type'; | |
| 3 | + | |
| 4 | +const componentKeys = useComponentKeys('StatisticsComponent6'); | |
| 5 | + | |
| 6 | +export const StatisticsComponent6Config: ConfigType = { | |
| 7 | + ...componentKeys, | |
| 8 | + title: '实时数据折线图', | |
| 9 | + package: PackagesCategoryEnum.STATISTICS, | |
| 10 | +}; | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { EChartsOption, ECharts, init } from 'echarts'; | |
| 3 | + import { unref, ref, onMounted, nextTick } from 'vue'; | |
| 4 | + import { useMultipleDataFetch } from '../../../hook/useSocket'; | |
| 5 | + import { ComponentPropsConfigType, MultipleDataFetchUpdateFn } from '../../../index.type'; | |
| 6 | + import { option } from './config'; | |
| 7 | + import { UpdateTime } from '/@/views/visual/commonComponents/UpdateTime'; | |
| 8 | + import { useComponentScale } from '../../../hook/useComponentScale'; | |
| 9 | + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName'; | |
| 10 | + import { dateFormat } from '/@/utils/common/compUtils'; | |
| 11 | + | |
| 12 | + const props = defineProps<{ | |
| 13 | + config: ComponentPropsConfigType<typeof option>; | |
| 14 | + }>(); | |
| 15 | + | |
| 16 | + const chartRefEl = ref<Nullable<HTMLDivElement>>(null); | |
| 17 | + | |
| 18 | + const chartInstance = ref<Nullable<ECharts>>(null); | |
| 19 | + | |
| 20 | + const time = ref<Nullable<number>>(null); | |
| 21 | + | |
| 22 | + function randomData() { | |
| 23 | + now.value = now.value + oneDay; | |
| 24 | + const newTime = dateFormat(unref(now), 'MM-dd hh:mm:ss'); | |
| 25 | + value = value + Math.random() * 21 - 10; | |
| 26 | + return { | |
| 27 | + name: newTime, | |
| 28 | + value: [newTime, Math.round(value)], | |
| 29 | + }; | |
| 30 | + } | |
| 31 | + const data = ref<any>([]); | |
| 32 | + const now = ref<number>(1688026367000); | |
| 33 | + let oneDay = 5000; //间隔秒数 | |
| 34 | + let value = Math.random() * 1000; | |
| 35 | + for (let i = 0; i < 10; i++) { | |
| 36 | + data.value.push(randomData()); | |
| 37 | + } | |
| 38 | + setInterval(function () { | |
| 39 | + for (let i = 0; i < 1; i++) { | |
| 40 | + data.value.shift(); | |
| 41 | + data.value.push(randomData()); | |
| 42 | + } | |
| 43 | + unref(chartInstance)?.setOption(options()); | |
| 44 | + }, 1000); | |
| 45 | + | |
| 46 | + // const getDesign = computed(() => { | |
| 47 | + // const { persetOption, option } = props.config; | |
| 48 | + // const { dataSource = [] } = option || {}; | |
| 49 | + // const { unit: presetUnit, fontColor: presetFontColor } = persetOption || {}; | |
| 50 | + // return { | |
| 51 | + // dataSource: dataSource?.map((item) => { | |
| 52 | + // const { unit, fontColor } = item.componentInfo || {}; | |
| 53 | + // const { attribute, attributeRename } = item; | |
| 54 | + // return { | |
| 55 | + // unit: unit ?? presetUnit, | |
| 56 | + // fontColor: fontColor ?? presetFontColor, | |
| 57 | + // attribute, | |
| 58 | + // attributeRename, | |
| 59 | + // }; | |
| 60 | + // }), | |
| 61 | + // }; | |
| 62 | + // }); | |
| 63 | + | |
| 64 | + const options = (): EChartsOption => { | |
| 65 | + // getStageColor(gradientInfo); | |
| 66 | + return { | |
| 67 | + trigger: 'axis', | |
| 68 | + axisPointer: { | |
| 69 | + lineStyle: { | |
| 70 | + width: 1, | |
| 71 | + color: '#019680', | |
| 72 | + }, | |
| 73 | + }, | |
| 74 | + legend: { | |
| 75 | + top: '10%', | |
| 76 | + left: 'center', | |
| 77 | + data: ['温度', '湿度'], | |
| 78 | + }, | |
| 79 | + grid: { | |
| 80 | + top: '45%', | |
| 81 | + left: '20%', | |
| 82 | + bottom: '14%', | |
| 83 | + containLabel: true, | |
| 84 | + }, | |
| 85 | + xAxis: { | |
| 86 | + type: 'category', | |
| 87 | + splitLine: { | |
| 88 | + show: true, | |
| 89 | + lineStyle: { | |
| 90 | + width: 1, | |
| 91 | + type: 'solid', | |
| 92 | + color: 'rgba(226,226,226,0.5)', | |
| 93 | + }, | |
| 94 | + }, | |
| 95 | + data: unref(data).map((item) => item.name), | |
| 96 | + }, | |
| 97 | + yAxis: { | |
| 98 | + type: 'value', | |
| 99 | + boundaryGap: [0, '50%'], | |
| 100 | + splitLine: { | |
| 101 | + show: false, | |
| 102 | + }, | |
| 103 | + }, | |
| 104 | + series: [ | |
| 105 | + { | |
| 106 | + type: 'line', | |
| 107 | + name: '温度', | |
| 108 | + stack: 'Total', | |
| 109 | + data: unref(data).map((item) => item.value), | |
| 110 | + }, | |
| 111 | + { | |
| 112 | + type: 'line', | |
| 113 | + name: '湿度', | |
| 114 | + stack: 'Total', | |
| 115 | + data: unref(data).map((item) => { | |
| 116 | + return Number(item.value[1]) * 0.99; | |
| 117 | + }), | |
| 118 | + }, | |
| 119 | + ], | |
| 120 | + }; | |
| 121 | + }; | |
| 122 | + | |
| 123 | + const initial = () => { | |
| 124 | + chartInstance.value = init(unref(chartRefEl)! as HTMLElement); | |
| 125 | + chartInstance.value.setOption(options()); | |
| 126 | + }; | |
| 127 | + | |
| 128 | + // const updateChart = (data: SeriesOption['data'], yAxisData) => { | |
| 129 | + // unref(chartInstance)?.setOption({ | |
| 130 | + // series: [{ data }], | |
| 131 | + // yAxis: { data: yAxisData }, | |
| 132 | + // } as EChartsOption); | |
| 133 | + // }; | |
| 134 | + | |
| 135 | + const updateFn: MultipleDataFetchUpdateFn = () => { | |
| 136 | + // console.log(message, 'message'); | |
| 137 | + return {}; | |
| 138 | + }; | |
| 139 | + | |
| 140 | + useMultipleDataFetch(props, updateFn); | |
| 141 | + | |
| 142 | + onMounted(() => { | |
| 143 | + initial(); | |
| 144 | + // !props.config.option.uuid && randomFn(); | |
| 145 | + !props.config.option.uuid; | |
| 146 | + }); | |
| 147 | + | |
| 148 | + const resize = async () => { | |
| 149 | + await nextTick(); | |
| 150 | + | |
| 151 | + // 修改echarts大小 | |
| 152 | + unref(chartInstance)?.setOption({ | |
| 153 | + legend: { | |
| 154 | + textStyle: { | |
| 155 | + fontSize: 14 * unref(getRatio), | |
| 156 | + }, | |
| 157 | + }, | |
| 158 | + } as EChartsOption); | |
| 159 | + unref(chartInstance)?.resize(); | |
| 160 | + }; | |
| 161 | + | |
| 162 | + const { getRatio } = useComponentScale(props, resize); | |
| 163 | +</script> | |
| 164 | + | |
| 165 | +<template> | |
| 166 | + <main class="w-full h-full flex flex-col justify-center items-center"> | |
| 167 | + <DeviceName :config="config" /> | |
| 168 | + <div ref="chartRefEl" class="flex-1 w-full h-full"> </div> | |
| 169 | + <UpdateTime :time="time" /> | |
| 170 | + </main> | |
| 171 | +</template> | ... | ... |
| 1 | +import { StatisticsComponent1Config } from './StatisticsComponent1'; | |
| 2 | +import { StatisticsComponent2Config } from './StatisticsComponent2'; | |
| 3 | +// import { StatisticsComponent3Config } from './StatisticsComponent3'; | |
| 4 | +// import { StatisticsComponent4Config } from './StatisticsComponent4'; | |
| 5 | +// import { StatisticsComponent5Config } from './StatisticsComponent5'; | |
| 6 | +// import { StatisticsComponent6Config } from './StatisticsComponent6'; | |
| 7 | + | |
| 8 | +export const STATISTICSList = [ | |
| 9 | + StatisticsComponent1Config, | |
| 10 | + StatisticsComponent2Config, | |
| 11 | + // StatisticsComponent3Config, | |
| 12 | + // StatisticsComponent4Config, | |
| 13 | + // StatisticsComponent5Config, | |
| 14 | + // StatisticsComponent6Config, | |
| 15 | +]; | ... | ... |
| 1 | +import cloneDeep from 'lodash-es/cloneDeep'; | |
| 2 | +import { SwitchSignalLightConfig } from '.'; | |
| 3 | +import { | |
| 4 | + ConfigType, | |
| 5 | + CreateComponentType, | |
| 6 | + PublicComponentOptions, | |
| 7 | + PublicPresetOptions, | |
| 8 | +} from '/@/views/visual/packages/index.type'; | |
| 9 | +import { PublicConfigClass, componentInitConfig } from '/@/views/visual/packages/publicConfig'; | |
| 10 | +import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum'; | |
| 11 | + | |
| 12 | +export const option: PublicPresetOptions = { | |
| 13 | + [ComponentConfigFieldEnum.OPEN_COLOR]: '#30f230', | |
| 14 | + [ComponentConfigFieldEnum.CLOSE_COLOR]: '#eeeeee', | |
| 15 | + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: true, | |
| 16 | +}; | |
| 17 | + | |
| 18 | +export default class Config extends PublicConfigClass implements CreateComponentType { | |
| 19 | + public key: string = SwitchSignalLightConfig.key; | |
| 20 | + | |
| 21 | + public attr = { ...componentInitConfig }; | |
| 22 | + | |
| 23 | + public componentConfig: ConfigType = cloneDeep(SwitchSignalLightConfig); | |
| 24 | + | |
| 25 | + public persetOption = cloneDeep(option); | |
| 26 | + | |
| 27 | + public option: PublicComponentOptions; | |
| 28 | + | |
| 29 | + constructor(option: PublicComponentOptions) { | |
| 30 | + super(); | |
| 31 | + this.option = { ...option }; | |
| 32 | + } | |
| 33 | +} | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum'; | |
| 3 | + import { useForm, BasicForm } from '/@/components/Form'; | |
| 4 | + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 5 | + import { option } from './config'; | |
| 6 | + | |
| 7 | + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({ | |
| 8 | + schemas: [ | |
| 9 | + { | |
| 10 | + field: ComponentConfigFieldEnum.OPEN_COLOR, | |
| 11 | + label: 'ON颜色', | |
| 12 | + component: 'ColorPicker', | |
| 13 | + changeEvent: 'update:value', | |
| 14 | + componentProps: { | |
| 15 | + defaultValue: option.openColor, | |
| 16 | + }, | |
| 17 | + }, | |
| 18 | + { | |
| 19 | + field: ComponentConfigFieldEnum.CLOSE_COLOR, | |
| 20 | + label: 'OFF颜色', | |
| 21 | + component: 'ColorPicker', | |
| 22 | + changeEvent: 'update:value', | |
| 23 | + componentProps: { | |
| 24 | + defaultValue: option.closeColor, | |
| 25 | + }, | |
| 26 | + }, | |
| 27 | + { | |
| 28 | + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME, | |
| 29 | + label: '显示设备名称', | |
| 30 | + component: 'Checkbox', | |
| 31 | + defaultValue: option.showDeviceName, | |
| 32 | + }, | |
| 33 | + ], | |
| 34 | + showActionButtonGroup: false, | |
| 35 | + labelWidth: 120, | |
| 36 | + baseColProps: { | |
| 37 | + span: 12, | |
| 38 | + }, | |
| 39 | + }); | |
| 40 | + | |
| 41 | + const getFormValues = () => { | |
| 42 | + return getFieldsValue(); | |
| 43 | + }; | |
| 44 | + | |
| 45 | + const setFormValues = (data: Recordable) => { | |
| 46 | + return setFieldsValue(data); | |
| 47 | + }; | |
| 48 | + | |
| 49 | + defineExpose({ | |
| 50 | + getFormValues, | |
| 51 | + setFormValues, | |
| 52 | + resetFormValues: resetFields, | |
| 53 | + } as PublicFormInstaceType); | |
| 54 | +</script> | |
| 55 | + | |
| 56 | +<template> | |
| 57 | + <BasicForm @register="register" /> | |
| 58 | +</template> | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { commonDataSourceSchemas } from '../../../config/common.config'; | |
| 3 | + import { BasicForm, useForm } from '/@/components/Form'; | |
| 4 | + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 5 | + | |
| 6 | + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({ | |
| 7 | + labelWidth: 0, | |
| 8 | + showActionButtonGroup: false, | |
| 9 | + layout: 'horizontal', | |
| 10 | + labelCol: { span: 0 }, | |
| 11 | + schemas: commonDataSourceSchemas(), | |
| 12 | + }); | |
| 13 | + | |
| 14 | + const getFormValues = () => { | |
| 15 | + return getFieldsValue(); | |
| 16 | + }; | |
| 17 | + | |
| 18 | + const setFormValues = (record: Recordable) => { | |
| 19 | + return setFieldsValue(record); | |
| 20 | + }; | |
| 21 | + | |
| 22 | + defineExpose({ | |
| 23 | + getFormValues, | |
| 24 | + setFormValues, | |
| 25 | + validate, | |
| 26 | + resetFormValues: resetFields, | |
| 27 | + } as PublicFormInstaceType); | |
| 28 | +</script> | |
| 29 | + | |
| 30 | +<template> | |
| 31 | + <BasicForm @register="register" /> | |
| 32 | +</template> | ... | ... |
| 1 | +// import { ComponentEnum, ComponentNameEnum } from '../index.type'; | |
| 2 | +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys'; | |
| 3 | +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type'; | |
| 4 | + | |
| 5 | +const componentKeys = useComponentKeys('SwitchSignalLight'); | |
| 6 | +export const SwitchSignalLightConfig: ConfigType = { | |
| 7 | + ...componentKeys, | |
| 8 | + // title: ComponentNameEnum.TEXT_COMPONENT_1, | |
| 9 | + title: '开关量信号灯', | |
| 10 | + package: PackagesCategoryEnum.TEXT, | |
| 11 | +}; | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { ComponentPropsConfigType, DataFetchUpdateFn } from '/@/views/visual/packages/index.type'; | |
| 3 | + import { option } from './config'; | |
| 4 | + import { useComponentScale } from '/@/views/visual/packages/hook/useComponentScale'; | |
| 5 | + import { useDataFetch } from '/@/views/visual/packages/hook/useSocket'; | |
| 6 | + import { computed } from 'vue'; | |
| 7 | + import { ref, onMounted, unref } from 'vue'; | |
| 8 | + import { useIntervalFn } from '@vueuse/core'; | |
| 9 | + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName'; | |
| 10 | + | |
| 11 | + const props = defineProps<{ | |
| 12 | + config: ComponentPropsConfigType<typeof option>; | |
| 13 | + }>(); | |
| 14 | + | |
| 15 | + const isOpenClose = ref<boolean>(true); | |
| 16 | + | |
| 17 | + const getDesign = computed(() => { | |
| 18 | + const { persetOption = {}, option } = props.config; | |
| 19 | + const { | |
| 20 | + openColor: persetOpenColor, | |
| 21 | + closeColor: persetCloseColor, | |
| 22 | + showDeviceName: persetShowDeviceName, | |
| 23 | + } = persetOption || {}; | |
| 24 | + const { componentInfo } = option; | |
| 25 | + | |
| 26 | + const { openColor, closeColor, showDeviceName } = componentInfo || {}; | |
| 27 | + return { | |
| 28 | + openColor: openColor ?? persetOpenColor, | |
| 29 | + closeColor: closeColor ?? persetCloseColor, | |
| 30 | + showDeviceName: showDeviceName ?? persetShowDeviceName, | |
| 31 | + }; | |
| 32 | + }); | |
| 33 | + | |
| 34 | + const randomFn = () => { | |
| 35 | + useIntervalFn(() => { | |
| 36 | + isOpenClose.value = !unref(isOpenClose); | |
| 37 | + }, 2000); | |
| 38 | + }; | |
| 39 | + | |
| 40 | + const updateFn: DataFetchUpdateFn = () => {}; | |
| 41 | + | |
| 42 | + onMounted(() => { | |
| 43 | + !props.config.option.uuid && randomFn(); | |
| 44 | + }); | |
| 45 | + | |
| 46 | + useDataFetch(props, updateFn); | |
| 47 | + | |
| 48 | + const { getScale } = useComponentScale(props); | |
| 49 | +</script> | |
| 50 | + | |
| 51 | +<template> | |
| 52 | + <main :style="getScale" class="w-full h-full flex flex-col justify-center items-center"> | |
| 53 | + <DeviceName :config="config" class="text-center" /> | |
| 54 | + <div | |
| 55 | + :style="{ | |
| 56 | + '--open-color': getDesign.openColor, | |
| 57 | + '--close-color': getDesign.closeColor, | |
| 58 | + }" | |
| 59 | + :class="isOpenClose ? 'switch_open' : 'switch_close'" | |
| 60 | + ></div> | |
| 61 | + </main> | |
| 62 | +</template> | |
| 63 | +<style lang="less" scoped> | |
| 64 | + .switch_open { | |
| 65 | + background: var(--open-color); | |
| 66 | + box-shadow: var(--open-color) 0 0 10px 3px; | |
| 67 | + width: 60px; | |
| 68 | + height: 60px; | |
| 69 | + border-radius: 50%; | |
| 70 | + margin: 10px 0; | |
| 71 | + } | |
| 72 | + | |
| 73 | + .switch_close { | |
| 74 | + background-color: var(--close-color); | |
| 75 | + box-shadow: none; | |
| 76 | + width: 42.023px; | |
| 77 | + height: 42.023px; | |
| 78 | + border-radius: 50%; | |
| 79 | + margin: 10px 0; | |
| 80 | + } | |
| 81 | +</style> | ... | ... |
| 1 | +import cloneDeep from 'lodash-es/cloneDeep'; | |
| 2 | +import { SwitchStatusConfig } from '.'; | |
| 3 | +import { | |
| 4 | + ConfigType, | |
| 5 | + CreateComponentType, | |
| 6 | + PublicComponentOptions, | |
| 7 | + PublicPresetOptions, | |
| 8 | +} from '/@/views/visual/packages/index.type'; | |
| 9 | +import { PublicConfigClass, componentInitConfig } from '/@/views/visual/packages/publicConfig'; | |
| 10 | +import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum'; | |
| 11 | + | |
| 12 | +export const option: PublicPresetOptions = { | |
| 13 | + [ComponentConfigFieldEnum.ICON]: 'shuiwen', | |
| 14 | + [ComponentConfigFieldEnum.ICON_COLOR]: '#367bff', | |
| 15 | + [ComponentConfigFieldEnum.ICON_CLOSE]: 'shuiwen', | |
| 16 | + [ComponentConfigFieldEnum.ICON_COLOR_CLOSE]: '#CCCCCC', | |
| 17 | + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, | |
| 18 | +}; | |
| 19 | + | |
| 20 | +export default class Config extends PublicConfigClass implements CreateComponentType { | |
| 21 | + public key: string = SwitchStatusConfig.key; | |
| 22 | + | |
| 23 | + public attr = { ...componentInitConfig }; | |
| 24 | + | |
| 25 | + public componentConfig: ConfigType = cloneDeep(SwitchStatusConfig); | |
| 26 | + | |
| 27 | + public persetOption = cloneDeep(option); | |
| 28 | + | |
| 29 | + public option: PublicComponentOptions; | |
| 30 | + | |
| 31 | + constructor(option: PublicComponentOptions) { | |
| 32 | + super(); | |
| 33 | + this.option = { ...option }; | |
| 34 | + } | |
| 35 | +} | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum'; | |
| 3 | + import { useForm, BasicForm } from '/@/components/Form'; | |
| 4 | + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 5 | + import { option } from './config'; | |
| 6 | + | |
| 7 | + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({ | |
| 8 | + schemas: [ | |
| 9 | + { | |
| 10 | + field: ComponentConfigFieldEnum.ICON, | |
| 11 | + label: '开启状态图标', | |
| 12 | + component: 'IconDrawer', | |
| 13 | + changeEvent: 'update:value', | |
| 14 | + defaultValue: option.icon, | |
| 15 | + componentProps({ formModel }) { | |
| 16 | + const color = formModel[ComponentConfigFieldEnum.ICON_COLOR]; | |
| 17 | + return { | |
| 18 | + color, | |
| 19 | + }; | |
| 20 | + }, | |
| 21 | + }, | |
| 22 | + { | |
| 23 | + field: ComponentConfigFieldEnum.ICON_COLOR, | |
| 24 | + label: '开启图标颜色', | |
| 25 | + component: 'ColorPicker', | |
| 26 | + changeEvent: 'update:value', | |
| 27 | + defaultValue: option.iconColor, | |
| 28 | + }, | |
| 29 | + { | |
| 30 | + field: ComponentConfigFieldEnum.ICON_CLOSE, | |
| 31 | + label: '关闭状态图标', | |
| 32 | + component: 'IconDrawer', | |
| 33 | + changeEvent: 'update:value', | |
| 34 | + defaultValue: option.iconClose, | |
| 35 | + componentProps({ formModel }) { | |
| 36 | + const color = formModel[ComponentConfigFieldEnum.ICON_COLOR_CLOSE]; | |
| 37 | + return { | |
| 38 | + color, | |
| 39 | + }; | |
| 40 | + }, | |
| 41 | + }, | |
| 42 | + { | |
| 43 | + field: ComponentConfigFieldEnum.ICON_COLOR_CLOSE, | |
| 44 | + label: '关闭图标颜色', | |
| 45 | + component: 'ColorPicker', | |
| 46 | + changeEvent: 'update:value', | |
| 47 | + defaultValue: option.iconColorClose, | |
| 48 | + }, | |
| 49 | + { | |
| 50 | + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME, | |
| 51 | + label: '显示设备名称', | |
| 52 | + component: 'Checkbox', | |
| 53 | + defaultValue: option.showDeviceName, | |
| 54 | + }, | |
| 55 | + ], | |
| 56 | + showActionButtonGroup: false, | |
| 57 | + labelWidth: 120, | |
| 58 | + baseColProps: { | |
| 59 | + span: 12, | |
| 60 | + }, | |
| 61 | + }); | |
| 62 | + | |
| 63 | + const getFormValues = () => { | |
| 64 | + return getFieldsValue(); | |
| 65 | + }; | |
| 66 | + | |
| 67 | + const setFormValues = (data: Recordable) => { | |
| 68 | + return setFieldsValue(data); | |
| 69 | + }; | |
| 70 | + | |
| 71 | + defineExpose({ | |
| 72 | + getFormValues, | |
| 73 | + setFormValues, | |
| 74 | + resetFormValues: resetFields, | |
| 75 | + } as PublicFormInstaceType); | |
| 76 | +</script> | |
| 77 | + | |
| 78 | +<template> | |
| 79 | + <BasicForm @register="register" /> | |
| 80 | +</template> | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { commonDataSourceSchemas } from '../../../config/common.config'; | |
| 3 | + import { BasicForm, useForm } from '/@/components/Form'; | |
| 4 | + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 5 | + | |
| 6 | + // const props = defineProps<{ | |
| 7 | + // values: PublicComponentDataSourceProps; | |
| 8 | + // }>(); | |
| 9 | + | |
| 10 | + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({ | |
| 11 | + labelWidth: 0, | |
| 12 | + showActionButtonGroup: false, | |
| 13 | + layout: 'horizontal', | |
| 14 | + labelCol: { span: 0 }, | |
| 15 | + schemas: commonDataSourceSchemas(), | |
| 16 | + }); | |
| 17 | + | |
| 18 | + const getFormValues = () => { | |
| 19 | + return getFieldsValue(); | |
| 20 | + }; | |
| 21 | + | |
| 22 | + const setFormValues = (record: Recordable) => { | |
| 23 | + return setFieldsValue(record); | |
| 24 | + }; | |
| 25 | + | |
| 26 | + defineExpose({ | |
| 27 | + getFormValues, | |
| 28 | + setFormValues, | |
| 29 | + validate, | |
| 30 | + resetFormValues: resetFields, | |
| 31 | + } as PublicFormInstaceType); | |
| 32 | +</script> | |
| 33 | + | |
| 34 | +<template> | |
| 35 | + <BasicForm @register="register" /> | |
| 36 | +</template> | ... | ... |
| 1 | +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys'; | |
| 2 | +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type'; | |
| 3 | + | |
| 4 | +const componentKeys = useComponentKeys('SwitchStatus'); | |
| 5 | +export const SwitchStatusConfig: ConfigType = { | |
| 6 | + ...componentKeys, | |
| 7 | + title: '开关量状态', | |
| 8 | + package: PackagesCategoryEnum.TEXT, | |
| 9 | +}; | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { useDataFetch } from '/@/views/visual/packages/hook/useSocket'; | |
| 3 | + import { ComponentPropsConfigType, DataFetchUpdateFn } from '/@/views/visual/packages/index.type'; | |
| 4 | + | |
| 5 | + import { option } from './config'; | |
| 6 | + import { SvgIcon } from '/@/components/Icon'; | |
| 7 | + import { computed } from 'vue'; | |
| 8 | + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName'; | |
| 9 | + | |
| 10 | + const props = defineProps<{ | |
| 11 | + config: ComponentPropsConfigType<typeof option>; | |
| 12 | + }>(); | |
| 13 | + | |
| 14 | + const getDesign = computed(() => { | |
| 15 | + const { persetOption = {}, option } = props.config; | |
| 16 | + | |
| 17 | + const { | |
| 18 | + iconColor: persetIconColor, | |
| 19 | + unit: perseUnit, | |
| 20 | + icon: persetIcon, | |
| 21 | + fontColor: persetFontColor, | |
| 22 | + } = persetOption; | |
| 23 | + | |
| 24 | + const { componentInfo, attribute, attributeRename } = option; | |
| 25 | + | |
| 26 | + const { icon, iconColor, fontColor, unit } = componentInfo || {}; | |
| 27 | + return { | |
| 28 | + iconColor: iconColor || persetIconColor, | |
| 29 | + unit: unit ?? perseUnit, | |
| 30 | + icon: icon || persetIcon, | |
| 31 | + fontColor: fontColor || persetFontColor, | |
| 32 | + attribute: attributeRename || attribute, | |
| 33 | + }; | |
| 34 | + }); | |
| 35 | + | |
| 36 | + // const svgList = ref<any>([ | |
| 37 | + // { | |
| 38 | + // value: 26.2, | |
| 39 | + // name: 'wendu', | |
| 40 | + // icon: 'zongfushe', | |
| 41 | + // unit: 'kw', | |
| 42 | + // iconColor: '#367BFF', | |
| 43 | + // fontColor: '#357CFB', | |
| 44 | + // }, | |
| 45 | + // { | |
| 46 | + // value: 53.7, | |
| 47 | + // name: 'shidu', | |
| 48 | + // icon: 'guangzhaoqiangdu', | |
| 49 | + // unit: '℃', | |
| 50 | + // iconColor: '#FFA000', | |
| 51 | + // fontColor: '#FFA000', | |
| 52 | + // }, | |
| 53 | + // ]); | |
| 54 | + | |
| 55 | + const updateFn: DataFetchUpdateFn = () => {}; | |
| 56 | + | |
| 57 | + useDataFetch(props, updateFn); | |
| 58 | +</script> | |
| 59 | + | |
| 60 | +<template> | |
| 61 | + <main class="w-full h-full flex flex-col justify-evenly items-center"> | |
| 62 | + <DeviceName :config="config" /> | |
| 63 | + <div class="flex justify-center items-center"> | |
| 64 | + <SvgIcon | |
| 65 | + :name="getDesign.icon!" | |
| 66 | + prefix="iconfont" | |
| 67 | + :size="60" | |
| 68 | + :style="{ color: getDesign.iconColor }" | |
| 69 | + /> | |
| 70 | + </div> | |
| 71 | + </main> | |
| 72 | +</template> | ... | ... |
| 1 | +import cloneDeep from 'lodash-es/cloneDeep'; | |
| 2 | +import { ValueList1Config } from '.'; | |
| 3 | +import { | |
| 4 | + ConfigType, | |
| 5 | + CreateComponentType, | |
| 6 | + PublicComponentOptions, | |
| 7 | + PublicPresetOptions, | |
| 8 | +} from '/@/views/visual/packages/index.type'; | |
| 9 | +import { PublicConfigClass, componentInitConfig } from '/@/views/visual/packages/publicConfig'; | |
| 10 | +import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum'; | |
| 11 | + | |
| 12 | +export const option: PublicPresetOptions = { | |
| 13 | + multipleDataSourceComponent: true, | |
| 14 | + [ComponentConfigFieldEnum.FONT_COLOR]: '#000', | |
| 15 | + [ComponentConfigFieldEnum.UNIT]: '℃', | |
| 16 | + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, | |
| 17 | + [ComponentConfigFieldEnum.BACKGROUND_COLOR]: '#377dff', | |
| 18 | + fontSize: '18px', | |
| 19 | +}; | |
| 20 | + | |
| 21 | +export default class Config extends PublicConfigClass implements CreateComponentType { | |
| 22 | + public key: string = ValueList1Config.key; | |
| 23 | + | |
| 24 | + public attr = { ...componentInitConfig }; | |
| 25 | + | |
| 26 | + public componentConfig: ConfigType = cloneDeep(ValueList1Config); | |
| 27 | + | |
| 28 | + public persetOption = cloneDeep(option); | |
| 29 | + | |
| 30 | + public option: PublicComponentOptions; | |
| 31 | + | |
| 32 | + constructor(option: PublicComponentOptions) { | |
| 33 | + super(); | |
| 34 | + this.option = { ...option }; | |
| 35 | + } | |
| 36 | +} | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum'; | |
| 3 | + import { useForm, BasicForm } from '/@/components/Form'; | |
| 4 | + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 5 | + import { option } from './config'; | |
| 6 | + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({ | |
| 7 | + schemas: [ | |
| 8 | + { | |
| 9 | + field: ComponentConfigFieldEnum.FONT_COLOR, | |
| 10 | + label: '数值字体颜色', | |
| 11 | + component: 'ColorPicker', | |
| 12 | + changeEvent: 'update:value', | |
| 13 | + componentProps: { | |
| 14 | + defaultValue: option.fontColor, | |
| 15 | + }, | |
| 16 | + }, | |
| 17 | + { | |
| 18 | + field: ComponentConfigFieldEnum.BACKGROUND_COLOR, | |
| 19 | + label: '进度条背景色', | |
| 20 | + component: 'ColorPicker', | |
| 21 | + changeEvent: 'update:value', | |
| 22 | + componentProps: { | |
| 23 | + defaultValue: option.backgroundColor, | |
| 24 | + }, | |
| 25 | + }, | |
| 26 | + | |
| 27 | + { | |
| 28 | + field: ComponentConfigFieldEnum.UNIT, | |
| 29 | + label: '数值单位', | |
| 30 | + component: 'Input', | |
| 31 | + defaultValue: option.unit, | |
| 32 | + }, | |
| 33 | + // { | |
| 34 | + // field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME, | |
| 35 | + // label: '显示设备名称', | |
| 36 | + // component: 'Checkbox', | |
| 37 | + // }, | |
| 38 | + ], | |
| 39 | + showActionButtonGroup: false, | |
| 40 | + labelWidth: 120, | |
| 41 | + baseColProps: { | |
| 42 | + span: 12, | |
| 43 | + }, | |
| 44 | + }); | |
| 45 | + | |
| 46 | + const getFormValues = () => { | |
| 47 | + return getFieldsValue(); | |
| 48 | + }; | |
| 49 | + | |
| 50 | + const setFormValues = (data: Recordable) => { | |
| 51 | + return setFieldsValue(data); | |
| 52 | + }; | |
| 53 | + | |
| 54 | + defineExpose({ | |
| 55 | + getFormValues, | |
| 56 | + setFormValues, | |
| 57 | + resetFormValues: resetFields, | |
| 58 | + } as PublicFormInstaceType); | |
| 59 | +</script> | |
| 60 | + | |
| 61 | +<template> | |
| 62 | + <BasicForm @register="register" /> | |
| 63 | +</template> | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { commonDataSourceSchemas } from '../../../config/common.config'; | |
| 3 | + import { BasicForm, useForm } from '/@/components/Form'; | |
| 4 | + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 5 | + | |
| 6 | + // const props = defineProps<{ | |
| 7 | + // values: PublicComponentDataSourceProps; | |
| 8 | + // }>(); | |
| 9 | + | |
| 10 | + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({ | |
| 11 | + labelWidth: 0, | |
| 12 | + showActionButtonGroup: false, | |
| 13 | + layout: 'horizontal', | |
| 14 | + labelCol: { span: 0 }, | |
| 15 | + schemas: commonDataSourceSchemas(), | |
| 16 | + }); | |
| 17 | + | |
| 18 | + const getFormValues = () => { | |
| 19 | + return getFieldsValue(); | |
| 20 | + }; | |
| 21 | + | |
| 22 | + const setFormValues = (record: Recordable) => { | |
| 23 | + return setFieldsValue(record); | |
| 24 | + }; | |
| 25 | + | |
| 26 | + defineExpose({ | |
| 27 | + getFormValues, | |
| 28 | + setFormValues, | |
| 29 | + validate, | |
| 30 | + resetFormValues: resetFields, | |
| 31 | + } as PublicFormInstaceType); | |
| 32 | +</script> | |
| 33 | + | |
| 34 | +<template> | |
| 35 | + <BasicForm @register="register" /> | |
| 36 | +</template> | ... | ... |
| 1 | +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys'; | |
| 2 | +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type'; | |
| 3 | + | |
| 4 | +const componentKeys = useComponentKeys('ValueList1'); | |
| 5 | +export const ValueList1Config: ConfigType = { | |
| 6 | + ...componentKeys, | |
| 7 | + title: '数值列表1', | |
| 8 | + package: PackagesCategoryEnum.TEXT, | |
| 9 | +}; | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { option } from './config'; | |
| 3 | + // import { useComponentScale } from '/@/views/visual/packages/hook/useComponentScale'; | |
| 4 | + import { ComponentPropsConfigType, MultipleDataFetchUpdateFn } from '../../../index.type'; | |
| 5 | + import { useMultipleDataFetch } from '/@/views/visual/packages/hook/useSocket'; | |
| 6 | + import { computed } from 'vue'; | |
| 7 | + import { ref } from 'vue'; | |
| 8 | + import { Progress } from 'ant-design-vue'; | |
| 9 | + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName'; | |
| 10 | + import { unref } from 'vue'; | |
| 11 | + import { onMounted } from 'vue'; | |
| 12 | + | |
| 13 | + const props = defineProps<{ | |
| 14 | + config: ComponentPropsConfigType<typeof option>; | |
| 15 | + }>(); | |
| 16 | + | |
| 17 | + const percentList = ref<any[]>([ | |
| 18 | + { | |
| 19 | + value: 20, | |
| 20 | + fontColor: '#19eff', | |
| 21 | + backgroundColor: '#19eff', | |
| 22 | + color: '#000', | |
| 23 | + fontSize: '16px', | |
| 24 | + unit: '℃', | |
| 25 | + id: 1, | |
| 26 | + }, | |
| 27 | + { | |
| 28 | + value: 66, | |
| 29 | + fontColor: '#1E8667', | |
| 30 | + backgroundColor: '#1E8667', | |
| 31 | + color: '#000', | |
| 32 | + fontSize: '16px', | |
| 33 | + unit: '℃', | |
| 34 | + id: 2, | |
| 35 | + }, | |
| 36 | + { | |
| 37 | + value: 49, | |
| 38 | + fontColor: '#2196F3', | |
| 39 | + backgroundColor: '#2196F3', | |
| 40 | + color: '#000', | |
| 41 | + fontSize: '16px', | |
| 42 | + unit: '℃', | |
| 43 | + id: 3, | |
| 44 | + }, | |
| 45 | + ]); | |
| 46 | + | |
| 47 | + const getDesign = computed(() => { | |
| 48 | + const { persetOption = {}, option } = props.config; | |
| 49 | + const { dataSource = [] } = option || {}; | |
| 50 | + const { | |
| 51 | + unit: presetUnit, | |
| 52 | + fontColor: presetFontColor, | |
| 53 | + backgroundColor: persetBackgroundColor, | |
| 54 | + } = persetOption || {}; | |
| 55 | + return { | |
| 56 | + dataSource: dataSource?.map((item) => { | |
| 57 | + const { unit, fontColor, fontSize, backgroundColor } = item.componentInfo || {}; | |
| 58 | + const { attribute, attributeRename } = item; | |
| 59 | + return { | |
| 60 | + unit: unit ?? presetUnit, | |
| 61 | + fontColor: fontColor ?? presetFontColor, | |
| 62 | + fontSize, | |
| 63 | + backgroundColor: backgroundColor ?? persetBackgroundColor, | |
| 64 | + attribute, | |
| 65 | + attributeRename, | |
| 66 | + }; | |
| 67 | + }), | |
| 68 | + }; | |
| 69 | + }); | |
| 70 | + | |
| 71 | + const newPercentList = ref<any[]>([]); | |
| 72 | + | |
| 73 | + const updateFn: MultipleDataFetchUpdateFn = (message) => { | |
| 74 | + const { data = {} } = message; | |
| 75 | + const { dataSource } = unref(getDesign); | |
| 76 | + newPercentList.value = dataSource.map((item) => { | |
| 77 | + const { attribute, fontSize, attributeRename, fontColor, unit, backgroundColor } = item; | |
| 78 | + | |
| 79 | + const [latest] = data[attribute] || []; | |
| 80 | + const [_timespan, value] = latest || []; | |
| 81 | + return { | |
| 82 | + value: Number(value), | |
| 83 | + name: attributeRename ?? attribute, | |
| 84 | + fontSize, | |
| 85 | + unit, | |
| 86 | + backgroundColor: backgroundColor, | |
| 87 | + fontColor: fontColor, | |
| 88 | + }; | |
| 89 | + }); | |
| 90 | + // console.log(numberList, 'numberList'); | |
| 91 | + }; | |
| 92 | + | |
| 93 | + onMounted(() => { | |
| 94 | + newPercentList.value = percentList.value; | |
| 95 | + !props.config.option.uuid; | |
| 96 | + }); | |
| 97 | + | |
| 98 | + useMultipleDataFetch(props, updateFn); | |
| 99 | + | |
| 100 | + // const { getScale } = useComponentScale(props); | |
| 101 | +</script> | |
| 102 | + | |
| 103 | +<template> | |
| 104 | + <main class="w-full h-full flex flex-col justify-center"> | |
| 105 | + <DeviceName :config="config" /> | |
| 106 | + | |
| 107 | + <div | |
| 108 | + v-for="item in newPercentList" | |
| 109 | + :key="item.id" | |
| 110 | + class="flex flex-col ml-3 mr-3 items-stretch" | |
| 111 | + > | |
| 112 | + <div class="flex justify-between"> | |
| 113 | + <div class="text-gray-500 text-lg truncate">{{ item.name || '温度' }}</div> | |
| 114 | + <span class="text-lg" :style="{ color: item.fontColor }" | |
| 115 | + >{{ item.value }} {{ item.unit }}</span | |
| 116 | + > | |
| 117 | + </div> | |
| 118 | + <div> | |
| 119 | + <Progress :strokeColor="item.backgroundColor" :percent="item.value" :showInfo="false" /> | |
| 120 | + </div> | |
| 121 | + </div> | |
| 122 | + </main> | |
| 123 | +</template> | |
| 124 | +<style lang="less" scoped> | |
| 125 | + // :deep(.ant-progress-success-bg, .ant-progress-bg) { | |
| 126 | + // background: '#2196F3' !important; | |
| 127 | + // } | |
| 128 | +</style> | ... | ... |
| 1 | +import cloneDeep from 'lodash-es/cloneDeep'; | |
| 2 | +import { ValueList2Config } from '.'; | |
| 3 | +import { | |
| 4 | + ConfigType, | |
| 5 | + CreateComponentType, | |
| 6 | + PublicComponentOptions, | |
| 7 | + PublicPresetOptions, | |
| 8 | +} from '/@/views/visual/packages/index.type'; | |
| 9 | +import { PublicConfigClass, componentInitConfig } from '/@/views/visual/packages/publicConfig'; | |
| 10 | +import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum'; | |
| 11 | + | |
| 12 | +export const option: PublicPresetOptions = { | |
| 13 | + multipleDataSourceComponent: true, | |
| 14 | + [ComponentConfigFieldEnum.UNIT]: '℃', | |
| 15 | + [ComponentConfigFieldEnum.ICON]: 'shuiwen', | |
| 16 | + [ComponentConfigFieldEnum.ICON_COLOR]: '#367bff', | |
| 17 | + [ComponentConfigFieldEnum.FONT_COLOR]: '#000', | |
| 18 | + [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]: false, | |
| 19 | +}; | |
| 20 | + | |
| 21 | +export default class Config extends PublicConfigClass implements CreateComponentType { | |
| 22 | + public key: string = ValueList2Config.key; | |
| 23 | + | |
| 24 | + public attr = { ...componentInitConfig }; | |
| 25 | + | |
| 26 | + public componentConfig: ConfigType = cloneDeep(ValueList2Config); | |
| 27 | + | |
| 28 | + public persetOption = cloneDeep(option); | |
| 29 | + | |
| 30 | + public option: PublicComponentOptions; | |
| 31 | + | |
| 32 | + constructor(option: PublicComponentOptions) { | |
| 33 | + super(); | |
| 34 | + this.option = { ...option }; | |
| 35 | + } | |
| 36 | +} | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { ComponentConfigFieldEnum } from '/@/views/visual/packages/enum'; | |
| 3 | + import { useForm, BasicForm } from '/@/components/Form'; | |
| 4 | + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 5 | + import { option } from './config'; | |
| 6 | + | |
| 7 | + const [register, { getFieldsValue, setFieldsValue, resetFields }] = useForm({ | |
| 8 | + schemas: [ | |
| 9 | + { | |
| 10 | + field: ComponentConfigFieldEnum.FONT_COLOR, | |
| 11 | + label: '数值字体颜色', | |
| 12 | + component: 'ColorPicker', | |
| 13 | + changeEvent: 'update:value', | |
| 14 | + valueField: 'value', | |
| 15 | + defaultValue: option.fontColor, | |
| 16 | + }, | |
| 17 | + { | |
| 18 | + field: ComponentConfigFieldEnum.UNIT, | |
| 19 | + label: '数值单位', | |
| 20 | + component: 'Input', | |
| 21 | + defaultValue: option.unit, | |
| 22 | + componentProps: { | |
| 23 | + placeholder: '请输入数值单位', | |
| 24 | + }, | |
| 25 | + }, | |
| 26 | + { | |
| 27 | + field: ComponentConfigFieldEnum.ICON_COLOR, | |
| 28 | + label: '图标颜色', | |
| 29 | + component: 'ColorPicker', | |
| 30 | + changeEvent: 'update:value', | |
| 31 | + defaultValue: option.iconColor, | |
| 32 | + }, | |
| 33 | + { | |
| 34 | + field: ComponentConfigFieldEnum.ICON, | |
| 35 | + label: '图标', | |
| 36 | + component: 'IconDrawer', | |
| 37 | + changeEvent: 'update:value', | |
| 38 | + valueField: 'value', | |
| 39 | + defaultValue: option.icon, | |
| 40 | + componentProps({ formModel }) { | |
| 41 | + const color = formModel[ComponentConfigFieldEnum.ICON_COLOR]; | |
| 42 | + return { | |
| 43 | + color, | |
| 44 | + }; | |
| 45 | + }, | |
| 46 | + }, | |
| 47 | + { | |
| 48 | + field: ComponentConfigFieldEnum.SHOW_DEVICE_NAME, | |
| 49 | + label: '显示设备名称', | |
| 50 | + component: 'Checkbox', | |
| 51 | + defaultValue: option.showDeviceName, | |
| 52 | + }, | |
| 53 | + ], | |
| 54 | + showActionButtonGroup: false, | |
| 55 | + labelWidth: 120, | |
| 56 | + baseColProps: { | |
| 57 | + span: 12, | |
| 58 | + }, | |
| 59 | + }); | |
| 60 | + | |
| 61 | + const getFormValues = () => { | |
| 62 | + return getFieldsValue(); | |
| 63 | + }; | |
| 64 | + | |
| 65 | + const setFormValues = (data: Recordable) => { | |
| 66 | + return setFieldsValue(data); | |
| 67 | + }; | |
| 68 | + | |
| 69 | + defineExpose({ | |
| 70 | + getFormValues, | |
| 71 | + setFormValues, | |
| 72 | + resetFormValues: resetFields, | |
| 73 | + } as PublicFormInstaceType); | |
| 74 | +</script> | |
| 75 | + | |
| 76 | +<template> | |
| 77 | + <BasicForm @register="register" /> | |
| 78 | +</template> | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { commonDataSourceSchemas } from '../../../config/common.config'; | |
| 3 | + import { BasicForm, useForm } from '/@/components/Form'; | |
| 4 | + import { PublicFormInstaceType } from '/@/views/visual/dataSourceBindPanel/index.type'; | |
| 5 | + | |
| 6 | + // const props = defineProps<{ | |
| 7 | + // values: PublicComponentDataSourceProps; | |
| 8 | + // }>(); | |
| 9 | + | |
| 10 | + const [register, { getFieldsValue, setFieldsValue, validate, resetFields }] = useForm({ | |
| 11 | + labelWidth: 0, | |
| 12 | + showActionButtonGroup: false, | |
| 13 | + layout: 'horizontal', | |
| 14 | + labelCol: { span: 0 }, | |
| 15 | + schemas: commonDataSourceSchemas(), | |
| 16 | + }); | |
| 17 | + | |
| 18 | + const getFormValues = () => { | |
| 19 | + return getFieldsValue(); | |
| 20 | + }; | |
| 21 | + | |
| 22 | + const setFormValues = (record: Recordable) => { | |
| 23 | + return setFieldsValue(record); | |
| 24 | + }; | |
| 25 | + | |
| 26 | + defineExpose({ | |
| 27 | + getFormValues, | |
| 28 | + setFormValues, | |
| 29 | + validate, | |
| 30 | + resetFormValues: resetFields, | |
| 31 | + } as PublicFormInstaceType); | |
| 32 | +</script> | |
| 33 | + | |
| 34 | +<template> | |
| 35 | + <BasicForm @register="register" /> | |
| 36 | +</template> | ... | ... |
| 1 | +import { useComponentKeys } from '/@/views/visual/packages/hook/useComponentKeys'; | |
| 2 | +import { ConfigType, PackagesCategoryEnum } from '/@/views/visual/packages/index.type'; | |
| 3 | + | |
| 4 | +const componentKeys = useComponentKeys('ValueList2'); | |
| 5 | +export const ValueList2Config: ConfigType = { | |
| 6 | + ...componentKeys, | |
| 7 | + title: '数值列表2', | |
| 8 | + package: PackagesCategoryEnum.TEXT, | |
| 9 | +}; | ... | ... |
| 1 | +<script lang="ts" setup> | |
| 2 | + import { ComponentPropsConfigType, MultipleDataFetchUpdateFn } from '../../../index.type'; | |
| 3 | + | |
| 4 | + import { option } from './config'; | |
| 5 | + import { useMultipleDataFetch } from '/@/views/visual/packages/hook/useSocket'; | |
| 6 | + import { ref, unref } from 'vue'; | |
| 7 | + import { SvgIcon } from '/@/components/Icon'; | |
| 8 | + import { computed } from 'vue'; | |
| 9 | + import { DeviceName } from '/@/views/visual/commonComponents/DeviceName'; | |
| 10 | + | |
| 11 | + const props = defineProps<{ | |
| 12 | + config: ComponentPropsConfigType<typeof option>; | |
| 13 | + }>(); | |
| 14 | + | |
| 15 | + const getDesign = computed(() => { | |
| 16 | + const { persetOption = {}, option } = props.config; | |
| 17 | + const { dataSource = [] } = option || {}; | |
| 18 | + const { | |
| 19 | + unit: persetUnit, | |
| 20 | + fontColor: persetFontColor, | |
| 21 | + icon: persetIcon, | |
| 22 | + iconColor: persetIconColor, | |
| 23 | + } = persetOption || {}; | |
| 24 | + return { | |
| 25 | + dataSource: dataSource.map((item) => { | |
| 26 | + const { fontColor, icon, iconColor, unit } = item.componentInfo; | |
| 27 | + const { attribute, attributeRename } = item; | |
| 28 | + return { | |
| 29 | + unit: unit ?? persetUnit, | |
| 30 | + fontColor: fontColor ?? persetFontColor, | |
| 31 | + icon: icon ?? persetIcon, | |
| 32 | + iconColor: iconColor ?? persetIconColor, | |
| 33 | + attribute: attribute || attributeRename, | |
| 34 | + attributeRename, | |
| 35 | + }; | |
| 36 | + }), | |
| 37 | + }; | |
| 38 | + }); | |
| 39 | + const svgList = ref<any>([ | |
| 40 | + { | |
| 41 | + value: 26.2, | |
| 42 | + name: 'wendu', | |
| 43 | + icon: 'zongfushe', | |
| 44 | + unit: 'kw', | |
| 45 | + iconColor: '#367BFF', | |
| 46 | + fontColor: '#357CFB', | |
| 47 | + }, | |
| 48 | + { | |
| 49 | + value: 53.7, | |
| 50 | + name: 'shidu', | |
| 51 | + icon: 'guangzhaoqiangdu', | |
| 52 | + unit: '℃', | |
| 53 | + iconColor: '#FFA000', | |
| 54 | + fontColor: '#FFA000', | |
| 55 | + }, | |
| 56 | + ]); | |
| 57 | + | |
| 58 | + const updateFn: MultipleDataFetchUpdateFn = (message) => { | |
| 59 | + const { data = {} } = message; | |
| 60 | + const { dataSource } = unref(getDesign); | |
| 61 | + svgList.value.length = 0; | |
| 62 | + svgList.value = dataSource.map((item) => { | |
| 63 | + const { icon, iconColor, unit, fontColor, attribute } = item || {}; | |
| 64 | + const [latest] = data[attribute] || []; | |
| 65 | + const [_timespan, value] = latest || []; | |
| 66 | + return { | |
| 67 | + value: Number(value), | |
| 68 | + name: attribute, | |
| 69 | + icon, | |
| 70 | + unit, | |
| 71 | + iconColor, | |
| 72 | + fontColor, | |
| 73 | + }; | |
| 74 | + }); | |
| 75 | + }; | |
| 76 | + | |
| 77 | + useMultipleDataFetch(props, updateFn); | |
| 78 | +</script> | |
| 79 | + | |
| 80 | +<template> | |
| 81 | + <main class="w-full h-full flex flex-col justify-evenly items-center"> | |
| 82 | + <DeviceName :config="config" /> | |
| 83 | + <div | |
| 84 | + style="width: 86%" | |
| 85 | + v-for="item in svgList" | |
| 86 | + :key="item.id" | |
| 87 | + class="flex justify-between items-center" | |
| 88 | + > | |
| 89 | + <div class="flex items-center"> | |
| 90 | + <SvgIcon | |
| 91 | + :name="item.icon!" | |
| 92 | + prefix="iconfont" | |
| 93 | + :size="45" | |
| 94 | + :style="{ color: item.iconColor }" | |
| 95 | + /> | |
| 96 | + | |
| 97 | + <div class="text-gray-500 text-lg truncate ml-6">{{ item.attribute || '温度' }}</div> | |
| 98 | + </div> | |
| 99 | + | |
| 100 | + <h1 class="font-bold text-xl m-2 truncate" :style="{ color: item.fontColor }"> | |
| 101 | + <span> {{ item.value || 0 }}</span> | |
| 102 | + <span>{{ item.unit }} </span> | |
| 103 | + </h1> | |
| 104 | + </div> | |
| 105 | + </main> | |
| 106 | +</template> | ... | ... |
| ... | ... | @@ -2,10 +2,18 @@ import { TextComponent1Config } from './TextComponent1'; |
| 2 | 2 | import { TextComponent2Config } from './TextComponent2'; |
| 3 | 3 | import { TextComponent3Config } from './TextComponent3'; |
| 4 | 4 | import { TextComponent4Config } from './TextComponent4'; |
| 5 | +import { SwitchSignalLightConfig } from './SwitchSignalLight'; | |
| 6 | +// import { SwitchStatusConfig } from './SwitchStatus'; | |
| 7 | +import { ValueList1Config } from './ValueList1'; | |
| 8 | +// import { ValueList2Config } from './ValueList2'; | |
| 5 | 9 | |
| 6 | 10 | export const TextList = [ |
| 7 | 11 | TextComponent1Config, |
| 8 | 12 | TextComponent2Config, |
| 9 | 13 | TextComponent3Config, |
| 10 | 14 | TextComponent4Config, |
| 15 | + ValueList1Config, | |
| 16 | + // ValueList2Config, | |
| 17 | + SwitchSignalLightConfig, | |
| 18 | + // SwitchStatusConfig, | |
| 11 | 19 | ]; | ... | ... |
| ... | ... | @@ -3,12 +3,15 @@ export enum ComponentConfigFieldEnum { |
| 3 | 3 | UNIT = 'unit', |
| 4 | 4 | POINTER_COLOR = 'pointerColor', |
| 5 | 5 | INSTRUMENT_PANEL_COLOR = 'instrumentPanelColor', |
| 6 | + CONTROL_BAR_COLOR = 'controlBarColor', | |
| 6 | 7 | // INSTRUMENT_PANEL_WIDTH = 'instrumentPanelWidth', |
| 7 | 8 | |
| 8 | 9 | PROGRESS_BAR_CIRCLE = 'progressBarCircle', |
| 9 | 10 | |
| 10 | 11 | ICON_COLOR = 'iconColor', |
| 12 | + ICON_COLOR_CLOSE = 'iconColorClose', | |
| 11 | 13 | ICON = 'icon', |
| 14 | + ICON_CLOSE = 'iconClose', | |
| 12 | 15 | FIRST_PHASE_COLOR = 'firstPhaseColor', |
| 13 | 16 | SECOND_PHASE_COLOR = 'secondPhaseColor', |
| 14 | 17 | THIRD_PHASE_COLOR = 'thirdPhaseColor', |
| ... | ... | @@ -23,4 +26,6 @@ export enum ComponentConfigFieldEnum { |
| 23 | 26 | WAVE_SECOND = 'waveSecond', |
| 24 | 27 | WAVE_THIRD = 'waveThird', |
| 25 | 28 | BACKGROUND_COLOR = 'backgroundColor', |
| 29 | + OPEN_COLOR = 'openColor', | |
| 30 | + CLOSE_COLOR = 'closeColor', | |
| 26 | 31 | } | ... | ... |
| ... | ... | @@ -8,6 +8,7 @@ export const useGetComponentConfig = ( |
| 8 | 8 | ): CreateComponentType => { |
| 9 | 9 | try { |
| 10 | 10 | const config = createComponent({ key: transformComponentKey(key) } as ConfigType, options); |
| 11 | + if (!config) console.error(`can not get component config by component key (${key})`); | |
| 11 | 12 | return config; |
| 12 | 13 | } catch (error) { |
| 13 | 14 | console.error(`can not get component config by component key (${key})`); | ... | ... |
| ... | ... | @@ -20,6 +20,7 @@ export enum PackagesCategoryNameEnum { |
| 20 | 20 | CONTROL = '控制组件', |
| 21 | 21 | MAP = '地图组件', |
| 22 | 22 | FLOWMETER = '流量计', |
| 23 | + STATISTICS = '统计', | |
| 23 | 24 | OTHER = '其他', |
| 24 | 25 | } |
| 25 | 26 | |
| ... | ... | @@ -33,6 +34,7 @@ export enum PackagesCategoryEnum { |
| 33 | 34 | CONTROL = 'CONTROL', |
| 34 | 35 | MAP = 'MAP', |
| 35 | 36 | FLOWMETER = 'FLOWMETER', |
| 37 | + STATISTICS = 'STATISTICS', | |
| 36 | 38 | OTHER = 'OTHER', |
| 37 | 39 | } |
| 38 | 40 | |
| ... | ... | @@ -92,6 +94,7 @@ export interface PublicPresetOptions { |
| 92 | 94 | [ComponentConfigFieldEnum.UNIT]?: string; |
| 93 | 95 | [ComponentConfigFieldEnum.ICON_COLOR]?: string; |
| 94 | 96 | [ComponentConfigFieldEnum.ICON]?: string; |
| 97 | + [ComponentConfigFieldEnum.CONTROL_BAR_COLOR]?: string; | |
| 95 | 98 | [ComponentConfigFieldEnum.SHOW_DEVICE_NAME]?: boolean; |
| 96 | 99 | [ComponentConfigFieldEnum.PROGRESS_BAR_CIRCLE]?: boolean; |
| 97 | 100 | [ComponentConfigFieldEnum.GRADIENT_INFO]?: ComponentInfoGradientInfoType[]; |
| ... | ... | @@ -134,6 +137,7 @@ export interface PackagesType { |
| 134 | 137 | [PackagesCategoryEnum.CONTROL]: ConfigType[]; |
| 135 | 138 | [PackagesCategoryEnum.MAP]: ConfigType[]; |
| 136 | 139 | [PackagesCategoryEnum.FLOWMETER]: ConfigType[]; |
| 140 | + [PackagesCategoryEnum.STATISTICS]: ConfigType[]; | |
| 137 | 141 | [PackagesCategoryEnum.OTHER]: ConfigType[]; |
| 138 | 142 | } |
| 139 | 143 | ... | ... |
| ... | ... | @@ -5,6 +5,7 @@ import { MapList } from './components/Map'; |
| 5 | 5 | import { OtherList } from './components/Other'; |
| 6 | 6 | import { PictureList } from './components/Picture'; |
| 7 | 7 | import { TextList } from './components/Text'; |
| 8 | +import { STATISTICSList } from './components/Statistics'; | |
| 8 | 9 | import { PackagesCategoryEnum, PackagesType } from './index.type'; |
| 9 | 10 | |
| 10 | 11 | export const packageList: PackagesType = { |
| ... | ... | @@ -14,5 +15,6 @@ export const packageList: PackagesType = { |
| 14 | 15 | [PackagesCategoryEnum.CONTROL]: ControlList, |
| 15 | 16 | [PackagesCategoryEnum.MAP]: MapList, |
| 16 | 17 | [PackagesCategoryEnum.FLOWMETER]: FlowmeterList, |
| 18 | + [PackagesCategoryEnum.STATISTICS]: STATISTICSList, | |
| 17 | 19 | [PackagesCategoryEnum.OTHER]: OtherList, |
| 18 | 20 | }; | ... | ... |