mirror of
https://github.com/dataease/dataease.git
synced 2026-05-15 13:32:18 +08:00
feat(图表): 柱条图、柱线组合图增加顶部圆角选项
This commit is contained in:
committed by
jianneng-fit2cloud
parent
0309a54849
commit
5cc6c80a57
@@ -1943,6 +1943,7 @@ export default {
|
||||
radiusColumnBar: 'Column',
|
||||
rightAngle: 'Right angle',
|
||||
roundAngle: 'Rounded angle',
|
||||
topRoundAngle: 'Top rounded angle',
|
||||
table_layout_mode: 'Display form',
|
||||
table_layout_grid: 'Tile display',
|
||||
table_layout_tree: 'Tree display',
|
||||
|
||||
@@ -1892,6 +1892,7 @@ export default {
|
||||
radiusColumnBar: '柱形',
|
||||
rightAngle: '直角',
|
||||
roundAngle: '圓角',
|
||||
topRoundAngle: '頂部圓角',
|
||||
table_layout_mode: '展示形式',
|
||||
table_layout_grid: '平鋪展示',
|
||||
table_layout_tree: '樹形展示',
|
||||
|
||||
@@ -1897,6 +1897,7 @@ export default {
|
||||
radiusColumnBar: '柱形',
|
||||
rightAngle: '直角',
|
||||
roundAngle: '圆角',
|
||||
topRoundAngle: '顶部圆角',
|
||||
table_layout_mode: '展示形式',
|
||||
table_layout_grid: '平铺展示',
|
||||
table_layout_tree: '树形展示',
|
||||
|
||||
@@ -182,9 +182,9 @@ declare interface ChartBasicStyle {
|
||||
*/
|
||||
barWidth: number
|
||||
/**
|
||||
* 柱子形状:直角|圆角
|
||||
* 柱子形状:直角|圆角|顶部圆角
|
||||
*/
|
||||
radiusColumnBar?: 'rightAngle' | 'roundAngle'
|
||||
radiusColumnBar?: 'rightAngle' | 'roundAngle' | 'topRoundAngle'
|
||||
/**
|
||||
* 圆角柱倒角
|
||||
*/
|
||||
|
||||
@@ -490,9 +490,11 @@ onMounted(() => {
|
||||
:effect="themes"
|
||||
v-model="state.basicStyleForm.radiusColumnBar"
|
||||
@change="changeBasicStyle('radiusColumnBar')"
|
||||
class="radius-class"
|
||||
>
|
||||
<el-radio label="rightAngle" :effect="themes">{{ t('chart.rightAngle') }}</el-radio>
|
||||
<el-radio label="roundAngle" :effect="themes">{{ t('chart.roundAngle') }}</el-radio>
|
||||
<el-radio label="topRoundAngle" :effect="themes">{{ t('chart.topRoundAngle') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
|
||||
@@ -1741,4 +1743,7 @@ onMounted(() => {
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
}
|
||||
.radius-class {
|
||||
flex-wrap: nowrap !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -224,9 +224,13 @@ onMounted(() => {
|
||||
:effect="themes"
|
||||
v-model="state.basicStyleForm.radiusColumnBar"
|
||||
@change="changeBasicStyle('radiusColumnBar')"
|
||||
class="radius-class"
|
||||
>
|
||||
<el-radio label="rightAngle" :effect="themes">{{ t('chart.rightAngle') }}</el-radio>
|
||||
<el-radio label="roundAngle" :effect="themes">{{ t('chart.roundAngle') }}</el-radio>
|
||||
<el-radio label="topRoundAngle" :effect="themes">{{
|
||||
t('chart.topRoundAngle')
|
||||
}}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<div class="alpha-setting" v-if="showProperty('columnWidthRatio')">
|
||||
@@ -552,4 +556,10 @@ onMounted(() => {
|
||||
border-top: none !important;
|
||||
}
|
||||
}
|
||||
.radius-class {
|
||||
flex-wrap: nowrap !important;
|
||||
:deep(.ed-radio) {
|
||||
margin-right: 30px !important;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
import {
|
||||
flow,
|
||||
hexColorToRGBA,
|
||||
hexToRgba,
|
||||
parseJson,
|
||||
setUpGroupSeriesColor,
|
||||
setUpStackSeriesColor
|
||||
@@ -21,6 +20,7 @@ import {
|
||||
} from '@/views/chart/components/js/panel/charts/bar/common'
|
||||
import {
|
||||
configPlotTooltipEvent,
|
||||
configRadius,
|
||||
getLabel,
|
||||
getPadding,
|
||||
getTooltipContainer,
|
||||
@@ -181,19 +181,9 @@ export class Bar extends G2PlotChartView<ColumnOptions, Column> {
|
||||
color
|
||||
}
|
||||
}
|
||||
if (basicStyle.radiusColumnBar === 'roundAngle') {
|
||||
const columnStyle = {
|
||||
radius: [
|
||||
basicStyle.columnBarRightAngleRadius,
|
||||
basicStyle.columnBarRightAngleRadius,
|
||||
basicStyle.columnBarRightAngleRadius,
|
||||
basicStyle.columnBarRightAngleRadius
|
||||
]
|
||||
}
|
||||
options = {
|
||||
...options,
|
||||
columnStyle
|
||||
}
|
||||
options = {
|
||||
...options,
|
||||
...configRadius(options.data, basicStyle, 'columnStyle', options.xField, options.seriesField)
|
||||
}
|
||||
let columnWidthRatio
|
||||
const _v = basicStyle.columnWidthRatio ?? DEFAULT_BASIC_STYLE.columnWidthRatio
|
||||
|
||||
@@ -12,8 +12,7 @@ import {
|
||||
getYAxis,
|
||||
getYAxisExt,
|
||||
setGradientColor,
|
||||
TOOLTIP_TPL,
|
||||
addConditionsStyleColorToData
|
||||
TOOLTIP_TPL
|
||||
} from '@/views/chart/components/js/panel/common/common_antv'
|
||||
import type {
|
||||
BidirectionalBar as G2BidirectionalBar,
|
||||
@@ -213,18 +212,16 @@ export class BidirectionalHorizontalBar extends G2PlotChartView<
|
||||
...options,
|
||||
layout: basicStyle.layout
|
||||
}
|
||||
if (basicStyle.radiusColumnBar === 'roundAngle') {
|
||||
const barStyle = {
|
||||
radius: [
|
||||
basicStyle.columnBarRightAngleRadius,
|
||||
basicStyle.columnBarRightAngleRadius,
|
||||
basicStyle.columnBarRightAngleRadius,
|
||||
basicStyle.columnBarRightAngleRadius
|
||||
]
|
||||
}
|
||||
if (['roundAngle', 'topRoundAngle'].includes(basicStyle.radiusColumnBar)) {
|
||||
const valueField = basicStyle.layout === 'vertical' ? 'valueExt' : 'value'
|
||||
const radius = Array(basicStyle.radiusColumnBar === 'roundAngle' ? 4 : 2).fill(
|
||||
basicStyle.columnBarRightAngleRadius
|
||||
)
|
||||
options = {
|
||||
...options,
|
||||
barStyle
|
||||
barStyle: datum => ({
|
||||
radius: datum[valueField] && radius.length === 2 ? [0, 0, ...radius] : radius
|
||||
})
|
||||
}
|
||||
}
|
||||
return options
|
||||
|
||||
@@ -140,23 +140,42 @@ export class BulletGraph extends G2PlotChartView<G2BulletOptions, G2Bullet> {
|
||||
const { radiusColumnBar, columnBarRightAngleRadius, layout } = basicStyle
|
||||
let radiusValue = 0
|
||||
let rangeLength = 1
|
||||
if (radiusColumnBar === 'roundAngle') {
|
||||
if (radiusColumnBar === 'roundAngle' || radiusColumnBar === 'topRoundAngle') {
|
||||
radiusValue = columnBarRightAngleRadius
|
||||
rangeLength = options.data[0]?.ranges?.length
|
||||
}
|
||||
const barRadiusStyle = { radius: Array(4).fill(radiusValue) }
|
||||
const barRadiusStyle = { radius: Array(2).fill(radiusValue) }
|
||||
const baseRadius = [...barRadiusStyle.radius, ...barRadiusStyle.radius]
|
||||
options = {
|
||||
...options,
|
||||
bulletStyle: {
|
||||
range: datum => {
|
||||
if (!datum.rKey) return { fill: 'rgba(0, 0, 0, 0)' }
|
||||
if (rangeLength === 1) return barRadiusStyle
|
||||
if (rangeLength > 1 && datum.rKey === 'ranges_0')
|
||||
return { radius: [0, 0, radiusValue, radiusValue] }
|
||||
if (rangeLength > 1 && datum.rKey === 'ranges_' + (rangeLength - 1))
|
||||
return { radius: [radiusValue, radiusValue, 0, 0] }
|
||||
if (rangeLength === 1) {
|
||||
return {
|
||||
radius:
|
||||
radiusColumnBar === 'topRoundAngle' ? [...barRadiusStyle.radius, 0, 0] : baseRadius
|
||||
}
|
||||
}
|
||||
if (rangeLength > 1 && datum.rKey === 'ranges_0') {
|
||||
return {
|
||||
radius: radiusColumnBar === 'topRoundAngle' ? [] : [0, 0, ...barRadiusStyle.radius]
|
||||
}
|
||||
}
|
||||
if (rangeLength > 1 && datum.rKey === 'ranges_' + (rangeLength - 1)) {
|
||||
return { radius: [...barRadiusStyle.radius, 0, 0] }
|
||||
}
|
||||
},
|
||||
measure: datum => {
|
||||
if (datum.measures) {
|
||||
return {
|
||||
radius:
|
||||
radiusColumnBar === 'topRoundAngle' ? [...barRadiusStyle.radius, 0, 0] : baseRadius
|
||||
}
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
},
|
||||
measure: datum => (datum.measures ? barRadiusStyle : undefined),
|
||||
target: datum => (datum.tKey === 'target' ? { lineWidth: 2 } : undefined)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import type { Bar, BarOptions } from '@antv/g2plot/esm/plots/bar'
|
||||
import {
|
||||
configAxisLabelLengthLimit,
|
||||
configPlotTooltipEvent,
|
||||
configRadius,
|
||||
getPadding,
|
||||
getTooltipContainer,
|
||||
setGradientColor,
|
||||
@@ -171,19 +172,16 @@ export class HorizontalBar extends G2PlotChartView<BarOptions, Bar> {
|
||||
color
|
||||
}
|
||||
}
|
||||
if (basicStyle.radiusColumnBar === 'roundAngle') {
|
||||
const barStyle = {
|
||||
radius: [
|
||||
basicStyle.columnBarRightAngleRadius,
|
||||
basicStyle.columnBarRightAngleRadius,
|
||||
basicStyle.columnBarRightAngleRadius,
|
||||
basicStyle.columnBarRightAngleRadius
|
||||
]
|
||||
}
|
||||
options = {
|
||||
...options,
|
||||
barStyle
|
||||
}
|
||||
options = {
|
||||
...options,
|
||||
...configRadius(
|
||||
options.data,
|
||||
basicStyle,
|
||||
'barStyle',
|
||||
options.yField,
|
||||
options.seriesField,
|
||||
true
|
||||
)
|
||||
}
|
||||
|
||||
let barWidthRatio
|
||||
|
||||
@@ -4,7 +4,6 @@ import {
|
||||
configAxisLabelLengthLimit,
|
||||
configPlotTooltipEvent,
|
||||
getTooltipContainer,
|
||||
getTooltipItemConditionColor,
|
||||
setGradientColor,
|
||||
TOOLTIP_TPL
|
||||
} from '../../common/common_antv'
|
||||
@@ -184,18 +183,13 @@ export class ProgressBar extends G2PlotChartView<BarOptions, G2Progress> {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (basicStyle.radiusColumnBar === 'roundAngle') {
|
||||
const barStyle = {
|
||||
radius: [
|
||||
basicStyle.columnBarRightAngleRadius,
|
||||
basicStyle.columnBarRightAngleRadius,
|
||||
basicStyle.columnBarRightAngleRadius,
|
||||
basicStyle.columnBarRightAngleRadius
|
||||
]
|
||||
}
|
||||
if (['roundAngle', 'topRoundAngle'].includes(basicStyle.radiusColumnBar)) {
|
||||
const radius = Array(basicStyle.radiusColumnBar === 'roundAngle' ? 4 : 2).fill(
|
||||
basicStyle.columnBarRightAngleRadius
|
||||
)
|
||||
options = {
|
||||
...options,
|
||||
barStyle
|
||||
barStyle: { radius }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -321,18 +321,24 @@ export class RangeBar extends G2PlotChartView<BarOptions, Bar> {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (basicStyle.radiusColumnBar === 'roundAngle') {
|
||||
const barStyle = {
|
||||
radius: [
|
||||
basicStyle.columnBarRightAngleRadius,
|
||||
basicStyle.columnBarRightAngleRadius,
|
||||
basicStyle.columnBarRightAngleRadius,
|
||||
basicStyle.columnBarRightAngleRadius
|
||||
]
|
||||
}
|
||||
if (['roundAngle', 'topRoundAngle'].includes(basicStyle.radiusColumnBar)) {
|
||||
const radius = Array(2).fill(basicStyle.columnBarRightAngleRadius)
|
||||
options = {
|
||||
...options,
|
||||
barStyle
|
||||
barStyle: datum => {
|
||||
const isTopRound = basicStyle.radiusColumnBar === 'topRoundAngle'
|
||||
const baseRadius = [...radius, ...radius]
|
||||
return {
|
||||
radius:
|
||||
datum.values[0] < datum.values[1]
|
||||
? isTopRound
|
||||
? [...radius, 0, 0]
|
||||
: baseRadius
|
||||
: isTopRound
|
||||
? [0, 0, ...radius]
|
||||
: baseRadius
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let barWidthRatio
|
||||
|
||||
@@ -120,10 +120,27 @@ export class ColumnLineMix extends G2PlotChartView<DualAxesOptions, DualAxes> {
|
||||
valueExt: d.value
|
||||
}
|
||||
})
|
||||
|
||||
// column数据分组
|
||||
const groupedByField = data1.reduce((acc, item) => {
|
||||
const groupField = isGroup ? `${item.field}-${item.category}` : item.field
|
||||
if (!acc[groupField]) {
|
||||
acc[groupField] = []
|
||||
}
|
||||
acc[groupField].push(item)
|
||||
return acc
|
||||
}, {})
|
||||
// 遍历每个分组,添加 isFirst 和 isLast 属性
|
||||
Object.values(groupedByField).forEach(group => {
|
||||
const firstItem = group[0]
|
||||
const lastItem = group[group.length - 1]
|
||||
firstItem.isFirst = true
|
||||
lastItem.isLast = true
|
||||
})
|
||||
// 将分组后的数据重新展开为一个数组
|
||||
const result = Object.values(groupedByField).flat()
|
||||
// options
|
||||
const initOptions: DualAxesOptions = {
|
||||
data: [data1, data2],
|
||||
data: [result, data2],
|
||||
xField: 'field',
|
||||
yField: ['value', 'valueExt'], //这里不能设置成一样的
|
||||
appendPadding: getPadding(chart),
|
||||
@@ -134,7 +151,8 @@ export class ColumnLineMix extends G2PlotChartView<DualAxesOptions, DualAxes> {
|
||||
color: [],
|
||||
isGroup: isGroup,
|
||||
isStack: isStack,
|
||||
seriesField: seriesField
|
||||
seriesField: seriesField,
|
||||
rawFields: ['isFirst', 'isLast']
|
||||
},
|
||||
{
|
||||
geometry: data2Type,
|
||||
@@ -298,17 +316,20 @@ export class ColumnLineMix extends G2PlotChartView<DualAxesOptions, DualAxes> {
|
||||
tempOption.geometryOptions[1].point = point
|
||||
tempOption.geometryOptions[1].lineStyle = lineStyle
|
||||
|
||||
if (s.radiusColumnBar === 'roundAngle') {
|
||||
const columnStyle = {
|
||||
radius: [
|
||||
s.columnBarRightAngleRadius,
|
||||
s.columnBarRightAngleRadius,
|
||||
s.columnBarRightAngleRadius,
|
||||
s.columnBarRightAngleRadius
|
||||
]
|
||||
if (['roundAngle', 'topRoundAngle'].includes(s.radiusColumnBar)) {
|
||||
const radius = Array(2).fill(s.columnBarRightAngleRadius)
|
||||
const isTopRound = s.radiusColumnBar === 'topRoundAngle'
|
||||
tempOption.geometryOptions[0].columnStyle = datum => {
|
||||
if (isTopRound && datum.isFirst && datum.isLast) {
|
||||
return { radius }
|
||||
}
|
||||
if (!isTopRound && datum.isFirst && datum.isLast) {
|
||||
return { radius: [...radius, ...radius] }
|
||||
}
|
||||
if (datum.isFirst || (!isTopRound && datum.isLast)) {
|
||||
return { radius: datum.isLast ? [0, 0, ...radius] : radius }
|
||||
}
|
||||
}
|
||||
tempOption.geometryOptions[0].columnStyle = columnStyle
|
||||
tempOption.geometryOptions[1].columnStyle = columnStyle
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ import { PositionType } from '@antv/l7-core'
|
||||
import { centroid } from '@turf/centroid'
|
||||
import type { Plot } from '@antv/g2plot'
|
||||
import type { PickOptions } from '@antv/g2plot/lib/core/plot'
|
||||
import { defaults, find } from 'lodash-es'
|
||||
import { defaults, find, groupBy, map, uniq } from 'lodash-es'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { isMobile } from '@/utils/utils'
|
||||
import { GaodeMap, TMap, TencentMap } from '@antv/l7-maps'
|
||||
@@ -2205,7 +2205,7 @@ const getColorByConditions = (quotaList: [], values: number | number[], chart) =
|
||||
* @param chart
|
||||
* @param options
|
||||
*/
|
||||
export function handleConditionsStyle(chart: Chart, options: O) {
|
||||
export function handleConditionsStyle(chart: Chart, options) {
|
||||
const { threshold } = parseJson(chart.senior)
|
||||
if (!threshold.enable) return options
|
||||
const { basicStyle } = parseJson(chart.customAttr)
|
||||
@@ -2394,3 +2394,77 @@ export const numberToChineseUnderHundred = (num: number): string => {
|
||||
// 处理其他两位数
|
||||
return tens === 1 ? '十' + digits[ones] : digits[tens] + '十' + digits[ones]
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置柱条图的圆角
|
||||
* @param data
|
||||
* @param basicStyle
|
||||
* @param styleName
|
||||
* @param xField
|
||||
* @param seriesField
|
||||
* @param isHorizontalBar 条形图
|
||||
*/
|
||||
export const configRadius = (
|
||||
data: Record<string, any>[],
|
||||
basicStyle: DeepPartial<ChartBasicStyle>,
|
||||
styleName: string,
|
||||
xField: string,
|
||||
seriesField: string,
|
||||
isHorizontalBar?: boolean
|
||||
) => {
|
||||
if (['roundAngle', 'topRoundAngle'].includes(basicStyle.radiusColumnBar)) {
|
||||
// 根据维度分组
|
||||
const grouped = groupBy(data, xField)
|
||||
// 分组下的堆叠项
|
||||
const result = map(grouped, (items, field) => ({
|
||||
field,
|
||||
seriesFields: uniq(map(items, seriesField))
|
||||
}))
|
||||
const radius = Array(2).fill(basicStyle.columnBarRightAngleRadius)
|
||||
// 分组下堆叠项索引
|
||||
const groupIndex = new Map()
|
||||
// 配置柱条样式
|
||||
const style = datum => {
|
||||
const group = result.find(item => item.field === datum[xField])
|
||||
// 未找到分组直接返回
|
||||
if (!group) return { radius }
|
||||
// 分组下堆叠项索引,每遇到一个索引+1
|
||||
if (groupIndex.has(group.field)) {
|
||||
groupIndex.set(group.field, groupIndex.get(group.field) + 1)
|
||||
} else {
|
||||
groupIndex.set(group.field, 0)
|
||||
}
|
||||
// 分组下堆叠项长度
|
||||
const seriesFieldLength = group.seriesFields.length
|
||||
// 只有一个柱子时
|
||||
if (seriesFieldLength === 1) {
|
||||
return {
|
||||
radius: [
|
||||
...radius,
|
||||
...(seriesFieldLength === 1 && basicStyle.radiusColumnBar === 'topRoundAngle'
|
||||
? [0, 0]
|
||||
: radius)
|
||||
]
|
||||
}
|
||||
}
|
||||
// 获取当前分组的索引
|
||||
const groupIdx = groupIndex.get(group.field)
|
||||
// 判断是否为第一个或最后一个堆叠项
|
||||
const isStart = isHorizontalBar ? groupIdx === seriesFieldLength - 1 : groupIdx === 0
|
||||
const isEnd = isHorizontalBar ? groupIdx === 0 : groupIdx === seriesFieldLength - 1
|
||||
return {
|
||||
radius: isStart
|
||||
? [...radius, 0, 0]
|
||||
: isEnd
|
||||
? basicStyle.radiusColumnBar === 'topRoundAngle'
|
||||
? []
|
||||
: [0, 0, ...radius]
|
||||
: []
|
||||
}
|
||||
}
|
||||
return {
|
||||
[styleName]: style
|
||||
}
|
||||
}
|
||||
return {}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user