ui: add sankey link sourceValue to chart tooltip

This commit is contained in:
nick-delirium 2025-02-20 17:07:48 +01:00
parent 1293cbde7d
commit b86e6fdadc
No known key found for this signature in database
GPG key ID: 93ABD695DF5FDBA0
2 changed files with 57 additions and 9 deletions

View file

@ -77,13 +77,18 @@ const EChartsSankey: React.FC<Props> = (props) => {
});
setFinalNodeCount(filteredNodes.length);
const nodeValues: Record<string, number> = {};
const echartNodes = filteredNodes
.map((n) => {
.map((n, i) => {
let computedName = getNodeName(n.eventType || 'Minor Paths', n.name);
if (computedName === 'Other') {
computedName = 'Others';
}
if (n.id) {
nodeValues[n.id] = 0;
} else {
nodeValues[i] = 0;
}
const itemColor =
computedName === 'Others'
? 'rgba(34,44,154,.9)'
@ -124,6 +129,17 @@ const EChartsSankey: React.FC<Props> = (props) => {
.filter((link) => link.source === 0)
.reduce((sum, link) => sum + link.value, 0);
Object.keys(nodeValues).forEach((nodeId) => {
const intId = parseInt(nodeId as string);
const outgoingValues = echartLinks
.filter((l) => l.source === intId)
.reduce((p, c) => p + c.value, 0);
const incomingValues = echartLinks
.filter((l) => l.target === intId)
.reduce((p, c) => p + c.value, 0);
nodeValues[nodeId] = Math.max(outgoingValues, incomingValues);
});
const option = {
...defaultOptions,
tooltip: {
@ -237,7 +253,7 @@ const EChartsSankey: React.FC<Props> = (props) => {
},
},
tooltip: {
formatter: sankeyTooltip(echartNodes, []),
formatter: sankeyTooltip(echartNodes, nodeValues),
},
nodeAlign: 'left',
nodeWidth: 40,

View file

@ -1,18 +1,32 @@
// sankeyUtils.ts
export function sankeyTooltip(echartNodes: any[], nodeValues: number[]) {
export function sankeyTooltip(
echartNodes: any[],
nodeValues: Record<string, number>
) {
return (params: any) => {
if ('source' in params.data && 'target' in params.data) {
const sourceName = echartNodes[params.data.source].name;
const targetName = echartNodes[params.data.target].name;
const sourceValue = nodeValues[params.data.source];
const safeSourceName = shortenString(sourceName);
const safeTargetName = shortenString(targetName);
return `
<div class="flex gap-2 w-fit px-2 bg-white items-center rounded-xl">
<div class="flex flex-col">
<div class="flex flex-col text-sm">
<div class="font-semibold">
${sourceName} <span class="text-base" style="color:#394eff">&#8594;</span> ${targetName}
<span class="text-base" style="color:#394eff">&#8592;</span> ${safeSourceName}
</div>
<div class="text-black">
${sourceValue} <span class="text-disabled-text">Sessions</span>
</div>
<div class="font-semibold mt-2">
<span class="text-base" style="color:#394eff">&#8594;</span> ${safeTargetName}
</div>
<div class="flex items-baseline gap-2 text-black">
<span>${params.data.value} ( ${params.data.percentage.toFixed(2)}% )</span>
<span>${params.data.value} ( ${params.data.percentage.toFixed(
2
)}% )</span>
<span class="text-disabled-text">Sessions</span>
</div>
</div>
@ -31,6 +45,21 @@ export function sankeyTooltip(echartNodes: any[], nodeValues: number[]) {
};
}
const shortenString = (str: string) => {
const limit = 60;
const leftPart = 25;
const rightPart = 20;
const safeStr =
str.length > limit
? `${str.slice(0, leftPart)}...${str.slice(
str.length - rightPart,
str.length
)}`
: str;
return safeStr;
};
export const getEventPriority = (type: string): number => {
switch (type) {
case 'DROP':
@ -42,9 +71,12 @@ export const getEventPriority = (type: string): number => {
}
};
export const getNodeName = (eventType: string, nodeName: string | null): string => {
export const getNodeName = (
eventType: string,
nodeName: string | null
): string => {
if (!nodeName) {
return eventType.charAt(0) + eventType.slice(1).toLowerCase();
}
return nodeName;
};
};