mirror of
https://github.com/pipipi-pikachu/PPTist.git
synced 2025-04-15 02:20:00 +08:00
feat: 图表添加配置(平滑曲线、堆叠模式)
This commit is contained in:
parent
495799aafa
commit
2e4a3df988
@ -660,13 +660,16 @@ export default () => {
|
||||
if (el.chartType === 'bar') {
|
||||
type = pptx.ChartType.bar
|
||||
options.barDir = 'col'
|
||||
if (el.options?.stack) options.barGrouping = 'stacked'
|
||||
}
|
||||
else if (el.chartType === 'column') {
|
||||
type = pptx.ChartType.bar
|
||||
options.barDir = 'bar'
|
||||
if (el.options?.stack) options.barGrouping = 'stacked'
|
||||
}
|
||||
else if (el.chartType === 'line') {
|
||||
type = pptx.ChartType.line
|
||||
if (el.options?.lineSmooth) options.lineSmooth = true
|
||||
}
|
||||
else if (el.chartType === 'area') {
|
||||
type = pptx.ChartType.area
|
||||
|
@ -19,6 +19,7 @@ import type {
|
||||
PPTLineElement,
|
||||
ShapeTextAlign,
|
||||
PPTTextElement,
|
||||
ChartOptions,
|
||||
} from '@/types/slides'
|
||||
|
||||
const convertFontSizePtToPx = (html: string, ratio: number) => {
|
||||
@ -398,6 +399,8 @@ export default () => {
|
||||
legends = data.map(item => item.key)
|
||||
series = data.map(item => item.values.map(v => v.y))
|
||||
}
|
||||
|
||||
const options: ChartOptions = {}
|
||||
|
||||
let chartType: ChartType = 'bar'
|
||||
|
||||
@ -406,6 +409,7 @@ export default () => {
|
||||
case 'bar3DChart':
|
||||
chartType = 'bar'
|
||||
if (el.barDir === 'bar') chartType = 'column'
|
||||
if (el.grouping === 'stacked' || el.grouping === 'percentStacked') options.stack = true
|
||||
break
|
||||
case 'lineChart':
|
||||
case 'line3DChart':
|
||||
@ -413,6 +417,7 @@ export default () => {
|
||||
break
|
||||
case 'areaChart':
|
||||
case 'area3DChart':
|
||||
if (el.grouping === 'stacked' || el.grouping === 'percentStacked') options.stack = true
|
||||
chartType = 'area'
|
||||
break
|
||||
case 'scatterChart':
|
||||
@ -445,6 +450,7 @@ export default () => {
|
||||
legends,
|
||||
series,
|
||||
},
|
||||
options,
|
||||
})
|
||||
}
|
||||
else if (el.type === 'group' || el.type === 'diagram') {
|
||||
|
@ -394,6 +394,12 @@ export interface PPTLineElement extends Omit<PPTBaseElement, 'height' | 'rotate'
|
||||
|
||||
|
||||
export type ChartType = 'bar' | 'column' | 'line' | 'pie' | 'ring' | 'area' | 'scatter'
|
||||
|
||||
export interface ChartOptions {
|
||||
lineSmooth?: boolean
|
||||
stack?: boolean
|
||||
}
|
||||
|
||||
export interface ChartData {
|
||||
labels: string[]
|
||||
legends: string[]
|
||||
@ -411,6 +417,8 @@ export interface ChartData {
|
||||
*
|
||||
* data: 图表数据
|
||||
*
|
||||
* options: 扩展选项
|
||||
*
|
||||
* outline?: 边框
|
||||
*
|
||||
* themeColors: 主题色
|
||||
@ -422,6 +430,7 @@ export interface PPTChartElement extends PPTBaseElement {
|
||||
fill?: string
|
||||
chartType: ChartType
|
||||
data: ChartData
|
||||
options?: ChartOptions
|
||||
outline?: PPTElementOutline
|
||||
themeColors: string[]
|
||||
textColor?: string
|
||||
|
@ -6,6 +6,24 @@
|
||||
|
||||
<Divider />
|
||||
|
||||
<template v-if="['bar', 'column', 'area', 'line'].includes(handleChartElement.chartType)">
|
||||
<div class="row">
|
||||
<Checkbox
|
||||
v-if="handleChartElement.chartType === 'line'"
|
||||
@update:value="value => updateOptions({ lineSmooth: value })"
|
||||
:value="lineSmooth"
|
||||
>使用平滑曲线</Checkbox>
|
||||
<Checkbox
|
||||
v-if="['bar', 'column', 'area'].includes(handleChartElement.chartType)"
|
||||
@update:value="value => updateOptions({ stack: value })"
|
||||
:value="stack"
|
||||
style="flex: 1;"
|
||||
>堆叠样式</Checkbox>
|
||||
</div>
|
||||
|
||||
<Divider />
|
||||
</template>
|
||||
|
||||
<div class="row">
|
||||
<div style="width: 40%;">背景填充:</div>
|
||||
<Popover trigger="click" style="width: 60%;">
|
||||
@ -99,7 +117,7 @@
|
||||
import { onUnmounted, ref, watch, type Ref } from 'vue'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { useMainStore, useSlidesStore } from '@/store'
|
||||
import type { ChartData, PPTChartElement } from '@/types/slides'
|
||||
import type { ChartData, ChartOptions, PPTChartElement } from '@/types/slides'
|
||||
import emitter, { EmitterEvents } from '@/utils/emitter'
|
||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||
import { CHART_PRESET_THEMES } from '@/configs/chart'
|
||||
@ -110,6 +128,7 @@ import ColorButton from '@/components/ColorButton.vue'
|
||||
import ColorPicker from '@/components/ColorPicker/index.vue'
|
||||
import Modal from '@/components/Modal.vue'
|
||||
import Divider from '@/components/Divider.vue'
|
||||
import Checkbox from '@/components/Checkbox.vue'
|
||||
import Button from '@/components/Button.vue'
|
||||
import ButtonGroup from '@/components/ButtonGroup.vue'
|
||||
import Popover from '@/components/Popover.vue'
|
||||
@ -131,11 +150,26 @@ const fill = ref<string>('#000')
|
||||
|
||||
const themeColors = ref<string[]>([])
|
||||
const textColor = ref('')
|
||||
const lineSmooth = ref(false)
|
||||
const stack = ref(false)
|
||||
|
||||
watch(handleElement, () => {
|
||||
if (!handleElement.value || handleElement.value.type !== 'chart') return
|
||||
fill.value = handleElement.value.fill || '#fff'
|
||||
|
||||
lineSmooth.value = false
|
||||
stack.value = false
|
||||
|
||||
if (handleElement.value.options) {
|
||||
const {
|
||||
lineSmooth: _lineSmooth,
|
||||
stack: _stack,
|
||||
} = handleElement.value.options
|
||||
|
||||
if (_lineSmooth !== undefined) lineSmooth.value = _lineSmooth
|
||||
if (_stack !== undefined) stack.value = _stack
|
||||
}
|
||||
|
||||
themeColors.value = handleElement.value.themeColors
|
||||
textColor.value = handleElement.value.textColor || '#333'
|
||||
}, { deep: true, immediate: true })
|
||||
@ -156,6 +190,15 @@ const updateFill = (value: string) => {
|
||||
updateElement({ fill: value })
|
||||
}
|
||||
|
||||
// 设置扩展选项
|
||||
const updateOptions = (optionProps: ChartOptions) => {
|
||||
console.log(optionProps)
|
||||
const _handleElement = handleElement.value as PPTChartElement
|
||||
|
||||
const newOptions = { ..._handleElement.options, ...optionProps }
|
||||
updateElement({ options: newOptions })
|
||||
}
|
||||
|
||||
// 设置主题色
|
||||
const updateTheme = (color: string, index: number) => {
|
||||
const props = {
|
||||
|
@ -29,7 +29,7 @@
|
||||
:data="elementInfo.data"
|
||||
:themeColors="elementInfo.themeColors"
|
||||
:textColor="elementInfo.textColor"
|
||||
:legends="elementInfo.data.legends"
|
||||
:options="elementInfo.options"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -6,7 +6,7 @@
|
||||
import { onMounted, ref, computed, watch } from 'vue'
|
||||
import * as echarts from 'echarts'
|
||||
import tinycolor from 'tinycolor2'
|
||||
import type { ChartData, ChartType } from '@/types/slides'
|
||||
import type { ChartData, ChartOptions, ChartType } from '@/types/slides'
|
||||
import { getChartOption } from './chartOption'
|
||||
|
||||
const props = defineProps<{
|
||||
@ -15,8 +15,8 @@ const props = defineProps<{
|
||||
type: ChartType
|
||||
data: ChartData
|
||||
themeColors: string[]
|
||||
legends: string[]
|
||||
textColor?: string
|
||||
options?: ChartOptions
|
||||
}>()
|
||||
|
||||
let chart: echarts.ECharts | null = null
|
||||
@ -40,6 +40,8 @@ const updateOption = () => {
|
||||
data: props.data,
|
||||
themeColors: themeColors.value,
|
||||
textColor: props.textColor,
|
||||
lineSmooth: props.options?.lineSmooth || false,
|
||||
stack: props.options?.stack || false,
|
||||
})
|
||||
if (option) chart!.setOption(option, true)
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ export interface ChartOptionPayload {
|
||||
data: ChartData
|
||||
themeColors: string[]
|
||||
textColor?: string
|
||||
lineSmooth?: boolean
|
||||
stack?: boolean
|
||||
}
|
||||
|
||||
export const getChartOption = ({
|
||||
@ -13,6 +15,8 @@ export const getChartOption = ({
|
||||
data,
|
||||
themeColors,
|
||||
textColor,
|
||||
lineSmooth,
|
||||
stack,
|
||||
}: ChartOptionPayload): echarts.EChartsOption | null => {
|
||||
if(type === 'bar') {
|
||||
return {
|
||||
@ -39,14 +43,18 @@ export const getChartOption = ({
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
},
|
||||
series: data.series.map((item, index) => ({
|
||||
data: item,
|
||||
name: data.legends[index],
|
||||
type: 'bar',
|
||||
label: {
|
||||
show: true,
|
||||
},
|
||||
})),
|
||||
series: data.series.map((item, index) => {
|
||||
const seriesItem: echarts.SeriesOption = {
|
||||
data: item,
|
||||
name: data.legends[index],
|
||||
type: 'bar',
|
||||
label: {
|
||||
show: true,
|
||||
},
|
||||
}
|
||||
if (stack) seriesItem.stack = 'A'
|
||||
return seriesItem
|
||||
}),
|
||||
}
|
||||
}
|
||||
if(type === 'column') {
|
||||
@ -74,14 +82,18 @@ export const getChartOption = ({
|
||||
xAxis: {
|
||||
type: 'value',
|
||||
},
|
||||
series: data.series.map((item, index) => ({
|
||||
data: item,
|
||||
name: data.legends[index],
|
||||
type: 'bar',
|
||||
label: {
|
||||
show: true,
|
||||
},
|
||||
})),
|
||||
series: data.series.map((item, index) => {
|
||||
const seriesItem: echarts.SeriesOption = {
|
||||
data: item,
|
||||
name: data.legends[index],
|
||||
type: 'bar',
|
||||
label: {
|
||||
show: true,
|
||||
},
|
||||
}
|
||||
if (stack) seriesItem.stack = 'A'
|
||||
return seriesItem
|
||||
}),
|
||||
}
|
||||
}
|
||||
if(type === 'line') {
|
||||
@ -113,6 +125,7 @@ export const getChartOption = ({
|
||||
data: item,
|
||||
name: data.legends[index],
|
||||
type: 'line',
|
||||
smooth: lineSmooth,
|
||||
label: {
|
||||
show: true,
|
||||
},
|
||||
@ -230,15 +243,19 @@ export const getChartOption = ({
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
},
|
||||
series: data.series.map((item, index) => ({
|
||||
data: item,
|
||||
name: data.legends[index],
|
||||
type: 'line',
|
||||
areaStyle: {},
|
||||
label: {
|
||||
show: true,
|
||||
},
|
||||
})),
|
||||
series: data.series.map((item, index) => {
|
||||
const seriesItem: echarts.SeriesOption = {
|
||||
data: item,
|
||||
name: data.legends[index],
|
||||
type: 'line',
|
||||
areaStyle: {},
|
||||
label: {
|
||||
show: true,
|
||||
},
|
||||
}
|
||||
if (stack) seriesItem.stack = 'A'
|
||||
return seriesItem
|
||||
}),
|
||||
}
|
||||
}
|
||||
if(type === 'scatter') {
|
||||
|
@ -34,7 +34,7 @@
|
||||
:data="elementInfo.data"
|
||||
:themeColors="elementInfo.themeColors"
|
||||
:textColor="elementInfo.textColor"
|
||||
:legends="elementInfo.data.legends"
|
||||
:options="elementInfo.options"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user