Merge branch 'dev-vchart' into dev

This commit is contained in:
奔跑的面条 2025-01-15 17:31:23 +08:00
commit 3b5e0fcdeb
47 changed files with 8969 additions and 52 deletions

View File

@ -2,7 +2,7 @@
"name": "go-view",
"version": "1.1.11",
"engines": {
"node": ">=16.14 <18.0.0"
"node": ">=16.14"
},
"scripts": {
"dev": "vite --host",
@ -39,7 +39,7 @@
"keymaster": "^1.6.2",
"mitt": "^3.0.0",
"monaco-editor": "^0.33.0",
"naive-ui": "2.34.3",
"naive-ui": "2.40.3",
"pinia": "^2.0.13",
"screenfull": "^6.0.1",
"three": "^0.145.0",

7604
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,5 @@
import test from './test.mock'
import vchart from './vchart.mock'
import { MockMethod } from 'vite-plugin-mock'
import { RequestHttpEnum } from '@/enums/httpEnum'
@ -22,6 +23,8 @@ export const threeEarth01Url = '/mock/threeEarth01Data'
export const sankeyUrl = '/mock/sankey'
export const graphUrl = '/mock/graphData'
export const vchartBarDataUrl = '/mock/vchart/barDataUrl'
const mockObject: MockMethod[] = [
{
// 正则
@ -115,6 +118,11 @@ const mockObject: MockMethod[] = [
method: RequestHttpEnum.GET,
response: () => test.graphData
},
{
url: vchartBarDataUrl,
method: RequestHttpEnum.GET,
response: () => vchart.bar
}
]
export default mockObject

View File

@ -0,0 +1,10 @@
import bar from './vchart/bar.json'
export default {
bar: {
code: 0,
status: 200,
msg: '请求成功',
data: bar
}
}

View File

@ -0,0 +1,16 @@
{
"values": [
{ "type": "Nail polish", "year": "Africa", "value|100-900": 3 },
{ "type": "Nail polish", "year": "EU", "value|100-900": 3 },
{ "type": "Nail polish", "year": "China", "value|100-900": 3 },
{ "type": "Nail polish", "year": "USA", "value|100-900": 3 },
{ "type": "Eyebrow pencil", "year": "Africa", "value|100-900": 3 },
{ "type": "Eyebrow pencil", "year": "EU", "value|100-900": 3 },
{ "type": "Eyebrow pencil", "year": "China", "value|100-900": 3 },
{ "type": "Eyebrow pencil", "year": "USA", "value|100-900": 3 },
{ "type": "Rouge", "year": "Africa", "value|100-900": 3 },
{ "type": "Rouge", "year": "EU", "value|100-900": 3 },
{ "type": "Rouge", "year": "China", "value|100-900": 3 },
{ "type": "Rouge", "year": "USA", "value|100-900": 3 }
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -2,14 +2,16 @@
<div
ref="vChartRef"
v-on="{
...Object.fromEntries(event.map(eventName => [eventName, (eventData: MouseEvent) => eventHandlers(eventData, eventName)]))
...Object.fromEntries(event.map((eventName: string) => [eventName, (eventData: MouseEvent) => eventHandlers(eventData, eventName)]))
}"
></div>
</template>
<script setup lang="ts">
import { ref, PropType, watch, onMounted, onBeforeUnmount, nextTick } from 'vue'
import { ref, PropType, watch, onBeforeUnmount, nextTick, toRaw, toRefs } from 'vue'
import { VChart, type IVChart, type IInitOption, type ISpec } from '@visactor/vchart'
import { transformHandler } from './transformProps'
import { IOption } from '@/packages/components/VChart/index.d'
// v1.13.0 https://www.visactor.io/vchart/api/API/event
const event = [
@ -133,13 +135,17 @@ const emit = defineEmits([
const props = defineProps({
option: {
type: Object as PropType<ISpec>,
type: Object as PropType<
IOption & {
dataset: any
}
>,
required: true
},
initOptions: {
type: Object as PropType<
IInitOption & {
deepWatch?: boolean
deepWatch?: boolean | number
}
>,
required: false,
@ -150,32 +156,56 @@ const props = defineProps({
const vChartRef = ref()
let chart: IVChart
// props.option dataset
const { dataset, ...restOfOption } = toRefs(props.option)
// data
watch(
() => props.option,
(chartProps: ISpec) => {
if (vChartRef.value) {
nextTick(() => {
createOrUpdateChart(chartProps)
})
}
() => ({
...restOfOption
}),
() => {
nextTick(() => {
createOrUpdateChart(props.option)
})
},
{
deep: props.initOptions.deepWatch || false
deep: props.initOptions?.deepWatch || true,
immediate: true
}
)
watch(
() => dataset.value,
() => {
nextTick(() => {
createOrUpdateChart(props.option)
})
},
{
deep: false
}
)
//
const createOrUpdateChart = (chartProps: ISpec) => {
const createOrUpdateChart = (
chartProps: IOption & {
dataset: any
}
) => {
if (vChartRef.value && !chart) {
chart = new VChart(chartProps, {
dom: vChartRef.value,
...props.initOptions
})
const spec = transformHandler[chartProps.category](chartProps)
chart = new VChart(
{ ...spec, data: chartProps.dataset },
{
dom: vChartRef.value,
...props.initOptions
}
)
chart.renderSync()
return true
} else if (chart) {
chart.updateSpec(chartProps)
chart.renderSync()
const spec = transformHandler[chartProps.category](chartProps)
chart.updateSpec({ ...spec, data: toRaw(chartProps.dataset), dataset: undefined })
return true
}
return false
@ -184,7 +214,6 @@ const createOrUpdateChart = (chartProps: ISpec) => {
//
const refresh = () => {
if (chart) {
chart.release()
chart.renderSync()
}
}
@ -194,11 +223,6 @@ const eventHandlers = (eventData: MouseEvent, eventName: string) => {
if (event.includes(eventName)) emit(eventName as any, eventData)
}
//
onMounted(() => {
createOrUpdateChart(props.option)
})
//
onBeforeUnmount(() => {
if (chart) {

View File

@ -0,0 +1,32 @@
import { cloneDeep } from "lodash"
export default (chartProps: any) => {
const spec = cloneDeep(chartProps)
delete spec.category
// tooltip
const keyFill = spec.tooltip.style.keyLabel.fill
const valueFill = spec.tooltip.style.valueLabel.fill
const titleFill = spec.tooltip.style.titleLabel.keyFill
delete spec.tooltip.style.keyLabel.fill
delete spec.tooltip.style.valueLabel.fill
delete spec.tooltip.style.titleLabel.keyFill
spec.tooltip.style.keyLabel.fontColor = keyFill
spec.tooltip.style.valueLabel.fontColor = valueFill
spec.tooltip.style.titleLabel.fontColor = titleFill
// axis
const { name: xAxisName, ...restXAxisProps } = chartProps.xAxis
const { name: yAxisName, ...restYAxisProps } = chartProps.yAxis
spec.axes = [{
orient: 'bottom',
...restXAxisProps
}, {
orient: 'left',
...restYAxisProps
}]
delete spec.xAxis
delete spec.yAxis
console.log('spec-transform', spec)
return spec
}

View File

@ -0,0 +1,8 @@
import { ChatCategoryEnum, IOption } from "@/packages/components/VChart/index.d";
import bars from './bars'
export const transformHandler: {
[key: string]: (args: IOption) => any
} = {
[ChatCategoryEnum.BAR]: bars,
// todo: more charts handler
}

View File

@ -0,0 +1,71 @@
<template>
<collapse-item v-model:name="axis.name">
<template #header>
<n-switch v-model:value="axis.visible" size="small"></n-switch>
</template>
<setting-item-box name="轴标签">
<setting-item name="可见性">
<n-space>
<n-switch v-model:value="axis.label.visible" size="small"></n-switch>
</n-space>
</setting-item>
<setting-item name="角度">
<n-input-number v-model:value="axis.label.style.angle" :min="0" :max="360" size="small" />
</setting-item>
<FontStyle :style="axis.label.style"></FontStyle>
</setting-item-box>
<setting-item-box name="轴标题">
<setting-item name="可见性">
<n-space>
<n-switch v-model:value="axis.title.visible" size="small"></n-switch>
</n-space>
</setting-item>
<setting-item name="标题内容">
<n-input v-model:value="axis.title.style.text" size="small"></n-input>
</setting-item>
<FontStyle :style="axis.title.style"></FontStyle>
</setting-item-box>
<setting-item-box name="轴线">
<setting-item name="可见性">
<n-space>
<n-switch v-model:value="axis.domainLine.visible" size="small"></n-switch>
</n-space>
</setting-item>
<setting-item name=""> </setting-item>
<setting-item name="粗细">
<n-input-number v-model:value="axis.domainLine.style.lineWidth" :min="0" size="small" />
</setting-item>
<setting-item name="颜色">
<n-color-picker v-model:value="axis.domainLine.style.stroke" size="small" />
</setting-item>
</setting-item-box>
<setting-item-box name="网格线">
<setting-item name="可见性">
<n-space>
<n-switch v-model:value="axis.grid.visible" size="small"></n-switch>
</n-space>
</setting-item>
<setting-item name=""> </setting-item>
<setting-item name="粗细">
<n-input-number v-model:value="axis.grid.style.lineWidth" :min="0" size="small" />
</setting-item>
<setting-item name="颜色">
<n-color-picker v-model:value="axis.grid.style.stroke" size="small" />
</setting-item>
</setting-item-box>
</collapse-item>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import FontStyle from './common/FontStyle.vue'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
defineProps({
axis: {
type: Object as PropType<vChartGlobalThemeJsonType>,
required: true
}
})
</script>

View File

@ -0,0 +1,38 @@
<template>
<!-- todo 补充常用配置项 -->
<div v-if="optionData.legends">
<div v-for="(legendItem, index) in optionData.legends" :key="index">
<collapse-item name="图例">
<template #header>
<n-switch v-model:value="legendItem.visible" size="small"></n-switch>
</template>
<setting-item-box name="布局">
<setting-item name="位置">
<n-select v-model:value="legendItem.orient" size="small" :options="legendsConfig.orient" />
</setting-item>
<setting-item name="对齐方式">
<n-select v-model:value="legendItem.position" size="small" :options="legendsConfig.position" />
</setting-item>
</setting-item-box>
<setting-item-box name="项配置">
<FontStyle :style="legendItem.item.label.style"></FontStyle>
</setting-item-box>
</collapse-item>
</div>
</div>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { legendsConfig } from '@/packages/chartConfiguration/vcharts/index'
import FontStyle from './common/FontStyle.vue'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
defineProps({
optionData: {
type: Object as PropType<vChartGlobalThemeJsonType>,
required: true
}
})
</script>

View File

@ -0,0 +1,47 @@
<template>
<!-- todo 补充常用配置项 -->
<div v-if="optionData.tooltip">
<collapse-item name="提示框">
<template #header>
<n-switch v-model:value="optionData.tooltip.visible" size="small"></n-switch>
</template>
<setting-item-box name="框">
<setting-item name="填充">
<n-color-picker v-model:value="optionData.tooltip.style.panel.backgroundColor" size="small" />
</setting-item>
<setting-item name="瞄边">
<n-color-picker v-model:value="optionData.tooltip.style.panel.border.color" size="small" />
</setting-item>
<setting-item name="粗细">
<n-input-number v-model:value="optionData.tooltip.style.panel.border.width" :min="0" size="small" />
</setting-item>
<setting-item name="圆角">
<n-input-number v-model:value="optionData.tooltip.style.panel.border.radius" :min="0" size="small" />
</setting-item>
</setting-item-box>
<setting-item-box name="标题">
<FontStyle :style="optionData.tooltip.style.titleLabel"></FontStyle>
</setting-item-box>
<setting-item-box name="名称">
<FontStyle :style="optionData.tooltip.style.keyLabel"></FontStyle>
</setting-item-box>
<setting-item-box name="值">
<FontStyle :style="optionData.tooltip.style.valueLabel"></FontStyle>
</setting-item-box>
</collapse-item>
</div>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import FontStyle from './common/FontStyle.vue'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
import { CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
defineProps({
optionData: {
type: Object as PropType<vChartGlobalThemeJsonType>,
required: true
}
})
</script>

View File

@ -0,0 +1,18 @@
<template>
<!-- 图例 -->
<Legends :optionData="optionData"></Legends>
<Tooltip :optionData="optionData"></Tooltip>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
import Legends from './Legends.vue'
import Tooltip from './Tooltip.vue'
const props = defineProps({
optionData: {
type: Object as PropType<vChartGlobalThemeJsonType>,
required: true
}
})
</script>

View File

@ -0,0 +1,33 @@
<template>
<!-- todo 补充常用配置项 -->
<!-- <div v-if="style"> -->
<!-- <setting-item-box v-if="style" name=""> -->
<setting-item name="颜色">
<n-color-picker v-model:value="style.fill" size="small" />
</setting-item>
<setting-item name="大小">
<n-input-number v-model:value="style.fontSize" :min="1" size="small" />
</setting-item>
<setting-item name="字体">
<n-select v-model:value="style.fontFamily" :options="fontStyleConfig.fontFamily" size="small" />
</setting-item>
<setting-item name="字重">
<n-select v-model:value="style.fontSize" :options="fontStyleConfig.fontWeight" size="small" />
</setting-item>
<!-- </setting-item-box> -->
<!-- </div> -->
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { fontStyleConfig } from '@/packages/chartConfiguration/vcharts/index'
import { FontType } from '@/settings/vchartThemes/index'
import { SettingItem } from '@/components/Pages/ChartItemSetting'
defineProps({
style: {
type: Object as PropType<FontType>,
required: true
}
})
</script>

View File

@ -0,0 +1,4 @@
import VChartGlobalSetting from './VChartGlobalSetting.vue'
import Axis from './Axis.vue'
export { VChartGlobalSetting, Axis }

View File

@ -5,4 +5,5 @@ export * from '@/hooks/useChartDataFetch.hook'
export * from '@/hooks/useChartDataPondFetch.hook'
export * from '@/hooks/useLifeHandler.hook'
export * from '@/hooks/useLang.hook'
export * from '@/hooks/useChartInteract.hook'
export * from '@/hooks/useChartInteract.hook'
export * from '@/hooks/useVCharts.hook'

View File

@ -0,0 +1,164 @@
import { watch } from 'vue'
import { VChart, type ITheme } from '@visactor/vchart'
import light from '@visactor/vchart-theme/public/light.json'
import dark from '@visactor/vchart-theme/public/dark.json'
import vScreenVolcanoBlue from '@visactor/vchart-theme/public/vScreenVolcanoBlue.json'
import vScreenClean from '@visactor/vchart-theme/public/vScreenClean.json'
import vScreenOutskirts from '@visactor/vchart-theme/public/vScreenOutskirts.json'
import vScreenBlueOrange from '@visactor/vchart-theme/public/vScreenBlueOrange.json'
import vScreenFinanceYellow from '@visactor/vchart-theme/public/vScreenFinanceYellow.json'
import vScreenWenLvCyan from '@visactor/vchart-theme/public/vScreenWenLvCyan.json'
import vScreenElectricGreen from '@visactor/vchart-theme/public/vScreenElectricGreen.json'
import vScreenECommercePurple from '@visactor/vchart-theme/public/vScreenECommercePurple.json'
import vScreenRedBlue from '@visactor/vchart-theme/public/vScreenRedBlue.json'
import vScreenPartyRed from '@visactor/vchart-theme/public/vScreenPartyRed.json'
// 行业色板
import veODesignLightFinance from '@visactor/vchart-theme/public/veODesignLightFinance.json'
import veODesignDarkFinance from '@visactor/vchart-theme/public/veODesignDarkFinance.json'
import veODesignLightGovernment from '@visactor/vchart-theme/public/veODesignLightGovernment.json'
import veODesignDarkGovernment from '@visactor/vchart-theme/public/veODesignDarkGovernment.json'
import veODesignLightConsumer from '@visactor/vchart-theme/public/veODesignLightConsumer.json'
import veODesignDarkConsumer from '@visactor/vchart-theme/public/veODesignDarkConsumer.json'
import veODesignLightAutomobile from '@visactor/vchart-theme/public/veODesignLightAutomobile.json'
import veODesignDarkAutomobile from '@visactor/vchart-theme/public/veODesignDarkAutomobile.json'
import veODesignLightCulturalTourism from '@visactor/vchart-theme/public/veODesignLightCulturalTourism.json'
import veODesignDarkCulturalTourism from '@visactor/vchart-theme/public/veODesignDarkCulturalTourism.json'
import veODesignLightMedical from '@visactor/vchart-theme/public/veODesignLightMedical.json'
import veODesignDarkMedical from '@visactor/vchart-theme/public/veODesignDarkMedical.json'
import veODesignLightNewEnergy from '@visactor/vchart-theme/public/veODesignLightNewEnergy.json'
import veODesignDarkNewEnergy from '@visactor/vchart-theme/public/veODesignDarkNewEnergy.json'
const themeMap = {
// 明亮
light: light,
// 暗黑
dark: dark,
// 火山蓝
vScreenVolcanoBlue: vScreenVolcanoBlue,
// 党建红
vScreenPartyRed: vScreenPartyRed,
// 清新蜡笔
vScreenClean: vScreenClean,
// 郊外
vScreenOutskirts: vScreenOutskirts,
// 汽车蓝橙
vScreenBlueOrange: vScreenBlueOrange,
// 金融黄
vScreenFinanceYellow: vScreenFinanceYellow,
// 文旅青
vScreenWenLvCyan: vScreenWenLvCyan,
// 电力绿
vScreenElectricGreen: vScreenElectricGreen,
// 电商紫
vScreenECommercePurple: vScreenECommercePurple,
// 红蓝
vScreenRedBlue: vScreenRedBlue,
// 金融行业色板
veODesignLightFinance: veODesignLightFinance,
veODesignDarkFinance: veODesignDarkFinance,
// 政府行业色板
veODesignLightGovernment: veODesignLightGovernment,
veODesignDarkGovernment: veODesignDarkGovernment,
// 消费行业色板
veODesignLightConsumer: veODesignLightConsumer,
veODesignDarkConsumer: veODesignDarkConsumer,
// 汽车行业色板
veODesignLightAutomobile: veODesignLightAutomobile,
veODesignDarkAutomobile: veODesignDarkAutomobile,
// 文旅行业色板
veODesignLightCulturalTourism: veODesignLightCulturalTourism,
veODesignDarkCulturalTourism: veODesignDarkCulturalTourism,
// 医疗行业色板
veODesignLightMedical: veODesignLightMedical,
veODesignDarkMedical: veODesignDarkMedical,
// 新能源行业色板
veODesignLightNewEnergy: veODesignLightNewEnergy,
veODesignDarkNewEnergy: veODesignDarkNewEnergy
}
export const useVCharts = () => {
const getThemeMap = () => {
return themeMap
}
// 注册主题(支持自定义主题)
const registerTheme = (themeName: keyof typeof themeMap, theme: any) => {
VChart.ThemeManager.registerTheme(themeName, (themeMap[themeName] as any) || theme)
}
// 设置当前主题
const setCurrentTheme = (themeName = 'vScreenVolcanoBlue') => {
VChart.ThemeManager.setCurrentTheme(themeName)
}
// 判断主题是否存在
const themeExist = (name: string): boolean => {
return VChart.ThemeManager.themeExist(name)
}
// 获取主题
const getTheme = (name: string): ITheme => {
return VChart.ThemeManager.getTheme(name)
}
// 获取当前主题
const getCurrentTheme = (): ITheme => {
return VChart.ThemeManager.getCurrentTheme()
}
// 设置主题
const setTheme = (name: keyof typeof themeMap): boolean => {
if (themeExist(name)) {
setCurrentTheme(name)
return true
} else {
// 先注册
const theme = themeMap[name]
if (theme) {
registerTheme(name, theme)
setCurrentTheme(name)
return true
} else {
// 注册默认主题
registerTheme('vScreenVolcanoBlue', vScreenVolcanoBlue)
}
}
return false
}
return {
getThemeMap,
registerTheme,
setCurrentTheme,
themeExist,
getTheme,
setTheme,
getCurrentTheme
}
}
// 主题初始化
export const useInitVChartsTheme = (chartEditStore: any) => {
const vCharts = useVCharts()
const initVChartsThemeIns = watch(
() => chartEditStore.getEditCanvasConfig.vChartThemeName,
(newTheme: string) => {
vCharts.setTheme(newTheme as any)
},
{
immediate: true
}
)
return {
initVChartsThemeIns
}
}

View File

@ -0,0 +1 @@
export * from './legends'

View File

@ -0,0 +1,99 @@
export const legendsConfig = {
// 位置
orient: [
{
label: '顶部',
value: 'top'
},
{
label: '底部',
value: 'bottom'
},
{
label: '左侧',
value: 'left'
},
{
label: '右侧',
value: 'right'
}
],
// 对齐方式
position: [
{
label: '起始',
value: 'start'
},
{
label: '居中',
value: 'middle'
},
{
label: '末尾',
value: 'end'
}
],
// 每一项的图例位置
align: [
{
label: '居左',
value: 'left'
},
{
label: '居右',
value: 'right'
}
]
}
export const fontStyleConfig = {
// 字重
fontWeight: [
{
label: '100',
value: 100
},
{
label: '200',
value: 200
},
{
label: '300',
value: 300
},
{
label: '400',
value: 400
},
{
label: '500',
value: 500
},
{
label: '600',
value: 600
},
{
label: '正常',
value: "normal"
},
{
label: '加粗',
value: "bold"
}
],
fontFamily: [
{
label: '宋体',
value: 'SimSun'
},
{
label: '黑体',
value: 'SimHei'
},
{
label: '楷体',
value: '楷体'
}
]
}

View File

@ -28,7 +28,7 @@ export const option = {
type: 'shadow'
}
},
xAxis: {
xAxis: {
show: true,
type: 'category'
},

View File

@ -1,15 +1,47 @@
import { PublicConfigClass } from '@/packages/public'
import { VChartBarCommonConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import { vChartOptionPrefixHandle } from '@/packages/public/vChart'
import data from './data.json'
import cloneDeep from 'lodash/cloneDeep'
import axisThemeJson from '@/settings/vchartThemes/axis.theme.json'
import { IBarOption } from '../../index.d'
export const option = {
export const includes = ['legends', 'tooltip']
export const option: IBarOption & { dataset?: any } = {
// 图表配置
type: 'bar',
dataset: data,
stack: true,
xField: ['year', 'type'],
yField: ['value'],
seriesField: 'type',
// 业务配置后续会被转换为图表spec)
category: VChartBarCommonConfig.category,
xAxis: {
name: 'x轴',
...axisThemeJson,
grid: {
...axisThemeJson.grid,
visible: false
}
},
yAxis: {
name: 'y轴',
...axisThemeJson,
grid: {
...axisThemeJson.grid,
style: {
...axisThemeJson.grid.style,
lineDash: [3, 3]
}
}
}
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = VChartBarCommonConfig.key
public chartConfig = cloneDeep(VChartBarCommonConfig)
// 图表配置项
public option = cloneDeep(option)
public option = vChartOptionPrefixHandle(option, includes)
}

View File

@ -1,3 +1,19 @@
<template></template>
<template>
<!-- vCharts 全局设置 -->
<VChartGlobalSetting :optionData="optionData"></VChartGlobalSetting>
<Axis :axis="optionData.xAxis"></Axis>
<Axis :axis="optionData.yAxis"></Axis>
</template>
<script setup lang="ts"></script>
<script setup lang="ts">
import { PropType } from 'vue'
import { VChartGlobalSetting, Axis } from '@/components/Pages/VChartItemSetting'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
defineProps({
optionData: {
type: Object as PropType<vChartGlobalThemeJsonType>,
required: true
}
})
</script>

View File

@ -0,0 +1,25 @@
{
"values": [
{ "type": "Autocracies", "year": "1930", "value": 129 },
{ "type": "Autocracies", "year": "1940", "value": 133 },
{ "type": "Autocracies", "year": "1950", "value": 130 },
{ "type": "Autocracies", "year": "1960", "value": 126 },
{ "type": "Autocracies", "year": "1970", "value": 117 },
{ "type": "Autocracies", "year": "1980", "value": 114 },
{ "type": "Autocracies", "year": "1990", "value": 111 },
{ "type": "Autocracies", "year": "2000", "value": 89 },
{ "type": "Autocracies", "year": "2010", "value": 80 },
{ "type": "Autocracies", "year": "2018", "value": 80 },
{ "type": "Democracies", "year": "1930", "value": 22 },
{ "type": "Democracies", "year": "1940", "value": 13 },
{ "type": "Democracies", "year": "1950", "value": 25 },
{ "type": "Democracies", "year": "1960", "value": 29 },
{ "type": "Democracies", "year": "1970", "value": 38 },
{ "type": "Democracies", "year": "1980", "value": 41 },
{ "type": "Democracies", "year": "1990", "value": 57 },
{ "type": "Democracies", "year": "2000", "value": 87 },
{ "type": "Democracies", "year": "2010", "value": 98 },
{ "type": "Democracies", "year": "2018", "value": 99 }
]
}

View File

@ -0,0 +1,22 @@
<template>
<GoVChart ref="vChartRef" :option="chartConfig.option"> </GoVChart>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { GoVChart } from '@/components/GoVChart'
import { useChartDataFetch } from '@/hooks'
import config from './config'
const props = defineProps({
chartConfig: {
type: Object as PropType<config>,
required: true
}
})
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
props.chartConfig.option.dataset = newData
})
</script>

View File

@ -0,0 +1,47 @@
import { PublicConfigClass } from '@/packages/public'
import { VChartBarStackConfig } from './index'
import { CreateComponentType } from '@/packages/index.d'
import { vChartOptionPrefixHandle } from '@/packages/public/vChart'
import data from './data.json'
import cloneDeep from 'lodash/cloneDeep'
import axisThemeJson from '@/settings/vchartThemes/axis.theme.json'
import { IBarOption } from '../../index.d'
export const includes = ['legends', 'tooltip']
export const option: IBarOption & { dataset?: any } = {
// 图表配置
type: 'bar',
dataset: data,
xField: ['type'],
yField: ['value'],
seriesField: 'year',
stack: true,
// 业务配置后续会被转换为图表spec)
category: VChartBarStackConfig.category,
xAxis: {
name: 'x轴',
...axisThemeJson,
grid: {
...axisThemeJson.grid,
visible: false
}
},
yAxis: {
name: 'y轴',
...axisThemeJson,
grid: {
...axisThemeJson.grid,
style: {
...axisThemeJson.grid.style,
lineDash: [3, 3]
}
}
}
}
export default class Config extends PublicConfigClass implements CreateComponentType {
public key = VChartBarStackConfig.key
public chartConfig = cloneDeep(VChartBarStackConfig)
// 图表配置项
public option = vChartOptionPrefixHandle(option, includes)
}

View File

@ -0,0 +1,19 @@
<template>
<!-- vCharts 全局设置 -->
<VChartGlobalSetting :optionData="optionData"></VChartGlobalSetting>
<Axis :axis="optionData.xAxis"></Axis>
<Axis :axis="optionData.yAxis"></Axis>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { VChartGlobalSetting, Axis } from '@/components/Pages/VChartItemSetting'
import { vChartGlobalThemeJsonType } from '@/settings/vchartThemes/index'
defineProps({
optionData: {
type: Object as PropType<vChartGlobalThemeJsonType>,
required: true
}
})
</script>

View File

@ -0,0 +1,16 @@
{
"values": [
{ "type": "Nail polish", "year": "Africa", "value": 590 },
{ "type": "Nail polish", "year": "EU", "value": 450 },
{ "type": "Nail polish", "year": "China", "value": 474 },
{ "type": "Nail polish", "year": "USA", "value": 459 },
{ "type": "Eyebrow pencil", "year": "Africa", "value": 746 },
{ "type": "Eyebrow pencil", "year": "EU", "value": 176 },
{ "type": "Eyebrow pencil", "year": "China", "value": 210 },
{ "type": "Eyebrow pencil", "year": "USA", "value": 775 },
{ "type": "Rouge", "year": "Africa", "value": 896 },
{ "type": "Rouge", "year": "EU", "value": 784 },
{ "type": "Rouge", "year": "China", "value": 866 },
{ "type": "Rouge", "year": "USA", "value": 899 }
]
}

View File

@ -0,0 +1,14 @@
import { ConfigType, PackagesCategoryEnum, ChartFrameEnum } from '@/packages/index.d'
import { ChatCategoryEnum, ChatCategoryEnumName } from '../../index.d'
export const VChartBarStackConfig: ConfigType = {
key: 'VChartBarStack',
chartKey: 'VVChartBarStack',
conKey: 'VCVChartBarStack',
title: 'VChart柱状图',
category: ChatCategoryEnum.BAR,
categoryName: ChatCategoryEnumName.BAR,
package: PackagesCategoryEnum.VCHART,
chartFrame: ChartFrameEnum.VCHART,
image: 'vchart_bar_x_stack.png'
}

View File

@ -0,0 +1,22 @@
<template>
<GoVChart ref="vChartRef" :option="chartConfig.option"> </GoVChart>
</template>
<script setup lang="ts">
import { PropType } from 'vue'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { GoVChart } from '@/components/GoVChart'
import { useChartDataFetch } from '@/hooks'
import config from './config'
const props = defineProps({
chartConfig: {
type: Object as PropType<config>,
required: true
}
})
const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore, (newData: any) => {
props.chartConfig.option.dataset = newData
})
</script>

View File

@ -1,3 +1,4 @@
import { VChartBarCommonConfig } from './VChartBarCommon/index'
import { VChartBarStackConfig } from './VChartBarStack/index'
export default [VChartBarCommonConfig]
export default [VChartBarCommonConfig, VChartBarStackConfig]

View File

@ -1,3 +1,7 @@
import { IBarChartSpec } from '@visactor/vchart'
import { ICartesianAxisCommonSpec } from '@visactor/vchart/esm/component/axis'
export enum ChatCategoryEnum {
BAR = 'Bars',
}
@ -5,3 +9,18 @@ export enum ChatCategoryEnum {
export enum ChatCategoryEnumName {
BAR = '柱状图',
}
export interface IBarOption extends Omit<IBarChartSpec, 'axes'> {
category: ChatCategoryEnum.BAR
type: 'bar'
xAxis?: {
name: string
} & ICartesianAxisCommonSpec
yAxis?: {
name: string
} & ICartesianAxisCommonSpec
}
// todo
// export type IOption = IBarOption | ILineOption ....
export type IOption = IBarOption

View File

@ -1,6 +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 type { ChatCategoryEnum, ChatCategoryEnumName } from '@/packages/components/VChart/index.d'
export enum ChartFrameEnum {
// 支持 dataset 的 echarts 框架
@ -26,11 +27,11 @@ export type ConfigType = {
// 标题
title: string
// 分类
category: string
category: ChatCategoryEnum
// 分类名称
categoryName: string
categoryName: ChatCategoryEnumName
// 所属包
package: string
package: PackagesCategoryEnum
// 归类
chartFrame?: ChartFrameEnum
// 预览图

View File

@ -20,7 +20,7 @@ export const mergeTheme = <T, U>(option: T, themeSetting: U, includes: string[])
* @param option
* @return option
*/
export const echartOptionProfixHandle = (option: any, includes: string[]) => {
export const echartOptionProfixHandle = (option: any, includes: string[] = []) => {
option['backgroundColor'] = 'rgba(0,0,0,0)'
return mergeTheme(option, globalThemeJson, includes)
}

View File

@ -0,0 +1,24 @@
import merge from 'lodash/merge'
import pick from 'lodash/pick'
import { vChartGlobalThemeJson } from '@/settings/vchartThemes/index'
/**
* * color
* @param option
* @param themeSetting
* @param excludes
* @returns object
*/
export const mergeTheme = <T, U>(option: T, themeSetting: U, includes: string[]) => {
return (option = merge({}, pick(themeSetting, includes), option))
}
/**
* * vCharts option
* @param option
* @return option
*/
export const vChartOptionPrefixHandle = (option: any, includes: string[] = []) => {
option['background'] = 'rgba(0,0,0,0)'
return mergeTheme(option, vChartGlobalThemeJson, includes)
}

View File

@ -0,0 +1,37 @@
{
"visible": true,
"label": {
"visible": true,
"style": {
"fontSize": 12,
"fill": "#B9B8CE",
"fontFamily": "SimSun",
"fontWeight": "normal",
"angle": 0
}
},
"title": {
"visible": true,
"style": {
"text": "",
"fontSize": 12,
"fill": "#B9B8CE",
"fontFamily": "SimSun",
"fontWeight": "normal"
}
},
"domainLine": {
"visible": false,
"style": {
"lineWidth": 1,
"stroke": "#D5D7E2"
}
},
"grid": {
"visible": true,
"style": {
"lineWidth": 1,
"stroke": "#FFFFFF24"
}
}
}

View File

@ -0,0 +1,78 @@
{
"legends": [
{
"visible": true,
"position": "middle",
"orient": "bottom",
"item": {
"visible": true,
"align": "left",
"shape": "circle",
"label": {
"style": {
"fontSize": 16,
"fill": "#B9B8CE",
"fontFamily": "SimSun",
"fontWeight": "normal"
}
}
}
}
],
"tooltip": {
"visible": true,
"style": {
"panel": {
"padding": {
"top": 5,
"bottom": 10,
"left": 10,
"right": 10
},
"backgroundColor": "rgba(8, 28, 48, 0.95)",
"border": {
"color": "#CFCFCF",
"width": 0,
"radius": 2
},
"shadow": {
"x": 0,
"y": 4,
"blur": 12,
"spread": 0,
"color": "rgba(0, 0, 0, 0.2)"
}
},
"titleLabel": {
"fontSize": 14,
"fill": "#FFF",
"fontWeight": "bold",
"fontFamily": "SimSun",
"align": "left",
"lineHeight": 18
},
"keyLabel": {
"fontSize": 12,
"fill": "rgba(255,255,255,0.65)",
"fontWeight": "normal",
"fontFamily": "SimSun",
"align": "left",
"lineHeight": 18
},
"valueLabel": {
"fontSize": 12,
"fill": "#FFF",
"fontWeight": "normal",
"fontFamily": "SimSun",
"align": "right",
"lineHeight": 18
},
"shape": {
"size": 10,
"spacing": 10,
"shapeLineWidth": 0
},
"spaceRow": 10
}
}
}

View File

@ -0,0 +1,16 @@
import themeJson from './global.theme.json'
type ThemeJsonType = typeof themeJson
export type FontType = {
fontSize: number
fontFamily: string
fontWeight: string
fill: string
[T: string]: any
}
export interface vChartGlobalThemeJsonType extends Partial<ThemeJsonType> {
dataset?: any
[T: string]: any
}
export const vChartGlobalThemeJson = { ...themeJson, dataset: null }

View File

@ -57,6 +57,7 @@ export enum EditCanvasConfigEnum {
CHART_THEME_COLOR = 'chartThemeColor',
CHART_CUSTOM_THEME_COLOR_INFO = 'chartCustomThemeColorInfo',
CHART_THEME_SETTING = 'chartThemeSetting',
VCHART_THEME_NAME = 'vChartThemeName',
BACKGROUND = 'background',
BACKGROUND_IMAGE = 'backgroundImage',
SELECT_COLOR = 'selectColor',
@ -100,7 +101,9 @@ export interface EditCanvasConfigType {
// 图表全局配置
[EditCanvasConfigEnum.CHART_THEME_SETTING]: GlobalThemeJsonType
// 图表主题颜色
[EditCanvasConfigEnum.SELECT_COLOR]: boolean
[EditCanvasConfigEnum.SELECT_COLOR]: boolean,
// vChart 主题
[EditCanvasConfigEnum.VCHART_THEME_NAME]: string
// 预览展示方式
[EditCanvasConfigEnum.PREVIEW_SCALE_TYPE]: PreviewScaleEnum
}

View File

@ -114,6 +114,8 @@ export const useChartEditStore = defineStore({
chartCustomThemeColorInfo: undefined,
// 全局配置
chartThemeSetting: globalThemeJson,
// vChart 主题
vChartThemeName: 'vScreenVolcanoBlue',
// 适配方式
previewScaleType: previewScaleType
},

View File

@ -0,0 +1,245 @@
<template>
<n-grid :x-gap="8" :y-gap="8" :cols="2">
<n-gi v-for="item in list" :key="item.value">
<div
class="theme-item"
:class="{ active: item.value === vChartThemeName }"
size="small"
@click="selectThemeHandle(item)"
>
<n-ellipsis class="go-mr-1" style="text-align: left">{{ item.name }} </n-ellipsis>
<n-space :wrap="false" :wrap-item="false" :size="2">
<span
class="theme-color-item"
v-for="colorItem in item.colors"
:key="colorItem"
:style="{ backgroundColor: colorItem }"
></span>
</n-space>
</div>
</n-gi>
</n-grid>
<div class="go-my-4">行业模板</div>
<n-grid :x-gap="8" :y-gap="8" :cols="2">
<n-gi v-for="item in industryList" :key="item.value">
<div
class="theme-item"
:class="{ active: item.value === vChartThemeName }"
size="small"
@click="selectThemeHandle(item)"
>
<n-ellipsis class="go-mr-2" style="text-align: left">{{ item.name }} </n-ellipsis>
<n-space :wrap="false" :wrap-item="false" :size="2">
<span
class="theme-color-item"
v-for="colorItem in item.colors"
:key="colorItem"
:style="{ backgroundColor: colorItem }"
></span>
</n-space>
</div>
</n-gi>
</n-grid>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import { useVCharts } from '@/hooks'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { EditCanvasConfigEnum } from '@/store/modules/chartEditStore/chartEditStore.d'
import { useDesignStore } from '@/store/modules/designStore/designStore'
const chartEditStore = useChartEditStore()
const designStore = useDesignStore()
const vCharts = useVCharts()
const themeMap = vCharts.getThemeMap()
const vChartThemeName = computed(() => {
return chartEditStore.getEditCanvasConfig.vChartThemeName
})
//
const themeColor = computed(() => {
return designStore.getAppTheme
})
const list = ref<
Array<{
name: string
value: keyof typeof themeMap
colors: string[]
}>
>([
{
name: '火山蓝(默认)',
value: 'vScreenVolcanoBlue',
colors: ['#2D64DD', '#284588', '#58B4B6']
},
{
name: '党建红',
value: 'vScreenPartyRed',
colors: ['#d3d3d4', '#d68a46', '#d74f3c']
},
{
name: '清新蜡笔',
value: 'vScreenClean',
colors: ['#94AF60', '#7696B8', '#d6837a']
},
{
name: '郊外',
value: 'vScreenOutskirts',
colors: ['#A7C4E6', '#e1bf99', '#c0bcbb']
},
{
name: '汽车蓝橙',
value: 'vScreenBlueOrange',
colors: ['#acd5fa', '#cc896b', '#5ea4dd']
},
{
name: '金融黄',
value: 'vScreenFinanceYellow',
colors: ['#d7d7d7', '#f09761', '#f7d177']
},
{
name: '文旅青',
value: 'vScreenWenLvCyan',
colors: ['#63c6ba', '#dcb974', '#a34440']
},
{
name: '电力绿',
value: 'vScreenElectricGreen',
colors: ['#75faf2', '#ee813e', '#f4ce7f']
},
{
name: '电商紫',
value: 'vScreenECommercePurple',
colors: ['#6d4cf6', '#ed7266', '#5f83f7']
},
{
name: '红蓝',
value: 'vScreenRedBlue',
colors: ['#2e6cf6', '#bc4741', '#c1e4fb']
}
])
//
const industryList = ref<
Array<{
name: string
value: keyof typeof themeMap
colors: string[]
}>
>([
{
name: '明亮(适用白背景)',
value: 'light',
colors: ['#3063f6', '#5dc3f9', '#f1f2f5']
},
{
name: '暗黑(适用黑背景)',
value: 'dark',
colors: ['#3063f6', '#5dc3f9', '#414348']
},
{
name: '亮-金融行业',
value: 'veODesignLightFinance',
colors: ['#dbba95', '#314b5e', '#f1f2f5']
},
{
name: '暗-金融行业',
value: 'veODesignDarkFinance',
colors: ['#dbba95', '#314b5e', '#414348']
},
{
name: '亮-政府行业',
value: 'veODesignLightGovernment',
colors: ['#c0403a', '#f6c552', '#f1f2f5']
},
{
name: '暗-政府行业',
value: 'veODesignDarkGovernment',
colors: ['#c0403a', '#f6c552', '#414348']
},
{
name: '亮-消费行业',
value: 'veODesignLightConsumer',
colors: ['#3f36ab', '#eb4854', '#f1f2f5']
},
{
name: '暗-消费行业',
value: 'veODesignDarkConsumer',
colors: ['#3f36ab', '#eb4854', '#414348']
},
{
name: '亮-汽车行业',
value: 'veODesignLightAutomobile',
colors: ['#1515d1', '#abb6cd', '#f1f2f5']
},
{
name: '暗-汽车行业',
value: 'veODesignDarkAutomobile',
colors: ['#1515d1', '#abb6cd', '#414348']
},
{
name: '亮-文旅行业',
value: 'veODesignLightCulturalTourism',
colors: ['#77b897', '#3c5a4b', '#f1f2f5']
},
{
name: '暗-文旅行业',
value: 'veODesignDarkCulturalTourism',
colors: ['#77b897', '#3c5a4b', '#414348']
},
{
name: '亮-医疗行业',
value: 'veODesignLightMedical',
colors: ['#76d0d1', '#314787', '#f1f2f5']
},
{
name: '暗-医疗行业',
value: 'veODesignDarkMedical',
colors: ['#76d0d1', '#314787', '#414348']
},
{
name: '亮-新能源行业',
value: 'veODesignLightNewEnergy',
colors: ['#64d886', '#1f3b76', '#f1f2f5']
},
{
name: '暗-新能源行业',
value: 'veODesignDarkNewEnergy',
colors: ['#64d886', '#1f3b76', '#414348']
}
])
const selectThemeHandle = (item: { name: string; value: keyof typeof themeMap; colors: string[] }) => {
vCharts.setTheme(item.value)
chartEditStore.setEditCanvasConfig(EditCanvasConfigEnum.VCHART_THEME_NAME, item.value)
}
</script>
<style lang="scss" scoped>
$radius: 6px;
$itemRadius: 2px;
.theme-item {
display: flex;
justify-content: space-between;
align-items: center;
height: 34px;
padding: 0 8px;
overflow: hidden;
cursor: pointer;
font-size: 13px;
border-radius: $radius;
@include fetch-bg-color('background-color4-shallow');
&.active {
color: v-bind('themeColor');
}
.theme-color-item {
display: inline-block;
width: 16px;
height: 16px;
border-radius: $itemRadius;
}
}
</style>

View File

@ -150,6 +150,7 @@ const switchSelectColorLoading = ref(false)
const selectColorValue = ref(0)
const ChartThemeColor = loadAsyncComponent(() => import('./components/ChartThemeColor/index.vue'))
const VChartThemeColor = loadAsyncComponent(() => import('./components/VChartThemeColor/index.vue'))
//
const selectColorOptions = [
@ -166,10 +167,16 @@ const selectColorOptions = [
const globalTabList = [
{
key: 'ChartTheme',
title: '主题颜色',
title: '默认主题',
icon: ColorPaletteIcon,
render: ChartThemeColor
}
},
{
key: 'VChartTheme',
title: 'VChart主题',
icon: ColorPaletteIcon,
render: VChartThemeColor
},
]
const previewTypeList = [

View File

@ -1,6 +1,7 @@
<template>
<n-timeline class="go-chart-configurations-timeline">
<n-timeline-item v-show="isCharts && dimensionsAndSource" type="info" :title="TimelineTitleEnum.MAPPING">
<!-- 处理 echarts 的数据映射 -->
<n-timeline-item v-if="isCharts && dimensionsAndSource" type="info" :title="TimelineTitleEnum.MAPPING">
<n-table striped>
<thead>
<tr>
@ -25,6 +26,47 @@
</tbody>
</n-table>
</n-timeline-item>
<!-- 处理 vcharts 的数据映射 -->
<n-timeline-item v-if="isVChart" type="info" :title="TimelineTitleEnum.MAPPING">
<n-table striped>
<thead>
<tr>
<th v-for="item in vchartTableTitle" :key="item">{{ item }}</th>
</tr>
</thead>
<tbody>
<tr v-for="item in fieldList" :key="item.field">
<td>
<n-ellipsis style="width: 70px; max-width: 240px">
{{ item.field }}
</n-ellipsis>
</td>
<td v-if="isArray(item.mapping)">
<n-space :size="4" vertical>
<n-input
v-for="(mappingItem, index) in item.mapping"
:key="index"
v-model:value="item.mapping[index]"
type="tiny"
size="small"
placeholder="输入字段"
@change="() => (item.result = matchingHandle(item.mapping[index]))"
/>
</n-space>
</td>
<td v-else>
<n-input v-model:value="item.mapping" type="text" size="small" placeholder="小" />
</td>
<!-- <td>
<n-space style="width: 70px" :size="4">
<n-badge dot :type="item.result === 1 ? 'success' : 'error'"></n-badge>
<n-text>匹配{{ item.result === 1 ? '成功' : '失败' }}</n-text>
</n-space>
</td> -->
</tr>
</tbody>
</n-table>
</n-timeline-item>
<n-timeline-item v-show="filterShow" color="#97846c" :title="TimelineTitleEnum.FILTER">
<n-space :size="18" vertical>
<n-text depth="3">过滤器默认处理接口返回值的data字段</n-text>
@ -66,7 +108,7 @@
<help-outline-icon></help-outline-icon>
</n-icon>
</template>
<n-text depth="3">点击下载查看完整数据</n-text>
<span>点击下载查看完整数据</span>
</n-tooltip>
</div>
</n-space>
@ -87,11 +129,10 @@ import { DataResultEnum, TimelineTitleEnum } from '../../index.d'
import { ChartDataMonacoEditor } from '../ChartDataMonacoEditor'
import { useFile } from '../../hooks/useFile.hooks'
import { useTargetData } from '../../../hooks/useTargetData.hook'
import isObject from 'lodash/isObject'
import { toString, isArray } from '@/utils'
const { targetData } = useTargetData()
const props = defineProps({
defineProps({
show: {
type: Boolean,
required: false
@ -104,6 +145,7 @@ const props = defineProps({
//
const tableTitle = ['字段', '映射', '状态']
const vchartTableTitle = ['字段', '接口映射字段']
const { HelpOutlineIcon } = icon.ionicons5
const { DocumentAddIcon, DocumentDownloadIcon } = icon.carbon
@ -113,6 +155,15 @@ const dimensions = ref()
const dimensionsAndSource = ref()
const noData = ref(false)
// , mapping
const fieldList = ref<
Array<{
field: string
mapping: string[]
result: DataResultEnum
}>
>([])
const { uploadFileListRef, customRequest, beforeUpload, download } = useFile(targetData)
//
@ -124,6 +175,10 @@ const filterShow = computed(() => {
const isCharts = computed(() => {
return targetData.value.chartConfig.chartFrame === ChartFrameEnum.ECHARTS
})
// vchart
const isVChart = computed(() => {
return targetData.value.chartConfig.chartFrame === ChartFrameEnum.VCHART
})
//
const matchingHandle = (mapping: string) => {
@ -162,6 +217,29 @@ const dimensionsAndSourceHandle = () => {
}
}
// vchart
const initFieldListHandle = () => {
if (targetData.value?.option) {
fieldList.value = []
// Field key
for (const key in targetData.value.option) {
if (key.endsWith('Field')) {
const value = targetData.value.option[key]
targetData.value.option[key] = value
const item = {
field: key,
mapping: value,
result: DataResultEnum.SUCCESS
}
if (item.mapping === undefined) {
item.result = DataResultEnum.FAILURE
}
fieldList.value.push(item)
}
}
}
}
watch(
() => targetData.value?.option?.dataset,
(
@ -178,9 +256,13 @@ watch(
dimensions.value = newData.dimensions
dimensionsAndSource.value = dimensionsAndSourceHandle()
}
} else if (newData && targetData?.value?.chartConfig?.chartFrame === ChartFrameEnum.VCHART) {
source.value = newData
initFieldListHandle()
} else if (newData !== undefined && newData !== null) {
dimensionsAndSource.value = null
source.value = newData
fieldList.value = []
} else {
noData.value = true
source.value = '此组件无数据源'

View File

@ -82,7 +82,8 @@ import {
wordCloudUrl,
treemapUrl,
threeEarth01Url,
sankeyUrl
sankeyUrl,
vchartBarDataUrl
} from '@/api/mock'
const props = defineProps({
@ -150,7 +151,10 @@ const apiList = [
},
{
value: `【关系图】${graphUrl}`
}
},
{
value: `【vchart 柱状图】${vchartBarDataUrl}`
},
]
</script>

View File

@ -83,7 +83,7 @@
</template>
<script lang="ts" setup>
import { onMounted, computed, provide } from 'vue'
import { onMounted, computed, provide, watch } from 'vue'
import { chartColors } from '@/settings/chartThemes/index'
import { MenuEnum } from '@/enums/editPageEnum'
import { CreateComponentType, CreateComponentGroupType } from '@/packages/index.d'
@ -96,6 +96,7 @@ import { useLayout } from './hooks/useLayout.hook'
import { useAddKeyboard } from '../hooks/useKeyboard.hook'
import { dragHandle, dragoverHandle, mousedownHandleUnStop, useMouseHandle } from './hooks/useDrag.hook'
import { useComponentStyle, useSizeStyle } from './hooks/useStyle.hook'
import { useInitVChartsTheme } from '@/hooks'
import { ContentBox } from '../ContentBox/index'
import { EditGroup } from './components/EditGroup'
@ -149,7 +150,7 @@ const themeSetting = computed(() => {
//
const themeColor = computed(() => {
const colorCustomMergeData = colorCustomMerge(chartEditStore.getEditCanvasConfig.chartCustomThemeColorInfo)
const colorCustomMergeData: any = colorCustomMerge(chartEditStore.getEditCanvasConfig.chartCustomThemeColorInfo)
return colorCustomMergeData[chartEditStore.getEditCanvasConfig.chartThemeColor]
})
@ -170,7 +171,6 @@ const rangeStyle = computed(() => {
? { background: backgroundColor }
: { background: `url(${backgroundImage}) no-repeat center center / cover !important` }
// @ts-ignore
return {
...computedBackground,
width: 'inherit',
@ -178,6 +178,9 @@ const rangeStyle = computed(() => {
}
})
// vChart
useInitVChartsTheme(chartEditStore)
//
onMounted(() => {
useAddKeyboard()

View File

@ -37,6 +37,7 @@ import { useStore } from './hooks/useStore.hook'
import { PreviewScaleEnum } from '@/enums/styleEnum'
import type { ChartEditStorageType } from './index.d'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { useInitVChartsTheme } from '@/hooks'
// const localStorageInfo: ChartEditStorageType = getSessionStorageInfo() as ChartEditStorageType
@ -64,6 +65,9 @@ const { show } = useComInstall(chartEditStore)
//
keyRecordHandle()
// vChart
useInitVChartsTheme(chartEditStore)
</script>
<style lang="scss" scoped>

View File

@ -20,6 +20,6 @@
// "strictNullChecks": true, //使null
"noImplicitThis": true //this
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "types/**/*"],
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue", "types/**/*", "src/api/mock/vchart/bar.js"],
"exclude": ["node_modules", "dist", "**/*.js"]
}