Heatmap: Add support for exemplar rendering with native heatmap-cells (#77324)

This commit is contained in:
Leon Sorokin 2023-10-30 14:16:57 -05:00 committed by GitHub
parent abebcf4385
commit c923e730d5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 14 deletions

View File

@ -84,24 +84,31 @@ export const HeatmapPanel = ({
const facets = useMemo(() => {
let exemplarsXFacet: number[] | undefined = []; // "Time" field
let exemplarsyFacet: Array<number | undefined> = [];
let exemplarsYFacet: Array<number | undefined> = [];
const meta = readHeatmapRowsCustomMeta(info.heatmap);
if (info.exemplars?.length && meta.yMatchWithLabel) {
if (info.exemplars?.length) {
exemplarsXFacet = info.exemplars?.fields[0].values;
// ordinal/labeled heatmap-buckets?
const hasLabeledY = meta.yOrdinalDisplay != null;
// render by match on ordinal y label
if (meta.yMatchWithLabel) {
// ordinal/labeled heatmap-buckets?
const hasLabeledY = meta.yOrdinalDisplay != null;
if (hasLabeledY) {
let matchExemplarsBy = info.exemplars?.fields.find((field) => field.name === meta.yMatchWithLabel)!.values;
exemplarsyFacet = matchExemplarsBy.map((label) => meta.yOrdinalLabel?.indexOf(label));
} else {
exemplarsyFacet = info.exemplars?.fields[1].values; // "Value" field
if (hasLabeledY) {
let matchExemplarsBy = info.exemplars?.fields.find((field) => field.name === meta.yMatchWithLabel)!.values;
exemplarsYFacet = matchExemplarsBy.map((label) => meta.yOrdinalLabel?.indexOf(label));
} else {
exemplarsYFacet = info.exemplars?.fields[1].values; // "Value" field
}
}
// render by raw value
else {
exemplarsYFacet = info.exemplars?.fields[1].values; // "Value" field
}
}
return [null, info.heatmap?.fields.map((f) => f.values), [exemplarsXFacet, exemplarsyFacet]];
return [null, info.heatmap?.fields.map((f) => f.values), [exemplarsXFacet, exemplarsYFacet]];
}, [info.heatmap, info.exemplars]);
const [hover, setHover] = useState<HeatmapHoverEvent | undefined>(undefined);

View File

@ -784,10 +784,19 @@ export function heatmapPathsPoints(opts: PointsBuilderOpts, exemplarColor: strin
for (let i = 0; i < dataX.length; i++) {
let yVal = dataY[i]!;
yVal -= 0.5; // center vertically in bucket (when tiles are le)
// y-randomize vertically to distribute exemplars in same bucket at same time
let randSign = Math.round(Math.random()) * 2 - 1;
yVal += randSign * 0.5 * Math.random();
// this is a hacky by-proxy check
// works okay since we have no exemplars in calculated heatmaps and...
// - heatmap-rows has ordinal y
// - heatmap-cells has log2 y
let isSparseHeatmap = scaleY.distr === 3 && scaleY.log === 2;
if (!isSparseHeatmap) {
yVal -= 0.5; // center vertically in bucket (when tiles are le)
// y-randomize vertically to distribute exemplars in same bucket at same time
let randSign = Math.round(Math.random()) * 2 - 1;
yVal += randSign * 0.5 * Math.random();
}
let x = valToPosX(dataX[i], scaleX, xDim, xOff);
let y = valToPosY(yVal, scaleY, yDim, yOff);