feat: 柱状图 折线图增加双y轴

This commit is contained in:
huanghao1412 2024-02-21 17:49:37 +08:00
parent c06ffdae84
commit 6085d01914
16 changed files with 470 additions and 172 deletions

View File

@ -160,97 +160,99 @@
</setting-item-box> </setting-item-box>
</collapse-item> </collapse-item>
<collapse-item v-if="yAxis" name="Y轴"> <template v-for="(yAxis, i) in yAxisArr" :key="i">
<template #header> <collapse-item v-if="yAxis" :name="`Y轴-${i + 1}`">
<n-switch v-model:value="yAxis.show" size="small"></n-switch> <template #header>
</template> <n-switch v-model:value="yAxis.show" size="small"></n-switch>
<setting-item-box name="单位"> </template>
<setting-item name="名称"> <setting-item-box name="单位">
<n-input v-model:value="yAxis.name" size="small"></n-input> <setting-item name="名称">
</setting-item> <n-input v-model:value="yAxis.name" size="small"></n-input>
<setting-item name="颜色"> </setting-item>
<n-color-picker size="small" v-model:value="yAxis.nameTextStyle.color"></n-color-picker> <setting-item name="颜色">
</setting-item> <n-color-picker size="small" v-model:value="yAxis.nameTextStyle.color"></n-color-picker>
<setting-item name="大小"> </setting-item>
<n-input-number v-model:value="yAxis.nameTextStyle.fontSize" :min="8" size="small"></n-input-number> <setting-item name="大小">
</setting-item> <n-input-number v-model:value="yAxis.nameTextStyle.fontSize" :min="8" size="small"></n-input-number>
<setting-item name="偏移量"> </setting-item>
<n-input-number v-model:value="yAxis.nameGap" :min="5" size="small"></n-input-number> <setting-item name="偏移量">
</setting-item> <n-input-number v-model:value="yAxis.nameGap" :min="5" size="small"></n-input-number>
</setting-item-box> </setting-item>
<setting-item-box name="标签"> </setting-item-box>
<setting-item name="展示"> <setting-item-box name="标签">
<n-space> <setting-item name="展示">
<n-switch v-model:value="yAxis.axisLabel.show" size="small"></n-switch> <n-space>
</n-space> <n-switch v-model:value="yAxis.axisLabel.show" size="small"></n-switch>
</setting-item> </n-space>
<setting-item name="颜色"> </setting-item>
<n-color-picker size="small" v-model:value="yAxis.axisLabel.color"></n-color-picker> <setting-item name="颜色">
</setting-item> <n-color-picker size="small" v-model:value="yAxis.axisLabel.color"></n-color-picker>
<setting-item name="大小"> </setting-item>
<n-input-number v-model:value="yAxis.axisLabel.fontSize" :min="8" size="small"></n-input-number> <setting-item name="大小">
</setting-item> <n-input-number v-model:value="yAxis.axisLabel.fontSize" :min="8" size="small"></n-input-number>
<setting-item name="偏移量"> </setting-item>
<n-input-number v-model:value="yAxis.axisLabel.rotate" :min="-90" :max="90" size="small"></n-input-number> <setting-item name="偏移量">
</setting-item> <n-input-number v-model:value="yAxis.axisLabel.rotate" :min="-90" :max="90" size="small"></n-input-number>
</setting-item-box> </setting-item>
<setting-item-box name="轴线"> </setting-item-box>
<setting-item name="展示"> <setting-item-box name="轴线">
<n-space> <setting-item name="展示">
<n-switch v-model:value="yAxis.axisLine.show" size="small"></n-switch> <n-space>
</n-space> <n-switch v-model:value="yAxis.axisLine.show" size="small"></n-switch>
</setting-item> </n-space>
<setting-item name="颜色"> </setting-item>
<n-color-picker v-model:value="yAxis.axisLine.lineStyle.color" size="small"></n-color-picker> <setting-item name="颜色">
</setting-item> <n-color-picker v-model:value="yAxis.axisLine.lineStyle.color" size="small"></n-color-picker>
<setting-item name="粗细"> </setting-item>
<n-input-number v-model:value="yAxis.axisLine.lineStyle.width" :min="1" size="small"></n-input-number> <setting-item name="粗细">
</setting-item> <n-input-number v-model:value="yAxis.axisLine.lineStyle.width" :min="1" size="small"></n-input-number>
<setting-item name="位置"> </setting-item>
<n-select v-model:value="yAxis.position" size="small" :options="axisConfig.yposition"></n-select> <setting-item name="位置">
</setting-item> <n-select v-model:value="yAxis.position" size="small" :options="axisConfig.yposition"></n-select>
<setting-item name="对齐零"> </setting-item>
<n-space> <setting-item name="对齐零">
<n-switch v-model:value="yAxis.axisLine.onZero" size="small"></n-switch> <n-space>
</n-space> <n-switch v-model:value="yAxis.axisLine.onZero" size="small"></n-switch>
</setting-item> </n-space>
<setting-item name="反向"> </setting-item>
<n-space> <setting-item name="反向">
<n-switch v-model:value="yAxis.inverse" size="small"></n-switch> <n-space>
</n-space> <n-switch v-model:value="yAxis.inverse" size="small"></n-switch>
</setting-item> </n-space>
</setting-item-box> </setting-item>
<setting-item-box name="刻度"> </setting-item-box>
<setting-item name="展示"> <setting-item-box name="刻度">
<n-space> <setting-item name="展示">
<n-switch v-model:value="yAxis.axisTick.show" size="small"></n-switch> <n-space>
</n-space> <n-switch v-model:value="yAxis.axisTick.show" size="small"></n-switch>
</setting-item> </n-space>
<setting-item name="长度"> </setting-item>
<n-input-number v-model:value="yAxis.axisTick.length" :min="1" size="small"></n-input-number> <setting-item name="长度">
</setting-item> <n-input-number v-model:value="yAxis.axisTick.length" :min="1" size="small"></n-input-number>
</setting-item-box> </setting-item>
<setting-item-box name="分割线"> </setting-item-box>
<setting-item name="展示"> <setting-item-box name="分割线">
<n-space> <setting-item name="展示">
<n-switch v-model:value="yAxis.splitLine.show" size="small"></n-switch> <n-space>
</n-space> <n-switch v-model:value="yAxis.splitLine.show" size="small"></n-switch>
</setting-item> </n-space>
<setting-item name="颜色"> </setting-item>
<n-color-picker v-model:value="yAxis.splitLine.lineStyle.color" size="small"></n-color-picker> <setting-item name="颜色">
</setting-item> <n-color-picker v-model:value="yAxis.splitLine.lineStyle.color" size="small"></n-color-picker>
<setting-item name="粗细"> </setting-item>
<n-input-number v-model:value="yAxis.splitLine.lineStyle.width" :min="1" size="small"></n-input-number> <setting-item name="粗细">
</setting-item> <n-input-number v-model:value="yAxis.splitLine.lineStyle.width" :min="1" size="small"></n-input-number>
<setting-item name="类型"> </setting-item>
<n-select <setting-item name="类型">
v-model:value="yAxis.splitLine.lineStyle.type" <n-select
size="small" v-model:value="yAxis.splitLine.lineStyle.type"
:options="axisConfig.splitLint.lineStyle.type" size="small"
></n-select> :options="axisConfig.splitLint.lineStyle.type"
</setting-item> ></n-select>
</setting-item-box> </setting-item>
</collapse-item> </setting-item-box>
</collapse-item>
</template>
<collapse-item v-if="legend" name="图例"> <collapse-item v-if="legend" name="图例">
<template #header> <template #header>
@ -372,7 +374,7 @@ const xAxis = computed(() => {
return props.optionData.xAxis return props.optionData.xAxis
}) })
const yAxis = computed(() => { const yAxisArr = computed(() => {
return props.optionData.yAxis return props.optionData.yAxis
}) })

View File

@ -52,21 +52,21 @@ export const useChartCommonData = (
// 多个值的处理方式 // 多个值的处理方式
if(SingleDataArr.every(_ => _ !== currentSource)) { if(SingleDataArr.every(_ => _ !== currentSource)) {
let seriesItem = cloneDeep(targetComponent.option.series[0]) let seriesItem = cloneDeep(targetComponent.option.series[0])
let series = [] // let series = []
if(dataset.dimensions.length - 1) { // if(dataset.dimensions.length - 1) {
for(let i = 0; i < dataset.dimensions.length - 1; i++) { // for(let i = 0; i < dataset.dimensions.length - 1; i++) {
series.push(cloneDeep(seriesItem)) // series.push(cloneDeep(seriesItem))
} // }
} // }
else { // else {
series = [seriesItem] // series = [seriesItem]
} // }
if (vChartRef.value) { if (vChartRef.value) {
Object.assign(targetComponent.option, { Object.assign(targetComponent.option, {
series, // series,
dataset, dataset,
}) })
setOption(vChartRef.value, { series, dataset }) setOption(vChartRef.value, { dataset })
} }
} }
else if(SingleDataArr.some(_ => _ === currentSource)) { // 单个值的处理 else if(SingleDataArr.some(_ => _ === currentSource)) { // 单个值的处理

View File

@ -17,7 +17,8 @@ export const seriesItem = {
itemStyle: { itemStyle: {
color: null, color: null,
borderRadius: 2 borderRadius: 2
} },
yAxisIndex: 0
} }
export const option = { export const option = {
tooltip: { tooltip: {
@ -28,7 +29,7 @@ export const option = {
type: 'shadow' type: 'shadow'
} }
}, },
xAxis: { xAxis: {
show: true, show: true,
type: 'category' type: 'category'
}, },

View File

@ -5,6 +5,11 @@
<SettingItemBox name="" :alone="true"> <SettingItemBox name="" :alone="true">
<n-text>修改此配置将覆盖全部系列配置</n-text> <n-text>修改此配置将覆盖全部系列配置</n-text>
</SettingItemBox> </SettingItemBox>
<SettingItemBox name="Y轴索引">
<setting-item>
<n-select v-model:value="allSeriesConfig.yAxisIndex" :options="yAxisIndexOptions" size="small" />
</setting-item>
</SettingItemBox>
<SettingItemBox name="图形"> <SettingItemBox name="图形">
<SettingItem name="宽度"> <SettingItem name="宽度">
<n-input-number <n-input-number
@ -46,6 +51,25 @@
</setting-item-box> </setting-item-box>
</CollapseItem> </CollapseItem>
<CollapseItem v-for="(item, index) in seriesList" :key="index" :name="`柱状图-${index + 1}`" :expanded="true"> <CollapseItem v-for="(item, index) in seriesList" :key="index" :name="`柱状图-${index + 1}`" :expanded="true">
<template #header>
<n-space align="center" :wrap="false">
<n-button v-if="index !== 0" @click="handleDelete(index)" circle size="tiny">
<template #icon>
<n-icon><CloseIcon /></n-icon>
</template>
</n-button>
<n-button v-if="index === seriesList.length - 1" @click="handleAdd" circle size="tiny">
<template #icon>
<n-icon><AddIcon /></n-icon>
</template>
</n-button>
</n-space>
</template>
<SettingItemBox name="Y轴索引">
<setting-item>
<n-select v-model:value="item.yAxisIndex" :options="yAxisIndexOptions" size="small" />
</setting-item>
</SettingItemBox>
<SettingItemBox name="图形"> <SettingItemBox name="图形">
<SettingItem name="宽度"> <SettingItem name="宽度">
<n-input-number <n-input-number
@ -95,6 +119,8 @@ import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/comp
import { GlobalThemeJsonType } from '@/settings/chartThemes/index' import { GlobalThemeJsonType } from '@/settings/chartThemes/index'
import { seriesItem } from "./config"; import { seriesItem } from "./config";
import { cloneDeep } from "lodash"; import { cloneDeep } from "lodash";
import { icon } from "@/plugins";
const { CloseIcon, AddIcon } = icon.ionicons5
const props = defineProps({ const props = defineProps({
optionData: { optionData: {
@ -113,13 +139,25 @@ const allSeriesConfig = computed(() => {
return props.optionData.allSeriesConfig return props.optionData.allSeriesConfig
}) })
const yAxisIndexOptions = [
{ label: 'Y轴-1', value: 0 },
{ label: 'Y轴-2', value: 1 },
]
const handleAdd = () => {
props.optionData.series.push(cloneDeep(seriesItem))
}
const handleDelete = (i: number) => {
props.optionData.series.splice(i, 1)
}
watch(() => allSeriesConfig.value, (v) => { watch(() => allSeriesConfig.value, (v) => {
seriesList.value.forEach((item: typeof seriesItem) => { seriesList.value.forEach((item: typeof seriesItem) => {
Object.assign(item, cloneDeep(v)) Object.assign(item, cloneDeep(v))
}) })
}, { }, {
deep: true, deep: true,
immediate: true // immediate: true
}) })
watch(() => seriesList.value, (v) => { watch(() => seriesList.value, (v) => {

View File

@ -17,7 +17,8 @@ export const seriesItem = {
itemStyle: { itemStyle: {
color: null, color: null,
borderRadius: 0 borderRadius: 0
} },
yAxisIndex: 0
} }
export const option = { export const option = {
tooltip: { tooltip: {
@ -32,10 +33,16 @@ export const option = {
show: true, show: true,
type: 'value' type: 'value'
}, },
yAxis: { yAxis: [
show: true, {
type: 'category' show: true,
}, type: 'category'
},
{
show: false,
type: 'category'
}
],
dataset: { ...dataJson }, dataset: { ...dataJson },
series: [seriesItem, seriesItem], series: [seriesItem, seriesItem],
allSeriesConfig: seriesItem allSeriesConfig: seriesItem

View File

@ -5,6 +5,11 @@
<SettingItemBox name="" :alone="true"> <SettingItemBox name="" :alone="true">
<n-text>修改此配置将覆盖全部系列配置</n-text> <n-text>修改此配置将覆盖全部系列配置</n-text>
</SettingItemBox> </SettingItemBox>
<SettingItemBox name="Y轴索引">
<setting-item>
<n-select v-model:value="allSeriesConfig.yAxisIndex" :options="yAxisIndexOptions" size="small" />
</setting-item>
</SettingItemBox>
<SettingItemBox name="图形"> <SettingItemBox name="图形">
<SettingItem name="宽度"> <SettingItem name="宽度">
<n-input-number <n-input-number
@ -58,6 +63,25 @@
</setting-item-box> </setting-item-box>
</CollapseItem> </CollapseItem>
<CollapseItem v-for="(item, index) in seriesList" :key="index" :name="`柱状图-${index+1}`" :expanded="true"> <CollapseItem v-for="(item, index) in seriesList" :key="index" :name="`柱状图-${index+1}`" :expanded="true">
<template #header>
<n-space align="center" :wrap="false">
<n-button v-if="index !== 0" @click="handleDelete(index)" circle size="tiny">
<template #icon>
<n-icon><CloseIcon /></n-icon>
</template>
</n-button>
<n-button v-if="index === seriesList.length - 1" @click="handleAdd" circle size="tiny">
<template #icon>
<n-icon><AddIcon /></n-icon>
</template>
</n-button>
</n-space>
</template>
<SettingItemBox name="Y轴索引">
<setting-item>
<n-select v-model:value="item.yAxisIndex" :options="yAxisIndexOptions" size="small" />
</setting-item>
</SettingItemBox>
<SettingItemBox name="图形"> <SettingItemBox name="图形">
<SettingItem name="宽度"> <SettingItem name="宽度">
<n-input-number <n-input-number
@ -120,6 +144,8 @@ import { option } from './config'
import { GlobalThemeJsonType } from '@/settings/chartThemes/index' import { GlobalThemeJsonType } from '@/settings/chartThemes/index'
import { seriesItem } from "./config" import { seriesItem } from "./config"
import { cloneDeep } from "lodash" import { cloneDeep } from "lodash"
import { icon } from "@/plugins";
const { CloseIcon, AddIcon } = icon.ionicons5
const props = defineProps({ const props = defineProps({
optionData: { optionData: {
@ -138,13 +164,25 @@ const allSeriesConfig = computed(() => {
return props.optionData.allSeriesConfig return props.optionData.allSeriesConfig
}) })
const yAxisIndexOptions = [
{ label: 'Y轴-1', value: 0 },
{ label: 'Y轴-2', value: 1 },
]
const handleAdd = () => {
props.optionData.series.push(cloneDeep(seriesItem))
}
const handleDelete = (i: number) => {
props.optionData.series.splice(i, 1)
}
watch(() => allSeriesConfig.value, (v) => { watch(() => allSeriesConfig.value, (v) => {
seriesList.value.forEach((item: typeof seriesItem) => { seriesList.value.forEach((item: typeof seriesItem) => {
Object.assign(item, cloneDeep(v)) Object.assign(item, cloneDeep(v))
}) })
}, { }, {
deep: true, deep: true,
immediate: true // immediate: true
}) })
watch(() => seriesList.value, (v) => { watch(() => seriesList.value, (v) => {

View File

@ -23,7 +23,8 @@ export const seriesItem = {
type: 'solid', type: 'solid',
width: 3, width: 3,
color: null color: null
} },
yAxisIndex: 0
} }
export const option = { export const option = {

View File

@ -5,6 +5,11 @@
<SettingItemBox name="" :alone="true"> <SettingItemBox name="" :alone="true">
<n-text>修改此配置将覆盖全部折线配置</n-text> <n-text>修改此配置将覆盖全部折线配置</n-text>
</SettingItemBox> </SettingItemBox>
<SettingItemBox name="Y轴索引">
<setting-item>
<n-select v-model:value="allSeriesConfig.yAxisIndex" :options="yAxisIndexOptions" size="small" />
</setting-item>
</SettingItemBox>
<SettingItemBox name="线条"> <SettingItemBox name="线条">
<setting-item> <setting-item>
<n-space> <n-space>
@ -63,6 +68,25 @@
</setting-item-box> </setting-item-box>
</CollapseItem> </CollapseItem>
<CollapseItem v-for="(item, index) in seriesList" :key="index" :name="`折线图-${index + 1}`" :expanded="true"> <CollapseItem v-for="(item, index) in seriesList" :key="index" :name="`折线图-${index + 1}`" :expanded="true">
<template #header>
<n-space align="center" :wrap="false">
<n-button v-if="index !== 0" @click="handleDelete(index)" circle size="tiny">
<template #icon>
<n-icon><CloseIcon /></n-icon>
</template>
</n-button>
<n-button v-if="index === seriesList.length - 1" @click="handleAdd" circle size="tiny">
<template #icon>
<n-icon><AddIcon /></n-icon>
</template>
</n-button>
</n-space>
</template>
<SettingItemBox name="Y轴索引">
<setting-item>
<n-select v-model:value="item.yAxisIndex" :options="yAxisIndexOptions" size="small" />
</setting-item>
</SettingItemBox>
<SettingItemBox name="线条"> <SettingItemBox name="线条">
<setting-item> <setting-item>
<n-space> <n-space>
@ -130,6 +154,8 @@ import { GlobalThemeJsonType } from '@/settings/chartThemes/index'
import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { seriesItem } from './config' import { seriesItem } from './config'
import { cloneDeep } from 'lodash' import { cloneDeep } from 'lodash'
import { icon } from "@/plugins";
const { CloseIcon, AddIcon } = icon.ionicons5
const props = defineProps({ const props = defineProps({
optionData: { optionData: {
@ -148,13 +174,25 @@ const allSeriesConfig = computed(() => {
return props.optionData.allSeriesConfig return props.optionData.allSeriesConfig
}) })
const yAxisIndexOptions = [
{ label: 'Y轴-1', value: 0 },
{ label: 'Y轴-2', value: 1 },
]
const handleAdd = () => {
props.optionData.series.push(cloneDeep(seriesItem))
}
const handleDelete = (i: number) => {
props.optionData.series.splice(i, 1)
}
watch(() => allSeriesConfig.value, (v) => { watch(() => allSeriesConfig.value, (v) => {
seriesList.value.forEach((item: typeof seriesItem) => { seriesList.value.forEach((item: typeof seriesItem) => {
Object.assign(item, cloneDeep(v)) Object.assign(item, cloneDeep(v))
}) })
}, { }, {
deep: true, deep: true,
immediate: true // immediate: true
}) })
watch(() => seriesList.value, (v) => { watch(() => seriesList.value, (v) => {

View File

@ -34,7 +34,8 @@ export const seriesItem = {
color: 'rgba(0,0,0,0)' color: 'rgba(0,0,0,0)'
} }
]) ])
} },
yAxisIndex: 0
} }
const options = { const options = {

View File

@ -5,6 +5,11 @@
<SettingItemBox name="" :alone="true"> <SettingItemBox name="" :alone="true">
<n-text>修改此配置将覆盖全部折线配置</n-text> <n-text>修改此配置将覆盖全部折线配置</n-text>
</SettingItemBox> </SettingItemBox>
<SettingItemBox name="Y轴索引">
<setting-item>
<n-select v-model:value="allSeriesConfig.yAxisIndex" :options="yAxisIndexOptions" size="small" />
</setting-item>
</SettingItemBox>
<SettingItemBox name="线条"> <SettingItemBox name="线条">
<setting-item> <setting-item>
<n-space> <n-space>
@ -63,6 +68,25 @@
</setting-item-box> </setting-item-box>
</CollapseItem> </CollapseItem>
<CollapseItem v-for="(item, index) in seriesList" :key="index" :name="`折线面积图-${index + 1}`" :expanded="true"> <CollapseItem v-for="(item, index) in seriesList" :key="index" :name="`折线面积图-${index + 1}`" :expanded="true">
<template #header>
<n-space align="center" :wrap="false">
<n-button v-if="index !== 0" @click="handleDelete(index)" circle size="tiny">
<template #icon>
<n-icon><CloseIcon /></n-icon>
</template>
</n-button>
<n-button v-if="index === seriesList.length - 1" @click="handleAdd(index)" circle size="tiny">
<template #icon>
<n-icon><AddIcon /></n-icon>
</template>
</n-button>
</n-space>
</template>
<SettingItemBox name="Y轴索引">
<setting-item>
<n-select v-model:value="item.yAxisIndex" :options="yAxisIndexOptions" size="small" />
</setting-item>
</SettingItemBox>
<SettingItemBox name="线条"> <SettingItemBox name="线条">
<setting-item> <setting-item>
<n-space> <n-space>
@ -126,11 +150,14 @@
import { PropType, computed, ref, watch } from 'vue' import { PropType, computed, ref, watch } from 'vue'
import type { Ref } from 'vue' import type { Ref } from 'vue'
import { lineConf } from '@/packages/chartConfiguration/echarts/index' import { lineConf } from '@/packages/chartConfiguration/echarts/index'
import { chartColorsSearch, defaultTheme, GlobalThemeJsonType } from '@/settings/chartThemes/index' import {chartColors, chartColorsSearch, defaultTheme, GlobalThemeJsonType} from '@/settings/chartThemes/index'
import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting' import { GlobalSetting, CollapseItem, SettingItemBox, SettingItem } from '@/components/Pages/ChartItemSetting'
import { seriesItem } from "./config"; import { seriesItem } from "./config";
import { cloneDeep } from "lodash"; import { cloneDeep } from "lodash";
import { graphic } from "echarts/core"; import { graphic } from "echarts/core";
import { icon } from "@/plugins";
import {alpha} from "@/utils";
const { CloseIcon, AddIcon } = icon.ionicons5
const props = defineProps({ const props = defineProps({
optionData: { optionData: {
@ -149,13 +176,39 @@ const allSeriesConfig = computed(() => {
return props.optionData.allSeriesConfig return props.optionData.allSeriesConfig
}) })
const yAxisIndexOptions = [
{ label: 'Y轴-1', value: 0 },
{ label: 'Y轴-2', value: 1 },
]
const handleAdd = (i: number) => {
let item = cloneDeep(seriesItem)
// const themeColor = chartColorsSearch[defaultTheme]
const themeColor = chartColors[defaultTheme].color
item.areaStyle.color = new graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: alpha(themeColor[(i + 1) % themeColor.length], 0.5)
},
{
offset: 1,
color: 'rgba(0,0,0, 0)'
}
])
props.optionData.series.push(item)
}
const handleDelete = (i: number) => {
props.optionData.series.splice(i, 1)
}
watch(() => allSeriesConfig.value, (v) => { watch(() => allSeriesConfig.value, (v) => {
seriesList.value.forEach((item: typeof seriesItem, index: number) => { seriesList.value.forEach((item: typeof seriesItem, index: number) => {
const themeColor = chartColorsSearch[defaultTheme] // const themeColor = chartColorsSearch[defaultTheme]
const themeColor = chartColors[defaultTheme].color
item.areaStyle.color = new graphic.LinearGradient(0, 0, 0, 1, [ item.areaStyle.color = new graphic.LinearGradient(0, 0, 0, 1, [
{ {
offset: 0, offset: 0,
color: themeColor[(3 + index) % themeColor.length] color: alpha(themeColor[index % themeColor.length], 0.5)
}, },
{ {
offset: 1, offset: 1,
@ -170,7 +223,7 @@ watch(() => allSeriesConfig.value, (v) => {
}) })
}, { }, {
deep: true, deep: true,
immediate: true // immediate: true
}) })
watch(() => seriesList.value, (v) => { watch(() => seriesList.value, (v) => {

View File

@ -13,10 +13,10 @@ import { LineChart } from 'echarts/charts'
import config, { includes } from './config' import config, { includes } from './config'
import { mergeTheme } from '@/packages/public/chart' import { mergeTheme } from '@/packages/public/chart'
import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore' import { useChartEditStore } from '@/store/modules/chartEditStore/chartEditStore'
import { chartColorsSearch, defaultTheme } from '@/settings/chartThemes/index' import {chartColors, chartColorsSearch, defaultTheme} from '@/settings/chartThemes/index'
import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components' import { DatasetComponent, GridComponent, TooltipComponent, LegendComponent } from 'echarts/components'
import {useChartCommonData, useChartDataFetch} from '@/hooks' import {useChartCommonData, useChartDataFetch} from '@/hooks'
import {isPreview, colorGradientCustomMerge, setTooltipPosition} from '@/utils' import {isPreview, colorGradientCustomMerge, setTooltipPosition, alpha} from '@/utils'
const props = defineProps({ const props = defineProps({
themeSetting: { themeSetting: {
@ -50,14 +50,16 @@ watch(
(newColor: keyof typeof chartColorsSearch) => { (newColor: keyof typeof chartColorsSearch) => {
try { try {
if (!isPreview()) { if (!isPreview()) {
const themeColor = // const themeColor =
colorGradientCustomMerge(chartEditStore.getEditCanvasConfig.chartCustomThemeColorInfo)[newColor] || // colorGradientCustomMerge(chartEditStore.getEditCanvasConfig.chartCustomThemeColorInfo)[newColor] ||
colorGradientCustomMerge(chartEditStore.getEditCanvasConfig.chartCustomThemeColorInfo)[defaultTheme] // colorGradientCustomMerge(chartEditStore.getEditCanvasConfig.chartCustomThemeColorInfo)[defaultTheme]
const themeColor = chartColors[newColor].color || chartColors[defaultTheme].color
props.chartConfig.option.series.forEach((value: any, index: number) => { props.chartConfig.option.series.forEach((value: any, index: number) => {
value.areaStyle.color = new graphic.LinearGradient(0, 0, 0, 1, [ value.areaStyle.color = new graphic.LinearGradient(0, 0, 0, 1, [
{ {
offset: 0, offset: 0,
color: themeColor[3] color: alpha(themeColor[index % themeColor.length], 0.5)
}, },
{ {
offset: 1, offset: 1,
@ -80,20 +82,41 @@ watch(
watch( watch(
() => props.chartConfig.option.dataset, () => props.chartConfig.option.dataset,
() => { () => {
const themeColor = colorGradientCustomMerge(chartEditStore.getEditCanvasConfig.chartCustomThemeColorInfo)[defaultTheme] // const themeColor = colorGradientCustomMerge(chartEditStore.getEditCanvasConfig.chartCustomThemeColorInfo)[defaultTheme]
props.chartConfig.option.series.forEach((value: any, index: number) => { // const themeColor = chartColors[defaultTheme].color
value.areaStyle.color = new graphic.LinearGradient(0, 0, 0, 1, [
{ // props.chartConfig.option.series.forEach((value: any, index: number) => {
offset: 0, // value.areaStyle.color = new graphic.LinearGradient(0, 0, 0, 1, [
color: themeColor[(3 + index) % themeColor.length] // {
}, // offset: 0,
{ // color: alpha(themeColor[index % themeColor.length], 0.5)
offset: 1, // },
color: 'rgba(0,0,0, 0)' // {
} // offset: 1,
]) // color: 'rgba(0,0,0, 0)'
}) // }
// ])
// })
option.value = props.chartConfig.option option.value = props.chartConfig.option
if (vChartRef.value) {
vChartRef.value.setOption(option.value, !isPreview())
}
}
)
watch(
() => props.chartConfig.option.series,
() => {
// option.value = mergeTheme(props.chartConfig.option, props.themeSetting, includes)
option.value = props.chartConfig.option
if (vChartRef.value) {
vChartRef.value.setOption(option.value, {
replaceMerge: ['series']
})
}
},
{
deep: true
} }
) )

View File

@ -35,7 +35,8 @@ export const seriesItem = {
shadowColor: chartColorsSearch[defaultTheme][2], shadowColor: chartColorsSearch[defaultTheme][2],
shadowBlur: 10, shadowBlur: 10,
shadowOffsetY: 20 shadowOffsetY: 20
} },
yAxisIndex: 0
} }
export const option = { export const option = {

View File

@ -5,6 +5,11 @@
<SettingItemBox name="" :alone="true"> <SettingItemBox name="" :alone="true">
<n-text>修改此配置将覆盖全部折线配置</n-text> <n-text>修改此配置将覆盖全部折线配置</n-text>
</SettingItemBox> </SettingItemBox>
<SettingItemBox name="Y轴索引">
<setting-item>
<n-select v-model:value="allSeriesConfig.yAxisIndex" :options="yAxisIndexOptions" size="small" />
</setting-item>
</SettingItemBox>
<SettingItemBox name="线条"> <SettingItemBox name="线条">
<setting-item> <setting-item>
<n-space> <n-space>
@ -81,6 +86,25 @@
:name="`折线图-${index + 1}`" :name="`折线图-${index + 1}`"
:expanded="true" :expanded="true"
> >
<template #header>
<n-space align="center" :wrap="false">
<n-button v-if="index !== 0" @click="handleDelete(index)" circle size="tiny">
<template #icon>
<n-icon><CloseIcon /></n-icon>
</template>
</n-button>
<n-button v-if="index === seriesList.length - 1" @click="handleAdd" circle size="tiny">
<template #icon>
<n-icon><AddIcon /></n-icon>
</template>
</n-button>
</n-space>
</template>
<SettingItemBox name="Y轴索引">
<setting-item>
<n-select v-model:value="item.yAxisIndex" :options="yAxisIndexOptions" size="small" />
</setting-item>
</SettingItemBox>
<SettingItemBox name="线条"> <SettingItemBox name="线条">
<setting-item> <setting-item>
<n-space> <n-space>
@ -166,6 +190,8 @@ import {
} from '@/components/Pages/ChartItemSetting' } from '@/components/Pages/ChartItemSetting'
import { seriesItem } from "./config"; import { seriesItem } from "./config";
import { cloneDeep } from "lodash"; import { cloneDeep } from "lodash";
import { icon } from "@/plugins";
const { CloseIcon, AddIcon } = icon.ionicons5
const props = defineProps({ const props = defineProps({
optionData: { optionData: {
@ -184,13 +210,25 @@ const allSeriesConfig = computed(() => {
return props.optionData.allSeriesConfig return props.optionData.allSeriesConfig
}) })
const yAxisIndexOptions = [
{ label: 'Y轴-1', value: 0 },
{ label: 'Y轴-2', value: 1 },
]
const handleAdd = () => {
props.optionData.series.push(cloneDeep(seriesItem))
}
const handleDelete = (i: number) => {
props.optionData.series.splice(i, 1)
}
watch(() => allSeriesConfig.value, (v) => { watch(() => allSeriesConfig.value, (v) => {
seriesList.value.forEach((item: typeof seriesItem) => { seriesList.value.forEach((item: typeof seriesItem) => {
Object.assign(item, cloneDeep(v)) Object.assign(item, cloneDeep(v))
}) })
}, { }, {
deep: true, deep: true,
immediate: true // immediate: true
}) })
watch(() => seriesList.value, (v) => { watch(() => seriesList.value, (v) => {

View File

@ -75,12 +75,30 @@ watch(
() => props.chartConfig.option.dataset, () => props.chartConfig.option.dataset,
() => { () => {
option.value = props.chartConfig.option option.value = props.chartConfig.option
if (vChartRef.value) {
vChartRef.value.setOption(option.value, !isPreview())
}
}, },
{ {
deep: false deep: false
} }
) )
watch(
() => props.chartConfig.option.series,
() => {
option.value = props.chartConfig.option
if (vChartRef.value) {
vChartRef.value.setOption(option.value, {
replaceMerge: ['series']
})
}
},
{
deep: true
}
)
// const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore) // const { vChartRef } = useChartDataFetch(props.chartConfig, useChartEditStore)
const { vChartRef } = useChartCommonData(props.chartConfig, useChartEditStore) const { vChartRef } = useChartCommonData(props.chartConfig, useChartEditStore)

View File

@ -282,7 +282,7 @@ const calcAligns = () => {
// //
// status.aligns = merge(aligns, align) // status.aligns = merge(aligns, align)
status.aligns = headerConfig.map((_: any) => _.align) status.aligns = headerConfig.filter((_: ItemType) => _.show).map((_: any) => _.align)
} }
const animation = async (start = false) => { const animation = async (start = false) => {

View File

@ -47,43 +47,82 @@
} }
} }
}, },
"yAxis": { "yAxis": [
"show": true, {
"name": "",
"nameGap": 15,
"nameTextStyle": {
"color": "#B9B8CE",
"fontSize": 12
},
"inverse": false,
"axisLabel": {
"show": true, "show": true,
"fontSize": 12, "name": "",
"color": "#B9B8CE", "nameGap": 15,
"rotate": 0 "nameTextStyle": {
},
"position": "left",
"axisLine": {
"show": true,
"lineStyle": {
"color": "#B9B8CE", "color": "#B9B8CE",
"width": 1 "fontSize": 12
}, },
"onZero": true "inverse": false,
"axisLabel": {
"show": true,
"fontSize": 12,
"color": "#B9B8CE",
"rotate": 0
},
"position": "left",
"axisLine": {
"show": true,
"lineStyle": {
"color": "#B9B8CE",
"width": 1
},
"onZero": true
},
"axisTick": {
"show": true,
"length": 5
},
"splitLine": {
"show": true,
"lineStyle": {
"color": "#484753",
"width": 1,
"type": "solid"
}
}
}, },
"axisTick": { {
"show": true, "show": false,
"length": 5 "name": "",
}, "nameGap": 15,
"splitLine": { "nameTextStyle": {
"show": true, "color": "#B9B8CE",
"lineStyle": { "fontSize": 12
"color": "#484753", },
"width": 1, "inverse": false,
"type": "solid" "axisLabel": {
"show": true,
"fontSize": 12,
"color": "#B9B8CE",
"rotate": 0
},
"position": "right",
"axisLine": {
"show": true,
"lineStyle": {
"color": "#B9B8CE",
"width": 1
},
"onZero": true
},
"axisTick": {
"show": true,
"length": 5
},
"splitLine": {
"show": false,
"lineStyle": {
"color": "#484753",
"width": 1,
"type": "solid"
}
} }
} }
}, ],
"legend": { "legend": {
"show": true, "show": true,
"type": "scroll", "type": "scroll",