|
|
|
|
@ -24,31 +24,43 @@ export interface Props { |
|
|
|
|
header?: string; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
interface DisplayValue { |
|
|
|
|
name: string; |
|
|
|
|
value: unknown; |
|
|
|
|
valueString: string; |
|
|
|
|
highlight: boolean; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
export const DataHoverView = ({ data, rowIndex, columnIndex, sortOrder, mode, header = undefined }: Props) => { |
|
|
|
|
const styles = useStyles2(getStyles); |
|
|
|
|
|
|
|
|
|
if (!data || rowIndex == null) { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const fields = data.fields.map((f, idx) => { |
|
|
|
|
return { ...f, hovered: idx === columnIndex }; |
|
|
|
|
}); |
|
|
|
|
// Put the traceID field in front.
|
|
|
|
|
const visibleFields = data.fields.filter((f) => !Boolean(f.config.custom?.hideFrom?.tooltip)); |
|
|
|
|
const traceIDField = visibleFields.find((field) => field.name === 'traceID') || data.fields[0]; |
|
|
|
|
const visibleFields = fields.filter((f) => !Boolean(f.config.custom?.hideFrom?.tooltip)); |
|
|
|
|
const traceIDField = visibleFields.find((field) => field.name === 'traceID') || fields[0]; |
|
|
|
|
const orderedVisibleFields = [traceIDField, ...visibleFields.filter((field) => traceIDField !== field)]; |
|
|
|
|
|
|
|
|
|
if (orderedVisibleFields.length === 0) { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const displayValues: Array<[string, unknown, string]> = []; |
|
|
|
|
const displayValues: DisplayValue[] = []; |
|
|
|
|
const links: Array<LinkModel<Field>> = []; |
|
|
|
|
const linkLookup = new Set<string>(); |
|
|
|
|
|
|
|
|
|
for (const f of orderedVisibleFields) { |
|
|
|
|
const v = f.values[rowIndex]; |
|
|
|
|
const disp = f.display ? f.display(v) : { text: `${v}`, numeric: +v }; |
|
|
|
|
if (f.getLinks) { |
|
|
|
|
f.getLinks({ calculatedValue: disp, valueRowIndex: rowIndex }).forEach((link) => { |
|
|
|
|
for (const field of orderedVisibleFields) { |
|
|
|
|
if (mode === TooltipDisplayMode.Single && columnIndex != null && !field.hovered) { |
|
|
|
|
continue; |
|
|
|
|
} |
|
|
|
|
const value = field.values[rowIndex]; |
|
|
|
|
const fieldDisplay = field.display ? field.display(value) : { text: `${value}`, numeric: +value }; |
|
|
|
|
if (field.getLinks) { |
|
|
|
|
field.getLinks({ calculatedValue: fieldDisplay, valueRowIndex: rowIndex }).forEach((link) => { |
|
|
|
|
const key = `${link.title}/${link.href}`; |
|
|
|
|
if (!linkLookup.has(key)) { |
|
|
|
|
links.push(link); |
|
|
|
|
@ -57,11 +69,16 @@ export const DataHoverView = ({ data, rowIndex, columnIndex, sortOrder, mode, he |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
displayValues.push([getFieldDisplayName(f, data), v, formattedValueToString(disp)]); |
|
|
|
|
displayValues.push({ |
|
|
|
|
name: getFieldDisplayName(field, data), |
|
|
|
|
value, |
|
|
|
|
valueString: formattedValueToString(fieldDisplay), |
|
|
|
|
highlight: field.hovered, |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (sortOrder && sortOrder !== SortOrder.None) { |
|
|
|
|
displayValues.sort((a, b) => arrayUtils.sortValues(sortOrder)(a[1], b[1])); |
|
|
|
|
displayValues.sort((a, b) => arrayUtils.sortValues(sortOrder)(a.value, b.value)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const renderLinks = () => |
|
|
|
|
@ -96,19 +113,12 @@ export const DataHoverView = ({ data, rowIndex, columnIndex, sortOrder, mode, he |
|
|
|
|
)} |
|
|
|
|
<table className={styles.infoWrap}> |
|
|
|
|
<tbody> |
|
|
|
|
{(mode === TooltipDisplayMode.Multi || mode == null) && |
|
|
|
|
displayValues.map((v, i) => ( |
|
|
|
|
<tr key={`${i}/${rowIndex}`} className={i === columnIndex ? styles.highlight : ''}> |
|
|
|
|
<th>{v[0]}:</th> |
|
|
|
|
<td>{renderValue(v[2])}</td> |
|
|
|
|
</tr> |
|
|
|
|
))} |
|
|
|
|
{mode === TooltipDisplayMode.Single && columnIndex && ( |
|
|
|
|
<tr key={`${columnIndex}/${rowIndex}`}> |
|
|
|
|
<th>{displayValues[columnIndex][0]}:</th> |
|
|
|
|
<td>{renderValue(displayValues[columnIndex][2])}</td> |
|
|
|
|
{displayValues.map((displayValue, i) => ( |
|
|
|
|
<tr key={`${i}/${rowIndex}`} className={displayValue.highlight ? styles.highlight : ''}> |
|
|
|
|
<th>{displayValue.name}:</th> |
|
|
|
|
<td>{renderValue(displayValue.valueString)}</td> |
|
|
|
|
</tr> |
|
|
|
|
)} |
|
|
|
|
))} |
|
|
|
|
{renderLinks()} |
|
|
|
|
</tbody> |
|
|
|
|
</table> |
|
|
|
|
@ -155,7 +165,8 @@ const getStyles = (theme: GrafanaTheme2) => { |
|
|
|
|
} |
|
|
|
|
`,
|
|
|
|
|
highlight: css` |
|
|
|
|
background: ${theme.colors.action.hover}; |
|
|
|
|
/* !important is required to overwrite default table styles */ |
|
|
|
|
background: ${theme.colors.action.hover} !important; |
|
|
|
|
`,
|
|
|
|
|
link: css` |
|
|
|
|
color: #6e9fff; |
|
|
|
|
|