Commit 0f4fd10441ed95b7bdda89cf7af57134fac6e525

Authored by xp.Huang
2 parents fdac1076 303d9e5d

Merge branch 'dev_byft' into 'main_dev'

fix(src/views/chart):修复当历史数据折线图开启动画效果时,数据显示为10条数据,但是只执行动效到第七条又返回从第一条开始执行了

See merge request yunteng/thingskit-view!182
Showing 31 changed files with 884 additions and 977 deletions
src/components/external/Common/TKDialog/components/Circle.vue renamed from src/packages/components/external/Decorates/Mores/PickIcon/components/Circle.vue
  1 +export interface PopupConfigInterface {
  2 + borderWidth: number
  3 + borderHeight: number
  4 + borderColor: string
  5 + boxShadowColor: string
  6 + linearLeftColor: string
  7 + linearRightColor: string
  8 + arrowColor: string
  9 + lineColor: string
  10 + fontColor: string
  11 + fontSize: number
  12 + fontWeight: number
  13 + fontContent: string
  14 + labelColor: string
  15 + valueColor: string
  16 + placement: string
  17 +}
  18 +export interface PopupConfigData {
  19 + label: string
  20 + value: string
  21 +}
... ...
  1 +import TKDialog from './index.vue';
  2 +
  3 +export { TKDialog };
... ...
  1 +<template>
  2 + <n-popover
  3 + :disabled="disabled"
  4 + :placement="popupConfig.placement"
  5 + trigger="click"
  6 + raw
  7 + @update:show="handleUpdateShow"
  8 + >
  9 + <template #trigger>
  10 + <slot />
  11 + </template>
  12 + <div
  13 + style="transform-origin: inherit"
  14 + :style="`width:${popupConfig.borderWidth}px;
  15 + height: ${popupConfig.borderHeight}px;
  16 + box-shadow: 0 0 10px 10px ${popupConfig.boxShadowColor};
  17 + background:linear-gradient(to right, ${popupConfig.linearLeftColor} , ${popupConfig.linearRightColor});
  18 + `"
  19 + >
  20 + <div class="popup-body">
  21 + <div class="popup-arrow-right" :style="`border-color:${popupConfig.arrowColor}`"></div>
  22 + <div class="popup-header-content">
  23 + <p
  24 + class="header-title"
  25 + :style="`color:${popupConfig.fontColor};font-size:${popupConfig.fontSize}px;font-weight:${popupConfig.fontWeight}`"
  26 + >
  27 + {{ popupConfig.fontContent }}
  28 + </p>
  29 + <div class="header-content-graphical">
  30 + <div class="graphical-circle-left"><Circle /></div>
  31 + <div class="graphical-line">
  32 + <div class="line-left" :style="`background-color:${popupConfig.lineColor}`"></div>
  33 + <div class="line-center" :style="`background-color:${popupConfig.lineColor}`"></div>
  34 + <div class="line-right" :style="`background-color:${popupConfig.lineColor}`"></div>
  35 + </div>
  36 + <div class="graphical-circle-right"><Circle /></div>
  37 + </div>
  38 + </div>
  39 + </div>
  40 + <div class="content-body">
  41 + <div class="body" v-for="(item, index) in popupConfigData" :key="index">
  42 + <span :style="`color:${popupConfig.labelColor};`">{{ item.label }}</span>
  43 + <span :style="`color:${popupConfig.valueColor};`">{{ item.value }}</span>
  44 + </div>
  45 + </div>
  46 + </div>
  47 + </n-popover>
  48 +</template>
  49 +
  50 +<script lang="ts" setup name="TKDialog">
  51 +import { PropType } from 'vue'
  52 +import { PopupConfigInterface, PopupConfigData } from './index.d'
  53 +import Circle from './components/Circle.vue'
  54 +
  55 +defineProps({
  56 + popupConfig: {
  57 + type: Object as PropType<PopupConfigInterface>,
  58 + required: true
  59 + },
  60 + popupConfigData: {
  61 + type: Array as PropType<PopupConfigData[]>
  62 + },
  63 + w: Number,
  64 + h: Number,
  65 + disabled: {
  66 + type: Boolean,
  67 + default: false
  68 + }
  69 +})
  70 +
  71 +const emits = defineEmits(['updateShow'])
  72 +
  73 +const handleUpdateShow = (show: boolean) => {
  74 + console.log(show)
  75 + emits('updateShow', show)
  76 +}
  77 +</script>
  78 +
  79 +<style lang="scss" scoped>
  80 +@mixin base-text-ellipsis() {
  81 + overflow: hidden;
  82 + white-space: nowrap;
  83 + text-overflow: ellipsis;
  84 + -o-text-overflow: ellipsis;
  85 +}
  86 +.popup-body {
  87 + display: flex;
  88 + justify-content: center;
  89 + flex-direction: column;
  90 + .popup-arrow-right {
  91 + position: absolute;
  92 + top: 15px;
  93 + left: 10px;
  94 + border-right: 1px solid;
  95 + border-bottom: 1px solid;
  96 + width: 7px;
  97 + height: 7px;
  98 + transform: rotate(-45deg);
  99 + -o-transform: rotate(-45deg);
  100 + -webkit-transform: rotate(-45deg);
  101 + -moz-transform: rotate(-45deg);
  102 + -ms-transform: rotate(-45deg);
  103 + }
  104 + .popup-header-content {
  105 + margin: 23px;
  106 + display: flex;
  107 + justify-content: center;
  108 + flex-direction: column;
  109 + .header-title {
  110 + @include base-text-ellipsis;
  111 + }
  112 + .header-content-graphical {
  113 + display: flex;
  114 + align-items: center;
  115 + .graphical-circle-left {
  116 + position: relative;
  117 + left: -2px;
  118 + }
  119 + .graphical-line {
  120 + display: flex;
  121 + position: relative;
  122 + .line-left {
  123 + width: 115px;
  124 + height: 2px;
  125 + position: relative;
  126 + }
  127 + .line-center {
  128 + width: 35px;
  129 + height: 2px;
  130 + transform: rotateZ(145deg);
  131 + position: absolute;
  132 + top: -10px;
  133 + left: 112px;
  134 + }
  135 + .line-right {
  136 + width: 50px;
  137 + height: 2px;
  138 + position: absolute;
  139 + top: -20px;
  140 + left: 143px;
  141 + }
  142 + }
  143 + .graphical-circle-right {
  144 + position: absolute;
  145 + top: 29px;
  146 + left: 231px;
  147 + }
  148 + }
  149 + }
  150 +}
  151 +.content-body {
  152 + display: flex;
  153 + flex-direction: column;
  154 + gap: 4px;
  155 + width: v-bind('w+"px"');
  156 + margin: 0 15px;
  157 + height: v-bind('h+"px"');
  158 +}
  159 +</style>
... ...
1   -import { toRefs } from 'vue'
2 1 import { CreateComponentType } from '@/packages/index.d'
3 2 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
4 3 import { PageChartEditStoreType } from '@/store/modules/chartEditStore/chartEditStore.d'
... ...
... ... @@ -10,5 +10,5 @@ export const InputsInputConfig: ConfigType = {
10 10 categoryName: ChatCategoryEnumName.INPUTS,
11 11 package: PackagesCategoryEnum.INFORMATIONS,
12 12 chartFrame: ChartFrameEnum.STATIC,
13   - image: 'inputs_select.png'
  13 + image: 'inputs_input.png'
14 14 }
\ No newline at end of file
... ...
... ... @@ -8,15 +8,19 @@ export const option = {
8 8 header: ['列1', '列2', '列3'],
9 9 dataset: dataJson,
10 10 index: true,
11   - columnWidth: [30, 100, 100],
12   - align: ['center', 'right', 'right', 'right'],
  11 + columnWidth: [100, 300, 300, 300],
  12 + align: ['center', 'center', 'center', 'center'],
13 13 rowNum: 5,
14 14 waitTime: 2,
15 15 headerHeight: 35,
16 16 carousel: 'single',
17 17 headerBGC: '#00BAFF',
18 18 oddRowBGC: '#003B51',
19   - evenRowBGC: '#0A2732'
  19 + evenRowBGC: '#0A2732',
  20 + ceilSpanColor: '#FFFFFF',
  21 + ceilSpanFontSize: 16,
  22 + headerSpanColor: '#FFFFFF',
  23 + headerSpanFontSize: 16
20 24 }
21 25
22 26 export default class Config extends PublicConfigClass implements CreateComponentType {
... ...
... ... @@ -45,12 +45,37 @@
45 45 v-model:value="optionData.carousel"
46 46 :options="[
47 47 { label: '单条轮播', value: 'single' },
48   - { label: '整页轮播', value: 'page' },
  48 + { label: '整页轮播', value: 'page' }
49 49 ]"
50 50 />
51 51 </SettingItem>
52 52 </SettingItemBox>
53   -
  53 + <SettingItemBox name="表头字体">
  54 + <SettingItem name="颜色">
  55 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.headerSpanColor"></n-color-picker>
  56 + </SettingItem>
  57 + <SettingItem name="大小">
  58 + <n-input-number
  59 + v-model:value="optionData.headerSpanFontSize"
  60 + :min="1"
  61 + size="small"
  62 + placeholder="请输入"
  63 + ></n-input-number>
  64 + </SettingItem>
  65 + </SettingItemBox>
  66 + <SettingItemBox name="内容字体">
  67 + <SettingItem name="颜色">
  68 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.ceilSpanColor"></n-color-picker>
  69 + </SettingItem>
  70 + <SettingItem name="大小">
  71 + <n-input-number
  72 + v-model:value="optionData.ceilSpanFontSize"
  73 + :min="1"
  74 + size="small"
  75 + placeholder="请输入"
  76 + ></n-input-number>
  77 + </SettingItem>
  78 + </SettingItemBox>
54 79 <SettingItemBox name="样式">
55 80 <SettingItem name="表头背景色">
56 81 <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.headerBGC"></n-color-picker>
... ...
... ... @@ -6,13 +6,15 @@
6 6 :style="`background-color: ${status.mergedConfig.headerBGC};`"
7 7 >
8 8 <div
9   - class="header-item"
  9 + class="header-item singe-line"
10 10 v-for="(headerItem, i) in status.header"
11 11 :key="`${headerItem}${i}`"
12 12 :style="`
13 13 height: ${status.mergedConfig.headerHeight}px;
14 14 line-height: ${status.mergedConfig.headerHeight}px;
15 15 width: ${status.widths[i]}px;
  16 + color:${headerSpanColor};
  17 + font-size:${headerSpanFontSize}px;
16 18 `"
17 19 :align="status.aligns[i]"
18 20 v-html="headerItem"
... ... @@ -24,30 +26,32 @@
24 26 class="rows"
25 27 :style="`height: ${h - (status.header.length ? status.mergedConfig.headerHeight : 0)}px;`"
26 28 >
27   - <div v-if="status.rows.length">
28   - <div
29   - class="row-item"
30   - v-for="(row, ri) in status.rows"
31   - :key="`${row.toString()}${row.scroll}`"
32   - :style="`
  29 + <div v-if="status.rows.length">
  30 + <div
  31 + class="row-item"
  32 + v-for="(row, ri) in status.rows"
  33 + :key="`${row.toString()}${row.scroll}`"
  34 + :style="`
33 35 height: ${status.heights[ri]}px;
34 36 line-height: ${status.heights[ri]}px;
35 37 background-color: ${status.mergedConfig[row.rowIndex % 2 === 0 ? 'evenRowBGC' : 'oddRowBGC']};
36 38 `"
37   - >
38   - <div
39   - class="ceil"
40   - v-for="(ceil, ci) in row.ceils"
41   - :key="`${ceil}${ri}${ci}`"
42   - :style="`width: ${status.widths[ci]}px;`"
43   - :align="status.aligns[ci]"
44   - v-html="ceil"
45   - />
  39 + >
  40 + <div
  41 + class="ceil singe-line"
  42 + v-for="(ceil, ci) in row.ceils"
  43 + :key="`${ceil}${ri}${ci}`"
  44 + :style="`
  45 + width: ${status.widths[ci]}px;
  46 + color:${ceilSpanColor};
  47 + font-size:${ceilSpanFontSize}px;
  48 + `"
  49 + :align="status.aligns[ci]"
  50 + v-html="ceil"
  51 + />
  52 + </div>
46 53 </div>
47   - </div>
48   - <div v-else class="nullData">
49   - 暂无数据
50   - </div>
  54 + <div v-else class="nullData">暂无数据</div>
51 55 </div>
52 56 </div>
53 57 </template>
... ... @@ -70,7 +74,7 @@ const props = defineProps({
70 74 // 这里能拿到图表宽高等
71 75 const { w, h } = toRefs(props.chartConfig.attr)
72 76 // 这里能拿到上面 config.ts 里的 option 数据
73   -// const { rowNum, headerHeight, index, backgroundColor } = toRefs(props.chartConfig.option)
  77 +const { ceilSpanColor, ceilSpanFontSize, headerSpanColor, headerSpanFontSize } = toRefs(props.chartConfig.option)
74 78
75 79 const status = reactive({
76 80 defaultConfig: {
... ... @@ -355,6 +359,12 @@ onUnmounted(() => {
355 359 </script>
356 360
357 361 <style lang="scss" scoped>
  362 +.singe-line {
  363 + text-overflow: ellipsis;
  364 + overflow: hidden;
  365 + word-break: break-all;
  366 + white-space: nowrap;
  367 +}
358 368 .dv-scroll-board {
359 369 position: relative;
360 370 width: 100%;
... ... @@ -389,11 +399,11 @@ onUnmounted(() => {
389 399 overflow: hidden;
390 400 }
391 401 }
392   - .nullData{
  402 + .nullData {
393 403 display: flex;
394 404 justify-content: center;
395 405 align-items: center;
396   - color:white;
  406 + color: white;
397 407 height: 100%;
398 408 width: 100%;
399 409 background: #356b80;
... ...
... ... @@ -254,6 +254,7 @@ const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (n
254 254 }
255 255 })
256 256 //
  257 + addPieInterval(newData)
257 258 updateVChart(newData)
258 259 })
259 260
... ...
... ... @@ -273,6 +273,7 @@ const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, ne
273 273 }
274 274 })
275 275 //
  276 + addPieInterval(newData)
276 277 updateVChart(newData)
277 278 })
278 279
... ...
... ... @@ -71,6 +71,27 @@ export const regionMapParentArea = {
71 71
72 72 export const includes = []
73 73
  74 +// 特殊处理安徽省的下钻
  75 +export const specialTreatmentAnhui = [
  76 + '合肥市',
  77 + '马鞍山市',
  78 + '淮北市',
  79 + '宿州市',
  80 + '阜阳市',
  81 + '蚌埠市',
  82 + '淮南市',
  83 + '滁州市',
  84 + '六安市',
  85 + '巢湖市',
  86 + '芜湖市',
  87 + '亳州市',
  88 + '安庆市',
  89 + '池州市',
  90 + '铜陵市',
  91 + '宣城市',
  92 + '黄山市'
  93 +]
  94 +
74 95 export const option = {
75 96 iconColor: 'black',
76 97 showIcon: false,
... ... @@ -158,7 +179,7 @@ export const option = {
158 179 bevelSize: 0,
159 180 minHeight: 12,
160 181 shading: 'lambert',
161   - barSize: 2,
  182 + barSize: 1,
162 183 itemStyle: {
163 184 color: '#4482B1FF'
164 185 },
... ...
... ... @@ -41,7 +41,7 @@
41 41 :drillingIn="optionData.drillingIn"
42 42 @submit="onHandleSelectValues"
43 43 />
44   - <div style="height:30px"></div>
  44 + <div style="height: 30px"></div>
45 45 <n-tag type="primary">若配置无响应,请在预览页面查看效果</n-tag>
46 46 <SettingItemBox name="区块配置">
47 47 <SettingItem name="区域颜色">
... ... @@ -170,11 +170,14 @@
170 170 ></n-input-number>
171 171 </SettingItem>
172 172 </SettingItemBox>
173   - <!-- <SettingItemBox name="区块配置">
  173 + <SettingItemBox name="区块配置">
174 174 <template v-for="(item, map3DIndex) in optionData.dataset.map3D" :key="map3DIndex">
175 175 <setting-item name="地区名称">
176 176 <n-input v-model:value="item.name"> </n-input>
177 177 </setting-item>
  178 + <setting-item name="地区代码">
  179 + <n-input v-model:value="item.adcode"> </n-input>
  180 + </setting-item>
178 181 <setting-item name="离地高度">
179 182 <n-input-number v-model:value="item.height"> </n-input-number>
180 183 </setting-item>
... ... @@ -195,14 +198,14 @@
195 198 >
196 199 +
197 200 </n-button>
198   - </SettingItemBox> -->
  201 + </SettingItemBox>
199 202 <SettingItemBox name="散点配置">
200 203 <template v-for="(item, scatterIndex) in optionData.dataset.scatter3D" :key="scatterIndex">
201 204 <setting-item name="地区名称">
202 205 <n-input v-model:value="item.name"> </n-input>
203 206 </setting-item>
204 207 <setting-item name="地区代码">
205   - <n-input-number v-model:value="item.adcode"> </n-input-number>
  208 + <n-input v-model:value="item.adcode"> </n-input>
206 209 </setting-item>
207 210 <setting-item name="离地高度">
208 211 <n-input-number v-model:value="item.height"> </n-input-number>
... ... @@ -238,7 +241,7 @@
238 241 <n-input v-model:value="item.name"> </n-input>
239 242 </setting-item>
240 243 <setting-item name="地区代码">
241   - <n-input-number v-model:value="item.adcode"> </n-input-number>
  244 + <n-input v-model:value="item.adcode"> </n-input>
242 245 </setting-item>
243 246 <setting-item name="离地高度">
244 247 <n-input-number v-model:value="item.height"> </n-input-number>
... ...
... ... @@ -3,6 +3,18 @@
3 3 {
4 4 "name": "四川省",
5 5 "height": 5,
  6 + "adcode": "510000",
  7 + "itemStyle": {
  8 + "color": "#4482B1FF",
  9 + "opacity": 1,
  10 + "borderWidth": 0.4,
  11 + "borderColor": "#5F9EA0"
  12 + }
  13 + },
  14 + {
  15 + "name": "山西省",
  16 + "height": 6,
  17 + "adcode": "140000",
6 18 "itemStyle": {
7 19 "color": "#4482B1FF",
8 20 "opacity": 1,
... ... @@ -19,7 +31,7 @@
19 31 23.1301964,
20 32 20000
21 33 ],
22   - "adcode": 440000,
  34 + "adcode": "440000",
23 35 "height": 5,
24 36 "itemStyle": {
25 37 "color": "#4482B1FF",
... ... @@ -33,11 +45,11 @@
33 45 {
34 46 "name": "安徽省",
35 47 "value": [
36   - 114.878463,
37   - 29.395191,
  48 + 117.283042,
  49 + 31.86119,
38 50 20000
39 51 ],
40   - "adcode": 340000,
  52 + "adcode": "340000",
41 53 "height": 5,
42 54 "itemStyle": {
43 55 "color": "#4482B1FF",
... ...
... ... @@ -19,7 +19,8 @@ import config, {
19 19 historyParentType,
20 20 backMapLevel,
21 21 levelFunc,
22   - regionMapParentArea
  22 + regionMapParentArea,
  23 + specialTreatmentAnhui
23 24 } from './config'
24 25 import { getGeoJsonMap } from '@/api/external/common'
25 26 import { ThreeMapEnum } from '@/enums/external/mapEnum'
... ... @@ -151,7 +152,9 @@ const handleMap3DClick = async (params: Recordable) => {
151 152 saveClickRegion.value.level = level
152 153 saveLevelStr.level = level
153 154 saveHistoryParent.value.push({
154   - adcode: item.properties.parent.adcode,
  155 + adcode: specialTreatmentAnhui.includes(item.properties.name)
  156 + ? JSON.parse(item.properties.parent)?.adcode
  157 + : item.properties.parent.adcode,
155 158 level: (regionMapParentArea as Recordable)[level]
156 159 })
157 160 }
... ... @@ -186,7 +189,7 @@ const getGeojson = (regionId: number | string) => {
186 189 const nameChina = name === '中国' ? 'china' : name //为中国的话,registerMap第一个必须是china,否则显示不出来
187 190 /**
188 191 * 主要注意的点,registerMap中的第一个参数需要和series中的map匹配,否则渲染不出地图,
189   - * 比如map: 'beijing' echarts.registerMap('beijing', beijingGeoJSON);
  192 + * 比如map: '北京市' echarts.registerMap('北京市', beijingGeoJSON);
190 193 */
191 194 registerMap(level === areaEnum.COUNTRY ? nameChina : code, { geoJSON: geoJsonFile, specialAreas: {} }) //注册geoJSON
192 195 resolve(true)
... ... @@ -221,7 +224,7 @@ const initMap3D = async () => {
221 224 await nextTick()
222 225 await getGeojson(mapRegion.value.adcode)
223 226 await nextTick().then(() => {
224   - handleRegisterMapNameAndData(mapRegion.value.adcode, dataset.value, true)
  227 + handleRegisterMapNameAndData(mapRegion.value.adcode, dataset.value)
225 228 })
226 229 chartInstance.value?.on('click', (e: Recordable) => {
227 230 if (!e) return
... ... @@ -232,14 +235,12 @@ const initMap3D = async () => {
232 235 onMounted(() => initMap3D())
233 236
234 237 // 动态注册 series中的map必须和registerMap的第一个参数匹配,否则渲染不出
235   -const handleRegisterMapNameAndData = (adcode: string | number, data: Recordable, includeMap3D: boolean) => {
  238 +const handleRegisterMapNameAndData = (adcode: string | number, data: Recordable) => {
236 239 geo3D.value.map = adcode // coordinateSystem使用了geo3D,不能删除这一行
237 240 series.value.forEach((item: Recordable) => {
238   - if (includeMap3D) {
239   - if (item.type === ThreeMapEnum.MAP3D) {
240   - item.map = adcode
241   - // item.data = data[ThreeMapEnum.MAP3D]
242   - }
  241 + if (item.type === ThreeMapEnum.MAP3D) {
  242 + item.map = adcode
  243 + item.data = data[ThreeMapEnum.MAP3D]
243 244 }
244 245 if (item.type === ThreeMapEnum.SCATTER3D) {
245 246 item.data = data[ThreeMapEnum.SCATTER3D]
... ... @@ -254,8 +255,8 @@ const handleRegisterMapNameAndData = (adcode: string | number, data: Recordable,
254 255 const handleSetOption = (instance: EChartsType, option: Recordable) => {
255 256 if (!instance) return
256 257 try {
257   - instance.clear()
258   - instance.setOption(option)
  258 + instance && instance.clear()
  259 + instance && instance.setOption(option)
259 260 } catch (error) {
260 261 console.error('动态触发渲染出错,出错原因->', error)
261 262 }
... ... @@ -275,14 +276,19 @@ watch(
275 276 //处理数据标点
276 277 const handleDataPoint = (newData: string | number) => {
277 278 if (newData === 'china') {
278   - handleRegisterMapNameAndData(newData, dataset.value, true)
  279 + // 全国则展示所有的标点
  280 + handleRegisterMapNameAndData(newData, dataset.value)
279 281 } else {
  282 + // 展示对应区域的标点
280 283 series.value.forEach((item: Recordable) => {
  284 + if (item.type === ThreeMapEnum.MAP3D) {
  285 + item.data = [] //置空,否则鼠标移上去点击不了,不知道原因!
  286 + }
281 287 if (item.type === ThreeMapEnum.SCATTER3D) {
282   - item.data = dataset.value[ThreeMapEnum.SCATTER3D].filter((item: dataPointI) => item.adcode === newData)
  288 + item.data = dataset.value[ThreeMapEnum.SCATTER3D].filter((dataItem: dataPointI) => dataItem.adcode === newData)
283 289 }
284 290 if (item.type === ThreeMapEnum.BAR3D) {
285   - item.data = dataset.value[ThreeMapEnum.BAR3D].filter((item: dataPointI) => item.adcode === newData)
  291 + item.data = dataset.value[ThreeMapEnum.BAR3D].filter((dataItem: dataPointI) => dataItem.adcode === newData)
286 292 }
287 293 })
288 294 }
... ... @@ -294,9 +300,9 @@ watch(
294 300 async (newData: string | number) => {
295 301 try {
296 302 await getGeojson(newData)
297   - handleRegisterMapNameAndData(newData, dataset.value, true)
298   - handleSetOption(chartInstance.value!, props.chartConfig.option)
  303 + handleRegisterMapNameAndData(newData, dataset.value)
299 304 handleDataPoint(newData)
  305 + handleSetOption(chartInstance.value!, props.chartConfig.option)
300 306 } catch (error) {
301 307 console.error('展示区域发生变化出错,出错原因->', error)
302 308 }
... ...
1   -<template>
2   - <!-- 原生方式,没有使用vue-echarts -->
3   - <n-space vertical>
4   - <n-spin :show="show">
5   - <div :style="`width:${w}px;height:${h}px;`" ref="map3DRef"></div>
6   - </n-spin>
7   - </n-space>
8   -</template>
9   -
10   -<script setup lang="ts">
11   -import { onMounted, ref, nextTick, PropType, toRefs, watch, reactive } from 'vue'
12   -import * as echarts from 'echarts'
13   -import { registerMap } from 'echarts/core'
14   -import 'echarts-gl'
15   -import config, { areaEnum, dataPointI, optionType, historyParentType, backMapLevel } from './config'
16   -import { getGeoJsonMap } from '@/api/external/common'
17   -
18   -const props = defineProps({
19   - chartConfig: {
20   - type: Object as PropType<config>,
21   - required: true
22   - }
23   -})
24   -
25   -const backIcon =
26   - 'path://M853.333333 245.333333H245.333333l93.866667-93.866666c12.8-12.8 12.8-34.133333 0-46.933334-12.8-12.8-34.133333-12.8-46.933333 0l-145.066667 145.066667c-12.8 12.8-12.8 34.133333 0 46.933333l145.066667 145.066667c6.4 6.4 14.933333 10.666667 23.466666 10.666667s17.066667-4.266667 23.466667-10.666667c12.8-12.8 12.8-34.133333 0-46.933333L256 311.466667h597.333333c6.4 0 10.666667 4.266667 10.666667 10.666666v426.666667c0 6.4-4.266667 10.666667-10.666667 10.666667H170.666667c-17.066667 0-32 14.933333-32 32s14.933333 32 32 32h682.666666c40.533333 0 74.666667-34.133333 74.666667-74.666667V320c0-40.533333-34.133333-74.666667-74.666667-74.666667z'
27   -
28   -const { w, h } = toRefs(props.chartConfig.attr)
29   -
30   -const map3DRef = ref()
31   -
32   -const show = ref(true)
33   -
34   -const chartInstance = ref()
35   -
36   -const toolBoxOption = ref({
37   - show: true,
38   - right: 110,
39   - top: 20,
40   - feature: {
41   - myFullButton: {
42   - show: false,
43   - title: '返回',
44   - icon: backIcon,
45   - iconStyle: {
46   - color: ''
47   - },
48   - onclick: () => handleBack()
49   - }
50   - }
51   -})
52   -
53   -const excludeCountryLevels = ['PROVINCE', 'CITY'] //如果从右侧配置选择全中国
54   -
55   -const includeCityLevels = ['CITY'] //如果从右侧配置选择省份
56   -
57   -//元组 优化if elseif else分支 隐藏返回图标
58   -const backIconMappingLevels: any[][] = [
59   - [
60   - (levelStr: string) => levelStr === areaEnum.COUNTRY,
61   - (level: string) => excludeCountryLevels.includes(level),
62   - () => (toolBoxOption.value.feature.myFullButton.show = true),
63   - () => (toolBoxOption.value.feature.myFullButton.show = false)
64   - ],
65   - [
66   - (levelStr: string) => levelStr === areaEnum.PROVINCE,
67   - (level: string) => includeCityLevels.includes(level),
68   - () => (toolBoxOption.value.feature.myFullButton.show = true),
69   - () => (toolBoxOption.value.feature.myFullButton.show = false)
70   - ]
71   -]
72   -
73   -watch(
74   - () => props.chartConfig.option,
75   - (newData: optionType) => {
76   - const { iconColor, iconDistanceRight, iconDistanceTop, mapRegion } = newData
77   - const { saveSelect } = mapRegion
78   - const { levelStr } = saveSelect
79   - const findBackLevel = backIconMappingLevels.find((backLevelItem: backMapLevel[]) =>
80   - backLevelItem[0](levelStr)
81   - ) as backMapLevel[]
82   - if (findBackLevel) {
83   - if (findBackLevel[0]) {
84   - const findLevel = findBackLevel[1](saveLevelStr.level)
85   - if (findLevel) findBackLevel[2]()
86   - else findBackLevel[3]()
87   - }
88   - }
89   - toolBoxOption.value.feature.myFullButton.iconStyle.color = iconColor //返回图标颜色
90   - toolBoxOption.value.right = iconDistanceRight
91   - toolBoxOption.value.top = iconDistanceTop
92   - },
93   - {
94   - deep: true
95   - }
96   -)
97   -
98   -//追加echarts右上角自带toolbox
99   -props.chartConfig.option = {
100   - ...props.chartConfig.option,
101   - ...{ toolbox: toolBoxOption.value }
102   -}
103   -
104   -//地图点击返回
105   -const handleBack = async () => {
106   - stopWatch()
107   - if (props.chartConfig.option.drillingIn) {
108   - //如果是从右边配置里设置的,比如点击四川省,然后点击返回
109   - const savePopParent = saveHistoryParent.value.pop()
110   - let saveAdcode = savePopParent?.adcode as string | number
111   - saveLevelStr.level = savePopParent?.level as string
112   - if (!savePopParent) {
113   - saveAdcode = getParentAdcode(props.chartConfig.option.mapRegion.adcode)
114   - saveLevelStr.level = (regionMapParentArea as Recordable)[props.chartConfig.option.mapRegion.saveSelect.levelStr]
115   - }
116   - if (saveAdcode === 0) {
117   - saveAdcode = 'china'
118   - saveLevelStr.level = areaEnum.COUNTRY
119   - }
120   - const exist = await getGeojson(saveAdcode)
121   - const adcode = saveAdcode === 100000 ? 'china' : saveAdcode
122   - props.chartConfig.option.saveClickRegion.level = saveLevelStr.level
123   - if (exist) {
124   - //fix解决点击下钻返回后页面为空问题
125   - props.chartConfig.option.mapRegion.adcode = adcode
126   - }
127   - }
128   -}
129   -
130   -//地区上级对应配置
131   -const regionMapParentArea = {
132   - PROVINCE: areaEnum.COUNTRY, //省份的上一级 中国
133   - CITY: areaEnum.PROVINCE, //城市的上一级 省份
134   - COUNTY: areaEnum.CITY, //县或者区的上一级 城市
135   - TOWN: areaEnum.COUNTY //镇的上一级 县或者区
136   -}
137   -
138   -//地图点击
139   -const handleMap3DClick = async (params: Recordable) => {
140   - if (props.chartConfig.option.drillingIn) {
141   - const { name } = params
142   - saveGeojson.value?.features.forEach((item: Recordable) => {
143   - if (item.properties.name === name) {
144   - const level = item.properties.level.toUpperCase()
145   - const adcode = item.properties.adcode
146   - if (level === 'DISTRICT') return //下钻暂且不支持地区
147   - if (String(adcode).startsWith('15') && level === areaEnum.CITY) return //特殊处理地区码15开头的
148   - props.chartConfig.option.mapRegion.adcode = adcode
149   - props.chartConfig.option.saveClickRegion.level = level
150   - saveLevelStr.level = level
151   - handleDataPoint(adcode)
152   - saveHistoryParent.value.push({
153   - adcode: item.properties.parent.adcode,
154   - level: (regionMapParentArea as Recordable)[level]
155   - })
156   - }
157   - })
158   - }
159   -}
160   -
161   -const saveGeojson: Recordable = ref({}) // 保存geojson
162   -
163   -const chinaDefaultRegionId = ref(100000) //如果是china则adcode为100000
164   -
165   -const saveLevelStr = reactive<{ level: historyParentType['level'] }>({
166   - // 地区级别
167   - level: ''
168   -})
169   -
170   -const saveHistoryParent = ref<historyParentType[]>([])
171   -
172   -//动态注册地图
173   -const getGeojson = (regionId: number | string) => {
174   - try {
175   - return new Promise<boolean>(resolve => {
176   - const { levelStr } = props.chartConfig.option.mapRegion.saveSelect //右侧配置项获取的行政级别
177   - getGeoJsonMap(
178   - regionId === 'china' ? chinaDefaultRegionId.value : regionId,
179   - !saveLevelStr.level ? levelStr : saveLevelStr.level //没有则获取右侧配置的行政级别
180   - ).then(res => {
181   - const { geoJson, name, code, level } = res.data
182   - const geoJsonFile = JSON.parse(geoJson)
183   - if (!geoJsonFile) return
184   - saveGeojson.value = geoJsonFile //保存一份服务端返回的geojson
185   - const nameChina = name === '中国' ? 'china' : name
186   - registerMap(level === areaEnum.COUNTRY ? nameChina : code, { geoJSON: geoJsonFile, specialAreas: {} })
187   - show.value = false
188   - resolve(true)
189   - })
190   - })
191   - } catch (error) {
192   - show.value = false
193   - console.error('注册地图出错', error)
194   - //注册出错则注册空的,不然在选择正确的adcode,则视图无法更新
195   - registerMap(props.chartConfig.option.mapRegion.adcode, { geoJSON: {} as any, specialAreas: {} })
196   - }
197   -}
198   -
199   -//异步时先注册空的 保证初始化不报错
200   -registerMap(props.chartConfig.option.mapRegion.adcode, { geoJSON: {} as any, specialAreas: {} })
201   -
202   -//传adcode 获取上级
203   -const getParentAdcode = (adcode: number) => {
204   - let adcodeNum = 100000
205   - saveGeojson.value?.features.forEach((item: Recordable) => {
206   - if (item.properties.adcode === adcode) {
207   - adcodeNum = item.properties.parent.adcode
208   - }
209   - })
210   - return adcodeNum
211   -}
212   -
213   -const initMap = async () => {
214   - chartInstance.value = echarts.init(map3DRef.value)
215   - await nextTick()
216   - await getGeojson(props.chartConfig.option.mapRegion.adcode)
217   - await nextTick().then(() => {
218   - handleSetOption(chartInstance.value, props.chartConfig.option)
219   - })
220   - chartInstance.value.on('click', (e: Recordable) => {
221   - handleMap3DClick(e)
222   - })
223   -}
224   -
225   -// 手动触发渲染
226   -const handleSetOption = (instance: any, option: Recordable) => {
227   - if (!instance) return
228   - try {
229   - instance.clear()
230   - instance.setOption(option)
231   - } catch (error) {
232   - console.error('触发渲染出错', error)
233   - }
234   -}
235   -
236   -onMounted(() => {
237   - initMap()
238   -})
239   -
240   -watch(
241   - () => [w.value, h.value],
242   - async (newValue: number[]) => {
243   - await nextTick()
244   - chartInstance.value.resize({
245   - width: newValue.at(-2) + 'px',
246   - height: newValue.at(-1) + 'px'
247   - })
248   - }
249   -)
250   -
251   -//处理数据标点
252   -const handleDataPoint = (newData: string | number) => {
253   - if (newData === 'china') {
254   - props.chartConfig.option.dataset = props.chartConfig.option.dataConfig
255   - props.chartConfig.option.series.forEach((item: Recordable) => {
256   - if (item.type === 'scatter3D') {
257   - item.data = props.chartConfig.option.dataConfig['scatter3D']
258   - }
259   - if (item.type === 'bar3D') {
260   - item.data = props.chartConfig.option.dataConfig['bar3D']
261   - }
262   - })
263   - } else {
264   - props.chartConfig.option.dataset = props.chartConfig.option.dataConfig['map3D'].filter(
265   - (item: dataPointI) => item.adcode === newData
266   - )
267   - props.chartConfig.option.series.forEach((item: Recordable) => {
268   - if (item.type === 'scatter3D') {
269   - item.data = props.chartConfig.option.dataConfig['scatter3D'].filter(
270   - (item: dataPointI) => item.adcode === newData
271   - )
272   - }
273   - if (item.type === 'bar3D') {
274   - item.data = props.chartConfig.option.dataConfig['bar3D'].filter((item: dataPointI) => item.adcode === newData)
275   - }
276   - })
277   - }
278   -}
279   -
280   -//监听地图展示区域发生变化
281   -watch(
282   - () => `${props.chartConfig.option.mapRegion.adcode}`,
283   - async (newData: string | number) => {
284   - try {
285   - await getGeojson(newData)
286   - props.chartConfig.option.geo3D.map = newData
287   - props.chartConfig.option.series.forEach((item: Recordable) => {
288   - if (item.type === 'map3D') {
289   - item.map = newData
290   - item.data = props.chartConfig.option.dataset['map3D']
291   - }
292   - })
293   - handleSetOption(chartInstance.value, props.chartConfig.option)
294   - handleDataPoint(newData)
295   - } catch (error) {
296   - console.log('展示区域发生变化出错', error)
297   - }
298   - },
299   - {
300   - immediate: true
301   - }
302   -)
303   -
304   -// 监听地图右侧配置项变化
305   -const stopWatch = watch(
306   - props.chartConfig.option,
307   - async newData => {
308   - try {
309   - handleSetOption(chartInstance.value, newData)
310   - } catch (error) {
311   - console.log(error)
312   - }
313   - },
314   - {
315   - deep: true
316   - }
317   -)
318   -
319   -// 监听地图dataset配置项变化
320   -watch(
321   - () => props.chartConfig.option.dataset,
322   - newData => {
323   - try {
324   - props.chartConfig.option.series.forEach((item: Recordable) => {
325   - if (item.type === 'map3D') {
326   - item.data = newData['map3D']
327   - }
328   - })
329   - handleSetOption(chartInstance.value, props.chartConfig.option)
330   - } catch (error) {
331   - console.log(error)
332   - }
333   - },
334   - {
335   - deep: true
336   - }
337   -)
338   -</script>
... ... @@ -59,10 +59,10 @@ export const option: IconOptions = {
59 59 { label: '设备:', value: 'xxxxxxxxx设备' },
60 60 { label: '产品:', value: 'xxxxxxxxx产品' },
61 61 { label: '位置:', value: 'xxxxxxxxx位置' },
62   - { label: '创建时间:', value: '2024-01-01' }
  62 + { label: '创建时间:', value: '2024-01-12 11:27:44' }
63 63 ],
64 64 popupConfig: {
65   - borderWidth: 380,
  65 + borderWidth: 300,
66 66 borderHeight: 200,
67 67 borderColor: 'red',
68 68 boxShadowColor: '#356A82FF',
... ...
... ... @@ -88,9 +88,6 @@
88 88 <SettingItem name="线条颜色">
89 89 <NColorPicker size="small" v-model:value="optionData.popupConfig.lineColor"> </NColorPicker>
90 90 </SettingItem>
91   - <SettingItem name="标题内容">
92   - <NInput v-model:value="optionData.popupConfig.fontContent"> </NInput>
93   - </SettingItem>
94 91 <SettingItem name="标题颜色">
95 92 <NColorPicker size="small" v-model:value="optionData.popupConfig.fontColor"> </NColorPicker>
96 93 </SettingItem>
... ... @@ -102,6 +99,9 @@
102 99 :min="0"
103 100 ></NInputNumber>
104 101 </SettingItem>
  102 + <SettingItem name="标题内容">
  103 + <NInput v-model:value="optionData.popupConfig.fontContent"> </NInput>
  104 + </SettingItem>
105 105 <SettingItem name="内容键文本颜色">
106 106 <NColorPicker size="small" v-model:value="optionData.popupConfig.labelColor"> </NColorPicker>
107 107 </SettingItem>
... ... @@ -137,9 +137,16 @@
137 137 import { computed, PropType } from 'vue'
138 138 import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
139 139 import { option } from './config'
140   -import { NColorPicker, NInputNumber, NSelect, SelectOption } from 'naive-ui';
141   -import { IconBorderStyleEnum, IconBorderStyleNameEnum, IconBorderEnum, IconBorderNameEnum, IconDynamicEffectNameEnum, IconDynamicEffectEnum } from '../../../types';
142   -import IconPicker from '@/components/external/Icon/src/IconPicker.vue';
  140 +import { NColorPicker, NInputNumber, NSelect, SelectOption } from 'naive-ui'
  141 +import {
  142 + IconBorderStyleEnum,
  143 + IconBorderStyleNameEnum,
  144 + IconBorderEnum,
  145 + IconBorderNameEnum,
  146 + IconDynamicEffectNameEnum,
  147 + IconDynamicEffectEnum
  148 +} from '../../../types'
  149 +import IconPicker from '@/components/external/Icon/src/IconPicker.vue'
143 150
144 151 const props = defineProps({
145 152 optionData: {
... ... @@ -153,7 +160,7 @@ const getBorderStyleOptions: SelectOption[] = [
153 160 { label: IconBorderStyleNameEnum.DASHED, value: IconBorderStyleEnum.DASHED },
154 161 { label: IconBorderStyleNameEnum.DOTTED, value: IconBorderStyleEnum.DOTTED },
155 162 { label: IconBorderStyleNameEnum.DOUBLE, value: IconBorderStyleEnum.DOUBLE },
156   - { label: IconBorderStyleNameEnum.NONE, value: IconBorderStyleEnum.NONE },
  163 + { label: IconBorderStyleNameEnum.NONE, value: IconBorderStyleEnum.NONE }
157 164 ]
158 165
159 166 const getBorderTypeOptions: SelectOption[] = [
... ... @@ -163,10 +170,17 @@ const getBorderTypeOptions: SelectOption[] = [
163 170
164 171 const getDynamicEffectOptions = computed<SelectOption[]>(() => {
165 172 return [
166   - { label: IconDynamicEffectNameEnum.JUMP, value: IconDynamicEffectEnum.JUMP, disabled: props.optionData.dynamicEffect?.includes(IconDynamicEffectEnum.SPIN) },
167   - { label: IconDynamicEffectNameEnum.SPIN, value: IconDynamicEffectEnum.SPIN, disabled: props.optionData.dynamicEffect?.includes(IconDynamicEffectEnum.JUMP) },
  173 + {
  174 + label: IconDynamicEffectNameEnum.JUMP,
  175 + value: IconDynamicEffectEnum.JUMP,
  176 + disabled: props.optionData.dynamicEffect?.includes(IconDynamicEffectEnum.SPIN)
  177 + },
  178 + {
  179 + label: IconDynamicEffectNameEnum.SPIN,
  180 + value: IconDynamicEffectEnum.SPIN,
  181 + disabled: props.optionData.dynamicEffect?.includes(IconDynamicEffectEnum.JUMP)
  182 + }
168 183 ]
169   -
170 184 })
171 185
172 186 //native-ui 组件popover内置弹窗位置,不需要通过枚举方式
... ...
... ... @@ -2,8 +2,9 @@
2 2 import { computed, PropType, toRefs } from 'vue'
3 3 import { CreateComponentType } from '@/packages/index.d'
4 4 import { option } from './config'
5   -import SvgBorder from './SvgBorder.vue';
6   -import SvgIcon from '@/components/external/Icon/src/SvgIcon.vue';
  5 +import SvgBorder from './SvgBorder.vue'
  6 +import SvgIcon from '@/components/external/Icon/src/SvgIcon.vue'
  7 +import { TKDialog } from '@/components/external/Common/TKDialog'
7 8
8 9 const props = defineProps({
9 10 chartConfig: {
... ... @@ -17,144 +18,22 @@ const size = computed(() => {
17 18 return Math.min(w, h) / 2
18 19 })
19 20
  21 +const { w, h } = toRefs(props.chartConfig.attr)
  22 +
20 23 const { popupConfig, dataset } = toRefs(props.chartConfig.option)
21 24 </script>
22 25
23 26 <template>
24   - <section>
25   - <n-popover :placement="popupConfig.placement" trigger="click" raw>
26   - <template #trigger>
27   - <SvgBorder :option="chartConfig.option">
28   - <SvgIcon
29   - :style="{ color: chartConfig.option.iconColor }"
30   - :size="size"
31   - :name="chartConfig.option.icon!"
32   - prefix="iconfont"
33   - />
34   - </SvgBorder>
35   - </template>
36   - <div
37   - style="transform-origin: inherit"
38   - :style="`width:${popupConfig.borderWidth}px;
39   - height: ${popupConfig.borderHeight}px;
40   - box-shadow: 0 0 10px 10px ${popupConfig.boxShadowColor};
41   - background:linear-gradient(to right, ${popupConfig.linearLeftColor} , ${popupConfig.linearRightColor});
42   - `"
43   - >
44   - <div class="popup-body">
45   - <div class="popup-arrow-right" :style="`border-color:${popupConfig.arrowColor}`"></div>
46   - <div class="popup-header-content">
47   - <p
48   - class="header-title"
49   - :style="`color:${popupConfig.fontColor};font-size:${popupConfig.fontSize}px;font-weight:${popupConfig.fontWeight}`"
50   - >
51   - {{ popupConfig.fontContent }}
52   - </p>
53   - <div class="header-content-graphical">
54   - <div class="graphical-circle-left"><Circle /></div>
55   - <div class="graphical-line">
56   - <div class="line-left" :style="`background-color:${popupConfig.lineColor}`"></div>
57   - <div class="line-center" :style="`background-color:${popupConfig.lineColor}`"></div>
58   - <div class="line-right" :style="`background-color:${popupConfig.lineColor}`"></div>
59   - </div>
60   - <div class="graphical-circle-right"><Circle /></div>
61   - </div>
62   - </div>
63   - </div>
64   - <div class="content-body">
65   - <div class="body" v-for="(item, index) in dataset" :key="index">
66   - <span :style="`color:${popupConfig.labelColor};`">{{ item.label }}</span>
67   - <span :style="`color:${popupConfig.valueColor};`">{{ item.value }}</span>
68   - </div>
69   - </div>
70   - </div>
71   - </n-popover>
  27 + <section>
  28 + <TKDialog :popupConfig="popupConfig" :popupConfigData="dataset" :w="w" :h="h">
  29 + <SvgBorder :option="chartConfig.option">
  30 + <SvgIcon
  31 + :style="{ color: chartConfig.option.iconColor }"
  32 + :size="size"
  33 + :name="chartConfig.option.icon!"
  34 + prefix="iconfont"
  35 + />
  36 + </SvgBorder>
  37 + </TKDialog>
72 38 </section>
73 39 </template>
74   -
75   -<style lang="scss" scoped>
76   -@mixin base-text-ellipsis() {
77   - overflow: hidden;
78   - white-space: nowrap;
79   - text-overflow: ellipsis;
80   - -o-text-overflow: ellipsis;
81   -}
82   -.popup-body {
83   - display: flex;
84   - justify-content: center;
85   - flex-direction: column;
86   - .popup-arrow-right {
87   - position: absolute;
88   - top: 15px;
89   - left: 10px;
90   - border-right: 1px solid;
91   - border-bottom: 1px solid;
92   - width: 7px;
93   - height: 7px;
94   - transform: rotate(-45deg);
95   - -o-transform: rotate(-45deg);
96   - -webkit-transform: rotate(-45deg);
97   - -moz-transform: rotate(-45deg);
98   - -ms-transform: rotate(-45deg);
99   - }
100   - .popup-header-content {
101   - margin: 23px;
102   - display: flex;
103   - justify-content: center;
104   - flex-direction: column;
105   - .header-title {
106   - @include base-text-ellipsis;
107   - }
108   - .header-content-graphical {
109   - display: flex;
110   - align-items: center;
111   - .graphical-circle-left {
112   - position: relative;
113   - left: -2px;
114   - }
115   - .graphical-line {
116   - display: flex;
117   - .line-left {
118   - width: 115px;
119   - height: 2px;
120   - position: relative;
121   - }
122   - .line-center {
123   - width: 35px;
124   - height: 2px;
125   - transform: rotateZ(145deg);
126   - position: absolute;
127   - top: 44px;
128   - left: 146px;
129   - }
130   - .line-right {
131   - width: 50px;
132   - height: 2px;
133   - position: absolute;
134   - top: 34px;
135   - left: 178px;
136   - }
137   - }
138   - .graphical-circle-right {
139   - position: absolute;
140   - top: 29px;
141   - left: 231px;
142   - }
143   - }
144   - }
145   -}
146   -.content-body {
147   - display: flex;
148   - align-items: center;
149   - flex-wrap: wrap;
150   - margin: -10px 0;
151   - .body {
152   - display: flex;
153   - align-items: center;
154   - justify-content: flex-start;
155   - gap: 27px;
156   - margin-left: 15px;
157   - margin-top: 1px;
158   - }
159   -}
160   -</style>
... ...
... ... @@ -8,7 +8,7 @@ export const ButtonConfig: ConfigType = {
8 8 key,
9 9 chartKey,
10 10 conKey,
11   - title: '切换菜单按钮',
  11 + title: '同一页面切换按钮',
12 12 category: ChatCategoryEnum.INPUTS,
13 13 categoryName: ChatCategoryEnumName.INPUTS,
14 14 package: PackagesCategoryEnum.INFORMATIONS,
... ...
... ... @@ -6,26 +6,50 @@ import { COMPONENT_INTERACT_EVENT_KET } from '@/enums/eventEnum'
6 6 import { interactActions, ComponentInteractEventEnum } from './interact'
7 7 import { DecorateButton1Config } from './index'
8 8
9   -
10 9 export const option = {
11 10 // 时间组件展示类型,必须和 interactActions 中定义的数据一致
12 11 [COMPONENT_INTERACT_EVENT_KET]: ComponentInteractEventEnum.DATA,
13 12 // 暴露配置内容给用户
14   - dataset: '第1页',
15   - buttonType: 'primary',
16   - buttonGhost: false,
17   - buttonDashed: false,
18   - buttonColor: '',
19   - buttonTextColor: 'white',
20   - buttonTextSize: '16',
21   - buttonTextBold: 500,
22   - selectTargetItems: [],
23   - quaternary: false
  13 + svgTitle: '装饰按钮',
  14 + disabled: false,
  15 + fontConfig: {
  16 + x1: 33,
  17 + y1: 34.952,
  18 + datasetTspanFill: '#FFFFFF',
  19 + datasetTspanFontSize: 32
  20 + },
  21 + colorConfig: {
  22 + notActiveColor: '#001735',
  23 + activeColor: '#001E29'
  24 + },
  25 + dataset: [
  26 + { label: '设备:', value: 'xxxxxxxxx设备' },
  27 + { label: '产品:', value: 'xxxxxxxxx产品' },
  28 + { label: '位置:', value: 'xxxxxxxxx位置' },
  29 + { label: '创建时间:', value: '2024-01-12 11:27:44' }
  30 + ],
  31 + popupConfig: {
  32 + borderWidth: 300,
  33 + borderHeight: 200,
  34 + borderColor: 'red',
  35 + boxShadowColor: '#356A82FF',
  36 + linearLeftColor: '#385391FF',
  37 + linearRightColor: '#385391FF',
  38 + arrowColor: '#427FB4',
  39 + lineColor: '#427FB4',
  40 + fontColor: '#ffffff',
  41 + fontSize: 16,
  42 + fontWeight: 500,
  43 + fontContent: '我是标题',
  44 + labelColor: '#3d6e9d',
  45 + valueColor: '#ffffff',
  46 + placement: 'top'
  47 + }
24 48 }
25 49
26 50 export default class Config extends PublicConfigClass implements CreateComponentType {
27 51 public key = DecorateButton1Config.key
28   - public attr = { ...chartInitConfig, w: 90, h: 40, zIndex: -1 }
  52 + public attr = { ...chartInitConfig, w: 262, h: 73, zIndex: -1 }
29 53 public chartConfig = cloneDeep(DecorateButton1Config)
30 54 public interactActions = interactActions
31 55 public option = cloneDeep(option)
... ...
1 1 <template>
2   - <collapse-item name="按钮配置" :expanded="true">
3   - <setting-item-box name="默认值" :alone="true">
4   - <n-select size="small" v-model:value="optionData.buttonType" :options="buttonTypeOptions" />
5   - </setting-item-box>
6   - <setting-item-box name="虚线">
7   - <setting-item name="是否开启">
8   - <n-switch v-model:value="optionData.buttonDashed" />
9   - </setting-item>
10   - </setting-item-box>
11   - <setting-item-box name="透明">
12   - <setting-item name="是否开启">
13   - <n-switch v-model:value="optionData.buttonGhost" />
14   - </setting-item>
15   - </setting-item-box>
16   - <setting-item-box name="边框">
17   - <setting-item name="是否开启">
18   - <n-switch v-model:value="optionData.quaternary" />
19   - </setting-item>
20   - </setting-item-box>
21   - <setting-item-box name="颜色">
22   - <setting-item name="">
23   - <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.buttonColor"></n-color-picker>
24   - </setting-item>
25   - <setting-item>
26   - <n-button size="small" @click="optionData.buttonColor=''">
27   - 恢复默认
28   - </n-button>
29   - </setting-item>
30   - </setting-item-box>
31   - <setting-item-box name="文字颜色">
32   - <setting-item name="">
33   - <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.buttonTextColor"></n-color-picker>
34   - </setting-item>
35   - <setting-item>
36   - <n-button size="small" @click="optionData.buttonTextColor='white'">
37   - 恢复默认
38   - </n-button>
39   - </setting-item>
40   - </setting-item-box>
41   - <setting-item-box name="文字大小">
42   - <setting-item name="">
43   - <n-input-number v-model:value="optionData.buttonTextSize" />
44   - </setting-item>
45   - <setting-item>
46   - <n-button size="small" @click="optionData.buttonTextSize='16'">
47   - 恢复默认
48   - </n-button>
49   - </setting-item>
50   - </setting-item-box>
51   - <setting-item-box name="文字加粗">
52   - <setting-item name="">
53   - <n-input-number :step="200" v-model:value="optionData.buttonTextBold" />
54   - </setting-item>
55   - <setting-item>
56   - <n-button size="small" @click="optionData.buttonTextBold=100">
57   - 恢复默认
58   - </n-button>
59   - </setting-item>
60   - </setting-item-box>
61   - <setting-item-box :alone="true">
62   - <setting-item name="按钮文字" :alone="true">
63   - <n-input v-model:value="optionData.dataset" size="small" placeholder="按钮文字"></n-input>
64   - </setting-item>
65   - </setting-item-box>
  2 + <collapse-item name="装饰按钮配置" :expanded="true">
  3 + <SettingItemBox :name="`数据源字体`">
  4 + <SettingItem name="内容">
  5 + <n-input v-model:value="optionData.svgTitle"></n-input>
  6 + </SettingItem>
  7 + <SettingItem name="x">
  8 + <n-input-number v-model:value="optionData.fontConfig.x1"></n-input-number>
  9 + </SettingItem>
  10 + <SettingItem name="y">
  11 + <n-input-number v-model:value="optionData.fontConfig.y1"></n-input-number>
  12 + </SettingItem>
  13 + <SettingItem name="大小">
  14 + <n-input-number :min="0" v-model:value="optionData.fontConfig.datasetTspanFontSize"></n-input-number>
  15 + </SettingItem>
  16 + <SettingItem name="颜色">
  17 + <n-color-picker
  18 + size="small"
  19 + :modes="['hex']"
  20 + v-model:value="optionData.fontConfig.datasetTspanFill"
  21 + ></n-color-picker>
  22 + </SettingItem>
  23 + </SettingItemBox>
  24 + <SettingItemBox :name="`按钮背景`">
  25 + <SettingItem name="未激活背景">
  26 + <n-color-picker
  27 + size="small"
  28 + :modes="['hex']"
  29 + v-model:value="optionData.colorConfig.notActiveColor"
  30 + ></n-color-picker>
  31 + </SettingItem>
  32 + <SettingItem>
  33 + <n-button size="small" @click="optionData.colorConfig.notActiveColor = '#001735'"> 恢复默认 </n-button>
  34 + </SettingItem>
  35 + <SettingItem name="激活背景">
  36 + <n-color-picker
  37 + size="small"
  38 + :modes="['hex']"
  39 + v-model:value="optionData.colorConfig.activeColor"
  40 + ></n-color-picker>
  41 + </SettingItem>
  42 + <SettingItem>
  43 + <n-button size="small" @click="optionData.colorConfig.activeColor = '#001E29'"> 恢复默认 </n-button>
  44 + </SettingItem>
  45 + </SettingItemBox>
  46 + <CollapseItem name="弹窗配置" expanded>
  47 + <SettingItemBox name="开启弹窗">
  48 + <SettingItem>
  49 + <n-switch v-model:value="optionData.disabled"></n-switch>
  50 + </SettingItem>
  51 + </SettingItemBox>
  52 + <SettingItemBox name="宽高">
  53 + <SettingItem name="宽">
  54 + <NInputNumber
  55 + v-model:value="optionData.popupConfig.borderWidth"
  56 + size="small"
  57 + :step="10"
  58 + :min="0"
  59 + ></NInputNumber>
  60 + </SettingItem>
  61 + <SettingItem name="高">
  62 + <NInputNumber
  63 + v-model:value="optionData.popupConfig.borderHeight"
  64 + size="small"
  65 + :step="10"
  66 + :min="0"
  67 + ></NInputNumber>
  68 + </SettingItem>
  69 + </SettingItemBox>
  70 + <SettingItemBox name="位置">
  71 + <SettingItem name="">
  72 + <NSelect v-model:value="optionData.popupConfig.placement" size="small" :options="placementOptions"> </NSelect>
  73 + </SettingItem>
  74 + </SettingItemBox>
  75 + <SettingItemBox name="颜色">
  76 + <SettingItem name="边框阴影">
  77 + <NColorPicker
  78 + size="small"
  79 + :modes="['hex']"
  80 + :actions="['clear']"
  81 + v-model:value="optionData.popupConfig.boxShadowColor"
  82 + >
  83 + </NColorPicker>
  84 + </SettingItem>
  85 + <SettingItem name="背景线性渐变左">
  86 + <NColorPicker size="small" v-model:value="optionData.popupConfig.linearLeftColor"> </NColorPicker>
  87 + </SettingItem>
  88 + <SettingItem name="背景线性渐变右">
  89 + <NColorPicker size="small" v-model:value="optionData.popupConfig.linearRightColor"> </NColorPicker>
  90 + </SettingItem>
  91 + <SettingItem name="箭头颜色">
  92 + <NColorPicker size="small" v-model:value="optionData.popupConfig.arrowColor"> </NColorPicker>
  93 + </SettingItem>
  94 + <SettingItem name="线条颜色">
  95 + <NColorPicker size="small" v-model:value="optionData.popupConfig.lineColor"> </NColorPicker>
  96 + </SettingItem>
  97 + <SettingItem name="标题颜色">
  98 + <NColorPicker size="small" v-model:value="optionData.popupConfig.fontColor"> </NColorPicker>
  99 + </SettingItem>
  100 + <SettingItem name="标题加粗">
  101 + <NInputNumber
  102 + v-model:value="optionData.popupConfig.fontWeight"
  103 + size="small"
  104 + :step="100"
  105 + :min="0"
  106 + ></NInputNumber>
  107 + </SettingItem>
  108 + <SettingItem name="标题内容">
  109 + <NInput v-model:value="optionData.popupConfig.fontContent"> </NInput>
  110 + </SettingItem>
  111 + <SettingItem name="内容键文本颜色">
  112 + <NColorPicker size="small" v-model:value="optionData.popupConfig.labelColor"> </NColorPicker>
  113 + </SettingItem>
  114 + <SettingItem name="内容值文本颜色">
  115 + <NColorPicker size="small" v-model:value="optionData.popupConfig.valueColor"> </NColorPicker>
  116 + </SettingItem>
  117 + </SettingItemBox>
  118 + <template v-for="(item, index) in optionData.dataset" :key="index">
  119 + <setting-item-box name="内容键" :alone="true">
  120 + <setting-item>
  121 + <NInput v-model:value="item.label"> </NInput>
  122 + </setting-item>
  123 + </setting-item-box>
  124 + <setting-item-box name="内容值" :alone="true">
  125 + <setting-item>
  126 + <NInput v-model:value="item.value"> </NInput>
  127 + </setting-item>
  128 + </setting-item-box>
  129 + <n-button size="small" @click="optionData.dataset.splice(index, 1)"> - </n-button>
  130 + </template>
  131 + <n-button
  132 + style="margin-left: 10px"
  133 + v-if="optionData.dataset.length < 8"
  134 + size="small"
  135 + @click="optionData.dataset.push({ label: '', value: '' })"
  136 + >
  137 + +
  138 + </n-button>
  139 + </CollapseItem>
66 140 </collapse-item>
67 141 </template>
68 142
69 143 <script lang="ts" setup>
70   -import { PropType, ref, onMounted } from 'vue'
71   -import { CollapseItem, SettingItemBox ,SettingItem} from '@/components/Pages/ChartItemSetting'
  144 +import { PropType } from 'vue'
  145 +import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
72 146 import { option } from './config'
73   -import { icon } from '@/plugins'
74   -import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
  147 +import { SelectOption } from 'naive-ui'
75 148
76 149 defineProps({
77 150 optionData: {
... ... @@ -80,58 +153,24 @@ defineProps({
80 153 }
81 154 })
82 155
83   -const chartEditStore = useChartEditStore()
84   -
85   -const { HelpOutlineIcon } = icon.ionicons5
86   -
87   -const targetHelpMessgae = ref(`勾选目标项,支持多个`)
88   -
89   -const buttonTypeOptions = [
90   - {
91   - label: 'default',
92   - value: 'default'
93   - },
94   - {
95   - label: 'primary',
96   - value: 'primary'
97   - },
98   - {
99   - label: 'tertiary',
100   - value: 'tertiary'
101   - },
  156 +//native-ui 组件popover内置弹窗位置,不需要通过枚举方式
  157 +const placementOptions: SelectOption[] = [
102 158 {
103   - label: 'info',
104   - value: 'info'
  159 + label: '顶部',
  160 + value: 'top'
105 161 },
106 162 {
107   - label: 'success',
108   - value: 'success'
  163 + label: '右边',
  164 + value: 'right'
109 165 },
110 166 {
111   - label: 'warning',
112   - value: 'warning'
  167 + label: '左边',
  168 + value: 'left'
113 169 },
114 170 {
115   - label: 'error',
116   - value: 'error'
  171 + label: '底部',
  172 + value: 'bottom'
117 173 }
118 174 ]
119   -
120   -const selectTargetItemOptions = ref<{ label: string; value: string }[]>([])
121   -
122   -onMounted(() => {
123   - const componentList = chartEditStore.getComponentList?.map(item => ({
124   - label: item.chartConfig?.title,
125   - value: item.id
126   - }))
127   - selectTargetItemOptions.value = componentList
128   -})
129 175 </script>
130   -<style lang="scss" scoped>
131   -.help-span {
132   - display: flex;
133   - flex-wrap: wrap;
134   - width: 8vw;
135   - color: white;
136   -}
137   -</style>
  176 +<style lang="scss" scoped></style>
... ...
... ... @@ -13,5 +13,5 @@ export const DecorateButton1Config: ConfigType = {
13 13 categoryName: ChatCategoryEnumName.INPUTS,
14 14 package: PackagesCategoryEnum.INFORMATIONS,
15 15 chartFrame: ChartFrameEnum.COMMON,
16   - image: 'page_button.png'
  16 + image: 'decorate_button1.png'
17 17 }
... ...
1 1 <template>
2   - <div class="decorate-button" @mouseup="handleSvgMouseUpClick" @mousedown="handleSvgMouseDownClick">
3   - <svg :width="w" :height="h" viewBox="0 0 723 100" fill="none">
4   - <g opacity="1" transform="translate(0 0)">
5   - <g v-if="isActivate" opacity="1" transform="translate(0 0)">
6   - <path id="矩形 1" fill-rule="evenodd" style="fill: #cccccc" opacity="0" d="M0 100L342 100L342 0L0 0L0 100Z" />
7   - <path
8   - fill-rule="evenodd"
9   - id="矩形 1"
10   - style="fill: #044e92; opacity: 1"
11   - d="M342 100L0 100L0 0L342 0L342 100ZM341 1L1 1L1 99L341 99L341 1Z"
12   - />
13   - <path
14   - id="并集"
15   - fill-rule="evenodd"
16   - style="fill: #29a2ff"
17   - opacity="1"
18   - d="M2 16L0 16L0 0L16 0L16 2L2 2L2 16Z"
19   - />
20   - <path
21   - id="并集"
22   - fill-rule="evenodd"
23   - style="fill: #29a2ff"
24   - opacity="1"
25   - d="M326 2L326 0L342 0L342 16L340 16L340 2L326 2Z"
26   - />
27   - <path
28   - id="并集"
29   - fill-rule="evenodd"
30   - style="fill: #29a2ff"
31   - opacity="1"
32   - d="M2 100L0 100L0 84L2 84L2 98L16 98L16 100L2 100Z"
33   - />
34   - <path
35   - id="并集"
36   - fill-rule="evenodd"
37   - style="fill: #29a2ff"
38   - opacity="1"
39   - d="M342 98L342 100L326 100L326 98L340 98L340 84L342 84L342 98Z"
40   - />
41   - <path id="路径" fill-rule="evenodd" style="fill: #00ff7e" opacity="1" d="M8 16L17 7L8 7L8 16Z" />
42   - <path id="路径" fill-rule="evenodd" style="fill: #00ff7e" opacity="1" d="M335 84L326 93L335 93L335 84Z" />
43   - <g filter="url(#filter_9)">
  2 + <section class="decorate1-button">
  3 + <TKDialog
  4 + :disabled="!disabled"
  5 + :popupConfig="popupConfig"
  6 + :popupConfigData="dataset"
  7 + :w="w"
  8 + :h="h"
  9 + @updateShow="handleUpdateShow"
  10 + >
  11 + <svg
  12 + @click="handleSvgClick(useChartEditStore().getPageConfig)"
  13 + style="outline: none"
  14 + :width="w"
  15 + :height="h"
  16 + viewBox="0 0 473 100"
  17 + fill="none"
  18 + >
  19 + <g opacity="1" transform="translate(68 0)">
  20 + <g v-if="!isActivate" opacity="1" transform="translate(0 0)">
44 21 <path
45   - id="路径"
  22 + id="矩形 1"
46 23 fill-rule="evenodd"
47   - style="fill: #001735"
48   - opacity="1"
49   - d="M9 92L318 92L335 74.5L335 8L24.5 8L9 22.5L9 92Z"
  24 + style="fill: #cccccc"
  25 + opacity="0"
  26 + d="M0 100L342 100L342 0L0 0L0 100Z"
50 27 />
51 28 <path
52   - id="路径"
  29 + fill-rule="evenodd"
  30 + id="矩形 1"
53 31 style="fill: #044e92; opacity: 1"
54   - d="M9 91.5L318 91.5L318 92L317.641 91.6516L334.641 74.1516L335 74.5L334.5 74.5L334.5 8L335 8L335 8.5L24.5 8.5L24.5 8L24.8416 8.36514L9.34158 22.8651L9 22.5L9.5 22.5L9.5 92L9 92L9 91.5ZM8.5 92.5L8.5 22.2831L24.3026 7.5L335.5 7.5L335.5 74.7029L318.211 92.5L9 92.5L8.5 92.5Z"
  32 + d="M342 100L0 100L0 0L342 0L342 100ZM341 1L1 1L1 99L341 99L341 1Z"
55 33 />
56   - </g>
57   - <path
58   - id="矩形 2"
59   - fill-rule="evenodd"
60   - style="fill: #29a2ff"
61   - opacity="1"
62   - d="M128.5 10L213.5 10L213.5 6L128.5 6L128.5 10Z"
63   - />
64   - <path
65   - id="矩形 2"
66   - fill-rule="evenodd"
67   - style="fill: #29a2ff"
68   - opacity="1"
69   - d="M128.5 94L213.5 94L213.5 90L128.5 90L128.5 94Z"
70   - />
71   - <g opacity="1" transform="translate(108 28.5)">
72   - <text>
73   - <tspan
74   - x="0"
75   - y="34.952"
76   - font-size="32"
77   - line-height="42"
78   - fill="#FFFFFF"
  34 + <path
  35 + id="并集"
  36 + fill-rule="evenodd"
  37 + style="fill: #29a2ff"
  38 + opacity="1"
  39 + d="M2 16L0 16L0 0L16 0L16 2L2 2L2 16Z"
  40 + />
  41 + <path
  42 + id="并集"
  43 + fill-rule="evenodd"
  44 + style="fill: #29a2ff"
  45 + opacity="1"
  46 + d="M326 2L326 0L342 0L342 16L340 16L340 2L326 2Z"
  47 + />
  48 + <path
  49 + id="并集"
  50 + fill-rule="evenodd"
  51 + style="fill: #29a2ff"
  52 + opacity="1"
  53 + d="M2 100L0 100L0 84L2 84L2 98L16 98L16 100L2 100Z"
  54 + />
  55 + <path
  56 + id="并集"
  57 + fill-rule="evenodd"
  58 + style="fill: #29a2ff"
  59 + opacity="1"
  60 + d="M342 98L342 100L326 100L326 98L340 98L340 84L342 84L342 98Z"
  61 + />
  62 + <path id="路径" fill-rule="evenodd" style="fill: #00ff7e" opacity="1" d="M8 16L17 7L8 7L8 16Z" />
  63 + <path id="路径" fill-rule="evenodd" style="fill: #00ff7e" opacity="1" d="M335 84L326 93L335 93L335 84Z" />
  64 + <g filter="url(#filter_9)">
  65 + <path
  66 + id="路径"
  67 + fill-rule="evenodd"
  68 + :style="{ fill: colorConfig.notActiveColor }"
79 69 opacity="1"
80   - font-family="SourceHanSansCN-Regular"
81   - font-weight="Regular"
82   - letter-spacing="0"
83   - >
84   - 正常按钮
85   - </tspan>
86   - </text>
87   - </g>
88   - </g>
89   - <g v-else opacity="1" transform="translate(0 0)">
90   - <path id="矩形 1" fill-rule="evenodd" style="fill: #cccccc" opacity="0" d="M0 100L342 100L342 0L0 0L0 100Z" />
91   - <path
92   - fill-rule="evenodd"
93   - id="矩形 1"
94   - style="fill: #044e92; opacity: 1"
95   - d="M342 100L0 100L0 0L342 0L342 100ZM341 1L1 1L1 99L341 99L341 1Z"
96   - />
97   - <path
98   - id="并集"
99   - fill-rule="evenodd"
100   - style="fill: #29a2ff"
101   - opacity="1"
102   - d="M2 16L0 16L0 0L16 0L16 2L2 2L2 16Z"
103   - />
104   - <path
105   - id="并集"
106   - fill-rule="evenodd"
107   - style="fill: #29a2ff"
108   - opacity="1"
109   - d="M326 2L326 0L342 0L342 16L340 16L340 2L326 2Z"
110   - />
111   - <path
112   - id="并集"
113   - fill-rule="evenodd"
114   - style="fill: #29a2ff"
115   - opacity="1"
116   - d="M2 100L0 100L0 84L2 84L2 98L16 98L16 100L2 100Z"
117   - />
118   - <path
119   - id="并集"
120   - fill-rule="evenodd"
121   - style="fill: #29a2ff"
122   - opacity="1"
123   - d="M342 98L342 100L326 100L326 98L340 98L340 84L342 84L342 98Z"
124   - />
125   - <path id="路径" fill-rule="evenodd" style="fill: #00ff7e" opacity="1" d="M8 16L17 7L8 7L8 16Z" />
126   - <path id="路径" fill-rule="evenodd" style="fill: #00ff7e" opacity="1" d="M335 84L326 93L335 93L335 84Z" />
127   - <g filter="url(#filter_21)">
  70 + d="M9 92L318 92L335 74.5L335 8L24.5 8L9 22.5L9 92Z"
  71 + />
  72 + <path
  73 + id="路径"
  74 + style="fill: #044e92; opacity: 1"
  75 + d="M9 91.5L318 91.5L318 92L317.641 91.6516L334.641 74.1516L335 74.5L334.5 74.5L334.5 8L335 8L335 8.5L24.5 8.5L24.5 8L24.8416 8.36514L9.34158 22.8651L9 22.5L9.5 22.5L9.5 92L9 92L9 91.5ZM8.5 92.5L8.5 22.2831L24.3026 7.5L335.5 7.5L335.5 74.7029L318.211 92.5L9 92.5L8.5 92.5Z"
  76 + />
  77 + </g>
128 78 <path
129   - id="路径"
  79 + id="矩形 2"
130 80 fill-rule="evenodd"
131   - style="fill: #001e29"
  81 + style="fill: #29a2ff"
132 82 opacity="1"
133   - d="M9 92L318 92L335 74.5L335 8L24.5 8L9 22.5L9 92Z"
  83 + d="M128.5 10L213.5 10L213.5 6L128.5 6L128.5 10Z"
134 84 />
135 85 <path
136   - id="路径"
137   - style="fill: #00c9e8; opacity: 1"
138   - d="M9 91.5L318 91.5L318 92L317.641 91.6516L334.641 74.1516L335 74.5L334.5 74.5L334.5 8L335 8L335 8.5L24.5 8.5L24.5 8L24.8416 8.36514L9.34158 22.8651L9 22.5L9.5 22.5L9.5 92L9 92L9 91.5ZM8.5 92.5L8.5 22.2831L24.3026 7.5L335.5 7.5L335.5 74.7029L318.211 92.5L9 92.5L8.5 92.5Z"
  86 + id="矩形 2"
  87 + fill-rule="evenodd"
  88 + style="fill: #29a2ff"
  89 + opacity="1"
  90 + d="M128.5 94L213.5 94L213.5 90L128.5 90L128.5 94Z"
139 91 />
140   - </g>
141   - <path
142   - id="矩形 2"
143   - fill-rule="evenodd"
144   - style="fill: #17ece9"
145   - opacity="1"
146   - d="M128.5 10L213.5 10L213.5 6L128.5 6L128.5 10Z"
147   - />
148   - <path
149   - id="矩形 2"
150   - fill-rule="evenodd"
151   - style="fill: #17ece9"
152   - opacity="1"
153   - d="M128.5 94L213.5 94L213.5 90L128.5 90L128.5 94Z"
154   - />
155   - <g id="激活按钮" filter="url(#filter_25)">
156 92 <g opacity="1" transform="translate(108 28.5)">
157 93 <text>
158 94 <tspan
159   - x="0"
160   - y="34.952"
161   - font-size="32"
  95 + :x="fontConfig.x1"
  96 + :y="fontConfig.y1"
  97 + :font-size="fontConfig.datasetTspanFontSize"
162 98 line-height="42"
163   - fill="#00DEFF"
  99 + :fill="fontConfig.datasetTspanFill"
164 100 opacity="1"
165 101 font-family="SourceHanSansCN-Regular"
166 102 font-weight="Regular"
167 103 letter-spacing="0"
168 104 >
169   - 激活按钮
  105 + {{ svgTitle }}
170 106 </tspan>
171 107 </text>
172 108 </g>
173 109 </g>
174   - <g opacity="1" transform="translate(108 28.5)">
175   - <text>
176   - <tspan
177   - x="0"
178   - y="34.952"
179   - font-size="32"
180   - line-height="42"
181   - fill="#FFFFFF"
  110 + <g v-else opacity="1" transform="translate(0 0)">
  111 + <path
  112 + id="矩形 1"
  113 + fill-rule="evenodd"
  114 + style="fill: #cccccc"
  115 + opacity="0"
  116 + d="M0 100L342 100L342 0L0 0L0 100Z"
  117 + />
  118 + <path
  119 + fill-rule="evenodd"
  120 + id="矩形 1"
  121 + style="fill: #044e92; opacity: 1"
  122 + d="M342 100L0 100L0 0L342 0L342 100ZM341 1L1 1L1 99L341 99L341 1Z"
  123 + />
  124 + <path
  125 + id="并集"
  126 + fill-rule="evenodd"
  127 + style="fill: #29a2ff"
  128 + opacity="1"
  129 + d="M2 16L0 16L0 0L16 0L16 2L2 2L2 16Z"
  130 + />
  131 + <path
  132 + id="并集"
  133 + fill-rule="evenodd"
  134 + style="fill: #29a2ff"
  135 + opacity="1"
  136 + d="M326 2L326 0L342 0L342 16L340 16L340 2L326 2Z"
  137 + />
  138 + <path
  139 + id="并集"
  140 + fill-rule="evenodd"
  141 + style="fill: #29a2ff"
  142 + opacity="1"
  143 + d="M2 100L0 100L0 84L2 84L2 98L16 98L16 100L2 100Z"
  144 + />
  145 + <path
  146 + id="并集"
  147 + fill-rule="evenodd"
  148 + style="fill: #29a2ff"
  149 + opacity="1"
  150 + d="M342 98L342 100L326 100L326 98L340 98L340 84L342 84L342 98Z"
  151 + />
  152 + <path id="路径" fill-rule="evenodd" style="fill: #00ff7e" opacity="1" d="M8 16L17 7L8 7L8 16Z" />
  153 + <path id="路径" fill-rule="evenodd" style="fill: #00ff7e" opacity="1" d="M335 84L326 93L335 93L335 84Z" />
  154 + <g filter="url(#filter_21)">
  155 + <path
  156 + id="路径"
  157 + fill-rule="evenodd"
  158 + :style="{ fill: colorConfig.activeColor }"
182 159 opacity="1"
183   - font-family="SourceHanSansCN-Regular"
184   - font-weight="Regular"
185   - letter-spacing="0"
186   - >
187   - 激活按钮
188   - </tspan>
189   - </text>
  160 + d="M9 92L318 92L335 74.5L335 8L24.5 8L9 22.5L9 92Z"
  161 + />
  162 + <path
  163 + id="路径"
  164 + style="fill: #00c9e8; opacity: 1"
  165 + d="M9 91.5L318 91.5L318 92L317.641 91.6516L334.641 74.1516L335 74.5L334.5 74.5L334.5 8L335 8L335 8.5L24.5 8.5L24.5 8L24.8416 8.36514L9.34158 22.8651L9 22.5L9.5 22.5L9.5 92L9 92L9 91.5ZM8.5 92.5L8.5 22.2831L24.3026 7.5L335.5 7.5L335.5 74.7029L318.211 92.5L9 92.5L8.5 92.5Z"
  166 + />
  167 + </g>
  168 + <path
  169 + id="矩形 2"
  170 + fill-rule="evenodd"
  171 + style="fill: #17ece9"
  172 + opacity="1"
  173 + d="M128.5 10L213.5 10L213.5 6L128.5 6L128.5 10Z"
  174 + />
  175 + <path
  176 + id="矩形 2"
  177 + fill-rule="evenodd"
  178 + style="fill: #17ece9"
  179 + opacity="1"
  180 + d="M128.5 94L213.5 94L213.5 90L128.5 90L128.5 94Z"
  181 + />
  182 + <g id="激活按钮" filter="url(#filter_25)">
  183 + <g opacity="1" transform="translate(108 28.5)">
  184 + <text>
  185 + <tspan
  186 + :x="fontConfig.x1"
  187 + :y="fontConfig.y1"
  188 + :font-size="fontConfig.datasetTspanFontSize"
  189 + line-height="42"
  190 + :fill="fontConfig.datasetTspanFill"
  191 + opacity="1"
  192 + font-family="SourceHanSansCN-Regular"
  193 + font-weight="Regular"
  194 + letter-spacing="0"
  195 + >
  196 + {{ svgTitle }}
  197 + </tspan>
  198 + </text>
  199 + </g>
  200 + </g>
  201 + <g opacity="1" transform="translate(108 28.5)">
  202 + <text>
  203 + <tspan
  204 + :x="fontConfig.x1"
  205 + :y="fontConfig.y1"
  206 + :font-size="fontConfig.datasetTspanFontSize"
  207 + line-height="42"
  208 + :fill="fontConfig.datasetTspanFill"
  209 + opacity="1"
  210 + font-family="SourceHanSansCN-Regular"
  211 + font-weight="Regular"
  212 + letter-spacing="0"
  213 + >
  214 + {{ svgTitle }}
  215 + </tspan>
  216 + </text>
  217 + </g>
190 218 </g>
191 219 </g>
192   - </g>
193   -
194   - <defs>
195   - <filter
196   - id="filter_9"
197   - x="0"
198   - y="0"
199   - width="336"
200   - height="93"
201   - filterUnits="userSpaceOnUse"
202   - color-interpolation-filters="sRGB"
203   - >
204   - <feFlood flood-opacity="0" result="feFloodId" />
205   - <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
206   - <feColorMatrix
207   - in="SourceAlpha"
208   - type="matrix"
209   - values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
210   - result="hardAlpha"
211   - />
  220 + <defs>
  221 + <filter
  222 + id="filter_9"
  223 + x="0"
  224 + y="0"
  225 + width="336"
  226 + height="93"
  227 + filterUnits="userSpaceOnUse"
  228 + color-interpolation-filters="sRGB"
  229 + >
  230 + <feFlood flood-opacity="0" result="feFloodId" />
  231 + <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
  232 + <feColorMatrix
  233 + in="SourceAlpha"
  234 + type="matrix"
  235 + values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
  236 + result="hardAlpha"
  237 + />
212 238
213   - <feOffset dx="0" dy="0" />
214   - <feGaussianBlur stdDeviation="10" />
215   - <feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
216   - <feColorMatrix
217   - type="matrix"
218   - values="0 0 0 0 0.01568627450980392 0 0 0 0 0.4 0 0 0 0 0.8392156862745098 0 0 0 0.64 0"
219   - />
220   - <feBlend mode="normal" in2="shape" result="innerShadow_0" />
221   - </filter>
222   - <filter
223   - id="filter_21"
224   - x="0"
225   - y="0"
226   - width="336"
227   - height="93"
228   - filterUnits="userSpaceOnUse"
229   - color-interpolation-filters="sRGB"
230   - >
231   - <feFlood flood-opacity="0" result="feFloodId" />
232   - <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
233   - <feColorMatrix
234   - in="SourceAlpha"
235   - type="matrix"
236   - values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
237   - result="hardAlpha"
238   - />
  239 + <feOffset dx="0" dy="0" />
  240 + <feGaussianBlur stdDeviation="10" />
  241 + <feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
  242 + <feColorMatrix
  243 + type="matrix"
  244 + values="0 0 0 0 0.01568627450980392 0 0 0 0 0.4 0 0 0 0 0.8392156862745098 0 0 0 0.64 0"
  245 + />
  246 + <feBlend mode="normal" in2="shape" result="innerShadow_0" />
  247 + </filter>
  248 + <filter
  249 + id="filter_21"
  250 + x="0"
  251 + y="0"
  252 + width="336"
  253 + height="93"
  254 + filterUnits="userSpaceOnUse"
  255 + color-interpolation-filters="sRGB"
  256 + >
  257 + <feFlood flood-opacity="0" result="feFloodId" />
  258 + <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
  259 + <feColorMatrix
  260 + in="SourceAlpha"
  261 + type="matrix"
  262 + values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
  263 + result="hardAlpha"
  264 + />
239 265
240   - <feOffset dx="0" dy="0" />
241   - <feGaussianBlur stdDeviation="10" />
242   - <feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
243   - <feColorMatrix
244   - type="matrix"
245   - values="0 0 0 0 0.027450980392156862 0 0 0 0 0.5568627450980392 0 0 0 0 0.6392156862745098 0 0 0 1 0"
246   - />
247   - <feBlend mode="normal" in2="shape" result="innerShadow_0" />
248   - </filter>
249   - <filter
250   - id="filter_25"
251   - x="-6"
252   - y="-6"
253   - width="140"
254   - height="55"
255   - filterUnits="userSpaceOnUse"
256   - color-interpolation-filters="sRGB"
257   - >
258   - <feFlood flood-opacity="0" result="BackgroundImageFix" />
259   - <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
260   - <feGaussianBlur stdDeviation="3" result="effect1_foregroundBlur" />
261   - </filter>
262   - </defs>
263   - </svg>
264   - </div>
  266 + <feOffset dx="0" dy="0" />
  267 + <feGaussianBlur stdDeviation="10" />
  268 + <feComposite in2="hardAlpha" operator="arithmetic" k2="-1" k3="1" />
  269 + <feColorMatrix
  270 + type="matrix"
  271 + values="0 0 0 0 0.027450980392156862 0 0 0 0 0.5568627450980392 0 0 0 0 0.6392156862745098 0 0 0 1 0"
  272 + />
  273 + <feBlend mode="normal" in2="shape" result="innerShadow_0" />
  274 + </filter>
  275 + <filter
  276 + id="filter_25"
  277 + x="-6"
  278 + y="-6"
  279 + width="140"
  280 + height="55"
  281 + filterUnits="userSpaceOnUse"
  282 + color-interpolation-filters="sRGB"
  283 + >
  284 + <feFlood flood-opacity="0" result="BackgroundImageFix" />
  285 + <feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape" />
  286 + <feGaussianBlur stdDeviation="3" result="effect1_foregroundBlur" />
  287 + </filter>
  288 + </defs>
  289 + </svg>
  290 + </TKDialog>
  291 + </section>
265 292 </template>
266 293
267 294 <script setup lang="ts">
268   -import { PropType, toRefs, shallowReactive, watch, onMounted, ref } from 'vue'
269   -import cloneDeep from 'lodash/cloneDeep'
  295 +import { PropType, toRefs, ref, nextTick, watch } from 'vue'
  296 +import type { option as rewriteOption } from './config'
270 297 import { CreateComponentType } from '@/packages/index.d'
271 298 import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
272 299 import { useChartInteract } from '@/hooks/external/useButtonPageChangeInteract.hook'
273 300 import { InteractEventOn } from '@/enums/eventEnum'
274 301 import { ComponentInteractParamsEnum } from './interact'
  302 +import { PageChartListItem } from '@/store/modules/chartEditStore/chartEditStore.d'
  303 +import { TKDialog } from '@/components/external/Common/TKDialog'
275 304
276 305 const props = defineProps({
277 306 chartConfig: {
... ... @@ -282,35 +311,13 @@ const props = defineProps({
282 311
283 312 const { w, h } = toRefs(props.chartConfig.attr)
284 313
285   -const {
286   - buttonType,
287   - buttonDashed,
288   - buttonGhost,
289   - buttonColor,
290   - buttonTextColor,
291   - buttonTextSize,
292   - dataset,
293   - buttonTextBold,
294   - quaternary
295   -} = toRefs(props.chartConfig.option)
296   -
297   -const option = shallowReactive({
298   - value: cloneDeep(props.chartConfig.option)
299   -})
300   -
301   -const interactPageId = ref('')
  314 +const { dataset, fontConfig, colorConfig, popupConfig, svgTitle, disabled } = toRefs(
  315 + props.chartConfig.option as typeof rewriteOption
  316 +)
302 317
303   -const isActivate = ref(true)
  318 +const isActivate = ref(false)
304 319
305   -const onClick = (v: any) => {
306   - // useChartInteract(
307   - // props.chartConfig,
308   - // useChartEditStore,
309   - // { [ComponentInteractParamsEnum.DATA]: v },
310   - // InteractEventOn.CHANGE,
311   - // status
312   - // )
313   - interactPageId.value = v
  320 +const useInteract = (v: PageChartListItem) => {
314 321 useChartInteract(
315 322 props.chartConfig,
316 323 useChartEditStore,
... ... @@ -319,54 +326,29 @@ const onClick = (v: any) => {
319 326 )
320 327 }
321 328
322   -const handleSvgMouseUpClick = () => {
323   - isActivate.value = true
  329 +const handleSvgClick = (v: PageChartListItem) => {
  330 + if (disabled.value) return
  331 + useInteract(v)
324 332 }
325 333
326   -const handleSvgMouseDownClick = () => {
327   - isActivate.value = false
  334 +const handleUpdateShow = async (show: boolean) => {
  335 + await nextTick()
  336 + isActivate.value = show
328 337 }
329 338
330   -onMounted(() => {
331   - // onClick(option.value.selectTargetItems)
332   - // onClick(useChartEditStore().getPageConfig)
333   -})
334   -
335   -// 手动更新
336 339 watch(
337   - () => props.chartConfig.option,
338   - (newData: any) => {
339   - option.value = newData
340   - // onClick(newData.tabValue)
  340 + () => disabled.value,
  341 + (newValue: boolean) => {
  342 + disabled.value = newValue
341 343 },
342 344 {
343   - immediate: true,
344   - deep: true
345   - }
346   -)
347   -
348   -watch(
349   - () => interactPageId.value,
350   - (newValue: Recordable) => {
351   - useChartInteract(
352   - props.chartConfig,
353   - useChartEditStore,
354   - { [ComponentInteractParamsEnum.DATA]: newValue },
355   - InteractEventOn.PAGE_CHANGE
356   - )
357   - },
358   - {
359   - deep: true
  345 + immediate: true
360 346 }
361 347 )
362 348 </script>
363 349
364 350 <style lang="scss" scoped>
365   -.button-text-color {
366   - color: v-bind('buttonTextColor');
367   - font-size: v-bind('`${buttonTextSize}px`');
368   -}
369   -.decorate-button {
  351 +.decorate1-button {
370 352 cursor: pointer;
371 353 }
372 354 </style>
... ...
... ... @@ -8,7 +8,7 @@ export const PageButtonConfig: ConfigType = {
8 8 key,
9 9 chartKey,
10 10 conKey,
11   - title: '页面切换按钮',
  11 + title: '切换多页按钮',
12 12 category: ChatCategoryEnum.INPUTS,
13 13 categoryName: ChatCategoryEnumName.INPUTS,
14 14 package: PackagesCategoryEnum.INFORMATIONS,
... ...
... ... @@ -8,15 +8,19 @@ export const option = {
8 8 header: ['列1', '列2', '列3'],
9 9 dataset: dataJson,
10 10 index: true,
11   - columnWidth: [30, 100, 100],
12   - align: ['center', 'right', 'right', 'right'],
  11 + columnWidth: [100, 300, 300, 300],
  12 + align: ['center', 'center', 'center', 'center'],
13 13 rowNum: 5,
14 14 waitTime: 2,
15 15 headerHeight: 35,
16 16 carousel: 'single',
17 17 headerBGC: '#00BAFF',
18 18 oddRowBGC: '#003B51',
19   - evenRowBGC: '#0A2732'
  19 + evenRowBGC: '#0A2732',
  20 + ceilSpanColor: '#FFFFFF',
  21 + ceilSpanFontSize: 16,
  22 + headerSpanColor: '#FFFFFF',
  23 + headerSpanFontSize: 16
20 24 }
21 25
22 26 export default class Config extends PublicConfigClass implements CreateComponentType {
... ...
... ... @@ -50,7 +50,32 @@
50 50 />
51 51 </SettingItem>
52 52 </SettingItemBox>
53   -
  53 + <SettingItemBox name="表头字体">
  54 + <SettingItem name="颜色">
  55 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.headerSpanColor"></n-color-picker>
  56 + </SettingItem>
  57 + <SettingItem name="大小">
  58 + <n-input-number
  59 + v-model:value="optionData.headerSpanFontSize"
  60 + :min="1"
  61 + size="small"
  62 + placeholder="请输入"
  63 + ></n-input-number>
  64 + </SettingItem>
  65 + </SettingItemBox>
  66 + <SettingItemBox name="内容字体">
  67 + <SettingItem name="颜色">
  68 + <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.ceilSpanColor"></n-color-picker>
  69 + </SettingItem>
  70 + <SettingItem name="大小">
  71 + <n-input-number
  72 + v-model:value="optionData.ceilSpanFontSize"
  73 + :min="1"
  74 + size="small"
  75 + placeholder="请输入"
  76 + ></n-input-number>
  77 + </SettingItem>
  78 + </SettingItemBox>
54 79 <SettingItemBox name="样式">
55 80 <SettingItem name="表头背景色">
56 81 <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.headerBGC"></n-color-picker>
... ...
... ... @@ -6,13 +6,15 @@
6 6 :style="`background-color: ${status.mergedConfig.headerBGC};`"
7 7 >
8 8 <div
9   - class="header-item"
  9 + class="header-item singe-line"
10 10 v-for="(headerItem, i) in status.header"
11 11 :key="`${headerItem}${i}`"
12 12 :style="`
13 13 height: ${status.mergedConfig.headerHeight}px;
14 14 line-height: ${status.mergedConfig.headerHeight}px;
15 15 width: ${status.widths[i]}px;
  16 + color:${headerSpanColor};
  17 + font-size:${headerSpanFontSize}px;
16 18 `"
17 19 :align="status.aligns[i]"
18 20 v-html="headerItem"
... ... @@ -35,10 +37,14 @@
35 37 `"
36 38 >
37 39 <div
38   - class="ceil"
  40 + class="ceil singe-line"
39 41 v-for="(ceil, ci) in row.ceils"
40 42 :key="`${ceil}${ri}${ci}`"
41   - :style="`width: ${status.widths[ci]}px;`"
  43 + :style="`
  44 + width: ${status.widths[ci]}px;
  45 + color:${ceilSpanColor};
  46 + font-size:${ceilSpanFontSize}px;
  47 + `"
42 48 :align="status.aligns[ci]"
43 49 v-html="ceil"
44 50 />
... ... @@ -66,7 +72,7 @@ const props = defineProps({
66 72 // 这里能拿到图表宽高等
67 73 const { w, h } = toRefs(props.chartConfig.attr)
68 74 // 这里能拿到上面 config.ts 里的 option 数据
69   -// const { rowNum, headerHeight, index, backgroundColor } = toRefs(props.chartConfig.option)
  75 +const { ceilSpanColor, ceilSpanFontSize, headerSpanColor, headerSpanFontSize } = toRefs(props.chartConfig.option)
70 76
71 77 const status = reactive({
72 78 defaultConfig: {
... ... @@ -391,6 +397,12 @@ const handleDataFormat = (deviceDetail: any, attributes: any) => {
391 397 </script>
392 398
393 399 <style lang="scss" scoped>
  400 +.singe-line {
  401 + text-overflow: ellipsis;
  402 + overflow: hidden;
  403 + word-break: break-all;
  404 + white-space: nowrap;
  405 +}
394 406 .dv-scroll-board {
395 407 position: relative;
396 408 width: 100%;
... ...
... ... @@ -1139,4 +1139,5 @@ export const useChartEditStore = defineStore({
1139 1139 }
1140 1140 }
1141 1141 })
  1142 +
1142 1143 //
... ...