fix: refine treemap sizing and add earth bgp collectors
This commit is contained in:
@@ -703,6 +703,22 @@ body {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.data-list-treemap-tile--compact {
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.data-list-treemap-tile--compact .data-list-treemap-head {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.data-list-treemap-tile--compact .data-list-treemap-body {
|
||||
margin-top: 0;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.data-list-treemap-tile--ocean {
|
||||
background: linear-gradient(135deg, #dbeafe 0%, #93c5fd 100%);
|
||||
}
|
||||
|
||||
@@ -242,6 +242,56 @@ function estimateTreemapRows(
|
||||
return Math.max(occupancy.length, 1)
|
||||
}
|
||||
|
||||
function getTreemapSpan(value: number, maxValue: number, columns: number) {
|
||||
if (columns <= 1) return 1
|
||||
|
||||
const normalized = Math.log10(value + 1) / Math.log10(maxValue + 1)
|
||||
|
||||
if (columns >= 4 && normalized >= 0.94) return 3
|
||||
if (normalized >= 0.62) return 2
|
||||
return 1
|
||||
}
|
||||
|
||||
function isCompactTreemapItem(item: { colSpan: number; rowSpan: number }) {
|
||||
return item.colSpan === 1 && item.rowSpan === 1
|
||||
}
|
||||
|
||||
function getTreemapColumnCount(
|
||||
width: number,
|
||||
minCellSize: number,
|
||||
gap: number,
|
||||
isCompact: boolean
|
||||
) {
|
||||
const visualCap = isCompact ? 4 : 8
|
||||
if (width <= 0) return Math.min(visualCap, isCompact ? 2 : 4)
|
||||
|
||||
const maxColumnsByWidth = Math.max(1, Math.floor((width + gap) / (minCellSize + gap)))
|
||||
return Math.max(1, Math.min(maxColumnsByWidth, visualCap))
|
||||
}
|
||||
|
||||
function getTreemapBaseSize(width: number, columns: number, gap: number, minCellSize: number) {
|
||||
const fittedSize = Math.floor((Math.max(width, 0) - Math.max(0, columns - 1) * gap) / columns)
|
||||
return Math.max(minCellSize, fittedSize || minCellSize)
|
||||
}
|
||||
|
||||
function getTreemapTypography(rowHeight: number) {
|
||||
const tilePadding = rowHeight <= 72 ? 8 : rowHeight <= 84 ? 10 : 12
|
||||
const labelSize = rowHeight <= 72 ? 10 : rowHeight <= 84 ? 11 : 12
|
||||
const valueSize = rowHeight <= 72 ? 13 : rowHeight <= 84 ? 15 : 16
|
||||
|
||||
return { tilePadding, labelSize, valueSize }
|
||||
}
|
||||
|
||||
function getTreemapItemValueSize(
|
||||
item: { colSpan: number; rowSpan: number },
|
||||
baseValueSize: number
|
||||
) {
|
||||
if (isCompactTreemapItem(item)) {
|
||||
return Math.max(11, baseValueSize - 2)
|
||||
}
|
||||
return baseValueSize
|
||||
}
|
||||
|
||||
function DataList() {
|
||||
const screens = useBreakpoint()
|
||||
const isCompact = !screens.lg
|
||||
@@ -579,57 +629,44 @@ function DataList() {
|
||||
}))
|
||||
}, [summary, treemapDimension])
|
||||
|
||||
const treemapGap = isCompact ? 8 : 10
|
||||
const treemapMinCellSize = isCompact ? 72 : 52
|
||||
const treemapColumns = useMemo(() => {
|
||||
if (isCompact) return summaryBodyWidth >= 320 ? 2 : 1
|
||||
if (leftPanelWidth < 360) return 2
|
||||
if (leftPanelWidth < 520) return 3
|
||||
return 4
|
||||
}, [isCompact, leftPanelWidth, summaryBodyWidth])
|
||||
return getTreemapColumnCount(summaryBodyWidth, treemapMinCellSize, treemapGap, isCompact)
|
||||
}, [isCompact, summaryBodyWidth, treemapGap, treemapMinCellSize])
|
||||
|
||||
const treemapItems = useMemo(() => {
|
||||
const palette = ['ocean', 'sky', 'mint', 'amber', 'rose', 'violet', 'slate']
|
||||
const limitedItems = distributionItems.slice(0, isCompact ? 6 : 10)
|
||||
const maxItems = isCompact ? 6 : 10
|
||||
const limitedItems = distributionItems.slice(0, maxItems)
|
||||
const maxValue = Math.max(...limitedItems.map((item) => item.value), 1)
|
||||
const allowFeaturedTile = !isCompact && treemapColumns > 1 && limitedItems.length > 2
|
||||
|
||||
return limitedItems.map((item, index) => {
|
||||
const ratio = item.value / maxValue
|
||||
let colSpan = 1
|
||||
let rowSpan = 1
|
||||
|
||||
if (allowFeaturedTile && index === 0 && ratio >= 0.35) {
|
||||
colSpan = Math.min(2, treemapColumns)
|
||||
rowSpan = colSpan
|
||||
}
|
||||
const span = Math.min(getTreemapSpan(item.value, maxValue, treemapColumns), treemapColumns)
|
||||
|
||||
return {
|
||||
...item,
|
||||
colSpan,
|
||||
rowSpan,
|
||||
colSpan: span,
|
||||
rowSpan: span,
|
||||
tone: palette[index % palette.length],
|
||||
}
|
||||
})
|
||||
}, [distributionItems, isCompact, leftPanelWidth, treemapColumns])
|
||||
}, [distributionItems, isCompact, treemapColumns])
|
||||
|
||||
const treemapRows = useMemo(
|
||||
() => estimateTreemapRows(treemapItems, treemapColumns),
|
||||
[treemapColumns, treemapItems]
|
||||
)
|
||||
|
||||
const treemapGap = isCompact ? 8 : 10
|
||||
const treemapBaseSize = Math.max(
|
||||
isCompact ? 88 : 68,
|
||||
Math.min(
|
||||
isCompact ? 220 : 180,
|
||||
Math.floor((Math.max(summaryBodyWidth, 0) - Math.max(0, treemapColumns - 1) * treemapGap) / treemapColumns)
|
||||
) || (isCompact ? 88 : 68)
|
||||
treemapMinCellSize,
|
||||
getTreemapBaseSize(summaryBodyWidth, treemapColumns, treemapGap, treemapMinCellSize)
|
||||
)
|
||||
const treemapAvailableHeight = Math.max(summaryBodyHeight, 0)
|
||||
const treemapRowHeight = treemapBaseSize
|
||||
const treemapContentHeight = treemapRows * treemapRowHeight + Math.max(0, treemapRows - 1) * treemapGap
|
||||
const treemapTilePadding = treemapRowHeight <= 72 ? 8 : treemapRowHeight <= 84 ? 10 : 12
|
||||
const treemapLabelSize = treemapRowHeight <= 72 ? 10 : treemapRowHeight <= 84 ? 11 : 12
|
||||
const treemapValueSize = treemapRowHeight <= 72 ? 13 : treemapRowHeight <= 84 ? 15 : 16
|
||||
const { tilePadding: treemapTilePadding, labelSize: treemapLabelSize, valueSize: treemapValueSize } =
|
||||
getTreemapTypography(treemapRowHeight)
|
||||
|
||||
const pageHeight = '100%'
|
||||
const desktopTableHeight = rightColumnHeight - tableHeaderHeight - 132
|
||||
@@ -801,18 +838,28 @@ function DataList() {
|
||||
{treemapItems.length > 0 ? treemapItems.map((item) => (
|
||||
<div
|
||||
key={item.key}
|
||||
className={`data-list-treemap-tile data-list-treemap-tile--${item.tone}`}
|
||||
className={`data-list-treemap-tile data-list-treemap-tile--${item.tone}${isCompactTreemapItem(item) ? ' data-list-treemap-tile--compact' : ''}`}
|
||||
style={{
|
||||
gridColumn: `span ${item.colSpan}`,
|
||||
gridRow: `span ${item.rowSpan}`,
|
||||
}}
|
||||
>
|
||||
<div className="data-list-treemap-head">
|
||||
<span className="data-list-summary-tile-icon">{item.icon}</span>
|
||||
<Text className="data-list-treemap-label">{item.label}</Text>
|
||||
<Tooltip title={item.label}>
|
||||
<span className="data-list-summary-tile-icon">{item.icon}</span>
|
||||
</Tooltip>
|
||||
{!isCompactTreemapItem(item) ? (
|
||||
<Tooltip title={item.label}>
|
||||
<Text className="data-list-treemap-label">{item.label}</Text>
|
||||
</Tooltip>
|
||||
) : null}
|
||||
</div>
|
||||
<div className="data-list-treemap-body">
|
||||
<Text strong className="data-list-summary-tile-value">
|
||||
<Text
|
||||
strong
|
||||
className="data-list-summary-tile-value"
|
||||
style={{ fontSize: getTreemapItemValueSize(item, treemapValueSize) }}
|
||||
>
|
||||
{item.value.toLocaleString()}
|
||||
</Text>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user