perf: 图表插入优化、添加柱状图堆叠模式

This commit is contained in:
pipipi-pikachu 2022-04-22 10:59:41 +08:00
parent 962331100c
commit d8ea311945
10 changed files with 75 additions and 26 deletions

View File

@ -26,7 +26,7 @@ npm run serve
- 历史记录(撤销、重做)
- 快捷键
- 右键菜单
- 导出本地文件PPTX、JSON
- 导出本地文件PPTX、JSON、图片
### 幻灯片页面编辑
- 页面添加、删除
- 页面顺序调整
@ -84,12 +84,12 @@ npm run serve
- 宽度
- 样式
- 端点样式
#### 图表(柱状图、折线图、饼图)
#### 图表(柱状图、条形图、折线图、面积图、散点图、图、环形图)
- 数据编辑
- 背景填充
- 主题色
- 坐标系与坐标文字颜色
- 其他设置(柱状图转条形图、折线图转面积图、折线图转散点图、饼图转环形图、折线图开关平滑曲线)
- 其他图表设置
- 边框
- 图例
#### 表格

6
package-lock.json generated
View File

@ -1491,9 +1491,9 @@
}
},
"@icon-park/vue-next": {
"version": "1.3.5",
"resolved": "https://registry.nlark.com/@icon-park/vue-next/download/@icon-park/vue-next-1.3.5.tgz",
"integrity": "sha1-TJy+bHfE9Nrb5g/Sa4axDtStGGs="
"version": "1.3.6",
"resolved": "https://registry.npmmirror.com/@icon-park/vue-next/-/vue-next-1.3.6.tgz",
"integrity": "sha512-AZaCcjRPU9vTNVfcrG03CYJM+uv0SXx5lC4njanlRorFo+TV/x0ZTYGYGpTR/l6ek6QmFu9THmrgqKl7i/8yHg=="
},
"@intervolga/optimize-cssnano-plugin": {
"version": "1.0.6",

View File

@ -9,7 +9,7 @@
"lint": "vue-cli-service lint"
},
"dependencies": {
"@icon-park/vue-next": "^1.3.5",
"@icon-park/vue-next": "^1.3.6",
"animate.css": "^4.1.1",
"ant-design-vue": "^3.1.0",
"chartist": "^0.11.4",

15
src/configs/chartTypes.ts Normal file
View 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',
}

View File

@ -3,9 +3,10 @@ import { useMainStore, useSlidesStore } from '@/store'
import { createRandomCode } from '@/utils/common'
import { getImageSize } from '@/utils/image'
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 { LinePoolItem } from '@/configs/lines'
import { CHART_TYPES } from '@/configs/chartTypes'
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
interface CommonElementPosition {
@ -79,11 +80,11 @@ export default () => {
*
* @param chartType
*/
const createChartElement = (chartType: ChartType) => {
createElement({
const createChartElement = (type: PresetChartType) => {
const newElement: PPTChartElement = {
type: 'chart',
id: createRandomCode(),
chartType,
chartType: CHART_TYPES[type],
left: 300,
top: 81.25,
width: 400,
@ -98,6 +99,17 @@ export default () => {
[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,
})
}

View File

@ -56,6 +56,10 @@ import {
Github,
ChartProportion,
ChartHistogram,
ChartHistogramOne,
ChartLineArea,
ChartRing,
ChartScatter,
ChartLine,
ChartPie,
Text,
@ -185,6 +189,10 @@ export default {
app.component('IconChartHistogram', ChartHistogram)
app.component('IconChartLine', ChartLine)
app.component('IconChartPie', ChartPie)
app.component('IconChartHistogramOne', ChartHistogramOne)
app.component('IconChartLineArea', ChartLineArea)
app.component('IconChartRing', ChartRing)
app.component('IconChartScatter', ChartScatter)
// 其他
app.component('IconPlayOne', PlayOne)

View File

@ -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 ChartOptions = ILineChartOptions & IBarChartOptions & IPieChartOptions
export interface ChartData {
labels: string[];
legends: string[];
@ -368,7 +370,7 @@ export interface ChartData {
*
* fill?: 填充色
*
* chartType: 图表类型
* chartType: 图表基础类型bar/line/pie
*
* data: 图表数据
*
@ -387,7 +389,7 @@ export interface PPTChartElement extends PPTBaseElement {
fill?: string;
chartType: ChartType;
data: ChartData;
options?: ILineChartOptions & IBarChartOptions & IPieChartOptions;
options?: ChartOptions;
outline?: PPTElementOutline;
themeColor: string[];
gridColor?: string;

View File

@ -5,21 +5,26 @@
<IconChartLine size="24" v-if="chart === 'line'" />
<IconChartHistogram size="24" v-else-if="chart === 'bar'" />
<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>
</li>
</ul>
</template>
<script lang="ts">
import { PresetChartType } from '@/types/slides'
import { defineComponent } from 'vue'
export default defineComponent({
name: 'chart-pool',
emits: ['select'],
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)
}
@ -33,16 +38,16 @@ export default defineComponent({
<style lang="scss" scoped>
.chart-pool {
width: 120px;
width: 200px;
margin-bottom: -5px;
@include flex-grid-layout();
}
.chart-item {
@include flex-grid-layout-children(3, 32%);
@include flex-grid-layout-children(5, 19%);
height: 0;
padding-bottom: 32%;
padding-bottom: 19%;
flex-shrink: 0;
position: relative;
cursor: pointer;

View File

@ -31,6 +31,10 @@
@change="e => updateOptions({ horizontalBars: e.target.checked })"
:checked="horizontalBars"
>条形图样式</Checkbox>
<Checkbox
@change="e => updateOptions({ stackBars: e.target.checked })"
:checked="stackBars"
>堆叠样式</Checkbox>
</div>
<div class="row" v-if="handleElement.chartType === 'pie'">
<Checkbox
@ -149,10 +153,9 @@
<script lang="ts">
import { defineComponent, onUnmounted, ref, watch } from 'vue'
import { IBarChartOptions, ILineChartOptions, IPieChartOptions } from 'chartist'
import { storeToRefs } from 'pinia'
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 useHistorySnapshot from '@/hooks/useHistorySnapshot'
@ -205,6 +208,7 @@ export default defineComponent({
const showArea = ref(false)
const horizontalBars = ref(false)
const donut = ref(false)
const stackBars = ref(false)
watch(handleElement, () => {
if (!handleElement.value || handleElement.value.type !== 'chart') return
@ -217,6 +221,7 @@ export default defineComponent({
showArea: _showArea,
horizontalBars: _horizontalBars,
donut: _donut,
stackBars: _stackBars,
} = handleElement.value.options
if (_lineSmooth !== undefined) lineSmooth.value = _lineSmooth as boolean
@ -224,6 +229,7 @@ export default defineComponent({
if (_showArea !== undefined) showArea.value = _showArea
if (_horizontalBars !== undefined) horizontalBars.value = _horizontalBars
if (_donut !== undefined) donut.value = _donut
if (_stackBars !== undefined) stackBars.value = _stackBars
}
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 newOptions = { ..._handleElement.options, ...optionProps }
@ -316,6 +322,7 @@ export default defineComponent({
showArea,
horizontalBars,
donut,
stackBars,
updateOptions,
themeColor,
gridColor,
@ -333,6 +340,9 @@ export default defineComponent({
</script>
<style lang="scss" scoped>
.chart-style-panel {
user-select: none;
}
.row {
width: 100%;
display: flex;

View File

@ -34,11 +34,8 @@ import Chartist, {
IChartistLineChart,
IChartistBarChart,
IChartistPieChart,
ILineChartOptions,
IBarChartOptions,
IPieChartOptions,
} from 'chartist'
import { ChartData, ChartType } from '@/types/slides'
import { ChartData, ChartOptions, ChartType } from '@/types/slides'
import { injectKeySlideScale } from '@/types/injectKey'
import 'chartist/dist/scss/chartist.scss'
@ -63,7 +60,7 @@ export default defineComponent({
required: true,
},
options: {
type: Object as PropType<ILineChartOptions & IBarChartOptions & IPieChartOptions>,
type: Object as PropType<ChartOptions>,
},
themeColor: {
type: Array as PropType<string[]>,