mirror of
https://github.com/pipipi-pikachu/PPTist.git
synced 2025-04-15 02:20:00 +08:00
perf: 图表插入优化、添加柱状图堆叠模式
This commit is contained in:
parent
962331100c
commit
d8ea311945
@ -26,7 +26,7 @@ npm run serve
|
|||||||
- 历史记录(撤销、重做)
|
- 历史记录(撤销、重做)
|
||||||
- 快捷键
|
- 快捷键
|
||||||
- 右键菜单
|
- 右键菜单
|
||||||
- 导出本地文件(PPTX、JSON)
|
- 导出本地文件(PPTX、JSON、图片)
|
||||||
### 幻灯片页面编辑
|
### 幻灯片页面编辑
|
||||||
- 页面添加、删除
|
- 页面添加、删除
|
||||||
- 页面顺序调整
|
- 页面顺序调整
|
||||||
@ -84,12 +84,12 @@ npm run serve
|
|||||||
- 宽度
|
- 宽度
|
||||||
- 样式
|
- 样式
|
||||||
- 端点样式
|
- 端点样式
|
||||||
#### 图表(柱状图、折线图、饼图)
|
#### 图表(柱状图、条形图、折线图、面积图、散点图、饼图、环形图)
|
||||||
- 数据编辑
|
- 数据编辑
|
||||||
- 背景填充
|
- 背景填充
|
||||||
- 主题色
|
- 主题色
|
||||||
- 坐标系与坐标文字颜色
|
- 坐标系与坐标文字颜色
|
||||||
- 其他设置(柱状图转条形图、折线图转面积图、折线图转散点图、饼图转环形图、折线图开关平滑曲线)
|
- 其他图表设置
|
||||||
- 边框
|
- 边框
|
||||||
- 图例
|
- 图例
|
||||||
#### 表格
|
#### 表格
|
||||||
|
6
package-lock.json
generated
6
package-lock.json
generated
@ -1491,9 +1491,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@icon-park/vue-next": {
|
"@icon-park/vue-next": {
|
||||||
"version": "1.3.5",
|
"version": "1.3.6",
|
||||||
"resolved": "https://registry.nlark.com/@icon-park/vue-next/download/@icon-park/vue-next-1.3.5.tgz",
|
"resolved": "https://registry.npmmirror.com/@icon-park/vue-next/-/vue-next-1.3.6.tgz",
|
||||||
"integrity": "sha1-TJy+bHfE9Nrb5g/Sa4axDtStGGs="
|
"integrity": "sha512-AZaCcjRPU9vTNVfcrG03CYJM+uv0SXx5lC4njanlRorFo+TV/x0ZTYGYGpTR/l6ek6QmFu9THmrgqKl7i/8yHg=="
|
||||||
},
|
},
|
||||||
"@intervolga/optimize-cssnano-plugin": {
|
"@intervolga/optimize-cssnano-plugin": {
|
||||||
"version": "1.0.6",
|
"version": "1.0.6",
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
"lint": "vue-cli-service lint"
|
"lint": "vue-cli-service lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@icon-park/vue-next": "^1.3.5",
|
"@icon-park/vue-next": "^1.3.6",
|
||||||
"animate.css": "^4.1.1",
|
"animate.css": "^4.1.1",
|
||||||
"ant-design-vue": "^3.1.0",
|
"ant-design-vue": "^3.1.0",
|
||||||
"chartist": "^0.11.4",
|
"chartist": "^0.11.4",
|
||||||
|
15
src/configs/chartTypes.ts
Normal file
15
src/configs/chartTypes.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { ChartType } from '@/types/slides'
|
||||||
|
|
||||||
|
interface ChartTypes {
|
||||||
|
[propName: string]: ChartType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CHART_TYPES: ChartTypes = {
|
||||||
|
bar: 'bar',
|
||||||
|
horizontalBar: 'bar',
|
||||||
|
line: 'line',
|
||||||
|
area: 'line',
|
||||||
|
scatter: 'line',
|
||||||
|
pie: 'pie',
|
||||||
|
ring: 'pie',
|
||||||
|
}
|
@ -3,9 +3,10 @@ import { useMainStore, useSlidesStore } from '@/store'
|
|||||||
import { createRandomCode } from '@/utils/common'
|
import { createRandomCode } from '@/utils/common'
|
||||||
import { getImageSize } from '@/utils/image'
|
import { getImageSize } from '@/utils/image'
|
||||||
import { VIEWPORT_SIZE } from '@/configs/canvas'
|
import { VIEWPORT_SIZE } from '@/configs/canvas'
|
||||||
import { PPTLineElement, ChartType, PPTElement, TableCell, TableCellStyle, PPTShapeElement } from '@/types/slides'
|
import { PPTLineElement, PPTElement, TableCell, TableCellStyle, PPTShapeElement, PPTChartElement, ChartOptions, PresetChartType } from '@/types/slides'
|
||||||
import { ShapePoolItem, SHAPE_PATH_FORMULAS } from '@/configs/shapes'
|
import { ShapePoolItem, SHAPE_PATH_FORMULAS } from '@/configs/shapes'
|
||||||
import { LinePoolItem } from '@/configs/lines'
|
import { LinePoolItem } from '@/configs/lines'
|
||||||
|
import { CHART_TYPES } from '@/configs/chartTypes'
|
||||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||||
|
|
||||||
interface CommonElementPosition {
|
interface CommonElementPosition {
|
||||||
@ -79,11 +80,11 @@ export default () => {
|
|||||||
* 创建图表元素
|
* 创建图表元素
|
||||||
* @param chartType 图表类型
|
* @param chartType 图表类型
|
||||||
*/
|
*/
|
||||||
const createChartElement = (chartType: ChartType) => {
|
const createChartElement = (type: PresetChartType) => {
|
||||||
createElement({
|
const newElement: PPTChartElement = {
|
||||||
type: 'chart',
|
type: 'chart',
|
||||||
id: createRandomCode(),
|
id: createRandomCode(),
|
||||||
chartType,
|
chartType: CHART_TYPES[type],
|
||||||
left: 300,
|
left: 300,
|
||||||
top: 81.25,
|
top: 81.25,
|
||||||
width: 400,
|
width: 400,
|
||||||
@ -98,6 +99,17 @@ export default () => {
|
|||||||
[12, 19, 5, 2, 18],
|
[12, 19, 5, 2, 18],
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
let options: ChartOptions = {}
|
||||||
|
if (type === 'horizontalBar') options = { horizontalBars: true }
|
||||||
|
else if (type === 'area') options = { showArea: true }
|
||||||
|
else if (type === 'scatter') options = { showLine: false }
|
||||||
|
else if (type === 'ring') options = { donut: true }
|
||||||
|
|
||||||
|
createElement({
|
||||||
|
...newElement,
|
||||||
|
options,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +56,10 @@ import {
|
|||||||
Github,
|
Github,
|
||||||
ChartProportion,
|
ChartProportion,
|
||||||
ChartHistogram,
|
ChartHistogram,
|
||||||
|
ChartHistogramOne,
|
||||||
|
ChartLineArea,
|
||||||
|
ChartRing,
|
||||||
|
ChartScatter,
|
||||||
ChartLine,
|
ChartLine,
|
||||||
ChartPie,
|
ChartPie,
|
||||||
Text,
|
Text,
|
||||||
@ -185,6 +189,10 @@ export default {
|
|||||||
app.component('IconChartHistogram', ChartHistogram)
|
app.component('IconChartHistogram', ChartHistogram)
|
||||||
app.component('IconChartLine', ChartLine)
|
app.component('IconChartLine', ChartLine)
|
||||||
app.component('IconChartPie', ChartPie)
|
app.component('IconChartPie', ChartPie)
|
||||||
|
app.component('IconChartHistogramOne', ChartHistogramOne)
|
||||||
|
app.component('IconChartLineArea', ChartLineArea)
|
||||||
|
app.component('IconChartRing', ChartRing)
|
||||||
|
app.component('IconChartScatter', ChartScatter)
|
||||||
|
|
||||||
// 其他
|
// 其他
|
||||||
app.component('IconPlayOne', PlayOne)
|
app.component('IconPlayOne', PlayOne)
|
||||||
|
@ -354,7 +354,9 @@ export interface PPTLineElement extends Omit<PPTBaseElement, 'height' | 'rotate'
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export type PresetChartType = 'bar' | 'horizontalBar' | 'line' | 'area' | 'scatter' | 'pie' | 'ring'
|
||||||
export type ChartType = 'bar' | 'line' | 'pie'
|
export type ChartType = 'bar' | 'line' | 'pie'
|
||||||
|
export type ChartOptions = ILineChartOptions & IBarChartOptions & IPieChartOptions
|
||||||
export interface ChartData {
|
export interface ChartData {
|
||||||
labels: string[];
|
labels: string[];
|
||||||
legends: string[];
|
legends: string[];
|
||||||
@ -368,7 +370,7 @@ export interface ChartData {
|
|||||||
*
|
*
|
||||||
* fill?: 填充色
|
* fill?: 填充色
|
||||||
*
|
*
|
||||||
* chartType: 图表类型
|
* chartType: 图表基础类型(bar/line/pie),所有图表类型都是由这三种基本类型衍生而来
|
||||||
*
|
*
|
||||||
* data: 图表数据
|
* data: 图表数据
|
||||||
*
|
*
|
||||||
@ -387,7 +389,7 @@ export interface PPTChartElement extends PPTBaseElement {
|
|||||||
fill?: string;
|
fill?: string;
|
||||||
chartType: ChartType;
|
chartType: ChartType;
|
||||||
data: ChartData;
|
data: ChartData;
|
||||||
options?: ILineChartOptions & IBarChartOptions & IPieChartOptions;
|
options?: ChartOptions;
|
||||||
outline?: PPTElementOutline;
|
outline?: PPTElementOutline;
|
||||||
themeColor: string[];
|
themeColor: string[];
|
||||||
gridColor?: string;
|
gridColor?: string;
|
||||||
|
@ -5,21 +5,26 @@
|
|||||||
<IconChartLine size="24" v-if="chart === 'line'" />
|
<IconChartLine size="24" v-if="chart === 'line'" />
|
||||||
<IconChartHistogram size="24" v-else-if="chart === 'bar'" />
|
<IconChartHistogram size="24" v-else-if="chart === 'bar'" />
|
||||||
<IconChartPie size="24" v-else-if="chart === 'pie'" />
|
<IconChartPie size="24" v-else-if="chart === 'pie'" />
|
||||||
|
<IconChartHistogramOne size="24" v-else-if="chart === 'horizontalBar'" />
|
||||||
|
<IconChartLineArea size="24" v-else-if="chart === 'area'" />
|
||||||
|
<IconChartRing size="24" v-else-if="chart === 'ring'" />
|
||||||
|
<IconChartScatter size="24" v-else-if="chart === 'scatter'" />
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { PresetChartType } from '@/types/slides'
|
||||||
import { defineComponent } from 'vue'
|
import { defineComponent } from 'vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'chart-pool',
|
name: 'chart-pool',
|
||||||
emits: ['select'],
|
emits: ['select'],
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
const chartList = ['bar', 'line', 'pie']
|
const chartList: PresetChartType[] = ['bar', 'horizontalBar', 'line', 'area', 'scatter', 'pie', 'ring']
|
||||||
|
|
||||||
const selectChart = (chart: string) => {
|
const selectChart = (chart: PresetChartType) => {
|
||||||
emit('select', chart)
|
emit('select', chart)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,16 +38,16 @@ export default defineComponent({
|
|||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.chart-pool {
|
.chart-pool {
|
||||||
width: 120px;
|
width: 200px;
|
||||||
margin-bottom: -5px;
|
margin-bottom: -5px;
|
||||||
|
|
||||||
@include flex-grid-layout();
|
@include flex-grid-layout();
|
||||||
}
|
}
|
||||||
.chart-item {
|
.chart-item {
|
||||||
@include flex-grid-layout-children(3, 32%);
|
@include flex-grid-layout-children(5, 19%);
|
||||||
|
|
||||||
height: 0;
|
height: 0;
|
||||||
padding-bottom: 32%;
|
padding-bottom: 19%;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
position: relative;
|
position: relative;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
@ -31,6 +31,10 @@
|
|||||||
@change="e => updateOptions({ horizontalBars: e.target.checked })"
|
@change="e => updateOptions({ horizontalBars: e.target.checked })"
|
||||||
:checked="horizontalBars"
|
:checked="horizontalBars"
|
||||||
>条形图样式</Checkbox>
|
>条形图样式</Checkbox>
|
||||||
|
<Checkbox
|
||||||
|
@change="e => updateOptions({ stackBars: e.target.checked })"
|
||||||
|
:checked="stackBars"
|
||||||
|
>堆叠样式</Checkbox>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" v-if="handleElement.chartType === 'pie'">
|
<div class="row" v-if="handleElement.chartType === 'pie'">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
@ -149,10 +153,9 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, onUnmounted, ref, watch } from 'vue'
|
import { defineComponent, onUnmounted, ref, watch } from 'vue'
|
||||||
import { IBarChartOptions, ILineChartOptions, IPieChartOptions } from 'chartist'
|
|
||||||
import { storeToRefs } from 'pinia'
|
import { storeToRefs } from 'pinia'
|
||||||
import { useMainStore, useSlidesStore } from '@/store'
|
import { useMainStore, useSlidesStore } from '@/store'
|
||||||
import { ChartData, PPTChartElement } from '@/types/slides'
|
import { ChartData, ChartOptions, 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'
|
||||||
|
|
||||||
@ -205,6 +208,7 @@ export default defineComponent({
|
|||||||
const showArea = ref(false)
|
const showArea = ref(false)
|
||||||
const horizontalBars = ref(false)
|
const horizontalBars = ref(false)
|
||||||
const donut = ref(false)
|
const donut = ref(false)
|
||||||
|
const stackBars = ref(false)
|
||||||
|
|
||||||
watch(handleElement, () => {
|
watch(handleElement, () => {
|
||||||
if (!handleElement.value || handleElement.value.type !== 'chart') return
|
if (!handleElement.value || handleElement.value.type !== 'chart') return
|
||||||
@ -217,6 +221,7 @@ export default defineComponent({
|
|||||||
showArea: _showArea,
|
showArea: _showArea,
|
||||||
horizontalBars: _horizontalBars,
|
horizontalBars: _horizontalBars,
|
||||||
donut: _donut,
|
donut: _donut,
|
||||||
|
stackBars: _stackBars,
|
||||||
} = handleElement.value.options
|
} = handleElement.value.options
|
||||||
|
|
||||||
if (_lineSmooth !== undefined) lineSmooth.value = _lineSmooth as boolean
|
if (_lineSmooth !== undefined) lineSmooth.value = _lineSmooth as boolean
|
||||||
@ -224,6 +229,7 @@ export default defineComponent({
|
|||||||
if (_showArea !== undefined) showArea.value = _showArea
|
if (_showArea !== undefined) showArea.value = _showArea
|
||||||
if (_horizontalBars !== undefined) horizontalBars.value = _horizontalBars
|
if (_horizontalBars !== undefined) horizontalBars.value = _horizontalBars
|
||||||
if (_donut !== undefined) donut.value = _donut
|
if (_donut !== undefined) donut.value = _donut
|
||||||
|
if (_stackBars !== undefined) stackBars.value = _stackBars
|
||||||
}
|
}
|
||||||
|
|
||||||
themeColor.value = handleElement.value.themeColor
|
themeColor.value = handleElement.value.themeColor
|
||||||
@ -248,7 +254,7 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 设置其他选项:柱状图转条形图、折线图转面积图、折线图转散点图、饼图转环形图、折线图开关平滑曲线
|
// 设置其他选项:柱状图转条形图、折线图转面积图、折线图转散点图、饼图转环形图、折线图开关平滑曲线
|
||||||
const updateOptions = (optionProps: ILineChartOptions & IBarChartOptions & IPieChartOptions) => {
|
const updateOptions = (optionProps: ChartOptions) => {
|
||||||
const _handleElement = handleElement.value as PPTChartElement
|
const _handleElement = handleElement.value as PPTChartElement
|
||||||
|
|
||||||
const newOptions = { ..._handleElement.options, ...optionProps }
|
const newOptions = { ..._handleElement.options, ...optionProps }
|
||||||
@ -316,6 +322,7 @@ export default defineComponent({
|
|||||||
showArea,
|
showArea,
|
||||||
horizontalBars,
|
horizontalBars,
|
||||||
donut,
|
donut,
|
||||||
|
stackBars,
|
||||||
updateOptions,
|
updateOptions,
|
||||||
themeColor,
|
themeColor,
|
||||||
gridColor,
|
gridColor,
|
||||||
@ -333,6 +340,9 @@ export default defineComponent({
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
.chart-style-panel {
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
.row {
|
.row {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -34,11 +34,8 @@ import Chartist, {
|
|||||||
IChartistLineChart,
|
IChartistLineChart,
|
||||||
IChartistBarChart,
|
IChartistBarChart,
|
||||||
IChartistPieChart,
|
IChartistPieChart,
|
||||||
ILineChartOptions,
|
|
||||||
IBarChartOptions,
|
|
||||||
IPieChartOptions,
|
|
||||||
} from 'chartist'
|
} from 'chartist'
|
||||||
import { ChartData, ChartType } from '@/types/slides'
|
import { ChartData, ChartOptions, ChartType } from '@/types/slides'
|
||||||
import { injectKeySlideScale } from '@/types/injectKey'
|
import { injectKeySlideScale } from '@/types/injectKey'
|
||||||
|
|
||||||
import 'chartist/dist/scss/chartist.scss'
|
import 'chartist/dist/scss/chartist.scss'
|
||||||
@ -63,7 +60,7 @@ export default defineComponent({
|
|||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
options: {
|
options: {
|
||||||
type: Object as PropType<ILineChartOptions & IBarChartOptions & IPieChartOptions>,
|
type: Object as PropType<ChartOptions>,
|
||||||
},
|
},
|
||||||
themeColor: {
|
themeColor: {
|
||||||
type: Array as PropType<string[]>,
|
type: Array as PropType<string[]>,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user