mirror of
https://github.com/pipipi-pikachu/PPTist.git
synced 2025-04-15 02:20:00 +08:00
添加图表样式配置
This commit is contained in:
parent
628dee10d6
commit
beee25590d
@ -49,6 +49,12 @@ export default defineComponent({
|
|||||||
options: {
|
options: {
|
||||||
type: Object as PropType<ILineChartOptions & IBarChartOptions & IPieChartOptions>,
|
type: Object as PropType<ILineChartOptions & IBarChartOptions & IPieChartOptions>,
|
||||||
},
|
},
|
||||||
|
themeColors: {
|
||||||
|
type: Array as PropType<string[]>,
|
||||||
|
},
|
||||||
|
gridColor: {
|
||||||
|
type: String,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const chartRef = ref<HTMLElement | null>(null)
|
const chartRef = ref<HTMLElement | null>(null)
|
||||||
@ -93,6 +99,24 @@ export default defineComponent({
|
|||||||
|
|
||||||
onMounted(renderChart)
|
onMounted(renderChart)
|
||||||
|
|
||||||
|
const updateTheme = () => {
|
||||||
|
if(!chartRef.value) return
|
||||||
|
|
||||||
|
if(props.themeColors) {
|
||||||
|
for(let i = 0; i < props.themeColors.length; i++) {
|
||||||
|
chartRef.value.style.setProperty(`--theme-color-${i + 1}`, props.themeColors[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(props.gridColor) chartRef.value.style.setProperty(`--grid-color`, props.gridColor)
|
||||||
|
}
|
||||||
|
|
||||||
|
watch([
|
||||||
|
() => props.themeColors,
|
||||||
|
() => props.gridColor,
|
||||||
|
], updateTheme)
|
||||||
|
onMounted(updateTheme)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
slideScale,
|
slideScale,
|
||||||
chartRef,
|
chartRef,
|
||||||
@ -106,3 +130,47 @@ export default defineComponent({
|
|||||||
transform-origin: 0 0;
|
transform-origin: 0 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.chart-content {
|
||||||
|
$ct-series-names: (a, b, c, d);
|
||||||
|
|
||||||
|
--theme-color-1: #d70206;
|
||||||
|
--theme-color-2: #f05b4f;
|
||||||
|
--theme-color-3: #f4c63d;
|
||||||
|
--theme-color-4: #d17905;
|
||||||
|
|
||||||
|
@for $i from 1 to length($ct-series-names) {
|
||||||
|
$color: var(--theme-color-#{$i});
|
||||||
|
|
||||||
|
.ct-series-#{nth($ct-series-names, $i)} .ct-line {
|
||||||
|
stroke: $color;
|
||||||
|
}
|
||||||
|
.ct-series-#{nth($ct-series-names, $i)} .ct-point {
|
||||||
|
stroke: $color;
|
||||||
|
}
|
||||||
|
.ct-series-#{nth($ct-series-names, $i)} .ct-area {
|
||||||
|
fill: $color;
|
||||||
|
}
|
||||||
|
.ct-series-#{nth($ct-series-names, $i)} .ct-bar {
|
||||||
|
stroke: $color;
|
||||||
|
}
|
||||||
|
.ct-series-#{nth($ct-series-names, $i)} .ct-slice-pie {
|
||||||
|
fill: $color;
|
||||||
|
}
|
||||||
|
.ct-series-#{nth($ct-series-names, $i)} .ct-slice-donut {
|
||||||
|
stroke: $color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--grid-color: rgba(0, 0, 0, 0.4);
|
||||||
|
|
||||||
|
.ct-grid {
|
||||||
|
stroke: var(--grid-color);
|
||||||
|
}
|
||||||
|
.ct-label {
|
||||||
|
fill: var(--grid-color);
|
||||||
|
color: var(--grid-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
10
src/configs/chartTheme.ts
Normal file
10
src/configs/chartTheme.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
export const CHART_THEME_COLORS = [
|
||||||
|
['#d70206', '#f05b4f', '#f4c63d', '#d17905'],
|
||||||
|
['#67d5b5', '#ee7785', '#c89ec4', '#84b1ed'],
|
||||||
|
['#f6ea8c', '#f26d5b', '#c03546', '#492540'],
|
||||||
|
['#583d72', '#9f5f80', '#ffba93', '#ff8e71'],
|
||||||
|
['#59886b', '#c05555', '#ffc85c', '#fff8c1'],
|
||||||
|
['#d87c7c', '#919e8b', '#d7ab82', '#6e7074'],
|
||||||
|
['#1a1a2e', '#16213e', '#0f3460', '#e94560'],
|
||||||
|
['#e01f54', '#001852', '#f5e8c8', '#b8d2c7'],
|
||||||
|
]
|
@ -126,6 +126,8 @@ export interface PPTChartElement {
|
|||||||
data: ChartData;
|
data: ChartData;
|
||||||
options?: ILineChartOptions & IBarChartOptions & IPieChartOptions;
|
options?: ILineChartOptions & IBarChartOptions & IPieChartOptions;
|
||||||
outline?: PPTElementOutline;
|
outline?: PPTElementOutline;
|
||||||
|
themeColors?: string[];
|
||||||
|
gridColor?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TableElementCell {
|
export interface TableElementCell {
|
||||||
|
@ -51,6 +51,51 @@
|
|||||||
<ColorButton :color="fill" style="flex: 3;" />
|
<ColorButton :color="fill" style="flex: 3;" />
|
||||||
</Popover>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div style="flex: 2;">主题配色:</div>
|
||||||
|
<Popover trigger="click" v-model:visible="themePoolVisible">
|
||||||
|
<template #content>
|
||||||
|
<div class="theme-pool">
|
||||||
|
<div
|
||||||
|
class="theme-item"
|
||||||
|
v-for="(theme, index) in CHART_THEME_COLORS"
|
||||||
|
:key="index"
|
||||||
|
@click="updateTheme(theme)"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="color-block"
|
||||||
|
v-for="(color, index) in theme"
|
||||||
|
:key="index"
|
||||||
|
:style="{ backgroundColor: color }"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<Button class="theme-color-btn" style="flex: 3;">
|
||||||
|
<div class="theme-color-content">
|
||||||
|
<div
|
||||||
|
class="color-block"
|
||||||
|
v-for="(color, index) in themeColors"
|
||||||
|
:key="index"
|
||||||
|
:style="{ backgroundColor: color }"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
<IconPlatte class="theme-color-btn-icon" />
|
||||||
|
</Button>
|
||||||
|
</Popover>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div style="flex: 2;">网格颜色:</div>
|
||||||
|
<Popover trigger="click">
|
||||||
|
<template #content>
|
||||||
|
<ColorPicker
|
||||||
|
:modelValue="gridColor"
|
||||||
|
@update:modelValue="value => updateGridColor(value)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<ColorButton :color="gridColor" style="flex: 3;" />
|
||||||
|
</Popover>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Divider />
|
<Divider />
|
||||||
<ElementOutline />
|
<ElementOutline />
|
||||||
@ -78,6 +123,7 @@ import { IBarChartOptions, ILineChartOptions, IPieChartOptions } from 'chartist'
|
|||||||
import { useStore } from 'vuex'
|
import { useStore } from 'vuex'
|
||||||
import { MutationTypes, State } from '@/store'
|
import { MutationTypes, State } from '@/store'
|
||||||
import { ChartData, PPTChartElement } from '@/types/slides'
|
import { ChartData, PPTChartElement } from '@/types/slides'
|
||||||
|
import { CHART_THEME_COLORS } from '@/configs/chartTheme'
|
||||||
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
|
||||||
|
|
||||||
import ElementOutline from '../../common/ElementOutline.vue'
|
import ElementOutline from '../../common/ElementOutline.vue'
|
||||||
@ -96,11 +142,15 @@ export default defineComponent({
|
|||||||
const handleElement: Ref<PPTChartElement> = computed(() => store.getters.handleElement)
|
const handleElement: Ref<PPTChartElement> = computed(() => store.getters.handleElement)
|
||||||
|
|
||||||
const chartDataEditorVisible = ref(false)
|
const chartDataEditorVisible = ref(false)
|
||||||
|
const themePoolVisible = ref(false)
|
||||||
|
|
||||||
const { addHistorySnapshot } = useHistorySnapshot()
|
const { addHistorySnapshot } = useHistorySnapshot()
|
||||||
|
|
||||||
const fill = ref<string>()
|
const fill = ref<string>()
|
||||||
|
|
||||||
|
const themeColors = ref<string[]>([])
|
||||||
|
const gridColor = ref('')
|
||||||
|
|
||||||
const lineSmooth = ref<boolean | Function>(true)
|
const lineSmooth = ref<boolean | Function>(true)
|
||||||
const showLine = ref(true)
|
const showLine = ref(true)
|
||||||
const showArea = ref(false)
|
const showArea = ref(false)
|
||||||
@ -126,6 +176,9 @@ export default defineComponent({
|
|||||||
if(_horizontalBars !== undefined) horizontalBars.value = _horizontalBars
|
if(_horizontalBars !== undefined) horizontalBars.value = _horizontalBars
|
||||||
if(_donut !== undefined) donut.value = _donut
|
if(_donut !== undefined) donut.value = _donut
|
||||||
}
|
}
|
||||||
|
|
||||||
|
themeColors.value = handleElement.value.themeColors || CHART_THEME_COLORS[0]
|
||||||
|
gridColor.value = handleElement.value.gridColor || 'rgba(0, 0, 0, 0.4)'
|
||||||
}, { deep: true, immediate: true })
|
}, { deep: true, immediate: true })
|
||||||
|
|
||||||
const updateData = (data: ChartData) => {
|
const updateData = (data: ChartData) => {
|
||||||
@ -149,8 +202,22 @@ export default defineComponent({
|
|||||||
addHistorySnapshot()
|
addHistorySnapshot()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const updateTheme = (themeColors: string[]) => {
|
||||||
|
themePoolVisible.value = false
|
||||||
|
const props = { themeColors }
|
||||||
|
store.commit(MutationTypes.UPDATE_ELEMENT, { id: handleElement.value.id, props })
|
||||||
|
addHistorySnapshot()
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateGridColor = (gridColor: string) => {
|
||||||
|
const props = { gridColor }
|
||||||
|
store.commit(MutationTypes.UPDATE_ELEMENT, { id: handleElement.value.id, props })
|
||||||
|
addHistorySnapshot()
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
chartDataEditorVisible,
|
chartDataEditorVisible,
|
||||||
|
themePoolVisible,
|
||||||
handleElement,
|
handleElement,
|
||||||
updateData,
|
updateData,
|
||||||
fill,
|
fill,
|
||||||
@ -161,6 +228,11 @@ export default defineComponent({
|
|||||||
horizontalBars,
|
horizontalBars,
|
||||||
donut,
|
donut,
|
||||||
updateOptions,
|
updateOptions,
|
||||||
|
themeColors,
|
||||||
|
gridColor,
|
||||||
|
CHART_THEME_COLORS,
|
||||||
|
updateTheme,
|
||||||
|
updateGridColor,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
@ -179,4 +251,51 @@ export default defineComponent({
|
|||||||
.btn-icon {
|
.btn-icon {
|
||||||
margin-right: 3px;
|
margin-right: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.theme-item {
|
||||||
|
border-radius: $borderRadius;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 5px 20px;
|
||||||
|
transition: background-color .1s;
|
||||||
|
|
||||||
|
& + .theme-item {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #e1e1e1;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.theme-color-btn {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
.theme-color-content {
|
||||||
|
height: 20px;
|
||||||
|
margin-left: 8px;
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
.color-block {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
border-radius: 50%;
|
||||||
|
|
||||||
|
& + .color-block {
|
||||||
|
margin-left: -3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.theme-color-btn-icon {
|
||||||
|
width: 30px;
|
||||||
|
font-size: 12px;
|
||||||
|
margin-top: 2px;
|
||||||
|
color: #bfbfbf;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
@ -18,9 +18,9 @@
|
|||||||
:height="elementInfo.height"
|
:height="elementInfo.height"
|
||||||
:outline="elementInfo.outline"
|
:outline="elementInfo.outline"
|
||||||
/>
|
/>
|
||||||
<IconChartLine fill="#d70206" strokeWidth="2" :size="size" v-if="elementInfo.chartType === 'line'" />
|
<IconChartLine :fill="color" strokeWidth="2" :size="size" v-if="elementInfo.chartType === 'line'" />
|
||||||
<IconChartHistogram fill="#d70206" strokeWidth="2" :size="size" v-else-if="elementInfo.chartType === 'bar'" />
|
<IconChartHistogram :fill="color" strokeWidth="2" :size="size" v-else-if="elementInfo.chartType === 'bar'" />
|
||||||
<IconChartProportion fill="#d70206" strokeWidth="2" :size="size" v-else-if="elementInfo.chartType === 'pie'" />
|
<IconChartProportion :fill="color" strokeWidth="2" :size="size" v-else-if="elementInfo.chartType === 'pie'" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -28,6 +28,7 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { computed, defineComponent, PropType } from 'vue'
|
import { computed, defineComponent, PropType } from 'vue'
|
||||||
import { PPTChartElement } from '@/types/slides'
|
import { PPTChartElement } from '@/types/slides'
|
||||||
|
import { CHART_THEME_COLORS } from '@/configs/chartTheme'
|
||||||
|
|
||||||
import ElementOutline from '@/views/components/element/ElementOutline.vue'
|
import ElementOutline from '@/views/components/element/ElementOutline.vue'
|
||||||
|
|
||||||
@ -44,9 +45,13 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const size = computed(() => Math.min(props.elementInfo.width, props.elementInfo.height))
|
const size = computed(() => Math.min(props.elementInfo.width, props.elementInfo.height))
|
||||||
|
const color = computed(() => {
|
||||||
|
return props.elementInfo.themeColors ? props.elementInfo.themeColors[0] : CHART_THEME_COLORS[0][0]
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
size,
|
size,
|
||||||
|
color,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
:type="elementInfo.chartType"
|
:type="elementInfo.chartType"
|
||||||
:data="elementInfo.data"
|
:data="elementInfo.data"
|
||||||
:options="elementInfo.options"
|
:options="elementInfo.options"
|
||||||
|
:themeColors="elementInfo.themeColors"
|
||||||
|
:gridColor="elementInfo.gridColor"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
:type="elementInfo.chartType"
|
:type="elementInfo.chartType"
|
||||||
:data="elementInfo.data"
|
:data="elementInfo.data"
|
||||||
:options="elementInfo.options"
|
:options="elementInfo.options"
|
||||||
|
:themeColors="elementInfo.themeColors"
|
||||||
|
:gridColor="elementInfo.gridColor"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user