mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
[Profiling] Update coloring logic (#140846)
This commit is contained in:
parent
416a4733e1
commit
2b0dddb8de
3 changed files with 59 additions and 41 deletions
|
@ -8,35 +8,38 @@ import { getInterpolationValue } from './get_interpolation_value';
|
|||
|
||||
describe('getInterpolationValue', () => {
|
||||
it('returns 0 for no change', () => {
|
||||
expect(getInterpolationValue(100, 100)).toBe(0);
|
||||
expect(getInterpolationValue(8, 8)).toBe(0);
|
||||
});
|
||||
|
||||
it('returns -1 when the background is undefined', () => {
|
||||
expect(getInterpolationValue(100, undefined)).toBe(-1);
|
||||
expect(getInterpolationValue(8, undefined)).toBe(1);
|
||||
});
|
||||
|
||||
it('returns -1 when the background is 0', () => {
|
||||
expect(getInterpolationValue(100, 0)).toBe(-1);
|
||||
expect(getInterpolationValue(8, 0)).toBe(1);
|
||||
});
|
||||
|
||||
it('returns 0 when both values are 0', () => {
|
||||
expect(getInterpolationValue(0, 0)).toBe(0);
|
||||
it('returns 0 when both values are equal', () => {
|
||||
expect(getInterpolationValue(1, 1)).toBe(0);
|
||||
});
|
||||
|
||||
it('returns the correct value on positive changes', () => {
|
||||
expect(getInterpolationValue(100, 120)).toBeCloseTo(0.1);
|
||||
expect(getInterpolationValue(80, 100)).toBeCloseTo(0.125);
|
||||
|
||||
expect(getInterpolationValue(90, 270)).toBeCloseTo(1);
|
||||
it('returns the correct positive change', () => {
|
||||
expect(getInterpolationValue(8, 5)).toBe(0.375);
|
||||
});
|
||||
|
||||
it('returns the correct value on negative changes', () => {
|
||||
expect(getInterpolationValue(160, 120)).toBeCloseTo(-0.5);
|
||||
expect(getInterpolationValue(150, 100)).toBeCloseTo(-2 / 3);
|
||||
it('returns the correct negative change', () => {
|
||||
expect(getInterpolationValue(5, 8)).toBe(-0.6);
|
||||
});
|
||||
|
||||
it('clamps the value', () => {
|
||||
expect(getInterpolationValue(90, 360)).toBeCloseTo(1);
|
||||
expect(getInterpolationValue(360, 90)).toBeCloseTo(-1);
|
||||
it('returns the correct positive change with a denominator', () => {
|
||||
expect(getInterpolationValue(10, 8, 50)).toBe(0.04);
|
||||
});
|
||||
|
||||
it('returns the correct negative change with a denominator', () => {
|
||||
expect(getInterpolationValue(8, 10, 50)).toBe(-0.04);
|
||||
});
|
||||
|
||||
it('clamps changes', () => {
|
||||
expect(getInterpolationValue(5, 12)).toBe(-1);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,15 +7,14 @@
|
|||
|
||||
import { clamp } from 'lodash';
|
||||
|
||||
const MAX_POSITIVE_CHANGE = 2;
|
||||
const MAX_NEGATIVE_CHANGE = 0.5;
|
||||
|
||||
export function getInterpolationValue(foreground: number, background: number | null | undefined) {
|
||||
if (background === null || background === undefined) {
|
||||
return -1;
|
||||
export function getInterpolationValue(
|
||||
foreground: number,
|
||||
background: number | undefined,
|
||||
denominator: number = foreground
|
||||
) {
|
||||
if (background === undefined) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const change = clamp(background / foreground - 1, -MAX_NEGATIVE_CHANGE, MAX_POSITIVE_CHANGE) || 0;
|
||||
|
||||
return change >= 0 ? change / MAX_POSITIVE_CHANGE : change / MAX_NEGATIVE_CHANGE;
|
||||
return clamp((foreground - background) / denominator, -1, 1);
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
import { ColumnarViewModel } from '@elastic/charts';
|
||||
import d3 from 'd3';
|
||||
import { uniqueId } from 'lodash';
|
||||
import { sum, uniqueId } from 'lodash';
|
||||
import { ElasticFlameGraph, FlameGraphComparisonMode, rgbToRGBA } from '../../../common/flamegraph';
|
||||
import { getInterpolationValue } from './get_interpolation_value';
|
||||
|
||||
|
@ -57,28 +57,44 @@ export function getFlamegraphModel({
|
|||
};
|
||||
});
|
||||
|
||||
const positiveChangeInterpolator = d3.interpolateRgb(colorNeutral, colorDanger);
|
||||
const positiveChangeInterpolator = d3.interpolateRgb(colorNeutral, colorSuccess);
|
||||
|
||||
const negativeChangeInterpolator = d3.interpolateRgb(colorNeutral, colorSuccess);
|
||||
const negativeChangeInterpolator = d3.interpolateRgb(colorNeutral, colorDanger);
|
||||
|
||||
const comparisonExclusive: number[] = [];
|
||||
const comparisonInclusive: number[] = [];
|
||||
// per @thomasdullien:
|
||||
// In "relative" mode: Take the percentage of CPU time consumed by block A and subtract
|
||||
// the percentage of CPU time consumed by block B. If the number is positive, linearly
|
||||
// interpolate a color between grey and green, with the delta relative to the size of
|
||||
// block A as percentage.
|
||||
|
||||
// Example 1: BlockA 8%, BlockB 5%, delta 3%. This represents a 3/8th reduction, 37.5%
|
||||
// of the original time, so the color should be 37.5% "green".
|
||||
|
||||
// Example 2: BlockA 5%, BlockB 8%, delta -3%. This represents a 3/5th worsening of BlockA,
|
||||
// so the color should be 62.5% "red". In "absolute" mode: Take the number of samples in
|
||||
// blockA, subtract the number of samples in blockB. Divide the result by the number of
|
||||
// samples in the first graph. The result is the amount of saturation for the color.
|
||||
// Example 3: BlockA 10k samples, BlockB 8k samples, total samples 50k. 10k-8k = 2k, 2k/50k
|
||||
// = 4%, therefore 4% "green".
|
||||
|
||||
const totalSamples = sum(primaryFlamegraph.CountExclusive);
|
||||
const comparisonTotalSamples = sum(comparisonFlamegraph.CountExclusive);
|
||||
|
||||
primaryFlamegraph.ID.forEach((nodeID, index) => {
|
||||
const countInclusive = primaryFlamegraph.CountInclusive[index];
|
||||
const countExclusive = primaryFlamegraph.CountExclusive[index];
|
||||
const samples = primaryFlamegraph.Value[index];
|
||||
const comparisonSamples = comparisonNodesById[nodeID]?.Value as number | undefined;
|
||||
|
||||
const comparisonNode = comparisonNodesById[nodeID];
|
||||
|
||||
comparisonExclusive![index] = comparisonNode?.CountExclusive;
|
||||
comparisonInclusive![index] = comparisonNode?.CountInclusive;
|
||||
|
||||
const [foreground, background] =
|
||||
const foreground =
|
||||
comparisonMode === FlameGraphComparisonMode.Absolute ? samples : samples / totalSamples;
|
||||
const background =
|
||||
comparisonMode === FlameGraphComparisonMode.Absolute
|
||||
? [countInclusive, comparisonNode?.CountInclusive]
|
||||
: [countExclusive, comparisonNode?.CountExclusive];
|
||||
? comparisonSamples
|
||||
: (comparisonSamples ?? 0) / comparisonTotalSamples;
|
||||
|
||||
const interpolationValue = getInterpolationValue(foreground, background);
|
||||
const denominator =
|
||||
comparisonMode === FlameGraphComparisonMode.Absolute ? totalSamples : foreground;
|
||||
|
||||
const interpolationValue = getInterpolationValue(foreground, background, denominator);
|
||||
|
||||
const nodeColor =
|
||||
interpolationValue >= 0
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue