mirror of
https://github.com/dataease/dataease.git
synced 2026-06-16 11:21:44 +08:00
fix(图表): 优化调整柱条图的柱宽百分比的宽度度和间距计算逻辑,确保样式一致性
This commit is contained in:
@@ -40,6 +40,7 @@ import {
|
||||
isSeriesTooltipFormatterShown,
|
||||
isTooltipItemShown,
|
||||
renderGroupedTooltipItems,
|
||||
ChildSpec,
|
||||
tooltipCss,
|
||||
tooltipMaxHeight,
|
||||
Transform,
|
||||
@@ -50,6 +51,8 @@ import G2TooltipCarousel from '@/views/chart/components/js/G2TooltipCarousel'
|
||||
|
||||
const { t } = useI18n()
|
||||
const DEFAULT_DATA: any[] = []
|
||||
const FULL_COLUMN_WIDTH_PADDING = 0.01
|
||||
const PERCENTAGE_FULL_COLUMN_WIDTH_PADDING = 0.002
|
||||
|
||||
/**
|
||||
* 柱状图
|
||||
@@ -268,7 +271,7 @@ export class Bar extends G2ChartView<ViewSpec, G2Column> {
|
||||
const titleHtml = TOOLTIP_TITLE_TPL.replace('{title}', title)
|
||||
let tooltipItems = originalItems
|
||||
if (tooltipAttr.seriesTooltipFormatter?.length) {
|
||||
// 只隐藏明确配置为不展示的字段,避免过期 formatter 漏掉新指标。
|
||||
// 只隐藏明确配置为不展示的字段,避免过期 formatter 漏掉新指标
|
||||
tooltipItems = originalItems.filter(item =>
|
||||
isTooltipItemShown(formatterMap, item, 'yAxis')
|
||||
)
|
||||
@@ -347,7 +350,7 @@ export class Bar extends G2ChartView<ViewSpec, G2Column> {
|
||||
colors.push(color ? color : hexColorToRGBA(ele, basicStyle.alpha))
|
||||
})
|
||||
}
|
||||
const scale = {
|
||||
const scale: Record<string, any> = {
|
||||
color: {
|
||||
range: colors
|
||||
},
|
||||
@@ -387,19 +390,17 @@ export class Bar extends G2ChartView<ViewSpec, G2Column> {
|
||||
radius: 0
|
||||
}
|
||||
}
|
||||
let columnWidthRatio
|
||||
const _v = basicStyle.columnWidthRatio ?? DEFAULT_BASIC_STYLE.columnWidthRatio
|
||||
if (_v >= 1 && _v <= 100) {
|
||||
columnWidthRatio = _v / 100.0
|
||||
} else if (_v < 1) {
|
||||
columnWidthRatio = 1 / 100.0
|
||||
} else if (_v > 100) {
|
||||
columnWidthRatio = 1
|
||||
}
|
||||
const columnWidthRatio = this.getColumnWidthRatio(basicStyle)
|
||||
const columnPadding = this.getColumnPadding(columnWidthRatio)
|
||||
let transform = children[0].transform
|
||||
if (columnWidthRatio) {
|
||||
// 100% 时保留极小 band 间距,避免 transpose 条形图贴边
|
||||
scale.x.padding = columnPadding
|
||||
scale.x.paddingInner = columnPadding
|
||||
transform = this.configDodgePadding(transform, columnPadding)
|
||||
style = {
|
||||
...style,
|
||||
columnWidthRatio
|
||||
columnWidthRatio: this.getStyleColumnWidthRatio(columnPadding)
|
||||
}
|
||||
}
|
||||
return {
|
||||
@@ -408,6 +409,7 @@ export class Bar extends G2ChartView<ViewSpec, G2Column> {
|
||||
{
|
||||
...children[0],
|
||||
scale,
|
||||
transform,
|
||||
style
|
||||
},
|
||||
...children.slice(1)
|
||||
@@ -415,6 +417,49 @@ export class Bar extends G2ChartView<ViewSpec, G2Column> {
|
||||
}
|
||||
}
|
||||
|
||||
protected getColumnWidthRatio(basicStyle: DeepPartial<ChartBasicStyle>): number {
|
||||
// 兼容历史异常配置,保持样式面板 1-100% 的有效范围
|
||||
const value = basicStyle.columnWidthRatio ?? DEFAULT_BASIC_STYLE.columnWidthRatio
|
||||
if (value >= 1 && value <= 100) {
|
||||
return value / 100.0
|
||||
}
|
||||
if (value < 1) {
|
||||
return 1 / 100.0
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
protected getColumnPadding(columnWidthRatio: number): number {
|
||||
return Math.max(1 - columnWidthRatio, this.getFullColumnWidthPadding())
|
||||
}
|
||||
|
||||
protected getFullColumnWidthPadding(): number {
|
||||
if (this.name.startsWith('percentage-bar-stack')) {
|
||||
return PERCENTAGE_FULL_COLUMN_WIDTH_PADDING
|
||||
}
|
||||
return FULL_COLUMN_WIDTH_PADDING
|
||||
}
|
||||
|
||||
protected getStyleColumnWidthRatio(columnPadding: number): number {
|
||||
return 1 - columnPadding
|
||||
}
|
||||
|
||||
protected configDodgePadding(
|
||||
transforms: ChildSpec['transform'],
|
||||
padding: number
|
||||
): ChildSpec['transform'] {
|
||||
if (!transforms?.length) {
|
||||
return transforms
|
||||
}
|
||||
if (padding > this.getFullColumnWidthPadding()) {
|
||||
return transforms
|
||||
}
|
||||
// dodgeX 会生成 series band,单独控制多指标柱之间的组内间距
|
||||
return transforms.map(transform =>
|
||||
transform.type === 'dodgeX' ? { ...transform, padding } : transform
|
||||
)
|
||||
}
|
||||
|
||||
protected configLegend(chart: Chart, options: ViewSpec): ViewSpec {
|
||||
const { children } = options
|
||||
return {
|
||||
|
||||
@@ -22,7 +22,6 @@ import {
|
||||
setGradientColor
|
||||
} from '@/views/chart/components/js/panel/common/common_antv'
|
||||
import { valueFormatter } from '@/views/chart/components/js/formatter'
|
||||
import { DEFAULT_BASIC_STYLE } from '@/views/chart/components/editor/util/chart'
|
||||
import { defaultsDeep } from 'lodash-es'
|
||||
|
||||
const { t } = useI18n()
|
||||
@@ -85,19 +84,12 @@ export class HorizontalBar extends Bar {
|
||||
...(basicStyle.radiusColumnBar !== 'topRoundAngle' &&
|
||||
basicStyle.radiusColumnBar !== 'roundAngle' && { radius: 0 })
|
||||
} as any
|
||||
let columnWidthRatio: number | undefined
|
||||
const _v = basicStyle.columnWidthRatio ?? DEFAULT_BASIC_STYLE.columnWidthRatio
|
||||
if (_v >= 1 && _v <= 100) {
|
||||
columnWidthRatio = _v / 100.0
|
||||
} else if (_v < 1) {
|
||||
columnWidthRatio = 1 / 100.0
|
||||
} else if (_v > 100) {
|
||||
columnWidthRatio = 1
|
||||
}
|
||||
const columnWidthRatio = this.getColumnWidthRatio(basicStyle)
|
||||
const columnPadding = this.getColumnPadding(columnWidthRatio)
|
||||
if (columnWidthRatio) {
|
||||
style = {
|
||||
...style,
|
||||
columnWidthRatio: columnWidthRatio
|
||||
columnWidthRatio: this.getStyleColumnWidthRatio(columnPadding)
|
||||
}
|
||||
}
|
||||
if (
|
||||
@@ -110,6 +102,13 @@ export class HorizontalBar extends Bar {
|
||||
paddingInner: 0.01
|
||||
}
|
||||
}
|
||||
// 横向条形图同样通过 x band 控制分类宽度,需要同步外层和 dodgeX 组内间距
|
||||
children[0].scale.x = {
|
||||
...(children[0].scale.x || {}),
|
||||
padding: columnPadding,
|
||||
paddingInner: columnPadding
|
||||
}
|
||||
children[0].transform = this.configDodgePadding(children[0].transform, columnPadding)
|
||||
children[0].scale.color.range = colors
|
||||
children[0].scale.y.nice = true
|
||||
children[0].style = { ...children[0].style, ...style }
|
||||
|
||||
@@ -200,10 +200,8 @@ export class PercentageStackBar extends GroupStackBar {
|
||||
|
||||
constructor(name = 'percentage-bar-stack') {
|
||||
super(name)
|
||||
this.intervalOptions.encode = {
|
||||
...this.intervalOptions.encode,
|
||||
series: d => d.group
|
||||
}
|
||||
// 百分比堆叠没有分组槽位,移除 series band,避免默认 series padding 放大柱间距
|
||||
delete this.intervalOptions.encode.series
|
||||
// 百分比堆叠与普通堆叠保持同向层级,避免 tooltip 顺序和视觉层级相反
|
||||
this.intervalOptions.transform = [{ type: 'stackY', reverse: true }, { type: 'normalizeY' }]
|
||||
this.axis = [...BAR_AXIS_TYPE, 'extStack']
|
||||
|
||||
@@ -202,10 +202,8 @@ export class PercentageStackBar extends HorizontalStackBar {
|
||||
|
||||
constructor(name = 'percentage-bar-stack-horizontal') {
|
||||
super(name)
|
||||
this.intervalOptions.encode = {
|
||||
...this.intervalOptions.encode,
|
||||
series: d => d.group
|
||||
}
|
||||
// 百分比堆叠没有分组槽位,移除 series band,避免默认 series padding 放大条间距
|
||||
delete this.intervalOptions.encode.series
|
||||
this.intervalOptions.transform = [{ type: 'stackY' }, { type: 'normalizeY' }]
|
||||
this.axis = [...BAR_AXIS_TYPE, 'extStack']
|
||||
}
|
||||
|
||||
@@ -21,7 +21,6 @@ import {
|
||||
TOOLTIP_ITEM_TPL,
|
||||
TOOLTIP_TITLE_TPL
|
||||
} from '@/views/chart/components/js/panel/common/common_antv'
|
||||
import { DEFAULT_BASIC_STYLE } from '@/views/chart/components/editor/util/chart'
|
||||
import { valueFormatter } from '@/views/chart/components/js/formatter'
|
||||
import { HorizontalStackBar } from '@/views/chart/components/js/panel/charts/g2/bar/stack-horizontal-bar'
|
||||
|
||||
@@ -218,18 +217,20 @@ export class ProgressBar extends HorizontalStackBar {
|
||||
const { children } = superOptions
|
||||
children[0].encode.color = color1[0]
|
||||
children[1].encode.color = color1[1]
|
||||
let barWidthRatio
|
||||
const _v = basicStyle.columnWidthRatio ?? DEFAULT_BASIC_STYLE.columnWidthRatio
|
||||
if (_v >= 1 && _v <= 100) {
|
||||
barWidthRatio = _v / 100.0
|
||||
} else if (_v < 1) {
|
||||
barWidthRatio = 1 / 100.0
|
||||
} else if (_v > 100) {
|
||||
barWidthRatio = 1
|
||||
}
|
||||
if (barWidthRatio) {
|
||||
children[0].style = { ...children[0].style, columnWidthRatio: barWidthRatio }
|
||||
children[1].style = { ...children[1].style, columnWidthRatio: barWidthRatio }
|
||||
const columnWidthRatio = this.getColumnWidthRatio(basicStyle)
|
||||
const columnPadding = this.getColumnPadding(columnWidthRatio)
|
||||
const styleColumnWidthRatio = this.getStyleColumnWidthRatio(columnPadding)
|
||||
if (styleColumnWidthRatio) {
|
||||
children[0].style = { ...children[0].style, columnWidthRatio: styleColumnWidthRatio }
|
||||
children[1].scale = {
|
||||
...children[1].scale,
|
||||
x: {
|
||||
...(children[1].scale?.x || {}),
|
||||
padding: columnPadding,
|
||||
paddingInner: columnPadding
|
||||
}
|
||||
}
|
||||
children[1].style = { ...children[1].style, columnWidthRatio: styleColumnWidthRatio }
|
||||
}
|
||||
return superOptions
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user