mirror of
https://github.com/dataease/dataease.git
synced 2026-05-23 22:08:34 +08:00
fix(图表): 修复世界地图-图例-自动图例时,默认固定创建9个图例的问题
This commit is contained in:
committed by
jianneng-fit2cloud
parent
1caa78e522
commit
e2fc576e10
@@ -307,8 +307,8 @@ export class Map extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
||||
const { legend } = parseJson(chart.customStyle)
|
||||
let data = sourceData
|
||||
let colorScale = []
|
||||
let minValue = misc.mapLegendMin
|
||||
let maxValue = misc.mapLegendMax
|
||||
let minValue = misc.mapAutoLegend ? 0 : misc.mapLegendMin
|
||||
let maxValue = misc.mapAutoLegend ? 0 : misc.mapLegendMax
|
||||
let mapLegendNumber = misc.mapLegendNumber
|
||||
if (legend.show) {
|
||||
getMaxAndMinValueByData(sourceData, 'value', maxValue, minValue, (max, min) => {
|
||||
@@ -322,6 +322,9 @@ export class Map extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
||||
} else {
|
||||
mapLegendNumber = 9
|
||||
}
|
||||
mapLegendNumber = misc.mapAutoLegend
|
||||
? this.calculateAutoLegendNumber(sourceData)
|
||||
: mapLegendNumber
|
||||
// 定义最大值、最小值、区间数量和对应的颜色
|
||||
colorScale = getDynamicColorScale(minValue, maxValue, mapLegendNumber, colors)
|
||||
} else {
|
||||
@@ -360,6 +363,49 @@ export class Map extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
||||
return options
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动图例数量计算
|
||||
* 根据数据的最大值、最小值和数据条数动态确定合适的图例数量
|
||||
* @param data 源数据
|
||||
*/
|
||||
private calculateAutoLegendNumber(data: any[]): number {
|
||||
if (!data || data.length === 0) {
|
||||
return 1
|
||||
}
|
||||
// 提取有效数值
|
||||
const values = data
|
||||
.map(item => parseFloat(item.value))
|
||||
.filter(v => !isNaN(v) && v !== null && v !== undefined)
|
||||
if (values.length === 0) {
|
||||
return 1
|
||||
}
|
||||
// 计算最大值和最小值
|
||||
const maxValue = Math.max(...values)
|
||||
const minValue = Math.min(...values)
|
||||
// 如果所有数据都相同,只需要 1 个图例
|
||||
if (maxValue === minValue) {
|
||||
return 1
|
||||
}
|
||||
// 根据数据条数和值范围计算合适的图例数量
|
||||
const dataCount = values.length
|
||||
// 基础图例数量:根据数据量决定
|
||||
let legendNumber: number
|
||||
if (dataCount <= 5) {
|
||||
// 数据很少,每个数据一个图例
|
||||
legendNumber = dataCount
|
||||
} else if (dataCount <= 9) {
|
||||
// 数据适中,按数据量
|
||||
legendNumber = dataCount
|
||||
} else {
|
||||
// 数据较多,根据值范围平均分配,最多 9 个
|
||||
// 计算每个区间的跨度
|
||||
const idealIntervals = Math.min(9, Math.ceil(Math.sqrt(dataCount)))
|
||||
legendNumber = idealIntervals
|
||||
}
|
||||
// 确保图例数量在 1-9 之间
|
||||
return Math.max(1, Math.min(9, legendNumber))
|
||||
}
|
||||
|
||||
// 内部函数 创建自定义图例的内容
|
||||
private createLegendCustomContent = showItems => {
|
||||
const containerDom = createDom(CONTAINER_TPL) as HTMLElement
|
||||
@@ -478,10 +524,40 @@ export class Map extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
||||
options.color.scale.domain = [ranges[0][0], ranges[ranges.length - 1][1]]
|
||||
} else {
|
||||
customLegend['customContent'] = (_: string, items: CategoryLegendListItem[]) => {
|
||||
const showItems = items?.length > 30 ? items.slice(0, 30) : items
|
||||
// 去重逻辑
|
||||
const uniqueItems = items.reduce(
|
||||
(acc, item) => {
|
||||
const valueKey = JSON.stringify(item.value)
|
||||
if (!acc.seen.has(valueKey)) {
|
||||
acc.seen.add(valueKey)
|
||||
acc.result.push(item)
|
||||
}
|
||||
return acc
|
||||
},
|
||||
{ seen: new Set(), result: [] }
|
||||
).result
|
||||
// 限制最多显示 30 个元素
|
||||
const showItems = uniqueItems.length > 30 ? uniqueItems.slice(0, 30) : uniqueItems
|
||||
if (showItems?.length) {
|
||||
if (showItems.length === 1) {
|
||||
showItems[0].value = options.color.scale.domain.slice(0, 2)
|
||||
const domain = options.color.scale.domain
|
||||
if (domain) {
|
||||
showItems[0].value = domain?.slice(0, 2)
|
||||
} else {
|
||||
const firstValue = showItems[0].value?.[0]
|
||||
const secondValue = showItems[0].value?.[1]
|
||||
if (
|
||||
firstValue !== undefined &&
|
||||
secondValue !== undefined &&
|
||||
!Number.isNaN(firstValue) &&
|
||||
!Number.isNaN(secondValue)
|
||||
) {
|
||||
showItems[0].value = [firstValue, secondValue]
|
||||
} else {
|
||||
const v = firstValue ?? secondValue
|
||||
showItems[0].value = [v, v]
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.createLegendCustomContent(showItems)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user