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
16aaea3310
commit
da43a56f96
@ -118,7 +118,7 @@ npm run dev
|
|||||||
- Style
|
- Style
|
||||||
- Endpoint style
|
- Endpoint style
|
||||||
#### Charts (bar, column, line, area, scatter, pie, donut, radar)
|
#### Charts (bar, column, line, area, scatter, pie, donut, radar)
|
||||||
- Chart conversion
|
- Chart type conversion
|
||||||
- Data editing
|
- Data editing
|
||||||
- Background fill
|
- Background fill
|
||||||
- Theme color
|
- Theme color
|
||||||
|
@ -114,7 +114,7 @@ npm run dev
|
|||||||
- 样式
|
- 样式
|
||||||
- 端点样式
|
- 端点样式
|
||||||
#### 图表(柱状图、条形图、折线图、面积图、散点图、饼图、环形图、雷达图)
|
#### 图表(柱状图、条形图、折线图、面积图、散点图、饼图、环形图、雷达图)
|
||||||
- 图表转换
|
- 图表类型转换
|
||||||
- 数据编辑
|
- 数据编辑
|
||||||
- 背景填充
|
- 背景填充
|
||||||
- 主题色
|
- 主题色
|
||||||
|
@ -68,11 +68,23 @@
|
|||||||
|
|
||||||
<div class="btns">
|
<div class="btns">
|
||||||
<div class="left">
|
<div class="left">
|
||||||
<Button class="btn" @click="clear()">清空</Button>
|
图表类型:{{ CHART_TYPE_MAP[chartType] }}
|
||||||
|
<Popover trigger="click" placement="top" v-model:value="chartTypeSelectVisible">
|
||||||
|
<template #content>
|
||||||
|
<PopoverMenuItem
|
||||||
|
center
|
||||||
|
v-for="item in chartList"
|
||||||
|
:key="item"
|
||||||
|
@click="chartType = item; chartTypeSelectVisible = false"
|
||||||
|
>{{CHART_TYPE_MAP[item]}}</PopoverMenuItem>
|
||||||
|
</template>
|
||||||
|
<span class="change">点击更换</span>
|
||||||
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<Button class="btn" @click="closeEditor()">取消</Button>
|
<Button class="btn" @click="closeEditor()">取消</Button>
|
||||||
<Button type="primary" class="btn" @click="getTableData()" style="margin-left: 10px;">确认</Button>
|
<Button class="btn" @click="clear()">清空数据</Button>
|
||||||
|
<Button type="primary" class="btn" @click="getTableData()">确认</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -82,8 +94,11 @@
|
|||||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||||
import type { ChartData, ChartType } from '@/types/slides'
|
import type { ChartData, ChartType } from '@/types/slides'
|
||||||
import { KEYS } from '@/configs/hotkey'
|
import { KEYS } from '@/configs/hotkey'
|
||||||
|
import { CHART_TYPE_MAP } from '@/configs/chart'
|
||||||
import { pasteCustomClipboardString, pasteExcelClipboardString } from '@/utils/clipboard'
|
import { pasteCustomClipboardString, pasteExcelClipboardString } from '@/utils/clipboard'
|
||||||
import Button from '@/components/Button.vue'
|
import Button from '@/components/Button.vue'
|
||||||
|
import Popover from '@/components/Popover.vue'
|
||||||
|
import PopoverMenuItem from '@/components/PopoverMenuItem.vue'
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
type: ChartType
|
type: ChartType
|
||||||
@ -91,7 +106,10 @@ const props = defineProps<{
|
|||||||
}>()
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(event: 'save', payload: ChartData): void
|
(event: 'save', payload: {
|
||||||
|
data: ChartData
|
||||||
|
type: ChartType
|
||||||
|
}): void
|
||||||
(event: 'close'): void
|
(event: 'close'): void
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
@ -99,9 +117,12 @@ const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|||||||
const CELL_WIDTH = 100
|
const CELL_WIDTH = 100
|
||||||
const CELL_HEIGHT = 32
|
const CELL_HEIGHT = 32
|
||||||
|
|
||||||
|
const chartList: ChartType[] = ['bar', 'column', 'line', 'area', 'scatter', 'pie', 'ring', 'radar']
|
||||||
|
const chartTypeSelectVisible = ref(false)
|
||||||
const selectedRange = ref([0, 0])
|
const selectedRange = ref([0, 0])
|
||||||
const tempRangeSize = ref({ width: 0, height: 0 })
|
const tempRangeSize = ref({ width: 0, height: 0 })
|
||||||
const focusCell = ref<[number, number] | null>(null)
|
const focusCell = ref<[number, number] | null>(null)
|
||||||
|
const chartType = ref<ChartType>('bar')
|
||||||
|
|
||||||
// 当前选区的边框线条位置
|
// 当前选区的边框线条位置
|
||||||
const rangeLines = computed(() => {
|
const rangeLines = computed(() => {
|
||||||
@ -124,6 +145,8 @@ const resizablePointStyle = computed(() => {
|
|||||||
|
|
||||||
// 初始化图表数据:将数据格式化并填充到DOM
|
// 初始化图表数据:将数据格式化并填充到DOM
|
||||||
const initData = () => {
|
const initData = () => {
|
||||||
|
chartType.value = props.type
|
||||||
|
|
||||||
const _data: string[][] = []
|
const _data: string[][] = []
|
||||||
|
|
||||||
const { labels, legends, series } = props.data
|
const { labels, legends, series } = props.data
|
||||||
@ -210,7 +233,7 @@ const getTableData = () => {
|
|||||||
|
|
||||||
// 一些特殊图表类型,数据需要单独处理
|
// 一些特殊图表类型,数据需要单独处理
|
||||||
// 散点图有且只有两列数据
|
// 散点图有且只有两列数据
|
||||||
if (props.type === 'scatter') {
|
if (chartType.value === 'scatter') {
|
||||||
if (legends.length > 2) {
|
if (legends.length > 2) {
|
||||||
legends = legends.slice(0, 2)
|
legends = legends.slice(0, 2)
|
||||||
series = series.slice(0, 2)
|
series = series.slice(0, 2)
|
||||||
@ -221,14 +244,14 @@ const getTableData = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 饼图和环形图只有一列数据
|
// 饼图和环形图只有一列数据
|
||||||
if (props.type === 'ring' || props.type === 'pie') {
|
if (chartType.value === 'ring' || chartType.value === 'pie') {
|
||||||
if (legends.length > 1) {
|
if (legends.length > 1) {
|
||||||
legends = legends.slice(0, 1)
|
legends = legends.slice(0, 1)
|
||||||
series = series.slice(0, 1)
|
series = series.slice(0, 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emit('save', { labels, legends, series })
|
emit('save', { data: { labels, legends, series }, type: chartType.value })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 清空表格数据
|
// 清空表格数据
|
||||||
@ -439,6 +462,26 @@ table {
|
|||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
|
||||||
|
.btn {
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.left {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
font-size: 12px;
|
||||||
|
|
||||||
|
.change {
|
||||||
|
color: #ccc;
|
||||||
|
margin-left: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.col-header {
|
.col-header {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="chart-style-panel">
|
<div class="chart-style-panel">
|
||||||
<Button class="full-width-btn" @click="chartDataEditorVisible = true">
|
<Button class="full-width-btn" @click="chartDataEditorVisible = true">
|
||||||
<IconEdit class="btn-icon" /> 编辑图表数据
|
<IconEdit class="btn-icon" /> 编辑图表
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<Divider />
|
<Divider />
|
||||||
@ -118,7 +118,7 @@
|
|||||||
import { onUnmounted, ref, watch, type Ref } from 'vue'
|
import { onUnmounted, ref, watch, type Ref } from 'vue'
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { useMainStore, useSlidesStore } from '@/store'
|
import { useMainStore, useSlidesStore } from '@/store'
|
||||||
import type { ChartData, ChartOptions, PPTChartElement } from '@/types/slides'
|
import type { ChartData, ChartOptions, ChartType, PPTChartElement } from '@/types/slides'
|
||||||
import emitter, { EmitterEvents } from '@/utils/emitter'
|
import emitter, { EmitterEvents } from '@/utils/emitter'
|
||||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||||
import { CHART_PRESET_THEMES } from '@/configs/chart'
|
import { CHART_PRESET_THEMES } from '@/configs/chart'
|
||||||
@ -181,9 +181,12 @@ const updateElement = (props: Partial<PPTChartElement>) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 设置图表数据
|
// 设置图表数据
|
||||||
const updateData = (data: ChartData) => {
|
const updateData = (payload: {
|
||||||
|
data: ChartData
|
||||||
|
type: ChartType
|
||||||
|
}) => {
|
||||||
chartDataEditorVisible.value = false
|
chartDataEditorVisible.value = false
|
||||||
updateElement({ data })
|
updateElement({ data: payload.data, chartType: payload.type })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置填充色
|
// 设置填充色
|
||||||
|
Loading…
x
Reference in New Issue
Block a user