You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When the time range is updated for a flamegraph, we fetch the respective data; then the flamegraph will re-render without a page refresh. In the common case where the data before and after are different, then the flamegraph will render incorrectly (text will be offset from the expected rectangle bounds, colors will not applied to the rectangles, etc). At least in Firefox, we see an error like this:
WebGL warning: drawArraysInstanced: Instance fetch requires 15054, but attribs only supply 12822.
What's interesting is that the left number (15054) represents the length of the position array before the time range was updated, whereas 12822 is the array length after fetching.
To Reproduce
Steps to reproduce the behavior:
Go to Flamegraphs section
Select a time range larger than the existing range
See error
See these screenshots that reproduce the behavior:
Flamegraph before updating time range
Flamegraph after updating time range (1st time)
Flamegraph after updating time range (2nd time)
Expected behavior
The flamegraph should always rendering correctly when the time range is updated. No WebGL warnings should be seen in the browser console.
Additional context
I created a sample test case from the existing storybook story to demonstrate the issue. I have two different columnar datasets and the example toggles between the datasets every 10 seconds.
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { action } from '@storybook/addon-actions';
import React, { useEffect, useState } from 'react';
import { Chart, ColumnarViewModel, Datum, Flame, Settings, PartialTheme, ControlProviderCallback } from '@elastic/charts';
import columnarMock from '@elastic/charts/src/mocks/hierarchical/cpu_profile_tree_mock_columnar.json';
import { getRandomNumberGenerator } from '@elastic/charts/src/mocks/utils';
import { useBaseTheme } from '../../use_base_theme';
const pseudoRandom = getRandomNumberGenerator('a_seed');
const paletteColorBrewerCat12 = [
[141, 211, 199],
[255, 255, 179],
[190, 186, 218],
[251, 128, 114],
[128, 177, 211],
[253, 180, 98],
[179, 222, 105],
[252, 205, 229],
[217, 217, 217],
[188, 128, 189],
[204, 235, 197],
[255, 237, 111],
];
function generateColorsForLabels(labels: any[]): number[] {
return labels.flatMap(() => [...paletteColorBrewerCat12[pseudoRandom(0, 11)].map((c) => c / 255), 1]);
}
const largeDataset: ColumnarViewModel = (() => {
const labels = columnarMock.label;
const value = new Float64Array(columnarMock.value);
const position = new Float32Array(columnarMock.position);
const size = new Float32Array(columnarMock.size);
return {
label: labels.map((index: number) => columnarMock.dictionary[index]),
value: value,
color: new Float32Array(generateColorsForLabels(labels)),
position0: position,
position1: position,
size0: size,
size1: size,
};
})();
const smallDataset: ColumnarViewModel = (() => {
const labels = ["root", "kernel", "libxul.so", "libxul.so"];
const value = [1428, 1428, 1099, 329];
const position = [0, 0.67, 0, 0.33, 0, 0, 0.769607, 0];
const size = [1, 1, 0.769607, 0.230393];
return {
label: labels,
value: new Float64Array(value),
color: new Float32Array(generateColorsForLabels(labels)),
position0: new Float32Array(position),
position1: new Float32Array(position),
size0: new Float32Array(size),
size1: new Float32Array(size),
};
})();
export const Example = (
// should check why it's not a good idea; in the meantime:
// eslint-disable-next-line unicorn/no-object-as-default-parameter
props?: { controlProviderCallback: ControlProviderCallback },
) => {
const [columnarData, setColumnarData] = useState(largeDataset);
const [seconds, setSeconds] = useState(0);
const onElementListeners = {
onElementClick: action('onElementClick'),
onElementOver: action('onElementOver'),
onElementOut: action('onElementOut'),
};
const theme: PartialTheme = {
chartMargins: { top: 0, left: 0, bottom: 0, right: 0 },
chartPaddings: { left: 0, right: 0, top: 0, bottom: 0 },
};
useEffect(() => {
const interval = setInterval(() => {
setSeconds(seconds => seconds + 1);
}, 1000);
return () => clearInterval(interval);
}, []);
useEffect(() => {
if (seconds > 0 && seconds % 10 === 0) {
if ((seconds / 10) % 2 == 0) {
setColumnarData(largeDataset)
} else {
setColumnarData(smallDataset)
}
}
}, [seconds]);
return (
<Chart>
<Settings theme={theme} baseTheme={useBaseTheme()} {...onElementListeners} />
<Flame
id="spec_1"
columnarData={columnarData}
valueAccessor={(d: Datum) => d.value as number}
valueFormatter={(value) => `${value}`}
animation={{ duration: 500 }}
controlProviderCallback={props?.controlProviderCallback ?? (() => { })}
/>
</Chart>
);
};
Example.parameters = {
background: { default: 'white' },
};
The text was updated successfully, but these errors were encountered:
Thanks for the detailed report! We're looking into it. In the meantime, to avoid being blocked, would a fresh instantiation of the chart work? Ie. it gets a new key, so the old chart and its resources are removed from the DOM tree and a fresh one gets inserted
(copied from @jbcrail's issue in a private repo
Describe the bug
When the time range is updated for a flamegraph, we fetch the respective data; then the flamegraph will re-render without a page refresh. In the common case where the data before and after are different, then the flamegraph will render incorrectly (text will be offset from the expected rectangle bounds, colors will not applied to the rectangles, etc). At least in Firefox, we see an error like this:
What's interesting is that the left number (15054) represents the length of the position array before the time range was updated, whereas 12822 is the array length after fetching.
To Reproduce
Steps to reproduce the behavior:
Flamegraphs
sectionSee these screenshots that reproduce the behavior:
Expected behavior
The flamegraph should always rendering correctly when the time range is updated. No WebGL warnings should be seen in the browser console.
Additional context
I created a sample test case from the existing storybook story to demonstrate the issue. I have two different columnar datasets and the example toggles between the datasets every 10 seconds.
The text was updated successfully, but these errors were encountered: