"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CriticalPathFlamegraph = CriticalPathFlamegraph; var _charts = require("@elastic/charts"); var _eui = require("@elastic/eui"); var _css = require("@emotion/css"); var _public = require("@kbn/observability-shared-plugin/public"); var _lodash = require("lodash"); var _react = _interopRequireWildcard(require("react")); var _use_fetcher = require("../../../hooks/use_fetcher"); var _critical_path_flamegraph_tooltip = require("./critical_path_flamegraph_tooltip"); var _critical_path_to_flamegraph = require("./critical_path_to_flamegraph"); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /* * 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; you may not use this file except in compliance with the Elastic License * 2.0. */ const chartClassName = (0, _css.css)` flex-grow: 1; `; function CriticalPathFlamegraph(props) { const { start, end, traceIds, traceIdsFetchStatus } = props; const serviceName = 'serviceName' in props ? props.serviceName : null; const transactionName = 'transactionName' in props ? props.transactionName : null; // Use a reference to time range, to not invalidate the API fetch // we only care for traceIds, start/end are there to limit the search // request to a certain time range. It shouldn't affect the actual results // of the search. const timerange = (0, _react.useRef)({ start, end }); timerange.current = { start, end }; const { data: { criticalPath } = { criticalPath: null }, status: criticalPathFetchStatus } = (0, _use_fetcher.useFetcher)(callApmApi => { if (!traceIds.length) { return Promise.resolve({ criticalPath: null }); } return callApmApi('POST /internal/apm/traces/aggregated_critical_path', { params: { body: { start: timerange.current.start, end: timerange.current.end, traceIds, serviceName, transactionName } } }); }, [timerange, traceIds, serviceName, transactionName]); const chartTheme = (0, _public.useChartTheme)(); const isLoading = (0, _use_fetcher.isPending)(traceIdsFetchStatus) || (0, _use_fetcher.isPending)(criticalPathFetchStatus); const flameGraph = (0, _react.useMemo)(() => { if (!criticalPath) { return undefined; } const colors = (0, _eui.euiPaletteColorBlind)({}); const flamegraph = (0, _critical_path_to_flamegraph.criticalPathToFlamegraph)({ criticalPath, colors }); return { ...flamegraph, // make sure Flame re-renders when data changes, workaround for https://github.com/elastic/elastic-charts/issues/1766 key: (0, _lodash.uniqueId)() }; }, [criticalPath]); const themeOverrides = { chartMargins: { top: 0, left: 0, bottom: 0, right: 0 }, chartPaddings: { left: 0, right: 0, top: 0, bottom: 0 } }; return /*#__PURE__*/_react.default.createElement(_eui.EuiFlexGroup, { direction: "column", gutterSize: "l", alignItems: "stretch", justifyContent: "center", style: { minHeight: 400 } }, isLoading ? /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, { grow: false, style: { alignSelf: 'center' } }, /*#__PURE__*/_react.default.createElement(_eui.EuiLoadingSpinner, { size: "l" })) : flameGraph && /*#__PURE__*/_react.default.createElement(_eui.EuiFlexItem, { grow: true }, /*#__PURE__*/_react.default.createElement(_charts.Chart, { key: flameGraph.key, className: chartClassName }, /*#__PURE__*/_react.default.createElement(_charts.Tooltip, { customTooltip: tooltipProps => { const valueIndex = tooltipProps.values[0].valueAccessor; const operationId = flameGraph.operationId[valueIndex]; const operationMetadata = criticalPath === null || criticalPath === void 0 ? void 0 : criticalPath.metadata[operationId]; const countInclusive = flameGraph.viewModel.value[valueIndex]; const countExclusive = flameGraph.countExclusive[valueIndex]; return /*#__PURE__*/_react.default.createElement(_critical_path_flamegraph_tooltip.CriticalPathFlamegraphTooltip, { metadata: operationMetadata, countInclusive: countInclusive, countExclusive: countExclusive, totalCount: flameGraph.viewModel.value[0] }); } }), /*#__PURE__*/_react.default.createElement(_charts.Settings, { theme: [{ chartMargins: themeOverrides.chartMargins, chartPaddings: themeOverrides.chartPaddings }, ...chartTheme], onElementClick: elements => {} }), /*#__PURE__*/_react.default.createElement(_charts.Flame, { id: "aggregated_critical_path", columnarData: flameGraph.viewModel, valueAccessor: d => d.value, valueFormatter: value => `${value}`, animation: { duration: 100 }, controlProviderCallback: {} })))); }