Explorar el Código

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

pipipi-pikachu hace 5 años
padre
commit
33a4d93100

+ 5 - 0
src/assets/styles/antd.scss

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

+ 2 - 0
src/main.ts

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

src/views/Editor/Toolbar/ElementStylePanel/ChartDataEditor.vue → src/views/Editor/Toolbar/ElementStylePanel/ChartStylePanel/ChartDataEditor.vue


+ 181 - 110
src/views/Editor/Toolbar/ElementStylePanel/ChartStylePanel.vue

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

+ 1 - 1
src/views/Editor/Toolbar/ElementStylePanel/index.vue

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