Commit 11a3a6df9518ad551cfd23119138bafc5117cb00

Authored by xp.Huang
2 parents 2bebc57c 0794e0b7

Merge branch 'ft' into 'main_dev'

perf(src/packages): 重写图表里的饼图-环形等组件

See merge request yunteng/thingskit-view!76
Showing 26 changed files with 961 additions and 57 deletions
... ... @@ -10,11 +10,11 @@ export const useChartInteract = (
10 10 chartConfig: CreateComponentType,
11 11 useChartEditStore: ChartEditStoreType,
12 12 param: { [T: string]: any },
13   - interactEventOn: string
  13 + interactEventOn: string,
  14 + status: boolean
14 15 ) => {
15 16 const chartEditStore = useChartEditStore()
16 17 const { interactEvents } = chartConfig.events
17   - const { selectCurrentItems } = chartConfig.option
18 18 const { selectTargetItems } = chartConfig.option
19 19 const fnOnEvent = interactEvents.filter(item => {
20 20 return item.interactOn === interactEventOn
... ... @@ -32,19 +32,35 @@ export const useChartInteract = (
32 32 Header.value[key] = param[item.interactFn[key]]
33 33 }
34 34 })
35   - setJump(selectCurrentItems, selectTargetItems)
  35 + setTabJump(selectTargetItems)
36 36 })
37   - function setJump(selectCurrentItems: string[], selectTargetItems: string[]) {
  37 + function setTabJump(selectTargetItems: string[]) {
  38 + /**
  39 + * 逻辑
  40 + * 排除按钮组件
  41 + * 先遍历图表数组,只要是目标项,则认为是联动绑定,新增一个属性是否是联动组件设置为true
  42 + * 在遍历图表数组,只要是目标项并且是联动组件则显示,否则隐藏
  43 + */
38 44 try {
  45 + chartEditStore.componentList.forEach((item: any) => {
  46 + if (item.key !== 'Button') {
  47 + if (selectTargetItems.includes(item.id)) {
  48 + item.isInteractComponent = true
  49 + }
  50 + }
  51 + })
39 52 //优化循环性能
40 53 for (let i = 0, len = chartEditStore.componentList.length; i < len; i++) {
41 54 const compId = chartEditStore.componentList[i].id
42   - const compItem = chartEditStore.componentList[i]
43   - if (selectCurrentItems.includes(compId)) {
44   - compItem.status.hide = true
45   - }
46   - if (selectTargetItems.includes(compId)) {
47   - compItem.status.hide = false
  55 + const compItem = chartEditStore.componentList[i] as any
  56 + if (status) {
  57 + if (compItem.key !== 'Button') {
  58 + if (selectTargetItems.includes(compId) && compItem.isInteractComponent) {
  59 + compItem.status.hide = false
  60 + } else if (!selectTargetItems.includes(compId) && compItem.isInteractComponent) {
  61 + compItem.status.hide = true
  62 + }
  63 + }
48 64 }
49 65 }
50 66 } finally {
... ...
  1 +import { PublicConfigClass } from '@/packages/public'
  2 +import { CreateComponentType } from '@/packages/index.d'
  3 +import { OverrideProcessConfig } from './index'
  4 +import { chartInitConfig } from '@/settings/designSetting'
  5 +import cloneDeep from 'lodash/cloneDeep'
  6 +
  7 +
  8 +export const types = [
  9 + {
  10 + label: '线形',
  11 + value: 'line'
  12 + },
  13 + {
  14 + label: '圆形',
  15 + value: 'circle'
  16 + },
  17 + {
  18 + label: '仪表盘',
  19 + value: 'dashboard'
  20 + },
  21 +]
  22 +
  23 +export const indicatorPlacements = [
  24 + {
  25 + label: '内部',
  26 + value: 'inside'
  27 + },
  28 + {
  29 + label: '外部',
  30 + value: 'outside'
  31 + }
  32 +]
  33 +
  34 +export const option = {
  35 + dataset: 36,
  36 + // 默认类型
  37 + type: types[2].value,
  38 + // 进行时效果
  39 + processing: true,
  40 + // 主颜色
  41 + color: '#4992FFFF',
  42 + // 轨道颜色
  43 + railColor: '#3e3e3f',
  44 + // 指标
  45 + unit: '%',
  46 + // 指标大小
  47 + indicatorTextSize: 34,
  48 + // 指标位置(线条时可用)
  49 + indicatorPlacement: 'outside',
  50 + // 指标颜色
  51 + indicatorTextColor: '#FFFFFFFF',
  52 + // 偏移角度
  53 + offsetDegree: 0
  54 +}
  55 +
  56 +export default class Config extends PublicConfigClass implements CreateComponentType {
  57 + public key = OverrideProcessConfig.key
  58 + public attr = { ...chartInitConfig, h: 500, zIndex: -1 }
  59 + public chartConfig = cloneDeep(OverrideProcessConfig)
  60 + public option = cloneDeep(option)
  61 +}
\ No newline at end of file
... ...
  1 +<template>
  2 + <!-- 默认展开 -->
  3 + <CollapseItem name="进度条" :expanded="true">
  4 + <SettingItemBox name="内容">
  5 + <SettingItem name="数值">
  6 + <!-- 与 config.ts 里的 option 对应 --><!-- n-input-number 是 NaiveUI 的控件 -->
  7 + <n-input-number v-model:value="optionData.dataset" size="small" :min="0" placeholder="进度值"></n-input-number>
  8 + </SettingItem>
  9 + <setting-item name="单位">
  10 + <n-input v-model:value="optionData.unit" size="small"></n-input>
  11 + </setting-item>
  12 + </SettingItemBox>
  13 +
  14 + <SettingItemBox name="轨道">
  15 + <SettingItem name="形状">
  16 + <n-select v-model:value="optionData.type" :options="types" placeholder="选择形状" />
  17 + </SettingItem>
  18 +
  19 + <!-- 颜色粗细等等... -->
  20 + <SettingItem name="进度条颜色">
  21 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.color"></n-color-picker>
  22 + </SettingItem>
  23 + <SettingItem name="轨道颜色">
  24 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.railColor"></n-color-picker>
  25 + </SettingItem>
  26 + <setting-item name="偏移角度" v-if="optionData.type !== types[0].value">
  27 + <n-input-number v-model:value="optionData.offsetDegree" size="small"></n-input-number>
  28 + </setting-item>
  29 + <SettingItem v-if="optionData.type == types[0].value">
  30 + <n-space>
  31 + <n-switch v-model:value="optionData.processing" size="small" />
  32 + <n-text>进行时动画</n-text>
  33 + </n-space>
  34 + </SettingItem>
  35 + </SettingItemBox>
  36 +
  37 + <SettingItemBox name="指标">
  38 + <SettingItem name="位置" v-if="optionData.type == types[0].value">
  39 + <n-select v-model:value="optionData.indicatorPlacement" :options="indicatorPlacements" placeholder="选择形状" />
  40 + </SettingItem>
  41 + <SettingItem name="文本颜色">
  42 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.indicatorTextColor"></n-color-picker>
  43 + </SettingItem>
  44 + <setting-item name="文本大小">
  45 + <n-input-number v-model:value="optionData.indicatorTextSize" size="small"></n-input-number>
  46 + </setting-item>
  47 + </SettingItemBox>
  48 + </CollapseItem>
  49 +</template>
  50 +
  51 +<script setup lang="ts">
  52 +import { PropType } from 'vue'
  53 +// 以下是封装的设置模块布局组件,具体效果可在官网查看
  54 +import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
  55 +
  56 +// 获取 option 的数据,便于使用 typeof 获取类型
  57 +import { option, types, indicatorPlacements } from './config'
  58 +
  59 +defineProps({
  60 + optionData: {
  61 + type: Object as PropType<typeof option>,
  62 + required: true
  63 + }
  64 +})
  65 +</script>
... ...
  1 +
  2 +
  3 +import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
  4 +import { ChatCategoryEnum, ChatCategoryEnumName } from '@/packages/components/Charts/index.d'
  5 +import { useWidgetKey } from '@/packages/external/useWidgetKey'
  6 +
  7 +const { key, conKey, chartKey } = useWidgetKey('OverrideProcess', true)
  8 +
  9 +export const OverrideProcessConfig: ConfigType = {
  10 + key,
  11 + chartKey,
  12 + conKey,
  13 + title: '自定义NaiveUI-进度',
  14 + category: ChatCategoryEnum.MORE,
  15 + categoryName: ChatCategoryEnumName.MORE,
  16 + package: PackagesCategoryEnum.CHARTS,
  17 + chartFrame: ChartFrameEnum.ECHARTS,
  18 + image: 'process.png'
  19 +}
... ...
  1 +<template>
  2 + <n-progress
  3 + :type="type"
  4 + :height="h"
  5 + :processing="processing"
  6 + :percentage="dataset"
  7 + :indicator-placement="indicatorPlacement"
  8 + :color="color"
  9 + :rail-color="railColor"
  10 + :offset-degree="offsetDegree"
  11 + >
  12 + <n-text
  13 + :style="{
  14 + color: indicatorTextColor,
  15 + fontSize: `${indicatorTextSize}px`
  16 + }"
  17 + >
  18 + {{ dataset }} {{ unit }}
  19 + </n-text>
  20 + </n-progress>
  21 +</template>
  22 +
  23 +<script setup lang="ts">
  24 +import { PropType, toRefs, watch } from 'vue'
  25 +import { useChartDataFetch } from '@/hooks'
  26 +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  27 +import config from './config'
  28 +import { toNumber } from '@/utils'
  29 +
  30 +const props = defineProps({
  31 + chartConfig: {
  32 + type: Object as PropType<config>,
  33 + required: true
  34 + }
  35 +})
  36 +
  37 +// 取配置数据
  38 +const { w, h } = toRefs(props.chartConfig.attr)
  39 +const {
  40 + type,
  41 + unit,
  42 + color,
  43 + processing,
  44 + railColor,
  45 + indicatorTextColor,
  46 + indicatorPlacement,
  47 + indicatorTextSize,
  48 + offsetDegree,
  49 + dataset
  50 +} = toRefs(props.chartConfig.option)
  51 +
  52 +// 手动更新
  53 +watch(
  54 + () => props.chartConfig.option.dataset,
  55 + (newData: any) => {
  56 + try {
  57 + dataset.value = toNumber(newData, 2)
  58 + } catch (error) {
  59 + console.log(error)
  60 + }
  61 + },
  62 + {
  63 + deep: false
  64 + }
  65 +)
  66 +// 预览更新
  67 +useChartDataFetch(props.chartConfig, useChartEditStore, (newData: number) => {
  68 + dataset.value = toNumber(newData, 2)
  69 +})
  70 +</script>
... ...
  1 +import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public'
  2 +import { OverridePieCircleConfig } from './index'
  3 +import { CreateComponentType } from '@/packages/index.d'
  4 +import cloneDeep from 'lodash/cloneDeep'
  5 +
  6 +export const includes = []
  7 +
  8 +const option = {
  9 + tooltip: {
  10 + show: true,
  11 + trigger: 'item'
  12 + },
  13 + legend: {
  14 + show: true,
  15 + },
  16 + dataset: 0.25,
  17 + title: {
  18 + text: 25 + "%",
  19 + x: "center",
  20 + y: "center",
  21 + textStyle: {
  22 + color: "#56B9F8",
  23 + fontSize: 30
  24 + }
  25 + },
  26 + series: [
  27 + {
  28 + type: "pie",
  29 + radius: ["75%", "80%"],
  30 + center: ["50%", "50%"],
  31 + hoverAnimation: true,
  32 + color: ["#00bcd44a", "transparent"],
  33 + label: {
  34 + show: false
  35 + },
  36 + data: [
  37 + {
  38 + value: [25],
  39 + itemStyle: {
  40 + color: "#03a9f4",
  41 + shadowBlur: 10,
  42 + shadowColor:"#97e2f5"
  43 + }
  44 + },
  45 + {
  46 + value: [75],
  47 + itemStyle: {
  48 + color: "#00bcd44a",
  49 + shadowBlur: 0,
  50 + shadowColor:"#00bcd44a"
  51 + }
  52 + }
  53 + ]
  54 + },
  55 + ]
  56 +}
  57 +
  58 +export default class Config extends PublicConfigClass implements CreateComponentType {
  59 + public key: string = OverridePieCircleConfig.key
  60 +
  61 + public chartConfig = cloneDeep(OverridePieCircleConfig)
  62 +
  63 + // 图表配置项
  64 + public option = echartOptionProfixHandle(option, includes)
  65 +}
... ...
  1 +<template>
  2 + <!-- 遍历 seriesList -->
  3 + <CollapseItem v-for="(item, index) in config.series" :key="index" :name="`圆环`" :expanded="true">
  4 + <SettingItemBox name="数据">
  5 + <SettingItem name="数值">
  6 + <n-input-number v-model:value="config.dataset" :min="0" :max="1" :step="0.01" size="small" placeholder="数值">
  7 + </n-input-number>
  8 + </SettingItem>
  9 + </SettingItemBox>
  10 + <!-- Echarts 全局设置 -->
  11 + <SettingItemBox name="进度条">
  12 + <SettingItem name="颜色">
  13 + <n-color-picker size="small" :modes="['hex']" v-model:value="item.data[0].itemStyle.color"></n-color-picker>
  14 + </SettingItem>
  15 + <SettingItem name="阴影模糊等级">
  16 + <n-input-number
  17 + v-model:value="item.data[0].itemStyle.shadowBlur"
  18 + :min="0"
  19 + :max="50"
  20 + :step="1"
  21 + size="small"
  22 + placeholder="阴影模糊等级"
  23 + >
  24 + </n-input-number>
  25 + </SettingItem>
  26 + <SettingItem name="阴影颜色">
  27 + <n-color-picker
  28 + size="small"
  29 + :modes="['hex']"
  30 + v-model:value="item.data[0].itemStyle.shadowColor"
  31 + ></n-color-picker>
  32 + </SettingItem>
  33 + </SettingItemBox>
  34 + <!-- 中心标题 -->
  35 + <SettingItemBox v-if="config.title" name="标题">
  36 + <SettingItem name="颜色">
  37 + <n-color-picker size="small" :modes="['hex']" v-model:value="config.title.textStyle.color"></n-color-picker>
  38 + </SettingItem>
  39 + <SettingItem name="字体大小">
  40 + <n-input-number
  41 + v-model:value="config.title.textStyle.fontSize"
  42 + :min="0"
  43 + :step="1"
  44 + size="small"
  45 + placeholder="字体大小"
  46 + >
  47 + </n-input-number>
  48 + </SettingItem>
  49 + </SettingItemBox>
  50 + <!-- 其他样式 -->
  51 + <SettingItemBox name="轨道样式">
  52 + <SettingItem name="颜色">
  53 + <n-color-picker size="small" :modes="['hex']" v-model:value="item.data[1].itemStyle.color"></n-color-picker>
  54 + </SettingItem>
  55 + <SettingItem name="阴影模糊等级">
  56 + <n-input-number
  57 + v-model:value="item.data[1].itemStyle.shadowBlur"
  58 + :min="0"
  59 + :step="1"
  60 + size="small"
  61 + placeholder="阴影模糊等级"
  62 + >
  63 + </n-input-number>
  64 + </SettingItem>
  65 + <SettingItem name="阴影颜色">
  66 + <n-color-picker
  67 + size="small"
  68 + :modes="['hex']"
  69 + v-model:value="item.data[1].itemStyle.shadowColor"
  70 + ></n-color-picker>
  71 + </SettingItem>
  72 + </SettingItemBox>
  73 + </CollapseItem>
  74 +</template>
  75 +
  76 +<script setup lang="ts">
  77 +import { PropType, computed } from 'vue'
  78 +// 以下是封装的设置模块布局组件,具体效果可在官网查看
  79 +import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
  80 +import { GlobalThemeJsonType } from '@/settings/chartThemes'
  81 +
  82 +const props = defineProps({
  83 + optionData: {
  84 + type: Object as PropType<GlobalThemeJsonType>,
  85 + required: true
  86 + }
  87 +})
  88 +
  89 +const config = computed(() => {
  90 + return props.optionData
  91 +})
  92 +</script>
... ...
  1 +import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
  2 +import { ChatCategoryEnum, ChatCategoryEnumName } from '@/packages/components/Charts/index.d'
  3 +import { useWidgetKey } from '@/packages/external/useWidgetKey'
  4 +
  5 +const { key, conKey, chartKey } = useWidgetKey('OverridePieCircle', true)
  6 +
  7 +export const OverridePieCircleConfig: ConfigType = {
  8 + key,
  9 + chartKey,
  10 + conKey,
  11 + title: '自定义饼图-环形',
  12 + category: ChatCategoryEnum.PIE,
  13 + categoryName: ChatCategoryEnumName.PIE,
  14 + package: PackagesCategoryEnum.CHARTS,
  15 + chartFrame: ChartFrameEnum.ECHARTS,
  16 + image: 'pie-circle.png'
  17 +}
... ...
  1 +<template>
  2 + <v-chart :theme="themeColor" :init-options="initOptions" :option="option.value" autoresize> </v-chart>
  3 +</template>
  4 +
  5 +<script setup lang="ts">
  6 +import { PropType, reactive, watch } from 'vue'
  7 +import VChart from 'vue-echarts'
  8 +import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook'
  9 +import { use } from 'echarts/core'
  10 +import { CanvasRenderer } from 'echarts/renderers'
  11 +import { PieChart } from 'echarts/charts'
  12 +import { mergeTheme } from '@/packages/public/chart'
  13 +import config, { includes } from './config'
  14 +import { useChartDataFetch } from '@/hooks'
  15 +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  16 +import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent, TitleComponent } from 'echarts/components'
  17 +
  18 +const props = defineProps({
  19 + themeSetting: {
  20 + type: Object,
  21 + required: true
  22 + },
  23 + themeColor: {
  24 + type: Object,
  25 + required: true
  26 + },
  27 + chartConfig: {
  28 + type: Object as PropType<config>,
  29 + required: true
  30 + }
  31 +})
  32 +
  33 +const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting)
  34 +
  35 +use([DatasetComponent, CanvasRenderer, PieChart, GridComponent, TooltipComponent, LegendComponent, TitleComponent])
  36 +
  37 +const option = reactive({
  38 + value: {}
  39 +})
  40 +
  41 +const dataHandle = (newData: any) => {
  42 + const d = parseFloat(`${newData}`) * 100
  43 + let config = props.chartConfig.option
  44 + config.title.text = d.toFixed(0) + '%'
  45 + config.series[0].data[0].value[0] = d
  46 + config.series[0].data[1].value[0] = 100 - d
  47 + option.value = mergeTheme(props.chartConfig.option, props.themeSetting, includes)
  48 + option.value = props.chartConfig.option
  49 +}
  50 +
  51 +// 配置时
  52 +watch(
  53 + () => props.chartConfig.option.dataset,
  54 + newData => {
  55 + try {
  56 + dataHandle(newData)
  57 + } catch (error) {
  58 + console.log(error)
  59 + }
  60 + },
  61 + {
  62 + immediate: true,
  63 + deep: false
  64 + }
  65 +)
  66 +
  67 +// 预览时
  68 +useChartDataFetch(props.chartConfig, useChartEditStore, (resData: number) => {
  69 + let d = parseFloat(`${resData}`) * 100
  70 + // @ts-ignore
  71 + option.value.title.text = d.toFixed(0) + '%'
  72 + // @ts-ignore
  73 + option.value.series[0].data[0].value[0] = d
  74 + // @ts-ignore
  75 + option.value.series[0].data[1].value[0] = 100 - d
  76 +})
  77 +</script>
... ...
... ... @@ -18,7 +18,6 @@ export const option = {
18 18 buttonColor: '',
19 19 buttonTextColor: 'white',
20 20 buttonTextSize: '16',
21   - selectCurrentItems: [],
22 21 selectTargetItems: []
23 22 }
24 23
... ...
... ... @@ -29,42 +29,29 @@
29 29 </setting-item>
30 30 </setting-item-box>
31 31 <setting-item-box :alone="true">
  32 + <setting-item name="按钮文字" :alone="true">
  33 + <n-input v-model:value="optionData.dataset" size="small" placeholder="按钮文字"></n-input>
  34 + </setting-item>
  35 + </setting-item-box>
  36 + <setting-item-box :alone="true">
32 37 <template #name>
33   - <n-text>跳转</n-text>
  38 + <n-text>目标</n-text>
34 39 <n-tooltip trigger="hover">
35 40 <template #trigger>
36 41 <n-icon size="21" :depth="3">
37 42 <help-outline-icon></help-outline-icon>
38 43 </n-icon>
39 44 </template>
40   - <span class="help-span">{{ threeFileHelpMessgae }}</span>
  45 + <span class="help-span">{{ targetHelpMessgae }}</span>
41 46 </n-tooltip>
42 47 </template>
43   - <setting-item name="按钮文字" :alone="true">
44   - <n-input v-model:value="optionData.dataset" size="small" placeholder="按钮文字"></n-input>
45   - </setting-item>
46   - </setting-item-box>
47   - <setting-item-box name="当前项">
48   - <setting-item name="当前项" :alone="true">
49   - <n-select
50   - placeholder="请选择当前项"
51   - multiple
52   - size="small"
53   - v-model:value="optionData.selectCurrentItems"
54   - :options="selectCurrentItemOptions"
55   - />
56   - </setting-item>
57   - </setting-item-box>
58   - <setting-item-box name="目标项">
59   - <setting-item name="目标项" :alone="true">
60   - <n-select
61   - placeholder="请选择目标项"
62   - multiple
63   - size="small"
64   - v-model:value="optionData.selectTargetItems"
65   - :options="selectTargetItemOptions"
66   - />
67   - </setting-item>
  48 + <n-select
  49 + style="width: 13.5vw"
  50 + placeholder="请选择目标项"
  51 + multiple
  52 + v-model:value="optionData.selectTargetItems"
  53 + :options="selectTargetItemOptions"
  54 + />
68 55 </setting-item-box>
69 56 </collapse-item>
70 57 </template>
... ... @@ -87,7 +74,7 @@ const chartEditStore = useChartEditStore()
87 74
88 75 const { HelpOutlineIcon } = icon.ionicons5
89 76
90   -const threeFileHelpMessgae = ref(`勾选当前项和跳转的目标项`)
  77 +const targetHelpMessgae = ref(`勾选目标项,支持多个`)
91 78
92 79 const buttonTypeOptions = [
93 80 {
... ... @@ -120,8 +107,6 @@ const buttonTypeOptions = [
120 107 }
121 108 ]
122 109
123   -const selectCurrentItemOptions = ref<{ label: string; value: string }[]>([])
124   -
125 110 const selectTargetItemOptions = ref<{ label: string; value: string }[]>([])
126 111
127 112 onMounted(() => {
... ... @@ -129,7 +114,6 @@ onMounted(() => {
129 114 label: item.chartConfig?.title,
130 115 value: item.id
131 116 }))
132   - selectCurrentItemOptions.value = componentList
133 117 selectTargetItemOptions.value = componentList
134 118 })
135 119 </script>
... ...
... ... @@ -5,7 +5,7 @@
5 5 :dashed="buttonDashed"
6 6 :ghost="buttonGhost"
7 7 :color="buttonColor"
8   - @click="onClick(option.value.dataset)"
  8 + @click="onClick(option.value.selectTargetItems, true)"
9 9 >
10 10 <span class="button-text-color">{{ dataset }}</span>
11 11 </n-button>
... ... @@ -28,24 +28,27 @@ const props = defineProps({
28 28 })
29 29
30 30 const { w, h } = toRefs(props.chartConfig.attr)
  31 +
31 32 const { buttonType, buttonDashed, buttonGhost, buttonColor, buttonTextColor, buttonTextSize, dataset } = toRefs(
32 33 props.chartConfig.option
33 34 )
  35 +
34 36 const option = shallowReactive({
35 37 value: cloneDeep(props.chartConfig.option)
36 38 })
37 39
38   -const onClick = (v: any) => {
  40 +const onClick = (v: any, status: boolean) => {
39 41 useChartInteract(
40 42 props.chartConfig,
41 43 useChartEditStore,
42 44 { [ComponentInteractParamsEnum.DATA]: v },
43   - InteractEventOn.CHANGE
  45 + InteractEventOn.CHANGE,
  46 + status
44 47 )
45 48 }
46 49
47 50 onMounted(() => {
48   - onClick(option.value.dataset)
  51 + onClick(option.value.selectTargetItems, false)
49 52 })
50 53
51 54 // 手动更新
... ...
... ... @@ -17,11 +17,13 @@ export const option = {
17 17 textColor: 'black',
18 18 textBackgroundColor: 'white',
19 19 textBackgroundColorAlpha: 1,
20   - iconColor:'black',
  20 + iconColor: 'black',
21 21 //弹出下拉框
22 22 textSelectModalBackgroundColor: 'white',
23 23 textSelectModalTextColor: 'black'
24   - }
  24 + },
  25 + //是否开启前一周
  26 + openLastWeek: false
25 27 }
26 28
27 29 export default class Config extends PublicConfigClass implements CreateComponentType {
... ...
... ... @@ -6,9 +6,19 @@
6 6 </collapse-item>
7 7
8 8 <collapse-item name="时间配置" :expanded="true">
  9 + <setting-item-box name="近一周">
  10 + <setting-item>
  11 + <n-switch @change="handleChange" v-model:value="optionData.openLastWeek" size="small"></n-switch>
  12 + </setting-item>
  13 + </setting-item-box>
9 14 <setting-item-box name="基础">
10 15 <setting-item name="类型">
11   - <n-select v-model:value="optionData.componentInteractEventKey" size="small" :options="datePickerTypeOptions" />
  16 + <n-select
  17 + @change="handleSelect"
  18 + v-model:value="optionData.componentInteractEventKey"
  19 + size="small"
  20 + :options="datePickerTypeOptions"
  21 + />
12 22 </setting-item>
13 23 </setting-item-box>
14 24
... ... @@ -159,4 +169,12 @@ const datePickerTypeOptions = [
159 169 value: ComponentInteractEventEnum.QUARTER_RANGE
160 170 }
161 171 ]
  172 +const handleChange = (value: boolean) => {
  173 + if (!value) return
  174 + const lastWeekEnd = new Date(new Date().toLocaleDateString()).getTime() - 7 * 24 * 3600 * 1000
  175 + const lastWeekStart = new Date().getTime()
  176 + props.optionData.dataset = [lastWeekEnd, lastWeekStart] as any
  177 +}
  178 +
  179 +const handleSelect = (value: string) => (props.optionData.openLastWeek = false)
162 180 </script>
... ...
... ... @@ -79,6 +79,21 @@ watch(
79 79 immediate: true
80 80 }
81 81 )
  82 +
  83 +watch(
  84 + () => props.chartConfig.option.openLastWeek,
  85 + newData => {
  86 + if (!newData) return
  87 + const lastWeekEnd = new Date(new Date().toLocaleDateString()).getTime() - 7 * 24 * 3600 * 1000
  88 + const lastWeekStart = new Date().getTime()
  89 + props.chartConfig.option.componentInteractEventKey = 'daterange'
  90 + option.dataset = [lastWeekEnd, lastWeekStart]
  91 + onChange(option.dataset)
  92 + },
  93 + {
  94 + immediate: true
  95 + }
  96 +)
82 97 </script>
83 98
84 99 <style lang="scss" scoped>
... ... @@ -98,8 +113,8 @@ watch(
98 113 .n-base-icon {
99 114 color: v-bind('iconColor') !important;
100 115 }
101   - .n-date-panel{
102   - background: v-bind('textSelectModalBackgroundColor') !important;;
  116 + .n-date-panel {
  117 + background: v-bind('textSelectModalBackgroundColor') !important;
103 118 }
104 119 }
105 120 </style>
... ...
... ... @@ -2,6 +2,7 @@ import { PublicConfigClass } from '@/packages/public'
2 2 import { CreateComponentType } from '@/packages/index.d'
3 3 import { OverrideTextCommonConfig } from './index'
4 4 import cloneDeep from 'lodash/cloneDeep'
  5 +import { chartInitConfig } from '@/settings/designSetting'
5 6
6 7 export enum WritingModeEnum {
7 8 HORIZONTAL = '水平',
... ... @@ -50,6 +51,7 @@ export const option = {
50 51
51 52 export default class Config extends PublicConfigClass implements CreateComponentType {
52 53 public key = OverrideTextCommonConfig.key
  54 + public attr = { ...chartInitConfig, w: 150, h: 40, zIndex: -1 }
53 55 public chartConfig = cloneDeep(OverrideTextCommonConfig)
54 56 public option = cloneDeep(option)
55 57 }
... ...
  1 +import { PublicConfigClass } from '@/packages/public'
  2 +import { CreateComponentType } from '@/packages/index.d'
  3 +import { OverrideTextBarrageConfig } from './index'
  4 +import { chartInitConfig } from '@/settings/designSetting'
  5 +import cloneDeep from 'lodash/cloneDeep'
  6 +
  7 +export enum FontWeightEnum {
  8 + NORMAL = '常规',
  9 + BOLD = '加粗',
  10 +}
  11 +
  12 +export const FontWeightObject = {
  13 + [FontWeightEnum.NORMAL]: 'normal',
  14 + [FontWeightEnum.BOLD]: 'bold',
  15 +}
  16 +
  17 +export const option = {
  18 + dataset: '让数字化看得见',
  19 + fontSize: 32,
  20 + fontColor: '#ffffff',
  21 + fontWeight: 'normal',
  22 + // 字间距
  23 + letterSpacing: 5,
  24 + //阴影
  25 + showShadow: true,
  26 + boxShadow: 'none',
  27 + hShadow: 0,
  28 + vShadow: 0,
  29 + blurShadow: 8,
  30 + colorShadow: '#0075ff',
  31 + //动画
  32 + animationTime: 0,
  33 + animationSpeed: 50,
  34 +}
  35 +
  36 +export default class Config extends PublicConfigClass implements CreateComponentType {
  37 + public key = OverrideTextBarrageConfig.key
  38 + public attr = { ...chartInitConfig, w: 260, h: 40, zIndex: -1 }
  39 + public chartConfig = cloneDeep(OverrideTextBarrageConfig)
  40 + public option = cloneDeep(option)
  41 + public preview = { overFlowHidden: true }
  42 +}
... ...
  1 +<template>
  2 + <collapse-item name="信息" :expanded="true">
  3 + <setting-item-box name="文字" :alone="true">
  4 + <setting-item>
  5 + <n-input v-model:value="optionData.dataset" size="small"></n-input>
  6 + </setting-item>
  7 + </setting-item-box>
  8 + </collapse-item>
  9 +
  10 + <collapse-item name="样式" :expanded="true">
  11 + <setting-item-box name="文字">
  12 + <setting-item name="颜色">
  13 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.fontColor"></n-color-picker>
  14 + </setting-item>
  15 + <setting-item name="字体大小">
  16 + <n-input-number v-model:value="optionData.fontSize" size="small" placeholder="字体大小"></n-input-number>
  17 + </setting-item>
  18 + <setting-item name="字体粗细">
  19 + <n-select v-model:value="optionData.fontWeight" size="small" :options="fontWeightOptions" />
  20 + </setting-item>
  21 +
  22 + <setting-item name="字间距">
  23 + <n-input-number v-model:value="optionData.letterSpacing" size="small" placeholder="输入字间距"></n-input-number>
  24 + </setting-item>
  25 + </setting-item-box>
  26 + <setting-item-box name="阴影">
  27 + <setting-item>
  28 + <n-space>
  29 + <n-switch v-model:value="optionData.showShadow" size="small" />
  30 + <n-text>展示阴影</n-text>
  31 + </n-space>
  32 + </setting-item>
  33 + <setting-item name="颜色">
  34 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.colorShadow"></n-color-picker
  35 + ></setting-item>
  36 + <setting-item name="x">
  37 + <n-input-number v-model:value="optionData.hShadow" size="small"></n-input-number
  38 + ></setting-item>
  39 + <setting-item name="y">
  40 + <n-input-number v-model:value="optionData.vShadow" size="small"></n-input-number
  41 + ></setting-item>
  42 + <setting-item name="模糊">
  43 + <n-input-number v-model:value="optionData.blurShadow" size="small"></n-input-number
  44 + ></setting-item>
  45 + </setting-item-box>
  46 +
  47 + <setting-item-box name="动画">
  48 + <setting-item name="动画速度">
  49 + <n-input-number
  50 + v-model:value="optionData.animationSpeed"
  51 + size="small"
  52 + placeholder="动画速度"
  53 + :min="0"
  54 + ></n-input-number>
  55 + </setting-item>
  56 + <setting-item name="动画间隔">
  57 + <n-input-number
  58 + v-model:value="optionData.animationTime"
  59 + size="small"
  60 + placeholder="动画间隔"
  61 + :min="0"
  62 + ></n-input-number>
  63 + </setting-item>
  64 + </setting-item-box>
  65 + </collapse-item>
  66 +</template>
  67 +
  68 +<script setup lang="ts">
  69 +import { PropType } from 'vue'
  70 +import { option, FontWeightEnum, FontWeightObject } from './config'
  71 +import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
  72 +const props = defineProps({
  73 + optionData: {
  74 + type: Object as PropType<typeof option>,
  75 + required: true
  76 + }
  77 +})
  78 +
  79 +const fontWeightOptions = [
  80 + {
  81 + label: FontWeightEnum.NORMAL,
  82 + value: FontWeightObject[FontWeightEnum.NORMAL]
  83 + },
  84 + {
  85 + label: FontWeightEnum.BOLD,
  86 + value: FontWeightObject[FontWeightEnum.BOLD]
  87 + }
  88 +]
  89 +</script>
... ...
  1 +import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
  2 +import { ChatCategoryEnum, ChatCategoryEnumName } from '@/packages/components/Informations/index.d'
  3 +import { useWidgetKey } from '@/packages/external/useWidgetKey'
  4 +
  5 +const { key, conKey, chartKey } = useWidgetKey('OverrideTextBarrage', true)
  6 +
  7 +export const OverrideTextBarrageConfig: ConfigType = {
  8 + key,
  9 + chartKey,
  10 + conKey,
  11 + title: '自定义弹幕文字',
  12 + category: ChatCategoryEnum.TEXT,
  13 + categoryName: ChatCategoryEnumName.TEXT,
  14 + package: PackagesCategoryEnum.INFORMATIONS,
  15 + chartFrame: ChartFrameEnum.COMMON,
  16 + image: 'text_barrage.png'
  17 +}
... ...
  1 +<template>
  2 + <div class="go-text-box">
  3 + <div class="content">
  4 + <span>
  5 + {{ option.dataset }}
  6 + </span>
  7 + </div>
  8 + </div>
  9 +</template>
  10 +
  11 +<script setup lang="ts">
  12 +import { PropType, toRefs, shallowReactive, watch, computed, ref } from 'vue'
  13 +import { CreateComponentType } from '@/packages/index.d'
  14 +import { useChartDataFetch } from '@/hooks'
  15 +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  16 +import { option as configOption } from './config'
  17 +import { values } from 'lodash'
  18 +
  19 +const props = defineProps({
  20 + chartConfig: {
  21 + type: Object as PropType<CreateComponentType & typeof option>,
  22 + required: true
  23 + }
  24 +})
  25 +
  26 +const { w } = toRefs(props.chartConfig.attr)
  27 +
  28 +const { fontColor, fontSize, letterSpacing, fontWeight, animationTime, animationSpeed, boxShadow } = toRefs(
  29 + props.chartConfig.option
  30 +)
  31 +
  32 +const option = shallowReactive({
  33 + dataset: configOption.dataset
  34 +})
  35 +
  36 +// 手动更新
  37 +watch(
  38 + () => props.chartConfig.option.dataset,
  39 + (newData: any) => {
  40 + option.dataset = newData
  41 + },
  42 + {
  43 + immediate: true,
  44 + deep: false
  45 + }
  46 +)
  47 +
  48 +//阴影
  49 +watch(
  50 + props.chartConfig.option,
  51 + () => {
  52 + try {
  53 + if (props.chartConfig.option.showShadow) {
  54 + boxShadow.value = `${props.chartConfig.option.hShadow}px ${props.chartConfig.option.vShadow}px ${props.chartConfig.option.blurShadow}px ${props.chartConfig.option.colorShadow}`
  55 + } else {
  56 + boxShadow.value = 'none'
  57 + }
  58 + } catch (error) {
  59 + console.log(error)
  60 + }
  61 + },
  62 + {
  63 + immediate: true
  64 + }
  65 +)
  66 +
  67 +const transitionDuration = computed(() => {
  68 + return Math.floor((w.value as any) / (animationSpeed.value as any))
  69 +})
  70 +
  71 +// 预览更新
  72 +useChartDataFetch(props.chartConfig, useChartEditStore, (newData: string) => {
  73 + option.dataset = newData
  74 +})
  75 +</script>
  76 +
  77 +<style lang="scss" scoped>
  78 +@include go('text-box') {
  79 + display: flex;
  80 + align-items: center;
  81 + .content {
  82 + width: 100%;
  83 + color: v-bind('fontColor');
  84 + font-size: v-bind('fontSize + "px"');
  85 + letter-spacing: v-bind('letterSpacing + "px"');
  86 + font-weight: v-bind('fontWeight');
  87 + text-shadow: v-bind('boxShadow');
  88 + position: absolute;
  89 + animation: barrage v-bind('transitionDuration + "s"') linear v-bind('animationTime + "s"') infinite;
  90 + }
  91 + @keyframes barrage {
  92 + from {
  93 + left: 100%;
  94 + transform: translateX(0);
  95 + }
  96 + to {
  97 + left: 0;
  98 + transform: translateX(-100%);
  99 + }
  100 + }
  101 +}
  102 +</style>
... ...
  1 +import { PublicConfigClass } from '@/packages/public'
  2 +import { CreateComponentType } from '@/packages/index.d'
  3 +import { OverrideTextGradientConfig } from './index'
  4 +import cloneDeep from 'lodash/cloneDeep'
  5 +import { chartInitConfig } from '@/settings/designSetting'
  6 +
  7 +export const option = {
  8 + dataset: '我是渐变文本',
  9 + size: 20,
  10 + gradient: {
  11 + from: '#0000FFFF',
  12 + to: '#00FF00FF',
  13 + deg: 45
  14 + }
  15 +}
  16 +
  17 +export default class Config extends PublicConfigClass implements CreateComponentType {
  18 + public key = OverrideTextGradientConfig.key
  19 + public attr = { ...chartInitConfig, w: 150, h: 40, zIndex: -1 }
  20 + public chartConfig = cloneDeep(OverrideTextGradientConfig)
  21 + public option = cloneDeep(option)
  22 +}
... ...
  1 +<template>
  2 + <collapse-item name="信息" :expanded="true">
  3 + <setting-item-box name="文字" :alone="true">
  4 + <setting-item>
  5 + <n-input v-model:value="optionData.dataset" size="small"></n-input>
  6 + </setting-item>
  7 + </setting-item-box>
  8 + </collapse-item>
  9 + <collapse-item name="样式" :expanded="true">
  10 + <setting-item-box name="文字">
  11 + <setting-item name="字体大小">
  12 + <n-input-number v-model:value="optionData.size" size="small" placeholder="字体大小"></n-input-number>
  13 + </setting-item>
  14 + </setting-item-box>
  15 + <setting-item-box name="渐变色参数">
  16 + <setting-item name="起始值">
  17 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.gradient.from"></n-color-picker>
  18 + </setting-item>
  19 + <setting-item name="结束值">
  20 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.gradient.to"></n-color-picker>
  21 + </setting-item>
  22 + <setting-item name="偏移角度">
  23 + <n-input-number v-model:value="optionData.gradient.deg" size="small" placeholder="颜色旋转"></n-input-number>
  24 + </setting-item>
  25 + </setting-item-box>
  26 +
  27 + </collapse-item>
  28 +</template>
  29 +
  30 +<script setup lang="ts">
  31 +import { PropType } from 'vue'
  32 +import { option } from './config'
  33 +import {
  34 + CollapseItem,
  35 + SettingItemBox,
  36 + SettingItem
  37 +} from '@/components/Pages/ChartItemSetting'
  38 +
  39 +const props = defineProps({
  40 + optionData: {
  41 + type: Object as PropType<typeof option>,
  42 + required: true
  43 + }
  44 +})
  45 +</script>
... ...
  1 +import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
  2 +import { ChatCategoryEnum, ChatCategoryEnumName } from '@/packages/components/Informations/index.d'
  3 +import { useWidgetKey } from '@/packages/external/useWidgetKey'
  4 +
  5 +const { key, conKey, chartKey } = useWidgetKey('OverrideTextGradient', true)
  6 +
  7 +export const OverrideTextGradientConfig: ConfigType = {
  8 + key,
  9 + chartKey,
  10 + conKey,
  11 + title: '自定义渐变文字',
  12 + category: ChatCategoryEnum.TEXT,
  13 + categoryName: ChatCategoryEnumName.TEXT,
  14 + package: PackagesCategoryEnum.INFORMATIONS,
  15 + chartFrame: ChartFrameEnum.COMMON,
  16 + image: 'text_gradient.png'
  17 +}
... ...
  1 +<template>
  2 + <div class="go-text-box">
  3 + <n-gradient-text :size="size" :gradient="gradient">
  4 + {{ option.dataset }}
  5 + </n-gradient-text>
  6 + </div>
  7 +</template>
  8 +<script setup lang="ts">
  9 +import { PropType, toRefs, shallowReactive, watch } from 'vue'
  10 +import { CreateComponentType } from '@/packages/index.d'
  11 +import { useChartDataFetch } from '@/hooks'
  12 +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  13 +import { option as configOption } from './config'
  14 +
  15 +const props = defineProps({
  16 + chartConfig: {
  17 + type: Object as PropType<CreateComponentType>,
  18 + required: true
  19 + }
  20 +})
  21 +
  22 +const option = shallowReactive({
  23 + dataset: configOption.dataset
  24 +})
  25 +
  26 +const { w, h } = toRefs(props.chartConfig.attr)
  27 +const { size, gradient } = toRefs(props.chartConfig.option)
  28 +
  29 +watch(
  30 + () => props.chartConfig.option.dataset,
  31 + (newData: any) => {
  32 + option.dataset = newData
  33 + },
  34 + {
  35 + immediate: true,
  36 + deep: false
  37 + }
  38 +)
  39 +
  40 +useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
  41 + option.dataset = newData
  42 +})
  43 +</script>
  44 +
  45 +<style lang="scss" scoped>
  46 +@include go('text-box') {
  47 + display: flex;
  48 + align-items: center;
  49 + justify-content: center;
  50 + .n-gradient-text {
  51 + white-space: initial;
  52 + }
  53 +}
  54 +</style>
... ...
... ... @@ -11,12 +11,15 @@ import { OverrideInputsTabConfig } from '@/packages/components/external/Informat
11 11 import { OverrideTextCommonConfig } from '@/packages/components/external/Informations/Mores/OverrideTextCommon'
12 12 import { OverrideIframeConfig } from '@/packages/components/external/Informations/Mores/OverrideIframe'
13 13 import { ButtonConfig } from '@/packages/components/external/Informations/Mores/Button'
  14 +import { OverrideTextBarrageConfig } from '@/packages/components/external/Informations/Texts/OverrideTextBarrage'
  15 +import { OverrideTextGradientConfig } from '@/packages/components/external/Informations/Texts/OverrideTextGradient'
14 16 import { OverrideBarCommonConfig } from '@/packages/components/external/Charts/Bars/OverrideBarCommon'
15 17 import { OverrideLineCommonConfig } from '@/packages/components/external/Charts/Lines/OverrideLineCommon'
16 18 import { OverrideLineGradientsConfig } from '@/packages/components/external/Charts/Lines/OverrideLineGradients'
  19 +import { OverrideProcessConfig } from '@/packages/components/external/Charts/Mores/OverrideProcess'
  20 +import { OverridePieCircleConfig } from '@/packages/components/external/Charts/Pies/OverridePieCircle'
17 21
18 22 export function useInjectLib(packagesList: EPackagesType) {
19   -
20 23 packagesList[EPackagesCategoryEnum.COMPOSES] = ComposesList
21 24
22 25 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.DECORATES, PickIconConfig)
... ... @@ -29,17 +32,25 @@ export function useInjectLib(packagesList: EPackagesType) {
29 32 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideTextCommonConfig)
30 33 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, ButtonConfig)
31 34 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideIframeConfig)
  35 + addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideTextBarrageConfig)
  36 + addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideTextGradientConfig)
32 37 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.CHARTS, OverrideBarCommonConfig)
33 38 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.CHARTS, OverrideLineCommonConfig)
34 39 addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.CHARTS, OverrideLineGradientsConfig)
  40 + addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.CHARTS, OverrideProcessConfig)
  41 + addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.CHARTS, OverridePieCircleConfig)
35 42 }
36 43
37 44 /**
38   - *
39   - * @param packagesList
40   - * @param categoryName
41   - * @param config
  45 + *
  46 + * @param packagesList
  47 + * @param categoryName
  48 + * @param config
42 49 */
43   -function addWidgetToCategoryByCategoryName(packagesList: EPackagesType, categoryName: PackagesCategoryEnum, config: ConfigType) {
  50 +function addWidgetToCategoryByCategoryName(
  51 + packagesList: EPackagesType,
  52 + categoryName: PackagesCategoryEnum,
  53 + config: ConfigType
  54 +) {
44 55 packagesList[categoryName].push(config)
45 56 }
... ...