fix(图表): 修复饼图使用存在负数数据时显示异常的问题

This commit is contained in:
jianneng-fit2cloud
2025-03-03 17:48:53 +08:00
committed by jianneng-fit2cloud
parent 057effb7da
commit 7f609ccbc3
11 changed files with 101 additions and 16 deletions

View File

@@ -1,11 +1,14 @@
package io.dataease.chart.charts.impl.pie;
import io.dataease.chart.charts.impl.YoyChartHandler;
import io.dataease.extensions.view.dto.AxisFormatResult;
import io.dataease.extensions.view.dto.ChartAxis;
import io.dataease.extensions.view.dto.ChartViewDTO;
import io.dataease.extensions.view.dto.*;
import org.springframework.stereotype.Component;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Component
public class PieHandler extends YoyChartHandler {
@Override
@@ -26,4 +29,73 @@ public class PieHandler extends YoyChartHandler {
result.getAxisMap().put(ChartAxis.extTooltip, view.getExtTooltip());
return result;
}
@Override
public ChartViewDTO buildChart(ChartViewDTO view, ChartCalcDataResult calcResult, AxisFormatResult formatResult, CustomFilterResult filterResult) {
ChartViewDTO result = super.buildChart(view, calcResult, formatResult, filterResult);
filterPositiveData(result, "data", AxisChartDataAntVDTO.class);
filterPositiveData(result, "tableRow", Map.class, view.getYAxis().get(0).getDataeaseName());
return result;
}
/**
* 过滤正数数据根据data
* @param result
* @param key
* @param clazz
* @param <T>
*/
private <T> void filterPositiveData(ChartViewDTO result, String key, Class<T> clazz) {
if (result.getData().containsKey(key)) {
List<T> list = ((List<T>) result.getData().get(key))
.stream()
.filter(item -> {
if (clazz == AxisChartDataAntVDTO.class) {
return ((AxisChartDataAntVDTO) item).getValue().compareTo(BigDecimal.ZERO) >= 0;
} else if (clazz == Map.class) {
return isPositive(((Map<String, Object>) item).get("value"));
}
return false;
})
.collect(Collectors.toList());
result.getData().put(key, list);
}
}
/**
* 过滤正数数据根据tableRow
* @param result
* @param key
* @param clazz
* @param yAxisName
* @param <T>
*/
private <T> void filterPositiveData(ChartViewDTO result, String key, Class<T> clazz, String yAxisName) {
if (result.getData().containsKey(key)) {
List<T> list = ((List<T>) result.getData().get(key))
.stream()
.filter(item -> {
if (clazz == Map.class) {
Object value = ((Map<String, Object>) item).get(yAxisName);
return isPositive(value);
}
return false;
})
.collect(Collectors.toList());
result.getData().put(key, list);
}
}
private boolean isPositive(Object value) {
if (value instanceof String) {
try {
return new BigDecimal((String) value).compareTo(BigDecimal.ZERO) >= 0;
} catch (NumberFormatException e) {
return false;
}
} else if (value instanceof BigDecimal) {
return ((BigDecimal) value).compareTo(BigDecimal.ZERO) >= 0;
}
return false;
}
}

View File

@@ -2038,7 +2038,8 @@ export default {
'Table can not be exported cause the number of columns exceeds the maximum limit!',
expand_all: 'Expand all',
level_label: 'Level {num}',
default_expand_level: 'Default expand level'
default_expand_level: 'Default expand level',
no_data_or_not_positive: 'No data available, or all data are not positive, unable to plot'
},
dataset: {
field_value: 'Field Value',

View File

@@ -1982,7 +1982,8 @@ export default {
pivot_export_invalid_col_exceed: '表格列數超過最大限制不可導出!',
expand_all: '全展開',
level_label: '第{num}層級',
default_expand_level: '默認展開層級'
default_expand_level: '默認展開層級',
no_data_or_not_positive: '暫無數據,或數據均不是正數,無法繪製'
},
dataset: {
field_value: '欄位值',

View File

@@ -1988,7 +1988,8 @@ export default {
pivot_export_invalid_col_exceed: '表格列数超过最大限制不可导出!',
expand_all: '全展开',
level_label: '第{num}层级',
default_expand_level: '默认展开层级'
default_expand_level: '默认展开层级',
no_data_or_not_positive: '暂无数据,或数据均不是正数,无法绘制'
},
dataset: {
field_value: '字段值',

View File

@@ -74,7 +74,7 @@ export class Liquid extends G2PlotChartView<LiquidOptions, G2Liquid> {
})
// 处理空数据, 只要有一个指标是空数据,就不显示图表
const hasNoneData = chart.data?.series.some(s => !s.data?.[0])
this.configEmptyDataStyle(newChart, hasNoneData ? [] : [1], container)
this.configEmptyDataStyle(hasNoneData ? [] : [1], container, newChart)
if (hasNoneData) {
return
}

View File

@@ -110,7 +110,7 @@ export class Gauge extends G2PlotChartView<GaugeOptions, G2Gauge> {
})
})
const hasNoneData = chart.data?.series.some(s => !s.data?.[0])
this.configEmptyDataStyle(newChart, hasNoneData ? [] : [1], container)
this.configEmptyDataStyle(hasNoneData ? [] : [1], container, newChart)
if (hasNoneData) {
return
}

View File

@@ -27,7 +27,9 @@ import type { Datum } from '@antv/g2plot/esm/types/common'
import { add } from 'mathjs'
import isEmpty from 'lodash-es/isEmpty'
import { cloneDeep } from 'lodash-es'
import { Chart } from '@antv/g2'
import { useI18n } from '@/hooks/web/useI18n'
const { t } = useI18n()
const DEFAULT_DATA = []
export class Pie extends G2PlotChartView<PieOptions, G2Pie> {
axis: AxisType[] = PIE_AXIS_TYPE
@@ -40,6 +42,7 @@ export class Pie extends G2PlotChartView<PieOptions, G2Pie> {
async drawChart(drawOptions: G2PlotDrawOptions<G2Pie>): Promise<G2Pie> {
const { chart, container, action } = drawOptions
this.configEmptyDataStyle(chart.data?.data, container, null, t('chart.no_data_or_not_positive'))
if (!chart.data?.data?.length) {
return
}

View File

@@ -40,6 +40,7 @@ export class Rose extends G2PlotChartView<RoseOptions, G2Rose> {
async drawChart(drawOptions: G2PlotDrawOptions<G2Rose>): Promise<G2Rose> {
const { chart, container, action } = drawOptions
this.configEmptyDataStyle(chart.data?.data, container, null, t('chart.no_data_or_not_positive'))
if (!chart?.data?.data?.length) {
return
}

View File

@@ -1934,7 +1934,7 @@ export const getTooltipItemConditionColor = item => {
* @param newData
* @param container
*/
export const configEmptyDataStyle = (newChart, newData, container) => {
export const configEmptyDataStyle = (newData, container, newChart?, content?) => {
/**
* 辅助函数移除空数据dom
*/
@@ -1949,16 +1949,19 @@ export const configEmptyDataStyle = (newChart, newData, container) => {
if (!newData.length) {
const emptyDom = document.createElement('div')
emptyDom.id = container + '_empty'
emptyDom.textContent = tI18n('data_set.no_data')
emptyDom.textContent = content || tI18n('data_set.no_data')
emptyDom.setAttribute(
'style',
`position: absolute;
left: 45%;
top: 50%;`
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
color: darkgray;
textAlign: center;`
)
const parent = document.getElementById(container)
parent.insertBefore(emptyDom, parent.firstChild)
newChart.destroy()
newChart?.destroy()
}
}

View File

@@ -191,8 +191,8 @@ export abstract class G2PlotChartView<
return addConditionsStyleColorToData(chart, data)
}
protected configEmptyDataStyle(newChart, newData: any[], container: string) {
configEmptyDataStyle(newChart, newData, container)
protected configEmptyDataStyle(newData, container, newChart?, content?) {
configEmptyDataStyle(newData, container, newChart, content)
}
/**

View File

@@ -29,6 +29,7 @@ import { useEmitt } from '@/hooks/web/useEmitt'
import { L7ChartView } from '@/views/chart/components/js/panel/types/impl/l7'
import { useI18n } from '@/hooks/web/useI18n'
import { ExportImage } from '@antv/l7'
import { configEmptyDataStyle } from '@/views/chart/components/js/panel/common/common_antv'
const { t } = useI18n()
const dvMainStore = dvMainStoreWithOut()
const { nowPanelTrackInfo, nowPanelJumpInfo, mobileInPc, embeddedCallBack, inMobile } =
@@ -283,6 +284,8 @@ const renderG2Plot = async (chart, chartView: G2PlotChartView<any, any>) => {
g2Timer && clearTimeout(g2Timer)
g2Timer = setTimeout(async () => {
try {
// 在这里清理掉之前图表的空dom
configEmptyDataStyle([1], containerId)
myChart?.destroy()
myChart = await chartView.drawChart({
chartObj: myChart,