feat: 允许图表设置多个主题色(#45)

This commit is contained in:
pipipi-pikachu 2021-08-27 13:52:01 +08:00
parent c1e56746f9
commit 1b31abb230
6 changed files with 97 additions and 24 deletions

View File

@ -90,7 +90,7 @@ export default () => {
top: 81.25,
width: 400,
height: 400,
themeColor: themeColor.value,
themeColor: [themeColor.value],
gridColor: fontColor.value,
data: {
labels: ['类别1', '类别2', '类别3', '类别4', '类别5'],

View File

@ -382,7 +382,15 @@ export default () => {
})
}
const chartColors = tinycolor(el.themeColor).analogous(10).map(item => item.toHexString())
let chartColors: string[] = []
if (el.themeColor.length === 10) chartColors = el.themeColor.map(color => formatColor(color).color)
else if (el.themeColor.length === 1) chartColors = tinycolor(el.themeColor[0]).analogous(10).map(color => formatColor(color.toHexString()).color)
else {
const len = el.themeColor.length
const supplement = tinycolor(el.themeColor[len - 1]).analogous(10 + 1 - len).map(color => color.toHexString())
chartColors = [...el.themeColor.slice(0, len - 1), ...supplement].map(color => formatColor(color).color)
}
const options: pptxgen.IChartOpts = {
x: el.left / 100,
y: el.top / 100,

View File

@ -354,7 +354,7 @@ export interface PPTChartElement extends PPTBaseElement {
data: ChartData;
options?: ILineChartOptions & IBarChartOptions & IPieChartOptions;
outline?: PPTElementOutline;
themeColor: string;
themeColor: string[];
gridColor?: string;
}

View File

@ -53,18 +53,6 @@
<ColorButton :color="fill" style="flex: 3;" />
</Popover>
</div>
<div class="row">
<div style="flex: 2;">主题配色</div>
<Popover trigger="click">
<template #content>
<ColorPicker
:modelValue="themeColor"
@update:modelValue="value => updateTheme(value)"
/>
</template>
<ColorButton :color="themeColor" style="flex: 3;" />
</Popover>
</div>
<div class="row">
<div style="flex: 2;">网格颜色</div>
<Popover trigger="click">
@ -79,6 +67,33 @@
</div>
<Divider />
<div class="row" v-for="(color, index) in themeColor" :key="index">
<div style="flex: 2;">{{index === 0 ? '主题配色:' : ''}}</div>
<Popover trigger="click">
<template #content>
<ColorPicker
:modelValue="color"
@update:modelValue="value => updateTheme(value, index)"
/>
</template>
<div class="color-btn-wrap" style="flex: 3;">
<ColorButton :color="color" style="width: 100%;" />
<Tooltip :mouseLeaveDelay="0" :mouseEnterDelay="0.5" title="删除">
<div class="delete-color-btn" @click.stop="deleteThemeColor(index)" v-if="index !== 0"><IconCloseSmall /></div>
</Tooltip>
</div>
</Popover>
</div>
<div class="row" v-if="themeColor.length < 10">
<div style="flex: 2;"></div>
<Button class="add-color-btn" style="flex: 3;" @click="addThemeColor()">
<IconPlus />
</Button>
</div>
<Divider />
<ElementOutline />
<Modal
@ -120,6 +135,7 @@ export default defineComponent({
setup() {
const store = useStore()
const handleElement = computed<PPTChartElement>(() => store.getters.handleElement)
const theme = computed(() => store.state.theme)
const chartDataEditorVisible = ref(false)
@ -127,7 +143,7 @@ export default defineComponent({
const fill = ref<string>()
const themeColor = ref<string>('')
const themeColor = ref<string[]>([])
const gridColor = ref('')
const lineSmooth = ref(true)
@ -185,8 +201,28 @@ export default defineComponent({
}
//
const updateTheme = (themeColor: string) => {
const props = { themeColor }
const updateTheme = (color: string, index: number) => {
const props = {
themeColor: themeColor.value.map((c, i) => i === index ? color : c),
}
store.commit(MutationTypes.UPDATE_ELEMENT, { id: handleElement.value.id, props })
addHistorySnapshot()
}
//
const addThemeColor = () => {
const props = {
themeColor: [...themeColor.value, theme.value.themeColor],
}
store.commit(MutationTypes.UPDATE_ELEMENT, { id: handleElement.value.id, props })
addHistorySnapshot()
}
//
const deleteThemeColor = (index: number) => {
const props = {
themeColor: themeColor.value.filter((c, i) => i !== index),
}
store.commit(MutationTypes.UPDATE_ELEMENT, { id: handleElement.value.id, props })
addHistorySnapshot()
}
@ -220,6 +256,8 @@ export default defineComponent({
themeColor,
gridColor,
updateTheme,
addThemeColor,
deleteThemeColor,
updateGridColor,
}
},
@ -239,4 +277,23 @@ export default defineComponent({
.btn-icon {
margin-right: 3px;
}
.add-color-btn {
padding: 0 !important;
}
.color-btn-wrap {
position: relative;
}
.delete-color-btn {
position: absolute;
width: 30px;
right: 2px;
top: 2px;
bottom: 2px;
display: flex;
justify-content: center;
align-items: center;
background-color: #fff;
cursor: pointer;
}
</style>

View File

@ -327,7 +327,7 @@ export default defineComponent({
}
}
else if (el.type === 'chart') {
el.themeColor = themeColor
el.themeColor = [themeColor]
el.gridColor = fontColor
}
}

View File

@ -51,7 +51,7 @@ export default defineComponent({
type: Object as PropType<ILineChartOptions & IBarChartOptions & IPieChartOptions>,
},
themeColor: {
type: String,
type: Array as PropType<string[]>,
required: true,
},
gridColor: {
@ -101,14 +101,22 @@ export default defineComponent({
onMounted(renderChart)
//
//
// 10
const updateTheme = () => {
if (!chartRef.value) return
const colors = tinycolor(props.themeColor).analogous(10)
let colors: string[] = []
if (props.themeColor.length === 10) colors = props.themeColor
else if (props.themeColor.length === 1) colors = tinycolor(props.themeColor[0]).analogous(10).map(color => color.toHexString())
else {
const len = props.themeColor.length
const supplement = tinycolor(props.themeColor[len - 1]).analogous(10 + 1 - len).map(color => color.toHexString())
colors = [...props.themeColor.slice(0, len - 1), ...supplement]
}
for (let i = 0; i < 10; i++) {
const color = colors[i].toRgbString()
chartRef.value.style.setProperty(`--theme-color-${i + 1}`, color)
chartRef.value.style.setProperty(`--theme-color-${i + 1}`, colors[i])
}
}