@grafana/flamegraph
Version:
Grafana flamegraph visualization component
290 lines (286 loc) • 9.03 kB
JavaScript
'use strict';
var jsxRuntime = require('react/jsx-runtime');
var css = require('@emotion/css');
var react = require('react');
var ui = require('@grafana/ui');
var ColorSchemeButton = require('../ColorSchemeButton.cjs');
var FlameGraphHeader = require('../FlameGraphHeader.cjs');
var constants = require('../constants.cjs');
var FlameGraphCanvas = require('./FlameGraphCanvas.cjs');
var FlameGraphMetadata = require('./FlameGraphMetadata.cjs');
"use strict";
const FlameGraph = ({
data,
rangeMin,
rangeMax,
matchedLabels,
setRangeMin,
setRangeMax,
onItemFocused,
focusedItemData,
textAlign,
onSandwich,
sandwichItem,
onFocusPillClick,
onSandwichPillClick,
colorScheme,
showFlameGraphOnly,
getExtraContextMenuButtons,
collapsing,
search,
collapsedMap,
setCollapsedMap,
selectedView,
enableNewUI,
viewMode,
paneView,
onTextAlignChange,
onColorSchemeChange,
isDiffMode
}) => {
const isNewUI = enableNewUI === true;
const newStyles = ui.useStyles2(getStylesNew);
const legacyStyles = getStylesLegacy();
const [levels, setLevels] = react.useState();
const [levelsCallers, setLevelsCallers] = react.useState();
const [totalProfileTicks, setTotalProfileTicks] = react.useState(0);
const [totalProfileTicksRight, setTotalProfileTicksRight] = react.useState();
const [totalViewTicks, setTotalViewTicks] = react.useState(0);
react.useEffect(() => {
var _a, _b, _c;
if (data) {
let levels2 = data.getLevels();
let totalProfileTicks2 = levels2.length ? levels2[0][0].value : 0;
let totalProfileTicksRight2 = levels2.length ? levels2[0][0].valueRight : void 0;
let totalViewTicks2 = totalProfileTicks2;
let levelsCallers2 = void 0;
if (sandwichItem) {
const [callers, callees] = data.getSandwichLevels(sandwichItem);
levels2 = callees;
levelsCallers2 = callers;
totalViewTicks2 = (_c = (_b = (_a = callees[0]) == null ? void 0 : _a[0]) == null ? void 0 : _b.value) != null ? _c : 0;
}
setLevels(levels2);
setLevelsCallers(levelsCallers2);
setTotalProfileTicks(totalProfileTicks2);
setTotalProfileTicksRight(totalProfileTicksRight2);
setTotalViewTicks(totalViewTicks2);
}
}, [data, sandwichItem]);
if (!levels) {
return null;
}
const commonCanvasProps = {
data,
rangeMin,
rangeMax,
matchedLabels,
setRangeMin,
setRangeMax,
onItemFocused,
focusedItemData,
textAlign,
onSandwich,
colorScheme,
totalProfileTicks,
totalProfileTicksRight,
totalViewTicks,
showFlameGraphOnly,
collapsedMap,
setCollapsedMap,
getExtraContextMenuButtons,
collapsing,
search,
selectedView,
viewMode,
paneView
};
let canvas = null;
const canvasStyles = isNewUI ? newStyles : legacyStyles;
if (levelsCallers == null ? void 0 : levelsCallers.length) {
canvas = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: canvasStyles.sandwichCanvasWrapper, children: [
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: canvasStyles.sandwichMarker, children: [
"Callers",
/* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { className: canvasStyles.sandwichMarkerIcon, name: "arrow-down" })
] }),
/* @__PURE__ */ jsxRuntime.jsx(
FlameGraphCanvas.default,
{
...commonCanvasProps,
root: levelsCallers[levelsCallers.length - 1][0],
depth: levelsCallers.length,
direction: "parents",
collapsing: false
}
)
] }),
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: canvasStyles.sandwichCanvasWrapper, children: [
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: css.cx(canvasStyles.sandwichMarker, canvasStyles.sandwichMarkerCalees), children: [
/* @__PURE__ */ jsxRuntime.jsx(ui.Icon, { className: canvasStyles.sandwichMarkerIcon, name: "arrow-up" }),
"Callees"
] }),
/* @__PURE__ */ jsxRuntime.jsx(
FlameGraphCanvas.default,
{
...commonCanvasProps,
root: levels[0][0],
depth: levels.length,
direction: "children",
collapsing: false
}
)
] })
] });
} else if (levels == null ? void 0 : levels.length) {
canvas = /* @__PURE__ */ jsxRuntime.jsx(FlameGraphCanvas.default, { ...commonCanvasProps, root: levels[0][0], depth: levels.length, direction: "children" });
}
if (isNewUI) {
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: newStyles.graph, children: [
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: newStyles.toolbar, children: [
/* @__PURE__ */ jsxRuntime.jsx(
FlameGraphMetadata,
{
data,
focusedItem: focusedItemData,
sandwichedLabel: sandwichItem,
totalTicks: totalViewTicks,
onFocusPillClick,
onSandwichPillClick
}
),
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: newStyles.controls, children: [
onColorSchemeChange && /* @__PURE__ */ jsxRuntime.jsx(ColorSchemeButton.ColorSchemeButton, { value: colorScheme, onChange: onColorSchemeChange, isDiffMode: isDiffMode != null ? isDiffMode : false }),
/* @__PURE__ */ jsxRuntime.jsxs(ui.ButtonGroup, { className: newStyles.buttonSpacing, children: [
/* @__PURE__ */ jsxRuntime.jsx(
ui.Button,
{
variant: "secondary",
fill: "outline",
size: "sm",
tooltip: "Expand all groups",
onClick: () => {
setCollapsedMap(collapsedMap.setAllCollapsedStatus(false));
},
"aria-label": "Expand all groups",
icon: "angle-double-down"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
ui.Button,
{
variant: "secondary",
fill: "outline",
size: "sm",
tooltip: "Collapse all groups",
onClick: () => {
setCollapsedMap(collapsedMap.setAllCollapsedStatus(true));
},
"aria-label": "Collapse all groups",
icon: "angle-double-up"
}
)
] }),
onTextAlignChange && /* @__PURE__ */ jsxRuntime.jsx(
ui.RadioButtonGroup,
{
size: "sm",
options: FlameGraphHeader.alignOptions,
value: textAlign,
onChange: onTextAlignChange
}
)
] })
] }),
canvas
] });
}
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: legacyStyles.graph, children: [
/* @__PURE__ */ jsxRuntime.jsx(
FlameGraphMetadata,
{
data,
focusedItem: focusedItemData,
sandwichedLabel: sandwichItem,
totalTicks: totalViewTicks,
onFocusPillClick,
onSandwichPillClick
}
),
canvas
] });
};
const getStylesLegacy = () => ({
graph: css.css({
label: "graph",
overflow: "auto",
flexGrow: 1,
flexBasis: "50%"
}),
sandwichCanvasWrapper: css.css({
label: "sandwichCanvasWrapper",
display: "flex",
marginBottom: `${constants.PIXELS_PER_LEVEL / window.devicePixelRatio}px`
}),
sandwichMarker: css.css({
label: "sandwichMarker",
writingMode: "vertical-lr",
transform: "rotate(180deg)",
overflow: "hidden",
whiteSpace: "nowrap"
}),
sandwichMarkerCalees: css.css({
label: "sandwichMarkerCalees",
textAlign: "right"
}),
sandwichMarkerIcon: css.css({
label: "sandwichMarkerIcon",
verticalAlign: "baseline"
})
});
const getStylesNew = (theme) => ({
graph: css.css({
label: "graph",
overflow: "auto",
flexGrow: 1,
flexBasis: "50%"
}),
toolbar: css.css({
label: "toolbar",
display: "flex",
justifyContent: "space-between",
alignItems: "center"
}),
controls: css.css({
label: "controls",
display: "flex",
alignItems: "center",
gap: theme.spacing(1)
}),
buttonSpacing: css.css({
label: "buttonSpacing",
marginRight: theme.spacing(1)
}),
sandwichCanvasWrapper: css.css({
label: "sandwichCanvasWrapper",
display: "flex",
marginBottom: `${constants.PIXELS_PER_LEVEL / window.devicePixelRatio}px`
}),
sandwichMarker: css.css({
label: "sandwichMarker",
writingMode: "vertical-lr",
transform: "rotate(180deg)",
overflow: "hidden",
whiteSpace: "nowrap"
}),
sandwichMarkerCalees: css.css({
label: "sandwichMarkerCalees",
textAlign: "right"
}),
sandwichMarkerIcon: css.css({
label: "sandwichMarkerIcon",
verticalAlign: "baseline"
})
});
module.exports = FlameGraph;
//# sourceMappingURL=FlameGraph.cjs.map