feat: 增加得分环 边框 图片等

This commit is contained in:
huanghao1412 2024-01-25 16:57:18 +08:00
parent 9e30c6b6af
commit c615c38eb9
46 changed files with 1351 additions and 156 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -38,7 +38,7 @@ defineProps({
</script>
<style lang="scss" scoped>
$leftWidth: 100px;
$leftWidth: 90px;
@include go('config-item-box') {
position: relative;
display: flex;

View File

@ -0,0 +1,10 @@
import { publicInterface } from "@/api/path";
import { commonDataType, SinglePointType } from '@/store/modules/chartEditStore/chartEditStore.d'
import { CreateComponentType } from '@/packages/index.d'
export const handleSinglePoint = (targetComponent: CreateComponentType) => {
let { enable, pointId } = (targetComponent.commonData as commonDataType).singlePoint as SinglePointType
if(!enable) return
return publicInterface('/dcim/system/custom_large_screen', 'get_point_value', pointId)
}

View File

@ -10,6 +10,7 @@ import { handlePointHistory } from './commonDataComponents/usePointHistoryRes'
import { handleEnergyUseHistory } from './commonDataComponents/useEnergyUseHistoryRes';
import { handleRecordValueHistory } from './commonDataComponents/useRecordValueHistoryRes'
import { handlePointRealTime } from './commonDataComponents/usePointRealTimeRes'
import { handleSinglePoint } from './commonDataComponents/useSinglePointRes'
import { ResultErrcode } from '@/enums/httpEnum'
// 获取类型
@ -39,23 +40,39 @@ export const useChartCommonData = (
// }
// if(!dataset.dimensions) return
if(targetComponent.option){
let seriesItem = cloneDeep(targetComponent.option.series[0])
let series = []
if(dataset.dimensions.length - 1) {
for(let i = 0; i < dataset.dimensions.length - 1; i++) {
series.push(cloneDeep(seriesItem))
const SingleDataArr = [
CurrentSourceEnum.SINGLEPOINT
]
const currentSource = targetComponent.commonData?.currentSource
// 多个值的处理方式
if(SingleDataArr.every(_ => _ !== currentSource)) {
let seriesItem = cloneDeep(targetComponent.option.series[0])
let series = []
if(dataset.dimensions.length - 1) {
for(let i = 0; i < dataset.dimensions.length - 1; i++) {
series.push(cloneDeep(seriesItem))
}
}
else {
series = [seriesItem]
}
if (vChartRef.value) {
setOption(vChartRef.value, { series, dataset: dataset })
}
}
else {
series = [seriesItem]
}
if (vChartRef.value) {
setOption(vChartRef.value, { series, dataset: dataset })
else if(SingleDataArr.some(_ => _ === currentSource)) { // 单个值的处理
if(targetComponent.commonData[currentSource]?.result) {
stopWatch = true
targetComponent.commonData[currentSource].result = dataset
setTimeout(() => {
stopWatch = false
}, 500)
}
}
}
}
}
let stopWatch = false
const requestIntervalFn = () => {
const chartEditStore = useChartEditStore()
@ -89,6 +106,9 @@ export const useChartCommonData = (
case CurrentSourceEnum.POINTREALTIME:
res = await handlePointRealTime(targetComponent)
break;
case CurrentSourceEnum.SINGLEPOINT:
res = await handleSinglePoint(targetComponent)
break;
default:
break;
}
@ -113,6 +133,7 @@ export const useChartCommonData = (
watch(
() => targetComponent.commonData,
() => {
if(stopWatch) return
fetchFn()
},
{
@ -120,7 +141,6 @@ export const useChartCommonData = (
deep: true
}
)
// 定时时间
const time = targetInterval && targetInterval.value ? targetInterval.value : globalRequestInterval.value
// 单位

View File

@ -2,6 +2,7 @@ import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public'
import { PieCircleConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import cloneDeep from 'lodash/cloneDeep'
import { CurrentSourceEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
export const includes = []
@ -14,6 +15,13 @@ const option = {
show: true,
},
dataset: 0.25,
titleContrl: {
showPercent: false,
showUnit: false,
showSubText: true,
showSubTextUnit: true,
max: 100,
},
title: {
text: 25 + "%",
x: "center",
@ -21,6 +29,11 @@ const option = {
textStyle: {
color: "#56B9F8",
fontSize: 30
},
subtext: '',
subtextStyle: {
color: "#56B9F8",
fontSize: 30
}
},
series: [
@ -56,6 +69,10 @@ const option = {
}
export default class Config extends PublicConfigClass implements CreateComponentType {
constructor() {
super();
this.commonData.currentSource = CurrentSourceEnum.SINGLEPOINT
}
public key: string = PieCircleConfig.key
public chartConfig = cloneDeep(PieCircleConfig)

View File

@ -2,19 +2,54 @@
<!-- 遍历 seriesList -->
<CollapseItem v-for="(item, index) in config.series" :key="index" :name="`圆环`" :expanded="true">
<SettingItemBox name="数据">
<SettingItem name="数值">
<n-input-number v-model:value="config.dataset" :min="0" :max="1" :step="0.01" size="small" placeholder="数值">
</n-input-number>
<SettingItem>
<n-space>
<n-switch v-model:value="config.titleContrl.showPercent" size="small" />
<n-text>是否百分比</n-text>
</n-space>
</SettingItem>
<SettingItem v-if="!config.titleContrl.showPercent" name="最大值">
<n-input-number v-model:value="config.titleContrl.max" :min="0" :step="1" size="small" placeholder="请输入最大值"/>
</SettingItem>
<SettingItem v-if="!config.titleContrl.showPercent">
<n-space>
<n-switch v-model:value="config.titleContrl.showUnit" size="small" />
<n-text>展示单位</n-text>
</n-space>
</SettingItem>
</SettingItemBox>
<!-- 中心标题 -->
<SettingItemBox v-if="config.title" name="标题">
<SettingItem name="颜色">
<n-color-picker size="small" :modes="['hex']" v-model:value="config.title.textStyle.color"></n-color-picker>
</SettingItem>
<SettingItem name="字体大小">
<n-input-number
v-model:value="config.title.textStyle.fontSize"
v-model:value="config.title.textStyle.fontSize"
:min="0"
:step="1"
size="small"
placeholder="字体大小"
>
</n-input-number>
</SettingItem>
</SettingItemBox>
<SettingItemBox name="副标题">
<SettingItem>
<n-space>
<n-switch v-model:value="config.titleContrl.showSubText" size="small" />
<n-text>展示副标题</n-text>
</n-space>
</SettingItem>
<SettingItem>
<n-space>
<n-switch v-model:value="config.titleContrl.showSubTextUnit" size="small" />
<n-text>展示单位</n-text>
</n-space>
</SettingItem>
<SettingItem name="颜色">
<n-color-picker size="small" :modes="['hex']" v-model:value="config.title.subtextStyle.color"></n-color-picker>
</SettingItem>
<SettingItem name="字体大小">
<n-input-number
v-model:value="config.title.subtextStyle.fontSize"
:min="0"
:step="1"
size="small"

View File

@ -6,7 +6,7 @@ export const PieCircleConfig: ConfigType = {
key: 'PieCircle',
chartKey: 'VPieCircle',
conKey: 'VCPieCircle',
title: '饼图-',
title: '饼图-得分环',
category: ChatCategoryEnum.PIE,
categoryName: ChatCategoryEnumName.PIE,
package: PackagesCategoryEnum.CHARTS,

View File

@ -3,7 +3,7 @@
</template>
<script setup lang="ts">
import { PropType, reactive, watch } from 'vue'
import { PropType, reactive, watch, ref } from 'vue'
import VChart from 'vue-echarts'
import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook'
import { use } from 'echarts/core'
@ -11,7 +11,7 @@ import { CanvasRenderer } from 'echarts/renderers'
import { PieChart } from 'echarts/charts'
import { mergeTheme } from '@/packages/public/chart'
import config, { includes } from './config'
import { useChartDataFetch } from '@/hooks'
import { useChartCommonData, useChartDataFetch } from '@/hooks'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent, TitleComponent } from 'echarts/components'
@ -38,31 +38,76 @@ const option = reactive({
value: {}
})
// const dataHandle = (newData: any) => {
// const d = parseFloat(`${newData}`) * 100
// let config = props.chartConfig.option
// config.title.text = `${+d.toFixed(2)}%`
// config.series[0].data[0].value[0] = d
// config.series[0].data[1].value[0] = 100 - d
// option.value = mergeTheme(props.chartConfig.option, props.themeSetting, includes)
// option.value = props.chartConfig.option
// }
// //
// watch(
// () => props.chartConfig.option.dataset,
// newData => {
// try {
// dataHandle(newData)
// } catch (error) {
// console.log(error)
// }
// },
// {
// immediate: true,
// deep: false
// }
// )
const dataHandle = (newData: any) => {
const d = parseFloat(`${newData}`) * 100
const { name, unit, value } = newData
let config = props.chartConfig.option
config.title.text = `${+d.toFixed(2)}%`
config.series[0].data[0].value[0] = d
config.series[0].data[1].value[0] = 100 - d
const { showPercent, showUnit, showSubText, showSubTextUnit, max } = config.titleContrl
config.title.subtext = showSubText ? name: ''
config.title.subtext += showSubTextUnit && unit ? showSubText ? '(a)'.replace('a', unit) : unit : ''
if(showPercent) {
config.title.text = `${value * 100}%`
config.series[0].data[0].value[0] = value <= 1 ? value * 100 : 100
config.series[0].data[1].value[0] = value <= 1 ? (1 - value) * 100 : 0
}
else {
config.title.text = `${value}${showUnit ? '(a)'.replace('a', unit) : ''}`
config.series[0].data[0].value[0] = value
config.series[0].data[1].value[0] = max - value
}
option.value = mergeTheme(props.chartConfig.option, props.themeSetting, includes)
option.value = props.chartConfig.option
}
//
watch(
() => props.chartConfig.option.dataset,
() => props.chartConfig.commonData,
newData => {
try {
dataHandle(newData)
const data = newData[newData.currentSource]
dataHandle(data.result)
} catch (error) {
console.log(error)
}
},
{
immediate: true,
deep: false
deep: true
}
)
watch(() => props.chartConfig.option.titleContrl, (v) => {
const commonData = props.chartConfig.commonData
const data = commonData[commonData.currentSource]
dataHandle(data.result)
}, {
immediate: true,
deep: true,
})
//
useChartDataFetch(props.chartConfig, useChartEditStore, (resData: number) => {
@ -74,4 +119,6 @@ useChartDataFetch(props.chartConfig, useChartEditStore, (resData: number) => {
// @ts-ignore
option.value.series[0].data[1].value[0] = 100 - d
})
const { vChartRef } = useChartCommonData(props.chartConfig, useChartEditStore)
</script>

View File

@ -13,7 +13,7 @@ export enum PieTypeEnum {
}
export const PieTypeObject = {
[PieTypeEnum.NORMAL]: 'nomal',
[PieTypeEnum.NORMAL]: 'normal',
[PieTypeEnum.RING]: 'ring',
[PieTypeEnum.ROSE]: 'rose'
}
@ -26,7 +26,7 @@ const otherConfig = {
const option = {
...otherConfig,
type: 'ring',
type: 'normal',
tooltip: {
show: true,
trigger: 'item'

View File

@ -2,11 +2,11 @@
<!-- Echarts 全局设置 -->
<global-setting :optionData="optionData"></global-setting>
<CollapseItem name="饼图配置" :expanded="true">
<SettingItemBox name="类型">
<SettingItem>
<n-select v-model:value="optionData.type" size="small" :options="fontWeightOptions" />
</SettingItem>
</SettingItemBox>
<!-- <SettingItemBox name="类型">-->
<!-- <SettingItem>-->
<!-- <n-select v-model:value="optionData.type" size="small" :options="fontWeightOptions" />-->
<!-- </SettingItem>-->
<!-- </SettingItemBox>-->
<SettingItemBox name="动画" :alone="true">
<SettingItem>
<n-space>

View File

@ -103,7 +103,7 @@ watch(
() => props.chartConfig.option.type,
newData => {
try {
if (newData === 'nomal') {
if (newData === 'normal') {
props.chartConfig.option.series[0].radius = '70%'
props.chartConfig.option.series[0].roseType = false
} else if (newData === 'ring') {

View File

@ -0,0 +1,78 @@
import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public'
import { PieCommon1Config } from './index'
import { CreateComponentType } from '@/packages/index.d'
import cloneDeep from 'lodash/cloneDeep'
import dataJson from './data.json'
export const includes = ['legend']
export enum PieTypeEnum {
NORMAL = '常规图',
RING = '环形图',
ROSE = '玫瑰图'
}
export const PieTypeObject = {
[PieTypeEnum.NORMAL]: 'normal',
[PieTypeEnum.RING]: 'ring',
[PieTypeEnum.ROSE]: 'rose'
}
// 其它配置
const otherConfig = {
// 轮播动画
isCarousel: false,
}
const option = {
...otherConfig,
type: 'ring',
tooltip: {
show: true,
trigger: 'item'
},
legend: {
show: true
},
dataset: { ...dataJson },
series: [
{
type: 'pie',
radius: ['40%', '65%'],
center: ['50%', '60%'],
roseType: false,
avoidLabelOverlap: false,
itemStyle: {
show: true,
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2
},
label: {
show: false,
position: 'center',
formatter: '{b}',
fontSize:12
},
emphasis: {
label: {
show: true,
fontSize: '40',
fontWeight: 'bold'
}
},
labelLine: {
show: false
}
}
]
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key: string = PieCommon1Config.key
public chartConfig = cloneDeep(PieCommon1Config)
// 图表配置项
public option = echartOptionProfixHandle(option, includes)
}

View File

@ -0,0 +1,99 @@
<template>
<!-- Echarts 全局设置 -->
<global-setting :optionData="optionData"></global-setting>
<CollapseItem name="饼图配置" :expanded="true">
<!-- <SettingItemBox name="类型">-->
<!-- <SettingItem>-->
<!-- <n-select v-model:value="optionData.type" size="small" :options="fontWeightOptions" />-->
<!-- </SettingItem>-->
<!-- </SettingItemBox>-->
<SettingItemBox name="动画" :alone="true">
<SettingItem>
<n-space>
<n-switch v-model:value="optionData.isCarousel" size="small"></n-switch>
<n-text>开启<n-text :depth="3">将自动隐藏图例</n-text></n-text>
</n-space>
</SettingItem>
<SettingItem>
<n-text :depth="3">无鼠标点击图例场景时可强行打开图例</n-text>
</SettingItem>
</SettingItemBox>
<SettingItemBox name="标签">
<SettingItem>
<n-space>
<n-switch v-model:value="optionData.series[0].label.show" size="small"></n-switch>
<n-text>展示标签</n-text>
</n-space>
</SettingItem>
<setting-item>
<n-space>
<n-switch v-model:value="optionData.series[0].labelLine.show" size="small"></n-switch>
<n-text>引导线</n-text>
</n-space>
</setting-item>
<SettingItem name="位置">
<n-select v-model:value="optionData.series[0].label.position" size="small" :options="labelConfig.position" />
</SettingItem>
<setting-item name="展示类型">
<n-select v-model:value="optionData.series[0].label.formatter" size="small" :options="labelFormatterOptions" />
</setting-item>
</SettingItemBox>
<setting-item-box name="圆角">
<setting-item>
<n-space>
<n-input-number
v-model:value="optionData.series[0].itemStyle.borderRadius"
size="small"
:min="0"
></n-input-number>
<n-text>圆角大小</n-text>
</n-space>
</setting-item>
<setting-item>
<n-space>
<n-input-number
v-model:value="optionData.series[0].itemStyle.borderWidth"
size="small"
:min="0"
></n-input-number>
<n-text>线条宽度</n-text>
</n-space>
</setting-item>
</setting-item-box>
</CollapseItem>
</template>
<script setup lang="ts">
import { PropType, watch } from 'vue'
import { GlobalThemeJsonType } from '@/settings/chartThemes/index'
import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { PieTypeObject, PieTypeEnum } from './config'
import { labelConfig } from '@/packages/chartConfiguration/echarts'
const props = defineProps({
optionData: {
type: Object as PropType<GlobalThemeJsonType>,
required: true
}
})
const fontWeightOptions = [
{
label: PieTypeEnum.NORMAL,
value: PieTypeObject[PieTypeEnum.NORMAL]
},
{
label: PieTypeEnum.RING,
value: PieTypeObject[PieTypeEnum.RING]
},
{
label: PieTypeEnum.ROSE,
value: PieTypeObject[PieTypeEnum.ROSE]
}
]
const labelFormatterOptions = [
{ label: '数据名', value: '{b}' },
{ label: '百分比', value: '{d}' },
{ label: '列名:百分比', value: '{b}:{d}%' }
]
</script>

View File

@ -0,0 +1,33 @@
{
"dimensions": ["product", "data1"],
"source": [
{
"product": "Mon",
"data1": 120
},
{
"product": "Tue",
"data1": 200
},
{
"product": "Wed",
"data1": 150
},
{
"product": "Thu",
"data1": 80
},
{
"product": "Fri",
"data1": 70
},
{
"product": "Sat",
"data1": 110
},
{
"product": "Sun",
"data1": 130
}
]
}

View File

@ -0,0 +1,14 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const PieCommon1Config: ConfigType = {
key: 'PieCommon1',
chartKey: 'VPieCommon1',
conKey: 'VCPieCommon1',
title: '饼图-环形图',
category: ChatCategoryEnum.PIE,
categoryName: ChatCategoryEnumName.PIE,
package: PackagesCategoryEnum.CHARTS,
chartFrame: ChartFrameEnum.ECHARTS,
image: 'pie.png'
}

View File

@ -0,0 +1,151 @@
<template>
<v-chart
ref="vChartRef"
autoresize
:init-options="initOptions"
:theme="themeColor"
:option="option"
:manual-update="isPreview()"
@mouseover="handleHighlight"
@mouseout="handleDownplay"
></v-chart>
</template>
<script setup lang="ts">
import { computed, PropType, onMounted, watch } from 'vue'
import VChart from 'vue-echarts'
import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { PieChart } from 'echarts/charts'
import { mergeTheme } from '@/packages/public/chart'
import config, { includes } from './config'
import {useChartCommonData, useChartDataFetch} from '@/hooks'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { isPreview } from '@/utils'
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
import dataJson from './data.json'
const props = defineProps({
themeSetting: {
type: Object,
required: true
},
themeColor: {
type: Object,
required: true
},
chartConfig: {
type: Object as PropType<config>,
required: true
}
})
const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting)
let seriesDataNum = -1
let seriesDataMaxLength = 0
let intervalInstance: any = null
use([DatasetComponent, CanvasRenderer, PieChart, GridComponent, TooltipComponent, LegendComponent])
const option = computed(() => {
return mergeTheme(props.chartConfig.option, props.themeSetting, includes)
})
//
const handleSeriesData = () => {
if (seriesDataNum > -1) {
vChartRef.value?.dispatchAction({
type: 'downplay',
dataIndex: seriesDataNum
})
}
seriesDataNum = seriesDataNum >= seriesDataMaxLength - 1 ? 0 : seriesDataNum + 1
vChartRef.value?.dispatchAction({
type: 'highlight',
dataIndex: seriesDataNum
})
}
//
const addPieInterval = (newData?: typeof dataJson, skipPre = false) => {
if (!skipPre && !Array.isArray(newData?.source)) return
if (!skipPre) seriesDataMaxLength = newData?.source.length || 0
clearInterval(intervalInstance)
intervalInstance = setInterval(() => {
handleSeriesData()
}, 1000)
}
//
const clearPieInterval = () => {
vChartRef.value?.dispatchAction({
type: 'downplay',
dataIndex: seriesDataNum
})
clearInterval(intervalInstance)
intervalInstance = null
}
//
const handleHighlight = () => {
clearPieInterval()
}
//
const handleDownplay = () => {
if (props.chartConfig.option.isCarousel && !intervalInstance) {
//
addPieInterval(undefined, true)
}
}
watch(
() => props.chartConfig.option.type,
newData => {
try {
if (newData === 'normal') {
props.chartConfig.option.series[0].radius = '70%'
props.chartConfig.option.series[0].roseType = false
} else if (newData === 'ring') {
props.chartConfig.option.series[0].radius = ['40%', '65%']
props.chartConfig.option.series[0].roseType = false
} else {
props.chartConfig.option.series[0].radius = '70%'
props.chartConfig.option.series[0].roseType = true
}
} catch (error) {
console.log(error)
}
},
{ deep: false, immediate: true }
)
watch(
() => props.chartConfig.option.isCarousel,
newData => {
if (newData) {
addPieInterval(undefined, true)
props.chartConfig.option.legend.show = false
} else {
props.chartConfig.option.legend.show = true
clearPieInterval()
}
}
)
// const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: typeof dataJson) => {
// clearPieInterval()
// if (props.chartConfig.option.isCarousel) {
// addPieInterval(newData)
// }
// })
const { vChartRef } = useChartCommonData(props.chartConfig, useChartEditStore)
onMounted(() => {
seriesDataMaxLength = dataJson.source.length
if (props.chartConfig.option.isCarousel) {
addPieInterval(undefined, true)
}
})
</script>

View File

@ -0,0 +1,78 @@
import { echartOptionProfixHandle, PublicConfigClass } from '@/packages/public'
import { PieCommon2Config } from './index'
import { CreateComponentType } from '@/packages/index.d'
import cloneDeep from 'lodash/cloneDeep'
import dataJson from './data.json'
export const includes = ['legend']
export enum PieTypeEnum {
NORMAL = '常规图',
RING = '环形图',
ROSE = '玫瑰图'
}
export const PieTypeObject = {
[PieTypeEnum.NORMAL]: 'normal',
[PieTypeEnum.RING]: 'ring',
[PieTypeEnum.ROSE]: 'rose'
}
// 其它配置
const otherConfig = {
// 轮播动画
isCarousel: false,
}
const option = {
...otherConfig,
type: 'rose',
tooltip: {
show: true,
trigger: 'item'
},
legend: {
show: true
},
dataset: { ...dataJson },
series: [
{
type: 'pie',
radius: ['40%', '65%'],
center: ['50%', '60%'],
roseType: false,
avoidLabelOverlap: false,
itemStyle: {
show: true,
borderRadius: 10,
borderColor: '#fff',
borderWidth: 2
},
label: {
show: false,
position: 'center',
formatter: '{b}',
fontSize:12
},
emphasis: {
label: {
show: true,
fontSize: '40',
fontWeight: 'bold'
}
},
labelLine: {
show: false
}
}
]
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key: string = PieCommon2Config.key
public chartConfig = cloneDeep(PieCommon2Config)
// 图表配置项
public option = echartOptionProfixHandle(option, includes)
}

View File

@ -0,0 +1,99 @@
<template>
<!-- Echarts 全局设置 -->
<global-setting :optionData="optionData"></global-setting>
<CollapseItem name="饼图配置" :expanded="true">
<!-- <SettingItemBox name="类型">-->
<!-- <SettingItem>-->
<!-- <n-select v-model:value="optionData.type" size="small" :options="fontWeightOptions" />-->
<!-- </SettingItem>-->
<!-- </SettingItemBox>-->
<SettingItemBox name="动画" :alone="true">
<SettingItem>
<n-space>
<n-switch v-model:value="optionData.isCarousel" size="small"></n-switch>
<n-text>开启<n-text :depth="3">将自动隐藏图例</n-text></n-text>
</n-space>
</SettingItem>
<SettingItem>
<n-text :depth="3">无鼠标点击图例场景时可强行打开图例</n-text>
</SettingItem>
</SettingItemBox>
<SettingItemBox name="标签">
<SettingItem>
<n-space>
<n-switch v-model:value="optionData.series[0].label.show" size="small"></n-switch>
<n-text>展示标签</n-text>
</n-space>
</SettingItem>
<setting-item>
<n-space>
<n-switch v-model:value="optionData.series[0].labelLine.show" size="small"></n-switch>
<n-text>引导线</n-text>
</n-space>
</setting-item>
<SettingItem name="位置">
<n-select v-model:value="optionData.series[0].label.position" size="small" :options="labelConfig.position" />
</SettingItem>
<setting-item name="展示类型">
<n-select v-model:value="optionData.series[0].label.formatter" size="small" :options="labelFormatterOptions" />
</setting-item>
</SettingItemBox>
<setting-item-box name="圆角">
<setting-item>
<n-space>
<n-input-number
v-model:value="optionData.series[0].itemStyle.borderRadius"
size="small"
:min="0"
></n-input-number>
<n-text>圆角大小</n-text>
</n-space>
</setting-item>
<setting-item>
<n-space>
<n-input-number
v-model:value="optionData.series[0].itemStyle.borderWidth"
size="small"
:min="0"
></n-input-number>
<n-text>线条宽度</n-text>
</n-space>
</setting-item>
</setting-item-box>
</CollapseItem>
</template>
<script setup lang="ts">
import { PropType, watch } from 'vue'
import { GlobalThemeJsonType } from '@/settings/chartThemes/index'
import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { PieTypeObject, PieTypeEnum } from './config'
import { labelConfig } from '@/packages/chartConfiguration/echarts'
const props = defineProps({
optionData: {
type: Object as PropType<GlobalThemeJsonType>,
required: true
}
})
const fontWeightOptions = [
{
label: PieTypeEnum.NORMAL,
value: PieTypeObject[PieTypeEnum.NORMAL]
},
{
label: PieTypeEnum.RING,
value: PieTypeObject[PieTypeEnum.RING]
},
{
label: PieTypeEnum.ROSE,
value: PieTypeObject[PieTypeEnum.ROSE]
}
]
const labelFormatterOptions = [
{ label: '数据名', value: '{b}' },
{ label: '百分比', value: '{d}' },
{ label: '列名:百分比', value: '{b}:{d}%' }
]
</script>

View File

@ -0,0 +1,33 @@
{
"dimensions": ["product", "data1"],
"source": [
{
"product": "Mon",
"data1": 120
},
{
"product": "Tue",
"data1": 200
},
{
"product": "Wed",
"data1": 150
},
{
"product": "Thu",
"data1": 80
},
{
"product": "Fri",
"data1": 70
},
{
"product": "Sat",
"data1": 110
},
{
"product": "Sun",
"data1": 130
}
]
}

View File

@ -0,0 +1,14 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const PieCommon2Config: ConfigType = {
key: 'PieCommon2',
chartKey: 'VPieCommon2',
conKey: 'VCPieCommon2',
title: '饼图-玫瑰图',
category: ChatCategoryEnum.PIE,
categoryName: ChatCategoryEnumName.PIE,
package: PackagesCategoryEnum.CHARTS,
chartFrame: ChartFrameEnum.ECHARTS,
image: 'pie.png'
}

View File

@ -0,0 +1,151 @@
<template>
<v-chart
ref="vChartRef"
autoresize
:init-options="initOptions"
:theme="themeColor"
:option="option"
:manual-update="isPreview()"
@mouseover="handleHighlight"
@mouseout="handleDownplay"
></v-chart>
</template>
<script setup lang="ts">
import { computed, PropType, onMounted, watch } from 'vue'
import VChart from 'vue-echarts'
import { useCanvasInitOptions } from '@/hooks/useCanvasInitOptions.hook'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'
import { PieChart } from 'echarts/charts'
import { mergeTheme } from '@/packages/public/chart'
import config, { includes } from './config'
import {useChartCommonData, useChartDataFetch} from '@/hooks'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { isPreview } from '@/utils'
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
import dataJson from './data.json'
const props = defineProps({
themeSetting: {
type: Object,
required: true
},
themeColor: {
type: Object,
required: true
},
chartConfig: {
type: Object as PropType<config>,
required: true
}
})
const initOptions = useCanvasInitOptions(props.chartConfig.option, props.themeSetting)
let seriesDataNum = -1
let seriesDataMaxLength = 0
let intervalInstance: any = null
use([DatasetComponent, CanvasRenderer, PieChart, GridComponent, TooltipComponent, LegendComponent])
const option = computed(() => {
return mergeTheme(props.chartConfig.option, props.themeSetting, includes)
})
//
const handleSeriesData = () => {
if (seriesDataNum > -1) {
vChartRef.value?.dispatchAction({
type: 'downplay',
dataIndex: seriesDataNum
})
}
seriesDataNum = seriesDataNum >= seriesDataMaxLength - 1 ? 0 : seriesDataNum + 1
vChartRef.value?.dispatchAction({
type: 'highlight',
dataIndex: seriesDataNum
})
}
//
const addPieInterval = (newData?: typeof dataJson, skipPre = false) => {
if (!skipPre && !Array.isArray(newData?.source)) return
if (!skipPre) seriesDataMaxLength = newData?.source.length || 0
clearInterval(intervalInstance)
intervalInstance = setInterval(() => {
handleSeriesData()
}, 1000)
}
//
const clearPieInterval = () => {
vChartRef.value?.dispatchAction({
type: 'downplay',
dataIndex: seriesDataNum
})
clearInterval(intervalInstance)
intervalInstance = null
}
//
const handleHighlight = () => {
clearPieInterval()
}
//
const handleDownplay = () => {
if (props.chartConfig.option.isCarousel && !intervalInstance) {
//
addPieInterval(undefined, true)
}
}
watch(
() => props.chartConfig.option.type,
newData => {
try {
if (newData === 'normal') {
props.chartConfig.option.series[0].radius = '70%'
props.chartConfig.option.series[0].roseType = false
} else if (newData === 'ring') {
props.chartConfig.option.series[0].radius = ['40%', '65%']
props.chartConfig.option.series[0].roseType = false
} else {
props.chartConfig.option.series[0].radius = '70%'
props.chartConfig.option.series[0].roseType = true
}
} catch (error) {
console.log(error)
}
},
{ deep: false, immediate: true }
)
watch(
() => props.chartConfig.option.isCarousel,
newData => {
if (newData) {
addPieInterval(undefined, true)
props.chartConfig.option.legend.show = false
} else {
props.chartConfig.option.legend.show = true
clearPieInterval()
}
}
)
// const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: typeof dataJson) => {
// clearPieInterval()
// if (props.chartConfig.option.isCarousel) {
// addPieInterval(newData)
// }
// })
const { vChartRef } = useChartCommonData(props.chartConfig, useChartEditStore)
onMounted(() => {
seriesDataMaxLength = dataJson.source.length
if (props.chartConfig.option.isCarousel) {
addPieInterval(undefined, true)
}
})
</script>

View File

@ -1,4 +1,6 @@
import { PieCommonConfig } from './PieCommon/index'
// import { PieCircleConfig } from './PieCircle/index'
import { PieCommon1Config } from './PieCommon1/index'
import { PieCommon2Config } from './PieCommon2/index'
import { PieCircleConfig } from './PieCircle/index'
export default [PieCommonConfig]
export default [PieCommonConfig, PieCommon1Config, PieCommon2Config, PieCircleConfig]

View File

@ -0,0 +1,58 @@
<template>
<div class="box">
<div class="title">
<slot name="title">{{ title }}</slot>
</div>
<div class="content">
<slot></slot>
</div>
</div>
</template>
<script lang="ts" setup>
import { toRefs } from 'vue'
const props = defineProps(['title'])
const { title } = toRefs(props)
</script>
<style lang="scss" scoped>
.box{
height: 100%;
width: 100%;
background: rgba(65,150,255,.04);
.title{
position: relative;
padding: 0 20px;
height: 38px;
line-height: 38px;
font-size: 16px;
color: #fff;
border-top: 1px solid rgba(65,150,255,.5);
border-bottom: 1px solid rgba(65,150,255,.2);
background: linear-gradient(90deg,rgba(65,150,255,.1) 0,rgba(65,150,255,0));
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
&:after{
content: '';
height: 1px;
width: 20px;
background: linear-gradient(90deg,rgba(65,150,255,0) 0,#4196ff);
position: absolute;
bottom: 0;
left: 0;
}
}
.content{
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
height: calc(100% - 40px);
box-sizing: border-box;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding: 7px;
}
}
</style>

View File

@ -0,0 +1,31 @@
import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { BorderCustom1Config } from './index'
import cloneDeep from 'lodash/cloneDeep'
// import logo from '@/assets/logo.png'
export const option = {
// 图片路径
dataset: '',
// 适应方式
fit: 'contain',
// 圆角
borderRadius: 0
}
export default class Config extends PublicConfigClass implements CreateComponentType
{
constructor() {
super();
this.attr.w = 450
this.attr.h = 300
this.request.requestInterval = 15
}
public key = BorderCustom1Config.key
public chartConfig = cloneDeep(BorderCustom1Config)
public option = cloneDeep(option)
public customData = cloneDeep({
title: '',
showInterval: false,
})
}

View File

@ -0,0 +1,7 @@
<template>
</template>
<script setup lang="ts">
</script>

View File

@ -0,0 +1,14 @@
<template>
<setting-item-box name="标题" :alone="true">
<n-input v-model:value="props.customData.title" size="small" placeholder="请输入标题"/>
</setting-item-box>
</template>
<script lang="ts" setup>
import { SettingItemBox } from '@/components/Pages/ChartItemSetting'
const props = defineProps(['customData', 'request'])
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,15 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '@/packages/components/Decorates/index.d'
export const BorderCustom1Config: ConfigType = {
key: 'BorderCustom1',
chartKey: 'VBorderCustom1',
conKey: 'VCBorderCustom1',
conDataKey: 'VCDBorderCustom1',
title: '边框-自定义1',
category: ChatCategoryEnum.BORDER,
categoryName: ChatCategoryEnumName.BORDER,
package: PackagesCategoryEnum.DECORATES,
chartFrame: ChartFrameEnum.COMMON,
image: 'BorderCustom1.png'
}

View File

@ -0,0 +1,54 @@
<template>
<div :style="getStyle(borderRadius)">
<BorderBox :title="chartConfig?.customData?.title">
</BorderBox>
</div>
</template>
<script setup lang="ts">
import { PropType, shallowReactive, watch, toRefs, reactive, onMounted, onUnmounted } from 'vue'
import { useChartDataFetch } from '@/hooks'
import { CreateComponentType } from '@/packages/index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import BorderBox from './BorderBox.vue'
const props = defineProps({
chartConfig: {
type: Object as PropType<CreateComponentType>,
required: true
}
})
const { w, h } = toRefs(props.chartConfig.attr)
const { dataset, fit, borderRadius } = toRefs(props.chartConfig.option)
const option = shallowReactive({
dataset: ''
})
const getStyle = (radius: number) => {
return {
borderRadius: `${radius}px`,
overflow: 'hidden'
}
}
//
// //
// watch(
// () => props.chartConfig.option.dataset,
// (newData: any) => {
// option.dataset = newData
// },
// {
// immediate: true
// }
// )
//
// //
// useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
// option.dataset = newData
// })
</script>
<style lang="scss" scoped>
</style>

View File

@ -1,3 +1,4 @@
import { BorderCustom1Config } from './BorderCustom1/index';
import { Border01Config } from './Border01/index'
import { Border02Config } from './Border02/index'
import { Border03Config } from './Border03/index'
@ -13,6 +14,7 @@ import { Border12Config } from './Border12/index'
import { Border13Config } from './Border13/index'
export default [
BorderCustom1Config,
Border01Config,
Border02Config,
Border03Config,

View File

@ -3,6 +3,7 @@ import { CreateComponentType } from '@/packages/index.d'
import { TextBarrageConfig } from './index'
import { chartInitConfig } from '@/settings/designSetting'
import cloneDeep from 'lodash/cloneDeep'
import { CurrentSourceEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
export enum FontWeightEnum {
NORMAL = '常规',
@ -34,6 +35,10 @@ export const option = {
}
export default class Config extends PublicConfigClass implements CreateComponentType {
constructor() {
super();
this.commonData.currentSource = CurrentSourceEnum.SINGLEPOINT
}
public key = TextBarrageConfig.key
public attr = { ...chartInitConfig, w: 500, h: 70, zIndex: -1 }
public chartConfig = cloneDeep(TextBarrageConfig)

View File

@ -9,6 +9,6 @@ export const TextBarrageConfig: ConfigType = {
category: ChatCategoryEnum.TEXT,
categoryName: ChatCategoryEnumName.TEXT,
package: PackagesCategoryEnum.INFORMATIONS,
chartFrame: ChartFrameEnum.COMMON,
chartFrame: ChartFrameEnum.STATIC,
image: 'text_barrage.png'
}

View File

@ -2,6 +2,7 @@ import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { TextCommonConfig } from './index'
import cloneDeep from 'lodash/cloneDeep'
import { CurrentSourceEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
export enum WritingModeEnum {
HORIZONTAL = '水平',
@ -46,6 +47,10 @@ export const option = {
}
export default class Config extends PublicConfigClass implements CreateComponentType {
constructor() {
super();
this.commonData.currentSource = CurrentSourceEnum.SINGLEPOINT
}
public key = TextCommonConfig.key
public chartConfig = cloneDeep(TextCommonConfig)
public option = cloneDeep(option)

View File

@ -9,6 +9,6 @@ export const TextCommonConfig: ConfigType = {
category: ChatCategoryEnum.TEXT,
categoryName: ChatCategoryEnumName.TEXT,
package: PackagesCategoryEnum.INFORMATIONS,
chartFrame: ChartFrameEnum.COMMON,
chartFrame: ChartFrameEnum.STATIC,
image: 'text_static.png'
}

View File

@ -2,6 +2,7 @@ import { PublicConfigClass } from '@/packages/public'
import { CreateComponentType } from '@/packages/index.d'
import { TextGradientConfig } from './index'
import cloneDeep from 'lodash/cloneDeep'
import { CurrentSourceEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
export const option = {
dataset: '我是渐变文本',
@ -14,6 +15,10 @@ export const option = {
}
export default class Config extends PublicConfigClass implements CreateComponentType {
constructor() {
super();
this.commonData.currentSource = CurrentSourceEnum.SINGLEPOINT
}
public key = TextGradientConfig.key
public chartConfig = cloneDeep(TextGradientConfig)
public option = cloneDeep(option)

View File

@ -9,6 +9,6 @@ export const TextGradientConfig: ConfigType = {
category: ChatCategoryEnum.TEXT,
categoryName: ChatCategoryEnumName.TEXT,
package: PackagesCategoryEnum.INFORMATIONS,
chartFrame: ChartFrameEnum.NAIVE_UI,
chartFrame: ChartFrameEnum.STATIC,
image: 'text_gradient.png'
}

View File

@ -59,7 +59,8 @@ const addConfig = {
// 点击上传事件
addHandle: (photoConfig: ConfigType) => {
goDialog({
message: `图片需小于 ${backgroundImageSize}M 且只暂存在浏览器中。当前图片暂存上限5M超过不再缓存新图片请自行对接后端接口现编译成 base64 进行渲染对接后端后请使用【URL地址】进行交互`,
// message: `图片需小于 ${backgroundImageSize}M 且只暂存在浏览器中。当前图片暂存上限5M超过不再缓存新图片请自行对接后端接口现编译成 base64 进行渲染对接后端后请使用【URL地址】进行交互`,
message: `图片需小于 ${backgroundImageSize}M 且只暂存在浏览器中。当前图片暂存上限5M超过不再缓存新图片`,
transformOrigin: 'center',
onPositiveCallback: () => {
uploadFile((e: UploadCompletedEventType) => {

View File

@ -1,7 +1,7 @@
import { BaseEvent, EventLife, InteractEvents, InteractEventOn, InteractActionsType } from '@/enums/eventEnum'
import type { GlobalThemeJsonType } from '@/settings/chartThemes/index'
import type { RequestConfigType } from '@/store/modules/chartEditStore/chartEditStore.d'
import {CustomComponentsList} from "@/packages/components/CustomComponents/index";
import { CustomComponentsList } from "@/packages/components/CustomComponents/index";
import { commonDataType } from '@/store/modules/chartEditStore/chartEditStore.d'
export enum ChartFrameEnum {
@ -47,8 +47,6 @@ export type ConfigType = {
icon?: string
// 事件
configEvents?: { [T: string]: Function }
// 自定义数据配置
customData?: { [T: string]: any }
}
// 数据请求
@ -216,7 +214,7 @@ export type PackagesType = {
[PackagesCategoryEnum.CHARTS]: ConfigType[]
[PackagesCategoryEnum.INFORMATIONS]: ConfigType[]
// [PackagesCategoryEnum.TABLES]: ConfigType[]
// [PackagesCategoryEnum.PHOTOS]: ConfigType[]
[PackagesCategoryEnum.PHOTOS]: ConfigType[]
[PackagesCategoryEnum.ICONS]: ConfigType[]
[PackagesCategoryEnum.DECORATES]: ConfigType[]
// [PackagesCategoryEnum.THEMESANDLAYOUTS]: ConfigType[]

View File

@ -2,7 +2,7 @@ import { ChartList } from '@/packages/components/Charts/index'
import { DecorateList } from '@/packages/components/Decorates/index'
import { InformationList } from '@/packages/components/Informations/index'
// import { TableList } from '@/packages/components/Tables/index'
// import { PhotoList } from '@/packages/components/Photos/index'
import { PhotoList } from '@/packages/components/Photos/index'
import { IconList } from '@/packages/components/Icons/index'
import { CustomComponentsList } from '@/packages/components/CustomComponents/index'
import { PackagesCategoryEnum, PackagesType, ConfigType, FetchComFlagType } from '@/packages/index.d'
@ -26,7 +26,7 @@ export let packagesList: PackagesType = {
[PackagesCategoryEnum.INFORMATIONS]: InformationList,
// [PackagesCategoryEnum.TABLES]: TableList,
[PackagesCategoryEnum.DECORATES]: DecorateList,
// [PackagesCategoryEnum.PHOTOS]: PhotoList,
[PackagesCategoryEnum.PHOTOS]: PhotoList,
[PackagesCategoryEnum.ICONS]: IconList,
[PackagesCategoryEnum.CUSTOMCOMPONENTS]: CustomComponentsList,
}

View File

@ -71,6 +71,17 @@ const commonData: commonDataType = {
limit: 10,
with_device_name: false,
space_complete_name_prefix: false,
},
singlePoint: {
enable: false,
pointId: '',
result: {
name: '',
status: null,
time: '',
unit: '',
value: 0
}
}
}

View File

@ -259,7 +259,9 @@ export enum CurrentSourceEnum {
// 记录值历史
RECORDVALUEHISTORY = 'recordValueHistory',
// 测点实时值
POINTREALTIME = 'pointRealTime'
POINTREALTIME = 'pointRealTime',
// 单测点实时值
SINGLEPOINT = 'singlePoint'
}
// 测点历史参数
@ -283,7 +285,7 @@ export enum PolicyTypeEnum {
MAX = 1
}
// 记录值历史
// 记录值历史参数
export interface RecordValueHistoryType {
enable: boolean
policy: PolicyTypeEnum[]
@ -291,6 +293,7 @@ export interface RecordValueHistoryType {
dateType: DateTypeEnum
}
// 测点实时值参数
export interface PointRealTimeType {
enable: boolean
point_uid: string[]
@ -299,13 +302,29 @@ export interface PointRealTimeType {
space_complete_name_prefix: boolean
}
export interface resultType {
name: string
status: number | null
time: string
unit: string
value: number | null
}
// 单测点实时值
export interface SinglePointType {
enable: boolean
pointId: string
result: resultType
}
// 通用组件数据
export interface commonDataType {
currentSource: CurrentSourceEnum,
pointHistory: PointHistoryType,
energyUseHistory: EnergyUseHistoryType,
currentSource: CurrentSourceEnum
pointHistory: PointHistoryType
energyUseHistory: EnergyUseHistoryType
recordValueHistory: RecordValueHistoryType
pointRealTime: PointRealTimeType
singlePoint: SinglePointType
}
// Store 类型

View File

@ -18,15 +18,15 @@ export const usePackagesStore = defineStore({
},
actions: {
addPhotos(newPhoto: ConfigType, index: number) {
// this.newPhoto = newPhoto
// this.packagesList.Photos.splice(index, 0, newPhoto)
this.newPhoto = newPhoto
this.packagesList.Photos.splice(index, 0, newPhoto)
},
deletePhotos(photoInfo: ConfigType, index: number) {
// this.packagesList.Photos.splice(index, 1)
// const StoreKey = StorageEnum.GO_USER_MEDIA_PHOTOS
// const userPhotosList = getLocalStorage(StoreKey)
// userPhotosList.splice(index - 1, 1)
// setLocalStorage(StoreKey, userPhotosList)
this.packagesList.Photos.splice(index, 1)
const StoreKey = StorageEnum.GO_USER_MEDIA_PHOTOS
const userPhotosList = getLocalStorage(StoreKey)
userPhotosList.splice(index - 1, 1)
setLocalStorage(StoreKey, userPhotosList)
}
}
})

View File

@ -19,7 +19,7 @@
<n-space v-for="(item, i) in computeIds" :key="item.id" align="center" :wrap="false">
<n-input
:value="item.value"
@update:value="(v: number) => handleChange(v, i)"
@update:value="(v: string) => handleChange(v, i)"
placeholder="请输入测点ID"
size="small"
clearable

View File

@ -1,95 +1,98 @@
<template>
<setting-item-box name="启用数据" :alone="true">
<n-space justify="start">
<n-switch v-model:value="recordValueHistory.enable" />
</n-space>
<n-space justify="start">
<n-switch v-model:value="recordValueHistory.enable"/>
</n-space>
</setting-item-box>
<setting-item-box name="时间" :alone="true">
<n-select v-model:value="recordValueHistory.dateType" :options="DateOptions" size="small"/>
<n-select v-model:value="recordValueHistory.dateType" :options="DateOptions" size="small"/>
</setting-item-box>
<setting-item-box name="统计方式" :alone="true">
<n-select multiple v-model:value="recordValueHistory.policy" :options="PolicyOptions" size="small" />
<n-select multiple v-model:value="recordValueHistory.policy" :options="PolicyOptions" size="small"/>
</setting-item-box>
<setting-item-box name="报表ID" :alone="true">
<n-space vertical>
<n-space v-for="(item, i) in computeIds" :key="item.id" align="center" :wrap="false">
<n-input-number
:value="item.value"
@update:value="(v: number) => handleChange(v, i)"
min="1"
:show-button="false"
placeholder="请输入报表ID"
size="small"
clearable
/>
<n-button @click="handleDelete(i)" circle size="tiny">
<template #icon>
<n-icon><CloseIcon /></n-icon>
</template>
</n-button>
<n-button v-if="i === computeIds.length - 1" @click="handleAdd" circle size="tiny">
<template #icon>
<n-icon><AddIcon /></n-icon>
</template>
</n-button>
<div v-else style="width: 22px"></div>
<n-space vertical>
<n-space v-for="(item, i) in computeIds" :key="item.id" align="center" :wrap="false">
<n-input-number
:value="item.value"
@update:value="(v: number) => handleChange(v, i)"
min="1"
:show-button="false"
placeholder="请输入报表ID"
size="small"
clearable
/>
<n-button @click="handleDelete(i)" circle size="tiny">
<template #icon>
<n-icon>
<CloseIcon/>
</n-icon>
</template>
</n-button>
<n-button v-if="i === computeIds.length - 1" @click="handleAdd" circle size="tiny">
<template #icon>
<n-icon>
<AddIcon/>
</n-icon>
</template>
</n-button>
<div v-else style="width: 22px"></div>
</n-space>
</n-space>
</n-space>
</setting-item-box>
</template>
<script lang="ts" setup>
import { watch, reactive, computed } from 'vue'
import type { Ref } from 'vue'
import { SettingItemBox } from '@/components/Pages/ChartItemSetting'
import { useTargetData } from '../../hooks/useTargetData.hook'
import { DateOptions, PolicyOptions } from './ComponentsType.d'
import { icon } from '@/plugins/icon'
import { commonDataType, RecordValueHistoryType } from '@/store/modules/chartEditStore/chartEditStore.d'
const { CloseIcon, AddIcon } = icon.ionicons5
const { targetData } = useTargetData() as { targetData: Ref<{ commonData: commonDataType, id: string }> }
const recordValueHistory: Ref<RecordValueHistoryType> = computed(() => targetData.value.commonData.recordValueHistory)
type computeIdsItemType = {
</template>
<script lang="ts" setup>
import {watch, reactive, computed} from 'vue'
import type {Ref} from 'vue'
import {SettingItemBox} from '@/components/Pages/ChartItemSetting'
import {useTargetData} from '../../hooks/useTargetData.hook'
import {DateOptions, PolicyOptions} from './ComponentsType.d'
import {icon} from '@/plugins/icon'
import {commonDataType, RecordValueHistoryType} from '@/store/modules/chartEditStore/chartEditStore.d'
const {CloseIcon, AddIcon} = icon.ionicons5
const {targetData} = useTargetData() as { targetData: Ref<{ commonData: commonDataType, id: string }> }
const recordValueHistory: Ref<RecordValueHistoryType> = computed(() => targetData.value.commonData.recordValueHistory)
type computeIdsItemType = {
id: string,
value: number | null
}
const computeIds: computeIdsItemType[] = reactive([])
watch(() => [targetData.value.id, recordValueHistory.value.strategy_ids], () => {
if(!recordValueHistory.value.strategy_ids.length) recordValueHistory.value.strategy_ids.push(null)
}
const computeIds: computeIdsItemType[] = reactive([])
watch(() => [targetData.value.id, recordValueHistory.value.strategy_ids], () => {
if (!recordValueHistory.value.strategy_ids.length) recordValueHistory.value.strategy_ids.push(null)
let arr = recordValueHistory.value.strategy_ids.map((item, i) => {
return {
id: `${targetData.value.id}_${i}`,
value: item
}
return {
id: `${targetData.value.id}_${i}`,
value: item
}
})
computeIds.splice(0, computeIds.length, ...arr)
}, {
}, {
deep: true,
immediate: true
})
const handleChange = (v: number, i: number) => {
})
const handleChange = (v: number, i: number) => {
targetData.value.commonData.recordValueHistory.strategy_ids[i] = v
}
const handleAdd = () => {
}
const handleAdd = () => {
targetData.value.commonData.recordValueHistory.strategy_ids.push(null)
}
const handleDelete = (i: number) => {
}
const handleDelete = (i: number) => {
targetData.value.commonData.recordValueHistory.strategy_ids.splice(i, 1)
}
</script>
<style lang="scss" scoped>
</style>
}
</script>
<style lang="scss" scoped>
</style>

View File

@ -0,0 +1,32 @@
<template>
<setting-item-box name="启用数据" :alone="true">
<n-space justify="start">
<n-switch v-model:value="singlePoint.enable"/>
</n-space>
</setting-item-box>
<setting-item-box name="测点ID" :alone="true">
<n-input
v-model:value="singlePoint.pointId"
placeholder="请输入测点ID"
size="small"
clearable
/>
</setting-item-box>
</template>
<script setup lang="ts">
import { useTargetData } from "../../hooks/useTargetData.hook";
import { computed } from 'vue'
import type { Ref } from "vue";
import { commonDataType, SinglePointType } from '@/store/modules/chartEditStore/chartEditStore.d'
import { SettingItemBox } from '@/components/Pages/ChartItemSetting'
const { targetData } = useTargetData() as { targetData: Ref<{ commonData: commonDataType, id: string }> }
const singlePoint: Ref<SinglePointType> = computed(() => targetData.value.commonData.singlePoint)
</script>
<style lang="scss" scoped>
</style>

View File

@ -110,26 +110,44 @@ export const selectTimeOptions: SelectHttpTimeType[] = [
},
]
export enum optionTypeEnum {
// 多个值
MULTIPLE = 'multiple',
// 单个值的数据源 环形图等
SINGLE = 'single'
}
export interface sourceOptionsItemType {
label: string,
value: CurrentSourceEnum,
type: optionTypeEnum
}
// 通用组件数据源选项
export const sourceOptions: sourceOptionsItemType[] = [
{
label: '测点历史',
value: CurrentSourceEnum.POINTHISTORY
value: CurrentSourceEnum.POINTHISTORY,
type: optionTypeEnum.MULTIPLE,
},
{
label: '能耗历史',
value: CurrentSourceEnum.ENERGYUSEHISTORY
value: CurrentSourceEnum.ENERGYUSEHISTORY,
type: optionTypeEnum.MULTIPLE,
},
{
label: '记录值历史',
value: CurrentSourceEnum.RECORDVALUEHISTORY
value: CurrentSourceEnum.RECORDVALUEHISTORY,
type: optionTypeEnum.MULTIPLE,
},
{
label: '测点实时值',
value: CurrentSourceEnum.POINTREALTIME
value: CurrentSourceEnum.POINTREALTIME,
type: optionTypeEnum.MULTIPLE,
},
{
label: '单测点实时值',
value: CurrentSourceEnum.SINGLEPOINT,
type: optionTypeEnum.SINGLE,
},
]

View File

@ -1,12 +1,20 @@
<template>
<div v-if="!IsStatic() && !targetData.chartConfig.conDataKey" class="go-chart-configurations-data">
<setting-item-box name="数据源" :alone="true">
<n-select v-model:value="targetData.commonData.currentSource" :options="sourceOptions" size="small"/>
</setting-item-box>
<PointHistory v-if="targetData.commonData.currentSource === CurrentSourceEnum.POINTHISTORY"/>
<EnergyUseHistory v-else-if="targetData.commonData.currentSource === CurrentSourceEnum.ENERGYUSEHISTORY"/>
<RecordValueHistory v-else-if="targetData.commonData.currentSource === CurrentSourceEnum.RECORDVALUEHISTORY"/>
<PointRealTime v-else-if="targetData.commonData.currentSource === CurrentSourceEnum.POINTREALTIME"/>
<div v-if="!IsStatic && !targetData.chartConfig.conDataKey" class="go-chart-configurations-data">
<template v-if="!IsCommonSingle">
<setting-item-box name="数据源" :alone="true">
<n-select v-model:value="targetData.commonData.currentSource" :options="multipleSourceOptions" size="small"/>
</setting-item-box>
<PointHistory v-if="matchComponent(CurrentSourceEnum.POINTHISTORY)"/>
<EnergyUseHistory v-else-if="matchComponent(CurrentSourceEnum.ENERGYUSEHISTORY)"/>
<RecordValueHistory v-else-if="matchComponent(CurrentSourceEnum.RECORDVALUEHISTORY)"/>
<PointRealTime v-else-if="matchComponent(CurrentSourceEnum.POINTREALTIME)"/>
</template>
<template v-else-if="IsCommonSingle">
<setting-item-box name="数据源" :alone="true">
<n-select v-model:value="targetData.commonData.currentSource" :options="singleSourceOptions" size="small"/>
</setting-item-box>
<SinglePoint v-if="matchComponent(CurrentSourceEnum.SINGLEPOINT)"/>
</template>
<setting-item-box name="更新间隔" :alone="true">
<n-input-group>
<n-input-number
@ -23,7 +31,7 @@
</n-input-group>
</setting-item-box>
</div>
<div v-else-if="!IsStatic() && targetData.chartConfig.conDataKey">
<div v-else-if="!IsStatic && targetData.chartConfig.conDataKey">
<component :is="targetData.chartConfig.conDataKey" :customData="targetData.customData" :request="targetData.request"></component>
<setting-item-box v-if="targetData?.customData?.showInterval" name="更新间隔" :alone="true">
<n-input-group>
@ -41,7 +49,7 @@
</n-input-group>
</setting-item-box>
</div>
<div v-else-if="IsStatic()">
<div v-else-if="IsStatic">
暂无数据
</div>
</template>
@ -51,14 +59,19 @@ import PointHistory from './components/PointHistory.vue'
import EnergyUseHistory from './components/EnergyUseHistory.vue'
import RecordValueHistory from './components/RecordValueHistory.vue'
import PointRealTime from './components/PointRealTime.vue'
import SinglePoint from './components/SinglePoint.vue'
import { computed } from 'vue'
import type { Ref } from 'vue'
import { loadAsyncComponent } from '@/utils'
import { SettingItemBox } from '@/components/Pages/ChartItemSetting'
import { useTargetData } from '../hooks/useTargetData.hook'
import { sourceOptions, selectTimeOptions } from './index.d'
import { sourceOptions, optionTypeEnum, selectTimeOptions } from './index.d'
import { CurrentSourceEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
import { PackagesCategoryEnum, CreateComponentType, CreateComponentGroupType, ChartFrameEnum } from '@/packages/index.d'
import { PieCircleConfig } from '@/packages/components/Charts/Pies/PieCircle/index'
import { TextBarrageConfig } from "@/packages/components/Informations/Texts/TextBarrage/index";
import { TextCommonConfig } from "@/packages/components/Informations/Texts/TextCommon/index";
import { TextGradientConfig } from "@/packages/components/Informations/Texts/TextGradient/index";
// const ChartDataStatic = loadAsyncComponent(() => import('./components/ChartDataStatic/index.vue'))
@ -70,8 +83,31 @@ const { targetData } = useTargetData() as { targetData: Ref<CreateComponentType
* 静态组件: 无数据
* */
//
const IsStatic = () => {
const IsStatic = computed(() => {
return targetData.value.chartConfig.chartFrame === ChartFrameEnum.STATIC
})
/*
* 通用组件再分为: 多个点的数据和 一个点的数据(用于圆环图等)
*/
const IsCommonSingle = computed(() => {
let singleCharArr = [
PieCircleConfig,
TextBarrageConfig,
TextCommonConfig,
TextGradientConfig,
]
const { package:packageStr, category, key } = targetData.value.chartConfig
const flag = singleCharArr.some(_ => {
return _.package === packageStr && _.category === category && _.key === key
})
return flag
})
const multipleSourceOptions = sourceOptions.filter(_ => _.type === optionTypeEnum.MULTIPLE)
const singleSourceOptions = sourceOptions.filter(_ => _.type === optionTypeEnum.SINGLE)
const matchComponent = (name: string) => {
return targetData.value.commonData.currentSource === name
}
</script>