Commit 078c671ee2ab485976c6f230cd89c4c3e77f773b
Merge branch 'main_dev' into 'main'
Main dev See merge request yunteng/thingskit-view!218
Showing
72 changed files
with
3470 additions
and
467 deletions
Too many changes to show.
To preserve performance only 72 of 153 files are displayed.
| 1 | import { defHttp } from '@/utils/external/http/axios' | 1 | import { defHttp } from '@/utils/external/http/axios' |
| 2 | import { ConfigurationItemType, DictItem, OrganizationListItem, UploadResponse } from './model' | 2 | import { ConfigurationItemType, DictItem, OrganizationListItem, UploadResponse } from './model' |
| 3 | import { PaginationResult } from '/#/external/axios' | 3 | import { PaginationResult } from '/#/external/axios' |
| 4 | +import { isShareMode } from '@/views/share/hook' | ||
| 4 | 5 | ||
| 5 | enum Api { | 6 | enum Api { |
| 6 | GET_DICT = '/dict_item', | 7 | GET_DICT = '/dict_item', |
| @@ -114,10 +115,12 @@ export const getVideoUrl = (id: string) => | @@ -114,10 +115,12 @@ export const getVideoUrl = (id: string) => | ||
| 114 | }) | 115 | }) |
| 115 | 116 | ||
| 116 | //获取行政区域 | 117 | //获取行政区域 |
| 117 | -export const getGeoJsonMap = (code: number | string, level: string) => | ||
| 118 | - defHttp.get({ | 118 | +export const getGeoJsonMap = (code: number | string, level: string) => { |
| 119 | + return defHttp.get({ | ||
| 119 | url: `${Api.GEOJSONURL}${code}/${level}` | 120 | url: `${Api.GEOJSONURL}${code}/${level}` |
| 120 | - }) | 121 | + }, { withShareToken: isShareMode() }) |
| 122 | +} | ||
| 123 | + | ||
| 121 | 124 | ||
| 122 | // 获取设备详情 | 125 | // 获取设备详情 |
| 123 | export const getDeviceDetail = (id: string) => | 126 | export const getDeviceDetail = (id: string) => |
| @@ -133,11 +136,11 @@ export const getAttribute = (deviceProfileId: string) => | @@ -133,11 +136,11 @@ export const getAttribute = (deviceProfileId: string) => | ||
| 133 | 136 | ||
| 134 | // 获取设备最新数据 | 137 | // 获取设备最新数据 |
| 135 | export const getDeviceLatest = (tbDeviceId: string) => | 138 | export const getDeviceLatest = (tbDeviceId: string) => |
| 136 | -defHttp.get({ | ||
| 137 | - url: `${Api.GET_DEVICE_LATEST}${tbDeviceId}/values/timeseries` | ||
| 138 | -}, { | ||
| 139 | - joinPrefix: false | ||
| 140 | -}) | 139 | + defHttp.get({ |
| 140 | + url: `${Api.GET_DEVICE_LATEST}${tbDeviceId}/values/timeseries` | ||
| 141 | + }, { | ||
| 142 | + joinPrefix: false | ||
| 143 | + }) | ||
| 141 | 144 | ||
| 142 | //获取产品属性 | 145 | //获取产品属性 |
| 143 | export const getProfileAttrs = (params: { deviceProfileId: string; dataType?: string }) => { | 146 | export const getProfileAttrs = (params: { deviceProfileId: string; dataType?: string }) => { |
| @@ -94,13 +94,15 @@ const extraValue = (object: Recordable) => { | @@ -94,13 +94,15 @@ const extraValue = (object: Recordable) => { | ||
| 94 | 94 | ||
| 95 | const handleParams = (Params: Recordable) => { | 95 | const handleParams = (Params: Recordable) => { |
| 96 | if (Params.keys && Params?.keys?.length) { | 96 | if (Params.keys && Params?.keys?.length) { |
| 97 | + // 过滤无效参数 | ||
| 98 | + Reflect.deleteProperty(Params, 'attrName') | ||
| 97 | /** ft 修改select联动下拉框选择了属性(单个)报错问题 | 99 | /** ft 修改select联动下拉框选择了属性(单个)报错问题 |
| 98 | * 源代码 Params.keys = (Params.keys || [] as any).join(',') | 100 | * 源代码 Params.keys = (Params.keys || [] as any).join(',') |
| 99 | */ | 101 | */ |
| 100 | - if(!Array.isArray(Params.keys)){ | ||
| 101 | - Params.keys = ([Params.keys] || [] as any).join(',') | ||
| 102 | - }else{ | ||
| 103 | - Params.keys = (Params.keys || [] as any).join(',') | 102 | + if (!Array.isArray(Params.keys)) { |
| 103 | + Params.keys = ([Params.keys] || [] as any).join(',') | ||
| 104 | + } else { | ||
| 105 | + Params.keys = (Params.keys || [] as any).join(',') | ||
| 104 | } | 106 | } |
| 105 | //ft | 107 | //ft |
| 106 | } | 108 | } |
| @@ -116,12 +118,12 @@ const handleParams = (Params: Recordable) => { | @@ -116,12 +118,12 @@ const handleParams = (Params: Recordable) => { | ||
| 116 | } | 118 | } |
| 117 | 119 | ||
| 118 | //post请求动态追加query参数 | 120 | //post请求动态追加query参数 |
| 119 | -const objConvertQuery= (data:Recordable)=> { | 121 | +const objConvertQuery = (data: Recordable) => { |
| 120 | const _result = []; | 122 | const _result = []; |
| 121 | for (const key in data) { | 123 | for (const key in data) { |
| 122 | const value = data[key]; | 124 | const value = data[key]; |
| 123 | if (value.constructor == Array) { | 125 | if (value.constructor == Array) { |
| 124 | - value.forEach(function(_value) { | 126 | + value.forEach(function (_value) { |
| 125 | _result.push(key + "=" + _value); | 127 | _result.push(key + "=" + _value); |
| 126 | }); | 128 | }); |
| 127 | } else { | 129 | } else { |
| @@ -152,11 +154,12 @@ export const customRequest = async (request: RequestConfigType) => { | @@ -152,11 +154,12 @@ export const customRequest = async (request: RequestConfigType) => { | ||
| 152 | * 修改后代码 requestHttpType === RequestHttpEnum.GET.toUpperCase() ? requestUrl: `${requestUrl}?${objConvertQuery(Params)} | 154 | * 修改后代码 requestHttpType === RequestHttpEnum.GET.toUpperCase() ? requestUrl: `${requestUrl}?${objConvertQuery(Params)} |
| 153 | */ | 155 | */ |
| 154 | Params = handleParams(Params) | 156 | Params = handleParams(Params) |
| 157 | + | ||
| 155 | return customHttp.request<any>({ | 158 | return customHttp.request<any>({ |
| 156 | - url: requestHttpType === RequestHttpEnum.GET.toUpperCase() ? requestUrl: `${requestUrl}?${objConvertQuery(Params)}`, | 159 | + url: requestHttpType === RequestHttpEnum.GET.toUpperCase() ? requestUrl : `${requestUrl}?${objConvertQuery(Params)}`, |
| 157 | baseURL: getOriginUrl(requestOriginUrl!), | 160 | baseURL: getOriginUrl(requestOriginUrl!), |
| 158 | method: requestHttpType, | 161 | method: requestHttpType, |
| 159 | - params: requestHttpType === RequestHttpEnum.GET.toUpperCase() ? Params: null, | 162 | + params: requestHttpType === RequestHttpEnum.GET.toUpperCase() ? Params : null, |
| 160 | data: body, | 163 | data: body, |
| 161 | headers: extraValue(Header) | 164 | headers: extraValue(Header) |
| 162 | }, { | 165 | }, { |
| @@ -2,7 +2,8 @@ import { defHttp } from "@/utils/external/http/axios"; | @@ -2,7 +2,8 @@ import { defHttp } from "@/utils/external/http/axios"; | ||
| 2 | import { useGlobSetting } from '@/hooks/external/setting'; | 2 | import { useGlobSetting } from '@/hooks/external/setting'; |
| 3 | enum Api { | 3 | enum Api { |
| 4 | OPEN_FLV = '/rtsp/openFlv', | 4 | OPEN_FLV = '/rtsp/openFlv', |
| 5 | - CLOSE_FLV = '/rtsp/closeFlv' | 5 | + CLOSE_FLV = '/rtsp/closeFlv', |
| 6 | + GET_VIDEO_CONTROL_START = '/video/control/start', | ||
| 6 | } | 7 | } |
| 7 | 8 | ||
| 8 | export const getOpenFlvPlayUrl = (url: string, browserId: string) => { | 9 | export const getOpenFlvPlayUrl = (url: string, browserId: string) => { |
| @@ -19,3 +20,17 @@ export const closeFlvPlay = (url: string, browserId: string) => { | @@ -19,3 +20,17 @@ export const closeFlvPlay = (url: string, browserId: string) => { | ||
| 19 | } | 20 | } |
| 20 | }); | 21 | }); |
| 21 | }; | 22 | }; |
| 23 | + | ||
| 24 | +//gbt28181,获取flv地址 | ||
| 25 | +export const getVideoControlStart = ({ | ||
| 26 | + deviceId, | ||
| 27 | + channelId, | ||
| 28 | +}: Record<'deviceId' | 'channelId', string>) => { | ||
| 29 | + return defHttp.get<Recordable>( | ||
| 30 | + { | ||
| 31 | + url: `${Api.GET_VIDEO_CONTROL_START}/${deviceId}/${channelId}`, | ||
| 32 | + timeout: 30 * 1000, | ||
| 33 | + }, | ||
| 34 | + {} | ||
| 35 | + ); | ||
| 36 | +}; |
29.6 KB
80.3 KB
41.9 KB
65.7 KB
75.6 KB
70.8 KB
100 KB
92.9 KB
103 KB
102 KB
69.7 KB
87.5 KB
84.2 KB
50.3 KB
45.7 KB
15 KB
| 1 | +<template> | ||
| 2 | + <div class="smallcircle2"></div> | ||
| 3 | +</template> | ||
| 4 | + | ||
| 5 | +<script setup lang="ts"></script> | ||
| 6 | + | ||
| 7 | +<style lang="scss" scoped> | ||
| 8 | +.smallcircle2 { | ||
| 9 | + display: block; | ||
| 10 | + width: 12px; | ||
| 11 | + height: 12px; | ||
| 12 | + border-radius: 50%; | ||
| 13 | + opacity: 0.4; | ||
| 14 | + background: radial-gradient(circle at center, red 0, blue, #2277b2 100%); | ||
| 15 | +} | ||
| 16 | +</style> |
| 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 | +<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> |
src/enums/external/animationEnum.ts
0 → 100644
| 1 | + | ||
| 2 | + | ||
| 3 | +// 动画时间函数枚举 | ||
| 4 | +export enum AnimationTimingFunctionNameEnum { | ||
| 5 | + // 动画从头到尾的速度是相同的 | ||
| 6 | + LINEAR = '匀速', | ||
| 7 | + // 默认值:动画以低速开始,然后加快,在结束前变慢。 | ||
| 8 | + EASE = '缓速', | ||
| 9 | + // 动画以低速开始。 | ||
| 10 | + EASEIN = '低速开始', | ||
| 11 | + // 动画以低速结束。 | ||
| 12 | + EASEOUT = '低速结束', | ||
| 13 | + // 动画以低速开始和结束。 | ||
| 14 | + EASEINOUT = '低速开始和结束' | ||
| 15 | +} | ||
| 16 | + | ||
| 17 | +export enum AnimationTimingFunctionEnum { | ||
| 18 | + // 动画从头到尾的速度是相同的 | ||
| 19 | + LINEAR = 'linear', | ||
| 20 | + // 默认值:动画以低速开始,然后加快,在结束前变慢。 | ||
| 21 | + EASE = 'ease', | ||
| 22 | + // 动画以低速开始。 | ||
| 23 | + EASEIN = 'ease-in', | ||
| 24 | + // 动画以低速结束。 | ||
| 25 | + EASEOUT = 'ease-out', | ||
| 26 | + // 动画以低速开始和结束。 | ||
| 27 | + EASEINOUT = 'ease-in-out' | ||
| 28 | +} | ||
| 29 | + | ||
| 30 | +// 动画执行状态枚举 | ||
| 31 | +export enum AnimationPlayStateNameEnum { | ||
| 32 | + // 暂停 | ||
| 33 | + PAUSED = '暂停', | ||
| 34 | + // 运行 | ||
| 35 | + RUNNING = '运行' | ||
| 36 | +} | ||
| 37 | + | ||
| 38 | +export enum AnimationPlayStateEnum { | ||
| 39 | + // 暂停 | ||
| 40 | + PAUSED = 'paused', | ||
| 41 | + // 运行 | ||
| 42 | + RUNNING = 'running' | ||
| 43 | +} | ||
| 44 | + | ||
| 45 | +// 动画执行次数枚举 | ||
| 46 | +export enum AnimationIterationCountNameEnum { | ||
| 47 | + // 暂停 | ||
| 48 | + ITERATIONCOUNT = '无限次', | ||
| 49 | +} | ||
| 50 | + | ||
| 51 | +export enum AnimationIterationCountEnum { | ||
| 52 | + // 暂停 | ||
| 53 | + ITERATIONCOUNT = 'infinite', | ||
| 54 | +} |
src/enums/external/mapEnum.ts
0 → 100644
| 1 | -import { toRefs } from 'vue' | ||
| 2 | import { CreateComponentType } from '@/packages/index.d' | 1 | import { CreateComponentType } from '@/packages/index.d' |
| 3 | import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' | 2 | import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' |
| 4 | import { PageChartEditStoreType } from '@/store/modules/chartEditStore/chartEditStore.d' | 3 | import { PageChartEditStoreType } from '@/store/modules/chartEditStore/chartEditStore.d' |
| @@ -41,6 +41,10 @@ const getSocketInstance = (request: ExtraRequestConfigType) => { | @@ -41,6 +41,10 @@ const getSocketInstance = (request: ExtraRequestConfigType) => { | ||
| 41 | const socketUrl = `${getOriginUrl(requestOriginUrl || '')}${requestUrl}?token=${token}` | 41 | const socketUrl = `${getOriginUrl(requestOriginUrl || '')}${requestUrl}?token=${token}` |
| 42 | 42 | ||
| 43 | const instance = useWebSocket(socketUrl, { | 43 | const instance = useWebSocket(socketUrl, { |
| 44 | + autoReconnect: { | ||
| 45 | + retries: 20, | ||
| 46 | + delay: 1000 * 30 | ||
| 47 | + }, | ||
| 44 | onMessage() { | 48 | onMessage() { |
| 45 | const { data: originData } = instance | 49 | const { data: originData } = instance |
| 46 | const value = parse(unref(originData)) as SocketReceiveMessageType | 50 | const value = parse(unref(originData)) as SocketReceiveMessageType |
| @@ -121,7 +125,7 @@ export const useChartDataSocket = () => { | @@ -121,7 +125,7 @@ export const useChartDataSocket = () => { | ||
| 121 | return { | 125 | return { |
| 122 | initial, | 126 | initial, |
| 123 | sendMessage, | 127 | sendMessage, |
| 124 | - disconnectWs | 128 | + disconnectWs, |
| 125 | } | 129 | } |
| 126 | } | 130 | } |
| 127 | 131 |
| 1 | +/** | ||
| 2 | + * 此hook的作用是针对echarts图表类型,legend图例,映射成物模型中文 | ||
| 3 | + */ | ||
| 4 | + | ||
| 5 | +export const useEchartsMapLegend = (chartConfig: Recordable, seriesArr: Recordable[]) => { | ||
| 6 | + const { request } = chartConfig | ||
| 7 | + const { | ||
| 8 | + requestParams: { | ||
| 9 | + Params: { attrName } | ||
| 10 | + } | ||
| 11 | + } = request || {} | ||
| 12 | + seriesArr?.forEach((item: Recordable, index: number) => { | ||
| 13 | + item.name = attrName?.[index] | ||
| 14 | + }) | ||
| 15 | +} |
| @@ -27,6 +27,7 @@ import { isPreview } from '@/utils' | @@ -27,6 +27,7 @@ import { isPreview } from '@/utils' | ||
| 27 | import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components' | 27 | import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components' |
| 28 | import isObject from 'lodash/isObject' | 28 | import isObject from 'lodash/isObject' |
| 29 | import cloneDeep from 'lodash/cloneDeep' | 29 | import cloneDeep from 'lodash/cloneDeep' |
| 30 | +import { useEchartsMapLegend } from '@/hooks/external/useEchartLegendMapChinese.hook' | ||
| 30 | 31 | ||
| 31 | const props = defineProps({ | 32 | const props = defineProps({ |
| 32 | themeSetting: { | 33 | themeSetting: { |
| @@ -64,6 +65,7 @@ watch( | @@ -64,6 +65,7 @@ watch( | ||
| 64 | for (let i = 0; i < newData.dimensions.length - 1; i++) { | 65 | for (let i = 0; i < newData.dimensions.length - 1; i++) { |
| 65 | seriesArr.push(cloneDeep(seriesItem)) | 66 | seriesArr.push(cloneDeep(seriesItem)) |
| 66 | } | 67 | } |
| 68 | + useEchartsMapLegend(props.chartConfig, seriesArr) | ||
| 67 | replaceMergeArr.value = ['series'] | 69 | replaceMergeArr.value = ['series'] |
| 68 | props.chartConfig.option.series = seriesArr | 70 | props.chartConfig.option.series = seriesArr |
| 69 | nextTick(() => { | 71 | nextTick(() => { |
| @@ -5,6 +5,9 @@ | @@ -5,6 +5,9 @@ | ||
| 5 | :theme="themeColor" | 5 | :theme="themeColor" |
| 6 | :option="option" | 6 | :option="option" |
| 7 | :manual-update="isPreview()" | 7 | :manual-update="isPreview()" |
| 8 | + :update-options="{ | ||
| 9 | + replaceMerge: replaceMergeArr | ||
| 10 | + }" | ||
| 8 | autoresize | 11 | autoresize |
| 9 | ></v-chart> | 12 | ></v-chart> |
| 10 | </template> | 13 | </template> |
| @@ -23,6 +26,11 @@ import { useChartDataFetch } from '@/hooks' | @@ -23,6 +26,11 @@ import { useChartDataFetch } from '@/hooks' | ||
| 23 | import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' | 26 | import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' |
| 24 | import { isPreview } from '@/utils' | 27 | import { isPreview } from '@/utils' |
| 25 | import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components' | 28 | import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components' |
| 29 | +import { SocketReceiveMessageType } from '@/store/external/modules/socketStore.d' | ||
| 30 | +import isObject from 'lodash/isObject' | ||
| 31 | +import { useAssembleDataHooks } from '@/hooks/external/useAssembleData.hook' | ||
| 32 | +import { useEchartsMapLegend } from '@/hooks/external/useEchartLegendMapChinese.hook' | ||
| 33 | +import cloneDeep from 'lodash/cloneDeep' | ||
| 26 | 34 | ||
| 27 | const props = defineProps({ | 35 | const props = defineProps({ |
| 28 | themeSetting: { | 36 | themeSetting: { |
| @@ -43,25 +51,34 @@ const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSe | @@ -43,25 +51,34 @@ const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSe | ||
| 43 | 51 | ||
| 44 | use([DatasetComponent, CanvasRenderer, BarChart, LineChart, GridComponent, TooltipComponent, LegendComponent]) | 52 | use([DatasetComponent, CanvasRenderer, BarChart, LineChart, GridComponent, TooltipComponent, LegendComponent]) |
| 45 | 53 | ||
| 54 | +const chartEditStore = useChartEditStore() | ||
| 55 | + | ||
| 46 | const replaceMergeArr = ref<string[]>() | 56 | const replaceMergeArr = ref<string[]>() |
| 47 | 57 | ||
| 48 | const option = computed(() => { | 58 | const option = computed(() => { |
| 49 | return mergeTheme(props.chartConfig.option, props.themeSetting, includes) | 59 | return mergeTheme(props.chartConfig.option, props.themeSetting, includes) |
| 50 | }) | 60 | }) |
| 51 | 61 | ||
| 62 | +// dataset 无法变更条数的补丁 | ||
| 52 | watch( | 63 | watch( |
| 53 | () => props.chartConfig.option.dataset, | 64 | () => props.chartConfig.option.dataset, |
| 54 | - (newData, oldData) => { | ||
| 55 | - if (newData.dimensions.length !== oldData.dimensions.length) { | ||
| 56 | - const seriesArr = [] | ||
| 57 | - for (let i = 0; i < newData.dimensions.length - 1; i++) { | ||
| 58 | - seriesArr.push(barSeriesItem, lineSeriesItem) | 65 | + (newData: { dimensions: any }, oldData) => { |
| 66 | + try { | ||
| 67 | + if (!isObject(newData) || !('dimensions' in newData)) return | ||
| 68 | + if (Array.isArray(newData?.dimensions)) { | ||
| 69 | + const seriesArr = [] | ||
| 70 | + for (let i = 0; i < newData.dimensions.length - 1; i++) { | ||
| 71 | + seriesArr.push(cloneDeep(barSeriesItem),cloneDeep(lineSeriesItem)) | ||
| 72 | + } | ||
| 73 | + useEchartsMapLegend(props.chartConfig, seriesArr) | ||
| 74 | + replaceMergeArr.value = ['series'] | ||
| 75 | + props.chartConfig.option.series = seriesArr | ||
| 76 | + nextTick(() => { | ||
| 77 | + replaceMergeArr.value = [] | ||
| 78 | + }) | ||
| 59 | } | 79 | } |
| 60 | - replaceMergeArr.value = ['series'] | ||
| 61 | - props.chartConfig.option.series = seriesArr | ||
| 62 | - nextTick(() => { | ||
| 63 | - replaceMergeArr.value = [] | ||
| 64 | - }) | 80 | + } catch (error) { |
| 81 | + console.log(error) | ||
| 65 | } | 82 | } |
| 66 | }, | 83 | }, |
| 67 | { | 84 | { |
| @@ -69,5 +86,53 @@ watch( | @@ -69,5 +86,53 @@ watch( | ||
| 69 | } | 86 | } |
| 70 | ) | 87 | ) |
| 71 | 88 | ||
| 72 | -const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore) | 89 | +//fix 修复v-chart图表绑定联动组件视图不更新问题 |
| 90 | +const updateVChart =async (newData:SocketReceiveMessageType) => { | ||
| 91 | + //区分是普通请求还是ws请求 | ||
| 92 | + if (!isObject(newData) || !('dimensions' in newData)) { | ||
| 93 | + const { data } = newData | ||
| 94 | + const { keys, record } = useAssembleDataHooks(data) | ||
| 95 | + vChartRef.value?.setOption({ | ||
| 96 | + dataset: { | ||
| 97 | + dimensions: ['ts', ...keys], | ||
| 98 | + source: [record] | ||
| 99 | + } | ||
| 100 | + }) | ||
| 101 | + } else { | ||
| 102 | + //异步更新,同步更新会造成联动组件控制,图表不及时更新 | ||
| 103 | + await nextTick().then(()=>{ | ||
| 104 | + vChartRef.value?.setOption( | ||
| 105 | + { | ||
| 106 | + ...option.value, | ||
| 107 | + dataset: newData | ||
| 108 | + }, | ||
| 109 | + { | ||
| 110 | + notMerge: true | ||
| 111 | + } | ||
| 112 | + ) | ||
| 113 | + }) | ||
| 114 | + } | ||
| 115 | +} | ||
| 116 | + | ||
| 117 | +const {vChartRef} = useChartDataFetch(props.chartConfig, useChartEditStore, (newData) => { | ||
| 118 | + //联动支持分组 | ||
| 119 | + /** | ||
| 120 | + * 修复多个分组,然后下拉框联动,会影响另一个组件 | ||
| 121 | + */ | ||
| 122 | + chartEditStore.getComponentList.forEach(targetItem => { | ||
| 123 | + if (targetItem.isGroup) { | ||
| 124 | + targetItem.groupList?.forEach(groupItem => { | ||
| 125 | + if (groupItem.id === props.chartConfig.id) { | ||
| 126 | + groupItem.option.dataset = newData | ||
| 127 | + } | ||
| 128 | + }) | ||
| 129 | + } else { | ||
| 130 | + if (targetItem.id === props.chartConfig.id) { | ||
| 131 | + targetItem.option.dataset = newData | ||
| 132 | + } | ||
| 133 | + } | ||
| 134 | + }) | ||
| 135 | + // | ||
| 136 | + updateVChart(newData) | ||
| 137 | +}) | ||
| 73 | </script> | 138 | </script> |
| @@ -17,6 +17,7 @@ import { chartColorsSearch, defaultTheme } from '@/settings/chartThemes/index' | @@ -17,6 +17,7 @@ import { chartColorsSearch, defaultTheme } from '@/settings/chartThemes/index' | ||
| 17 | import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components' | 17 | import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components' |
| 18 | import { useChartDataFetch } from '@/hooks' | 18 | import { useChartDataFetch } from '@/hooks' |
| 19 | import { isPreview, colorGradientCustomMerge} from '@/utils' | 19 | import { isPreview, colorGradientCustomMerge} from '@/utils' |
| 20 | +import { useEchartsMapLegend } from '@/hooks/external/useEchartLegendMapChinese.hook' | ||
| 20 | 21 | ||
| 21 | const props = defineProps({ | 22 | const props = defineProps({ |
| 22 | themeSetting: { | 23 | themeSetting: { |
| @@ -79,6 +80,9 @@ watch( | @@ -79,6 +80,9 @@ watch( | ||
| 79 | () => props.chartConfig.option.dataset, | 80 | () => props.chartConfig.option.dataset, |
| 80 | () => { | 81 | () => { |
| 81 | option.value = props.chartConfig.option | 82 | option.value = props.chartConfig.option |
| 83 | + useEchartsMapLegend(props.chartConfig, props.chartConfig.option.series) | ||
| 84 | + },{ | ||
| 85 | + deep: false | ||
| 82 | } | 86 | } |
| 83 | ) | 87 | ) |
| 84 | 88 |
| @@ -17,6 +17,7 @@ import { chartColorsSearch, defaultTheme } from '@/settings/chartThemes/index' | @@ -17,6 +17,7 @@ import { chartColorsSearch, defaultTheme } from '@/settings/chartThemes/index' | ||
| 17 | import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components' | 17 | import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components' |
| 18 | import { useChartDataFetch } from '@/hooks' | 18 | import { useChartDataFetch } from '@/hooks' |
| 19 | import { isPreview, colorGradientCustomMerge } from '@/utils' | 19 | import { isPreview, colorGradientCustomMerge } from '@/utils' |
| 20 | +import { useEchartsMapLegend } from '@/hooks/external/useEchartLegendMapChinese.hook' | ||
| 20 | 21 | ||
| 21 | const props = defineProps({ | 22 | const props = defineProps({ |
| 22 | themeSetting: { | 23 | themeSetting: { |
| @@ -73,6 +74,7 @@ watch( | @@ -73,6 +74,7 @@ watch( | ||
| 73 | () => props.chartConfig.option.dataset, | 74 | () => props.chartConfig.option.dataset, |
| 74 | () => { | 75 | () => { |
| 75 | option.value = props.chartConfig.option | 76 | option.value = props.chartConfig.option |
| 77 | + useEchartsMapLegend(props.chartConfig, props.chartConfig.option.series) | ||
| 76 | }, | 78 | }, |
| 77 | { | 79 | { |
| 78 | deep: false | 80 | deep: false |
| 1 | <template> | 1 | <template> |
| 2 | <n-space class="go-decorates-flipper-number" :size="flipperGap" align="center" justify="center"> | 2 | <n-space class="go-decorates-flipper-number" :size="flipperGap" align="center" justify="center"> |
| 3 | - <flipper | ||
| 4 | - :count="item" | ||
| 5 | - :width="flipperWidth" | ||
| 6 | - :height="flipperHeight" | ||
| 7 | - :front-color="flipperTextColor" | ||
| 8 | - :back-color="flipperBgColor" | ||
| 9 | - :radius="flipperRadius" | ||
| 10 | - :flip-type="flipperType" | ||
| 11 | - :duration="flipperSpeed" | ||
| 12 | - :border-width="flipperBorderWidth" | ||
| 13 | - v-for="(item, index) in flipperData" | ||
| 14 | - :key="index" | ||
| 15 | - class="go-d-block" | ||
| 16 | - /> | 3 | + <flipper :count="item" :width="flipperWidth" :height="flipperHeight" :front-color="flipperTextColor" |
| 4 | + :back-color="flipperBgColor" :radius="flipperRadius" :flip-type="flipperType" :duration="flipperSpeed" | ||
| 5 | + :border-width="flipperBorderWidth" v-for="(item, index) in flipperData" :key="index" class="go-d-block" /> | ||
| 17 | </n-space> | 6 | </n-space> |
| 18 | </template> | 7 | </template> |
| 19 | 8 | ||
| 20 | <script setup lang="ts"> | 9 | <script setup lang="ts"> |
| 21 | -import { PropType, toRefs, watch, ref } from 'vue' | 10 | +import { PropType, toRefs, watch, ref, computed, unref } from 'vue' |
| 22 | import { CreateComponentType } from '@/packages/index.d' | 11 | import { CreateComponentType } from '@/packages/index.d' |
| 23 | import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' | 12 | import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' |
| 24 | import { useChartDataFetch } from '@/hooks' | 13 | import { useChartDataFetch } from '@/hooks' |
| 25 | import { Flipper } from '@/components/Pages/Flipper' | 14 | import { Flipper } from '@/components/Pages/Flipper' |
| 26 | import { OptionType } from './config' | 15 | import { OptionType } from './config' |
| 16 | +import { RequestContentTypeEnum } from '@/enums/external/httpEnum' | ||
| 17 | +import { useTargetData } from '@/views/chart/ContentConfigurations/components/hooks/useTargetData.hook' | ||
| 27 | 18 | ||
| 28 | const props = defineProps({ | 19 | const props = defineProps({ |
| 29 | chartConfig: { | 20 | chartConfig: { |
| @@ -34,6 +25,37 @@ const props = defineProps({ | @@ -34,6 +25,37 @@ const props = defineProps({ | ||
| 34 | 25 | ||
| 35 | const { w, h } = toRefs(props.chartConfig.attr) | 26 | const { w, h } = toRefs(props.chartConfig.attr) |
| 36 | 27 | ||
| 28 | +const { targetData, chartEditStore } = useTargetData() | ||
| 29 | + | ||
| 30 | +const isWebsocket = computed(() => { | ||
| 31 | + const result = query(chartEditStore.getComponentList) | ||
| 32 | + if (result === false) return false | ||
| 33 | + | ||
| 34 | + if (result.id === targetData.value.id) | ||
| 35 | + return targetData.value.request.requestContentType as RequestContentTypeEnum === RequestContentTypeEnum.WEB_SOCKET | ||
| 36 | + else { | ||
| 37 | + return result.request.requestContentType as RequestContentTypeEnum === RequestContentTypeEnum.WEB_SOCKET | ||
| 38 | + } | ||
| 39 | +}) | ||
| 40 | + | ||
| 41 | +function query(list: CreateComponentType[]) { | ||
| 42 | + if (!list || !list?.length) return false | ||
| 43 | + | ||
| 44 | + for (const item of list) { | ||
| 45 | + if (item.id === targetData.value.id) { | ||
| 46 | + return item | ||
| 47 | + } | ||
| 48 | + if (item.groupList && item.groupList?.length) { | ||
| 49 | + const flag = query(list) | ||
| 50 | + if (flag) { | ||
| 51 | + return item | ||
| 52 | + } | ||
| 53 | + } | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + return false | ||
| 57 | +} | ||
| 58 | + | ||
| 37 | const { | 59 | const { |
| 38 | flipperLength, | 60 | flipperLength, |
| 39 | flipperBgColor, | 61 | flipperBgColor, |
| @@ -75,6 +97,7 @@ watch( | @@ -75,6 +97,7 @@ watch( | ||
| 75 | ) | 97 | ) |
| 76 | 98 | ||
| 77 | useChartDataFetch(props.chartConfig, useChartEditStore, (newVal: string | number) => { | 99 | useChartDataFetch(props.chartConfig, useChartEditStore, (newVal: string | number) => { |
| 100 | + if (unref(isWebsocket)) return | ||
| 78 | updateDatasetHandler(newVal) | 101 | updateDatasetHandler(newVal) |
| 79 | }) | 102 | }) |
| 80 | </script> | 103 | </script> |
| @@ -10,5 +10,5 @@ export const InputsInputConfig: ConfigType = { | @@ -10,5 +10,5 @@ export const InputsInputConfig: ConfigType = { | ||
| 10 | categoryName: ChatCategoryEnumName.INPUTS, | 10 | categoryName: ChatCategoryEnumName.INPUTS, |
| 11 | package: PackagesCategoryEnum.INFORMATIONS, | 11 | package: PackagesCategoryEnum.INFORMATIONS, |
| 12 | chartFrame: ChartFrameEnum.STATIC, | 12 | chartFrame: ChartFrameEnum.STATIC, |
| 13 | - image: 'inputs_select.png' | 13 | + image: 'inputs_input.png' |
| 14 | } | 14 | } |
| @@ -8,15 +8,19 @@ export const option = { | @@ -8,15 +8,19 @@ export const option = { | ||
| 8 | header: ['列1', '列2', '列3'], | 8 | header: ['列1', '列2', '列3'], |
| 9 | dataset: dataJson, | 9 | dataset: dataJson, |
| 10 | index: true, | 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 | rowNum: 5, | 13 | rowNum: 5, |
| 14 | waitTime: 2, | 14 | waitTime: 2, |
| 15 | headerHeight: 35, | 15 | headerHeight: 35, |
| 16 | carousel: 'single', | 16 | carousel: 'single', |
| 17 | headerBGC: '#00BAFF', | 17 | headerBGC: '#00BAFF', |
| 18 | oddRowBGC: '#003B51', | 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 | export default class Config extends PublicConfigClass implements CreateComponentType { | 26 | export default class Config extends PublicConfigClass implements CreateComponentType { |
| @@ -45,12 +45,37 @@ | @@ -45,12 +45,37 @@ | ||
| 45 | v-model:value="optionData.carousel" | 45 | v-model:value="optionData.carousel" |
| 46 | :options="[ | 46 | :options="[ |
| 47 | { label: '单条轮播', value: 'single' }, | 47 | { label: '单条轮播', value: 'single' }, |
| 48 | - { label: '整页轮播', value: 'page' }, | 48 | + { label: '整页轮播', value: 'page' } |
| 49 | ]" | 49 | ]" |
| 50 | /> | 50 | /> |
| 51 | </SettingItem> | 51 | </SettingItem> |
| 52 | </SettingItemBox> | 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 | <SettingItemBox name="样式"> | 79 | <SettingItemBox name="样式"> |
| 55 | <SettingItem name="表头背景色"> | 80 | <SettingItem name="表头背景色"> |
| 56 | <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.headerBGC"></n-color-picker> | 81 | <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.headerBGC"></n-color-picker> |
| @@ -6,13 +6,15 @@ | @@ -6,13 +6,15 @@ | ||
| 6 | :style="`background-color: ${status.mergedConfig.headerBGC};`" | 6 | :style="`background-color: ${status.mergedConfig.headerBGC};`" |
| 7 | > | 7 | > |
| 8 | <div | 8 | <div |
| 9 | - class="header-item" | 9 | + class="header-item singe-line" |
| 10 | v-for="(headerItem, i) in status.header" | 10 | v-for="(headerItem, i) in status.header" |
| 11 | :key="`${headerItem}${i}`" | 11 | :key="`${headerItem}${i}`" |
| 12 | :style="` | 12 | :style="` |
| 13 | height: ${status.mergedConfig.headerHeight}px; | 13 | height: ${status.mergedConfig.headerHeight}px; |
| 14 | line-height: ${status.mergedConfig.headerHeight}px; | 14 | line-height: ${status.mergedConfig.headerHeight}px; |
| 15 | width: ${status.widths[i]}px; | 15 | width: ${status.widths[i]}px; |
| 16 | + color:${headerSpanColor}; | ||
| 17 | + font-size:${headerSpanFontSize}px; | ||
| 16 | `" | 18 | `" |
| 17 | :align="status.aligns[i]" | 19 | :align="status.aligns[i]" |
| 18 | v-html="headerItem" | 20 | v-html="headerItem" |
| @@ -24,30 +26,32 @@ | @@ -24,30 +26,32 @@ | ||
| 24 | class="rows" | 26 | class="rows" |
| 25 | :style="`height: ${h - (status.header.length ? status.mergedConfig.headerHeight : 0)}px;`" | 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 | height: ${status.heights[ri]}px; | 35 | height: ${status.heights[ri]}px; |
| 34 | line-height: ${status.heights[ri]}px; | 36 | line-height: ${status.heights[ri]}px; |
| 35 | background-color: ${status.mergedConfig[row.rowIndex % 2 === 0 ? 'evenRowBGC' : 'oddRowBGC']}; | 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 | </div> | 53 | </div> |
| 47 | - </div> | ||
| 48 | - <div v-else class="nullData"> | ||
| 49 | - 暂无数据 | ||
| 50 | - </div> | 54 | + <div v-else class="nullData">暂无数据</div> |
| 51 | </div> | 55 | </div> |
| 52 | </div> | 56 | </div> |
| 53 | </template> | 57 | </template> |
| @@ -70,7 +74,7 @@ const props = defineProps({ | @@ -70,7 +74,7 @@ const props = defineProps({ | ||
| 70 | // 这里能拿到图表宽高等 | 74 | // 这里能拿到图表宽高等 |
| 71 | const { w, h } = toRefs(props.chartConfig.attr) | 75 | const { w, h } = toRefs(props.chartConfig.attr) |
| 72 | // 这里能拿到上面 config.ts 里的 option 数据 | 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 | const status = reactive({ | 79 | const status = reactive({ |
| 76 | defaultConfig: { | 80 | defaultConfig: { |
| @@ -355,6 +359,12 @@ onUnmounted(() => { | @@ -355,6 +359,12 @@ onUnmounted(() => { | ||
| 355 | </script> | 359 | </script> |
| 356 | 360 | ||
| 357 | <style lang="scss" scoped> | 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 | .dv-scroll-board { | 368 | .dv-scroll-board { |
| 359 | position: relative; | 369 | position: relative; |
| 360 | width: 100%; | 370 | width: 100%; |
| @@ -389,11 +399,11 @@ onUnmounted(() => { | @@ -389,11 +399,11 @@ onUnmounted(() => { | ||
| 389 | overflow: hidden; | 399 | overflow: hidden; |
| 390 | } | 400 | } |
| 391 | } | 401 | } |
| 392 | - .nullData{ | 402 | + .nullData { |
| 393 | display: flex; | 403 | display: flex; |
| 394 | justify-content: center; | 404 | justify-content: center; |
| 395 | align-items: center; | 405 | align-items: center; |
| 396 | - color:white; | 406 | + color: white; |
| 397 | height: 100%; | 407 | height: 100%; |
| 398 | width: 100%; | 408 | width: 100%; |
| 399 | background: #356b80; | 409 | background: #356b80; |
| @@ -35,6 +35,7 @@ import cloneDeep from 'lodash/cloneDeep' | @@ -35,6 +35,7 @@ import cloneDeep from 'lodash/cloneDeep' | ||
| 35 | import { useAssembleDataHooks } from '@/hooks/external/useAssembleData.hook' | 35 | import { useAssembleDataHooks } from '@/hooks/external/useAssembleData.hook' |
| 36 | import { SocketReceiveMessageType } from '@/store/external/modules/socketStore.d' | 36 | import { SocketReceiveMessageType } from '@/store/external/modules/socketStore.d' |
| 37 | import { CreateComponentGroupType, CreateComponentType } from '@/packages/index.d' | 37 | import { CreateComponentGroupType, CreateComponentType } from '@/packages/index.d' |
| 38 | +import { useEchartsMapLegend } from '@/hooks/external/useEchartLegendMapChinese.hook' | ||
| 38 | 39 | ||
| 39 | const props = defineProps({ | 40 | const props = defineProps({ |
| 40 | themeSetting: { | 41 | themeSetting: { |
| @@ -112,6 +113,7 @@ watch( | @@ -112,6 +113,7 @@ watch( | ||
| 112 | } | 113 | } |
| 113 | replaceMergeArr.value = ['series'] | 114 | replaceMergeArr.value = ['series'] |
| 114 | nextTick(() => { | 115 | nextTick(() => { |
| 116 | + useEchartsMapLegend(props.chartConfig, props.chartConfig.option.series) | ||
| 115 | replaceMergeArr.value = [] | 117 | replaceMergeArr.value = [] |
| 116 | }) | 118 | }) |
| 117 | } | 119 | } |
| @@ -244,6 +246,7 @@ const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, ne | @@ -244,6 +246,7 @@ const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, ne | ||
| 244 | } | 246 | } |
| 245 | }) | 247 | }) |
| 246 | // | 248 | // |
| 249 | + addPieInterval(newData) | ||
| 247 | updateVChart(newData) | 250 | updateVChart(newData) |
| 248 | }) | 251 | }) |
| 249 | 252 |
| @@ -35,6 +35,7 @@ import { useFullScreen } from '../../utls/fullScreen' | @@ -35,6 +35,7 @@ import { useFullScreen } from '../../utls/fullScreen' | ||
| 35 | import { useAssembleDataHooks } from '@/hooks/external/useAssembleData.hook' | 35 | import { useAssembleDataHooks } from '@/hooks/external/useAssembleData.hook' |
| 36 | import { SocketReceiveMessageType } from '@/store/external/modules/socketStore.d' | 36 | import { SocketReceiveMessageType } from '@/store/external/modules/socketStore.d' |
| 37 | import {CreateComponentGroupType, CreateComponentType} from '@/packages/index.d' | 37 | import {CreateComponentGroupType, CreateComponentType} from '@/packages/index.d' |
| 38 | +import { useEchartsMapLegend } from '@/hooks/external/useEchartLegendMapChinese.hook' | ||
| 38 | 39 | ||
| 39 | const props = defineProps({ | 40 | const props = defineProps({ |
| 40 | themeSetting: { | 41 | themeSetting: { |
| @@ -112,6 +113,7 @@ watch( | @@ -112,6 +113,7 @@ watch( | ||
| 112 | } | 113 | } |
| 113 | replaceMergeArr.value = ['series'] | 114 | replaceMergeArr.value = ['series'] |
| 114 | nextTick(() => { | 115 | nextTick(() => { |
| 116 | + useEchartsMapLegend(props.chartConfig, props.chartConfig.option.series) | ||
| 115 | replaceMergeArr.value = [] | 117 | replaceMergeArr.value = [] |
| 116 | }) | 118 | }) |
| 117 | } | 119 | } |
| @@ -243,10 +245,10 @@ const {vChartRef} = useChartDataFetch(props.chartConfig, useChartEditStore, (new | @@ -243,10 +245,10 @@ const {vChartRef} = useChartDataFetch(props.chartConfig, useChartEditStore, (new | ||
| 243 | } | 245 | } |
| 244 | }) | 246 | }) |
| 245 | // | 247 | // |
| 248 | + addPieInterval(newData) | ||
| 246 | updateVChart(newData) | 249 | updateVChart(newData) |
| 247 | }) | 250 | }) |
| 248 | 251 | ||
| 249 | - | ||
| 250 | onMounted(() => { | 252 | onMounted(() => { |
| 251 | seriesDataMaxLength = dataJson.source.length | 253 | seriesDataMaxLength = dataJson.source.length |
| 252 | if (props.chartConfig.option.isCarousel) { | 254 | if (props.chartConfig.option.isCarousel) { |
| @@ -41,6 +41,7 @@ import { useAssembleDataHooks } from '@/hooks/external/useAssembleData.hook' | @@ -41,6 +41,7 @@ import { useAssembleDataHooks } from '@/hooks/external/useAssembleData.hook' | ||
| 41 | import { SocketReceiveMessageType } from '@/store/external/modules/socketStore.d' | 41 | import { SocketReceiveMessageType } from '@/store/external/modules/socketStore.d' |
| 42 | import { useChartInteract } from '@/hooks/external/useChartSelectDeviceInteract.hook' | 42 | import { useChartInteract } from '@/hooks/external/useChartSelectDeviceInteract.hook' |
| 43 | import { getPacketIntervalByRange } from './helper' | 43 | import { getPacketIntervalByRange } from './helper' |
| 44 | +import { useEchartsMapLegend } from '@/hooks/external/useEchartLegendMapChinese.hook' | ||
| 44 | 45 | ||
| 45 | const props = defineProps({ | 46 | const props = defineProps({ |
| 46 | themeSetting: { | 47 | themeSetting: { |
| @@ -122,6 +123,7 @@ watch( | @@ -122,6 +123,7 @@ watch( | ||
| 122 | } | 123 | } |
| 123 | replaceMergeArr.value = ['series'] | 124 | replaceMergeArr.value = ['series'] |
| 124 | nextTick(() => { | 125 | nextTick(() => { |
| 126 | + useEchartsMapLegend(props.chartConfig, props.chartConfig.option.series) | ||
| 125 | replaceMergeArr.value = [] | 127 | replaceMergeArr.value = [] |
| 126 | }) | 128 | }) |
| 127 | } | 129 | } |
| @@ -254,6 +256,7 @@ const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (n | @@ -254,6 +256,7 @@ const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (n | ||
| 254 | } | 256 | } |
| 255 | }) | 257 | }) |
| 256 | // | 258 | // |
| 259 | + addPieInterval(newData) | ||
| 257 | updateVChart(newData) | 260 | updateVChart(newData) |
| 258 | }) | 261 | }) |
| 259 | 262 |
| @@ -35,6 +35,7 @@ import cloneDeep from 'lodash/cloneDeep' | @@ -35,6 +35,7 @@ import cloneDeep from 'lodash/cloneDeep' | ||
| 35 | import { useAssembleDataHooks } from '@/hooks/external/useAssembleData.hook' | 35 | import { useAssembleDataHooks } from '@/hooks/external/useAssembleData.hook' |
| 36 | import { SocketReceiveMessageType } from '@/store/external/modules/socketStore.d' | 36 | import { SocketReceiveMessageType } from '@/store/external/modules/socketStore.d' |
| 37 | import {CreateComponentGroupType, CreateComponentType} from '@/packages/index.d' | 37 | import {CreateComponentGroupType, CreateComponentType} from '@/packages/index.d' |
| 38 | +import { useEchartsMapLegend } from '@/hooks/external/useEchartLegendMapChinese.hook' | ||
| 38 | 39 | ||
| 39 | const props = defineProps({ | 40 | const props = defineProps({ |
| 40 | themeSetting: { | 41 | themeSetting: { |
| @@ -214,6 +215,7 @@ watch( | @@ -214,6 +215,7 @@ watch( | ||
| 214 | } | 215 | } |
| 215 | replaceMergeArr.value = ['series'] | 216 | replaceMergeArr.value = ['series'] |
| 216 | nextTick(() => { | 217 | nextTick(() => { |
| 218 | + useEchartsMapLegend(props.chartConfig, props.chartConfig.option.series) | ||
| 217 | replaceMergeArr.value = [] | 219 | replaceMergeArr.value = [] |
| 218 | }) | 220 | }) |
| 219 | } | 221 | } |
| @@ -273,6 +275,7 @@ const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, ne | @@ -273,6 +275,7 @@ const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, ne | ||
| 273 | } | 275 | } |
| 274 | }) | 276 | }) |
| 275 | // | 277 | // |
| 278 | + addPieInterval(newData) | ||
| 276 | updateVChart(newData) | 279 | updateVChart(newData) |
| 277 | }) | 280 | }) |
| 278 | 281 |
| @@ -8,7 +8,7 @@ export const includes = ['legend', 'xAxis', 'yAxis', 'grid'] | @@ -8,7 +8,7 @@ export const includes = ['legend', 'xAxis', 'yAxis', 'grid'] | ||
| 8 | export const seriesItem = { | 8 | export const seriesItem = { |
| 9 | type: 'line', | 9 | type: 'line', |
| 10 | label: { | 10 | label: { |
| 11 | - show: true, | 11 | + show: false, |
| 12 | position: 'top', | 12 | position: 'top', |
| 13 | color: '#fff', | 13 | color: '#fff', |
| 14 | fontSize: 12 | 14 | fontSize: 12 |
| 1 | <template> | 1 | <template> |
| 2 | - <v-chart | ||
| 3 | - ref="vChartRef" | ||
| 4 | - :init-options="initOptions" | ||
| 5 | - :theme="themeColor" | ||
| 6 | - :option="option" | ||
| 7 | - :manual-update="isPreview()" | 2 | + <v-chart ref="vChartRef" :init-options="initOptions" :theme="themeColor" :option="option" :manual-update="isPreview()" |
| 8 | :update-options="{ | 3 | :update-options="{ |
| 9 | replaceMerge: replaceMergeArr | 4 | replaceMerge: replaceMergeArr |
| 10 | - }" | ||
| 11 | - autoresize | ||
| 12 | - @mouseover="handleHighlight" | ||
| 13 | - @mouseout="handleDownplay" | ||
| 14 | - > | 5 | + }" autoresize @mouseover="handleHighlight" @mouseout="handleDownplay"> |
| 15 | </v-chart> | 6 | </v-chart> |
| 16 | </template> | 7 | </template> |
| 17 | 8 | ||
| @@ -186,6 +177,12 @@ watch( | @@ -186,6 +177,12 @@ watch( | ||
| 186 | for (let i = 0; i < dimensionsGap; i++) { | 177 | for (let i = 0; i < dimensionsGap; i++) { |
| 187 | seriesArr.push(cloneDeep(seriesItem)) | 178 | seriesArr.push(cloneDeep(seriesItem)) |
| 188 | } | 179 | } |
| 180 | + | ||
| 181 | + const { request } = props.chartConfig | ||
| 182 | + const { requestParams: { Params: { attrName } } } = request || {} | ||
| 183 | + seriesArr.forEach((item: any, index: number) => { | ||
| 184 | + item.name = attrName?.[index] | ||
| 185 | + }) | ||
| 189 | props.chartConfig.option.series.push(...seriesArr) | 186 | props.chartConfig.option.series.push(...seriesArr) |
| 190 | } | 187 | } |
| 191 | replaceMergeArr.value = ['series'] | 188 | replaceMergeArr.value = ['series'] |
| @@ -205,23 +202,29 @@ watch( | @@ -205,23 +202,29 @@ watch( | ||
| 205 | //fix 修复v-chart图表绑定联动组件视图不更新问题 | 202 | //fix 修复v-chart图表绑定联动组件视图不更新问题 |
| 206 | const updateVChart = (newData: SocketReceiveMessageType) => { | 203 | const updateVChart = (newData: SocketReceiveMessageType) => { |
| 207 | if (!newData) return | 204 | if (!newData) return |
| 208 | - const { option } = props.chartConfig | 205 | + const { option, request } = props.chartConfig |
| 206 | + const { requestParams: { Params: { attrName } } } = request || {} | ||
| 209 | const { dataset: overrideDataset } = option | 207 | const { dataset: overrideDataset } = option |
| 210 | const { dimensions } = overrideDataset | 208 | const { dimensions } = overrideDataset |
| 211 | if (!Array.isArray(dimensions)) return | 209 | if (!Array.isArray(dimensions)) return |
| 212 | const { data } = newData | 210 | const { data } = newData |
| 213 | - const { keys, record } = useAssembleDataHooks(data,dimensions) | 211 | + const { record } = useAssembleDataHooks(data, dimensions, (attrName as any)) |
| 214 | if (unref(realTimeList).length >= chartMaxDataPoint.value) { | 212 | if (unref(realTimeList).length >= chartMaxDataPoint.value) { |
| 215 | unref(realTimeList).splice(0, 1) | 213 | unref(realTimeList).splice(0, 1) |
| 216 | } | 214 | } |
| 217 | realTimeList.value.push(record) | 215 | realTimeList.value.push(record) |
| 218 | const dataset = { | 216 | const dataset = { |
| 219 | - dimensions: ['ts', ...keys], | 217 | + dimensions: ['ts', ...attrName], |
| 220 | source: toRaw(unref(realTimeList)) | 218 | source: toRaw(unref(realTimeList)) |
| 221 | } | 219 | } |
| 220 | + option.series.forEach((item: any, index: number) => { | ||
| 221 | + item.name = attrName?.[index] | ||
| 222 | + }) | ||
| 223 | + | ||
| 222 | vChartRef.value?.setOption({ | 224 | vChartRef.value?.setOption({ |
| 223 | - ...option.value, | ||
| 224 | - dataset | 225 | + ...option, |
| 226 | + dataset, | ||
| 227 | + legend: { data: attrName || [] } | ||
| 225 | }) | 228 | }) |
| 226 | } | 229 | } |
| 227 | const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, newData => { | 230 | const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, newData => { |
| @@ -3,9 +3,10 @@ | @@ -3,9 +3,10 @@ | ||
| 3 | * @param data {'wendu':[[xxxxxx,xxxx]]} | 3 | * @param data {'wendu':[[xxxxxx,xxxx]]} |
| 4 | * @returns keys:[xx,xx,xx] record:{'x':'xx'} | 4 | * @returns keys:[xx,xx,xx] record:{'x':'xx'} |
| 5 | */ | 5 | */ |
| 6 | +import { isNullOrUnDef } from '@/utils/external/is' | ||
| 6 | import dayjs from 'dayjs' | 7 | import dayjs from 'dayjs' |
| 7 | 8 | ||
| 8 | -export const useAssembleDataHooks = (data: Record<string, string | [number, string]>, dimensions: string[]) => { | 9 | +export const useAssembleDataHooks = (data: Record<string, string | [number, string]>, dimensions: string[],attrName?:string[]) => { |
| 9 | const formatValueToNumber = (value: string | number, defaultValue = 0) => | 10 | const formatValueToNumber = (value: string | number, defaultValue = 0) => |
| 10 | isNaN(value as number) ? defaultValue : Number(value) | 11 | isNaN(value as number) ? defaultValue : Number(value) |
| 11 | const tempObj: Recordable = {} | 12 | const tempObj: Recordable = {} |
| @@ -17,11 +18,12 @@ export const useAssembleDataHooks = (data: Record<string, string | [number, stri | @@ -17,11 +18,12 @@ export const useAssembleDataHooks = (data: Record<string, string | [number, stri | ||
| 17 | }) | 18 | }) |
| 18 | }) | 19 | }) |
| 19 | const keys = Object.keys(tempObj) | 20 | const keys = Object.keys(tempObj) |
| 20 | - const record = keys.reduce((prev, next) => { | 21 | + const record = keys.reduce((prev, next,index) => { |
| 21 | const [latest] = data[next] || [] | 22 | const [latest] = data[next] || [] |
| 23 | + if (isNullOrUnDef(latest)) return prev | ||
| 22 | const [ts, value] = latest as unknown as string[] | 24 | const [ts, value] = latest as unknown as string[] |
| 23 | //把值转为number类型 wendu:"23" 转为 wendu:23 | 25 | //把值转为number类型 wendu:"23" 转为 wendu:23 |
| 24 | - return { ...prev, ts: dayjs(ts).format('YYYY-MM-DD HH:mm:ss'), [next]: formatValueToNumber(value) } | 26 | + return { ...prev, ts: dayjs(ts).format('YYYY-MM-DD HH:mm:ss'),[ attrName![index]]: formatValueToNumber(value) } |
| 25 | }, {}) | 27 | }, {}) |
| 26 | 28 | ||
| 27 | return { | 29 | return { |
| @@ -136,6 +136,7 @@ const stopWatch = watch( | @@ -136,6 +136,7 @@ const stopWatch = watch( | ||
| 136 | // 预览 | 136 | // 预览 |
| 137 | useChartDataFetch(props.chartConfig, useChartEditStore, newData => { | 137 | useChartDataFetch(props.chartConfig, useChartEditStore, newData => { |
| 138 | const { data } = newData | 138 | const { data } = newData |
| 139 | + // 不是结构体 | ||
| 139 | if (Reflect.get(data, 'longitude') && Reflect.get(data, 'latitude')) { | 140 | if (Reflect.get(data, 'longitude') && Reflect.get(data, 'latitude')) { |
| 140 | //必须有经纬度 | 141 | //必须有经纬度 |
| 141 | for (let _ in data) { | 142 | for (let _ in data) { |
| @@ -143,6 +144,13 @@ useChartDataFetch(props.chartConfig, useChartEditStore, newData => { | @@ -143,6 +144,13 @@ useChartDataFetch(props.chartConfig, useChartEditStore, newData => { | ||
| 143 | viewControlPaths.value.push([Number(data['longitude'][0][1]), Number(data['latitude'][0][1])]) | 144 | viewControlPaths.value.push([Number(data['longitude'][0][1]), Number(data['latitude'][0][1])]) |
| 144 | } | 145 | } |
| 145 | renderLocaLayerLine(viewControlPaths.value) | 146 | renderLocaLayerLine(viewControlPaths.value) |
| 147 | + } else { | ||
| 148 | + // 序列化获取里面的经纬度 | ||
| 149 | + const values = Object.values(data) as string[][] | ||
| 150 | + const serializeValue = JSON.parse(values[0][0][1]) | ||
| 151 | + const { longitude, latitude } = serializeValue | ||
| 152 | + viewControlPaths.value.push([Number(longitude), Number(latitude)]) | ||
| 153 | + renderLocaLayerLine(viewControlPaths.value) | ||
| 146 | } | 154 | } |
| 147 | stopWatch() | 155 | stopWatch() |
| 148 | }) | 156 | }) |
| 1 | <script lang="ts" setup name="SelectCity"> | 1 | <script lang="ts" setup name="SelectCity"> |
| 2 | -import { onMounted, reactive } from 'vue' | 2 | +import { onMounted, reactive, nextTick, ref } from 'vue' |
| 3 | import { getAreaList } from '@/api/external/common/index' | 3 | import { getAreaList } from '@/api/external/common/index' |
| 4 | -import { areaEnum } from '../config' | 4 | +import { areaEnum, ifSpecialCity } from '../config' |
| 5 | 5 | ||
| 6 | const props = defineProps({ | 6 | const props = defineProps({ |
| 7 | drillingIn: { | 7 | drillingIn: { |
| @@ -25,45 +25,67 @@ const selectValues = reactive({ | @@ -25,45 +25,67 @@ const selectValues = reactive({ | ||
| 25 | provinceValue: 'china', | 25 | provinceValue: 'china', |
| 26 | cityValue: null, | 26 | cityValue: null, |
| 27 | countyValue: null, | 27 | countyValue: null, |
| 28 | - levelStr: areaEnum.COUNTRY | 28 | + levelStr: areaEnum.COUNTRY, |
| 29 | + areaName: '' | ||
| 29 | }) | 30 | }) |
| 30 | 31 | ||
| 31 | const getAreaLists = async (level = areaEnum.PROVINCE, parentId = 1) => { | 32 | const getAreaLists = async (level = areaEnum.PROVINCE, parentId = 1) => { |
| 32 | const resp = await getAreaList({ | 33 | const resp = await getAreaList({ |
| 33 | level, | 34 | level, |
| 34 | - parentId | 35 | + parentId:(parentId as any)==='china'?1:parentId |
| 35 | }) | 36 | }) |
| 36 | if (!resp) return [] | 37 | if (!resp) return [] |
| 37 | - return resp.map((item: any) => ({ label: item.name, value: item.code })) | 38 | + return resp.map((item: Recordable) => ({ label: item.name, value: item.code,parentId:item.parentId })) |
| 38 | } | 39 | } |
| 39 | 40 | ||
| 40 | onMounted(async () => { | 41 | onMounted(async () => { |
| 41 | selectOptions.provinceOptions = await getAreaLists() | 42 | selectOptions.provinceOptions = await getAreaLists() |
| 42 | - ;(selectOptions.provinceOptions as never as any).unshift({ | 43 | + ;(selectOptions.provinceOptions as never as Recordable[]).unshift({ |
| 43 | label: '中国', | 44 | label: '中国', |
| 44 | value: 'china' | 45 | value: 'china' |
| 45 | }) | 46 | }) |
| 46 | - onHandleSelectProvince(props.optionData?.mapRegion.saveSelect['provinceValue']) | 47 | + onHandleSelectProvince(props.optionData?.mapRegion.saveSelect['provinceValue'], {}) |
| 47 | for (let i in selectValues) Reflect.set(selectValues, i, props.optionData?.mapRegion.saveSelect[i]) | 48 | for (let i in selectValues) Reflect.set(selectValues, i, props.optionData?.mapRegion.saveSelect[i]) |
| 48 | }) | 49 | }) |
| 49 | 50 | ||
| 50 | -const onHandleSelectProvince = async (value: number | string) => { | ||
| 51 | - selectValues.cityValue = null | 51 | + |
| 52 | + | ||
| 53 | +const disabledCity = ref<boolean>(false)//直辖市禁用下面省份选择 | ||
| 54 | +const onHandleSelectProvince = async (value: number | string, options: Recordable) => { | ||
| 55 | + selectValues.cityValue = null | ||
| 52 | selectValues.countyValue = null | 56 | selectValues.countyValue = null |
| 53 | - if (value === 'china') return (selectValues.levelStr = areaEnum.COUNTRY) | ||
| 54 | - selectOptions.cityOptions = await getAreaLists(areaEnum.CITY, value as any) | 57 | + if (value === 'china') { |
| 58 | + disabledCity.value = false | ||
| 59 | + selectValues.provinceValue = 'china' | ||
| 60 | + selectOptions.cityOptions = [] | ||
| 61 | + selectValues.areaName = '' | ||
| 62 | + selectValues.levelStr= areaEnum.COUNTRY | ||
| 63 | + return | ||
| 64 | + } | ||
| 65 | + const cityOptions = await getAreaLists(areaEnum.CITY, value as number) | ||
| 66 | + selectOptions.cityOptions = cityOptions | ||
| 55 | selectValues.levelStr = areaEnum.PROVINCE | 67 | selectValues.levelStr = areaEnum.PROVINCE |
| 68 | + selectValues.areaName = options.label | ||
| 69 | + if(ifSpecialCity(value)){//直辖市的话就不能跟省份的逻辑一样了 | ||
| 70 | + selectOptions.cityOptions = cityOptions.map((item:any)=>({...item,value:item.parentId})) | ||
| 71 | + disabledCity.value = true | ||
| 72 | + return | ||
| 73 | + } | ||
| 74 | + disabledCity.value = false | ||
| 56 | } | 75 | } |
| 57 | 76 | ||
| 58 | -const onHandleSelectCity = async (value: number) => { | 77 | +const onHandleSelectCity = async (value: number, options: Recordable) => { |
| 59 | selectValues.countyValue = null | 78 | selectValues.countyValue = null |
| 60 | selectOptions.countryOptions = await getAreaLists(areaEnum.COUNTY, value) | 79 | selectOptions.countryOptions = await getAreaLists(areaEnum.COUNTY, value) |
| 61 | selectValues.levelStr = areaEnum.CITY | 80 | selectValues.levelStr = areaEnum.CITY |
| 81 | + selectValues.areaName = options.label | ||
| 62 | } | 82 | } |
| 63 | 83 | ||
| 64 | -const onHandleSubmit = () => { | 84 | +const onHandleSubmit = async () => { |
| 85 | + await nextTick() | ||
| 65 | emits('submit', selectValues) | 86 | emits('submit', selectValues) |
| 66 | } | 87 | } |
| 88 | + | ||
| 67 | const resetValue = () => { | 89 | const resetValue = () => { |
| 68 | selectValues.provinceValue = 'china' | 90 | selectValues.provinceValue = 'china' |
| 69 | selectValues.cityValue = null | 91 | selectValues.cityValue = null |
| @@ -72,6 +94,7 @@ const resetValue = () => { | @@ -72,6 +94,7 @@ const resetValue = () => { | ||
| 72 | selectOptions.cityOptions = [] | 94 | selectOptions.cityOptions = [] |
| 73 | selectOptions.countryOptions = [] | 95 | selectOptions.countryOptions = [] |
| 74 | } | 96 | } |
| 97 | + | ||
| 75 | defineExpose({ | 98 | defineExpose({ |
| 76 | resetValue | 99 | resetValue |
| 77 | }) | 100 | }) |
| @@ -87,6 +110,7 @@ defineExpose({ | @@ -87,6 +110,7 @@ defineExpose({ | ||
| 87 | /> | 110 | /> |
| 88 | <n-select | 111 | <n-select |
| 89 | v-if="!props.drillingIn" | 112 | v-if="!props.drillingIn" |
| 113 | + :disabled="disabledCity" | ||
| 90 | @change="onHandleSelectCity" | 114 | @change="onHandleSelectCity" |
| 91 | placeholder="请选择城市" | 115 | placeholder="请选择城市" |
| 92 | v-model:value="selectValues.cityValue" | 116 | v-model:value="selectValues.cityValue" |
| @@ -4,6 +4,7 @@ import { chartInitConfig } from '@/settings/designSetting' | @@ -4,6 +4,7 @@ import { chartInitConfig } from '@/settings/designSetting' | ||
| 4 | import { CreateComponentType } from '@/packages/index.d' | 4 | import { CreateComponentType } from '@/packages/index.d' |
| 5 | import cloneDeep from 'lodash/cloneDeep' | 5 | import cloneDeep from 'lodash/cloneDeep' |
| 6 | import dataMaps from './data.json' | 6 | import dataMaps from './data.json' |
| 7 | +import { getAreaList } from '@/api/external/common' | ||
| 7 | 8 | ||
| 8 | //省市区枚举 | 9 | //省市区枚举 |
| 9 | export const enum areaEnum { | 10 | export const enum areaEnum { |
| @@ -16,19 +17,20 @@ export const enum areaEnum { | @@ -16,19 +17,20 @@ export const enum areaEnum { | ||
| 16 | } | 17 | } |
| 17 | 18 | ||
| 18 | export interface regionInfo { | 19 | export interface regionInfo { |
| 19 | - provinceValue:string | ||
| 20 | - cityValue: string|null | ||
| 21 | - countyValue: string|null | ||
| 22 | - levelStr:areaEnum | 20 | + provinceValue: string |
| 21 | + cityValue: string | null | ||
| 22 | + countyValue: string | null | ||
| 23 | + levelStr: areaEnum | ||
| 24 | + areaName: string | ||
| 23 | } | 25 | } |
| 24 | 26 | ||
| 25 | type itemOption = { | 27 | type itemOption = { |
| 26 | - label:string | ||
| 27 | - value:string | 28 | + label: string |
| 29 | + value: string | ||
| 28 | } | 30 | } |
| 29 | -export interface regionOption{ | ||
| 30 | - provinceOptions: itemOption[], | ||
| 31 | - cityOptions: itemOption[], | 31 | +export interface regionOption { |
| 32 | + provinceOptions: itemOption[] | ||
| 33 | + cityOptions: itemOption[] | ||
| 32 | countryOptions: itemOption[] | 34 | countryOptions: itemOption[] |
| 33 | } | 35 | } |
| 34 | 36 | ||
| @@ -36,18 +38,22 @@ export interface regionOption{ | @@ -36,18 +38,22 @@ export interface regionOption{ | ||
| 36 | export interface historyParentType { | 38 | export interface historyParentType { |
| 37 | adcode: number | 39 | adcode: number |
| 38 | level: string | 40 | level: string |
| 41 | + areaName: string | ||
| 39 | } | 42 | } |
| 40 | 43 | ||
| 41 | -export interface backMapLevel{ | ||
| 42 | - (levelStr:string): boolean | ||
| 43 | - (level:string): boolean | ||
| 44 | - (): void | 44 | +export interface backMapLevel { |
| 45 | + (str: string): boolean | ||
| 45 | (): void | 46 | (): void |
| 46 | } | 47 | } |
| 47 | 48 | ||
| 49 | +export interface levelFunc { | ||
| 50 | + (str: string): boolean | ||
| 51 | +} | ||
| 52 | + | ||
| 48 | //数据源接口 | 53 | //数据源接口 |
| 49 | export interface dataPointI { | 54 | export interface dataPointI { |
| 50 | name: string | 55 | name: string |
| 56 | + city_name: string | ||
| 51 | value: number[] | 57 | value: number[] |
| 52 | adcode: number | 58 | adcode: number |
| 53 | height: number | 59 | height: number |
| @@ -59,83 +65,128 @@ export interface dataPointI { | @@ -59,83 +65,128 @@ export interface dataPointI { | ||
| 59 | } | 65 | } |
| 60 | } | 66 | } |
| 61 | 67 | ||
| 68 | +//地区上级对应配置 | ||
| 69 | +export const regionMapParentArea = { | ||
| 70 | + PROVINCE: areaEnum.COUNTRY, //省份的上一级 中国 | ||
| 71 | + CITY: areaEnum.PROVINCE, //城市的上一级 省份 | ||
| 72 | + COUNTY: areaEnum.CITY, //县或者区的上一级 城市 | ||
| 73 | + TOWN: areaEnum.COUNTY //镇的上一级 县或者区 | ||
| 74 | +} | ||
| 75 | + | ||
| 76 | + | ||
| 77 | + | ||
| 62 | export const includes = [] | 78 | export const includes = [] |
| 63 | 79 | ||
| 80 | +// 特殊处理安徽省的下钻 | ||
| 81 | +export const specialTreatmentAnhui = [ | ||
| 82 | + '合肥市', | ||
| 83 | + '马鞍山市', | ||
| 84 | + '淮北市', | ||
| 85 | + '宿州市', | ||
| 86 | + '阜阳市', | ||
| 87 | + '蚌埠市', | ||
| 88 | + '淮南市', | ||
| 89 | + '滁州市', | ||
| 90 | + '六安市', | ||
| 91 | + '巢湖市', | ||
| 92 | + '芜湖市', | ||
| 93 | + '亳州市', | ||
| 94 | + '安庆市', | ||
| 95 | + '池州市', | ||
| 96 | + '铜陵市', | ||
| 97 | + '宣城市', | ||
| 98 | + '黄山市' | ||
| 99 | +] | ||
| 100 | + | ||
| 64 | export const option = { | 101 | export const option = { |
| 65 | iconColor: 'black', | 102 | iconColor: 'black', |
| 66 | showIcon: false, | 103 | showIcon: false, |
| 67 | iconDistanceRight: 20, | 104 | iconDistanceRight: 20, |
| 68 | iconDistanceTop: 20, | 105 | iconDistanceTop: 20, |
| 69 | - drillingIn: false, | 106 | + drillingIn: true, |
| 70 | dataset: dataMaps, | 107 | dataset: dataMaps, |
| 108 | + isShowExecute:false, | ||
| 71 | saveClickRegion: { | 109 | saveClickRegion: { |
| 72 | level: '' | 110 | level: '' |
| 73 | }, | 111 | }, |
| 74 | mapRegion: { | 112 | mapRegion: { |
| 75 | adcode: 'china', | 113 | adcode: 'china', |
| 76 | showHainanIsLands: true, | 114 | showHainanIsLands: true, |
| 115 | + areaName: '', | ||
| 77 | saveSelect: { | 116 | saveSelect: { |
| 78 | levelStr: areaEnum.COUNTRY, | 117 | levelStr: areaEnum.COUNTRY, |
| 79 | - cityValue:null, | ||
| 80 | - countyValue:null, | ||
| 81 | - provinceValue:'china' | 118 | + cityValue: null, |
| 119 | + countyValue: null, | ||
| 120 | + provinceValue: 'china', | ||
| 121 | + areaName: '' | ||
| 82 | } | 122 | } |
| 83 | }, | 123 | }, |
| 84 | tooltip: { | 124 | tooltip: { |
| 85 | show: true | 125 | show: true |
| 86 | }, | 126 | }, |
| 127 | + //三维地图有两种,一种是geo3D,另一种是map3D,但是如果使用geo3D,地图点击获取不到点击区域name | ||
| 87 | geo3D: { | 128 | geo3D: { |
| 88 | show: false, // 隐藏该层,为true时会导致出现两个地图 | 129 | show: false, // 隐藏该层,为true时会导致出现两个地图 |
| 89 | - map: 'centerMap', | 130 | + map: '', |
| 90 | roam: true, | 131 | roam: true, |
| 91 | - regionHeight: 0, | ||
| 92 | - emphasis: { | ||
| 93 | - label: { | ||
| 94 | - show: true, | ||
| 95 | - formatter: function (params: Recordable) { | ||
| 96 | - return params.data.name ? params.data.name : ' ' | ||
| 97 | - }, | ||
| 98 | - textStyle: { | ||
| 99 | - color: '#000', | ||
| 100 | - fontSize: 14 | ||
| 101 | - } | ||
| 102 | - }, | ||
| 103 | - itemStyle: { | ||
| 104 | - color: '#ff0' | ||
| 105 | - } | 132 | + viewControl:{ |
| 133 | + distance:100 | ||
| 106 | } | 134 | } |
| 107 | }, | 135 | }, |
| 108 | series: [ | 136 | series: [ |
| 109 | { | 137 | { |
| 110 | type: 'map3D', | 138 | type: 'map3D', |
| 111 | - map: 'centerMap', | ||
| 112 | - name: 'centerMap', | ||
| 113 | - regionHeight: 3, | 139 | + map: '', |
| 140 | + name: '', | ||
| 141 | + regionHeight: 0, | ||
| 114 | label: { | 142 | label: { |
| 115 | show: true, | 143 | show: true, |
| 116 | formatter: function (params: Recordable) { | 144 | formatter: function (params: Recordable) { |
| 117 | return params.data.name ? params.data.name : ' ' | 145 | return params.data.name ? params.data.name : ' ' |
| 118 | }, | 146 | }, |
| 119 | textStyle: { | 147 | textStyle: { |
| 120 | - color: '#fff', | 148 | + color: '#ffffffff', |
| 121 | fontSize: 14 | 149 | fontSize: 14 |
| 122 | } | 150 | } |
| 123 | }, | 151 | }, |
| 124 | itemStyle: { | 152 | itemStyle: { |
| 125 | - color: 'green', | 153 | + color: '#3c7effff', //背景颜色 |
| 154 | + opacity: 1, | ||
| 126 | borderWidth: 0.8, | 155 | borderWidth: 0.8, |
| 127 | - borderColor: 'blue' | 156 | + borderColor: '#51d6a9FF' |
| 128 | }, | 157 | }, |
| 129 | - data: [] | 158 | + emphasis: { |
| 159 | + // 鼠标hover 高亮时图形和标签的样式 (当鼠标放上去时 label和itemStyle 的样式) | ||
| 160 | + label: { | ||
| 161 | + // label高亮时的配置 | ||
| 162 | + show: true, | ||
| 163 | + textStyle: { | ||
| 164 | + color: '#57c3c2ff', | ||
| 165 | + fontSize: 14 | ||
| 166 | + } | ||
| 167 | + }, | ||
| 168 | + itemStyle: { | ||
| 169 | + color: '#1ba784ff' | ||
| 170 | + } | ||
| 171 | + }, | ||
| 172 | + data: [], | ||
| 173 | + viewControl: { | ||
| 174 | + projection: 'perspective' | ||
| 175 | + } | ||
| 130 | }, | 176 | }, |
| 131 | { | 177 | { |
| 132 | - name: 'scatter3D', | ||
| 133 | - type: 'scatter3D', | 178 | + name: 'bar3D', |
| 179 | + type: 'bar3D', | ||
| 134 | coordinateSystem: 'geo3D', | 180 | coordinateSystem: 'geo3D', |
| 135 | - symbol: 'circle', | ||
| 136 | - symbolSize: 20, | ||
| 137 | - animation: true, | ||
| 138 | - data: dataMaps | 181 | + // 倒角尺寸 |
| 182 | + bevelSize: 0, | ||
| 183 | + minHeight: 5, | ||
| 184 | + shading: 'lambert', | ||
| 185 | + barSize: 1, | ||
| 186 | + itemStyle: { | ||
| 187 | + color: '#4482B1FF' | ||
| 188 | + }, | ||
| 189 | + data: [] | ||
| 139 | } | 190 | } |
| 140 | ] | 191 | ] |
| 141 | } | 192 | } |
| @@ -149,3 +200,544 @@ export default class Config extends PublicConfigClass implements CreateComponent | @@ -149,3 +200,544 @@ export default class Config extends PublicConfigClass implements CreateComponent | ||
| 149 | public chartConfig = cloneDeep(AddThreeDimensionalMapConfig) | 200 | public chartConfig = cloneDeep(AddThreeDimensionalMapConfig) |
| 150 | public option = echartOptionProfixHandle(option, includes) | 201 | public option = echartOptionProfixHandle(option, includes) |
| 151 | } | 202 | } |
| 203 | + | ||
| 204 | +export const ifSpecialCity = (value:string|number) => { | ||
| 205 | + if(value==110000 || value ==120000 || value ==500000 || value==310000 || value==810000 || value==820000){//直辖市的话就不能跟省份的逻辑一样了 | ||
| 206 | + return true | ||
| 207 | + } | ||
| 208 | + return false | ||
| 209 | +} | ||
| 210 | + | ||
| 211 | + | ||
| 212 | + | ||
| 213 | +//循环获取直辖市下面得区县数据 | ||
| 214 | + | ||
| 215 | +export const getAreaLists = async (level = areaEnum.PROVINCE as any, parentId = 1) => { | ||
| 216 | + const resp = await getAreaList({ | ||
| 217 | + level, | ||
| 218 | + parentId:(parentId as any)=='china'?1:parentId | ||
| 219 | + }) | ||
| 220 | + if (!resp) return [] | ||
| 221 | + return resp.map((item: Recordable) => ({ label: item.name, value: item.name, adcode: item.code })) | ||
| 222 | +} | ||
| 223 | + | ||
| 224 | +export const allFetch = (arr:any,items:string) => { | ||
| 225 | + return Promise.all( | ||
| 226 | + arr.map(async(item:any)=>{ | ||
| 227 | + try{ | ||
| 228 | + const values = await getAreaLists(areaEnum.COUNTY, item[items] as any) | ||
| 229 | + return {...values} | ||
| 230 | + }catch(err){ | ||
| 231 | + console.log(err,'err') | ||
| 232 | + return | ||
| 233 | + } | ||
| 234 | + }) | ||
| 235 | + ) | ||
| 236 | +} | ||
| 237 | + | ||
| 238 | + | ||
| 239 | +// 缩放配置文件 | ||
| 240 | +export const setScale = (adcode: string | number) => { | ||
| 241 | + switch (adcode) { | ||
| 242 | + case 'china': | ||
| 243 | + return { distance: 100 } | ||
| 244 | + case '110000': | ||
| 245 | + return { distance: 150 } | ||
| 246 | + case '120000': | ||
| 247 | + return { distance: 190 } | ||
| 248 | + case '130000': | ||
| 249 | + return { distance: 165 } | ||
| 250 | + case '130200': | ||
| 251 | + return { distance: 135 } | ||
| 252 | + case '130300': | ||
| 253 | + return { distance: 135 } | ||
| 254 | + case '130400': | ||
| 255 | + return { distance: 130 } | ||
| 256 | + case '130500': | ||
| 257 | + return { distance: 130 } | ||
| 258 | + case '130700': | ||
| 259 | + return { distance: 160 } | ||
| 260 | + case '131000': | ||
| 261 | + return { distance: 200 } | ||
| 262 | + case '131100': | ||
| 263 | + return { distance: 135 } | ||
| 264 | + case '140000': | ||
| 265 | + return { distance: 216 } | ||
| 266 | + case '140200': | ||
| 267 | + return { distance: 140 } | ||
| 268 | + case '140300': | ||
| 269 | + return { distance: 150 } | ||
| 270 | + case '140400': | ||
| 271 | + return { distance: 150 } | ||
| 272 | + case '140600': | ||
| 273 | + return { distance: 135 } | ||
| 274 | + case '140700': | ||
| 275 | + return { distance: 135 } | ||
| 276 | + case '140800': | ||
| 277 | + return { distance: 145 } | ||
| 278 | + case '141000': | ||
| 279 | + return { distance: 140 } | ||
| 280 | + case '141100': | ||
| 281 | + return { distance: 165 } | ||
| 282 | + case '150000': | ||
| 283 | + return { distance: 130 } | ||
| 284 | + case '150100': | ||
| 285 | + return { distance: 150 } | ||
| 286 | + case '150300': | ||
| 287 | + return { distance: 240 } | ||
| 288 | + case '150400': | ||
| 289 | + return { distance: 130 } | ||
| 290 | + case '150500': | ||
| 291 | + return { distance: 130 } | ||
| 292 | + case '150600': | ||
| 293 | + return { distance: 130 } | ||
| 294 | + case '210000': | ||
| 295 | + return { distance: 130 } | ||
| 296 | + case '210100': | ||
| 297 | + return { distance: 165 } | ||
| 298 | + case '210200': | ||
| 299 | + return { distance: 135 } | ||
| 300 | + case '210300': | ||
| 301 | + return { distance: 155 } | ||
| 302 | + case '210600': | ||
| 303 | + return { distance: 145 } | ||
| 304 | + case '210800': | ||
| 305 | + return { distance: 150 } | ||
| 306 | + case '211200': | ||
| 307 | + return { distance: 150 } | ||
| 308 | + case '211300': | ||
| 309 | + return { distance: 150 } | ||
| 310 | + case '220100': | ||
| 311 | + return { distance: 130 } | ||
| 312 | + case '220200': | ||
| 313 | + return { distance: 145 } | ||
| 314 | + case '220400': | ||
| 315 | + return { distance: 145 } | ||
| 316 | + case '220500': | ||
| 317 | + return { distance: 225 } | ||
| 318 | + case '220600': | ||
| 319 | + return { distance: 155 } | ||
| 320 | + case '230600': | ||
| 321 | + return { distance: 195 } | ||
| 322 | + case '230700': | ||
| 323 | + return { distance: 155 } | ||
| 324 | + case '231000': | ||
| 325 | + return { distance: 160 } | ||
| 326 | + case '310000': | ||
| 327 | + return { distance: 135 } | ||
| 328 | + case '320000': | ||
| 329 | + return { distance: 145 } | ||
| 330 | + case '320100': | ||
| 331 | + return { distance: 240 } | ||
| 332 | + case '320200': | ||
| 333 | + return { distance: 155 } | ||
| 334 | + case '320400': | ||
| 335 | + return { distance: 145 } | ||
| 336 | + case '320500': | ||
| 337 | + return { distance: 145 } | ||
| 338 | + case '320600': | ||
| 339 | + return { distance: 145 } | ||
| 340 | + case '320800': | ||
| 341 | + return { distance: 160 } | ||
| 342 | + case '320900': | ||
| 343 | + return { distance: 180 } | ||
| 344 | + case '321000': | ||
| 345 | + return { distance: 200 } | ||
| 346 | + case '321100': | ||
| 347 | + return { distance: 135 } | ||
| 348 | + case '321200': | ||
| 349 | + return { distance: 200 } | ||
| 350 | + case '321300': | ||
| 351 | + return { distance: 160 } | ||
| 352 | + case '330000': | ||
| 353 | + return { distance: 135 } | ||
| 354 | + case '330100': | ||
| 355 | + return { distance: 135 } | ||
| 356 | + case '330200': | ||
| 357 | + return { distance: 135 } | ||
| 358 | + case '330300': | ||
| 359 | + return { distance: 140 } | ||
| 360 | + case '330400': | ||
| 361 | + return { distance: 140 } | ||
| 362 | + case '330500': | ||
| 363 | + return { distance: 135 } | ||
| 364 | + case '330600': | ||
| 365 | + return { distance: 145 } | ||
| 366 | + case '330800': | ||
| 367 | + return { distance: 150 } | ||
| 368 | + case '331100': | ||
| 369 | + return { distance: 135 } | ||
| 370 | + case '340000': | ||
| 371 | + return { distance: 170 } | ||
| 372 | + case '340100': | ||
| 373 | + return { distance: 175 } | ||
| 374 | + case '340300': | ||
| 375 | + return { distance: 130 } | ||
| 376 | + case '340400': | ||
| 377 | + return { distance: 190 } | ||
| 378 | + case '340600': | ||
| 379 | + return { distance: 220 } | ||
| 380 | + case '340800': | ||
| 381 | + return { distance: 160 } | ||
| 382 | + case '341200': | ||
| 383 | + return { distance: 135 } | ||
| 384 | + case '341300': | ||
| 385 | + return { distance: 130 } | ||
| 386 | + case '341500': | ||
| 387 | + return { distance: 145 } | ||
| 388 | + case '341600': | ||
| 389 | + return { distance: 160 } | ||
| 390 | + case '341700': | ||
| 391 | + return { distance: 155 } | ||
| 392 | + case '350000': | ||
| 393 | + return { distance: 150} | ||
| 394 | + case '350200': | ||
| 395 | + return { distance: 140} | ||
| 396 | + case '350500': | ||
| 397 | + return { distance: 135} | ||
| 398 | + case '350600': | ||
| 399 | + return { distance: 190} | ||
| 400 | + case '350900': | ||
| 401 | + return { distance: 140} | ||
| 402 | + case '360000': | ||
| 403 | + return { distance: 190} | ||
| 404 | + case '360100': | ||
| 405 | + return { distance: 145} | ||
| 406 | + case '360200': | ||
| 407 | + return { distance: 225} | ||
| 408 | + case '360300': | ||
| 409 | + return { distance: 215} | ||
| 410 | + case '360500': | ||
| 411 | + return { distance: 135} | ||
| 412 | + case '360600': | ||
| 413 | + return { distance: 175} | ||
| 414 | + case '360700': | ||
| 415 | + return { distance: 175} | ||
| 416 | + case '360800': | ||
| 417 | + return { distance: 145} | ||
| 418 | + case '360900': | ||
| 419 | + return { distance: 135} | ||
| 420 | + case '361000': | ||
| 421 | + return { distance: 170} | ||
| 422 | + case '361100': | ||
| 423 | + return { distance: 140} | ||
| 424 | + case '370000': | ||
| 425 | + return { distance: 135 } | ||
| 426 | + case '370100': | ||
| 427 | + return { distance: 165 } | ||
| 428 | + case '370200': | ||
| 429 | + return { distance: 165 } | ||
| 430 | + case '370300': | ||
| 431 | + return { distance: 210 } | ||
| 432 | + case '370400': | ||
| 433 | + return { distance: 150 } | ||
| 434 | + case '370500': | ||
| 435 | + return { distance: 150 } | ||
| 436 | + case '370800': | ||
| 437 | + return { distance: 135 } | ||
| 438 | + case '371100': | ||
| 439 | + return { distance: 140 } | ||
| 440 | + case '371300': | ||
| 441 | + return { distance: 150 } | ||
| 442 | + case '371400': | ||
| 443 | + return { distance: 130 } | ||
| 444 | + case '371500': | ||
| 445 | + return { distance: 150 } | ||
| 446 | + case '371600': | ||
| 447 | + return { distance: 200 } | ||
| 448 | + case '371700': | ||
| 449 | + return { distance: 180 } | ||
| 450 | + case '410100': | ||
| 451 | + return { distance: 135 } | ||
| 452 | + case '410200': | ||
| 453 | + return { distance: 140 } | ||
| 454 | + case '410300': | ||
| 455 | + return { distance: 140 } | ||
| 456 | + case '410400': | ||
| 457 | + return { distance: 155 } | ||
| 458 | + case '410500': | ||
| 459 | + return { distance: 145 } | ||
| 460 | + case '410800': | ||
| 461 | + return { distance: 140 } | ||
| 462 | + case '410900': | ||
| 463 | + return { distance: 145 } | ||
| 464 | + case '411000': | ||
| 465 | + return { distance: 140 } | ||
| 466 | + case '411100': | ||
| 467 | + return { distance: 155 } | ||
| 468 | + case '411200': | ||
| 469 | + return { distance: 140 } | ||
| 470 | + case '411300': | ||
| 471 | + return { distance: 140 } | ||
| 472 | + case '411400': | ||
| 473 | + return { distance: 135 } | ||
| 474 | + case '411700': | ||
| 475 | + return { distance: 130 } | ||
| 476 | + case '420000': | ||
| 477 | + return { distance: 145 } | ||
| 478 | + case '420100': | ||
| 479 | + return { distance: 160 } | ||
| 480 | + case '420300': | ||
| 481 | + return { distance: 130 } | ||
| 482 | + case '420500': | ||
| 483 | + return { distance: 155 } | ||
| 484 | + case '420700': | ||
| 485 | + return { distance: 170 } | ||
| 486 | + case '420900': | ||
| 487 | + return { distance: 180 } | ||
| 488 | + case '421100': | ||
| 489 | + return { distance: 180 } | ||
| 490 | + case '421200': | ||
| 491 | + return { distance: 150 } | ||
| 492 | + case '421300': | ||
| 493 | + return { distance: 165 } | ||
| 494 | + case '422800': | ||
| 495 | + return { distance: 150 } | ||
| 496 | + case '430000': | ||
| 497 | + return { distance: 155 } | ||
| 498 | + case '430200': | ||
| 499 | + return { distance: 250 } | ||
| 500 | + case '430600': | ||
| 501 | + return { distance: 155 } | ||
| 502 | + case '430700': | ||
| 503 | + return { distance: 155 } | ||
| 504 | + case '430900': | ||
| 505 | + return { distance: 145 } | ||
| 506 | + case '431000': | ||
| 507 | + return { distance: 150 } | ||
| 508 | + case '431100': | ||
| 509 | + return { distance: 235 } | ||
| 510 | + case '431200': | ||
| 511 | + return { distance: 195 } | ||
| 512 | + case '431300': | ||
| 513 | + return { distance: 135 } | ||
| 514 | + case '433100': | ||
| 515 | + return { distance: 220 } | ||
| 516 | + case '440000': | ||
| 517 | + return { distance: 165 } | ||
| 518 | + case '440100': | ||
| 519 | + return { distance: 185 } | ||
| 520 | + case '440300': | ||
| 521 | + return { distance: 135 } | ||
| 522 | + case '440400': | ||
| 523 | + return { distance: 135 } | ||
| 524 | + case '440500': | ||
| 525 | + return { distance: 140 } | ||
| 526 | + case '440600': | ||
| 527 | + return { distance: 180 } | ||
| 528 | + case '440700': | ||
| 529 | + return { distance: 150 } | ||
| 530 | + case '440800': | ||
| 531 | + return { distance: 190 } | ||
| 532 | + case '440900': | ||
| 533 | + return { distance: 160 } | ||
| 534 | + case '441200': | ||
| 535 | + return { distance: 165 } | ||
| 536 | + case '441400': | ||
| 537 | + return { distance: 160 } | ||
| 538 | + case '441600': | ||
| 539 | + return { distance: 185 } | ||
| 540 | + case '441700': | ||
| 541 | + return { distance: 180 } | ||
| 542 | + case '445100': | ||
| 543 | + return { distance: 170 } | ||
| 544 | + case '445200': | ||
| 545 | + return { distance: 160 } | ||
| 546 | + case '445300': | ||
| 547 | + return { distance: 130 } | ||
| 548 | + case '450100': | ||
| 549 | + return { distance: 135 } | ||
| 550 | + case '450200': | ||
| 551 | + return { distance: 195 } | ||
| 552 | + case '450300': | ||
| 553 | + return { distance: 175 } | ||
| 554 | + case '450400': | ||
| 555 | + return { distance: 195 } | ||
| 556 | + case '450600': | ||
| 557 | + return { distance: 155 } | ||
| 558 | + case '450800': | ||
| 559 | + return { distance: 165 } | ||
| 560 | + case '450900': | ||
| 561 | + return { distance: 165 } | ||
| 562 | + case '451000': | ||
| 563 | + return { distance: 135 } | ||
| 564 | + case '451100': | ||
| 565 | + return { distance: 145 } | ||
| 566 | + case '451400': | ||
| 567 | + return { distance: 165 } | ||
| 568 | + case '460100': | ||
| 569 | + return { distance: 155 } | ||
| 570 | + case '500000': | ||
| 571 | + return { distance: 140 } | ||
| 572 | + case '510000': | ||
| 573 | + return { distance: 115 } | ||
| 574 | + case '510100': | ||
| 575 | + return { distance: 135 } | ||
| 576 | + case '510300': | ||
| 577 | + return { distance: 145 } | ||
| 578 | + case '510400': | ||
| 579 | + return { distance: 165 } | ||
| 580 | + case '510500': | ||
| 581 | + return { distance: 195 } | ||
| 582 | + case '510600': | ||
| 583 | + return { distance: 155 } | ||
| 584 | + case '510700': | ||
| 585 | + return { distance: 170 } | ||
| 586 | + case '510800': | ||
| 587 | + return { distance: 115 } | ||
| 588 | + case '510900': | ||
| 589 | + return { distance: 160 } | ||
| 590 | + case '511000': | ||
| 591 | + return { distance: 145 } | ||
| 592 | + case '511100': | ||
| 593 | + return { distance: 165 } | ||
| 594 | + case '511300': | ||
| 595 | + return { distance: 135 } | ||
| 596 | + case '511400': | ||
| 597 | + return { distance: 140 } | ||
| 598 | + case '511500': | ||
| 599 | + return { distance: 140 } | ||
| 600 | + case '511700': | ||
| 601 | + return { distance: 155 } | ||
| 602 | + case '511800': | ||
| 603 | + return { distance: 215 } | ||
| 604 | + case '511900': | ||
| 605 | + return { distance: 160 } | ||
| 606 | + case '512000': | ||
| 607 | + return { distance: 135 } | ||
| 608 | + case '513200': | ||
| 609 | + return { distance: 105 } | ||
| 610 | + case '513300': | ||
| 611 | + return { distance: 175 } | ||
| 612 | + case '520000': | ||
| 613 | + return { distance: 135 } | ||
| 614 | + case '520100': | ||
| 615 | + return { distance: 145 } | ||
| 616 | + case '520200': | ||
| 617 | + return { distance: 165 } | ||
| 618 | + case '520300': | ||
| 619 | + return { distance: 148 } | ||
| 620 | + case '520400': | ||
| 621 | + return { distance: 145 } | ||
| 622 | + case '522300': | ||
| 623 | + return { distance: 145 } | ||
| 624 | + case '522600': | ||
| 625 | + return { distance: 139 } | ||
| 626 | + case '522700': | ||
| 627 | + return { distance: 175 } | ||
| 628 | + case '530000': | ||
| 629 | + return { distance: 145 } | ||
| 630 | + case '530100': | ||
| 631 | + return { distance: 205 } | ||
| 632 | + case '530300': | ||
| 633 | + return { distance: 228 } | ||
| 634 | + case '530500': | ||
| 635 | + return { distance: 135 } | ||
| 636 | + case '530600': | ||
| 637 | + return { distance: 155 } | ||
| 638 | + case '530700': | ||
| 639 | + return { distance: 150 } | ||
| 640 | + case '530800': | ||
| 641 | + return { distance: 165 } | ||
| 642 | + case '530900': | ||
| 643 | + return { distance: 165 } | ||
| 644 | + case '532300': | ||
| 645 | + return { distance:205 } | ||
| 646 | + case '532500': | ||
| 647 | + return { distance: 165 } | ||
| 648 | + case '532800': | ||
| 649 | + return { distance: 160 } | ||
| 650 | + case '532900': | ||
| 651 | + return { distance: 140 } | ||
| 652 | + case '533100': | ||
| 653 | + return { distance: 175 } | ||
| 654 | + case '533300': | ||
| 655 | + return { distance: 275 } | ||
| 656 | + case '533400': | ||
| 657 | + return { distance: 200 } | ||
| 658 | + case '540000': | ||
| 659 | + return { distance: 140 } | ||
| 660 | + case '540100': | ||
| 661 | + return { distance: 145 } | ||
| 662 | + case '542500': | ||
| 663 | + return { distance: 155 } | ||
| 664 | + case '610000': | ||
| 665 | + return { distance: 210 } | ||
| 666 | + case '610100': | ||
| 667 | + return { distance: 145 } | ||
| 668 | + case '610200': | ||
| 669 | + return { distance: 140 } | ||
| 670 | + case '610300': | ||
| 671 | + return { distance: 145 } | ||
| 672 | + case '610400': | ||
| 673 | + return { distance: 135 } | ||
| 674 | + case '610500': | ||
| 675 | + return { distance: 155 } | ||
| 676 | + case '610600': | ||
| 677 | + return { distance: 135 } | ||
| 678 | + case '610700': | ||
| 679 | + return { distance: 140 } | ||
| 680 | + case '610800': | ||
| 681 | + return { distance: 155 } | ||
| 682 | + case '610900': | ||
| 683 | + return { distance: 160} | ||
| 684 | + case '611000': | ||
| 685 | + return { distance: 150} | ||
| 686 | + case '620000': | ||
| 687 | + return { distance: 135 } | ||
| 688 | + case '620300': | ||
| 689 | + return { distance: 140 } | ||
| 690 | + case '620400': | ||
| 691 | + return { distance: 165 } | ||
| 692 | + case '620500': | ||
| 693 | + return { distance: 135 } | ||
| 694 | + case '620600': | ||
| 695 | + return { distance: 175 } | ||
| 696 | + case '620700': | ||
| 697 | + return { distance: 135 } | ||
| 698 | + case '620900': | ||
| 699 | + return { distance: 135 } | ||
| 700 | + case '621000': | ||
| 701 | + return { distance: 155 } | ||
| 702 | + case '621100': | ||
| 703 | + return { distance: 145 } | ||
| 704 | + case '622900': | ||
| 705 | + return { distance: 165 } | ||
| 706 | + case '623000': | ||
| 707 | + return { distance: 145 } | ||
| 708 | + case '630100': | ||
| 709 | + return { distance: 185 } | ||
| 710 | + case '632200': | ||
| 711 | + return { distance: 130 } | ||
| 712 | + case '632300': | ||
| 713 | + return { distance: 180 } | ||
| 714 | + case '632500': | ||
| 715 | + return { distance: 135 } | ||
| 716 | + case '632600': | ||
| 717 | + return { distance: 135 } | ||
| 718 | + case '632800': | ||
| 719 | + return { distance: 150 } | ||
| 720 | + case '640000': | ||
| 721 | + return { distance: 195 } | ||
| 722 | + case '640100': | ||
| 723 | + return { distance: 175 } | ||
| 724 | + case '640500': | ||
| 725 | + return { distance: 135 } | ||
| 726 | + case '650000': | ||
| 727 | + return { distance: 135 } | ||
| 728 | + case '650100': | ||
| 729 | + return { distance: 155 } | ||
| 730 | + case '652900': | ||
| 731 | + return { distance: 135 } | ||
| 732 | + case '653100': | ||
| 733 | + return { distance: 138 } | ||
| 734 | + case '710000': | ||
| 735 | + return { distance: 135 } | ||
| 736 | + case '810000': | ||
| 737 | + return { distance: 145 } | ||
| 738 | + case '820000': | ||
| 739 | + return { distance: 240 } | ||
| 740 | + default: | ||
| 741 | + return { distance: 125} | ||
| 742 | + } | ||
| 743 | +} |
| @@ -19,127 +19,159 @@ | @@ -19,127 +19,159 @@ | ||
| 19 | </SettingItemBox> | 19 | </SettingItemBox> |
| 20 | <SettingItemBox name="图标距离"> | 20 | <SettingItemBox name="图标距离"> |
| 21 | <SettingItem name="距右"> | 21 | <SettingItem name="距右"> |
| 22 | - <n-input-number | ||
| 23 | - v-model:value="optionData.iconDistanceRight" | ||
| 24 | - :min="1" | ||
| 25 | - size="small" | ||
| 26 | - placeholder="请输入" | ||
| 27 | - ></n-input-number> | 22 | + <n-input-number v-model:value="optionData.iconDistanceRight" :min="1" size="small" |
| 23 | + placeholder="请输入"></n-input-number> | ||
| 28 | </SettingItem> | 24 | </SettingItem> |
| 29 | <SettingItem name="距上"> | 25 | <SettingItem name="距上"> |
| 30 | - <n-input-number | ||
| 31 | - v-model:value="optionData.iconDistanceTop" | ||
| 32 | - :min="1" | ||
| 33 | - size="small" | ||
| 34 | - placeholder="请输入" | ||
| 35 | - ></n-input-number> | 26 | + <n-input-number v-model:value="optionData.iconDistanceTop" :min="1" size="small" |
| 27 | + placeholder="请输入"></n-input-number> | ||
| 36 | </SettingItem> | 28 | </SettingItem> |
| 37 | </SettingItemBox> | 29 | </SettingItemBox> |
| 38 | - <SelectCity | ||
| 39 | - ref="SelectCityRef" | ||
| 40 | - :optionData="optionData" | ||
| 41 | - :drillingIn="optionData.drillingIn" | ||
| 42 | - @submit="onHandleSelectValues" | ||
| 43 | - /> | ||
| 44 | - <SettingItemBox name="颜色"> | 30 | + <SelectCity ref="SelectCityRef" :optionData="optionData" :drillingIn="optionData.drillingIn" |
| 31 | + @submit="onHandleSelectValues" /> | ||
| 32 | + <div style="height: 30px"></div> | ||
| 33 | + <n-tag type="primary">若配置无响应,请在预览页面查看效果</n-tag> | ||
| 34 | + <SettingItemBox name="地图配置"> | ||
| 45 | <SettingItem name="区域颜色"> | 35 | <SettingItem name="区域颜色"> |
| 46 | <n-color-picker size="small" :modes="['hex']" v-model:value="seriesList[0].itemStyle.color"></n-color-picker> | 36 | <n-color-picker size="small" :modes="['hex']" v-model:value="seriesList[0].itemStyle.color"></n-color-picker> |
| 47 | </SettingItem> | 37 | </SettingItem> |
| 48 | <SettingItem name="边框颜色"> | 38 | <SettingItem name="边框颜色"> |
| 49 | - <n-color-picker | ||
| 50 | - size="small" | ||
| 51 | - :modes="['hex']" | ||
| 52 | - v-model:value="seriesList[0].itemStyle.borderColor" | ||
| 53 | - ></n-color-picker> | 39 | + <n-color-picker size="small" :modes="['hex']" |
| 40 | + v-model:value="seriesList[0].itemStyle.borderColor"></n-color-picker> | ||
| 54 | </SettingItem> | 41 | </SettingItem> |
| 55 | <SettingItem name="边框大小"> | 42 | <SettingItem name="边框大小"> |
| 56 | - <n-input-number | ||
| 57 | - v-model:value="seriesList[0].itemStyle.borderWidth" | ||
| 58 | - :min="0" | ||
| 59 | - size="small" | ||
| 60 | - placeholder="请输入" | ||
| 61 | - ></n-input-number> | 43 | + <n-input-number v-model:value="seriesList[0].itemStyle.borderWidth" :min="0" size="small" |
| 44 | + placeholder="请输入"></n-input-number> | ||
| 45 | + </SettingItem> | ||
| 46 | + <SettingItem name="透明度"> | ||
| 47 | + <n-input-number v-model:value="seriesList[0].itemStyle.opacity" :min="0" size="small" | ||
| 48 | + placeholder="请输入"></n-input-number> | ||
| 62 | </SettingItem> | 49 | </SettingItem> |
| 63 | <SettingItem name="厚度"> | 50 | <SettingItem name="厚度"> |
| 64 | - <n-input-number | ||
| 65 | - v-model:value="seriesList[0].regionHeight" | ||
| 66 | - :min="0" | ||
| 67 | - size="small" | ||
| 68 | - placeholder="请输入" | ||
| 69 | - ></n-input-number> | 51 | + <n-input-number v-model:value="seriesList[0].regionHeight" :min="0" size="small" |
| 52 | + placeholder="请输入"></n-input-number> | ||
| 70 | </SettingItem> | 53 | </SettingItem> |
| 71 | </SettingItemBox> | 54 | </SettingItemBox> |
| 72 | - <SettingItemBox name="标题"> | 55 | + <SettingItemBox name="标题配置"> |
| 73 | <SettingItem name="是否显示"> | 56 | <SettingItem name="是否显示"> |
| 74 | <n-switch v-model:value="seriesList[0].label.show" size="small"></n-switch> | 57 | <n-switch v-model:value="seriesList[0].label.show" size="small"></n-switch> |
| 75 | </SettingItem> | 58 | </SettingItem> |
| 76 | <SettingItem name="颜色"> | 59 | <SettingItem name="颜色"> |
| 77 | - <n-color-picker | ||
| 78 | - size="small" | ||
| 79 | - :modes="['hex']" | ||
| 80 | - v-model:value="seriesList[0].label.textStyle.color" | ||
| 81 | - ></n-color-picker> | 60 | + <n-color-picker size="small" :modes="['hex']" |
| 61 | + v-model:value="seriesList[0].label.textStyle.color"></n-color-picker> | ||
| 82 | </SettingItem> | 62 | </SettingItem> |
| 83 | <SettingItem name="大小"> | 63 | <SettingItem name="大小"> |
| 84 | - <n-input-number | ||
| 85 | - v-model:value="seriesList[0].label.textStyle.fontSize" | ||
| 86 | - :min="0" | ||
| 87 | - size="small" | ||
| 88 | - placeholder="请输入" | ||
| 89 | - ></n-input-number> | 64 | + <n-input-number v-model:value="seriesList[0].label.textStyle.fontSize" :min="0" size="small" |
| 65 | + placeholder="请输入"></n-input-number> | ||
| 90 | </SettingItem> | 66 | </SettingItem> |
| 91 | </SettingItemBox> | 67 | </SettingItemBox> |
| 92 | - <SettingItemBox name="高亮"> | 68 | + <SettingItemBox name="高亮配置"> |
| 93 | <SettingItem name="标题显示"> | 69 | <SettingItem name="标题显示"> |
| 94 | - <n-switch v-model:value="optionData.geo3D.emphasis.label.show" size="small"></n-switch> | 70 | + <n-switch v-model:value="seriesList[0].emphasis.label.show" size="small"></n-switch> |
| 95 | </SettingItem> | 71 | </SettingItem> |
| 96 | <SettingItem name="颜色"> | 72 | <SettingItem name="颜色"> |
| 97 | - <n-color-picker | ||
| 98 | - size="small" | ||
| 99 | - :modes="['hex']" | ||
| 100 | - v-model:value="optionData.geo3D.emphasis.label.textStyle.color" | ||
| 101 | - ></n-color-picker> | 73 | + <n-color-picker size="small" :modes="['hex']" |
| 74 | + v-model:value="seriesList[0].emphasis.label.textStyle.color"></n-color-picker> | ||
| 102 | </SettingItem> | 75 | </SettingItem> |
| 103 | <SettingItem name="大小"> | 76 | <SettingItem name="大小"> |
| 104 | - <n-input-number | ||
| 105 | - v-model:value="optionData.geo3D.emphasis.label.textStyle.fontSize" | ||
| 106 | - :min="0" | ||
| 107 | - size="small" | ||
| 108 | - placeholder="请输入" | ||
| 109 | - ></n-input-number> | 77 | + <n-input-number v-model:value="seriesList[0].emphasis.label.textStyle.fontSize" :min="0" size="small" |
| 78 | + placeholder="请输入"></n-input-number> | ||
| 110 | </SettingItem> | 79 | </SettingItem> |
| 111 | <SettingItem name="区块颜色"> | 80 | <SettingItem name="区块颜色"> |
| 112 | - <n-color-picker | ||
| 113 | - size="small" | ||
| 114 | - :modes="['hex']" | ||
| 115 | - v-model:value="optionData.geo3D.emphasis.itemStyle.color" | ||
| 116 | - ></n-color-picker> | 81 | + <n-color-picker size="small" :modes="['hex']" |
| 82 | + v-model:value="seriesList[0].emphasis.itemStyle.color"></n-color-picker> | ||
| 117 | </SettingItem> | 83 | </SettingItem> |
| 118 | </SettingItemBox> | 84 | </SettingItemBox> |
| 119 | - <SettingItemBox name="标记"> | 85 | + <SettingItemBox name="柱状配置"> |
| 86 | + <SettingItem name="最小高度"> | ||
| 87 | + <n-input-number v-model:value="seriesList[1].minHeight" :min="0" :step="1" size="small" | ||
| 88 | + placeholder="请输入"></n-input-number> | ||
| 89 | + </SettingItem> | ||
| 120 | <SettingItem name="大小"> | 90 | <SettingItem name="大小"> |
| 121 | - <n-input-number | ||
| 122 | - v-model:value="seriesList[1].symbolSize" | ||
| 123 | - :min="0" | ||
| 124 | - :step="10" | ||
| 125 | - size="small" | ||
| 126 | - placeholder="请输入" | ||
| 127 | - ></n-input-number> | 91 | + <n-input-number v-model:value="seriesList[1].barSize" :min="0" :step="1" size="small" |
| 92 | + placeholder="请输入"></n-input-number> | ||
| 128 | </SettingItem> | 93 | </SettingItem> |
| 129 | - <SettingItem name="形状"> | ||
| 130 | - <n-select :options="symbolOption" v-model:value="seriesList[1].symbol"></n-select> | 94 | + <SettingItem name="倒角尺寸"> |
| 95 | + <n-input-number v-model:value="seriesList[1].bevelSize" :min="0" :max="1" :step="0.1" size="small" | ||
| 96 | + placeholder="请输入"></n-input-number> | ||
| 131 | </SettingItem> | 97 | </SettingItem> |
| 132 | </SettingItemBox> | 98 | </SettingItemBox> |
| 133 | </CollapseItem> | 99 | </CollapseItem> |
| 100 | + <CollapseItem name="地区配置" :expanded="true"> | ||
| 101 | + <SettingItemBox name="地区配置" :alone="true"> | ||
| 102 | + <template v-for="(item, map3DIndex) in optionData.dataset.map3D" :key="map3DIndex"> | ||
| 103 | + <setting-item name="省份名称" v-if="mapRegionCache.adcode == 'china'"> | ||
| 104 | + <n-select | ||
| 105 | + @change="(v: number, o: Recordable, w: Recordable, s1: number) => onHandleSelectProvince(v, o, item, map3DIndex)" | ||
| 106 | + placeholder="请选择省份" v-model:value="item.name" :options="item.provinceOptions" /> | ||
| 107 | + </setting-item> | ||
| 108 | + <setting-item name="市/区/县名称"> | ||
| 109 | + <n-select placeholder="请选择市/区/县" v-model:value="item.city_name" :options="item.cityOptions" /> | ||
| 110 | + </setting-item> | ||
| 111 | + <setting-item name="区块厚度"> | ||
| 112 | + <n-input-number v-model:value="item.height"> </n-input-number> | ||
| 113 | + </setting-item> | ||
| 114 | + <setting-item name="区块颜色"> | ||
| 115 | + <n-color-picker size="small" :modes="['hex']" v-model:value="item.itemStyle.color"></n-color-picker> | ||
| 116 | + </setting-item> | ||
| 117 | + <setting-item name="区块透明度"> | ||
| 118 | + <n-input-number v-model:value="item.itemStyle.opacity"> </n-input-number> | ||
| 119 | + </setting-item> | ||
| 120 | + <setting-item></setting-item> | ||
| 121 | + <setting-item> | ||
| 122 | + <n-button size="small" @click="optionData.dataset.map3D.splice(map3DIndex, 1)"> - </n-button> | ||
| 123 | + </setting-item> | ||
| 124 | + </template> | ||
| 125 | + <div class="h-space"></div> | ||
| 126 | + <n-button size="small" @click="handleAddRegion"> + </n-button> | ||
| 127 | + <div class="h-space"></div> | ||
| 128 | + <n-button type="primary" @click="handleAreaSubmit">确定</n-button> | ||
| 129 | + </SettingItemBox> | ||
| 130 | + </CollapseItem> | ||
| 131 | + <CollapseItem name="柱状配置" :expanded="true"> | ||
| 132 | + <SettingItemBox name="柱状配置" :alone="true"> | ||
| 133 | + <template v-for="(item, barIndex) in optionData.dataset.bar3D" :key="barIndex"> | ||
| 134 | + <setting-item name="经度"> | ||
| 135 | + <n-input-number v-model:value="item.value[0]"> </n-input-number> | ||
| 136 | + </setting-item> | ||
| 137 | + <setting-item name="纬度"> | ||
| 138 | + <n-input-number v-model:value="item.value[1]"> </n-input-number> | ||
| 139 | + </setting-item> | ||
| 140 | + <setting-item name="离地高度"> | ||
| 141 | + <n-input-number v-model:value="item.height"> </n-input-number> | ||
| 142 | + </setting-item> | ||
| 143 | + <setting-item name="柱状颜色"> | ||
| 144 | + <n-color-picker size="small" :modes="['hex']" v-model:value="item.itemStyle.color"></n-color-picker> | ||
| 145 | + </setting-item> | ||
| 146 | + <setting-item name="柱状透明度"> | ||
| 147 | + <n-input-number v-model:value="item.itemStyle.opacity"> </n-input-number> | ||
| 148 | + </setting-item> | ||
| 149 | + <setting-item> | ||
| 150 | + <n-button size="small" @click="optionData.dataset.bar3D.splice(barIndex, 1)"> - </n-button> | ||
| 151 | + </setting-item> | ||
| 152 | + </template> | ||
| 153 | + <div class="h-space"></div> | ||
| 154 | + <n-button style="float: right" size="small" | ||
| 155 | + @click="optionData.dataset.bar3D.push(cloneDeep(STATIC_SCATTER_CONFIG))"> | ||
| 156 | + + | ||
| 157 | + </n-button> | ||
| 158 | + <div class="h-space"></div> | ||
| 159 | + <n-button type="primary" @click="handleAreaSubmit">确定</n-button> | ||
| 160 | + </SettingItemBox> | ||
| 161 | + </CollapseItem> | ||
| 134 | </template> | 162 | </template> |
| 135 | 163 | ||
| 136 | <script setup lang="ts"> | 164 | <script setup lang="ts"> |
| 137 | -import { PropType, computed, ref } from 'vue' | 165 | +import { PropType, computed, ref, onMounted } from 'vue' |
| 138 | import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' | 166 | import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' |
| 139 | import { GlobalThemeJsonType } from '@/settings/chartThemes/index' | 167 | import { GlobalThemeJsonType } from '@/settings/chartThemes/index' |
| 140 | import { GlobalSetting } from '@/components/Pages/ChartItemSetting' | 168 | import { GlobalSetting } from '@/components/Pages/ChartItemSetting' |
| 141 | import SelectCity from './components/SelectCity.vue' | 169 | import SelectCity from './components/SelectCity.vue' |
| 142 | -import { regionInfo } from './config' | 170 | +import { allFetch, getAreaLists, ifSpecialCity, regionInfo } from './config' |
| 171 | +import { cloneDeep } from 'lodash' | ||
| 172 | + | ||
| 173 | +import { areaEnum } from '../../../Decorates/Mores/Weather/config' | ||
| 174 | +import { unref } from 'vue' | ||
| 143 | 175 | ||
| 144 | const props = defineProps({ | 176 | const props = defineProps({ |
| 145 | optionData: { | 177 | optionData: { |
| @@ -152,56 +184,133 @@ const seriesList = computed(() => { | @@ -152,56 +184,133 @@ const seriesList = computed(() => { | ||
| 152 | return props.optionData.series | 184 | return props.optionData.series |
| 153 | }) | 185 | }) |
| 154 | 186 | ||
| 155 | -const symbolOption = ref([ | ||
| 156 | - { | ||
| 157 | - label: 'circle', | ||
| 158 | - value: 'circle' | ||
| 159 | - }, | ||
| 160 | - { | ||
| 161 | - label: 'rect', | ||
| 162 | - value: 'rect' | ||
| 163 | - }, | ||
| 164 | - { | ||
| 165 | - label: 'roundRect', | ||
| 166 | - value: 'roundRect' | ||
| 167 | - }, | ||
| 168 | - { | ||
| 169 | - label: 'triangle', | ||
| 170 | - value: 'triangle' | ||
| 171 | - }, | ||
| 172 | - { | ||
| 173 | - label: 'diamond', | ||
| 174 | - value: 'diamond' | ||
| 175 | - }, | ||
| 176 | - { | ||
| 177 | - label: 'pin', | ||
| 178 | - value: 'pin' | ||
| 179 | - }, | ||
| 180 | - { | ||
| 181 | - label: 'arrow', | ||
| 182 | - value: 'arrow' | ||
| 183 | - }, | ||
| 184 | - { | ||
| 185 | - label: 'none', | ||
| 186 | - value: 'none' | 187 | +const datasetMap3DList = computed(() => { |
| 188 | + return props.optionData.dataset['map3D'] | ||
| 189 | +}) | ||
| 190 | + | ||
| 191 | +const STATIC_SCATTER_CONFIG = { | ||
| 192 | + name: null, | ||
| 193 | + adcode: 510000, | ||
| 194 | + city_name: null, | ||
| 195 | + value: [0, 0, 0], | ||
| 196 | + height: 2, | ||
| 197 | + itemStyle: { | ||
| 198 | + color: '#4482B1FF', | ||
| 199 | + opacity: 1 | ||
| 187 | } | 200 | } |
| 188 | -]) | 201 | +} |
| 189 | 202 | ||
| 190 | const SelectCityRef = ref<InstanceType<typeof SelectCity>>() | 203 | const SelectCityRef = ref<InstanceType<typeof SelectCity>>() |
| 191 | 204 | ||
| 192 | -const onHandleSelectValues = (values: regionInfo) => { | ||
| 193 | - const { cityValue, countyValue, provinceValue } = values | ||
| 194 | - props.optionData.mapRegion.saveSelect = values | ||
| 195 | - props.optionData.mapRegion.adcode = countyValue | 205 | + |
| 206 | + | ||
| 207 | +onMounted(async () => { | ||
| 208 | + const {saveSelect} = unref(mapRegionCache) || {} | ||
| 209 | + const {levelStr} = saveSelect || {} | ||
| 210 | + datasetMap3DList.value.forEach(async (item: Recordable) => { | ||
| 211 | + item.provinceOptions = await getAreaLists() | ||
| 212 | + const adcode = !item.adcode ? mapRegionCache.value.adcode : item.adcode | ||
| 213 | + const cityOptions = await getAreaLists(levelStr===areaEnum.CITY?areaEnum.COUNTY:areaEnum.CITY, adcode ) | ||
| 214 | + item.adcode = adcode | ||
| 215 | + if(ifSpecialCity(adcode)){//直辖市获取区县配置的数据不一样 | ||
| 216 | + const values = await allFetch(cityOptions,'adcode') || [] | ||
| 217 | + item.cityOptions = values.flatMap((obj:any) => Object.values(obj)) | ||
| 218 | + return | ||
| 219 | + } | ||
| 220 | + item.cityOptions = cityOptions | ||
| 221 | + }) | ||
| 222 | +}) | ||
| 223 | + | ||
| 224 | +const onHandleSelectProvince = async (value: number, option: Recordable, item: Recordable, mapIndex: number) => { | ||
| 225 | + const findIndex = datasetMap3DList.value.findIndex((findItem: Recordable) => findItem.name === item.name) | ||
| 226 | + datasetMap3DList.value[findIndex].city_name = null | ||
| 227 | + datasetMap3DList.value[findIndex].adcode = option.adcode | ||
| 228 | + datasetMap3DList.value[findIndex].cityOptions = await getAreaLists(areaEnum.CITY, option.adcode) | ||
| 229 | +} | ||
| 230 | + | ||
| 231 | +const handleAddRegion =async () => { | ||
| 232 | + props.optionData.dataset.map3D.push(cloneDeep(STATIC_SCATTER_CONFIG)) | ||
| 233 | + if (mapRegionCache.value.adcode !== 'china') { | ||
| 234 | + const { adcode, areaName,saveSelect } = unref(mapRegionCache) || {} | ||
| 235 | + const {levelStr} = saveSelect || {} | ||
| 236 | + const cityOptions = await getAreaLists(levelStr===areaEnum.CITY?areaEnum.COUNTY:areaEnum.CITY, adcode) | ||
| 237 | + // 循环 push 城市数据 | ||
| 238 | + datasetMap3DList.value.forEach((item: any) => { | ||
| 239 | + item.name = areaName | ||
| 240 | + item.value = null | ||
| 241 | + item.cityOptions = cityOptions && cityOptions.length ? cityOptions : [{ adcode, label: areaName, value: areaName }] | ||
| 242 | + }) | ||
| 243 | + return | ||
| 244 | + } | ||
| 245 | + datasetMap3DList.value.forEach(async (item: Recordable) => { | ||
| 246 | + item.provinceOptions = await getAreaLists() | ||
| 247 | + }) | ||
| 248 | +} | ||
| 249 | + | ||
| 250 | +const handleAreaSubmit = () => { | ||
| 251 | + props.optionData.isShowExecute = !props.optionData?.isShowExecute | ||
| 252 | +} | ||
| 253 | + | ||
| 254 | +const mapRegionCache = computed(() => { | ||
| 255 | + return props.optionData.mapRegion | ||
| 256 | +}) | ||
| 257 | + | ||
| 258 | +const onHandleSelectValues = async (values: regionInfo) => { | ||
| 259 | + const { cityValue, countyValue, provinceValue, areaName } = values | ||
| 260 | + mapRegionCache.value.areaName = areaName | ||
| 261 | + mapRegionCache.value.saveSelect = values | ||
| 262 | + mapRegionCache.value.adcode = countyValue | ||
| 196 | ? countyValue | 263 | ? countyValue |
| 197 | : cityValue | 264 | : cityValue |
| 198 | - ? cityValue | ||
| 199 | - : provinceValue === 'china' | ||
| 200 | - ? 'china' | ||
| 201 | - : provinceValue | 265 | + ? cityValue |
| 266 | + : provinceValue === 'china' | ||
| 267 | + ? 'china' | ||
| 268 | + : provinceValue | ||
| 269 | + props.optionData.mapRegion = mapRegionCache.value | ||
| 270 | + // if (mapRegionCache.value.adcode !== 'china') { | ||
| 271 | + //清空区块配置和柱状配置 | ||
| 272 | + props.optionData.dataset.map3D = [cloneDeep(STATIC_SCATTER_CONFIG)] | ||
| 273 | + props.optionData.dataset.bar3D = [cloneDeep(STATIC_SCATTER_CONFIG)] | ||
| 274 | + setDatasetArea() | ||
| 275 | + // } | ||
| 202 | } | 276 | } |
| 203 | 277 | ||
| 278 | + | ||
| 279 | +const mdutcgValues = ref<any>([])//直辖市的区县数据 | ||
| 280 | + | ||
| 281 | +const setDatasetArea = async () => { | ||
| 282 | + const { adcode, areaName,saveSelect } = unref(mapRegionCache) || {} | ||
| 283 | + const {levelStr} = saveSelect || {} | ||
| 284 | + const cityOptions = await getAreaLists(levelStr===areaEnum.CITY?areaEnum.COUNTY:areaEnum.CITY, adcode) | ||
| 285 | + let provinceOptions:any = [] | ||
| 286 | + if(adcode==='china'){ | ||
| 287 | + provinceOptions = await getAreaLists() | ||
| 288 | + } | ||
| 289 | + mdutcgValues.value = cityOptions | ||
| 290 | + if(adcode==110000 || adcode==120000 || adcode==500000 || adcode==310000 || adcode==810000 || adcode==820000){//直辖市 | ||
| 291 | + const values = await allFetch(cityOptions,'adcode') || [] | ||
| 292 | + mdutcgValues.value = values.flatMap((obj:any) => Object.values(obj))//讲获取到的多维转换成单一纬度 | ||
| 293 | + } | ||
| 294 | + // 循环 push 城市数据 | ||
| 295 | + datasetMap3DList.value.forEach((item: any) => { | ||
| 296 | + item.name = areaName | ||
| 297 | + item.city_name = null | ||
| 298 | + item.adcode = null, | ||
| 299 | + item.value = null | ||
| 300 | + item.provinceOptions=provinceOptions | ||
| 301 | + item.cityOptions = unref(mdutcgValues) && unref(mdutcgValues).length ? unref(mdutcgValues) : [{ adcode, label: areaName, value: areaName }] | ||
| 302 | + }) | ||
| 303 | +} | ||
| 204 | const handleChangeDrillingIn = () => { | 304 | const handleChangeDrillingIn = () => { |
| 205 | SelectCityRef.value?.resetValue() | 305 | SelectCityRef.value?.resetValue() |
| 306 | + props.optionData.mapRegion.adcode = 'china' | ||
| 307 | + props.optionData.mapRegion.areaName = '' | ||
| 308 | + props.optionData.mapRegion.saveSelect.areaName = '' | ||
| 206 | } | 309 | } |
| 207 | </script> | 310 | </script> |
| 311 | + | ||
| 312 | +<style scoped> | ||
| 313 | +.h-space { | ||
| 314 | + height: 10px; | ||
| 315 | +} | ||
| 316 | +</style> |
| 1 | -[ | ||
| 2 | - { | ||
| 3 | - "name": "四川省", | ||
| 4 | - "value": [104.10068024609373, 30.580525329665175, 20000], | ||
| 5 | - "adcode": 510000, | ||
| 6 | - "height": 5, | ||
| 7 | - "itemStyle": { | ||
| 8 | - "color": "pink", | ||
| 9 | - "opacity": 1, | ||
| 10 | - "borderWidth": 0.4, | ||
| 11 | - "borderColor": "#5F9EA0" | 1 | +{ |
| 2 | + "map3D": [ | ||
| 3 | + { | ||
| 4 | + "name": "四川省", | ||
| 5 | + "adcode": 510000, | ||
| 6 | + "city_name": "成都市", | ||
| 7 | + "height": 2, | ||
| 8 | + "itemStyle": { | ||
| 9 | + "color": "#4482B1FF", | ||
| 10 | + "opacity": 1, | ||
| 11 | + "borderWidth": 0.4, | ||
| 12 | + "borderColor": "#5F9EA0" | ||
| 13 | + } | ||
| 12 | } | 14 | } |
| 13 | - }, | ||
| 14 | - { | ||
| 15 | - "name": "湖南省", | ||
| 16 | - "value": [111.73068512890623, 27.86754509366569, 20000], | ||
| 17 | - "adcode": 430000, | ||
| 18 | - "height": 4, | ||
| 19 | - "itemStyle": { | ||
| 20 | - "color": "blue", | ||
| 21 | - "opacity": 1, | ||
| 22 | - "borderWidth": 0.4, | ||
| 23 | - "borderColor": "#5F9EA0" | 15 | + ], |
| 16 | + "bar3D": [ | ||
| 17 | + { | ||
| 18 | + "value": [ | ||
| 19 | + 117.283042, | ||
| 20 | + 31.86119, | ||
| 21 | + 20000 | ||
| 22 | + ], | ||
| 23 | + "height": 2, | ||
| 24 | + "itemStyle": { | ||
| 25 | + "color": "#4482B1FF", | ||
| 26 | + "opacity": 1, | ||
| 27 | + "borderWidth": 0.4, | ||
| 28 | + "borderColor": "#5F9EA0" | ||
| 29 | + } | ||
| 24 | } | 30 | } |
| 25 | - }, | ||
| 26 | - { | ||
| 27 | - "name": "吉林省", | ||
| 28 | - "value": [126.45236481640623, 43.7943407914815, 20000], | ||
| 29 | - "adcode": 220000, | ||
| 30 | - "height": 5, | ||
| 31 | - "itemStyle": { | ||
| 32 | - "color": "yellow", | ||
| 33 | - "opacity": 1, | ||
| 34 | - "borderWidth": 0.4, | ||
| 35 | - "borderColor": "#5F9EA0" | ||
| 36 | - } | ||
| 37 | - }, | ||
| 38 | - { | ||
| 39 | - "name": "山东省", | ||
| 40 | - "value": [118.67404450390623, 36.16387465872037, 20000], | ||
| 41 | - "adcode": 370000, | ||
| 42 | - "height": 6, | ||
| 43 | - "itemStyle": { | ||
| 44 | - "color": "orange", | ||
| 45 | - "opacity": 1, | ||
| 46 | - "borderWidth": 0.4, | ||
| 47 | - "borderColor": "#5F9EA0" | ||
| 48 | - } | ||
| 49 | - } | ||
| 50 | -] | 31 | + ] |
| 32 | +} |
| @@ -9,12 +9,23 @@ | @@ -9,12 +9,23 @@ | ||
| 9 | 9 | ||
| 10 | <script setup lang="ts"> | 10 | <script setup lang="ts"> |
| 11 | import { onMounted, ref, nextTick, PropType, toRefs, watch, reactive } from 'vue' | 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' | 12 | import 'echarts-gl' |
| 15 | -import config, { areaEnum, dataPointI, optionType, historyParentType, backMapLevel } from './config' | 13 | +import { registerMap, init } from 'echarts/core' |
| 14 | +import type { EChartsType } from 'echarts/core' | ||
| 15 | +import config, { | ||
| 16 | + areaEnum, | ||
| 17 | + dataPointI, | ||
| 18 | + optionType, | ||
| 19 | + historyParentType, | ||
| 20 | + backMapLevel, | ||
| 21 | + levelFunc, | ||
| 22 | + regionMapParentArea, | ||
| 23 | + specialTreatmentAnhui, | ||
| 24 | + setScale | ||
| 25 | +} from './config' | ||
| 16 | import { getGeoJsonMap } from '@/api/external/common' | 26 | import { getGeoJsonMap } from '@/api/external/common' |
| 17 | -import dataMaps from './data.json' | 27 | +import { ThreeMapEnum } from '@/enums/external/mapEnum' |
| 28 | +import cloneDeep from 'lodash/cloneDeep' | ||
| 18 | 29 | ||
| 19 | const props = defineProps({ | 30 | const props = defineProps({ |
| 20 | chartConfig: { | 31 | chartConfig: { |
| @@ -23,15 +34,18 @@ const props = defineProps({ | @@ -23,15 +34,18 @@ const props = defineProps({ | ||
| 23 | } | 34 | } |
| 24 | }) | 35 | }) |
| 25 | 36 | ||
| 26 | -const backIcon = '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' | 37 | +const backIcon = |
| 38 | + '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 | 39 | ||
| 28 | const { w, h } = toRefs(props.chartConfig.attr) | 40 | const { w, h } = toRefs(props.chartConfig.attr) |
| 29 | 41 | ||
| 30 | -const map3DRef = ref() | 42 | +const { mapRegion, dataset, drillingIn, saveClickRegion, geo3D, series } = toRefs(props.chartConfig.option) |
| 43 | + | ||
| 44 | +const map3DRef = ref<Nullable<HTMLElement>>() | ||
| 31 | 45 | ||
| 32 | const show = ref(true) | 46 | const show = ref(true) |
| 33 | 47 | ||
| 34 | -const chartInstance = ref() | 48 | +const chartInstance = ref<Nullable<EChartsType>>() |
| 35 | 49 | ||
| 36 | const toolBoxOption = ref({ | 50 | const toolBoxOption = ref({ |
| 37 | show: true, | 51 | show: true, |
| @@ -50,38 +64,39 @@ const toolBoxOption = ref({ | @@ -50,38 +64,39 @@ const toolBoxOption = ref({ | ||
| 50 | } | 64 | } |
| 51 | }) | 65 | }) |
| 52 | 66 | ||
| 53 | -const excludeCountryLevels = ['PROVINCE','CITY'] //如果从右侧配置选择全中国 | 67 | +const excludeCountryLevels = ['PROVINCE', 'CITY'] //如果从右侧配置选择全中国 |
| 54 | 68 | ||
| 55 | const includeCityLevels = ['CITY'] //如果从右侧配置选择省份 | 69 | const includeCityLevels = ['CITY'] //如果从右侧配置选择省份 |
| 56 | 70 | ||
| 57 | //元组 优化if elseif else分支 隐藏返回图标 | 71 | //元组 优化if elseif else分支 隐藏返回图标 |
| 58 | -const backIconMappingLevels: any[][] =[ | 72 | +const backIconMappingLevels: levelFunc[][] = [ |
| 59 | [ | 73 | [ |
| 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 | 74 | + (levelStr: string) => levelStr === areaEnum.COUNTRY, |
| 75 | + (level: string) => excludeCountryLevels.includes(level), | ||
| 76 | + () => (toolBoxOption.value.feature.myFullButton.show = true), | ||
| 77 | + () => (toolBoxOption.value.feature.myFullButton.show = false) | ||
| 64 | ], | 78 | ], |
| 65 | [ | 79 | [ |
| 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 | - ], | 80 | + (levelStr: string) => levelStr === areaEnum.PROVINCE, |
| 81 | + (level: string) => includeCityLevels.includes(level), | ||
| 82 | + () => (toolBoxOption.value.feature.myFullButton.show = true), | ||
| 83 | + () => (toolBoxOption.value.feature.myFullButton.show = false) | ||
| 84 | + ] | ||
| 71 | ] | 85 | ] |
| 72 | 86 | ||
| 73 | - | ||
| 74 | watch( | 87 | watch( |
| 75 | () => props.chartConfig.option, | 88 | () => props.chartConfig.option, |
| 76 | - (newData:optionType) => { | 89 | + (newData: optionType) => { |
| 77 | const { iconColor, iconDistanceRight, iconDistanceTop, mapRegion } = newData | 90 | const { iconColor, iconDistanceRight, iconDistanceTop, mapRegion } = newData |
| 78 | - const { saveSelect }=mapRegion | ||
| 79 | - const { levelStr }=saveSelect | ||
| 80 | - const findBackLevel = backIconMappingLevels.find((backLevelItem: backMapLevel[])=>backLevelItem[0](levelStr)) as backMapLevel[] | ||
| 81 | - if(findBackLevel){ | ||
| 82 | - if(findBackLevel[0]){ | 91 | + const { saveSelect } = mapRegion |
| 92 | + const { levelStr } = saveSelect | ||
| 93 | + const findBackLevel = backIconMappingLevels.find((backLevelItem: levelFunc[]) => | ||
| 94 | + backLevelItem[0](levelStr) | ||
| 95 | + ) as backMapLevel[] | ||
| 96 | + if (findBackLevel) { | ||
| 97 | + if (findBackLevel[0]) { | ||
| 83 | const findLevel = findBackLevel[1](saveLevelStr.level) | 98 | const findLevel = findBackLevel[1](saveLevelStr.level) |
| 84 | - if(findLevel)findBackLevel[2]() | 99 | + if (findLevel) findBackLevel[2]() |
| 85 | else findBackLevel[3]() | 100 | else findBackLevel[3]() |
| 86 | } | 101 | } |
| 87 | } | 102 | } |
| @@ -103,14 +118,14 @@ props.chartConfig.option = { | @@ -103,14 +118,14 @@ props.chartConfig.option = { | ||
| 103 | //地图点击返回 | 118 | //地图点击返回 |
| 104 | const handleBack = async () => { | 119 | const handleBack = async () => { |
| 105 | stopWatch() | 120 | stopWatch() |
| 106 | - if (props.chartConfig.option.drillingIn) { | 121 | + if (drillingIn.value) { |
| 107 | //如果是从右边配置里设置的,比如点击四川省,然后点击返回 | 122 | //如果是从右边配置里设置的,比如点击四川省,然后点击返回 |
| 108 | const savePopParent = saveHistoryParent.value.pop() | 123 | const savePopParent = saveHistoryParent.value.pop() |
| 109 | let saveAdcode = savePopParent?.adcode as string | number | 124 | let saveAdcode = savePopParent?.adcode as string | number |
| 110 | saveLevelStr.level = savePopParent?.level as string | 125 | saveLevelStr.level = savePopParent?.level as string |
| 111 | if (!savePopParent) { | 126 | if (!savePopParent) { |
| 112 | - saveAdcode = getParentAdcode(props.chartConfig.option.mapRegion.adcode) | ||
| 113 | - saveLevelStr.level = (regionMapParentArea as Recordable)[props.chartConfig.option.mapRegion.saveSelect.levelStr] | 127 | + saveAdcode = getParentAdcode(mapRegion.value.adcode).adcodeNum |
| 128 | + saveLevelStr.level = (regionMapParentArea as Recordable)[mapRegion.value.saveSelect.levelStr] | ||
| 114 | } | 129 | } |
| 115 | if (saveAdcode === 0) { | 130 | if (saveAdcode === 0) { |
| 116 | saveAdcode = 'china' | 131 | saveAdcode = 'china' |
| @@ -118,50 +133,48 @@ const handleBack = async () => { | @@ -118,50 +133,48 @@ const handleBack = async () => { | ||
| 118 | } | 133 | } |
| 119 | const exist = await getGeojson(saveAdcode) | 134 | const exist = await getGeojson(saveAdcode) |
| 120 | const adcode = saveAdcode === 100000 ? 'china' : saveAdcode | 135 | const adcode = saveAdcode === 100000 ? 'china' : saveAdcode |
| 121 | - props.chartConfig.option.saveClickRegion.level = saveLevelStr.level | 136 | + saveClickRegion.value.level = saveLevelStr.level |
| 122 | if (exist) { | 137 | if (exist) { |
| 123 | - //fix解决点击下钻返回后页面为空问题 | ||
| 124 | - props.chartConfig.option.mapRegion.adcode = adcode | 138 | + mapRegion.value.areaName = getParentAdcode(mapRegion.value.adcode).areaName |
| 139 | + //fix 解决点击下钻返回后页面为空问题 | ||
| 140 | + mapRegion.value.adcode = adcode | ||
| 125 | } | 141 | } |
| 126 | } | 142 | } |
| 127 | } | 143 | } |
| 128 | 144 | ||
| 129 | -//地区上级对应配置 | ||
| 130 | -const regionMapParentArea = { | ||
| 131 | - PROVINCE: areaEnum.COUNTRY, //省份的上一级 中国 | ||
| 132 | - CITY: areaEnum.PROVINCE, //城市的上一级 省份 | ||
| 133 | - COUNTY: areaEnum.CITY, //县或者区的上一级 城市 | ||
| 134 | - TOWN: areaEnum.COUNTY //镇的上一级 县或者区 | ||
| 135 | -} | ||
| 136 | - | ||
| 137 | //地图点击 | 145 | //地图点击 |
| 138 | const handleMap3DClick = async (params: Recordable) => { | 146 | const handleMap3DClick = async (params: Recordable) => { |
| 139 | - if (props.chartConfig.option.drillingIn) { | 147 | + if (drillingIn.value) { |
| 140 | const { name } = params | 148 | const { name } = params |
| 141 | - saveGeojson.value?.features.forEach((item: Recordable) => { | 149 | + const geoJson = JSON.parse(saveGeojson.value?.geoJson) |
| 150 | + geoJson?.features.forEach((item: Recordable) => { | ||
| 142 | if (item.properties.name === name) { | 151 | if (item.properties.name === name) { |
| 143 | const level = item.properties.level.toUpperCase() | 152 | const level = item.properties.level.toUpperCase() |
| 144 | const adcode = item.properties.adcode | 153 | const adcode = item.properties.adcode |
| 154 | + const areaName = item.properties.name | ||
| 145 | if (level === 'DISTRICT') return //下钻暂且不支持地区 | 155 | if (level === 'DISTRICT') return //下钻暂且不支持地区 |
| 146 | if (String(adcode).startsWith('15') && level === areaEnum.CITY) return //特殊处理地区码15开头的 | 156 | if (String(adcode).startsWith('15') && level === areaEnum.CITY) return //特殊处理地区码15开头的 |
| 147 | - props.chartConfig.option.mapRegion.adcode = adcode | ||
| 148 | - props.chartConfig.option.saveClickRegion.level = level | 157 | + mapRegion.value.adcode = adcode |
| 158 | + mapRegion.value.areaName = areaName | ||
| 159 | + saveClickRegion.value.level = level | ||
| 149 | saveLevelStr.level = level | 160 | saveLevelStr.level = level |
| 150 | - handleDataPoint(adcode) | ||
| 151 | saveHistoryParent.value.push({ | 161 | saveHistoryParent.value.push({ |
| 152 | - adcode: item.properties.parent.adcode, | ||
| 153 | - level: (regionMapParentArea as Recordable)[level] | 162 | + adcode: specialTreatmentAnhui.includes(item.properties.name) |
| 163 | + ? JSON.parse(item.properties.parent)?.adcode | ||
| 164 | + : item.properties.parent.adcode, | ||
| 165 | + level: (regionMapParentArea as Recordable)[level], | ||
| 166 | + areaName: saveGeojson.value.name | ||
| 154 | }) | 167 | }) |
| 155 | } | 168 | } |
| 156 | }) | 169 | }) |
| 157 | } | 170 | } |
| 158 | } | 171 | } |
| 159 | 172 | ||
| 160 | -const saveGeojson: Recordable = ref({}) // 保存geojson | 173 | +const saveGeojson: Recordable = ref({}) // 保存一份服务端返回的geojson |
| 161 | 174 | ||
| 162 | const chinaDefaultRegionId = ref(100000) //如果是china则adcode为100000 | 175 | const chinaDefaultRegionId = ref(100000) //如果是china则adcode为100000 |
| 163 | 176 | ||
| 164 | -const saveLevelStr = reactive<{level:historyParentType["level"]}>({ | 177 | +const saveLevelStr = reactive<{ level: historyParentType['level'] }>({ |
| 165 | // 地区级别 | 178 | // 地区级别 |
| 166 | level: '' | 179 | level: '' |
| 167 | }) | 180 | }) |
| @@ -172,155 +185,194 @@ const saveHistoryParent = ref<historyParentType[]>([]) | @@ -172,155 +185,194 @@ const saveHistoryParent = ref<historyParentType[]>([]) | ||
| 172 | const getGeojson = (regionId: number | string) => { | 185 | const getGeojson = (regionId: number | string) => { |
| 173 | try { | 186 | try { |
| 174 | return new Promise<boolean>(resolve => { | 187 | return new Promise<boolean>(resolve => { |
| 175 | - const { levelStr } = props.chartConfig.option.mapRegion.saveSelect //右侧配置项获取的行政级别 | 188 | + const { levelStr } = mapRegion.value.saveSelect //右侧配置项获取的行政级别 |
| 176 | getGeoJsonMap( | 189 | getGeoJsonMap( |
| 177 | regionId === 'china' ? chinaDefaultRegionId.value : regionId, | 190 | regionId === 'china' ? chinaDefaultRegionId.value : regionId, |
| 178 | !saveLevelStr.level ? levelStr : saveLevelStr.level //没有则获取右侧配置的行政级别 | 191 | !saveLevelStr.level ? levelStr : saveLevelStr.level //没有则获取右侧配置的行政级别 |
| 179 | ).then(res => { | 192 | ).then(res => { |
| 180 | - const { geoJson, name, code, level } = res.data | 193 | + saveGeojson.value = res.data //保存一份服务端返回的数据 |
| 194 | + const { geoJson, name, level, code } = res.data | ||
| 181 | const geoJsonFile = JSON.parse(geoJson) | 195 | const geoJsonFile = JSON.parse(geoJson) |
| 182 | if (!geoJsonFile) return | 196 | if (!geoJsonFile) return |
| 183 | - saveGeojson.value = geoJsonFile//保存一份服务端返回的geojson | ||
| 184 | - const nameChina = name === '中国' ? 'china' : name | ||
| 185 | - registerMap(level === areaEnum.COUNTRY ? nameChina : code, { geoJSON: geoJsonFile, specialAreas: {} }) | ||
| 186 | - show.value = false | 197 | + const nameChina = name === '中国' ? 'china' : name //为中国的话,registerMap第一个必须是china,否则显示不出来 |
| 198 | + /** | ||
| 199 | + * 主要注意的点,registerMap中的第一个参数需要和series中的map匹配,否则渲染不出地图, | ||
| 200 | + * 比如map: '北京市' echarts.registerMap('北京市', beijingGeoJSON); | ||
| 201 | + */ | ||
| 202 | + registerMap(level === areaEnum.COUNTRY ? nameChina : !mapRegion.value.areaName ? code : name, { | ||
| 203 | + geoJSON: geoJsonFile, | ||
| 204 | + specialAreas: {} | ||
| 205 | + }) //注册geoJSON | ||
| 187 | resolve(true) | 206 | resolve(true) |
| 207 | + show.value = false | ||
| 208 | + changeOption.value = true | ||
| 188 | }) | 209 | }) |
| 189 | }) | 210 | }) |
| 190 | } catch (error) { | 211 | } catch (error) { |
| 191 | show.value = false | 212 | show.value = false |
| 192 | - console.error('注册地图出错', error) | 213 | + console.error('注册三维地图出错,出错原因->', error) |
| 193 | //注册出错则注册空的,不然在选择正确的adcode,则视图无法更新 | 214 | //注册出错则注册空的,不然在选择正确的adcode,则视图无法更新 |
| 194 | - registerMap(props.chartConfig.option.mapRegion.adcode, { geoJSON: {} as any, specialAreas: {} }) | 215 | + registerMap(mapRegion.value.adcode, { geoJSON: {} as any, specialAreas: {} }) |
| 195 | } | 216 | } |
| 196 | } | 217 | } |
| 197 | 218 | ||
| 198 | //异步时先注册空的 保证初始化不报错 | 219 | //异步时先注册空的 保证初始化不报错 |
| 199 | -registerMap(props.chartConfig.option.mapRegion.adcode, { geoJSON: {} as any, specialAreas: {} }) | 220 | +registerMap(mapRegion.value.adcode, { geoJSON: {} as any, specialAreas: {} }) |
| 200 | 221 | ||
| 201 | //传adcode 获取上级 | 222 | //传adcode 获取上级 |
| 202 | const getParentAdcode = (adcode: number) => { | 223 | const getParentAdcode = (adcode: number) => { |
| 203 | let adcodeNum = 100000 | 224 | let adcodeNum = 100000 |
| 204 | - saveGeojson.value?.features.forEach((item: Recordable) => { | 225 | + let areaName = '' |
| 226 | + const geoJson = JSON.parse(saveGeojson.value?.geoJson) | ||
| 227 | + geoJson.features.forEach((item: Recordable) => { | ||
| 205 | if (item.properties.adcode === adcode) { | 228 | if (item.properties.adcode === adcode) { |
| 206 | adcodeNum = item.properties.parent.adcode | 229 | adcodeNum = item.properties.parent.adcode |
| 230 | + areaName = saveGeojson.value.name | ||
| 207 | } | 231 | } |
| 208 | }) | 232 | }) |
| 209 | - return adcodeNum | 233 | + return { adcodeNum, areaName } |
| 210 | } | 234 | } |
| 211 | 235 | ||
| 212 | -watch( | ||
| 213 | - () => w.value, | ||
| 214 | - (value: number) => { | ||
| 215 | - chartInstance.value.resize({ | ||
| 216 | - width: value + 'px', | ||
| 217 | - height: h.value + 'px' | ||
| 218 | - }) | ||
| 219 | - } | ||
| 220 | -) | ||
| 221 | - | ||
| 222 | -const initMap = async () => { | ||
| 223 | - chartInstance.value = echarts.init(map3DRef.value) | 236 | +// 初始化三维地图 |
| 237 | +const initMap3D = async () => { | ||
| 238 | + chartInstance.value = init(map3DRef.value as HTMLElement) as any as Nullable<EChartsType> | ||
| 224 | await nextTick() | 239 | await nextTick() |
| 225 | - await getGeojson(props.chartConfig.option.mapRegion.adcode) | 240 | + await getGeojson(mapRegion.value.adcode) |
| 226 | await nextTick().then(() => { | 241 | await nextTick().then(() => { |
| 227 | - handleSetOption(chartInstance.value, props.chartConfig.option) | 242 | + handleRegisterMapNameAndData(mapRegion.value.adcode, dataset.value, 'china') |
| 228 | }) | 243 | }) |
| 229 | - chartInstance.value.on('click', (e: Recordable) => { | 244 | + chartInstance.value?.on('click', (e: Recordable) => { |
| 245 | + if (!e) return | ||
| 230 | handleMap3DClick(e) | 246 | handleMap3DClick(e) |
| 231 | }) | 247 | }) |
| 232 | } | 248 | } |
| 233 | 249 | ||
| 234 | -// 手动触发渲染 | ||
| 235 | -const handleSetOption = (instance: any, option: Recordable) => { | 250 | +onMounted(() => initMap3D()) |
| 251 | + | ||
| 252 | +// 动态注册 series中的map必须和registerMap的第一个参数匹配,否则渲染不出 | ||
| 253 | +const handleRegisterMapNameAndData = (adcode: string | number, data: Recordable, areaName: string) => { | ||
| 254 | + geo3D.value.map = !areaName ? adcode : areaName // coordinateSystem使用了geo3D,不能删除这一行 | ||
| 255 | + series.value.forEach((item: Recordable) => { | ||
| 256 | + if (item.type === ThreeMapEnum.MAP3D) { | ||
| 257 | + item.map = !areaName ? adcode : areaName | ||
| 258 | + item.data = data[ThreeMapEnum.MAP3D] | ||
| 259 | + } | ||
| 260 | + if (item.type === ThreeMapEnum.BAR3D) { | ||
| 261 | + item.data = data[ThreeMapEnum.BAR3D] | ||
| 262 | + } | ||
| 263 | + }) | ||
| 264 | +} | ||
| 265 | + | ||
| 266 | +// 动态触发渲染 | ||
| 267 | +const handleSetOption = (instance: EChartsType, option: Recordable) => { | ||
| 236 | if (!instance) return | 268 | if (!instance) return |
| 237 | try { | 269 | try { |
| 238 | - instance.clear() | ||
| 239 | - instance.setOption(option) | 270 | + instance && instance.clear() |
| 271 | + instance && instance.setOption(option) | ||
| 240 | } catch (error) { | 272 | } catch (error) { |
| 241 | - console.error('触发渲染出错', error) | 273 | + console.error('动态触发渲染出错,出错原因->', error) |
| 242 | } | 274 | } |
| 243 | } | 275 | } |
| 244 | 276 | ||
| 245 | -onMounted(() => { | ||
| 246 | - initMap() | ||
| 247 | -}) | 277 | +watch( |
| 278 | + () => [w.value, h.value], | ||
| 279 | + async (newValue: number[]) => { | ||
| 280 | + await nextTick() | ||
| 281 | + chartInstance.value?.resize({ | ||
| 282 | + width: newValue.at(-2) + 'px', | ||
| 283 | + height: newValue.at(-1) + 'px' | ||
| 284 | + } as Recordable) | ||
| 285 | + } | ||
| 286 | +) | ||
| 248 | 287 | ||
| 249 | //处理数据标点 | 288 | //处理数据标点 |
| 250 | -const handleDataPoint = (newData: string | number) => { | 289 | +const handleDataPoint = (newData: string | number, areaName: string) => { |
| 251 | if (newData === 'china') { | 290 | if (newData === 'china') { |
| 252 | - props.chartConfig.option.dataset = dataMaps | ||
| 253 | - props.chartConfig.option.series.forEach((item: Recordable) => { | ||
| 254 | - if (item.type === 'scatter3D') { | ||
| 255 | - item.data = dataMaps | ||
| 256 | - } | ||
| 257 | - }) | 291 | + // 全国则展示所有的标点 |
| 292 | + handleRegisterMapNameAndData(newData, dataset.value, 'china') | ||
| 258 | } else { | 293 | } else { |
| 259 | - props.chartConfig.option.dataset = dataMaps.filter((item: dataPointI) => item.adcode === newData) | ||
| 260 | - props.chartConfig.option.series.forEach((item: Recordable) => { | ||
| 261 | - if (item.type === 'scatter3D') { | ||
| 262 | - item.data = dataMaps.filter((item: dataPointI) => item.adcode === newData) | 294 | + // 展示对应区域的标点 |
| 295 | + series.value.forEach((item: Recordable) => { | ||
| 296 | + if (item.type === ThreeMapEnum.MAP3D) { | ||
| 297 | + item.map = !areaName ? newData : areaName | ||
| 298 | + item.data = dataset.value[ThreeMapEnum.MAP3D].filter((dataItem: dataPointI) => { | ||
| 299 | + if (String(dataItem.adcode) === String(!areaName ? newData : areaName)) { | ||
| 300 | + return dataItem | ||
| 301 | + } else if (dataItem.name === String(!areaName ? newData : areaName)) { | ||
| 302 | + return dataItem | ||
| 303 | + } | ||
| 304 | + }) | ||
| 305 | + const cloneDeepData = cloneDeep(item.data) | ||
| 306 | + cloneDeepData.forEach((item: dataPointI) => { | ||
| 307 | + item.name = item.city_name | ||
| 308 | + }) | ||
| 309 | + item.data = cloneDeepData.filter((item: Recordable) => item.name !== null) || [] | ||
| 310 | + } | ||
| 311 | + if (item.type === ThreeMapEnum.BAR3D) { | ||
| 312 | + item.data = dataset.value[ThreeMapEnum.BAR3D] | ||
| 263 | } | 313 | } |
| 264 | }) | 314 | }) |
| 265 | } | 315 | } |
| 266 | } | 316 | } |
| 317 | +const changeOption = ref(false) | ||
| 267 | 318 | ||
| 268 | -//监听地图展示区域发生变化 | 319 | +// 监听地图展示区域发生变化 |
| 269 | watch( | 320 | watch( |
| 270 | () => `${props.chartConfig.option.mapRegion.adcode}`, | 321 | () => `${props.chartConfig.option.mapRegion.adcode}`, |
| 271 | - async (newData: string | number) => { | 322 | + async (newData: number | string) => { |
| 272 | try { | 323 | try { |
| 273 | await getGeojson(newData) | 324 | await getGeojson(newData) |
| 274 | - props.chartConfig.option.geo3D.map = newData | ||
| 275 | - props.chartConfig.option.series.forEach((item: Recordable) => { | 325 | + const { distance} = setScale(String(newData)) |
| 326 | + const option = props.chartConfig.option | ||
| 327 | + // 修复缩放 | ||
| 328 | + const { series,geo3D } = option || {} | ||
| 329 | + | ||
| 330 | + series?.forEach((item: Recordable) => { | ||
| 276 | if (item.type === 'map3D') { | 331 | if (item.type === 'map3D') { |
| 277 | - item.map = newData | ||
| 278 | - item.data = props.chartConfig.option.dataset | 332 | + item.viewControl = { |
| 333 | + ...item?.viewControl, | ||
| 334 | + distance, | ||
| 335 | + } | ||
| 279 | } | 336 | } |
| 280 | }) | 337 | }) |
| 281 | - handleSetOption(chartInstance.value, props.chartConfig.option) | ||
| 282 | - handleDataPoint(newData) | 338 | + handleRegisterMapNameAndData(newData, dataset.value, mapRegion.value.areaName) |
| 339 | + handleDataPoint(newData, mapRegion.value.areaName) | ||
| 340 | + changeOption.value = true | ||
| 341 | + handleSetOption(chartInstance.value!, { ...option, series ,geo3D:{...geo3D,viewControl:{distance:distance}}}) | ||
| 283 | } catch (error) { | 342 | } catch (error) { |
| 284 | - console.log('展示区域发生变化出错', error) | 343 | + console.error('展示区域发生变化出错,出错原因->', error) |
| 285 | } | 344 | } |
| 286 | }, | 345 | }, |
| 287 | { | 346 | { |
| 288 | - immediate: true | 347 | + immediate: true, |
| 348 | + deep: true | ||
| 289 | } | 349 | } |
| 290 | ) | 350 | ) |
| 291 | 351 | ||
| 292 | -// 监听地图右侧配置项变化 | 352 | +// 实时监听地图右侧配置项变化 |
| 293 | const stopWatch = watch( | 353 | const stopWatch = watch( |
| 294 | props.chartConfig.option, | 354 | props.chartConfig.option, |
| 295 | async newData => { | 355 | async newData => { |
| 296 | try { | 356 | try { |
| 297 | - handleSetOption(chartInstance.value, newData) | ||
| 298 | - } catch (error) { | ||
| 299 | - console.log(error) | ||
| 300 | - } | ||
| 301 | - }, | ||
| 302 | - { | ||
| 303 | - deep: true | ||
| 304 | - } | ||
| 305 | -) | ||
| 306 | - | ||
| 307 | -// 监听地图dataset配置项变化 | ||
| 308 | -watch( | ||
| 309 | - () => props.chartConfig.option.dataset, | ||
| 310 | - newData => { | ||
| 311 | - try { | ||
| 312 | - props.chartConfig.option.series.forEach((item: Recordable) => { | ||
| 313 | - if (item.type === 'map3D') { | ||
| 314 | - item.data = newData | ||
| 315 | - } | ||
| 316 | - }) | ||
| 317 | - handleSetOption(chartInstance.value, props.chartConfig.option) | 357 | + if (changeOption.value) { |
| 358 | + // handleSetOption(chartInstance.value!, newData) | ||
| 359 | + } | ||
| 318 | } catch (error) { | 360 | } catch (error) { |
| 319 | - console.log(error) | 361 | + console.error('监听地图右侧配置项变化,出错原因->', error) |
| 320 | } | 362 | } |
| 321 | }, | 363 | }, |
| 322 | { | 364 | { |
| 323 | deep: true | 365 | deep: true |
| 324 | } | 366 | } |
| 325 | ) | 367 | ) |
| 368 | +watch(()=>props.chartConfig.option.isShowExecute,async()=>{ | ||
| 369 | + const {adcode,areaName} = props.chartConfig.option.mapRegion || {} | ||
| 370 | + handleRegisterMapNameAndData(adcode,dataset.value,mapRegion.value.areaName) | ||
| 371 | + handleDataPoint(adcode,areaName) | ||
| 372 | + | ||
| 373 | + const { distance } = setScale(String(adcode)) | ||
| 374 | + const option = props.chartConfig.option | ||
| 375 | + const { series,geo3D } = option || {} | ||
| 376 | + handleSetOption(chartInstance.value!, { ...option, series ,geo3D:{...geo3D,viewControl:{distance:distance}}}) | ||
| 377 | +}) | ||
| 326 | </script> | 378 | </script> |
| @@ -27,7 +27,6 @@ import { getDeviceActiveTime } from '@/api/external/common/index' | @@ -27,7 +27,6 @@ import { getDeviceActiveTime } from '@/api/external/common/index' | ||
| 27 | import dayjs from 'dayjs' | 27 | import dayjs from 'dayjs' |
| 28 | import DeviceLatestTable from './components/DeviceLatestTable.vue' | 28 | import DeviceLatestTable from './components/DeviceLatestTable.vue' |
| 29 | import { getDeviceLatest, getProfileAttrs } from '@/api/external/common' | 29 | import { getDeviceLatest, getProfileAttrs } from '@/api/external/common' |
| 30 | -import { NButton } from 'naive-ui' | ||
| 31 | 30 | ||
| 32 | const props = defineProps({ | 31 | const props = defineProps({ |
| 33 | chartConfig: { | 32 | chartConfig: { |
| @@ -15,7 +15,7 @@ | @@ -15,7 +15,7 @@ | ||
| 15 | <n-input-number :min="0" v-model:value="optionData.value.min" size="small"></n-input-number> | 15 | <n-input-number :min="0" v-model:value="optionData.value.min" size="small"></n-input-number> |
| 16 | </SettingItem> | 16 | </SettingItem> |
| 17 | <setting-item name="最大值"> | 17 | <setting-item name="最大值"> |
| 18 | - <n-input-number v-model:value="optionData.value.max" size="small"></n-input-number> | 18 | + <n-input-number v-model:value="optionData.value.max" size="small" :min="100"></n-input-number> |
| 19 | </setting-item> | 19 | </setting-item> |
| 20 | </SettingItemBox> | 20 | </SettingItemBox> |
| 21 | <SettingItemBox name="轨道"> | 21 | <SettingItemBox name="轨道"> |
| @@ -3,7 +3,7 @@ | @@ -3,7 +3,7 @@ | ||
| 3 | :type="type" | 3 | :type="type" |
| 4 | :height="h" | 4 | :height="h" |
| 5 | :processing="processing" | 5 | :processing="processing" |
| 6 | - :percentage="dataset" | 6 | + :percentage="percentage" |
| 7 | :indicator-placement="indicatorPlacement" | 7 | :indicator-placement="indicatorPlacement" |
| 8 | :color="color" | 8 | :color="color" |
| 9 | :rail-color="railColor" | 9 | :rail-color="railColor" |
| @@ -21,11 +21,12 @@ | @@ -21,11 +21,12 @@ | ||
| 21 | </template> | 21 | </template> |
| 22 | 22 | ||
| 23 | <script setup lang="ts"> | 23 | <script setup lang="ts"> |
| 24 | -import { PropType, toRefs, watch } from 'vue' | 24 | +import { PropType, computed, ref, toRefs, watch } from 'vue' |
| 25 | import { useChartDataFetch } from '@/hooks' | 25 | import { useChartDataFetch } from '@/hooks' |
| 26 | import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' | 26 | import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' |
| 27 | import config from './config' | 27 | import config from './config' |
| 28 | import { toNumber } from '@/utils' | 28 | import { toNumber } from '@/utils' |
| 29 | +import { unref } from 'vue' | ||
| 29 | 30 | ||
| 30 | const props = defineProps({ | 31 | const props = defineProps({ |
| 31 | chartConfig: { | 32 | chartConfig: { |
| @@ -46,25 +47,38 @@ const { | @@ -46,25 +47,38 @@ const { | ||
| 46 | indicatorPlacement, | 47 | indicatorPlacement, |
| 47 | indicatorTextSize, | 48 | indicatorTextSize, |
| 48 | offsetDegree, | 49 | offsetDegree, |
| 49 | - dataset | 50 | + dataset, |
| 50 | } = toRefs(props.chartConfig.option) | 51 | } = toRefs(props.chartConfig.option) |
| 51 | 52 | ||
| 53 | +const max = computed(()=>{//获取最新的最大值 | ||
| 54 | + const {value:{max}} = props.chartConfig.option | ||
| 55 | + return max | ||
| 56 | +}) | ||
| 57 | +const percentage = ref<number>(unref(dataset) * (100/max.value))//计算当设置的最大值大于100的时候 | ||
| 52 | // 手动更新 | 58 | // 手动更新 |
| 53 | watch( | 59 | watch( |
| 54 | - () => props.chartConfig.option.dataset, | ||
| 55 | - (newData: any) => { | 60 | + () => {props.chartConfig.option.dataset,props.chartConfig.option.value.max}, |
| 61 | + () => { | ||
| 56 | try { | 62 | try { |
| 57 | - dataset.value = toNumber(newData, 2) | 63 | + if(max.value!==100){ |
| 64 | + const newValue = unref(dataset) * (100/max.value)//计算进度条的位置 | ||
| 65 | + percentage.value = toNumber(newValue,2) | ||
| 66 | + dataset.value = toNumber((unref(dataset)), 2) | ||
| 67 | + return | ||
| 68 | + } | ||
| 69 | + percentage.value = toNumber(unref(dataset), 2) | ||
| 70 | + dataset.value = toNumber((unref(dataset)), 2) | ||
| 58 | } catch (error) { | 71 | } catch (error) { |
| 59 | console.log(error) | 72 | console.log(error) |
| 60 | } | 73 | } |
| 61 | }, | 74 | }, |
| 62 | { | 75 | { |
| 63 | - deep: false | 76 | + deep: true |
| 64 | } | 77 | } |
| 65 | ) | 78 | ) |
| 66 | // 预览更新 | 79 | // 预览更新 |
| 67 | useChartDataFetch(props.chartConfig, useChartEditStore, (newData: number) => { | 80 | useChartDataFetch(props.chartConfig, useChartEditStore, (newData: number) => { |
| 81 | + percentage.value = toNumber(newData*(100/max.value), 2) | ||
| 68 | dataset.value = toNumber(newData, 2) | 82 | dataset.value = toNumber(newData, 2) |
| 69 | }) | 83 | }) |
| 70 | </script> | 84 | </script> |
| @@ -8,14 +8,6 @@ | @@ -8,14 +8,6 @@ | ||
| 8 | <n-button size="small" @click="optionData.attribute.bgColor1 = '#00e0db'"> 恢复默认 </n-button> | 8 | <n-button size="small" @click="optionData.attribute.bgColor1 = '#00e0db'"> 恢复默认 </n-button> |
| 9 | </SettingItem> | 9 | </SettingItem> |
| 10 | </SettingItemBox> | 10 | </SettingItemBox> |
| 11 | - <SettingItemBox :name="`装饰2`"> | ||
| 12 | - <SettingItem name="颜色"> | ||
| 13 | - <n-color-picker size="small" :modes="['hex']" v-model:value="optionData.attribute.bgColor2"></n-color-picker> | ||
| 14 | - </SettingItem> | ||
| 15 | - <SettingItem> | ||
| 16 | - <n-button size="small" @click="optionData.attribute.bgColor2 = '#66ffff'"> 恢复默认 </n-button> | ||
| 17 | - </SettingItem> | ||
| 18 | - </SettingItemBox> | ||
| 19 | </CollapseItem> | 11 | </CollapseItem> |
| 20 | </template> | 12 | </template> |
| 21 | 13 |
| @@ -32,7 +32,6 @@ | @@ -32,7 +32,6 @@ | ||
| 32 | <path | 32 | <path |
| 33 | id="矩形" | 33 | id="矩形" |
| 34 | fill-rule="evenodd" | 34 | fill-rule="evenodd" |
| 35 | - :style="{fill: attribute.bgColor2}" | ||
| 36 | opacity="0" | 35 | opacity="0" |
| 37 | d="M0 87.26L87.26 87.26L87.26 0L0 0L0 87.26Z" | 36 | d="M0 87.26L87.26 87.26L87.26 0L0 0L0 87.26Z" |
| 38 | /> | 37 | /> |
| 1 | +import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public' | ||
| 2 | +import { Decorates13Config } from './index' | ||
| 3 | +import { CreateComponentType } from '@/packages/index.d' | ||
| 4 | +import cloneDeep from 'lodash/cloneDeep' | ||
| 5 | + | ||
| 6 | +export const includes = ['legend', 'xAxis', 'yAxis', 'grid'] | ||
| 7 | + | ||
| 8 | +export const option = { | ||
| 9 | + dataset: 66, | ||
| 10 | + unitStr: '人', | ||
| 11 | + grid: { | ||
| 12 | + top: 200, | ||
| 13 | + bottom: 300 | ||
| 14 | + }, | ||
| 15 | + xAxis: { | ||
| 16 | + data: [], | ||
| 17 | + axisTick: { | ||
| 18 | + show: false | ||
| 19 | + }, | ||
| 20 | + axisLine: { | ||
| 21 | + show: false | ||
| 22 | + } | ||
| 23 | + }, | ||
| 24 | + yAxis: { | ||
| 25 | + splitLine: { | ||
| 26 | + show: false | ||
| 27 | + }, | ||
| 28 | + axisTick: { | ||
| 29 | + show: false | ||
| 30 | + }, | ||
| 31 | + axisLine: { | ||
| 32 | + show: false | ||
| 33 | + }, | ||
| 34 | + axisLabel: { | ||
| 35 | + show: false | ||
| 36 | + } | ||
| 37 | + }, | ||
| 38 | + series: [ | ||
| 39 | + { | ||
| 40 | + name: '', | ||
| 41 | + type: 'pictorialBar', | ||
| 42 | + symbolSize: [100, 45], | ||
| 43 | + symbolOffset: [-10, -20], | ||
| 44 | + z: 12, | ||
| 45 | + data: [ | ||
| 46 | + { | ||
| 47 | + name: '', | ||
| 48 | + value: 66, | ||
| 49 | + symbolPosition: 'end', | ||
| 50 | + itemStyle: { | ||
| 51 | + normal: { | ||
| 52 | + color: 'rgba(2, 163, 243,0.5)' //圆柱顶部颜色 | ||
| 53 | + } | ||
| 54 | + } | ||
| 55 | + } | ||
| 56 | + ] | ||
| 57 | + }, | ||
| 58 | + { | ||
| 59 | + name: '', | ||
| 60 | + type: 'pictorialBar', | ||
| 61 | + symbolSize: [100, 45], | ||
| 62 | + symbolOffset: [-10, 24], | ||
| 63 | + z: 12, | ||
| 64 | + data: [ | ||
| 65 | + { | ||
| 66 | + name: '', | ||
| 67 | + value: 66, | ||
| 68 | + itemStyle: { | ||
| 69 | + normal: { | ||
| 70 | + color: 'rgba(2, 163, 243, 1)' //圆柱底部颜色 | ||
| 71 | + } | ||
| 72 | + } | ||
| 73 | + } | ||
| 74 | + ] | ||
| 75 | + }, | ||
| 76 | + { | ||
| 77 | + type: 'bar', | ||
| 78 | + barWidth: 100, | ||
| 79 | + data: [ | ||
| 80 | + { | ||
| 81 | + name: '', | ||
| 82 | + value: 66, | ||
| 83 | + label: { | ||
| 84 | + normal: { | ||
| 85 | + show: true, | ||
| 86 | + formatter: '{c}' + '人', | ||
| 87 | + position: 'top', | ||
| 88 | + textStyle: { | ||
| 89 | + color: 'rgba(2, 163, 243, 1)', //柱子对应数值颜色 | ||
| 90 | + fontSize: 40, | ||
| 91 | + fontWeight: 600 | ||
| 92 | + } | ||
| 93 | + } | ||
| 94 | + }, | ||
| 95 | + itemStyle: { | ||
| 96 | + normal: { | ||
| 97 | + color: { | ||
| 98 | + x: 0, | ||
| 99 | + y: 0, | ||
| 100 | + x2: 0, | ||
| 101 | + y2: 1, | ||
| 102 | + type: 'linear', | ||
| 103 | + global: false, | ||
| 104 | + colorStops: [ | ||
| 105 | + { | ||
| 106 | + offset: 0, | ||
| 107 | + color: 'rgba(18, 246, 255, 0)' | ||
| 108 | + }, | ||
| 109 | + { | ||
| 110 | + offset: 1, | ||
| 111 | + color: 'rgba(2, 163, 243, 1)' //底部渐变颜色 | ||
| 112 | + } | ||
| 113 | + ] | ||
| 114 | + } | ||
| 115 | + } | ||
| 116 | + } | ||
| 117 | + } | ||
| 118 | + ] | ||
| 119 | + }, | ||
| 120 | + //往上是内部柱状图 | ||
| 121 | + //往下是外部柱状图 | ||
| 122 | + { | ||
| 123 | + name: '', | ||
| 124 | + type: 'pictorialBar', | ||
| 125 | + symbolSize: [340, 45], | ||
| 126 | + symbolOffset: [-10, -20], | ||
| 127 | + z: 12, | ||
| 128 | + data: [ | ||
| 129 | + { | ||
| 130 | + name: '', | ||
| 131 | + value: '100', | ||
| 132 | + symbolPosition: 'end', | ||
| 133 | + itemStyle: { | ||
| 134 | + normal: { | ||
| 135 | + color: 'rgba(0, 255, 136, 0)' //圆柱顶部颜色 | ||
| 136 | + } | ||
| 137 | + } | ||
| 138 | + } | ||
| 139 | + ] | ||
| 140 | + }, | ||
| 141 | + { | ||
| 142 | + name: '', | ||
| 143 | + type: 'pictorialBar', | ||
| 144 | + symbolSize: [150, 75], | ||
| 145 | + symbolOffset: [-10, 41], | ||
| 146 | + z: 12, | ||
| 147 | + data: [ | ||
| 148 | + { | ||
| 149 | + name: '', | ||
| 150 | + value: '100', | ||
| 151 | + itemStyle: { | ||
| 152 | + normal: { | ||
| 153 | + color: 'rgba(2, 163, 243, .1)' //圆柱底部颜色 | ||
| 154 | + } | ||
| 155 | + } | ||
| 156 | + } | ||
| 157 | + ] | ||
| 158 | + }, | ||
| 159 | + { | ||
| 160 | + name: '', | ||
| 161 | + type: 'pictorialBar', | ||
| 162 | + symbolSize: [150, 75], | ||
| 163 | + symbolOffset: [-10, 55], | ||
| 164 | + z: 11, | ||
| 165 | + data: [ | ||
| 166 | + { | ||
| 167 | + name: '', | ||
| 168 | + value: '100', | ||
| 169 | + itemStyle: { | ||
| 170 | + normal: { | ||
| 171 | + color: 'transparent', | ||
| 172 | + borderColor: 'rgba(2, 163, 243, 1)', //底部内圆圈颜色 | ||
| 173 | + borderWidth: 30 | ||
| 174 | + } | ||
| 175 | + } | ||
| 176 | + } | ||
| 177 | + ] | ||
| 178 | + }, | ||
| 179 | + { | ||
| 180 | + name: '', | ||
| 181 | + type: 'pictorialBar', | ||
| 182 | + symbolSize: [200, 100], | ||
| 183 | + symbolOffset: [-10, 62], | ||
| 184 | + z: 10, | ||
| 185 | + data: [ | ||
| 186 | + { | ||
| 187 | + name: '关井数', | ||
| 188 | + value: '100', | ||
| 189 | + itemStyle: { | ||
| 190 | + normal: { | ||
| 191 | + color: 'transparent', | ||
| 192 | + borderColor: 'rgba(2, 163, 243, 1)', //底部外圆圈颜色 | ||
| 193 | + borderType: 'dashed', | ||
| 194 | + borderWidth: 2 | ||
| 195 | + } | ||
| 196 | + } | ||
| 197 | + } | ||
| 198 | + ] | ||
| 199 | + }, | ||
| 200 | + { | ||
| 201 | + type: 'bar', | ||
| 202 | + silent: true, | ||
| 203 | + barWidth: 140, | ||
| 204 | + barGap: '-120%', | ||
| 205 | + data: [ | ||
| 206 | + { | ||
| 207 | + name: '', | ||
| 208 | + value: '100', | ||
| 209 | + label: { | ||
| 210 | + normal: { | ||
| 211 | + show: false | ||
| 212 | + } | ||
| 213 | + }, | ||
| 214 | + itemStyle: { | ||
| 215 | + normal: { | ||
| 216 | + color: { | ||
| 217 | + x: 1, | ||
| 218 | + y: 1, | ||
| 219 | + x2: 1, | ||
| 220 | + y2: 0, | ||
| 221 | + type: 'linear', | ||
| 222 | + global: false, | ||
| 223 | + colorStops: [ | ||
| 224 | + { | ||
| 225 | + offset: 0, | ||
| 226 | + color: 'rgba(0, 255, 136, 0)' | ||
| 227 | + }, | ||
| 228 | + { | ||
| 229 | + offset: 0.3, | ||
| 230 | + color: 'rgba(0, 255, 136, .1)' | ||
| 231 | + }, | ||
| 232 | + { | ||
| 233 | + offset: 0.5, | ||
| 234 | + color: 'rgba(0, 255, 136, .1)' | ||
| 235 | + }, | ||
| 236 | + { | ||
| 237 | + offset: 0.8, | ||
| 238 | + color: 'rgba(0, 255, 136, .1)' | ||
| 239 | + }, | ||
| 240 | + { | ||
| 241 | + offset: 1, | ||
| 242 | + color: 'rgba(0, 255, 136, 0)' //底部渐变颜色 | ||
| 243 | + } | ||
| 244 | + ] | ||
| 245 | + } | ||
| 246 | + } | ||
| 247 | + } | ||
| 248 | + } | ||
| 249 | + ] | ||
| 250 | + } | ||
| 251 | + ] | ||
| 252 | +} | ||
| 253 | + | ||
| 254 | +export default class Config extends PublicConfigClass implements CreateComponentType { | ||
| 255 | + public key: string = Decorates13Config.key | ||
| 256 | + public chartConfig = cloneDeep(Decorates13Config) | ||
| 257 | + // 图表配置项 | ||
| 258 | + public option = echartOptionProfixHandle(option, includes) | ||
| 259 | +} |
| 1 | +<template> | ||
| 2 | + <!-- Echarts 全局设置 --> | ||
| 3 | + <global-setting :optionData="optionData"></global-setting> | ||
| 4 | + <CollapseItem name="配置" :expanded="true"> | ||
| 5 | + <setting-item-box name="数据点配置"> | ||
| 6 | + <setting-item name="数据"> | ||
| 7 | + <n-input-number v-model:value="optionData.dataset"></n-input-number> | ||
| 8 | + </setting-item> | ||
| 9 | + <setting-item name="单位"> | ||
| 10 | + <n-input v-model:value="optionData.unitStr"></n-input> | ||
| 11 | + </setting-item> | ||
| 12 | + </setting-item-box> | ||
| 13 | + <setting-item-box name="grid配置"> | ||
| 14 | + <setting-item name="顶部"> | ||
| 15 | + <n-input-number v-model:value="optionData.grid.top"></n-input-number> | ||
| 16 | + </setting-item> | ||
| 17 | + <setting-item name="底部"> | ||
| 18 | + <n-input-number v-model:value="optionData.grid.bottom"></n-input-number> | ||
| 19 | + </setting-item> | ||
| 20 | + </setting-item-box> | ||
| 21 | + <setting-item-box name="内部圆柱"> | ||
| 22 | + <setting-item name="顶部颜色"> | ||
| 23 | + <n-color-picker size="small" v-model:value="seriesList[0].data[0].itemStyle.normal.color"></n-color-picker> | ||
| 24 | + </setting-item> | ||
| 25 | + <setting-item name="底部颜色"> | ||
| 26 | + <n-color-picker size="small" v-model:value="seriesList[1].data[0].itemStyle.normal.color"></n-color-picker> | ||
| 27 | + </setting-item> | ||
| 28 | + <setting-item name="数字颜色"> | ||
| 29 | + <n-color-picker | ||
| 30 | + size="small" | ||
| 31 | + v-model:value="seriesList[2].data[0].label.normal.textStyle.color" | ||
| 32 | + ></n-color-picker> | ||
| 33 | + </setting-item> | ||
| 34 | + <setting-item name="底部渐变色1"> | ||
| 35 | + <n-color-picker | ||
| 36 | + size="small" | ||
| 37 | + v-model:value="seriesList[2].data[0].itemStyle.normal.color.colorStops[0].color" | ||
| 38 | + ></n-color-picker> | ||
| 39 | + </setting-item> | ||
| 40 | + <setting-item name="底部渐变色1"> | ||
| 41 | + <n-color-picker | ||
| 42 | + size="small" | ||
| 43 | + v-model:value="seriesList[2].data[0].itemStyle.normal.color.colorStops[1].color" | ||
| 44 | + ></n-color-picker> | ||
| 45 | + </setting-item> | ||
| 46 | + </setting-item-box> | ||
| 47 | + <setting-item-box name="外部圆柱"> | ||
| 48 | + <setting-item name="顶部颜色"> | ||
| 49 | + <n-color-picker size="small" v-model:value="seriesList[3].data[0].itemStyle.normal.color"></n-color-picker> | ||
| 50 | + </setting-item> | ||
| 51 | + <setting-item name="底部颜色"> | ||
| 52 | + <n-color-picker size="small" v-model:value="seriesList[4].data[0].itemStyle.normal.color"></n-color-picker> | ||
| 53 | + </setting-item> | ||
| 54 | + <setting-item name="底部内圆圈颜色"> | ||
| 55 | + <n-color-picker | ||
| 56 | + size="small" | ||
| 57 | + v-model:value="seriesList[5].data[0].itemStyle.normal.borderColor" | ||
| 58 | + ></n-color-picker> | ||
| 59 | + </setting-item> | ||
| 60 | + <setting-item name="底部外圆圈颜色"> | ||
| 61 | + <n-color-picker | ||
| 62 | + size="small" | ||
| 63 | + v-model:value="seriesList[6].data[0].itemStyle.normal.borderColor" | ||
| 64 | + ></n-color-picker> | ||
| 65 | + </setting-item> | ||
| 66 | + <setting-item name="底部渐变色1"> | ||
| 67 | + <n-color-picker | ||
| 68 | + size="small" | ||
| 69 | + v-model:value="seriesList[7].data[0].itemStyle.normal.color.colorStops[0].color" | ||
| 70 | + ></n-color-picker> | ||
| 71 | + </setting-item> | ||
| 72 | + <setting-item name="底部渐变色2"> | ||
| 73 | + <n-color-picker | ||
| 74 | + size="small" | ||
| 75 | + v-model:value="seriesList[7].data[0].itemStyle.normal.color.colorStops[1].color" | ||
| 76 | + ></n-color-picker> | ||
| 77 | + </setting-item> | ||
| 78 | + <setting-item name="底部渐变色3"> | ||
| 79 | + <n-color-picker | ||
| 80 | + size="small" | ||
| 81 | + v-model:value="seriesList[7].data[0].itemStyle.normal.color.colorStops[2].color" | ||
| 82 | + ></n-color-picker> | ||
| 83 | + </setting-item> | ||
| 84 | + <setting-item name="底部渐变色4"> | ||
| 85 | + <n-color-picker | ||
| 86 | + size="small" | ||
| 87 | + v-model:value="seriesList[7].data[0].itemStyle.normal.color.colorStops[3].color" | ||
| 88 | + ></n-color-picker> | ||
| 89 | + </setting-item> | ||
| 90 | + <setting-item name="底部渐变色5"> | ||
| 91 | + <n-color-picker | ||
| 92 | + size="small" | ||
| 93 | + v-model:value="seriesList[7].data[0].itemStyle.normal.color.colorStops[4].color" | ||
| 94 | + ></n-color-picker> | ||
| 95 | + </setting-item> | ||
| 96 | + </setting-item-box> | ||
| 97 | + </CollapseItem> | ||
| 98 | +</template> | ||
| 99 | + | ||
| 100 | +<script setup lang="ts"> | ||
| 101 | +import { PropType, computed } from 'vue' | ||
| 102 | +import { GlobalThemeJsonType } from '@/settings/chartThemes/index' | ||
| 103 | +import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' | ||
| 104 | + | ||
| 105 | +const props = defineProps({ | ||
| 106 | + optionData: { | ||
| 107 | + type: Object as PropType<GlobalThemeJsonType> & PropType<any>, | ||
| 108 | + required: true | ||
| 109 | + } | ||
| 110 | +}) | ||
| 111 | + | ||
| 112 | +const seriesList = computed(() => { | ||
| 113 | + return props.optionData.series | ||
| 114 | +}) | ||
| 115 | +</script> |
| 1 | +import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d' | ||
| 2 | +import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d' | ||
| 3 | +import { useWidgetKey } from '@/packages/external/useWidgetKey' | ||
| 4 | + | ||
| 5 | +const { key, chartKey, conKey } = useWidgetKey('Decorates13',true) | ||
| 6 | + | ||
| 7 | +export const Decorates13Config: ConfigType = { | ||
| 8 | + key, | ||
| 9 | + chartKey, | ||
| 10 | + conKey, | ||
| 11 | + title: '装饰13', | ||
| 12 | + category: ChatCategoryEnum.DECORATE, | ||
| 13 | + categoryName: ChatCategoryEnumName.DECORATE, | ||
| 14 | + package: PackagesCategoryEnum.DECORATES, | ||
| 15 | + chartFrame: ChartFrameEnum.COMMON, | ||
| 16 | + image: 'decorates_13.png', | ||
| 17 | +} |
| 1 | +<template> | ||
| 2 | + <v-chart :theme="themeColor" :init-options="initOptions" :option="option.value" autoresize> </v-chart> | ||
| 3 | +</template> | ||
| 4 | + | ||
| 5 | +<script setup lang="ts"> | ||
| 6 | +import { PropType, watch, reactive } from 'vue' | ||
| 7 | +import VChart from 'vue-echarts' | ||
| 8 | +import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook' | ||
| 9 | +import { use } from 'echarts/core' | ||
| 10 | +import { CanvasRenderer } from 'echarts/renderers' | ||
| 11 | +import { LineChart } from 'echarts/charts' | ||
| 12 | +import config, { includes } from './config' | ||
| 13 | +import { mergeTheme } from '@/packages/public/chart' | ||
| 14 | +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' | ||
| 15 | +import { useChartDataFetch } from '@/hooks' | ||
| 16 | +import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components' | ||
| 17 | + | ||
| 18 | +const props = defineProps({ | ||
| 19 | + themeSetting: { | ||
| 20 | + type: Object, | ||
| 21 | + required: true | ||
| 22 | + }, | ||
| 23 | + themeColor: { | ||
| 24 | + type: Object, | ||
| 25 | + required: true | ||
| 26 | + }, | ||
| 27 | + chartConfig: { | ||
| 28 | + type: Object as PropType<config>, | ||
| 29 | + required: true | ||
| 30 | + } | ||
| 31 | +}) | ||
| 32 | + | ||
| 33 | +const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting) | ||
| 34 | + | ||
| 35 | +use([DatasetComponent, CanvasRenderer, LineChart, GridComponent, TooltipComponent, LegendComponent]) | ||
| 36 | + | ||
| 37 | +const option = reactive({ | ||
| 38 | + value: {} | ||
| 39 | +}) | ||
| 40 | + | ||
| 41 | +const dataHandle = (newData: number) => { | ||
| 42 | + let config = props.chartConfig.option | ||
| 43 | + config.series[2].data[0].value = newData | ||
| 44 | + config.series[2].data[0].label.normal.formatter = '{c}' + config.unitStr | ||
| 45 | + option.value = mergeTheme(props.chartConfig.option, props.themeSetting, includes) | ||
| 46 | + option.value = { ...props.chartConfig.option, ...config } | ||
| 47 | +} | ||
| 48 | + | ||
| 49 | +// 配置时 | ||
| 50 | +watch( | ||
| 51 | + () => props.chartConfig.option.dataset, | ||
| 52 | + (newData: number) => { | ||
| 53 | + try { | ||
| 54 | + dataHandle(newData) | ||
| 55 | + } catch (error) { | ||
| 56 | + console.log(error) | ||
| 57 | + } | ||
| 58 | + }, | ||
| 59 | + { | ||
| 60 | + immediate: true, | ||
| 61 | + } | ||
| 62 | +) | ||
| 63 | +// 预览时 | ||
| 64 | +useChartDataFetch(props.chartConfig, useChartEditStore, (resData: number) => { | ||
| 65 | + // @ts-ignore | ||
| 66 | + option.value.series[2].data[0].value = resData | ||
| 67 | +}) | ||
| 68 | +</script> |
| 1 | +import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public' | ||
| 2 | +import { Decorates14Config } from './index' | ||
| 3 | +import { CreateComponentType } from '@/packages/index.d' | ||
| 4 | +import cloneDeep from 'lodash/cloneDeep' | ||
| 5 | + | ||
| 6 | +export const includes = ['legend', 'xAxis', 'yAxis', 'grid'] | ||
| 7 | + | ||
| 8 | +const ydata = ['A2'] //y轴 | ||
| 9 | + | ||
| 10 | +export const option = { | ||
| 11 | + dataset: 60, | ||
| 12 | + backgroundColor: 'rgba(0,0,0,1)', | ||
| 13 | + grid: { | ||
| 14 | + left: '10%', | ||
| 15 | + top: 10, | ||
| 16 | + bottom: 10 | ||
| 17 | + }, | ||
| 18 | + tooltip: { | ||
| 19 | + show: false | ||
| 20 | + }, | ||
| 21 | + xAxis: { | ||
| 22 | + max: 100, | ||
| 23 | + splitLine: { | ||
| 24 | + show: false | ||
| 25 | + }, | ||
| 26 | + axisLine: { | ||
| 27 | + show: false | ||
| 28 | + }, | ||
| 29 | + axisLabel: { | ||
| 30 | + show: false | ||
| 31 | + }, | ||
| 32 | + axisTick: { | ||
| 33 | + show: false | ||
| 34 | + } | ||
| 35 | + }, | ||
| 36 | + yAxis: [ | ||
| 37 | + { | ||
| 38 | + type: 'category', | ||
| 39 | + inverse: false, | ||
| 40 | + data: ydata, | ||
| 41 | + axisLine: { | ||
| 42 | + show: false | ||
| 43 | + }, | ||
| 44 | + axisTick: { | ||
| 45 | + show: false | ||
| 46 | + }, | ||
| 47 | + axisLabel: { | ||
| 48 | + show: false | ||
| 49 | + } | ||
| 50 | + } | ||
| 51 | + ], | ||
| 52 | + series: [ | ||
| 53 | + { | ||
| 54 | + //内 | ||
| 55 | + type: 'bar', | ||
| 56 | + barWidth: 60, | ||
| 57 | + legendHoverLink: false, | ||
| 58 | + silent: true, | ||
| 59 | + itemStyle: { | ||
| 60 | + color: { | ||
| 61 | + type: 'linear', | ||
| 62 | + x: 0, | ||
| 63 | + y: 0, | ||
| 64 | + x2: 1, | ||
| 65 | + y2: 0, | ||
| 66 | + colorStops: [ | ||
| 67 | + { | ||
| 68 | + offset: 0, | ||
| 69 | + color: 'rgba(156,224,99,1)' // 0% 处的颜色 | ||
| 70 | + }, | ||
| 71 | + { | ||
| 72 | + offset: 1, | ||
| 73 | + color: 'rgba(12,245,243,1)' // 100% 处的颜色 | ||
| 74 | + } | ||
| 75 | + ], | ||
| 76 | + globalCoord: false // 缺省为 false | ||
| 77 | + } //底色 | ||
| 78 | + }, | ||
| 79 | + label: { | ||
| 80 | + normal: { | ||
| 81 | + show: true, | ||
| 82 | + textStyle: { | ||
| 83 | + color: '#fff', | ||
| 84 | + fontSize: 20 | ||
| 85 | + }, | ||
| 86 | + position: 'right', | ||
| 87 | + formatter: function (params: Recordable) { | ||
| 88 | + return '{white|' + params.value + '}' | ||
| 89 | + }, | ||
| 90 | + verticalAlign: 'bottom', | ||
| 91 | + rich: { | ||
| 92 | + white: { | ||
| 93 | + // backgroundColor: { | ||
| 94 | + // image: | ||
| 95 | + // 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADYAAAAZCAYAAAB6v90+AAAA2klEQVRYhe2YMUoDQRhG32zAwsKkyRGCHmE9hE3uuSkNSqogaOEBcgzXDVg+i2xhEdKYn2GWefDX33vlDCjoCu3QHrXQ68eGFUpC74EPYME0+ALahHbAOrfNldkktAfucptcmWNCzW0RQZNbIIoaVho1rDRqWGnUsNKoYaUx6bDv3BIBHBtgl9sigNeEPgDvTOsF/dgAB6AFNsCQVel/DJwaWuDA+JkTcTfo9sLnS4fOwvYDw0Bv0f2ZqJcxPG47OAx0jn7+iXobg0N306kunCXwDPwAT0AfPfgLAvYRIEVmrDQAAAAASUVORK5CYII=' | ||
| 96 | + // }, | ||
| 97 | + padding: [5, 0, 5, 5], | ||
| 98 | + align: 'center', | ||
| 99 | + fontSize: 16, | ||
| 100 | + color: 'black' | ||
| 101 | + } | ||
| 102 | + } | ||
| 103 | + } | ||
| 104 | + }, | ||
| 105 | + data: [60], | ||
| 106 | + z: 100 | ||
| 107 | + }, | ||
| 108 | + { | ||
| 109 | + //外 | ||
| 110 | + type: 'bar', | ||
| 111 | + barWidth: 61, | ||
| 112 | + barGap: '-100%', | ||
| 113 | + label: { | ||
| 114 | + normal: { | ||
| 115 | + show: false | ||
| 116 | + } | ||
| 117 | + }, | ||
| 118 | + legendHoverLink: false, | ||
| 119 | + silent: true, | ||
| 120 | + data: [100], | ||
| 121 | + itemStyle: { | ||
| 122 | + color: 'rgba(45, 46, 48,0.5)', | ||
| 123 | + borderWidth: 1, | ||
| 124 | + borderColor: '#fff' | ||
| 125 | + }, | ||
| 126 | + z: 98 | ||
| 127 | + }, | ||
| 128 | + { | ||
| 129 | + //分隔 | ||
| 130 | + type: 'pictorialBar', | ||
| 131 | + animationDuration: 0, | ||
| 132 | + itemStyle: { | ||
| 133 | + color: 'rgba(0,0,0,0.7)' | ||
| 134 | + }, | ||
| 135 | + symbolRepeat: 'fixed', | ||
| 136 | + symbolMargin: '8', | ||
| 137 | + symbol: 'rect', | ||
| 138 | + symbolClip: true, | ||
| 139 | + symbolSize: [4, 60], | ||
| 140 | + symbolPosition: 'start', | ||
| 141 | + symbolOffset: [0, 0], | ||
| 142 | + data: [60], | ||
| 143 | + z: 101 | ||
| 144 | + } | ||
| 145 | + ] | ||
| 146 | +} | ||
| 147 | + | ||
| 148 | +export default class Config extends PublicConfigClass implements CreateComponentType { | ||
| 149 | + public key: string = Decorates14Config.key | ||
| 150 | + public chartConfig = cloneDeep(Decorates14Config) | ||
| 151 | + // 图表配置项 | ||
| 152 | + public option = echartOptionProfixHandle(option, includes) | ||
| 153 | +} |
| 1 | +<template> | ||
| 2 | + <!-- Echarts 全局设置 --> | ||
| 3 | + <global-setting :optionData="optionData"></global-setting> | ||
| 4 | + <CollapseItem name="配置" :expanded="true"> | ||
| 5 | + <setting-item-box name="数据点配置"> | ||
| 6 | + <setting-item name="数据"> | ||
| 7 | + <n-input-number v-model:value="optionData.dataset"></n-input-number> | ||
| 8 | + </setting-item> | ||
| 9 | + </setting-item-box> | ||
| 10 | + <setting-item-box name="grid配置"> | ||
| 11 | + <setting-item name="顶部"> | ||
| 12 | + <n-input-number v-model:value="optionData.grid.top"></n-input-number> | ||
| 13 | + </setting-item> | ||
| 14 | + <setting-item name="底部"> | ||
| 15 | + <n-input-number v-model:value="optionData.grid.bottom"></n-input-number> | ||
| 16 | + </setting-item> | ||
| 17 | + </setting-item-box> | ||
| 18 | + <setting-item-box name="内外bar和中间分隔高度"> | ||
| 19 | + <setting-item name="内"> | ||
| 20 | + <n-input-number v-model:value="seriesList[0].barWidth"></n-input-number> | ||
| 21 | + </setting-item> | ||
| 22 | + <setting-item name="外"> | ||
| 23 | + <n-input-number v-model:value="seriesList[1].barWidth"></n-input-number> | ||
| 24 | + </setting-item> | ||
| 25 | + <setting-item name="分隔"> | ||
| 26 | + <n-input-number v-model:value="seriesList[2].symbolSize[1]"></n-input-number> | ||
| 27 | + </setting-item> | ||
| 28 | + </setting-item-box> | ||
| 29 | + <setting-item-box name="数值"> | ||
| 30 | + <setting-item name="颜色"> | ||
| 31 | + <n-color-picker v-model:value="seriesList[0].label.normal.rich.white.color"></n-color-picker> | ||
| 32 | + </setting-item> | ||
| 33 | + <setting-item name="大小"> | ||
| 34 | + <n-input-number v-model:value="seriesList[0].label.normal.rich.white.fontSize"></n-input-number> | ||
| 35 | + </setting-item> | ||
| 36 | + </setting-item-box> | ||
| 37 | + <setting-item-box name="内部bar"> | ||
| 38 | + <setting-item name="渐变色1"> | ||
| 39 | + <n-color-picker size="small" v-model:value="seriesList[0].itemStyle.color.colorStops[0].color"></n-color-picker> | ||
| 40 | + </setting-item> | ||
| 41 | + <setting-item name="渐变色2"> | ||
| 42 | + <n-color-picker size="small" v-model:value="seriesList[0].itemStyle.color.colorStops[1].color"></n-color-picker> | ||
| 43 | + </setting-item> | ||
| 44 | + </setting-item-box> | ||
| 45 | + <setting-item-box name="外部bar"> | ||
| 46 | + <setting-item name="颜色"> | ||
| 47 | + <n-color-picker size="small" v-model:value="seriesList[1].itemStyle.color"></n-color-picker> | ||
| 48 | + </setting-item> | ||
| 49 | + </setting-item-box> | ||
| 50 | + <setting-item-box name="分隔"> | ||
| 51 | + <setting-item name="颜色"> | ||
| 52 | + <n-color-picker size="small" v-model:value="seriesList[2].itemStyle.color"></n-color-picker> | ||
| 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 { GlobalThemeJsonType } from '@/settings/chartThemes/index' | ||
| 61 | +import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' | ||
| 62 | + | ||
| 63 | +const props = defineProps({ | ||
| 64 | + optionData: { | ||
| 65 | + type: Object as PropType<GlobalThemeJsonType> & PropType<any>, | ||
| 66 | + required: true | ||
| 67 | + } | ||
| 68 | +}) | ||
| 69 | + | ||
| 70 | +const seriesList = computed(() => { | ||
| 71 | + return props.optionData.series | ||
| 72 | +}) | ||
| 73 | +</script> |
| 1 | +import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d' | ||
| 2 | +import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d' | ||
| 3 | +import { useWidgetKey } from '@/packages/external/useWidgetKey' | ||
| 4 | + | ||
| 5 | +const { key, chartKey, conKey } = useWidgetKey('Decorates14',true) | ||
| 6 | + | ||
| 7 | +export const Decorates14Config: ConfigType = { | ||
| 8 | + key, | ||
| 9 | + chartKey, | ||
| 10 | + conKey, | ||
| 11 | + title: '装饰14', | ||
| 12 | + category: ChatCategoryEnum.DECORATE, | ||
| 13 | + categoryName: ChatCategoryEnumName.DECORATE, | ||
| 14 | + package: PackagesCategoryEnum.DECORATES, | ||
| 15 | + chartFrame: ChartFrameEnum.COMMON, | ||
| 16 | + image: 'decorates14.png', | ||
| 17 | +} |
| 1 | +<template> | ||
| 2 | + <v-chart :theme="themeColor" :init-options="initOptions" :option="option.value" autoresize> </v-chart> | ||
| 3 | +</template> | ||
| 4 | + | ||
| 5 | +<script setup lang="ts"> | ||
| 6 | +import { PropType, watch, reactive, onMounted } from 'vue' | ||
| 7 | +import VChart from 'vue-echarts' | ||
| 8 | +import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook' | ||
| 9 | +import { use } from 'echarts/core' | ||
| 10 | +import { CanvasRenderer } from 'echarts/renderers' | ||
| 11 | +import { LineChart } from 'echarts/charts' | ||
| 12 | +import config, { includes } from './config' | ||
| 13 | +import { mergeTheme } from '@/packages/public/chart' | ||
| 14 | +import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' | ||
| 15 | +import { useChartDataFetch } from '@/hooks' | ||
| 16 | +import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components' | ||
| 17 | + | ||
| 18 | +const props = defineProps({ | ||
| 19 | + themeSetting: { | ||
| 20 | + type: Object, | ||
| 21 | + required: true | ||
| 22 | + }, | ||
| 23 | + themeColor: { | ||
| 24 | + type: Object, | ||
| 25 | + required: true | ||
| 26 | + }, | ||
| 27 | + chartConfig: { | ||
| 28 | + type: Object as PropType<config>, | ||
| 29 | + required: true | ||
| 30 | + } | ||
| 31 | +}) | ||
| 32 | + | ||
| 33 | +const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting) | ||
| 34 | + | ||
| 35 | +use([DatasetComponent, CanvasRenderer, LineChart, GridComponent, TooltipComponent, LegendComponent]) | ||
| 36 | + | ||
| 37 | +const option = reactive<{ value: Recordable }>({ | ||
| 38 | + value: {} | ||
| 39 | +}) | ||
| 40 | + | ||
| 41 | +onMounted(() => { | ||
| 42 | + option.value = { ...props.chartConfig.option } | ||
| 43 | +}) | ||
| 44 | + | ||
| 45 | +const dataHandle = (newData: number) => { | ||
| 46 | + let config = props.chartConfig.option | ||
| 47 | + config.series[0].data = [newData] | ||
| 48 | + config.series[2].data = [newData] | ||
| 49 | + option.value = mergeTheme(props.chartConfig.option, props.themeSetting, includes) | ||
| 50 | + option.value = { ...props.chartConfig.option, ...config } | ||
| 51 | +} | ||
| 52 | + | ||
| 53 | +// 配置时 | ||
| 54 | +watch( | ||
| 55 | + () => props.chartConfig.option.dataset, | ||
| 56 | + (newData: number) => { | ||
| 57 | + try { | ||
| 58 | + dataHandle(newData) | ||
| 59 | + } catch (error) { | ||
| 60 | + console.log(error) | ||
| 61 | + } | ||
| 62 | + }, | ||
| 63 | + { | ||
| 64 | + immediate: true | ||
| 65 | + } | ||
| 66 | +) | ||
| 67 | +// 预览时 | ||
| 68 | +useChartDataFetch(props.chartConfig, useChartEditStore, (resData: number) => { | ||
| 69 | + option.value.series[0].data = [resData] | ||
| 70 | + option.value.series[2].data = [resData] | ||
| 71 | +}) | ||
| 72 | +</script> |
| 1 | +import { PublicConfigClass } from '@/packages/public' | ||
| 2 | +import { Decorates15Config } from './index' | ||
| 3 | +import { CreateComponentType } from '@/packages/index.d' | ||
| 4 | +import cloneDeep from 'lodash/cloneDeep' | ||
| 5 | +import { chartInitConfig } from '@/settings/designSetting' | ||
| 6 | +export const includes = ['legend', 'xAxis', 'yAxis', 'grid'] | ||
| 7 | + | ||
| 8 | +export const option = { | ||
| 9 | + styleConfig: { | ||
| 10 | + scale: 1 | ||
| 11 | + } | ||
| 12 | +} | ||
| 13 | + | ||
| 14 | +export default class Config extends PublicConfigClass implements CreateComponentType { | ||
| 15 | + public key = Decorates15Config.key | ||
| 16 | + public attr = { ...chartInitConfig, w: 300, h: 300, zIndex: -1 } | ||
| 17 | + public chartConfig = cloneDeep(Decorates15Config) | ||
| 18 | + public option = cloneDeep(option) | ||
| 19 | +} |
| 1 | +<template> | ||
| 2 | + <!-- Echarts 全局设置 --> | ||
| 3 | + <global-setting :optionData="optionData"></global-setting> | ||
| 4 | + <CollapseItem name="配置" :expanded="true"> | ||
| 5 | + <setting-item-box name="样式配置"> | ||
| 6 | + <setting-item name="缩放"> | ||
| 7 | + <n-input-number :min="0" v-model:value="optionData.styleConfig.scale"></n-input-number> | ||
| 8 | + </setting-item> | ||
| 9 | + </setting-item-box> | ||
| 10 | + </CollapseItem> | ||
| 11 | +</template> | ||
| 12 | + | ||
| 13 | +<script setup lang="ts"> | ||
| 14 | +import { PropType } from 'vue' | ||
| 15 | +import { option } from './config' | ||
| 16 | +import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' | ||
| 17 | + | ||
| 18 | +defineProps({ | ||
| 19 | + optionData: { | ||
| 20 | + type: Object as PropType<typeof option>, | ||
| 21 | + required: true | ||
| 22 | + } | ||
| 23 | +}) | ||
| 24 | +</script> |
| 1 | +import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d' | ||
| 2 | +import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d' | ||
| 3 | +import { useWidgetKey } from '@/packages/external/useWidgetKey' | ||
| 4 | + | ||
| 5 | +const { key, chartKey, conKey } = useWidgetKey('Decorates15',true) | ||
| 6 | + | ||
| 7 | +export const Decorates15Config: ConfigType = { | ||
| 8 | + key, | ||
| 9 | + chartKey, | ||
| 10 | + conKey, | ||
| 11 | + title: '装饰15', | ||
| 12 | + category: ChatCategoryEnum.DECORATE, | ||
| 13 | + categoryName: ChatCategoryEnumName.DECORATE, | ||
| 14 | + package: PackagesCategoryEnum.DECORATES, | ||
| 15 | + chartFrame: ChartFrameEnum.COMMON, | ||
| 16 | + image: 'decorates15.png', | ||
| 17 | +} |
| 1 | +<template> | ||
| 2 | + <div style="position: fixed" :style="{ width: `${w}px`, height: `${h}px` }"> | ||
| 3 | + <div :style="{ transform: `scale(${styleConfig.scale})` }" class="arc_reactor"> | ||
| 4 | + <div class="case_container"> | ||
| 5 | + <div class="e7"> | ||
| 6 | + <div class="semi_arc_3 e5_1"> | ||
| 7 | + <div class="semi_arc_3 e5_2"> | ||
| 8 | + <div class="semi_arc_3 e5_3"> | ||
| 9 | + <div class="semi_arc_3 e5_4"></div> | ||
| 10 | + </div> | ||
| 11 | + </div> | ||
| 12 | + </div> | ||
| 13 | + <div class="core2"></div> | ||
| 14 | + </div> | ||
| 15 | + <ul class="marks"> | ||
| 16 | + <li></li> | ||
| 17 | + <li></li> | ||
| 18 | + <li></li> | ||
| 19 | + <li></li> | ||
| 20 | + <li></li> | ||
| 21 | + <li></li> | ||
| 22 | + <li></li> | ||
| 23 | + <li></li> | ||
| 24 | + <li></li> | ||
| 25 | + <li></li> | ||
| 26 | + <li></li> | ||
| 27 | + <li></li> | ||
| 28 | + <li></li> | ||
| 29 | + <li></li> | ||
| 30 | + <li></li> | ||
| 31 | + <li></li> | ||
| 32 | + <li></li> | ||
| 33 | + <li></li> | ||
| 34 | + <li></li> | ||
| 35 | + <li></li> | ||
| 36 | + <li></li> | ||
| 37 | + <li></li> | ||
| 38 | + <li></li> | ||
| 39 | + <li></li> | ||
| 40 | + <li></li> | ||
| 41 | + <li></li> | ||
| 42 | + <li></li> | ||
| 43 | + <li></li> | ||
| 44 | + <li></li> | ||
| 45 | + <li></li> | ||
| 46 | + <li></li> | ||
| 47 | + <li></li> | ||
| 48 | + <li></li> | ||
| 49 | + <li></li> | ||
| 50 | + <li></li> | ||
| 51 | + <li></li> | ||
| 52 | + <li></li> | ||
| 53 | + <li></li> | ||
| 54 | + <li></li> | ||
| 55 | + <li></li> | ||
| 56 | + <li></li> | ||
| 57 | + <li></li> | ||
| 58 | + <li></li> | ||
| 59 | + <li></li> | ||
| 60 | + <li></li> | ||
| 61 | + <li></li> | ||
| 62 | + <li></li> | ||
| 63 | + <li></li> | ||
| 64 | + <li></li> | ||
| 65 | + <li></li> | ||
| 66 | + <li></li> | ||
| 67 | + <li></li> | ||
| 68 | + <li></li> | ||
| 69 | + <li></li> | ||
| 70 | + <li></li> | ||
| 71 | + <li></li> | ||
| 72 | + <li></li> | ||
| 73 | + <li></li> | ||
| 74 | + <li></li> | ||
| 75 | + <li></li> | ||
| 76 | + </ul> | ||
| 77 | + </div> | ||
| 78 | + </div> | ||
| 79 | + </div> | ||
| 80 | +</template> | ||
| 81 | + | ||
| 82 | +<script setup lang="ts"> | ||
| 83 | +import { PropType, toRefs, watch } from 'vue' | ||
| 84 | +import { CreateComponentType } from '@/packages/index.d' | ||
| 85 | +import { option } from './config' | ||
| 86 | + | ||
| 87 | +const props = defineProps({ | ||
| 88 | + chartConfig: { | ||
| 89 | + type: Object as PropType<CreateComponentType & typeof option>, | ||
| 90 | + required: true | ||
| 91 | + } | ||
| 92 | +}) | ||
| 93 | +const { w, h } = toRefs(props.chartConfig.attr) | ||
| 94 | + | ||
| 95 | +const { styleConfig } = toRefs(props.chartConfig.option) | ||
| 96 | + | ||
| 97 | +watch( | ||
| 98 | + () => styleConfig.value, | ||
| 99 | + (newValue: Recordable) => { | ||
| 100 | + styleConfig.value.scale = newValue.scale | ||
| 101 | + }, | ||
| 102 | + { | ||
| 103 | + immediate: true, | ||
| 104 | + deep: true | ||
| 105 | + } | ||
| 106 | +) | ||
| 107 | +</script> | ||
| 108 | + | ||
| 109 | +<style scoped> | ||
| 110 | +body { | ||
| 111 | + color: #02feff; | ||
| 112 | + overflow: hidden; | ||
| 113 | +} | ||
| 114 | + | ||
| 115 | +.core2 { | ||
| 116 | + background: #cedce0; | ||
| 117 | + width: 100px; | ||
| 118 | + height: 100px; | ||
| 119 | + -moz-border-radius: 50%; | ||
| 120 | + -webkit-border-radius: 50%; | ||
| 121 | + border-radius: 50%; | ||
| 122 | + border: 10px rgba(2, 255, 255, 0.15) solid; | ||
| 123 | + animation: flicker2 0.2s infinite; | ||
| 124 | + margin-left: auto; | ||
| 125 | + margin-right: auto; | ||
| 126 | + margin-top: 40px; | ||
| 127 | +} | ||
| 128 | + | ||
| 129 | +.big_core { | ||
| 130 | + background: #cedce0; | ||
| 131 | + width: 200px; | ||
| 132 | + height: 200px; | ||
| 133 | + -moz-border-radius: 50%; | ||
| 134 | + -webkit-border-radius: 50%; | ||
| 135 | + border-radius: 50%; | ||
| 136 | + border: 10px rgba(2, 255, 255, 0.15) solid; | ||
| 137 | + animation: big_flicker 0.2s infinite; | ||
| 138 | +} | ||
| 139 | + | ||
| 140 | +.c_ease { | ||
| 141 | + animation: colour_ease 3s infinite ease-in-out; | ||
| 142 | +} | ||
| 143 | + | ||
| 144 | +.counterspin5 { | ||
| 145 | + animation: rotate_anti 5s linear infinite; | ||
| 146 | +} | ||
| 147 | + | ||
| 148 | +.counterspin4 { | ||
| 149 | + animation: rotate_anti 4s linear infinite; | ||
| 150 | +} | ||
| 151 | + | ||
| 152 | +.semi_arc { | ||
| 153 | + width: 100px; | ||
| 154 | + height: 100px; | ||
| 155 | + border: 6px solid #02feff; | ||
| 156 | + background: rgba(2, 254, 255, 0.2); | ||
| 157 | + -moz-border-radius: 50%; | ||
| 158 | + -webkit-border-radius: 50%; | ||
| 159 | + border-radius: 50%; | ||
| 160 | + transform: rotateZ(0deg); | ||
| 161 | + transition: box-shadow 3s ease; | ||
| 162 | + text-align: center; | ||
| 163 | + line-height: 100px; | ||
| 164 | +} | ||
| 165 | + | ||
| 166 | +.semi_arc:hover { | ||
| 167 | + box-shadow: 0px 0px 30px rgba(2, 254, 255, 0.8); | ||
| 168 | + transition: 0.3s; | ||
| 169 | +} | ||
| 170 | + | ||
| 171 | +.semi_arc_2 { | ||
| 172 | + content: ''; | ||
| 173 | + position: absolute; | ||
| 174 | + width: 94%; | ||
| 175 | + height: 94%; | ||
| 176 | + left: 3%; | ||
| 177 | + top: 3%; | ||
| 178 | + border: 5px solid #02feff; | ||
| 179 | + -moz-border-radius: 50%; | ||
| 180 | + -webkit-border-radius: 50%; | ||
| 181 | + border-radius: 50%; | ||
| 182 | + -moz-box-sizing: border-box; | ||
| 183 | + -webkit-box-sizing: border-box; | ||
| 184 | + box-sizing: border-box; | ||
| 185 | + animation: rotate 4s linear infinite; | ||
| 186 | + text-align: center; | ||
| 187 | + line-height: 129px; | ||
| 188 | +} | ||
| 189 | + | ||
| 190 | +.semi_arc_2:after { | ||
| 191 | + content: ''; | ||
| 192 | + position: absolute; | ||
| 193 | + width: 94%; | ||
| 194 | + height: 94%; | ||
| 195 | + left: 3%; | ||
| 196 | + top: 3%; | ||
| 197 | + border: 4px solid #02feff; | ||
| 198 | + -moz-border-radius: 50%; | ||
| 199 | + -webkit-border-radius: 50%; | ||
| 200 | + border-radius: 50%; | ||
| 201 | + -moz-box-sizing: border-box; | ||
| 202 | + -webkit-box-sizing: border-box; | ||
| 203 | + box-sizing: border-box; | ||
| 204 | + animation: rotate_anti 2s linear infinite; | ||
| 205 | +} | ||
| 206 | + | ||
| 207 | +.semi_arc_3 { | ||
| 208 | + content: ''; | ||
| 209 | + position: absolute; | ||
| 210 | + width: 94%; | ||
| 211 | + height: 94%; | ||
| 212 | + left: 3%; | ||
| 213 | + top: 3%; | ||
| 214 | + border: 5px solid #02feff; | ||
| 215 | + -moz-border-radius: 50%; | ||
| 216 | + -webkit-border-radius: 50%; | ||
| 217 | + border-radius: 50%; | ||
| 218 | + -moz-box-sizing: border-box; | ||
| 219 | + -webkit-box-sizing: border-box; | ||
| 220 | + box-sizing: border-box; | ||
| 221 | + animation: rotate 4s linear infinite; | ||
| 222 | + text-align: center; | ||
| 223 | + line-height: 129px; | ||
| 224 | +} | ||
| 225 | + | ||
| 226 | +.arc { | ||
| 227 | + width: 100px; | ||
| 228 | + height: 100px; | ||
| 229 | + border: 6px solid #02feff; | ||
| 230 | + background: rgba(2, 254, 255, 0.2); | ||
| 231 | + -moz-border-radius: 50%; | ||
| 232 | + -webkit-border-radius: 50%; | ||
| 233 | + border-radius: 50%; | ||
| 234 | + -moz-transform: rotateY(-30deg) translateZ(-200px); | ||
| 235 | + -ms-transform: rotateY(-30deg) translateZ(-200px); | ||
| 236 | + -webkit-transform: rotateY(-30deg) translateZ(-200px); | ||
| 237 | + transform: rotateY(-30deg) translateZ(-200px); | ||
| 238 | + transform: rotateZ(0deg); | ||
| 239 | + transition: box-shadow 3s ease; | ||
| 240 | + text-align: center; | ||
| 241 | + line-height: 100px; | ||
| 242 | +} | ||
| 243 | + | ||
| 244 | +.arc:hover { | ||
| 245 | + box-shadow: 0px 0px 30px rgba(2, 254, 255, 0.8); | ||
| 246 | + transition: 0.3s; | ||
| 247 | +} | ||
| 248 | + | ||
| 249 | +.arc:after { | ||
| 250 | + content: ''; | ||
| 251 | + position: absolute; | ||
| 252 | + width: 94%; | ||
| 253 | + height: 94%; | ||
| 254 | + left: 3%; | ||
| 255 | + top: 3%; | ||
| 256 | + border: 4px solid #02feff; | ||
| 257 | + -moz-border-radius: 50%; | ||
| 258 | + -webkit-border-radius: 50%; | ||
| 259 | + border-radius: 50%; | ||
| 260 | + -moz-box-sizing: border-box; | ||
| 261 | + -webkit-box-sizing: border-box; | ||
| 262 | + box-sizing: border-box; | ||
| 263 | + animation: rotate 4s linear infinite; | ||
| 264 | +} | ||
| 265 | + | ||
| 266 | +.e1:after { | ||
| 267 | + border-color: rgba(2, 255, 255, 0.6); | ||
| 268 | + border-left: 5px solid transparent; | ||
| 269 | + border-right: 5px solid transparent; | ||
| 270 | +} | ||
| 271 | + | ||
| 272 | +.e2:after { | ||
| 273 | + border-color: rgba(2, 255, 255, 0.6); | ||
| 274 | + border-left: 5px solid transparent; | ||
| 275 | + border-right: 5px solid transparent; | ||
| 276 | + border-bottom: 5px solid transparent; | ||
| 277 | +} | ||
| 278 | + | ||
| 279 | +.e3 { | ||
| 280 | + border-left: 6px solid transparent; | ||
| 281 | + border-right: 6px solid transparent; | ||
| 282 | + animation: rotate 5s linear infinite; | ||
| 283 | +} | ||
| 284 | + | ||
| 285 | +.e3:after { | ||
| 286 | + border-color: rgba(2, 255, 255, 0.6); | ||
| 287 | + border-top: 5px solid transparent; | ||
| 288 | + border-bottom: 5px solid transparent; | ||
| 289 | +} | ||
| 290 | + | ||
| 291 | +.e4 { | ||
| 292 | + width: 150px; | ||
| 293 | + height: 150px; | ||
| 294 | +} | ||
| 295 | + | ||
| 296 | +.e4_1 { | ||
| 297 | + border-color: rgba(2, 255, 255, 0.3); | ||
| 298 | + border-left: 5px solid transparent; | ||
| 299 | + border-right: 5px solid transparent; | ||
| 300 | +} | ||
| 301 | + | ||
| 302 | +.e4_1:after { | ||
| 303 | + border-color: rgba(2, 255, 255, 0.6); | ||
| 304 | + border-top: 4px solid transparent; | ||
| 305 | + border-bottom: 4px solid transparent; | ||
| 306 | +} | ||
| 307 | + | ||
| 308 | +.e5 { | ||
| 309 | + width: 200px; | ||
| 310 | + height: 200px; | ||
| 311 | +} | ||
| 312 | + | ||
| 313 | +.e5_1 { | ||
| 314 | + color: rgba(2, 255, 255, 0.15); | ||
| 315 | + border: 2px solid; | ||
| 316 | + border-left: 2px solid transparent; | ||
| 317 | + animation: rotate 5s linear infinite; | ||
| 318 | +} | ||
| 319 | + | ||
| 320 | +.e5_2 { | ||
| 321 | + color: rgba(2, 255, 255, 0.7); | ||
| 322 | + border: 4px solid; | ||
| 323 | + border-left: 4px solid transparent; | ||
| 324 | + border-right: 4px solid transparent; | ||
| 325 | + animation: rotate_anti 4s linear infinite; | ||
| 326 | +} | ||
| 327 | + | ||
| 328 | +.e5_3 { | ||
| 329 | + color: rgba(2, 255, 255, 0.5); | ||
| 330 | + border: 2px solid; | ||
| 331 | + border-left: 2px solid transparent; | ||
| 332 | + border-right: 2px solid transparent; | ||
| 333 | + animation: rotate 3s linear infinite; | ||
| 334 | +} | ||
| 335 | + | ||
| 336 | +.e5_4 { | ||
| 337 | + color: rgba(2, 255, 255, 0.15); | ||
| 338 | + border: 4px solid; | ||
| 339 | + border-left: 4px solid transparent; | ||
| 340 | + border-right: 4px solid transparent; | ||
| 341 | + border-bottom: 4px solid transparent; | ||
| 342 | + animation: rotate_anti 2s linear infinite; | ||
| 343 | +} | ||
| 344 | + | ||
| 345 | +.e6 { | ||
| 346 | + border-color: transparent; | ||
| 347 | + background: rgba(255, 255, 255, 0); | ||
| 348 | + width: 200px; | ||
| 349 | + height: 200px; | ||
| 350 | +} | ||
| 351 | + | ||
| 352 | +@keyframes rotate { | ||
| 353 | + 0% { | ||
| 354 | + transform: rotateZ(0deg); | ||
| 355 | + } | ||
| 356 | + 100% { | ||
| 357 | + transform: rotateZ(360deg); | ||
| 358 | + } | ||
| 359 | +} | ||
| 360 | +@keyframes rotate_anti { | ||
| 361 | + 0% { | ||
| 362 | + transform: rotateZ(360deg); | ||
| 363 | + } | ||
| 364 | + 100% { | ||
| 365 | + transform: rotateZ(0deg); | ||
| 366 | + } | ||
| 367 | +} | ||
| 368 | +@keyframes colour_ease { | ||
| 369 | + 0% { | ||
| 370 | + border-color: #02feff; | ||
| 371 | + } | ||
| 372 | + 50% { | ||
| 373 | + border-color: rgba(2, 254, 255, 0.5); | ||
| 374 | + } | ||
| 375 | + 100% { | ||
| 376 | + border-color: #02feff; | ||
| 377 | + } | ||
| 378 | +} | ||
| 379 | +@keyframes flicker { | ||
| 380 | + 0% { | ||
| 381 | + box-shadow: 0px 0px 16px 8px rgba(150, 255, 255, 0.5), inset 0px 1px 4px 2px rgba(21, 211, 233, 0.3); | ||
| 382 | + } | ||
| 383 | + 40% { | ||
| 384 | + box-shadow: 0px 0px 16px 8px rgba(150, 255, 255, 0.5), inset 0px 1px 4px 2px rgba(21, 211, 233, 0.3); | ||
| 385 | + } | ||
| 386 | + 50% { | ||
| 387 | + box-shadow: 0px 0px 16px 6px rgba(150, 255, 255, 0.5), inset 0px 1px 100px 2px rgba(21, 211, 233, 0.3); | ||
| 388 | + } | ||
| 389 | + 60% { | ||
| 390 | + box-shadow: 0px 0px 16px 8px rgba(150, 255, 255, 0.5), inset 0px 1px 4px 2px rgba(21, 211, 233, 0.3); | ||
| 391 | + } | ||
| 392 | + 100% { | ||
| 393 | + box-shadow: 0px 0px 16px 8px rgba(150, 255, 255, 0.5), inset 0px 1px 4px 2px rgba(21, 211, 233, 0.3); | ||
| 394 | + } | ||
| 395 | +} | ||
| 396 | +@keyframes flicker2 { | ||
| 397 | + 0% { | ||
| 398 | + box-shadow: 0px 0px 60px 25px rgba(150, 255, 255, 0.5), inset 0px 1px 4px 2px rgba(21, 211, 233, 0.3); | ||
| 399 | + } | ||
| 400 | + 40% { | ||
| 401 | + box-shadow: 0px 0px 60px 25px rgba(150, 255, 255, 0.5), inset 0px 1px 4px 2px rgba(21, 211, 233, 0.3); | ||
| 402 | + } | ||
| 403 | + 50% { | ||
| 404 | + box-shadow: 0px 0px 50px 17px rgba(150, 255, 255, 0.5), inset 0px 1px 100px 2px rgba(21, 211, 233, 0.3); | ||
| 405 | + } | ||
| 406 | + 60% { | ||
| 407 | + box-shadow: 0px 0px 60px 25px rgba(150, 255, 255, 0.5), inset 0px 1px 4px 2px rgba(21, 211, 233, 0.3); | ||
| 408 | + } | ||
| 409 | + 100% { | ||
| 410 | + box-shadow: 0px 0px 60px 25px rgba(150, 255, 255, 0.5), inset 0px 1px 4px 2px rgba(21, 211, 233, 0.3); | ||
| 411 | + } | ||
| 412 | +} | ||
| 413 | +@keyframes big_flicker { | ||
| 414 | + 0% { | ||
| 415 | + box-shadow: 0px 0px 40px 20px rgba(150, 255, 255, 0.5), inset 0px 1px 30px 15px rgba(21, 211, 233, 0.3); | ||
| 416 | + } | ||
| 417 | + 40% { | ||
| 418 | + box-shadow: 0px 0px 40px 20px rgba(150, 255, 255, 0.5), inset 0px 1px 30px 15px rgba(21, 211, 233, 0.3); | ||
| 419 | + } | ||
| 420 | + 50% { | ||
| 421 | + box-shadow: 0px 0px 35px 17px rgba(150, 255, 255, 0.5), inset 0px 1px 50px 40px rgba(21, 211, 233, 0.3); | ||
| 422 | + } | ||
| 423 | + 60% { | ||
| 424 | + box-shadow: 0px 0px 40px 20px rgba(150, 255, 255, 0.5), inset 0px 1px 30px 15px rgba(21, 211, 233, 0.3); | ||
| 425 | + } | ||
| 426 | + 100% { | ||
| 427 | + box-shadow: 0px 0px 40px 20px rgba(150, 255, 255, 0.5), inset 0px 1px 30px 15px rgba(21, 211, 233, 0.3); | ||
| 428 | + } | ||
| 429 | +} | ||
| 430 | +html, | ||
| 431 | +body { | ||
| 432 | + height: 100%; | ||
| 433 | +} | ||
| 434 | + | ||
| 435 | +ul { | ||
| 436 | + list-style: none; | ||
| 437 | + margin: 0; | ||
| 438 | + padding: 0; | ||
| 439 | +} | ||
| 440 | + | ||
| 441 | +.arc_reactor { | ||
| 442 | + position: relative; | ||
| 443 | + top: 50%; | ||
| 444 | + margin-top: -125px; | ||
| 445 | + margin-left: auto; | ||
| 446 | + margin-right: auto; | ||
| 447 | + width: 250px; | ||
| 448 | + height: 250px; | ||
| 449 | + border-radius: 50%; | ||
| 450 | + box-shadow: 0px 0px 50px 15px rgba(2, 255, 255, 0.3), inset 0px 0px 50px 15px rgba(2, 255, 255, 0.3); | ||
| 451 | +} | ||
| 452 | + | ||
| 453 | +.core2 { | ||
| 454 | + background: #cedce0; | ||
| 455 | + width: 110px; | ||
| 456 | + height: 110px; | ||
| 457 | + -moz-border-radius: 50%; | ||
| 458 | + -webkit-border-radius: 50%; | ||
| 459 | + border-radius: 50%; | ||
| 460 | + border: 5px solid rgba(2, 255, 255, 0.15); | ||
| 461 | + animation: flicker2 0.2s infinite; | ||
| 462 | + margin-left: auto; | ||
| 463 | + margin-right: auto; | ||
| 464 | + margin-top: 40px; | ||
| 465 | +} | ||
| 466 | + | ||
| 467 | +.e7 { | ||
| 468 | + width: 95.25%; | ||
| 469 | + height: 95.25%; | ||
| 470 | + left: 2.5475%; | ||
| 471 | + right: 2.5475%; | ||
| 472 | + border: 6px solid transparent; | ||
| 473 | + background: transparent; | ||
| 474 | + -moz-border-radius: 50%; | ||
| 475 | + -webkit-border-radius: 50%; | ||
| 476 | + border-radius: 50%; | ||
| 477 | + transform: rotateZ(0deg); | ||
| 478 | + transition: box-shadow 3s ease; | ||
| 479 | + text-align: center; | ||
| 480 | + line-height: 100px; | ||
| 481 | +} | ||
| 482 | + | ||
| 483 | +.case_container { | ||
| 484 | + width: 210px; | ||
| 485 | + height: 210px; | ||
| 486 | + border-radius: 50%; | ||
| 487 | + position: absolute; | ||
| 488 | + margin-left: 20px; | ||
| 489 | + margin-top: 20px; | ||
| 490 | +} | ||
| 491 | + | ||
| 492 | +.marks li { | ||
| 493 | + display: block; | ||
| 494 | + width: 3px; | ||
| 495 | + height: 11px; | ||
| 496 | + background: rgba(2, 254, 255, 0.8); | ||
| 497 | + position: absolute; | ||
| 498 | + margin-left: 105px; | ||
| 499 | + margin-top: -110px; | ||
| 500 | + animation: colour_ease2 3s infinite ease-in-out; | ||
| 501 | +} | ||
| 502 | + | ||
| 503 | +@keyframes colour_ease2 { | ||
| 504 | + 0% { | ||
| 505 | + background: #02feff; | ||
| 506 | + } | ||
| 507 | + 50% { | ||
| 508 | + background: rgba(2, 254, 255, 0.3); | ||
| 509 | + } | ||
| 510 | + 100% { | ||
| 511 | + background: #02feff; | ||
| 512 | + } | ||
| 513 | +} | ||
| 514 | +.marks li:first-child { | ||
| 515 | + transform: rotate(6deg) translateY(125px); | ||
| 516 | +} | ||
| 517 | + | ||
| 518 | +.marks li:nth-child(2) { | ||
| 519 | + transform: rotate(12deg) translateY(125px); | ||
| 520 | +} | ||
| 521 | + | ||
| 522 | +.marks li:nth-child(3) { | ||
| 523 | + transform: rotate(18deg) translateY(125px); | ||
| 524 | +} | ||
| 525 | + | ||
| 526 | +.marks li:nth-child(4) { | ||
| 527 | + transform: rotate(24deg) translateY(125px); | ||
| 528 | +} | ||
| 529 | + | ||
| 530 | +.marks li:nth-child(5) { | ||
| 531 | + transform: rotate(30deg) translateY(125px); | ||
| 532 | +} | ||
| 533 | + | ||
| 534 | +.marks li:nth-child(6) { | ||
| 535 | + transform: rotate(36deg) translateY(125px); | ||
| 536 | +} | ||
| 537 | + | ||
| 538 | +.marks li:nth-child(7) { | ||
| 539 | + transform: rotate(42deg) translateY(125px); | ||
| 540 | +} | ||
| 541 | + | ||
| 542 | +.marks li:nth-child(8) { | ||
| 543 | + transform: rotate(48deg) translateY(125px); | ||
| 544 | +} | ||
| 545 | + | ||
| 546 | +.marks li:nth-child(9) { | ||
| 547 | + transform: rotate(54deg) translateY(125px); | ||
| 548 | +} | ||
| 549 | + | ||
| 550 | +.marks li:nth-child(10) { | ||
| 551 | + transform: rotate(60deg) translateY(125px); | ||
| 552 | +} | ||
| 553 | + | ||
| 554 | +.marks li:nth-child(11) { | ||
| 555 | + transform: rotate(66deg) translateY(125px); | ||
| 556 | +} | ||
| 557 | + | ||
| 558 | +.marks li:nth-child(12) { | ||
| 559 | + transform: rotate(72deg) translateY(125px); | ||
| 560 | +} | ||
| 561 | + | ||
| 562 | +.marks li:nth-child(13) { | ||
| 563 | + transform: rotate(78deg) translateY(125px); | ||
| 564 | +} | ||
| 565 | + | ||
| 566 | +.marks li:nth-child(14) { | ||
| 567 | + transform: rotate(84deg) translateY(125px); | ||
| 568 | +} | ||
| 569 | + | ||
| 570 | +.marks li:nth-child(15) { | ||
| 571 | + transform: rotate(90deg) translateY(125px); | ||
| 572 | +} | ||
| 573 | + | ||
| 574 | +.marks li:nth-child(16) { | ||
| 575 | + transform: rotate(96deg) translateY(125px); | ||
| 576 | +} | ||
| 577 | + | ||
| 578 | +.marks li:nth-child(17) { | ||
| 579 | + transform: rotate(102deg) translateY(125px); | ||
| 580 | +} | ||
| 581 | + | ||
| 582 | +.marks li:nth-child(18) { | ||
| 583 | + transform: rotate(108deg) translateY(125px); | ||
| 584 | +} | ||
| 585 | + | ||
| 586 | +.marks li:nth-child(19) { | ||
| 587 | + transform: rotate(114deg) translateY(125px); | ||
| 588 | +} | ||
| 589 | + | ||
| 590 | +.marks li:nth-child(20) { | ||
| 591 | + transform: rotate(120deg) translateY(125px); | ||
| 592 | +} | ||
| 593 | + | ||
| 594 | +.marks li:nth-child(21) { | ||
| 595 | + transform: rotate(126deg) translateY(125px); | ||
| 596 | +} | ||
| 597 | + | ||
| 598 | +.marks li:nth-child(22) { | ||
| 599 | + transform: rotate(132deg) translateY(125px); | ||
| 600 | +} | ||
| 601 | + | ||
| 602 | +.marks li:nth-child(23) { | ||
| 603 | + transform: rotate(138deg) translateY(125px); | ||
| 604 | +} | ||
| 605 | + | ||
| 606 | +.marks li:nth-child(24) { | ||
| 607 | + transform: rotate(144deg) translateY(125px); | ||
| 608 | +} | ||
| 609 | + | ||
| 610 | +.marks li:nth-child(25) { | ||
| 611 | + transform: rotate(150deg) translateY(125px); | ||
| 612 | +} | ||
| 613 | + | ||
| 614 | +.marks li:nth-child(26) { | ||
| 615 | + transform: rotate(156deg) translateY(125px); | ||
| 616 | +} | ||
| 617 | + | ||
| 618 | +.marks li:nth-child(27) { | ||
| 619 | + transform: rotate(162deg) translateY(125px); | ||
| 620 | +} | ||
| 621 | + | ||
| 622 | +.marks li:nth-child(28) { | ||
| 623 | + transform: rotate(168deg) translateY(125px); | ||
| 624 | +} | ||
| 625 | + | ||
| 626 | +.marks li:nth-child(29) { | ||
| 627 | + transform: rotate(174deg) translateY(125px); | ||
| 628 | +} | ||
| 629 | + | ||
| 630 | +.marks li:nth-child(30) { | ||
| 631 | + transform: rotate(180deg) translateY(125px); | ||
| 632 | +} | ||
| 633 | + | ||
| 634 | +.marks li:nth-child(31) { | ||
| 635 | + transform: rotate(186deg) translateY(125px); | ||
| 636 | +} | ||
| 637 | + | ||
| 638 | +.marks li:nth-child(32) { | ||
| 639 | + transform: rotate(192deg) translateY(125px); | ||
| 640 | +} | ||
| 641 | + | ||
| 642 | +.marks li:nth-child(33) { | ||
| 643 | + transform: rotate(198deg) translateY(125px); | ||
| 644 | +} | ||
| 645 | + | ||
| 646 | +.marks li:nth-child(34) { | ||
| 647 | + transform: rotate(204deg) translateY(125px); | ||
| 648 | +} | ||
| 649 | + | ||
| 650 | +.marks li:nth-child(35) { | ||
| 651 | + transform: rotate(210deg) translateY(125px); | ||
| 652 | +} | ||
| 653 | + | ||
| 654 | +.marks li:nth-child(36) { | ||
| 655 | + transform: rotate(216deg) translateY(125px); | ||
| 656 | +} | ||
| 657 | + | ||
| 658 | +.marks li:nth-child(37) { | ||
| 659 | + transform: rotate(222deg) translateY(125px); | ||
| 660 | +} | ||
| 661 | + | ||
| 662 | +.marks li:nth-child(38) { | ||
| 663 | + transform: rotate(228deg) translateY(125px); | ||
| 664 | +} | ||
| 665 | + | ||
| 666 | +.marks li:nth-child(39) { | ||
| 667 | + transform: rotate(234deg) translateY(125px); | ||
| 668 | +} | ||
| 669 | + | ||
| 670 | +.marks li:nth-child(40) { | ||
| 671 | + transform: rotate(240deg) translateY(125px); | ||
| 672 | +} | ||
| 673 | + | ||
| 674 | +.marks li:nth-child(41) { | ||
| 675 | + transform: rotate(246deg) translateY(125px); | ||
| 676 | +} | ||
| 677 | + | ||
| 678 | +.marks li:nth-child(42) { | ||
| 679 | + transform: rotate(252deg) translateY(125px); | ||
| 680 | +} | ||
| 681 | + | ||
| 682 | +.marks li:nth-child(43) { | ||
| 683 | + transform: rotate(258deg) translateY(125px); | ||
| 684 | +} | ||
| 685 | + | ||
| 686 | +.marks li:nth-child(44) { | ||
| 687 | + transform: rotate(264deg) translateY(125px); | ||
| 688 | +} | ||
| 689 | + | ||
| 690 | +.marks li:nth-child(45) { | ||
| 691 | + transform: rotate(270deg) translateY(125px); | ||
| 692 | +} | ||
| 693 | + | ||
| 694 | +.marks li:nth-child(46) { | ||
| 695 | + transform: rotate(276deg) translateY(125px); | ||
| 696 | +} | ||
| 697 | + | ||
| 698 | +.marks li:nth-child(47) { | ||
| 699 | + transform: rotate(282deg) translateY(125px); | ||
| 700 | +} | ||
| 701 | + | ||
| 702 | +.marks li:nth-child(48) { | ||
| 703 | + transform: rotate(288deg) translateY(125px); | ||
| 704 | +} | ||
| 705 | + | ||
| 706 | +.marks li:nth-child(49) { | ||
| 707 | + transform: rotate(294deg) translateY(125px); | ||
| 708 | +} | ||
| 709 | + | ||
| 710 | +.marks li:nth-child(50) { | ||
| 711 | + transform: rotate(300deg) translateY(125px); | ||
| 712 | +} | ||
| 713 | + | ||
| 714 | +.marks li:nth-child(51) { | ||
| 715 | + transform: rotate(306deg) translateY(125px); | ||
| 716 | +} | ||
| 717 | + | ||
| 718 | +.marks li:nth-child(52) { | ||
| 719 | + transform: rotate(312deg) translateY(125px); | ||
| 720 | +} | ||
| 721 | + | ||
| 722 | +.marks li:nth-child(53) { | ||
| 723 | + transform: rotate(318deg) translateY(125px); | ||
| 724 | +} | ||
| 725 | + | ||
| 726 | +.marks li:nth-child(54) { | ||
| 727 | + transform: rotate(324deg) translateY(125px); | ||
| 728 | +} | ||
| 729 | + | ||
| 730 | +.marks li:nth-child(55) { | ||
| 731 | + transform: rotate(330deg) translateY(125px); | ||
| 732 | +} | ||
| 733 | + | ||
| 734 | +.marks li:nth-child(56) { | ||
| 735 | + transform: rotate(336deg) translateY(125px); | ||
| 736 | +} | ||
| 737 | + | ||
| 738 | +.marks li:nth-child(57) { | ||
| 739 | + transform: rotate(342deg) translateY(125px); | ||
| 740 | +} | ||
| 741 | + | ||
| 742 | +.marks li:nth-child(58) { | ||
| 743 | + transform: rotate(348deg) translateY(125px); | ||
| 744 | +} | ||
| 745 | + | ||
| 746 | +.marks li:nth-child(59) { | ||
| 747 | + transform: rotate(354deg) translateY(125px); | ||
| 748 | +} | ||
| 749 | + | ||
| 750 | +.marks li:nth-child(60) { | ||
| 751 | + transform: rotate(360deg) translateY(125px); | ||
| 752 | +} | ||
| 753 | +</style> |
| 1 | +import { PublicConfigClass } from '@/packages/public' | ||
| 2 | +import { Decorates16Config } from './index' | ||
| 3 | +import { CreateComponentType } from '@/packages/index.d' | ||
| 4 | +import cloneDeep from 'lodash/cloneDeep' | ||
| 5 | +import { chartInitConfig } from '@/settings/designSetting' | ||
| 6 | +export const includes = ['legend', 'xAxis', 'yAxis', 'grid'] | ||
| 7 | + | ||
| 8 | +export const option = { | ||
| 9 | + dataset: 20, | ||
| 10 | + unit: '台', | ||
| 11 | + mainCicleColor: '#03A6E0CC', | ||
| 12 | + subCicleColor: '#03A6E07F', | ||
| 13 | + textColor:'green' | ||
| 14 | +} | ||
| 15 | + | ||
| 16 | +export default class Config extends PublicConfigClass implements CreateComponentType { | ||
| 17 | + public key = Decorates16Config.key | ||
| 18 | + public attr = { ...chartInitConfig, w: 150, h: 120, zIndex: -1 } | ||
| 19 | + public chartConfig = cloneDeep(Decorates16Config) | ||
| 20 | + public option = cloneDeep(option) | ||
| 21 | +} |
| 1 | +<template> | ||
| 2 | + <!-- Echarts 全局设置 --> | ||
| 3 | + <global-setting :optionData="optionData"></global-setting> | ||
| 4 | + <CollapseItem name="配置" :expanded="true"> | ||
| 5 | + <setting-item-box name="数据"> | ||
| 6 | + <setting-item name="数据源"> | ||
| 7 | + <n-input-number :min="0" v-model:value="optionData.dataset"></n-input-number> | ||
| 8 | + </setting-item> | ||
| 9 | + <setting-item name="单位"> | ||
| 10 | + <n-input v-model:value="optionData.unit"></n-input> | ||
| 11 | + </setting-item> | ||
| 12 | + </setting-item-box> | ||
| 13 | + <setting-item-box name="颜色"> | ||
| 14 | + <setting-item name="颜色1"> | ||
| 15 | + <n-color-picker v-model:value="optionData.mainCicleColor"></n-color-picker> | ||
| 16 | + </setting-item> | ||
| 17 | + <setting-item name="颜色2"> | ||
| 18 | + <n-color-picker v-model:value="optionData.subCicleColor"></n-color-picker> | ||
| 19 | + </setting-item> | ||
| 20 | + <setting-item name="文字颜色"> | ||
| 21 | + <n-color-picker v-model:value="optionData.textColor"></n-color-picker> | ||
| 22 | + </setting-item> | ||
| 23 | + </setting-item-box> | ||
| 24 | + </CollapseItem> | ||
| 25 | +</template> | ||
| 26 | + | ||
| 27 | +<script setup lang="ts"> | ||
| 28 | +import { PropType } from 'vue' | ||
| 29 | +import { option } from './config' | ||
| 30 | +import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' | ||
| 31 | + | ||
| 32 | +defineProps({ | ||
| 33 | + optionData: { | ||
| 34 | + type: Object as PropType<typeof option>, | ||
| 35 | + required: true | ||
| 36 | + } | ||
| 37 | +}) | ||
| 38 | +</script> |
| 1 | +import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d' | ||
| 2 | +import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d' | ||
| 3 | +import { useWidgetKey } from '@/packages/external/useWidgetKey' | ||
| 4 | + | ||
| 5 | +const { key, chartKey, conKey } = useWidgetKey('Decorates16',true) | ||
| 6 | + | ||
| 7 | +export const Decorates16Config: ConfigType = { | ||
| 8 | + key, | ||
| 9 | + chartKey, | ||
| 10 | + conKey, | ||
| 11 | + title: '装饰16', | ||
| 12 | + category: ChatCategoryEnum.DECORATE, | ||
| 13 | + categoryName: ChatCategoryEnumName.DECORATE, | ||
| 14 | + package: PackagesCategoryEnum.DECORATES, | ||
| 15 | + chartFrame: ChartFrameEnum.COMMON, | ||
| 16 | + image: 'decorates16.png', | ||
| 17 | +} |
| 1 | +<template> | ||
| 2 | + <div class="go-content-box"> | ||
| 3 | + <svg | ||
| 4 | + xmlns="http://www.w3.org/2000/svg" | ||
| 5 | + xmlns:xlink="http://www.w3.org/1999/xlink" | ||
| 6 | + :width="w" | ||
| 7 | + :height="h" | ||
| 8 | + viewBox="0 0 180 180" | ||
| 9 | + > | ||
| 10 | + <g opacity="0.6" transform="translate(11 14) scale(1.6)"> | ||
| 11 | + <defs> | ||
| 12 | + <polygon :id="polygonId" points="15, 46.5, 21, 47.5, 21, 52.5, 15, 53.5" /> | ||
| 13 | + </defs> | ||
| 14 | + <circle | ||
| 15 | + cx="50" | ||
| 16 | + cy="50" | ||
| 17 | + r="45" | ||
| 18 | + fill="transparent" | ||
| 19 | + :stroke="mainCicleColor || defaultColor[0]" | ||
| 20 | + stroke-width="10" | ||
| 21 | + stroke-dasharray="80, 100, 30, 100" | ||
| 22 | + > | ||
| 23 | + <animateTransform | ||
| 24 | + attributeName="transform" | ||
| 25 | + type="rotate" | ||
| 26 | + values="0 50 50;360 50 50" | ||
| 27 | + :dur="`${dur}s`" | ||
| 28 | + repeatCount="indefinite" | ||
| 29 | + /> | ||
| 30 | + </circle> | ||
| 31 | + <circle | ||
| 32 | + cx="50" | ||
| 33 | + cy="50" | ||
| 34 | + r="45" | ||
| 35 | + fill="transparent" | ||
| 36 | + :stroke="subCicleColor || defaultColor[1]" | ||
| 37 | + stroke-width="6" | ||
| 38 | + stroke-dasharray="50, 66, 100, 66" | ||
| 39 | + > | ||
| 40 | + <animateTransform | ||
| 41 | + attributeName="transform" | ||
| 42 | + type="rotate" | ||
| 43 | + values="0 50 50;-360 50 50" | ||
| 44 | + :dur="`${dur}s`" | ||
| 45 | + repeatCount="indefinite" | ||
| 46 | + /> | ||
| 47 | + </circle> | ||
| 48 | + <circle | ||
| 49 | + cx="50" | ||
| 50 | + cy="50" | ||
| 51 | + r="38" | ||
| 52 | + fill="transparent" | ||
| 53 | + :stroke="subCicleColor || defaultColor[1]" | ||
| 54 | + stroke-width="1" | ||
| 55 | + stroke-dasharray="5, 1" | ||
| 56 | + /> | ||
| 57 | + <use | ||
| 58 | + v-for="(foo, i) in new Array(20).fill(0)" | ||
| 59 | + :key="i" | ||
| 60 | + :xlink:href="`#${polygonId}`" | ||
| 61 | + :stroke="mainCicleColor || defaultColor[0]" | ||
| 62 | + :fill="Math.random() > 0.4 ? 'transparent' : mainCicleColor" | ||
| 63 | + > | ||
| 64 | + <animateTransform | ||
| 65 | + attributeName="transform" | ||
| 66 | + type="rotate" | ||
| 67 | + values="0 50 50;360 50 50" | ||
| 68 | + :dur="`${dur}s`" | ||
| 69 | + :begin="`${(i * dur) / 20}s`" | ||
| 70 | + repeatCount="indefinite" | ||
| 71 | + /> | ||
| 72 | + </use> | ||
| 73 | + <circle | ||
| 74 | + cx="50" | ||
| 75 | + cy="50" | ||
| 76 | + r="26" | ||
| 77 | + fill="transparent" | ||
| 78 | + :stroke="subCicleColor || defaultColor[1]" | ||
| 79 | + stroke-width="1" | ||
| 80 | + stroke-dasharray="5, 1" | ||
| 81 | + /> | ||
| 82 | + <text x="50" y="55" text-anchor="middle" :style="{ fill: textColor, opacity: 1 }" font-size="14"> | ||
| 83 | + {{ dataset + unit }} | ||
| 84 | + </text> | ||
| 85 | + </g> | ||
| 86 | + </svg> | ||
| 87 | + </div> | ||
| 88 | +</template> | ||
| 89 | +<script setup lang="ts"> | ||
| 90 | +import { PropType, toRefs, ref } from 'vue' | ||
| 91 | +import { CreateComponentType } from '@/packages/index.d' | ||
| 92 | +import { option } from './config' | ||
| 93 | + | ||
| 94 | +const props = defineProps({ | ||
| 95 | + chartConfig: { | ||
| 96 | + type: Object as PropType<CreateComponentType & typeof option>, | ||
| 97 | + required: true | ||
| 98 | + } | ||
| 99 | +}) | ||
| 100 | +const { w, h } = toRefs(props.chartConfig.attr) | ||
| 101 | + | ||
| 102 | +const { mainCicleColor, subCicleColor, dataset, unit, textColor } = toRefs(props.chartConfig.option) | ||
| 103 | + | ||
| 104 | +const id = Number(Math.random().toString().substring(2, 10) + Date.now()).toString(36) | ||
| 105 | + | ||
| 106 | +const dur = ref(3) | ||
| 107 | + | ||
| 108 | +const polygonId = ref(`decoration-9-polygon-${id}`) | ||
| 109 | + | ||
| 110 | +const defaultColor = ref(['rgba(3, 166, 224, 0.8)', 'rgba(3, 166, 224, 0.5)']) | ||
| 111 | +</script> | ||
| 112 | + | ||
| 113 | +<style lang="scss" scoped> | ||
| 114 | +.go-content-box { | ||
| 115 | + width: v-bind('w+"px"'); | ||
| 116 | + height: v-bind('h+"px"'); | ||
| 117 | + display: flex; | ||
| 118 | + align-items: center; | ||
| 119 | + justify-content: center; | ||
| 120 | +} | ||
| 121 | +</style> |