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;
|
||||
|
||||
import io.dataease.chart.utils.ChartDataBuild;
|
||||
import io.dataease.extensions.view.dto.*;
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class GroupMixHandler extends MixHandler {
|
||||
|
@ -7,7 +7,6 @@ import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Component
|
||||
public class StackMixHandler extends MixHandler {
|
||||
|
@ -1027,6 +1027,7 @@ export default {
|
||||
chart_mix: '柱线组合图',
|
||||
chart_mix_group_column: '分组柱线组合图',
|
||||
chart_mix_stack_column: '堆叠柱线组合图',
|
||||
chart_mix_dual_line: '双线组合图',
|
||||
axis_value: '轴值',
|
||||
axis_value_min: '最小值',
|
||||
axis_value_max: '最大值',
|
||||
|
@ -141,20 +141,22 @@ onMounted(() => {
|
||||
/>
|
||||
</template>
|
||||
|
||||
<el-form-item
|
||||
class="form-item"
|
||||
:class="'form-item-' + themes"
|
||||
v-if="showProperty('gradient')"
|
||||
>
|
||||
<el-checkbox
|
||||
size="small"
|
||||
:effect="themes"
|
||||
v-model="state.basicStyleForm.gradient"
|
||||
@change="changeBasicStyle('gradient')"
|
||||
<template v-if="chart.type !== 'chart-mix-dual-line'">
|
||||
<el-form-item
|
||||
class="form-item"
|
||||
:class="'form-item-' + themes"
|
||||
v-if="showProperty('gradient')"
|
||||
>
|
||||
{{ $t('chart.gradient') }}{{ $t('chart.color') }}
|
||||
</el-checkbox>
|
||||
</el-form-item>
|
||||
<el-checkbox
|
||||
size="small"
|
||||
: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')">
|
||||
<label class="alpha-label" :class="{ dark: 'dark' === themes }">
|
||||
@ -189,22 +191,100 @@ onMounted(() => {
|
||||
</el-row>
|
||||
</div>
|
||||
|
||||
<el-form-item
|
||||
class="form-item"
|
||||
v-if="showProperty('radiusColumnBar')"
|
||||
:label="t('chart.radiusColumnBar')"
|
||||
:class="'form-item-' + themes"
|
||||
>
|
||||
<el-radio-group
|
||||
size="small"
|
||||
:effect="themes"
|
||||
v-model="state.basicStyleForm.radiusColumnBar"
|
||||
@change="changeBasicStyle('radiusColumnBar')"
|
||||
<template v-if="chart.type !== 'chart-mix-dual-line'">
|
||||
<el-form-item
|
||||
class="form-item"
|
||||
v-if="showProperty('radiusColumnBar')"
|
||||
:label="t('chart.radiusColumnBar')"
|
||||
:class="'form-item-' + themes"
|
||||
>
|
||||
<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>
|
||||
<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 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 :label="t('chart.yAxisRight')" name="right">
|
||||
<template v-if="showProperty('colors')">
|
||||
|
@ -1482,6 +1482,13 @@ export const CHART_TYPE_CONFIGS = [
|
||||
value: 'chart-mix-stack',
|
||||
title: t('chart.chart_mix_stack_column'),
|
||||
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',
|
||||
'#00c039',
|
||||
'#ff7701'
|
||||
]
|
||||
],
|
||||
leftLineWidth: 2,
|
||||
leftLineSymbol: 'circle',
|
||||
leftLineSymbolSize: 4,
|
||||
leftLineSmooth: true
|
||||
}
|
||||
|
||||
export interface MixChartBasicStyle extends ChartBasicStyle {
|
||||
|
@ -66,6 +66,14 @@ export class ColumnLineMix extends G2PlotChartView<DualAxesOptions, DualAxes> {
|
||||
type: 'q'
|
||||
}
|
||||
}
|
||||
|
||||
protected getLeftType(): string {
|
||||
return 'column'
|
||||
}
|
||||
protected getRightType(): string {
|
||||
return 'line'
|
||||
}
|
||||
|
||||
async drawChart(drawOptions: G2PlotDrawOptions<DualAxes>): Promise<DualAxes> {
|
||||
const { chart, action, container } = drawOptions
|
||||
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 data2Type = (right[0]?.type === 'bar' ? 'column' : right[0]?.type) ?? 'column'
|
||||
const data1Type = 'column'
|
||||
const data2Type = 'line'
|
||||
const data1Type = this.getLeftType()
|
||||
const data2Type = this.getRightType()
|
||||
|
||||
const isGroup = this.name === 'chart-mix-group' && chart.xAxisExt?.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 {
|
||||
// size
|
||||
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 point = {
|
||||
size: s.lineSymbolSize,
|
||||
@ -234,6 +245,14 @@ export class ColumnLineMix extends G2PlotChartView<DualAxesOptions, DualAxes> {
|
||||
const lineStyle = {
|
||||
lineWidth: s.lineWidth
|
||||
}
|
||||
const leftSmooth = s.leftLineSmooth
|
||||
const leftPoint = {
|
||||
size: s.leftLineSymbolSize,
|
||||
shape: s.leftLineSymbol
|
||||
}
|
||||
const leftLineStyle = {
|
||||
lineWidth: s.leftLineWidth
|
||||
}
|
||||
const tempOption = {
|
||||
...options,
|
||||
smooth,
|
||||
@ -241,9 +260,9 @@ export class ColumnLineMix extends G2PlotChartView<DualAxesOptions, DualAxes> {
|
||||
lineStyle
|
||||
}
|
||||
if (tempOption.geometryOptions) {
|
||||
tempOption.geometryOptions[0].smooth = smooth
|
||||
tempOption.geometryOptions[0].point = point
|
||||
tempOption.geometryOptions[0].lineStyle = lineStyle
|
||||
tempOption.geometryOptions[0].smooth = leftSmooth
|
||||
tempOption.geometryOptions[0].point = leftPoint
|
||||
tempOption.geometryOptions[0].lineStyle = leftLineStyle
|
||||
|
||||
tempOption.geometryOptions[1].smooth = smooth
|
||||
tempOption.geometryOptions[1].point = point
|
||||
@ -815,3 +834,119 @@ export class StackColumnLineMix extends ColumnLineMix {
|
||||
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