forked from github/dataease
commit
18be831a7b
@ -0,0 +1,11 @@
|
|||||||
|
package io.dataease.chart.charts.impl.mix;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DualLineMixHandler extends GroupMixHandler {
|
||||||
|
@Getter
|
||||||
|
private final String type = "chart-mix-dual-line";
|
||||||
|
|
||||||
|
}
|
@ -1,13 +1,10 @@
|
|||||||
package io.dataease.chart.charts.impl.mix;
|
package io.dataease.chart.charts.impl.mix;
|
||||||
|
|
||||||
import io.dataease.chart.utils.ChartDataBuild;
|
|
||||||
import io.dataease.extensions.view.dto.*;
|
import io.dataease.extensions.view.dto.*;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class GroupMixHandler extends MixHandler {
|
public class GroupMixHandler extends MixHandler {
|
||||||
|
@ -7,7 +7,6 @@ import org.apache.commons.collections4.CollectionUtils;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class StackMixHandler extends MixHandler {
|
public class StackMixHandler extends MixHandler {
|
||||||
|
@ -1027,6 +1027,7 @@ export default {
|
|||||||
chart_mix: '柱线组合图',
|
chart_mix: '柱线组合图',
|
||||||
chart_mix_group_column: '分组柱线组合图',
|
chart_mix_group_column: '分组柱线组合图',
|
||||||
chart_mix_stack_column: '堆叠柱线组合图',
|
chart_mix_stack_column: '堆叠柱线组合图',
|
||||||
|
chart_mix_dual_line: '双线组合图',
|
||||||
axis_value: '轴值',
|
axis_value: '轴值',
|
||||||
axis_value_min: '最小值',
|
axis_value_min: '最小值',
|
||||||
axis_value_max: '最大值',
|
axis_value_max: '最大值',
|
||||||
|
@ -141,20 +141,22 @@ onMounted(() => {
|
|||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-form-item
|
<template v-if="chart.type !== 'chart-mix-dual-line'">
|
||||||
class="form-item"
|
<el-form-item
|
||||||
:class="'form-item-' + themes"
|
class="form-item"
|
||||||
v-if="showProperty('gradient')"
|
:class="'form-item-' + themes"
|
||||||
>
|
v-if="showProperty('gradient')"
|
||||||
<el-checkbox
|
|
||||||
size="small"
|
|
||||||
:effect="themes"
|
|
||||||
v-model="state.basicStyleForm.gradient"
|
|
||||||
@change="changeBasicStyle('gradient')"
|
|
||||||
>
|
>
|
||||||
{{ $t('chart.gradient') }}{{ $t('chart.color') }}
|
<el-checkbox
|
||||||
</el-checkbox>
|
size="small"
|
||||||
</el-form-item>
|
:effect="themes"
|
||||||
|
v-model="state.basicStyleForm.gradient"
|
||||||
|
@change="changeBasicStyle('gradient')"
|
||||||
|
>
|
||||||
|
{{ $t('chart.gradient') }}{{ $t('chart.color') }}
|
||||||
|
</el-checkbox>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
|
||||||
<div class="alpha-setting" v-if="showProperty('alpha')">
|
<div class="alpha-setting" v-if="showProperty('alpha')">
|
||||||
<label class="alpha-label" :class="{ dark: 'dark' === themes }">
|
<label class="alpha-label" :class="{ dark: 'dark' === themes }">
|
||||||
@ -189,22 +191,100 @@ onMounted(() => {
|
|||||||
</el-row>
|
</el-row>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<el-form-item
|
<template v-if="chart.type !== 'chart-mix-dual-line'">
|
||||||
class="form-item"
|
<el-form-item
|
||||||
v-if="showProperty('radiusColumnBar')"
|
class="form-item"
|
||||||
:label="t('chart.radiusColumnBar')"
|
v-if="showProperty('radiusColumnBar')"
|
||||||
:class="'form-item-' + themes"
|
:label="t('chart.radiusColumnBar')"
|
||||||
>
|
:class="'form-item-' + themes"
|
||||||
<el-radio-group
|
|
||||||
size="small"
|
|
||||||
:effect="themes"
|
|
||||||
v-model="state.basicStyleForm.radiusColumnBar"
|
|
||||||
@change="changeBasicStyle('radiusColumnBar')"
|
|
||||||
>
|
>
|
||||||
<el-radio label="rightAngle" :effect="themes">{{ t('chart.rightAngle') }}</el-radio>
|
<el-radio-group
|
||||||
<el-radio label="roundAngle" :effect="themes">{{ t('chart.roundAngle') }}</el-radio>
|
size="small"
|
||||||
</el-radio-group>
|
:effect="themes"
|
||||||
</el-form-item>
|
v-model="state.basicStyleForm.radiusColumnBar"
|
||||||
|
@change="changeBasicStyle('radiusColumnBar')"
|
||||||
|
>
|
||||||
|
<el-radio label="rightAngle" :effect="themes">{{ t('chart.rightAngle') }}</el-radio>
|
||||||
|
<el-radio label="roundAngle" :effect="themes">{{ t('chart.roundAngle') }}</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
</template>
|
||||||
|
<tempalte v-else>
|
||||||
|
<el-row :gutter="8">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item
|
||||||
|
:label="t('chart.line_width')"
|
||||||
|
class="form-item form-item-slider"
|
||||||
|
:class="'form-item-' + themes"
|
||||||
|
v-if="showProperty('lineWidth')"
|
||||||
|
>
|
||||||
|
<el-input-number
|
||||||
|
:effect="themes"
|
||||||
|
v-model="state.basicStyleForm.leftLineWidth"
|
||||||
|
:min="0"
|
||||||
|
:max="10"
|
||||||
|
controls-position="right"
|
||||||
|
@change="changeBasicStyle('lineWidth')"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-row :gutter="8">
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item
|
||||||
|
:label="t('chart.line_symbol')"
|
||||||
|
class="form-item"
|
||||||
|
:class="'form-item-' + themes"
|
||||||
|
v-if="showProperty('lineSymbol')"
|
||||||
|
>
|
||||||
|
<el-select
|
||||||
|
:effect="themes"
|
||||||
|
v-model="state.basicStyleForm.leftLineSymbol"
|
||||||
|
:placeholder="t('chart.line_symbol')"
|
||||||
|
@change="changeBasicStyle('lineSymbol')"
|
||||||
|
>
|
||||||
|
<el-option
|
||||||
|
v-for="item in symbolOptions"
|
||||||
|
:key="item.value"
|
||||||
|
:label="item.name"
|
||||||
|
:value="item.value"
|
||||||
|
/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
<el-col :span="12">
|
||||||
|
<el-form-item
|
||||||
|
:label="t('chart.line_symbol_size')"
|
||||||
|
class="form-item form-item-slider"
|
||||||
|
:class="'form-item-' + themes"
|
||||||
|
v-if="showProperty('lineSymbolSize')"
|
||||||
|
>
|
||||||
|
<el-input-number
|
||||||
|
:effect="themes"
|
||||||
|
v-model="state.basicStyleForm.leftLineSymbolSize"
|
||||||
|
:min="0"
|
||||||
|
:max="20"
|
||||||
|
controls-position="right"
|
||||||
|
@change="changeBasicStyle('lineSymbolSize')"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
<el-form-item
|
||||||
|
class="form-item"
|
||||||
|
:class="'form-item-' + themes"
|
||||||
|
v-if="showProperty('lineSmooth')"
|
||||||
|
>
|
||||||
|
<el-checkbox
|
||||||
|
size="small"
|
||||||
|
:effect="themes"
|
||||||
|
v-model="state.basicStyleForm.leftLineSmooth"
|
||||||
|
@change="changeBasicStyle('lineSmooth')"
|
||||||
|
>
|
||||||
|
{{ t('chart.line_smooth') }}
|
||||||
|
</el-checkbox>
|
||||||
|
</el-form-item>
|
||||||
|
</tempalte>
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<el-tab-pane :label="t('chart.yAxisRight')" name="right">
|
<el-tab-pane :label="t('chart.yAxisRight')" name="right">
|
||||||
<template v-if="showProperty('colors')">
|
<template v-if="showProperty('colors')">
|
||||||
|
@ -1482,6 +1482,13 @@ export const CHART_TYPE_CONFIGS = [
|
|||||||
value: 'chart-mix-stack',
|
value: 'chart-mix-stack',
|
||||||
title: t('chart.chart_mix_stack_column'),
|
title: t('chart.chart_mix_stack_column'),
|
||||||
icon: 'chart-mix-stack'
|
icon: 'chart-mix-stack'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
render: 'antv',
|
||||||
|
category: 'dual_axes',
|
||||||
|
value: 'chart-mix-dual-line',
|
||||||
|
title: t('chart.chart_mix_dual_line'),
|
||||||
|
icon: 'line'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -91,7 +91,11 @@ export const CHART_MIX_DEFAULT_BASIC_STYLE = {
|
|||||||
'#00ccdf',
|
'#00ccdf',
|
||||||
'#00c039',
|
'#00c039',
|
||||||
'#ff7701'
|
'#ff7701'
|
||||||
]
|
],
|
||||||
|
leftLineWidth: 2,
|
||||||
|
leftLineSymbol: 'circle',
|
||||||
|
leftLineSymbolSize: 4,
|
||||||
|
leftLineSmooth: true
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MixChartBasicStyle extends ChartBasicStyle {
|
export interface MixChartBasicStyle extends ChartBasicStyle {
|
||||||
|
@ -66,6 +66,14 @@ export class ColumnLineMix extends G2PlotChartView<DualAxesOptions, DualAxes> {
|
|||||||
type: 'q'
|
type: 'q'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected getLeftType(): string {
|
||||||
|
return 'column'
|
||||||
|
}
|
||||||
|
protected getRightType(): string {
|
||||||
|
return 'line'
|
||||||
|
}
|
||||||
|
|
||||||
async drawChart(drawOptions: G2PlotDrawOptions<DualAxes>): Promise<DualAxes> {
|
async drawChart(drawOptions: G2PlotDrawOptions<DualAxes>): Promise<DualAxes> {
|
||||||
const { chart, action, container } = drawOptions
|
const { chart, action, container } = drawOptions
|
||||||
if (!chart.data?.left?.data?.length && !chart.data?.right?.data?.length) {
|
if (!chart.data?.left?.data?.length && !chart.data?.right?.data?.length) {
|
||||||
@ -76,8 +84,8 @@ export class ColumnLineMix extends G2PlotChartView<DualAxesOptions, DualAxes> {
|
|||||||
|
|
||||||
// const data1Type = (left[0]?.type === 'bar' ? 'column' : left[0]?.type) ?? 'column'
|
// const data1Type = (left[0]?.type === 'bar' ? 'column' : left[0]?.type) ?? 'column'
|
||||||
// const data2Type = (right[0]?.type === 'bar' ? 'column' : right[0]?.type) ?? 'column'
|
// const data2Type = (right[0]?.type === 'bar' ? 'column' : right[0]?.type) ?? 'column'
|
||||||
const data1Type = 'column'
|
const data1Type = this.getLeftType()
|
||||||
const data2Type = 'line'
|
const data2Type = this.getRightType()
|
||||||
|
|
||||||
const isGroup = this.name === 'chart-mix-group' && chart.xAxisExt?.length > 0
|
const isGroup = this.name === 'chart-mix-group' && chart.xAxisExt?.length > 0
|
||||||
const isStack = this.name === 'chart-mix-stack' && chart.extStack?.length > 0
|
const isStack = this.name === 'chart-mix-stack' && chart.extStack?.length > 0
|
||||||
@ -225,7 +233,10 @@ export class ColumnLineMix extends G2PlotChartView<DualAxesOptions, DualAxes> {
|
|||||||
protected configBasicStyle(chart: Chart, options: DualAxesOptions): DualAxesOptions {
|
protected configBasicStyle(chart: Chart, options: DualAxesOptions): DualAxesOptions {
|
||||||
// size
|
// size
|
||||||
const customAttr: DeepPartial<ChartAttr> = parseJson(chart.customAttr)
|
const customAttr: DeepPartial<ChartAttr> = parseJson(chart.customAttr)
|
||||||
const s = JSON.parse(JSON.stringify(customAttr.basicStyle))
|
const s = defaultsDeep(
|
||||||
|
JSON.parse(JSON.stringify(customAttr.basicStyle)),
|
||||||
|
CHART_MIX_DEFAULT_BASIC_STYLE
|
||||||
|
)
|
||||||
const smooth = s.lineSmooth
|
const smooth = s.lineSmooth
|
||||||
const point = {
|
const point = {
|
||||||
size: s.lineSymbolSize,
|
size: s.lineSymbolSize,
|
||||||
@ -234,6 +245,14 @@ export class ColumnLineMix extends G2PlotChartView<DualAxesOptions, DualAxes> {
|
|||||||
const lineStyle = {
|
const lineStyle = {
|
||||||
lineWidth: s.lineWidth
|
lineWidth: s.lineWidth
|
||||||
}
|
}
|
||||||
|
const leftSmooth = s.leftLineSmooth
|
||||||
|
const leftPoint = {
|
||||||
|
size: s.leftLineSymbolSize,
|
||||||
|
shape: s.leftLineSymbol
|
||||||
|
}
|
||||||
|
const leftLineStyle = {
|
||||||
|
lineWidth: s.leftLineWidth
|
||||||
|
}
|
||||||
const tempOption = {
|
const tempOption = {
|
||||||
...options,
|
...options,
|
||||||
smooth,
|
smooth,
|
||||||
@ -241,9 +260,9 @@ export class ColumnLineMix extends G2PlotChartView<DualAxesOptions, DualAxes> {
|
|||||||
lineStyle
|
lineStyle
|
||||||
}
|
}
|
||||||
if (tempOption.geometryOptions) {
|
if (tempOption.geometryOptions) {
|
||||||
tempOption.geometryOptions[0].smooth = smooth
|
tempOption.geometryOptions[0].smooth = leftSmooth
|
||||||
tempOption.geometryOptions[0].point = point
|
tempOption.geometryOptions[0].point = leftPoint
|
||||||
tempOption.geometryOptions[0].lineStyle = lineStyle
|
tempOption.geometryOptions[0].lineStyle = leftLineStyle
|
||||||
|
|
||||||
tempOption.geometryOptions[1].smooth = smooth
|
tempOption.geometryOptions[1].smooth = smooth
|
||||||
tempOption.geometryOptions[1].point = point
|
tempOption.geometryOptions[1].point = point
|
||||||
@ -815,3 +834,119 @@ export class StackColumnLineMix extends ColumnLineMix {
|
|||||||
super(name)
|
super(name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export class DualLineMix extends ColumnLineMix {
|
||||||
|
axis: AxisType[] = [...this['axis'], 'xAxisExt']
|
||||||
|
propertyInner = {
|
||||||
|
...CHART_MIX_EDITOR_PROPERTY_INNER,
|
||||||
|
'label-selector': ['seriesLabelFormatter'],
|
||||||
|
'tooltip-selector': [
|
||||||
|
...CHART_MIX_EDITOR_PROPERTY_INNER['tooltip-selector'],
|
||||||
|
'seriesTooltipFormatter'
|
||||||
|
]
|
||||||
|
}
|
||||||
|
axisConfig = {
|
||||||
|
...this['axisConfig'],
|
||||||
|
xAxisExt: {
|
||||||
|
name: `${t('chart.drag_block_type_axis_left')} / ${t('chart.dimension')}`,
|
||||||
|
type: 'd',
|
||||||
|
limit: 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected getLeftType(): string {
|
||||||
|
return 'line'
|
||||||
|
}
|
||||||
|
|
||||||
|
protected configCustomColors(chart: Chart, options: DualAxesOptions): DualAxesOptions {
|
||||||
|
const tempOption = {
|
||||||
|
...options
|
||||||
|
}
|
||||||
|
const basicStyle = parseJson(chart.customAttr).basicStyle as MixChartBasicStyle
|
||||||
|
|
||||||
|
const { seriesColor } = basicStyle
|
||||||
|
if (seriesColor?.length) {
|
||||||
|
const seriesMap = seriesColor.reduce((p, n) => {
|
||||||
|
p[n.id] = n
|
||||||
|
return p
|
||||||
|
}, {})
|
||||||
|
const { yAxis, extStack } = chart
|
||||||
|
const { data } = options as unknown as Options
|
||||||
|
if (extStack?.length) {
|
||||||
|
const seriesSet = new Set()
|
||||||
|
data[0]?.forEach(d => d.category !== null && seriesSet.add(d.category))
|
||||||
|
const tmp = [...seriesSet]
|
||||||
|
tmp.forEach((c, i) => {
|
||||||
|
const curAxisColor = seriesMap[c as string]
|
||||||
|
if (curAxisColor) {
|
||||||
|
if (i + 1 > basicStyle.colors.length) {
|
||||||
|
basicStyle.colors.push(curAxisColor.color)
|
||||||
|
} else {
|
||||||
|
basicStyle.colors[i] = curAxisColor.color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
yAxis?.forEach((axis, index) => {
|
||||||
|
const curAxisColor = seriesMap[axis.id]
|
||||||
|
if (curAxisColor) {
|
||||||
|
if (index + 1 > basicStyle.colors.length) {
|
||||||
|
basicStyle.colors.push(curAxisColor.color)
|
||||||
|
} else {
|
||||||
|
basicStyle.colors[index] = curAxisColor.color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//左轴
|
||||||
|
const color = basicStyle.colors.map(ele => {
|
||||||
|
const tmp = hexColorToRGBA(ele, basicStyle.alpha)
|
||||||
|
if (basicStyle.gradient) {
|
||||||
|
return setGradientColor(tmp, true, 270)
|
||||||
|
} else {
|
||||||
|
return tmp
|
||||||
|
}
|
||||||
|
})
|
||||||
|
tempOption.geometryOptions[0].color = color
|
||||||
|
|
||||||
|
return tempOption
|
||||||
|
}
|
||||||
|
|
||||||
|
public setupSeriesColor(chart: ChartObj, data?: any[]): ChartBasicStyle['seriesColor'] {
|
||||||
|
const result: ChartBasicStyle['seriesColor'] = []
|
||||||
|
const seriesSet = new Set<string>()
|
||||||
|
const colors = chart.customAttr.basicStyle.colors
|
||||||
|
const { yAxis, extStack } = chart
|
||||||
|
if (extStack?.length) {
|
||||||
|
data?.forEach(d => {
|
||||||
|
if (d.value === null || d.category === null || seriesSet.has(d.category)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
seriesSet.add(d.category)
|
||||||
|
result.push({
|
||||||
|
id: d.category,
|
||||||
|
name: d.category,
|
||||||
|
color: colors[(seriesSet.size - 1) % colors.length]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
yAxis?.forEach(axis => {
|
||||||
|
if (seriesSet.has(axis.id)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
seriesSet.add(axis.id)
|
||||||
|
result.push({
|
||||||
|
id: axis.id,
|
||||||
|
name: axis.chartShowName ?? axis.name,
|
||||||
|
color: colors[(seriesSet.size - 1) % colors.length]
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(name = 'chart-mix-dual-line') {
|
||||||
|
super(name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
2
de-xpack
2
de-xpack
@ -1 +1 @@
|
|||||||
Subproject commit 8ec01af68b38419a065d57f80f915b903ddc00bb
|
Subproject commit b6142ad74ae10509990650cc6148277983b7e827
|
Loading…
Reference in New Issue
Block a user