Commit 06d82be089d77fd10e4d31a9eb5dc55d1d9b7a2e
1 parent
85d6cbf4
feat(packages/external): 重写部分柱状图和部分折线图,新增开启关闭动画效果
Showing
18 changed files
with
1162 additions
and
0 deletions
| 1 | +import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public' | |
| 2 | +import { OverrideBarCommonConfig } from './index' | |
| 3 | +import { CreateComponentType } from '@/packages/index.d' | |
| 4 | +import cloneDeep from 'lodash/cloneDeep' | |
| 5 | +import dataJson from './data.json' | |
| 6 | + | |
| 7 | +export const includes = ['legend', 'xAxis', 'yAxis', 'grid'] | |
| 8 | + | |
| 9 | +// 其它配置项比如新增(动画) | |
| 10 | +const otherConfig = { | |
| 11 | + // 轮播动画 | |
| 12 | + isCarousel: false, | |
| 13 | +} | |
| 14 | +export const seriesItem = { | |
| 15 | + type: 'bar', | |
| 16 | + barWidth: 15, | |
| 17 | + label: { | |
| 18 | + show: true, | |
| 19 | + position: 'top', | |
| 20 | + color: '#fff', | |
| 21 | + fontSize: 12 | |
| 22 | + }, | |
| 23 | + itemStyle: { | |
| 24 | + color: null, | |
| 25 | + borderRadius: 2 | |
| 26 | + } | |
| 27 | +} | |
| 28 | +export const option = { | |
| 29 | + ...otherConfig, | |
| 30 | + tooltip: { | |
| 31 | + show: true, | |
| 32 | + trigger: 'axis', | |
| 33 | + axisPointer: { | |
| 34 | + show: true, | |
| 35 | + type: 'shadow' | |
| 36 | + } | |
| 37 | + }, | |
| 38 | +xAxis: { | |
| 39 | + show: true, | |
| 40 | + type: 'category' | |
| 41 | + }, | |
| 42 | + yAxis: { | |
| 43 | + show: true, | |
| 44 | + type: 'value' | |
| 45 | + }, | |
| 46 | + dataset: { ...dataJson }, | |
| 47 | + series: [seriesItem, seriesItem] | |
| 48 | +} | |
| 49 | + | |
| 50 | +export default class Config extends PublicConfigClass implements CreateComponentType { | |
| 51 | + public key = OverrideBarCommonConfig.key | |
| 52 | + public chartConfig = cloneDeep(OverrideBarCommonConfig) | |
| 53 | + // 图表配置项 | |
| 54 | + public option = echartOptionProfixHandle(option, includes) | |
| 55 | +} | ... | ... |
| 1 | +<template> | |
| 2 | + <!-- Echarts 全局设置 --> | |
| 3 | + <global-setting :optionData="optionData"></global-setting> | |
| 4 | + <CollapseItem v-for="(item, index) in seriesList" :key="index" :name="`柱状图-${index + 1}`" :expanded="true"> | |
| 5 | + <SettingItemBox name="图形"> | |
| 6 | + <SettingItem name="宽度"> | |
| 7 | + <n-input-number | |
| 8 | + v-model:value="item.barWidth" | |
| 9 | + :min="1" | |
| 10 | + :max="100" | |
| 11 | + size="small" | |
| 12 | + placeholder="自动计算" | |
| 13 | + ></n-input-number> | |
| 14 | + </SettingItem> | |
| 15 | + <SettingItem name="圆角"> | |
| 16 | + <n-input-number v-model:value="item.itemStyle.borderRadius" :min="0" size="small"></n-input-number> | |
| 17 | + </SettingItem> | |
| 18 | + </SettingItemBox> | |
| 19 | + <SettingItemBox name="动画" :alone="true"> | |
| 20 | + <SettingItem> | |
| 21 | + <n-space> | |
| 22 | + <n-switch v-model:value="optionData.isCarousel" size="small"></n-switch> | |
| 23 | + <n-text>开启<n-text :depth="3">(将自动隐藏图例)</n-text></n-text> | |
| 24 | + </n-space> | |
| 25 | + </SettingItem> | |
| 26 | + <SettingItem> | |
| 27 | + <n-text :depth="3">无鼠标点击图例场景时,可强行打开图例</n-text> | |
| 28 | + </SettingItem> | |
| 29 | + </SettingItemBox> | |
| 30 | + <setting-item-box name="标签"> | |
| 31 | + <setting-item> | |
| 32 | + <n-space> | |
| 33 | + <n-switch v-model:value="item.label.show" size="small" /> | |
| 34 | + <n-text>展示标签</n-text> | |
| 35 | + </n-space> | |
| 36 | + </setting-item> | |
| 37 | + <setting-item name="大小"> | |
| 38 | + <n-input-number v-model:value="item.label.fontSize" size="small" :min="1"></n-input-number> | |
| 39 | + </setting-item> | |
| 40 | + <setting-item name="颜色"> | |
| 41 | + <n-color-picker size="small" :modes="['hex']" v-model:value="item.label.color"></n-color-picker> | |
| 42 | + </setting-item> | |
| 43 | + <setting-item name="位置"> | |
| 44 | + <n-select | |
| 45 | + v-model:value="item.label.position" | |
| 46 | + :options="[ | |
| 47 | + { label: 'top', value: 'top' }, | |
| 48 | + { label: 'left', value: 'left' }, | |
| 49 | + { label: 'right', value: 'right' }, | |
| 50 | + { label: 'bottom', value: 'bottom' } | |
| 51 | + ]" | |
| 52 | + /> | |
| 53 | + </setting-item> | |
| 54 | + </setting-item-box> | |
| 55 | + </CollapseItem> | |
| 56 | +</template> | |
| 57 | + | |
| 58 | +<script setup lang="ts"> | |
| 59 | +import { PropType, computed } from 'vue' | |
| 60 | +import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' | |
| 61 | +import { GlobalThemeJsonType } from '@/settings/chartThemes/index' | |
| 62 | + | |
| 63 | +const props = defineProps({ | |
| 64 | + optionData: { | |
| 65 | + type: Object as PropType<GlobalThemeJsonType>, | |
| 66 | + required: true | |
| 67 | + } | |
| 68 | +}) | |
| 69 | + | |
| 70 | +const seriesList = computed(() => { | |
| 71 | + return props.optionData.series | |
| 72 | +}) | |
| 73 | +</script> | ... | ... |
| 1 | +{ | |
| 2 | + "dimensions": ["product", "data1", "data2"], | |
| 3 | + "source": [ | |
| 4 | + { | |
| 5 | + "product": "Mon", | |
| 6 | + "data1": 120, | |
| 7 | + "data2": 130 | |
| 8 | + }, | |
| 9 | + { | |
| 10 | + "product": "Tue", | |
| 11 | + "data1": 200, | |
| 12 | + "data2": 130 | |
| 13 | + }, | |
| 14 | + { | |
| 15 | + "product": "Wed", | |
| 16 | + "data1": 150, | |
| 17 | + "data2": 312 | |
| 18 | + }, | |
| 19 | + { | |
| 20 | + "product": "Thu", | |
| 21 | + "data1": 80, | |
| 22 | + "data2": 268 | |
| 23 | + }, | |
| 24 | + { | |
| 25 | + "product": "Fri", | |
| 26 | + "data1": 70, | |
| 27 | + "data2": 155 | |
| 28 | + }, | |
| 29 | + { | |
| 30 | + "product": "Sat", | |
| 31 | + "data1": 110, | |
| 32 | + "data2": 117 | |
| 33 | + }, | |
| 34 | + { | |
| 35 | + "product": "Sun", | |
| 36 | + "data1": 130, | |
| 37 | + "data2": 160 | |
| 38 | + } | |
| 39 | + ] | |
| 40 | +} | ... | ... |
| 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('OverrideBarCommon', true) | |
| 6 | + | |
| 7 | +export const OverrideBarCommonConfig: ConfigType = { | |
| 8 | + key, | |
| 9 | + chartKey, | |
| 10 | + conKey, | |
| 11 | + title: '柱状图动画', | |
| 12 | + category: ChatCategoryEnum.BAR, | |
| 13 | + categoryName: ChatCategoryEnumName.BAR, | |
| 14 | + package: PackagesCategoryEnum.CHARTS, | |
| 15 | + chartFrame: ChartFrameEnum.ECHARTS, | |
| 16 | + image: 'bar_x.png' | |
| 17 | +} | ... | ... |
| 1 | +<template> | |
| 2 | + <v-chart | |
| 3 | + ref="vChartRef" | |
| 4 | + :init-options="initOptions" | |
| 5 | + :theme="themeColor" | |
| 6 | + :option="option" | |
| 7 | + :manual-update="isPreview()" | |
| 8 | + :update-options="{ | |
| 9 | + replaceMerge: replaceMergeArr | |
| 10 | + }" | |
| 11 | + autoresize | |
| 12 | + @mouseover="handleHighlight" | |
| 13 | + @mouseout="handleDownplay" | |
| 14 | + ></v-chart> | |
| 15 | +</template> | |
| 16 | + | |
| 17 | +<script setup lang="ts"> | |
| 18 | +import { ref, nextTick, computed, watch, PropType, onMounted } from 'vue' | |
| 19 | +import VChart from 'vue-echarts' | |
| 20 | +import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook' | |
| 21 | +import { use } from 'echarts/core' | |
| 22 | +import { CanvasRenderer } from 'echarts/renderers' | |
| 23 | +import { BarChart } from 'echarts/charts' | |
| 24 | +import config, { includes, seriesItem } from './config' | |
| 25 | +import { mergeTheme } from '@/packages/public/chart' | |
| 26 | +import { useChartDataFetch } from '@/hooks' | |
| 27 | +import { CreateComponentType } from '@/packages/index.d' | |
| 28 | +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' | |
| 29 | +import { isPreview } from '@/utils' | |
| 30 | +import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components' | |
| 31 | +import isObject from 'lodash/isObject' | |
| 32 | +import dataJson from './data.json' | |
| 33 | + | |
| 34 | +const props = defineProps({ | |
| 35 | + themeSetting: { | |
| 36 | + type: Object, | |
| 37 | + required: true | |
| 38 | + }, | |
| 39 | + themeColor: { | |
| 40 | + type: Object, | |
| 41 | + required: true | |
| 42 | + }, | |
| 43 | + chartConfig: { | |
| 44 | + type: Object as PropType<config>, | |
| 45 | + required: true | |
| 46 | + } | |
| 47 | +}) | |
| 48 | + | |
| 49 | +const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting) | |
| 50 | + | |
| 51 | +use([DatasetComponent, CanvasRenderer, BarChart, GridComponent, TooltipComponent, LegendComponent]) | |
| 52 | + | |
| 53 | +const replaceMergeArr = ref<string[]>() | |
| 54 | + | |
| 55 | +const option = computed(() => { | |
| 56 | + return mergeTheme(props.chartConfig.option, props.themeSetting, includes) | |
| 57 | +}) | |
| 58 | + | |
| 59 | +// dataset 无法变更条数的补丁 | |
| 60 | +watch( | |
| 61 | + () => props.chartConfig.option.dataset, | |
| 62 | + (newData: { dimensions: any }, oldData) => { | |
| 63 | + try { | |
| 64 | + if (!isObject(newData) || !('dimensions' in newData)) return | |
| 65 | + if (Array.isArray(newData?.dimensions)) { | |
| 66 | + const seriesArr = [] | |
| 67 | + for (let i = 0; i < newData.dimensions.length - 1; i++) { | |
| 68 | + seriesArr.push(seriesItem) | |
| 69 | + } | |
| 70 | + replaceMergeArr.value = ['series'] | |
| 71 | + props.chartConfig.option.series = seriesArr | |
| 72 | + nextTick(() => { | |
| 73 | + replaceMergeArr.value = [] | |
| 74 | + }) | |
| 75 | + } | |
| 76 | + } catch (error) { | |
| 77 | + console.log(error) | |
| 78 | + } | |
| 79 | + }, | |
| 80 | + { | |
| 81 | + deep: false | |
| 82 | + } | |
| 83 | +) | |
| 84 | + | |
| 85 | +let seriesDataNum = -1 | |
| 86 | +let seriesDataMaxLength = 0 | |
| 87 | +let intervalInstance: any = null | |
| 88 | +//轮播时长 | |
| 89 | +const duration = 1500 | |
| 90 | + | |
| 91 | +// 会重新选择需要选中和展示的数据 | |
| 92 | +const handleSeriesData = () => { | |
| 93 | + if (seriesDataNum > -1) { | |
| 94 | + vChartRef.value?.dispatchAction({ | |
| 95 | + type: 'downplay', | |
| 96 | + dataIndex: seriesDataNum | |
| 97 | + }) | |
| 98 | + } | |
| 99 | + seriesDataNum = seriesDataNum >= seriesDataMaxLength - 1 ? 0 : seriesDataNum + 1 | |
| 100 | + vChartRef.value?.dispatchAction({ | |
| 101 | + type: 'showTip', | |
| 102 | + seriesIndex: 0, | |
| 103 | + dataIndex: seriesDataNum | |
| 104 | + }) | |
| 105 | +} | |
| 106 | + | |
| 107 | +// 新增轮播 | |
| 108 | +const addPieInterval = (newData?: typeof dataJson, skipPre = false) => { | |
| 109 | + if (!skipPre && !Array.isArray(newData?.source)) return | |
| 110 | + if (!skipPre) seriesDataMaxLength = newData?.source.length || 0 | |
| 111 | + clearInterval(intervalInstance) | |
| 112 | + intervalInstance = setInterval(() => { | |
| 113 | + handleSeriesData() | |
| 114 | + }, duration) | |
| 115 | +} | |
| 116 | + | |
| 117 | +// 取消轮播 | |
| 118 | +const clearPieInterval = () => { | |
| 119 | + vChartRef.value?.dispatchAction({ | |
| 120 | + type: 'hideTip', | |
| 121 | + seriesIndex: 0, | |
| 122 | + dataIndex: seriesDataNum | |
| 123 | + }) | |
| 124 | + vChartRef.value?.dispatchAction({ | |
| 125 | + type: 'downplay', | |
| 126 | + dataIndex: seriesDataNum | |
| 127 | + }) | |
| 128 | + clearInterval(intervalInstance) | |
| 129 | + intervalInstance = null | |
| 130 | +} | |
| 131 | + | |
| 132 | +// 处理鼠标聚焦高亮内容 | |
| 133 | +const handleHighlight = () => { | |
| 134 | + clearPieInterval() | |
| 135 | +} | |
| 136 | + | |
| 137 | +// 处理鼠标取消悬浮 | |
| 138 | +const handleDownplay = () => { | |
| 139 | + if (props.chartConfig.option.isCarousel && !intervalInstance) { | |
| 140 | + // 恢复轮播 | |
| 141 | + addPieInterval(undefined, true) | |
| 142 | + } | |
| 143 | +} | |
| 144 | + | |
| 145 | +watch( | |
| 146 | + () => props.chartConfig.option.isCarousel, | |
| 147 | + newData => { | |
| 148 | + if (newData) { | |
| 149 | + addPieInterval(undefined, true) | |
| 150 | + props.chartConfig.option.legend.show = false | |
| 151 | + } else { | |
| 152 | + props.chartConfig.option.legend.show = true | |
| 153 | + clearPieInterval() | |
| 154 | + } | |
| 155 | + } | |
| 156 | +) | |
| 157 | + | |
| 158 | +const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: typeof dataJson) => { | |
| 159 | + addPieInterval(newData) | |
| 160 | +}) | |
| 161 | + | |
| 162 | +onMounted(() => { | |
| 163 | + seriesDataMaxLength = dataJson.source.length | |
| 164 | + if (props.chartConfig.option.isCarousel) { | |
| 165 | + addPieInterval(undefined, true) | |
| 166 | + } | |
| 167 | +}) | |
| 168 | +</script> | ... | ... |
| 1 | +import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public' | |
| 2 | +import { OverrideLineCommonConfig } from './index' | |
| 3 | +import { CreateComponentType } from '@/packages/index.d' | |
| 4 | +import cloneDeep from 'lodash/cloneDeep' | |
| 5 | +import dataJson from './data.json' | |
| 6 | + | |
| 7 | +export const includes = ['legend', 'xAxis', 'yAxis', 'grid'] | |
| 8 | +export const seriesItem = { | |
| 9 | + type: 'line', | |
| 10 | + label: { | |
| 11 | + show: true, | |
| 12 | + position: 'top', | |
| 13 | + color: '#fff', | |
| 14 | + fontSize: 12 | |
| 15 | + }, | |
| 16 | + symbolSize: 5, //设定实心点的大小 | |
| 17 | + itemStyle: { | |
| 18 | + color: null, | |
| 19 | + borderRadius: 0 | |
| 20 | + }, | |
| 21 | + lineStyle: { | |
| 22 | + type: 'solid', | |
| 23 | + width: 3, | |
| 24 | + color: null | |
| 25 | + } | |
| 26 | +} | |
| 27 | +// 其它配置项比如新增(动画) | |
| 28 | +const otherConfig = { | |
| 29 | + // 轮播动画 | |
| 30 | + isCarousel: false, | |
| 31 | +} | |
| 32 | +export const option = { | |
| 33 | + ...otherConfig, | |
| 34 | + tooltip: { | |
| 35 | + show: true, | |
| 36 | + trigger: 'axis', | |
| 37 | + axisPointer: { | |
| 38 | + type: 'line' | |
| 39 | + } | |
| 40 | + }, | |
| 41 | + xAxis: { | |
| 42 | + show: true, | |
| 43 | + type: 'category' | |
| 44 | + }, | |
| 45 | + yAxis: { | |
| 46 | + show: true, | |
| 47 | + type: 'value' | |
| 48 | + }, | |
| 49 | + dataset: { ...dataJson }, | |
| 50 | + series: [seriesItem, seriesItem] | |
| 51 | +} | |
| 52 | + | |
| 53 | +export default class Config extends PublicConfigClass implements CreateComponentType { | |
| 54 | + public key: string = OverrideLineCommonConfig.key | |
| 55 | + public chartConfig = cloneDeep(OverrideLineCommonConfig) | |
| 56 | + // 图表配置项 | |
| 57 | + public option = echartOptionProfixHandle(option, includes) | |
| 58 | +} | ... | ... |
| 1 | +<template> | |
| 2 | + <!-- Echarts 全局设置 --> | |
| 3 | + <global-setting :optionData="optionData"></global-setting> | |
| 4 | + <CollapseItem v-for="(item, index) in seriesList" :key="index" :name="`折线图-${index + 1}`" :expanded="true"> | |
| 5 | + <SettingItemBox name="线条"> | |
| 6 | + <SettingItem name="宽度"> | |
| 7 | + <n-input-number | |
| 8 | + v-model:value="item.lineStyle.width" | |
| 9 | + :min="1" | |
| 10 | + :max="100" | |
| 11 | + size="small" | |
| 12 | + placeholder="自动计算" | |
| 13 | + ></n-input-number> | |
| 14 | + </SettingItem> | |
| 15 | + <SettingItem name="类型"> | |
| 16 | + <n-select v-model:value="item.lineStyle.type" size="small" :options="lineConf.lineStyle.type"></n-select> | |
| 17 | + </SettingItem> | |
| 18 | + </SettingItemBox> | |
| 19 | + <SettingItemBox name="动画" :alone="true"> | |
| 20 | + <SettingItem> | |
| 21 | + <n-space> | |
| 22 | + <n-switch v-model:value="optionData.isCarousel" size="small"></n-switch> | |
| 23 | + <n-text>开启<n-text :depth="3">(将自动隐藏图例)</n-text></n-text> | |
| 24 | + </n-space> | |
| 25 | + </SettingItem> | |
| 26 | + <SettingItem> | |
| 27 | + <n-text :depth="3">无鼠标点击图例场景时,可强行打开图例</n-text> | |
| 28 | + </SettingItem> | |
| 29 | + </SettingItemBox> | |
| 30 | + <SettingItemBox name="实心点"> | |
| 31 | + <SettingItem name="大小"> | |
| 32 | + <n-input-number | |
| 33 | + v-model:value="item.symbolSize" | |
| 34 | + :min="1" | |
| 35 | + :max="100" | |
| 36 | + size="small" | |
| 37 | + placeholder="自动计算" | |
| 38 | + ></n-input-number> | |
| 39 | + </SettingItem> | |
| 40 | + </SettingItemBox> | |
| 41 | + <setting-item-box name="标签"> | |
| 42 | + <setting-item> | |
| 43 | + <n-space> | |
| 44 | + <n-switch v-model:value="item.label.show" size="small" /> | |
| 45 | + <n-text>展示标签</n-text> | |
| 46 | + </n-space> | |
| 47 | + </setting-item> | |
| 48 | + <setting-item name="大小"> | |
| 49 | + <n-input-number v-model:value="item.label.fontSize" size="small" :min="1"></n-input-number> | |
| 50 | + </setting-item> | |
| 51 | + <setting-item name="颜色"> | |
| 52 | + <n-color-picker size="small" :modes="['hex']" v-model:value="item.label.color"></n-color-picker> | |
| 53 | + </setting-item> | |
| 54 | + <setting-item name="位置"> | |
| 55 | + <n-select | |
| 56 | + v-model:value="item.label.position" | |
| 57 | + :options="[ | |
| 58 | + { label: 'top', value: 'top' }, | |
| 59 | + { label: 'left', value: 'left' }, | |
| 60 | + { label: 'right', value: 'right' }, | |
| 61 | + { label: 'bottom', value: 'bottom' } | |
| 62 | + ]" | |
| 63 | + /> | |
| 64 | + </setting-item> | |
| 65 | + </setting-item-box> | |
| 66 | + </CollapseItem> | |
| 67 | +</template> | |
| 68 | + | |
| 69 | +<script setup lang="ts"> | |
| 70 | +import { PropType, computed } from 'vue' | |
| 71 | +import { lineConf } from '@/packages/chartConfiguration/echarts/index' | |
| 72 | +import { GlobalThemeJsonType } from '@/settings/chartThemes/index' | |
| 73 | +import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' | |
| 74 | + | |
| 75 | +const props = defineProps({ | |
| 76 | + optionData: { | |
| 77 | + type: Object as PropType<GlobalThemeJsonType>, | |
| 78 | + required: true | |
| 79 | + } | |
| 80 | +}) | |
| 81 | + | |
| 82 | +const seriesList = computed(() => { | |
| 83 | + return props.optionData.series | |
| 84 | +}) | |
| 85 | +</script> | ... | ... |
| 1 | +{ | |
| 2 | + "dimensions": ["product", "data1", "data2"], | |
| 3 | + "source": [ | |
| 4 | + { | |
| 5 | + "product": "Mon", | |
| 6 | + "data1": 120, | |
| 7 | + "data2": 130 | |
| 8 | + }, | |
| 9 | + { | |
| 10 | + "product": "Tue", | |
| 11 | + "data1": 200, | |
| 12 | + "data2": 130 | |
| 13 | + }, | |
| 14 | + { | |
| 15 | + "product": "Wed", | |
| 16 | + "data1": 150, | |
| 17 | + "data2": 312 | |
| 18 | + }, | |
| 19 | + { | |
| 20 | + "product": "Thu", | |
| 21 | + "data1": 80, | |
| 22 | + "data2": 268 | |
| 23 | + }, | |
| 24 | + { | |
| 25 | + "product": "Fri", | |
| 26 | + "data1": 70, | |
| 27 | + "data2": 155 | |
| 28 | + }, | |
| 29 | + { | |
| 30 | + "product": "Sat", | |
| 31 | + "data1": 110, | |
| 32 | + "data2": 117 | |
| 33 | + }, | |
| 34 | + { | |
| 35 | + "product": "Sun", | |
| 36 | + "data1": 130, | |
| 37 | + "data2": 160 | |
| 38 | + } | |
| 39 | + ] | |
| 40 | +} | ... | ... |
| 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('OverrideLineCommon', true) | |
| 6 | + | |
| 7 | +export const OverrideLineCommonConfig: ConfigType = { | |
| 8 | + key, | |
| 9 | + chartKey, | |
| 10 | + conKey, | |
| 11 | + title: '折线图动画', | |
| 12 | + category: ChatCategoryEnum.LINE, | |
| 13 | + categoryName: ChatCategoryEnumName.LINE, | |
| 14 | + package: PackagesCategoryEnum.CHARTS, | |
| 15 | + chartFrame: ChartFrameEnum.ECHARTS, | |
| 16 | + image: 'line.png' | |
| 17 | +} | ... | ... |
| 1 | +<template> | |
| 2 | + <v-chart | |
| 3 | + ref="vChartRef" | |
| 4 | + :init-options="initOptions" | |
| 5 | + :theme="themeColor" | |
| 6 | + :option="option" | |
| 7 | + :manual-update="isPreview()" | |
| 8 | + :update-options="{ | |
| 9 | + replaceMerge: replaceMergeArr | |
| 10 | + }" | |
| 11 | + autoresize | |
| 12 | + @mouseover="handleHighlight" | |
| 13 | + @mouseout="handleDownplay" | |
| 14 | + > | |
| 15 | + </v-chart> | |
| 16 | +</template> | |
| 17 | + | |
| 18 | +<script setup lang="ts"> | |
| 19 | +import { PropType, computed, watch, ref, nextTick, onMounted } from 'vue' | |
| 20 | +import VChart from 'vue-echarts' | |
| 21 | +import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook' | |
| 22 | +import { use } from 'echarts/core' | |
| 23 | +import { CanvasRenderer } from 'echarts/renderers' | |
| 24 | +import { LineChart } from 'echarts/charts' | |
| 25 | +import config, { includes, seriesItem } from './config' | |
| 26 | +import { mergeTheme } from '@/packages/public/chart' | |
| 27 | +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' | |
| 28 | +import { useChartDataFetch } from '@/hooks' | |
| 29 | +import { isPreview } from '@/utils' | |
| 30 | +import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components' | |
| 31 | +import isObject from 'lodash/isObject' | |
| 32 | +import dataJson from './data.json' | |
| 33 | + | |
| 34 | +const props = defineProps({ | |
| 35 | + themeSetting: { | |
| 36 | + type: Object, | |
| 37 | + required: true | |
| 38 | + }, | |
| 39 | + themeColor: { | |
| 40 | + type: Object, | |
| 41 | + required: true | |
| 42 | + }, | |
| 43 | + chartConfig: { | |
| 44 | + type: Object as PropType<config>, | |
| 45 | + required: true | |
| 46 | + } | |
| 47 | +}) | |
| 48 | + | |
| 49 | +const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting) | |
| 50 | + | |
| 51 | +use([DatasetComponent, CanvasRenderer, LineChart, GridComponent, TooltipComponent, LegendComponent]) | |
| 52 | + | |
| 53 | +const replaceMergeArr = ref<string[]>() | |
| 54 | + | |
| 55 | +const option = computed(() => { | |
| 56 | + return mergeTheme(props.chartConfig.option, props.themeSetting, includes) | |
| 57 | +}) | |
| 58 | + | |
| 59 | +// dataset 无法变更条数的补丁 | |
| 60 | +watch( | |
| 61 | + () => props.chartConfig.option.dataset, | |
| 62 | + (newData: { dimensions: any }, oldData) => { | |
| 63 | + try { | |
| 64 | + if (!isObject(newData) || !('dimensions' in newData)) return | |
| 65 | + if (Array.isArray(newData?.dimensions)) { | |
| 66 | + const seriesArr = [] | |
| 67 | + for (let i = 0; i < newData.dimensions.length - 1; i++) { | |
| 68 | + seriesArr.push(seriesItem) | |
| 69 | + } | |
| 70 | + replaceMergeArr.value = ['series'] | |
| 71 | + props.chartConfig.option.series = seriesArr | |
| 72 | + nextTick(() => { | |
| 73 | + replaceMergeArr.value = [] | |
| 74 | + }) | |
| 75 | + } | |
| 76 | + } catch (error) { | |
| 77 | + console.log(error) | |
| 78 | + } | |
| 79 | + }, | |
| 80 | + { | |
| 81 | + deep: false | |
| 82 | + } | |
| 83 | +) | |
| 84 | + | |
| 85 | +let seriesDataNum = -1 | |
| 86 | +let seriesDataMaxLength = 0 | |
| 87 | +let intervalInstance: any = null | |
| 88 | +const duration = 1500 | |
| 89 | + | |
| 90 | +// 会重新选择需要选中和展示的数据 | |
| 91 | +const handleSeriesData = () => { | |
| 92 | + if (seriesDataNum > -1) { | |
| 93 | + vChartRef.value?.dispatchAction({ | |
| 94 | + type: 'downplay', | |
| 95 | + dataIndex: seriesDataNum | |
| 96 | + }) | |
| 97 | + } | |
| 98 | + seriesDataNum = seriesDataNum >= seriesDataMaxLength - 1 ? 0 : seriesDataNum + 1 | |
| 99 | + vChartRef.value?.dispatchAction({ | |
| 100 | + type: 'showTip', | |
| 101 | + seriesIndex: 0, | |
| 102 | + dataIndex: seriesDataNum | |
| 103 | + }) | |
| 104 | +} | |
| 105 | + | |
| 106 | +// 新增轮播 | |
| 107 | +const addPieInterval = (newData?: typeof dataJson, skipPre = false) => { | |
| 108 | + if (!skipPre && !Array.isArray(newData?.source)) return | |
| 109 | + if (!skipPre) seriesDataMaxLength = newData?.source.length || 0 | |
| 110 | + clearInterval(intervalInstance) | |
| 111 | + intervalInstance = setInterval(() => { | |
| 112 | + handleSeriesData() | |
| 113 | + }, duration) | |
| 114 | +} | |
| 115 | + | |
| 116 | +// 取消轮播 | |
| 117 | +const clearPieInterval = () => { | |
| 118 | + vChartRef.value?.dispatchAction({ | |
| 119 | + type: 'hideTip', | |
| 120 | + seriesIndex: 0, | |
| 121 | + dataIndex: seriesDataNum | |
| 122 | + }) | |
| 123 | + vChartRef.value?.dispatchAction({ | |
| 124 | + type: 'downplay', | |
| 125 | + dataIndex: seriesDataNum | |
| 126 | + }) | |
| 127 | + clearInterval(intervalInstance) | |
| 128 | + intervalInstance = null | |
| 129 | +} | |
| 130 | + | |
| 131 | +// 处理鼠标聚焦高亮内容 | |
| 132 | +const handleHighlight = () => { | |
| 133 | + clearPieInterval() | |
| 134 | +} | |
| 135 | + | |
| 136 | +// 处理鼠标取消悬浮 | |
| 137 | +const handleDownplay = () => { | |
| 138 | + if (props.chartConfig.option.isCarousel && !intervalInstance) { | |
| 139 | + // 恢复轮播 | |
| 140 | + addPieInterval(undefined, true) | |
| 141 | + } | |
| 142 | +} | |
| 143 | + | |
| 144 | +watch( | |
| 145 | + () => props.chartConfig.option.isCarousel, | |
| 146 | + newData => { | |
| 147 | + if (newData) { | |
| 148 | + addPieInterval(undefined, true) | |
| 149 | + props.chartConfig.option.legend.show = false | |
| 150 | + } else { | |
| 151 | + props.chartConfig.option.legend.show = true | |
| 152 | + clearPieInterval() | |
| 153 | + } | |
| 154 | + } | |
| 155 | +) | |
| 156 | + | |
| 157 | +const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: typeof dataJson) => { | |
| 158 | + addPieInterval(newData) | |
| 159 | +}) | |
| 160 | + | |
| 161 | +onMounted(() => { | |
| 162 | + seriesDataMaxLength = dataJson.source.length | |
| 163 | + if (props.chartConfig.option.isCarousel) { | |
| 164 | + addPieInterval(undefined, true) | |
| 165 | + } | |
| 166 | +}) | |
| 167 | +</script> | ... | ... |
| 1 | +import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public' | |
| 2 | +import { OverrideLineGradientsConfig } from './index' | |
| 3 | +import { CreateComponentType } from '@/packages/index.d' | |
| 4 | +import { graphic } from 'echarts/core' | |
| 5 | +import { defaultTheme, chartColorsSearch } from '@/settings/chartThemes/index' | |
| 6 | +import cloneDeep from 'lodash/cloneDeep' | |
| 7 | +import dataJson from './data.json' | |
| 8 | + | |
| 9 | +export const includes = ['legend', 'xAxis', 'yAxis', 'grid'] | |
| 10 | + | |
| 11 | +// 其它配置项比如新增(动画) | |
| 12 | +const otherConfig = { | |
| 13 | + // 轮播动画 | |
| 14 | + isCarousel: false, | |
| 15 | +} | |
| 16 | +const option = { | |
| 17 | + ...otherConfig, | |
| 18 | + tooltip: { | |
| 19 | + show: true, | |
| 20 | + trigger: 'axis', | |
| 21 | + axisPointer: { | |
| 22 | + type: 'line' | |
| 23 | + } | |
| 24 | + }, | |
| 25 | + xAxis: { | |
| 26 | + show: true, | |
| 27 | + type: 'category' | |
| 28 | + }, | |
| 29 | + yAxis: { | |
| 30 | + show: true, | |
| 31 | + type: 'value' | |
| 32 | + }, | |
| 33 | + dataset: { ...dataJson }, | |
| 34 | + series: [ | |
| 35 | + { | |
| 36 | + type: 'line', | |
| 37 | + smooth: false, | |
| 38 | + symbolSize: 5, //设定实心点的大小 | |
| 39 | + label: { | |
| 40 | + show: true, | |
| 41 | + position: 'top', | |
| 42 | + color: '#fff', | |
| 43 | + fontSize: 12 | |
| 44 | + }, | |
| 45 | + lineStyle: { | |
| 46 | + width: 3, | |
| 47 | + type: 'solid' | |
| 48 | + }, | |
| 49 | + areaStyle: { | |
| 50 | + opacity: 0.8, | |
| 51 | + color: new graphic.LinearGradient(0, 0, 0, 1, [ | |
| 52 | + { | |
| 53 | + offset: 0, | |
| 54 | + color: chartColorsSearch[defaultTheme][3] | |
| 55 | + }, | |
| 56 | + { | |
| 57 | + offset: 1, | |
| 58 | + color: 'rgba(0,0,0,0)' | |
| 59 | + } | |
| 60 | + ]) | |
| 61 | + } | |
| 62 | + }, | |
| 63 | + { | |
| 64 | + type: 'line', | |
| 65 | + smooth: false, | |
| 66 | + label: { | |
| 67 | + show: true, | |
| 68 | + position: 'top', | |
| 69 | + color: '#fff', | |
| 70 | + fontSize: 12 | |
| 71 | + }, | |
| 72 | + lineStyle: { | |
| 73 | + width: 3, | |
| 74 | + type: 'solid' | |
| 75 | + }, | |
| 76 | + areaStyle: { | |
| 77 | + opacity: 0.8, | |
| 78 | + color: new graphic.LinearGradient(0, 0, 0, 1, [ | |
| 79 | + { | |
| 80 | + offset: 0, | |
| 81 | + color: chartColorsSearch[defaultTheme][4] | |
| 82 | + }, | |
| 83 | + { | |
| 84 | + offset: 1, | |
| 85 | + color: 'rgba(0,0,0,0)' | |
| 86 | + } | |
| 87 | + ]) | |
| 88 | + } | |
| 89 | + } | |
| 90 | + ] | |
| 91 | +} | |
| 92 | + | |
| 93 | +export default class Config extends PublicConfigClass implements CreateComponentType { | |
| 94 | + public key: string = OverrideLineGradientsConfig.key | |
| 95 | + public chartConfig = cloneDeep(OverrideLineGradientsConfig) | |
| 96 | + // 图表配置项 | |
| 97 | + public option = echartOptionProfixHandle(option, includes) | |
| 98 | +} | ... | ... |
| 1 | +<template> | |
| 2 | + <!-- Echarts 全局设置 --> | |
| 3 | + <global-setting :optionData="optionData"></global-setting> | |
| 4 | + <CollapseItem | |
| 5 | + v-for="(item, index) in seriesList" | |
| 6 | + :key="index" | |
| 7 | + name="单折线面积图" | |
| 8 | + :expanded="true" | |
| 9 | + > | |
| 10 | + <SettingItemBox name="线条"> | |
| 11 | + <SettingItem name="宽度"> | |
| 12 | + <n-input-number | |
| 13 | + v-model:value="item.lineStyle.width" | |
| 14 | + :min="1" | |
| 15 | + size="small" | |
| 16 | + placeholder="自动计算" | |
| 17 | + ></n-input-number> | |
| 18 | + </SettingItem> | |
| 19 | + <SettingItem name="类型"> | |
| 20 | + <n-select | |
| 21 | + v-model:value="item.lineStyle.type" | |
| 22 | + size="small" | |
| 23 | + :options="lineConf.lineStyle.type" | |
| 24 | + ></n-select> | |
| 25 | + </SettingItem> | |
| 26 | + </SettingItemBox> | |
| 27 | + <SettingItemBox name="动画" :alone="true"> | |
| 28 | + <SettingItem> | |
| 29 | + <n-space> | |
| 30 | + <n-switch v-model:value="optionData.isCarousel" size="small"></n-switch> | |
| 31 | + <n-text>开启<n-text :depth="3">(将自动隐藏图例)</n-text></n-text> | |
| 32 | + </n-space> | |
| 33 | + </SettingItem> | |
| 34 | + <SettingItem> | |
| 35 | + <n-text :depth="3">无鼠标点击图例场景时,可强行打开图例</n-text> | |
| 36 | + </SettingItem> | |
| 37 | + </SettingItemBox> | |
| 38 | + <SettingItemBox name="实心点"> | |
| 39 | + <SettingItem name="大小"> | |
| 40 | + <n-input-number | |
| 41 | + v-model:value="item.symbolSize" | |
| 42 | + :min="1" | |
| 43 | + :max="100" | |
| 44 | + size="small" | |
| 45 | + placeholder="自动计算" | |
| 46 | + ></n-input-number> | |
| 47 | + </SettingItem> | |
| 48 | + </SettingItemBox> | |
| 49 | + <setting-item-box name="标签"> | |
| 50 | + <setting-item> | |
| 51 | + <n-space> | |
| 52 | + <n-switch v-model:value="item.label.show" size="small" /> | |
| 53 | + <n-text>展示标签</n-text> | |
| 54 | + </n-space> | |
| 55 | + </setting-item> | |
| 56 | + <setting-item name="大小"> | |
| 57 | + <n-input-number | |
| 58 | + v-model:value="item.label.fontSize" | |
| 59 | + size="small" | |
| 60 | + :min="1" | |
| 61 | + ></n-input-number> | |
| 62 | + </setting-item> | |
| 63 | + <setting-item name="颜色"> | |
| 64 | + <n-color-picker | |
| 65 | + size="small" | |
| 66 | + :modes="['hex']" | |
| 67 | + v-model:value="item.label.color" | |
| 68 | + ></n-color-picker> | |
| 69 | + </setting-item> | |
| 70 | + <setting-item name="位置"> | |
| 71 | + <n-select | |
| 72 | + v-model:value="item.label.position" | |
| 73 | + :options="[ | |
| 74 | + { label: 'top', value: 'top' }, | |
| 75 | + { label: 'left', value: 'left' }, | |
| 76 | + { label: 'right', value: 'right' }, | |
| 77 | + { label: 'bottom', value: 'bottom' }, | |
| 78 | + ]" | |
| 79 | + /> | |
| 80 | + </setting-item> | |
| 81 | + </setting-item-box> | |
| 82 | + </CollapseItem> | |
| 83 | +</template> | |
| 84 | + | |
| 85 | +<script setup lang="ts"> | |
| 86 | +import { PropType, computed } from 'vue' | |
| 87 | +import { lineConf } from '@/packages/chartConfiguration/echarts/index' | |
| 88 | +import { GlobalThemeJsonType } from '@/settings/chartThemes/index' | |
| 89 | +import { | |
| 90 | + GlobalSetting, | |
| 91 | + CollapseItem, | |
| 92 | + SettingItemBox, | |
| 93 | + SettingItem | |
| 94 | +} from '@/components/Pages/ChartItemSetting' | |
| 95 | + | |
| 96 | +const props = defineProps({ | |
| 97 | + optionData: { | |
| 98 | + type: Object as PropType<GlobalThemeJsonType>, | |
| 99 | + required: true | |
| 100 | + }, | |
| 101 | +}) | |
| 102 | + | |
| 103 | +const seriesList = computed(() => { | |
| 104 | + return props.optionData.series | |
| 105 | +}) | |
| 106 | +</script> | ... | ... |
| 1 | +{ | |
| 2 | + "dimensions": ["product", "data1", "data2"], | |
| 3 | + "source": [ | |
| 4 | + { | |
| 5 | + "product": "Mon", | |
| 6 | + "data1": 120, | |
| 7 | + "data2": 130 | |
| 8 | + }, | |
| 9 | + { | |
| 10 | + "product": "Tue", | |
| 11 | + "data1": 200, | |
| 12 | + "data2": 130 | |
| 13 | + }, | |
| 14 | + { | |
| 15 | + "product": "Wed", | |
| 16 | + "data1": 150, | |
| 17 | + "data2": 312 | |
| 18 | + }, | |
| 19 | + { | |
| 20 | + "product": "Thu", | |
| 21 | + "data1": 80, | |
| 22 | + "data2": 268 | |
| 23 | + }, | |
| 24 | + { | |
| 25 | + "product": "Fri", | |
| 26 | + "data1": 70, | |
| 27 | + "data2": 155 | |
| 28 | + }, | |
| 29 | + { | |
| 30 | + "product": "Sat", | |
| 31 | + "data1": 110, | |
| 32 | + "data2": 117 | |
| 33 | + }, | |
| 34 | + { | |
| 35 | + "product": "Sun", | |
| 36 | + "data1": 130, | |
| 37 | + "data2": 160 | |
| 38 | + } | |
| 39 | + ] | |
| 40 | +} | ... | ... |
| 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('OverrideLineGradients', true) | |
| 6 | + | |
| 7 | +export const OverrideLineGradientsConfig: ConfigType = { | |
| 8 | + key, | |
| 9 | + chartKey, | |
| 10 | + conKey, | |
| 11 | + title: '双折线渐变面积图动画', | |
| 12 | + category: ChatCategoryEnum.LINE, | |
| 13 | + categoryName: ChatCategoryEnumName.LINE, | |
| 14 | + package: PackagesCategoryEnum.CHARTS, | |
| 15 | + chartFrame: ChartFrameEnum.ECHARTS, | |
| 16 | + image: 'line_gradient.png' | |
| 17 | +} | ... | ... |
| 1 | +<template> | |
| 2 | + <v-chart | |
| 3 | + ref="vChartRef" | |
| 4 | + :init-options="initOptions" | |
| 5 | + :theme="themeColor" | |
| 6 | + :option="option.value" | |
| 7 | + :manual-update="isPreview()" | |
| 8 | + autoresize | |
| 9 | + @mouseover="handleHighlight" | |
| 10 | + @mouseout="handleDownplay" | |
| 11 | + ></v-chart> | |
| 12 | +</template> | |
| 13 | + | |
| 14 | +<script setup lang="ts"> | |
| 15 | +import { reactive, watch, PropType,onMounted } from 'vue' | |
| 16 | +import VChart from 'vue-echarts' | |
| 17 | +import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook' | |
| 18 | +import { use, graphic } from 'echarts/core' | |
| 19 | +import { CanvasRenderer } from 'echarts/renderers' | |
| 20 | +import { LineChart } from 'echarts/charts' | |
| 21 | +import config, { includes } from './config' | |
| 22 | +import { mergeTheme } from '@/packages/public/chart' | |
| 23 | +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' | |
| 24 | +import { chartColorsSearch, defaultTheme } from '@/settings/chartThemes/index' | |
| 25 | +import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components' | |
| 26 | +import { useChartDataFetch } from '@/hooks' | |
| 27 | +import { isPreview, colorGradientCustomMerge} from '@/utils' | |
| 28 | +import dataJson from './data.json' | |
| 29 | + | |
| 30 | +const props = defineProps({ | |
| 31 | + themeSetting: { | |
| 32 | + type: Object, | |
| 33 | + required: true | |
| 34 | + }, | |
| 35 | + themeColor: { | |
| 36 | + type: Object, | |
| 37 | + required: true | |
| 38 | + }, | |
| 39 | + chartConfig: { | |
| 40 | + type: Object as PropType<config>, | |
| 41 | + required: true | |
| 42 | + } | |
| 43 | +}) | |
| 44 | + | |
| 45 | +const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting) | |
| 46 | + | |
| 47 | +use([DatasetComponent, CanvasRenderer, LineChart, GridComponent, TooltipComponent, LegendComponent]) | |
| 48 | +const chartEditStore = useChartEditStore() | |
| 49 | + | |
| 50 | +const option = reactive({ | |
| 51 | + value: {} | |
| 52 | +}) | |
| 53 | + | |
| 54 | +// 渐变色处理 | |
| 55 | +watch( | |
| 56 | + () => chartEditStore.getEditCanvasConfig.chartThemeColor, | |
| 57 | + (newColor: keyof typeof chartColorsSearch) => { | |
| 58 | + try { | |
| 59 | + if (!isPreview()) { | |
| 60 | + const themeColor = | |
| 61 | + colorGradientCustomMerge(chartEditStore.getEditCanvasConfig.chartCustomThemeColorInfo)[newColor] || | |
| 62 | + colorGradientCustomMerge(chartEditStore.getEditCanvasConfig.chartCustomThemeColorInfo)[defaultTheme] | |
| 63 | + props.chartConfig.option.series.forEach((value: any, index: number) => { | |
| 64 | + value.areaStyle.color = new graphic.LinearGradient(0, 0, 0, 1, [ | |
| 65 | + { | |
| 66 | + offset: 0, | |
| 67 | + color: themeColor[3 + index] | |
| 68 | + }, | |
| 69 | + { | |
| 70 | + offset: 1, | |
| 71 | + color: 'rgba(0,0,0, 0)' | |
| 72 | + } | |
| 73 | + ]) | |
| 74 | + }) | |
| 75 | + } | |
| 76 | + option.value = mergeTheme(props.chartConfig.option, props.themeSetting, includes) | |
| 77 | + props.chartConfig.option = option.value | |
| 78 | + } catch (error) { | |
| 79 | + console.log(error) | |
| 80 | + } | |
| 81 | + }, | |
| 82 | + { | |
| 83 | + immediate: true | |
| 84 | + } | |
| 85 | +) | |
| 86 | + | |
| 87 | +watch( | |
| 88 | + () => props.chartConfig.option.dataset, | |
| 89 | + () => { | |
| 90 | + option.value = props.chartConfig.option | |
| 91 | + } | |
| 92 | +) | |
| 93 | +let seriesDataNum = -1 | |
| 94 | +let seriesDataMaxLength = 0 | |
| 95 | +let intervalInstance: any = null | |
| 96 | +const duration = 1500 | |
| 97 | + | |
| 98 | +// 会重新选择需要选中和展示的数据 | |
| 99 | +const handleSeriesData = () => { | |
| 100 | + if (seriesDataNum > -1) { | |
| 101 | + vChartRef.value?.dispatchAction({ | |
| 102 | + type: 'downplay', | |
| 103 | + dataIndex: seriesDataNum | |
| 104 | + }) | |
| 105 | + } | |
| 106 | + seriesDataNum = seriesDataNum >= seriesDataMaxLength - 1 ? 0 : seriesDataNum + 1 | |
| 107 | + vChartRef.value?.dispatchAction({ | |
| 108 | + type: 'showTip', | |
| 109 | + seriesIndex: 0, | |
| 110 | + dataIndex: seriesDataNum | |
| 111 | + }) | |
| 112 | +} | |
| 113 | + | |
| 114 | +// 新增轮播 | |
| 115 | +const addPieInterval = (newData?: typeof dataJson, skipPre = false) => { | |
| 116 | + if (!skipPre && !Array.isArray(newData?.source)) return | |
| 117 | + if (!skipPre) seriesDataMaxLength = newData?.source.length || 0 | |
| 118 | + clearInterval(intervalInstance) | |
| 119 | + intervalInstance = setInterval(() => { | |
| 120 | + handleSeriesData() | |
| 121 | + }, duration) | |
| 122 | +} | |
| 123 | + | |
| 124 | +// 取消轮播 | |
| 125 | +const clearPieInterval = () => { | |
| 126 | + vChartRef.value?.dispatchAction({ | |
| 127 | + type: 'hideTip', | |
| 128 | + seriesIndex: 0, | |
| 129 | + dataIndex: seriesDataNum | |
| 130 | + }) | |
| 131 | + vChartRef.value?.dispatchAction({ | |
| 132 | + type: 'downplay', | |
| 133 | + dataIndex: seriesDataNum | |
| 134 | + }) | |
| 135 | + clearInterval(intervalInstance) | |
| 136 | + intervalInstance = null | |
| 137 | +} | |
| 138 | + | |
| 139 | +// 处理鼠标聚焦高亮内容 | |
| 140 | +const handleHighlight = () => { | |
| 141 | + clearPieInterval() | |
| 142 | +} | |
| 143 | + | |
| 144 | +// 处理鼠标取消悬浮 | |
| 145 | +const handleDownplay = () => { | |
| 146 | + if (props.chartConfig.option.isCarousel && !intervalInstance) { | |
| 147 | + // 恢复轮播 | |
| 148 | + addPieInterval(undefined, true) | |
| 149 | + } | |
| 150 | +} | |
| 151 | + | |
| 152 | +watch( | |
| 153 | + () => props.chartConfig.option.isCarousel, | |
| 154 | + newData => { | |
| 155 | + if (newData) { | |
| 156 | + addPieInterval(undefined, true) | |
| 157 | + props.chartConfig.option.legend.show = false | |
| 158 | + } else { | |
| 159 | + props.chartConfig.option.legend.show = true | |
| 160 | + clearPieInterval() | |
| 161 | + } | |
| 162 | + } | |
| 163 | +) | |
| 164 | + | |
| 165 | +const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: typeof dataJson) => { | |
| 166 | + addPieInterval(newData) | |
| 167 | +}) | |
| 168 | + | |
| 169 | +onMounted(() => { | |
| 170 | + seriesDataMaxLength = dataJson.source.length | |
| 171 | + if (props.chartConfig.option.isCarousel) { | |
| 172 | + addPieInterval(undefined, true) | |
| 173 | + } | |
| 174 | +}) | |
| 175 | +</script> | ... | ... |
| ... | ... | @@ -9,6 +9,9 @@ import { OverrideSelectConfig } from '@/packages/components/external/Information |
| 9 | 9 | import { OverrideInputsDateConfig } from '@/packages/components/external/Informations/Mores/OverrideInputsDate' |
| 10 | 10 | import { OverrideInputsTabConfig } from '@/packages/components/external/Informations/Mores/OverrideInputsTab' |
| 11 | 11 | import { OverrideTextCommonConfig } from '@/packages/components/external/Informations/Mores/OverrideTextCommon' |
| 12 | +import { OverrideBarCommonConfig } from '@/packages/components/external/Charts/Bars/OverrideBarCommon' | |
| 13 | +import { OverrideLineCommonConfig } from '@/packages/components/external/Charts/Lines/OverrideLineCommon' | |
| 14 | +import { OverrideLineGradientsConfig } from '@/packages/components/external/Charts/Lines/OverrideLineGradients' | |
| 12 | 15 | |
| 13 | 16 | export function useInjectLib(packagesList: EPackagesType) { |
| 14 | 17 | |
| ... | ... | @@ -22,6 +25,9 @@ export function useInjectLib(packagesList: EPackagesType) { |
| 22 | 25 | addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideInputsDateConfig) |
| 23 | 26 | addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideInputsTabConfig) |
| 24 | 27 | addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.INFORMATIONS, OverrideTextCommonConfig) |
| 28 | + addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.CHARTS, OverrideBarCommonConfig) | |
| 29 | + addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.CHARTS, OverrideLineCommonConfig) | |
| 30 | + addWidgetToCategoryByCategoryName(packagesList, PackagesCategoryEnum.CHARTS, OverrideLineGradientsConfig) | |
| 25 | 31 | } |
| 26 | 32 | |
| 27 | 33 | /** | ... | ... |