添加图表样式配置

This commit is contained in:
pipipi-pikachu 2021-01-18 12:58:21 +08:00
parent 628dee10d6
commit beee25590d
7 changed files with 211 additions and 3 deletions

View File

@ -49,6 +49,12 @@ export default defineComponent({
options: {
type: Object as PropType<ILineChartOptions & IBarChartOptions & IPieChartOptions>,
},
themeColors: {
type: Array as PropType<string[]>,
},
gridColor: {
type: String,
},
},
setup(props) {
const chartRef = ref<HTMLElement | null>(null)
@ -93,6 +99,24 @@ export default defineComponent({
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 {
slideScale,
chartRef,
@ -105,4 +129,48 @@ export default defineComponent({
.chart-content {
transform-origin: 0 0;
}
</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
View 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'],
]

View File

@ -126,6 +126,8 @@ export interface PPTChartElement {
data: ChartData;
options?: ILineChartOptions & IBarChartOptions & IPieChartOptions;
outline?: PPTElementOutline;
themeColors?: string[];
gridColor?: string;
}
export interface TableElementCell {

View File

@ -51,6 +51,51 @@
<ColorButton :color="fill" style="flex: 3;" />
</Popover>
</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 />
<ElementOutline />
@ -78,6 +123,7 @@ import { IBarChartOptions, ILineChartOptions, IPieChartOptions } from 'chartist'
import { useStore } from 'vuex'
import { MutationTypes, State } from '@/store'
import { ChartData, PPTChartElement } from '@/types/slides'
import { CHART_THEME_COLORS } from '@/configs/chartTheme'
import useHistorySnapshot from '@/hooks/useHistorySnapshot'
import ElementOutline from '../../common/ElementOutline.vue'
@ -96,11 +142,15 @@ export default defineComponent({
const handleElement: Ref<PPTChartElement> = computed(() => store.getters.handleElement)
const chartDataEditorVisible = ref(false)
const themePoolVisible = ref(false)
const { addHistorySnapshot } = useHistorySnapshot()
const fill = ref<string>()
const themeColors = ref<string[]>([])
const gridColor = ref('')
const lineSmooth = ref<boolean | Function>(true)
const showLine = ref(true)
const showArea = ref(false)
@ -126,6 +176,9 @@ export default defineComponent({
if(_horizontalBars !== undefined) horizontalBars.value = _horizontalBars
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 })
const updateData = (data: ChartData) => {
@ -149,8 +202,22 @@ export default defineComponent({
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 {
chartDataEditorVisible,
themePoolVisible,
handleElement,
updateData,
fill,
@ -161,6 +228,11 @@ export default defineComponent({
horizontalBars,
donut,
updateOptions,
themeColors,
gridColor,
CHART_THEME_COLORS,
updateTheme,
updateGridColor,
}
},
})
@ -179,4 +251,51 @@ export default defineComponent({
.btn-icon {
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>

View File

@ -18,9 +18,9 @@
:height="elementInfo.height"
:outline="elementInfo.outline"
/>
<IconChartLine fill="#d70206" strokeWidth="2" :size="size" v-if="elementInfo.chartType === 'line'" />
<IconChartHistogram fill="#d70206" strokeWidth="2" :size="size" v-else-if="elementInfo.chartType === 'bar'" />
<IconChartProportion fill="#d70206" strokeWidth="2" :size="size" v-else-if="elementInfo.chartType === 'pie'" />
<IconChartLine :fill="color" strokeWidth="2" :size="size" v-if="elementInfo.chartType === 'line'" />
<IconChartHistogram :fill="color" strokeWidth="2" :size="size" v-else-if="elementInfo.chartType === 'bar'" />
<IconChartProportion :fill="color" strokeWidth="2" :size="size" v-else-if="elementInfo.chartType === 'pie'" />
</div>
</div>
</template>
@ -28,6 +28,7 @@
<script lang="ts">
import { computed, defineComponent, PropType } from 'vue'
import { PPTChartElement } from '@/types/slides'
import { CHART_THEME_COLORS } from '@/configs/chartTheme'
import ElementOutline from '@/views/components/element/ElementOutline.vue'
@ -44,9 +45,13 @@ export default defineComponent({
},
setup(props) {
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 {
size,
color,
}
},
})

View File

@ -24,6 +24,8 @@
:type="elementInfo.chartType"
:data="elementInfo.data"
:options="elementInfo.options"
:themeColors="elementInfo.themeColors"
:gridColor="elementInfo.gridColor"
/>
</div>
</div>

View File

@ -27,6 +27,8 @@
:type="elementInfo.chartType"
:data="elementInfo.data"
:options="elementInfo.options"
:themeColors="elementInfo.themeColors"
:gridColor="elementInfo.gridColor"
/>
</div>
</div>