添加各个图表的独立配置项

This commit is contained in:
pipipi-pikachu 2021-01-17 22:59:41 +08:00
parent 73f7c758ef
commit 33a4d93100
5 changed files with 189 additions and 111 deletions

View File

@ -70,4 +70,9 @@
// tooltip // tooltip
.ant-tooltip-inner { .ant-tooltip-inner {
font-size: 12px; font-size: 12px;
}
// checkbox
.ant-checkbox-wrapper {
font-size: 13px;
} }

View File

@ -33,6 +33,7 @@ import {
Modal, Modal,
Dropdown, Dropdown,
Menu, Menu,
Checkbox,
} from 'ant-design-vue' } from 'ant-design-vue'
const app = createApp(App) const app = createApp(App)
@ -56,6 +57,7 @@ app.component('Modal', Modal)
app.component('Dropdown', Dropdown) app.component('Dropdown', Dropdown)
app.component('Menu', Menu) app.component('Menu', Menu)
app.component('MenuItem', Menu.Item) app.component('MenuItem', Menu.Item)
app.component('Checkbox', Checkbox)
app.directive('contextmenu', Contextmenu) app.directive('contextmenu', Contextmenu)
app.directive('click-outside', ClickOutside) app.directive('click-outside', ClickOutside)

View File

@ -1,111 +1,182 @@
<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>
<div class="row"> <Divider />
<div style="flex: 2;">背景填充</div>
<Popover trigger="click"> <template v-if="handleElement.chartType === 'line'">
<template #content> <div class="row">
<ColorPicker <Checkbox
:modelValue="fill" @change="e => updateOptions({ showArea: e.target.checked })" :checked="showArea"
@update:modelValue="value => updateFill(value)" style="flex: 1;"
/> >面积图样式</Checkbox>
</template> <Checkbox
<ColorButton :color="fill" style="flex: 3;" /> @change="e => updateOptions({ showLine: !e.target.checked })" :checked="!showLine"
</Popover> style="flex: 1;"
</div> >散点图样式</Checkbox>
</div>
<Divider /> <div class="row">
<ElementOutline /> <Checkbox
@change="e => updateOptions({ lineSmooth: e.target.checked })"
<Modal :checked="lineSmooth"
v-model:visible="chartDataEditorVisible" >使用平滑曲线</Checkbox>
:footer="null" </div>
centered </template>
:closable="false" <div class="row" v-if="handleElement.chartType === 'bar'">
:width="648" <Checkbox
destroyOnClose @change="e => updateOptions({ horizontalBars: e.target.checked })"
> :checked="horizontalBars"
<ChartDataEditor >条形图样式</Checkbox>
:data="handleElement.data" </div>
@close="chartDataEditorVisible = false" <div class="row" v-if="handleElement.chartType === 'pie'">
@save="value => updateData(value)" <Checkbox
/> @change="e => updateOptions({ donut: e.target.checked })"
</Modal> :checked="donut"
</div> >环形图样式</Checkbox>
</template> </div>
<script lang="ts"> <Divider />
import { computed, defineComponent, Ref, ref, watch } from 'vue'
import { useStore } from 'vuex' <div class="row">
import { MutationTypes, State } from '@/store' <div style="flex: 2;">背景填充</div>
import { ChartData, PPTChartElement } from '@/types/slides' <Popover trigger="click">
import useHistorySnapshot from '@/hooks/useHistorySnapshot' <template #content>
<ColorPicker
import ElementOutline from '../common/ElementOutline.vue' :modelValue="fill"
import ChartDataEditor from './ChartDataEditor.vue' @update:modelValue="value => updateFill(value)"
import ColorButton from '../common/ColorButton.vue' />
</template>
export default defineComponent({ <ColorButton :color="fill" style="flex: 3;" />
name: 'chart-style-panel', </Popover>
components: { </div>
ElementOutline,
ChartDataEditor, <Divider />
ColorButton, <ElementOutline />
},
setup() { <Modal
const store = useStore<State>() v-model:visible="chartDataEditorVisible"
const handleElement: Ref<PPTChartElement> = computed(() => store.getters.handleElement) :footer="null"
centered
const chartDataEditorVisible = ref(false) :closable="false"
:width="648"
const { addHistorySnapshot } = useHistorySnapshot() destroyOnClose
>
const fill = ref<string>() <ChartDataEditor
:data="handleElement.data"
watch(handleElement, () => { @close="chartDataEditorVisible = false"
if(!handleElement.value) return @save="value => updateData(value)"
fill.value = handleElement.value.fill || '#000' />
}, { deep: true, immediate: true }) </Modal>
</div>
const updateData = (data: ChartData) => { </template>
chartDataEditorVisible.value = false
const props = { data } <script lang="ts">
store.commit(MutationTypes.UPDATE_ELEMENT, { id: handleElement.value.id, props }) import { computed, defineComponent, Ref, ref, watch } from 'vue'
addHistorySnapshot() import { IBarChartOptions, ILineChartOptions, IPieChartOptions } from 'chartist'
} import { useStore } from 'vuex'
import { MutationTypes, State } from '@/store'
const updateFill = (value: string) => { import { ChartData, PPTChartElement } from '@/types/slides'
const props = { fill: value } import useHistorySnapshot from '@/hooks/useHistorySnapshot'
store.commit(MutationTypes.UPDATE_ELEMENT, { id: handleElement.value.id, props })
addHistorySnapshot() import ElementOutline from '../../common/ElementOutline.vue'
} import ColorButton from '../../common/ColorButton.vue'
import ChartDataEditor from './ChartDataEditor.vue'
return {
chartDataEditorVisible, export default defineComponent({
handleElement, name: 'chart-style-panel',
updateData, components: {
fill, ElementOutline,
updateFill, ChartDataEditor,
} ColorButton,
}, },
}) setup() {
</script> const store = useStore<State>()
const handleElement: Ref<PPTChartElement> = computed(() => store.getters.handleElement)
<style lang="scss" scoped>
.row { const chartDataEditorVisible = ref(false)
width: 100%;
display: flex; const { addHistorySnapshot } = useHistorySnapshot()
align-items: center;
margin-bottom: 10px; const fill = ref<string>()
}
.full-width-btn { const lineSmooth = ref<boolean | Function>(true)
width: 100%; const showLine = ref(true)
margin-bottom: 10px; const showArea = ref(false)
} const horizontalBars = ref(false)
.btn-icon { const donut = ref(false)
margin-right: 3px;
} watch(handleElement, () => {
if(!handleElement.value) return
fill.value = handleElement.value.fill || '#000'
if(handleElement.value.options) {
const {
lineSmooth: _lineSmooth,
showLine: _showLine,
showArea: _showArea,
horizontalBars: _horizontalBars,
donut: _donut,
} = handleElement.value.options
if(_lineSmooth !== undefined) lineSmooth.value = _lineSmooth
if(_showLine !== undefined) showLine.value = _showLine
if(_showArea !== undefined) showArea.value = _showArea
if(_horizontalBars !== undefined) horizontalBars.value = _horizontalBars
if(_donut !== undefined) donut.value = _donut
}
}, { deep: true, immediate: true })
const updateData = (data: ChartData) => {
chartDataEditorVisible.value = false
const props = { data }
store.commit(MutationTypes.UPDATE_ELEMENT, { id: handleElement.value.id, props })
addHistorySnapshot()
}
const updateFill = (value: string) => {
const props = { fill: value }
store.commit(MutationTypes.UPDATE_ELEMENT, { id: handleElement.value.id, props })
addHistorySnapshot()
}
const updateOptions = (optionProps: ILineChartOptions & IBarChartOptions & IPieChartOptions) => {
const options = handleElement.value.options || {}
const newOptions = { ...options, ...optionProps }
const props = { options: newOptions }
store.commit(MutationTypes.UPDATE_ELEMENT, { id: handleElement.value.id, props })
addHistorySnapshot()
}
return {
chartDataEditorVisible,
handleElement,
updateData,
fill,
updateFill,
lineSmooth,
showLine,
showArea,
horizontalBars,
donut,
updateOptions,
}
},
})
</script>
<style lang="scss" scoped>
.row {
width: 100%;
display: flex;
align-items: center;
margin-bottom: 10px;
}
.full-width-btn {
width: 100%;
}
.btn-icon {
margin-right: 3px;
}
</style> </style>

View File

@ -17,7 +17,7 @@ import TextStylePanel from './TextStylePanel.vue'
import ImageStylePanel from './ImageStylePanel.vue' import ImageStylePanel from './ImageStylePanel.vue'
import ShapeStylePanel from './ShapeStylePanel.vue' import ShapeStylePanel from './ShapeStylePanel.vue'
import LineStylePanel from './LineStylePanel.vue' import LineStylePanel from './LineStylePanel.vue'
import ChartStylePanel from './ChartStylePanel.vue' import ChartStylePanel from './ChartStylePanel/index.vue'
export default defineComponent({ export default defineComponent({
name: 'element-style-panel', name: 'element-style-panel',