@splunk/visualizations 28.7.0 → 28.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Area.config.js +2 -4
- package/Area.config.js.map +2 -2
- package/Area.js +245 -147
- package/Area.js.map +4 -4
- package/Bar.config.js +2 -4
- package/Bar.config.js.map +2 -2
- package/Bar.js +246 -148
- package/Bar.js.map +4 -4
- package/Bubble/Bubble.d.ts +3 -1
- package/Bubble/Bubble.d.ts.map +1 -1
- package/Bubble.js +216 -108
- package/Bubble.js.map +4 -4
- package/CHANGELOG.external.md +56 -0
- package/ChoroplethSvg/ChoroplethSvg.d.ts +3 -1
- package/ChoroplethSvg/ChoroplethSvg.d.ts.map +1 -1
- package/ChoroplethSvg/PureChoroplethSvg/PureChoroplethSvg.d.ts.map +1 -1
- package/ChoroplethSvg/PureChoroplethSvg/SvgMutator.d.ts.map +1 -1
- package/ChoroplethSvg.js +638 -209
- package/ChoroplethSvg.js.map +4 -4
- package/Column.config.js +2 -4
- package/Column.config.js.map +2 -2
- package/Column.js +246 -148
- package/Column.js.map +4 -4
- package/Ellipse/Ellipse.d.ts +3 -1
- package/Ellipse/Ellipse.d.ts.map +1 -1
- package/Ellipse.js +216 -105
- package/Ellipse.js.map +4 -4
- package/Events/Events.d.ts +5 -3
- package/Events/Events.d.ts.map +1 -1
- package/Events/PureEvents/FieldSummaryTooltip.d.ts.map +1 -1
- package/Events/PureEvents/PureEvents.d.ts +0 -1
- package/Events/PureEvents/PureEvents.d.ts.map +1 -1
- package/Events.js +270 -157
- package/Events.js.map +4 -4
- package/FillerGauge.js +251 -143
- package/FillerGauge.js.map +4 -4
- package/Image/Image.d.ts +3 -1
- package/Image/Image.d.ts.map +1 -1
- package/Image.js +217 -106
- package/Image.js.map +4 -4
- package/Line.config.js +2 -4
- package/Line.config.js.map +2 -2
- package/Line.js +246 -148
- package/Line.js.map +4 -4
- package/LinkGraph/LinkGraph.d.ts +3 -1
- package/LinkGraph/LinkGraph.d.ts.map +1 -1
- package/LinkGraph/PureLinkGraph/PureLinkGraphUtils.d.ts.map +1 -1
- package/LinkGraph/PureLinkGraph/components/Node.d.ts.map +1 -1
- package/LinkGraph.config.js +1 -1
- package/LinkGraph.config.js.map +2 -2
- package/LinkGraph.js +802 -682
- package/LinkGraph.js.map +4 -4
- package/Map/Map.d.ts +10 -9
- package/Map/Map.d.ts.map +1 -1
- package/Map/PureMap/BubbleLayer.d.ts.map +1 -1
- package/Map/PureMap/ClusterLayer.d.ts.map +1 -1
- package/Map/PureMap/MapUtils.d.ts.map +1 -1
- package/Map/PureMap/MarkerWrapper.d.ts.map +1 -1
- package/Map/PureMap/PureMap.d.ts +8 -65
- package/Map/PureMap/PureMap.d.ts.map +1 -1
- package/Map.config.js +1 -1
- package/Map.config.js.map +2 -2
- package/Map.js +363 -313
- package/Map.js.map +4 -4
- package/Markdown/Markdown.d.ts +9 -1
- package/Markdown/Markdown.d.ts.map +1 -1
- package/Markdown/config.d.ts.map +1 -1
- package/Markdown.config.js +6 -1
- package/Markdown.config.js.map +2 -2
- package/Markdown.js +226 -95
- package/Markdown.js.map +3 -3
- package/MarkerGauge.js +247 -137
- package/MarkerGauge.js.map +4 -4
- package/NetworkGraph/PureNetworkGraph/PureNetworkGraph.d.ts.map +1 -1
- package/NetworkGraph/PureNetworkGraph/components/NetworkGraphSvg.d.ts +1 -0
- package/NetworkGraph/PureNetworkGraph/components/NetworkGraphSvg.d.ts.map +1 -1
- package/NetworkGraph/PureNetworkGraph/components/Node.d.ts +1 -0
- package/NetworkGraph/PureNetworkGraph/components/Node.d.ts.map +1 -1
- package/NetworkGraph/PureNetworkGraph/utils/networkGraphUtils.d.ts +3 -5
- package/NetworkGraph/PureNetworkGraph/utils/networkGraphUtils.d.ts.map +1 -1
- package/NetworkGraph.config.js +4 -2
- package/NetworkGraph.config.js.map +2 -2
- package/NetworkGraph.js +327 -188
- package/NetworkGraph.js.map +4 -4
- package/ParallelCoordinates/ParallelCoordinates.d.ts +3 -1
- package/ParallelCoordinates/ParallelCoordinates.d.ts.map +1 -1
- package/ParallelCoordinates.js +239 -128
- package/ParallelCoordinates.js.map +4 -4
- package/Pie/config.d.ts.map +1 -1
- package/Pie/pieUtils.d.ts.map +1 -1
- package/Pie.config.js +4 -2
- package/Pie.config.js.map +2 -2
- package/Pie.js +228 -125
- package/Pie.js.map +3 -3
- package/ProcessTree/ProcessTree.d.ts +3 -1
- package/ProcessTree/ProcessTree.d.ts.map +1 -1
- package/ProcessTree/PureProcessTree/PureProcessTree.d.ts +1 -0
- package/ProcessTree/PureProcessTree/PureProcessTree.d.ts.map +1 -1
- package/ProcessTree/PureProcessTree/components/ProcessTreeLeftPanel.d.ts +1 -0
- package/ProcessTree/PureProcessTree/components/ProcessTreeLeftPanel.d.ts.map +1 -1
- package/ProcessTree/PureProcessTree/hooks/useProcessTreeGraphData.d.ts +2 -1
- package/ProcessTree/PureProcessTree/hooks/useProcessTreeGraphData.d.ts.map +1 -1
- package/ProcessTree/PureProcessTree/utils/iconLoader.d.ts +2 -0
- package/ProcessTree/PureProcessTree/utils/iconLoader.d.ts.map +1 -1
- package/ProcessTree/PureProcessTree/utils/processTreeUtils.d.ts +5 -1
- package/ProcessTree/PureProcessTree/utils/processTreeUtils.d.ts.map +1 -1
- package/ProcessTree.js +435 -192
- package/ProcessTree.js.map +4 -4
- package/Punchcard/Punchcard.d.ts +3 -1
- package/Punchcard/Punchcard.d.ts.map +1 -1
- package/Punchcard.js +238 -129
- package/Punchcard.js.map +4 -4
- package/Rectangle/Rectangle.d.ts +3 -1
- package/Rectangle/Rectangle.d.ts.map +1 -1
- package/Rectangle.js +218 -116
- package/Rectangle.js.map +4 -4
- package/RichText/PureRichText/Editor/EditorPanel.d.ts +1 -4
- package/RichText/PureRichText/Editor/EditorPanel.d.ts.map +1 -1
- package/RichText/PureRichText/Editor/hooks/useConfigPanelFocus.d.ts +14 -0
- package/RichText/PureRichText/Editor/hooks/useConfigPanelFocus.d.ts.map +1 -0
- package/RichText/PureRichText/Editor/hooks/useEditorPanelSync.d.ts +15 -0
- package/RichText/PureRichText/Editor/hooks/useEditorPanelSync.d.ts.map +1 -0
- package/RichText/PureRichText/Editor/hooks/useLinkHandlers.d.ts.map +1 -1
- package/RichText/PureRichText/Editor/hooks/usePortalTarget.d.ts +9 -0
- package/RichText/PureRichText/Editor/hooks/usePortalTarget.d.ts.map +1 -0
- package/RichText/PureRichText/InnerEditor.d.ts +20 -4
- package/RichText/PureRichText/InnerEditor.d.ts.map +1 -1
- package/RichText/PureRichText/PureRichText.d.ts +21 -9
- package/RichText/PureRichText/PureRichText.d.ts.map +1 -1
- package/RichText/PureRichText/PureRichTextContext.d.ts +3 -6
- package/RichText/PureRichText/PureRichTextContext.d.ts.map +1 -1
- package/RichText/PureRichText/RichTextStyles.d.ts +5 -4
- package/RichText/PureRichText/RichTextStyles.d.ts.map +1 -1
- package/RichText/PureRichText/activeInstance.d.ts +6 -7
- package/RichText/PureRichText/activeInstance.d.ts.map +1 -1
- package/RichText/PureRichText/config.d.ts.map +1 -1
- package/RichText/PureRichText/hooks/useContentSave.d.ts +6 -0
- package/RichText/PureRichText/hooks/useContentSave.d.ts.map +1 -1
- package/RichText/PureRichText/hooks/useContentSync.d.ts +13 -1
- package/RichText/PureRichText/hooks/useContentSync.d.ts.map +1 -1
- package/RichText/PureRichText/hooks/useDashboardKeyboardNav.d.ts +2 -7
- package/RichText/PureRichText/hooks/useDashboardKeyboardNav.d.ts.map +1 -1
- package/RichText/PureRichText/hooks/useEditorSetup.d.ts +8 -4
- package/RichText/PureRichText/hooks/useEditorSetup.d.ts.map +1 -1
- package/RichText/PureRichText/hooks/useFakeHighlight.d.ts +1 -16
- package/RichText/PureRichText/hooks/useFakeHighlight.d.ts.map +1 -1
- package/RichText/PureRichText/hooks/useFocusHandlers.d.ts +2 -4
- package/RichText/PureRichText/hooks/useFocusHandlers.d.ts.map +1 -1
- package/RichText/PureRichText/hooks/useKeyboardShortcuts.d.ts.map +1 -1
- package/RichText/PureRichText/hooks/useMouseHandlers.d.ts +3 -7
- package/RichText/PureRichText/hooks/useMouseHandlers.d.ts.map +1 -1
- package/RichText/PureRichText/hooks/useStepFontSize.d.ts +2 -2
- package/RichText/PureRichText/hooks/useStepLineSpacing.d.ts +2 -3
- package/RichText/PureRichText/hooks/useStepLineSpacing.d.ts.map +1 -1
- package/RichText/PureRichText/hooks/useTokenMap.d.ts +31 -40
- package/RichText/PureRichText/hooks/useTokenMap.d.ts.map +1 -1
- package/RichText/PureRichText/renderers/ElementRenderer.d.ts +2 -5
- package/RichText/PureRichText/renderers/ElementRenderer.d.ts.map +1 -1
- package/RichText/PureRichText/renderers/LeafRenderer.d.ts +0 -4
- package/RichText/PureRichText/renderers/LeafRenderer.d.ts.map +1 -1
- package/RichText/PureRichText/types.d.ts +21 -0
- package/RichText/PureRichText/types.d.ts.map +1 -1
- package/RichText/PureRichText/utils/slateUtils.d.ts +26 -2
- package/RichText/PureRichText/utils/slateUtils.d.ts.map +1 -1
- package/RichText/RichText.d.ts +5 -1
- package/RichText/RichText.d.ts.map +1 -1
- package/RichText/config.d.ts.map +1 -1
- package/RichText.config.js +19 -1
- package/RichText.config.js.map +2 -2
- package/RichText.js +2311 -835
- package/RichText.js.map +4 -4
- package/Sankey/PureSankey/PureSankey.d.ts +2 -0
- package/Sankey/PureSankey/PureSankey.d.ts.map +1 -1
- package/Sankey/PureSankey/SankeyLink.d.ts +3 -1
- package/Sankey/PureSankey/SankeyLink.d.ts.map +1 -1
- package/Sankey/PureSankey/SankeyNode.d.ts +5 -2
- package/Sankey/PureSankey/SankeyNode.d.ts.map +1 -1
- package/Sankey/PureSankey/SankeyUtils.d.ts.map +1 -1
- package/Sankey/Sankey.d.ts +3 -1
- package/Sankey/Sankey.d.ts.map +1 -1
- package/Sankey.js +508 -219
- package/Sankey.js.map +4 -4
- package/Scatter.config.js +3 -5
- package/Scatter.config.js.map +2 -2
- package/Scatter.js +244 -146
- package/Scatter.js.map +4 -4
- package/SingleValue/SingleValue.d.ts.map +1 -1
- package/SingleValue.js +273 -173
- package/SingleValue.js.map +4 -4
- package/SingleValueBasic.js +4 -4
- package/SingleValueBasic.js.map +2 -2
- package/SingleValueIcon/SingleValueIcon.d.ts.map +1 -1
- package/SingleValueIcon.js +264 -164
- package/SingleValueIcon.js.map +4 -4
- package/SingleValueRadial.js +267 -167
- package/SingleValueRadial.js.map +4 -4
- package/SparkLine/SparkLine.d.ts.map +1 -1
- package/SparkLine.js.map +2 -2
- package/Table/PureTable.d.ts +2 -0
- package/Table/PureTable.d.ts.map +1 -1
- package/Table/Table.d.ts +2 -5
- package/Table/Table.d.ts.map +1 -1
- package/Table/config.d.ts.map +1 -1
- package/Table/hooks.d.ts.map +1 -1
- package/Table.config.js +8 -1
- package/Table.config.js.map +2 -2
- package/Table.js +374 -270
- package/Table.js.map +4 -4
- package/Timeline/PureTimeline/PureTimeline.d.ts +6 -5
- package/Timeline/PureTimeline/PureTimeline.d.ts.map +1 -1
- package/Timeline/PureTimeline/src/CursorPlugin.d.ts +1 -0
- package/Timeline/PureTimeline/src/CursorPlugin.d.ts.map +1 -1
- package/Timeline/PureTimeline/src/TimelineLegend.d.ts +10 -7
- package/Timeline/PureTimeline/src/TimelineLegend.d.ts.map +1 -1
- package/Timeline/PureTimeline/src/TimelineTooltip.d.ts +5 -1
- package/Timeline/PureTimeline/src/TimelineTooltip.d.ts.map +1 -1
- package/Timeline/PureTimeline/src/TimelineUplot.d.ts +19 -2
- package/Timeline/PureTimeline/src/TimelineUplot.d.ts.map +1 -1
- package/Timeline/PureTimeline/src/TimelineYAxis.d.ts.map +1 -1
- package/Timeline/PureTimeline/src/XAxisPlugin.d.ts +1 -0
- package/Timeline/PureTimeline/src/XAxisPlugin.d.ts.map +1 -1
- package/Timeline/PureTimeline/src/utils/timelineUtils.d.ts +8 -0
- package/Timeline/PureTimeline/src/utils/timelineUtils.d.ts.map +1 -1
- package/Timeline/Timeline.d.ts +3 -1
- package/Timeline/Timeline.d.ts.map +1 -1
- package/Timeline.config.js +2 -2
- package/Timeline.config.js.map +2 -2
- package/Timeline.js +713 -351
- package/Timeline.js.map +4 -4
- package/Treemap/PureTreemap/components/PureTreemap.d.ts +42 -0
- package/Treemap/PureTreemap/components/PureTreemap.d.ts.map +1 -0
- package/Treemap/PureTreemap/components/TreemapBreadcrumb.d.ts +10 -0
- package/Treemap/PureTreemap/components/TreemapBreadcrumb.d.ts.map +1 -0
- package/Treemap/PureTreemap/components/TreemapChildCell.d.ts +28 -0
- package/Treemap/PureTreemap/components/TreemapChildCell.d.ts.map +1 -0
- package/Treemap/PureTreemap/components/TreemapHeader.d.ts +19 -0
- package/Treemap/PureTreemap/components/TreemapHeader.d.ts.map +1 -0
- package/Treemap/PureTreemap/components/TreemapHoverTarget.d.ts +17 -0
- package/Treemap/PureTreemap/components/TreemapHoverTarget.d.ts.map +1 -0
- package/Treemap/PureTreemap/components/TreemapLegend.d.ts +20 -0
- package/Treemap/PureTreemap/components/TreemapLegend.d.ts.map +1 -0
- package/Treemap/PureTreemap/components/TreemapNode.d.ts +5 -0
- package/Treemap/PureTreemap/components/TreemapNode.d.ts.map +1 -0
- package/Treemap/PureTreemap/components/TreemapParentNode.d.ts +10 -0
- package/Treemap/PureTreemap/components/TreemapParentNode.d.ts.map +1 -0
- package/Treemap/PureTreemap/components/TreemapStandaloneNode.d.ts +6 -0
- package/Treemap/PureTreemap/components/TreemapStandaloneNode.d.ts.map +1 -0
- package/Treemap/PureTreemap/components/TreemapTooltip.d.ts +17 -0
- package/Treemap/PureTreemap/components/TreemapTooltip.d.ts.map +1 -0
- package/Treemap/PureTreemap/mockdata/data.d.ts +90 -0
- package/Treemap/PureTreemap/mockdata/data.d.ts.map +1 -0
- package/Treemap/PureTreemap/utils/treemapColorUtils.d.ts +67 -0
- package/Treemap/PureTreemap/utils/treemapColorUtils.d.ts.map +1 -0
- package/Treemap/PureTreemap/utils/treemapDataColorUtils.d.ts +5 -0
- package/Treemap/PureTreemap/utils/treemapDataColorUtils.d.ts.map +1 -0
- package/Treemap/PureTreemap/utils/treemapDataUtils.d.ts +14 -0
- package/Treemap/PureTreemap/utils/treemapDataUtils.d.ts.map +1 -0
- package/Treemap/PureTreemap/utils/treemapLayout.d.ts +49 -0
- package/Treemap/PureTreemap/utils/treemapLayout.d.ts.map +1 -0
- package/Treemap/PureTreemap/utils/treemapNodeUtils.d.ts +81 -0
- package/Treemap/PureTreemap/utils/treemapNodeUtils.d.ts.map +1 -0
- package/Treemap/PureTreemap/utils/treemapTypes.d.ts +37 -0
- package/Treemap/PureTreemap/utils/treemapTypes.d.ts.map +1 -0
- package/Treemap/PureTreemap/utils/treemapUtils.d.ts +76 -0
- package/Treemap/PureTreemap/utils/treemapUtils.d.ts.map +1 -0
- package/Treemap/Treemap.d.ts +14 -0
- package/Treemap/Treemap.d.ts.map +1 -0
- package/Treemap/config.d.ts +4 -0
- package/Treemap/config.d.ts.map +1 -0
- package/Treemap/index.d.ts +3 -0
- package/Treemap/index.d.ts.map +1 -0
- package/Treemap.config.js +465 -0
- package/Treemap.config.js.map +7 -0
- package/Treemap.js +6349 -0
- package/Treemap.js.map +7 -0
- package/common/Charting.js +8 -10
- package/common/Charting.js.map +2 -2
- package/common/ChartingApi.d.ts.map +1 -1
- package/common/ChartingApi.js +5 -2
- package/common/ChartingApi.js.map +2 -2
- package/common/DocExampleWithVizSandbox.js +3 -3
- package/common/DocExampleWithVizSandbox.js.map +2 -2
- package/common/GaugeMajorTicks.js.map +2 -2
- package/common/GaugeValueMarker.js +1 -0
- package/common/GaugeValueMarker.js.map +2 -2
- package/common/OptionsDoc.js +1 -1
- package/common/OptionsDoc.js.map +2 -2
- package/common/OverviewDoc.js +3 -3
- package/common/OverviewDoc.js.map +2 -2
- package/common/ThemesDoc.js.map +2 -2
- package/common/TimeSeriesChartWrapper.js +10 -9
- package/common/TimeSeriesChartWrapper.js.map +2 -2
- package/common/chartingUtils.d.ts.map +1 -1
- package/common/chartingUtils.js +12 -11
- package/common/chartingUtils.js.map +2 -2
- package/common/components/IconPlaceholder.d.ts.map +1 -1
- package/common/docUtils.d.ts.map +1 -1
- package/common/docUtils.js +16 -14
- package/common/docUtils.js.map +2 -2
- package/common/editorConfig/AxesChartDataDisplay.d.ts.map +1 -1
- package/common/gaugeUtils.d.ts.map +1 -1
- package/common/gaugeUtils.js +11 -5
- package/common/gaugeUtils.js.map +2 -2
- package/common/hocs/FixedSizeContainer.d.ts.map +1 -1
- package/common/hooks/useDynamicHeight.d.ts +67 -0
- package/common/hooks/useDynamicHeight.d.ts.map +1 -0
- package/common/hooks/useSorting.d.ts.map +1 -1
- package/common/interfaces/VizCategory.d.ts +2 -1
- package/common/interfaces/VizCategory.d.ts.map +1 -1
- package/common/interfaces/VizEvent.d.ts +7 -0
- package/common/interfaces/VizEvent.d.ts.map +1 -1
- package/common/utils/dataUtils.d.ts.map +1 -1
- package/common/utils/dataUtils.js +6 -10
- package/common/utils/dataUtils.js.map +2 -2
- package/common/utils/featureFlagUtils.js +2 -2
- package/common/utils/featureFlagUtils.js.map +2 -2
- package/common/utils/focusUtils.js +1 -1
- package/common/utils/focusUtils.js.map +2 -2
- package/common/utils/mapUtils.d.ts.map +1 -1
- package/common/utils/mapUtils.js +14 -18
- package/common/utils/mapUtils.js.map +2 -2
- package/common/utils/singleValueUtils.js +22 -25
- package/common/utils/singleValueUtils.js.map +2 -2
- package/common/utils/textUtils.d.ts.map +1 -1
- package/common/utils/textUtils.js +37 -23
- package/common/utils/textUtils.js.map +2 -2
- package/common/utils/trellisUtils.d.ts.map +1 -1
- package/common/utils/trellisUtils.js +18 -17
- package/common/utils/trellisUtils.js.map +2 -2
- package/common/utils/urlUtils.js.map +2 -2
- package/common/utils/visualizationTheme.d.ts +15 -0
- package/common/utils/visualizationTheme.d.ts.map +1 -0
- package/common/utils/visualizationTheme.js +72 -0
- package/common/utils/visualizationTheme.js.map +7 -0
- package/common/withDashboardViz.d.ts +3 -1
- package/common/withDashboardViz.d.ts.map +1 -1
- package/common/withDashboardViz.js +216 -105
- package/common/withDashboardViz.js.map +4 -4
- package/docs-llm/INDEX.md +1 -0
- package/docs-llm/area/options.md +84 -84
- package/docs-llm/bar/options.md +77 -77
- package/docs-llm/bubble/options.md +51 -51
- package/docs-llm/choropleth-svg/options.md +5 -5
- package/docs-llm/column/options.md +82 -82
- package/docs-llm/ellipse/options.md +6 -6
- package/docs-llm/events/options.md +6 -6
- package/docs-llm/filler-gauge/options.md +16 -16
- package/docs-llm/image/options.md +3 -3
- package/docs-llm/line/options.md +82 -82
- package/docs-llm/link-graph/options.md +16 -16
- package/docs-llm/map/options.md +12 -12
- package/docs-llm/markdown/options.md +7 -7
- package/docs-llm/marker-gauge/options.md +16 -16
- package/docs-llm/network-graph/options.md +39 -39
- package/docs-llm/parallel-coordinates/options.md +4 -4
- package/docs-llm/pie/examples-json.md +195 -0
- package/docs-llm/pie/examples-react.md +123 -0
- package/docs-llm/pie/options.md +23 -23
- package/docs-llm/process-tree/options.md +23 -22
- package/docs-llm/punchcard/options.md +23 -23
- package/docs-llm/pure-rich-text/options.md +6 -5
- package/docs-llm/rectangle/options.md +9 -9
- package/docs-llm/rich-text/options.md +6 -5
- package/docs-llm/sankey/options.md +9 -9
- package/docs-llm/scatter/options.md +57 -57
- package/docs-llm/single-value/options.md +39 -39
- package/docs-llm/single-value-icon/options.md +33 -33
- package/docs-llm/single-value-radial/options.md +31 -31
- package/docs-llm/table/options.md +14 -13
- package/docs-llm/timeline/options.md +17 -17
- package/docs-llm/treemap/examples-json.md +5 -0
- package/docs-llm/treemap/examples-react.md +5 -0
- package/docs-llm/treemap/options.md +26 -0
- package/docs-llm/treemap/overview.md +27 -0
- package/package.json +31 -30
package/common/gaugeUtils.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/common/gaugeUtils.ts", "esm-externals:lodash", "esm-externals:@splunk/visualizations-shared/colorConstants", "esm-externals:@splunk/visualizations-shared/numberUtils", "esm-externals:@splunk/ui-utils/i18n"],
|
|
4
|
-
"sourcesContent": ["import { chain, mapKeys, omit, uniqBy } from 'lodash';\nimport {\n SEMANTIC_SUCCESS,\n SEMANTIC_WARNING,\n SEMANTIC_ERROR,\n} from '@splunk/visualizations-shared/colorConstants';\nimport { formatNumber } from '@splunk/visualizations-shared/numberUtils';\nimport { _ } from '@splunk/ui-utils/i18n';\n\nexport const GAUGE_THICKNESS = 50;\nexport const FILL_THICKNESS = 38;\nconst GRADIENT_STOP_OFFSET_MIN = 0;\nconst GRADIENT_STOP_OFFSET_MAX = 100;\nconst DEFAULT_NUM_OF_TICKS = 5;\nconst MAX_TICK_LABEL_DECIMAL_PLACES = 5;\nconst MAX_VALUE_LABEL_DIGITS_WITHOUT_PERCENT = 6;\nconst MAX_VALUE_LABEL_DIGITS_WITH_PERCENT = 5;\n\n/**\n * get width for the whole gauge viz for horizontal or vertical view\n * @method getGaugeWidth\n * @param {Object} input\n * @param {Number} containerWidth\n * @param {String} orientation\n * @return {Number} width\n */\nexport const getGaugeWidth = ({ containerWidth, orientation }) =>\n orientation === 'vertical' ? GAUGE_THICKNESS : containerWidth * 0.8;\n\n/**\n * get height for the whole gauge viz for horizontal or vertical view\n * @method getGaugeHeight\n * @param {Object} input\n * @param {Number} containerHeight\n * @param {String} orientation\n * @return {Number} height\n */\nexport const getGaugeHeight = ({ containerHeight, orientation }) =>\n orientation === 'vertical' ? containerHeight * 0.8 : GAUGE_THICKNESS;\n\n/**\n * get how long the gauge shoud be.\n * In horizontal view, gauge length equals to gauge width. In vertical view, it equals to gauge height.\n * @method getGaugeLength\n * @param {Object} input\n * @param {Number} input.containerWidth\n * @param {Number} input.containerHeight\n * @param {String} input.orientation\n * @return {Number} gaugeLength\n */\nexport const getGaugeLength = ({ containerWidth, containerHeight, orientation }) =>\n orientation === 'vertical'\n ? getGaugeHeight({ containerHeight, orientation })\n : getGaugeWidth({ containerWidth, orientation });\n\n/**\n * get start x and y for rendering gauge\n * @method getGaugeStartPosition\n * @param {Object} input\n * @param {Number} containerWidth\n * @param {Number} containerHeight\n * @param {Number} gaugeLength\n * @param {String} orientation\n * @return {Object} position\n * @return {Number} position.gaugeStartX\n * @return {Number} position.gaugeStartY\n */\nexport const getGaugeStartPosition = ({ containerWidth, containerHeight, gaugeLength, orientation }) => {\n // for horizontal view\n let gaugeStartX = (containerWidth - gaugeLength) / 2.0;\n let gaugeStartY = (containerHeight - GAUGE_THICKNESS) / 2.0;\n\n if (orientation === 'vertical') {\n gaugeStartX = (containerWidth - GAUGE_THICKNESS) / 2.0;\n gaugeStartY = (containerHeight - gaugeLength) / 2.0;\n }\n\n return { gaugeStartX, gaugeStartY };\n};\n\n/**\n * get dimensions for the whole gauge viz,\n * which can be useful to calculate background bar and major ticks positions.\n * @method getGaugeDimensions\n * @param {Object} input\n * @param {Number} input.containerWidth\n * @param {Number} input.containerHeight\n * @param {String} input.orientation 'horizontal' or 'vertical'\n * @return {Object} gaugeDimensions\n * @return {Number} gaugeDimensions.gaugeLength how long the gauge shoud be in horizontal or vertical orientation.\n * @return {Number} gaugeDimensions.gaugeStartX start x to render gauge\n * @return {Number} gaugeDimensions.gaugeStartY start y to render gauge\n * @return {Number} gaugeDimensions.gaugeWidth natural width of gauge\n * @return {Number} gaugeDimensions.gaugeHeight natural height of gauge\n */\nexport const getGaugeDimensions = ({ containerWidth, containerHeight, orientation }) => {\n const gaugeLength = getGaugeLength({\n containerWidth,\n containerHeight,\n orientation,\n });\n const { gaugeStartX, gaugeStartY } = getGaugeStartPosition({\n containerWidth,\n containerHeight,\n gaugeLength,\n orientation,\n });\n const gaugeWidth = getGaugeWidth({ containerWidth, orientation });\n const gaugeHeight = getGaugeHeight({ containerHeight, orientation });\n\n return {\n gaugeLength,\n gaugeStartX,\n gaugeStartY,\n gaugeWidth,\n gaugeHeight,\n };\n};\n\n/**\n * if gaugeColor is not specified, auto assign a gauge color to the fill bar\n * based on how much percentage the value is taken between min and max\n * @method assignGaugeColor\n * @params\n * */\nexport const assignGaugeColor = ({ value, min, max }) => {\n const rate = (value - min) / (max - min);\n\n if (rate <= 0.3) {\n return SEMANTIC_SUCCESS;\n }\n if (rate > 0.3 && rate <= 0.6) {\n return SEMANTIC_WARNING;\n }\n\n return SEMANTIC_ERROR;\n};\n\n/**\n * get inner bar length in gauge\n * @method getGaugeBarLength\n * @param {Object} input\n * @param {Number} input.gaugeLength\n * @param {Number} input.value\n * @param {Number} input.min\n * @param {Number} input.max\n * @return {Number} gaugeBarLength\n */\nexport const getGaugeBarLength = ({ gaugeLength, value, min, max }) => {\n if (max < min) {\n return null;\n }\n\n if (value >= max) {\n return gaugeLength;\n }\n\n if (value < min) {\n return 0;\n }\n\n return (gaugeLength * (value - min)) / (max - min);\n};\n\n/**\n * get x and y position for rendering inner bar in gauge\n * @method getGaugeBarStartPositions\n * @param {Object} input\n * @param {Number} input.gaugeStartX\n * @param {Number} input.gaugeStartY\n * @param {Number} input.gaugeWidth\n * @param {Number} input.gaugeHeight\n * @param {Number} input.gaugeBarLength\n * @param {String} input.orientation\n * @return {Object} position\n * @return {Number} position.gaugeBarX\n * @return {Number} position.gaugeBarY\n */\nexport const getGaugeBarStartPositions = ({\n gaugeStartX,\n gaugeStartY,\n gaugeWidth,\n gaugeHeight,\n gaugeBarLength,\n orientation,\n}) => {\n let gaugeBarX = gaugeStartX;\n let gaugeBarY = gaugeStartY;\n\n if (orientation === 'vertical') {\n gaugeBarX += (gaugeWidth - FILL_THICKNESS) / 2;\n gaugeBarY += gaugeHeight - gaugeBarLength;\n } else {\n gaugeBarY += (gaugeHeight - FILL_THICKNESS) / 2;\n }\n\n return {\n gaugeBarX,\n gaugeBarY,\n };\n};\n\n/**\n * get width of inner bar in gauge\n * @method getGaugeBarWidth\n * @param {Object} input\n * @param {Number} input.gaugeBarLength\n * @param {String} orientation\n * @return {Number} gaugeBarWidth\n */\nexport const getGaugeBarWidth = ({ gaugeBarLength, orientation }) =>\n orientation === 'vertical' ? FILL_THICKNESS : gaugeBarLength;\n\n/**\n * get height of inner bar in gauge\n * @method getGaugeBarWidth\n * @param {Object} input\n * @param {Number} input.gaugeBarLength\n * @param {String} orientation\n * @return {Number} gaugeBarHeight\n */\nexport const getGaugeBarHeight = ({ gaugeBarLength, orientation }) =>\n orientation === 'vertical' ? gaugeBarLength : FILL_THICKNESS;\n\n/**\n * get dimensions for the fill bar in the gauge\n * @method getFillBarDimensions\n * @param {Object} input\n * @param {Number} input.gaugeLength\n * @param {Number} input.gaugeStartX\n * @param {Number} input.gaugeStartY\n * @param {Number} input.gaugeWidth,\n * @param {Number} input.gaugeHeight,\n * @param {Number} input.value,\n * @param {Number} input.min,\n * @param {Number} input.max,\n * @param {String} input.orientation\n * @return {Object} fillBarDimensions\n * @return {Number} fillBarDimensions.fillBarLength\n * @return {Number} fillBarDimensions.fillBarX\n * @return {Number} fillBarDimensions.fillBarY\n * @return {Number} fillBarDimensions.fillBarWidth\n * @return {Number} fillBarDimensions.fillBarHeight\n */\nexport const getFillBarDimensions = ({\n gaugeLength,\n gaugeStartX,\n gaugeStartY,\n gaugeWidth,\n gaugeHeight,\n value,\n min,\n max,\n orientation,\n}) => {\n const gaugeBarLength = getGaugeBarLength({ gaugeLength, value, max, min });\n const { gaugeBarX: fillBarX, gaugeBarY: fillBarY } = getGaugeBarStartPositions({\n gaugeStartX,\n gaugeStartY,\n gaugeWidth,\n gaugeHeight,\n gaugeBarLength,\n orientation,\n });\n const fillBarWidth = getGaugeBarWidth({ gaugeBarLength, orientation });\n const fillBarHeight = getGaugeBarHeight({ gaugeBarLength, orientation });\n\n return {\n fillBarLength: gaugeBarLength,\n fillBarX,\n fillBarY,\n fillBarWidth,\n fillBarHeight,\n };\n};\n\n/**\n * get position x and y for value marker in filler gauge\n * @method getFillerGaugeValueMarkerPositions\n * @param {Object} input\n * @param {Number} input.fillBarX\n * @param {Number} input.fillBarY\n * @param {Number} input.fillBarLength\n * @param {String} input.orientation\n * @return {Object} position\n * @return {Number} position.valueMarkerX\n * @return {Number} position.valueMarkerY\n */\nexport const getFillerGaugeValueMarkerPositions = ({ fillBarX, fillBarY, fillBarLength, orientation }) => {\n let valueMarkerX = fillBarX;\n let valueMarkerY = fillBarY;\n\n if (orientation === 'vertical') {\n valueMarkerX -= (GAUGE_THICKNESS - FILL_THICKNESS) / 4;\n } else {\n valueMarkerX += fillBarLength;\n valueMarkerY -= (GAUGE_THICKNESS - FILL_THICKNESS) / 4;\n }\n\n return {\n valueMarkerX,\n valueMarkerY,\n };\n};\n\n/**\n * get dimensions for the marker bar in the gauge\n * @method getMarkerBarDimensions\n * @param {Object} input\n * @param {Number} input.gaugeLength\n * @param {Number} input.gaugeStartX\n * @param {Number} input.gaugeStartY\n * @param {Number} input.gaugeWidth,\n * @param {Number} input.gaugeHeight,\n * @param {String} input.orientation\n * @return {Object} markerBarDimensions\n * @return {Number} markerBarDimensions.markerBarLength\n * @return {Number} markerBarDimensions.markerBarX\n * @return {Number} markerBarDimensions.markerBarY\n * @return {Number} markerBarDimensions.markerBarWidth\n * @return {Number} markerBarDimensions.markerBarHeight\n */\nexport const getMarkerBarDimensions = ({\n gaugeLength,\n gaugeStartX,\n gaugeStartY,\n gaugeWidth,\n gaugeHeight,\n orientation,\n}) => {\n const gaugeBarLength = gaugeLength; // For marker gauge, inner marker bar spans the entire gauge\n const { gaugeBarX: markerBarX, gaugeBarY: markerBarY } = getGaugeBarStartPositions({\n gaugeStartX,\n gaugeStartY,\n gaugeWidth,\n gaugeHeight,\n gaugeBarLength,\n orientation,\n });\n const markerBarWidth = getGaugeBarWidth({ gaugeBarLength, orientation });\n const markerBarHeight = getGaugeBarHeight({ gaugeBarLength, orientation });\n\n return {\n markerBarLength: gaugeBarLength,\n markerBarX,\n markerBarY,\n markerBarWidth,\n markerBarHeight,\n };\n};\n\n/**\n * get position x and y for value marker in marker gauge\n * @method getMarkerGaugeValueMarkerPositions\n * @param {Object} input\n * @param {Number} input.markerBarX\n * @param {Number} input.markerBarY\n * @param {Number} input.markerBarHeight\n * @param {Number} input.markerBarLength\n * @param {Number} input.value\n * @param {Number} input.min\n * @param {Number} input.max\n * @param {String} input.orientation\n * @return {Object} position\n * @return {Number} position.valueMarkerX\n * @return {Number} position.valueMarkerY\n */\nexport const getMarkerGaugeValueMarkerPositions = ({\n markerBarX,\n markerBarY,\n markerBarHeight,\n markerBarLength: gaugeLength,\n orientation,\n value,\n min,\n max,\n}) => {\n let valueMarkerX = markerBarX;\n let valueMarkerY = markerBarY;\n if (orientation === 'vertical') {\n valueMarkerY += markerBarHeight - getGaugeBarLength({ gaugeLength, value, max, min });\n valueMarkerX -= (GAUGE_THICKNESS - FILL_THICKNESS) / 4;\n } else {\n valueMarkerX += getGaugeBarLength({ gaugeLength, value, max, min });\n valueMarkerY -= (GAUGE_THICKNESS - FILL_THICKNESS) / 4;\n }\n\n return {\n valueMarkerX,\n valueMarkerY,\n };\n};\n\n/**\n * sort the ranges in ascending order\n * @method getSortedRanges\n * @param {Array} ranges\n * @return {Array} sortedRanges\n */\nexport const getSortedRanges = ranges => ranges.sort((a, b) => a.from - b.from);\n\n/**\n * validate whether ranges prop is valid - continuous ranges, range.to < range.from, range.from != range.to\n * @method validateRanges\n * @param {Array} ranges\n * @return {String} error\n */\nexport const validateRanges = ranges => {\n if (!ranges.length) {\n return _('Prop \"ranges\" is missing entries');\n }\n\n // check whether a range has \"from\" >= \"to\" eg: 10 - 10, 100 - 10, -20 - -10 are invalid\n if (ranges.some(range => range.from >= range.to)) {\n return _('Prop \"ranges\" has invalid entries: invalid range');\n }\n\n // check whether ranges have duplicate \"from/to\" eg: 0 - 50, 25 - 50\n if (ranges.length !== uniqBy(ranges, 'to').length || ranges.length !== uniqBy(ranges, 'from').length) {\n return _('Prop \"ranges\" has invalid entries: duplicate values');\n }\n\n const sortedRanges = getSortedRanges(ranges);\n\n // check whether ranges are continuous eg: 0 - 10, 10 - 20, 20 - 30\n for (let i = 1; i < sortedRanges.length; i += 1) {\n if (sortedRanges[i].from !== sortedRanges[i - 1].to) {\n return _('Prop \"ranges\" has invalid entries: discontinuous ranges');\n }\n }\n\n return null;\n};\n\n/**\n * calculate min and max value of gauge\n * @method getGaugeRange\n * @param {Array} ranges\n * @return {Object} gaugeRange\n * @return {Number} gaugeRange.min\n * @return {Number} gaugeRange.max\n */\nexport const getGaugeRange = ranges => {\n const min = Math.min(...ranges.map(range => range.from));\n const max = Math.max(...ranges.map(range => range.to));\n return { min, max };\n};\n\n/**\n * calculate stop offsets for linear gradient\n * @method getGradientStopOffsets\n * @param {Array} ranges\n * @param {String} orientation\n * @return {Array} cumulativeOffsets\n */\nexport const getGradientStopOffsets = ({ ranges, orientation }) => {\n const { min, max } = getGaugeRange(ranges);\n const offsetScale = (GRADIENT_STOP_OFFSET_MAX - GRADIENT_STOP_OFFSET_MIN) / (max - min);\n let offsets = ranges.map(range => Math.abs(range.from - range.to) * offsetScale);\n // When orientation is vertical, since the gauge starts from bottom to top, linear gradient should be reversed\n offsets = orientation === 'vertical' ? offsets.reverse() : offsets;\n const cumulativeOffsets = [];\n offsets.reduce((accumulator, currentValue, idx) => {\n cumulativeOffsets[idx] = accumulator + currentValue;\n return cumulativeOffsets[idx];\n }, 0);\n return cumulativeOffsets;\n};\n\n/**\n * calculate stop colors for linear gradient\n * @method getGradientStopColors\n * @param {Array} ranges\n * @param {String} orientation\n * @return {Array} stopColors\n */\nexport const getGradientStopColors = ({ ranges, orientation }) => {\n const stopColors = ranges.map(range => range.value);\n // When orientation is vertical, since the gauge starts from bottom to top, linear gradient should be reversed\n return orientation === 'vertical' ? stopColors.reverse() : stopColors;\n};\n\n/**\n * calculate linear gradient stops from ranges\n * @method getGradientStops\n * @param {Object} input\n * @param {Array} ranges\n * @param {String} orientation\n * @return {Array} stops\n */\nexport const getGradientStops = ({ ranges, orientation }) => {\n const stops = [];\n const offsets = getGradientStopOffsets({ ranges, orientation });\n const stopColors = getGradientStopColors({ ranges, orientation });\n // Initialize stops with the first color stop\n stops.push({ offset: `${offsets[0]}%`, stopColor: stopColors[0] });\n // Add the remaining color stops with gradient change at each stop\n for (let i = 1; i < ranges.length; i += 1) {\n stops.push({ offset: `${offsets[i - 1]}%`, stopColor: stopColors[i] });\n stops.push({ offset: `${offsets[i]}%`, stopColor: stopColors[i] });\n }\n return stops;\n};\n\n/**\n * calculate linear gradient dimensions\n * @method getGradientDimensions\n * @param {String} orientation\n * @return {Object} dimensions\n * @return {String} dimensions.x1\n * @return {String} dimensions.y1\n * @return {String} dimensions.x2\n * @return {String} dimensions.y2\n */\nexport const getGradientDimensions = orientation => {\n const x1 = '0%';\n const y1 = '0%';\n const x2 = orientation === 'horizontal' ? '100%' : '0%';\n const y2 = orientation === 'horizontal' ? '0%' : '100%';\n return { x1, y1, x2, y2 };\n};\n\ntype NumericInput = number | string;\n\ninterface UniqueDecimalPlacesInput {\n values: number[];\n minimumDecimalPlaces: number;\n}\n\ninterface PercentageFromRangeInput {\n value: number;\n min: number;\n range: number;\n}\n\ninterface NumOfTicksInput {\n min: number;\n max: number;\n majorUnit: number | string;\n usePercentageRange: boolean;\n}\n\ninterface TickLabelFormatterResult {\n numOfTicks: number;\n numericStep: number;\n formatTickLabel: (value: number) => string;\n}\n\ninterface FormatGaugeValueLabelInput {\n value: NumericInput;\n min: number;\n max: number;\n usePercentageValue: boolean;\n}\n\n// Returns the number of fractional digits in a numeric input.\nexport const getDecimalPlaces = (value: NumericInput): number => {\n const numericValue = Number(value);\n if (!Number.isFinite(numericValue)) {\n return 0;\n }\n\n const fractionPart = numericValue.toString().split('.')[1];\n return fractionPart ? fractionPart.length : 0;\n};\n\n// Finds the smallest precision that keeps all rounded tick values unique.\n// This avoids duplicated rendered labels caused by rounding collisions.\nexport const getUniqueDecimalPlaces = ({\n values,\n minimumDecimalPlaces,\n}: UniqueDecimalPlacesInput): number => {\n if (values.length <= 1) {\n return minimumDecimalPlaces;\n }\n\n for (\n let decimalPlaces = minimumDecimalPlaces;\n decimalPlaces <= MAX_TICK_LABEL_DECIMAL_PLACES;\n decimalPlaces += 1\n ) {\n const roundedValues = values.map(value => Number(value.toFixed(decimalPlaces)));\n if (new Set(roundedValues).size === roundedValues.length) {\n return decimalPlaces;\n }\n }\n\n return MAX_TICK_LABEL_DECIMAL_PLACES;\n};\n\n// Converts a value within [min, max] to percentage space.\nexport const getPercentageFromRange = ({ value, min, range }: PercentageFromRangeInput): number => {\n if (range === 0) {\n return 0;\n }\n return ((value - min) / range) * 100;\n};\n\n// Computes interval count from auto mode or explicit majorUnit.\nexport const getNumOfTicks = ({\n min,\n max,\n majorUnit,\n usePercentageRange,\n}: NumOfTicksInput): { numOfTicks: number; isAutoMajorUnit: boolean; majorUnitNumber: number } => {\n const range = max - min;\n const majorUnitNumber = Number(majorUnit);\n const isAutoMajorUnit = majorUnit === 'auto' || Number.isNaN(majorUnitNumber) || majorUnitNumber <= 0;\n\n let numOfTicks = DEFAULT_NUM_OF_TICKS;\n if (!isAutoMajorUnit) {\n numOfTicks = usePercentageRange ? 100 / majorUnitNumber : range / majorUnitNumber;\n }\n\n return { numOfTicks, isAutoMajorUnit, majorUnitNumber };\n};\n\n// Builds a reusable formatter and step size for major tick rendering.\nexport const getTickLabelFormatter = ({\n min,\n max,\n majorUnit,\n usePercentageRange,\n}: NumOfTicksInput): TickLabelFormatterResult => {\n const range = max - min;\n const { numOfTicks, isAutoMajorUnit, majorUnitNumber } = getNumOfTicks({\n min,\n max,\n majorUnit,\n usePercentageRange,\n });\n const numericStep = range / numOfTicks;\n const tickValues = [];\n\n // Materialize all candidate tick values (plus max for uneven divisions).\n for (let i = 0; i <= numOfTicks; i += 1) {\n tickValues.push(min + numericStep * i);\n }\n\n if (!Number.isInteger(numOfTicks)) {\n tickValues.push(max);\n }\n\n const minimumNumericDecimalPlaces = Math.min(\n MAX_TICK_LABEL_DECIMAL_PLACES,\n Math.max(\n getDecimalPlaces(min),\n getDecimalPlaces(max),\n isAutoMajorUnit ? 0 : getDecimalPlaces(majorUnitNumber)\n )\n );\n const numericLabelDecimalPlaces = getUniqueDecimalPlaces({\n values: tickValues,\n minimumDecimalPlaces: minimumNumericDecimalPlaces,\n });\n const percentageLabelDecimalPlaces = getUniqueDecimalPlaces({\n values: tickValues.map(value => getPercentageFromRange({ value, min, range })),\n minimumDecimalPlaces: 0,\n });\n\n // Keep fixed-width decimal formatting when decimals are needed; otherwise use trend formatting.\n const formatTickLabel = value => {\n if (usePercentageRange) {\n const percentageValue = getPercentageFromRange({ value, min, range });\n return `${percentageValue.toFixed(percentageLabelDecimalPlaces)}%`;\n }\n\n const numericLabel = value.toFixed(numericLabelDecimalPlaces);\n if (numericLabel.includes('.')) {\n return numericLabel;\n }\n\n return formatNumber(Number(numericLabel), 0, {\n useThousandSeparators: true,\n useTrendUnits: true,\n }).replace(/k$/, 'K');\n };\n\n return { numOfTicks, numericStep, formatTickLabel };\n};\n\n// Limits decimal places so displayed value length stays within a fixed digit budget.\nconst getDigitsBeforeDecimal = (numericValue: NumericInput): number =>\n Math.abs(Math.trunc(Number(numericValue))).toString().length;\n\nconst getCappedDecimalPlaces = (\n numericValue: NumericInput,\n rawDecimalPlaces: number,\n maxDigits: number\n): number => {\n const digitsBeforeDecimal = getDigitsBeforeDecimal(numericValue);\n const maxDecimalPlaces = Math.max(0, maxDigits - digitsBeforeDecimal);\n return Math.min(rawDecimalPlaces, maxDecimalPlaces);\n};\n\n// Formats the marker value label in number or percentage mode with capped precision.\nexport const formatGaugeValueLabel = ({\n value,\n min,\n max,\n usePercentageValue,\n}: FormatGaugeValueLabelInput): string => {\n const numericValue = Number(value);\n const range = max - min || 1;\n const percentageValue = getPercentageFromRange({ value: numericValue, min, range });\n const trendFormatOptions = {\n useThousandSeparators: true,\n useTrendUnits: true,\n };\n\n if (usePercentageValue) {\n // Use the same number-mode formatting behavior (including K/M/B/T) for percentages.\n const percentageDecimalPlaces = getCappedDecimalPlaces(\n percentageValue,\n 2,\n MAX_VALUE_LABEL_DIGITS_WITH_PERCENT\n );\n return `${formatNumber(percentageValue, percentageDecimalPlaces, trendFormatOptions)}%`;\n }\n\n const valueDecimalPlaces = getCappedDecimalPlaces(\n numericValue,\n getDecimalPlaces(numericValue),\n MAX_VALUE_LABEL_DIGITS_WITHOUT_PERCENT\n );\n return formatNumber(numericValue, valueDecimalPlaces, trendFormatOptions);\n};\n\ninterface GaugeOptions {\n [key: string]: any;\n}\n\n// map for new options names to old option names\nconst gaugeOptionsMapping = {\n majorTickInterval: 'majorUnit',\n gaugeRanges: 'ranges',\n};\n\n/**\n * Helper method to update the option names which can be mapped to pure component options\n * @method mapToOldKey\n * @param {Object} options\n * @returns {Object}\n */\nexport const mapToOldKey = (options: GaugeOptions): GaugeOptions =>\n mapKeys(options, (val, key) => (gaugeOptionsMapping[key] ? gaugeOptionsMapping[key] : key));\n\ntype LabelOrValue = 'label' | 'value';\n\n/**\n * Helper method to map labelDisplay and valueDisplay options to pure component option names\n * @method mapToOldKey\n * @param {string} labelOrValue\n * @param {Object} options\n * @returns {Object}\n */\nexport const mapValueLabelDisplay = (labelOrValue: LabelOrValue, options: GaugeOptions): GaugeOptions => {\n const rangeOrValue: string = labelOrValue === 'value' ? 'Value' : 'Range';\n const showKey: string = labelOrValue === 'value' ? 'showValue' : 'showLabels';\n const percentKey = `usePercentage${rangeOrValue}`;\n const optionString = `${labelOrValue}Display`;\n const newOptions = { ...options };\n if (newOptions[optionString]) {\n if (newOptions[optionString] === 'number') {\n newOptions[showKey] = true;\n newOptions[percentKey] = false;\n } else if (newOptions[optionString] === 'percentage') {\n newOptions[showKey] = true;\n newOptions[percentKey] = true;\n } else {\n newOptions[showKey] = false;\n newOptions[percentKey] = false;\n }\n }\n return omit(newOptions, [optionString]);\n};\n\n/**\n * Chained helper for mapping the option properties (and values) we expose in config.ts into property values that pure component accepts\n * This is for options that has new key name and can not directly be mapped with pure component props\n * @method convertToGaugeProperties\n * @param {Object} originalOptions\n * @returns {Object}\n */\nexport const convertToGaugeProperties = (originalOptions: GaugeOptions): GaugeOptions =>\n chain(mapToOldKey(originalOptions))\n .thru(options => mapValueLabelDisplay('label', options))\n .thru(options => mapValueLabelDisplay('value', options))\n .value();\n", "\nimport * as defaultImport from \"lodash\";\nexport * from \"lodash\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/visualizations-shared/colorConstants\";\nexport * from \"@splunk/visualizations-shared/colorConstants\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/visualizations-shared/numberUtils\";\nexport * from \"@splunk/visualizations-shared/numberUtils\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/ui-utils/i18n\";\nexport * from \"@splunk/ui-utils/i18n\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AACA,oBAA+B;AAC/B,2BAAc;AACd,IAAO,iBAAS,aAAa,gBAA8B,wBAAU;;;ACHrE;AAAA;AAAA;AAAA;AACA,IAAAA,iBAA+B;AAC/B,mCAAc;AACd,IAAO,yBAAS,aAAaA,iBAA8B,yBAAUA;;;ACHrE;AAAA;AAAA;AAAA;AACA,IAAAC,iBAA+B;AAC/B,gCAAc;AACd,IAAO,sBAAS,aAAaA,iBAA8B,yBAAUA;;;ACHrE;AAAA;AAAA;AAAA;AACA,IAAAC,iBAA+B;AAC/B,yBAAc;AACd,IAAO,eAAS,aAAaA,iBAA8B,yBAAUA;;;AJM9D,IAAM,kBAAkB;AACxB,IAAM,iBAAiB;AAC9B,IAAM,2BAA2B;AACjC,IAAM,2BAA2B;AACjC,IAAM,uBAAuB;AAC7B,IAAM,gCAAgC;AACtC,IAAM,yCAAyC;AAC/C,IAAM,sCAAsC;AAUrC,IAAM,gBAAgB,CAAC,EAAE,gBAAgB,YAAY,MACxD,gBAAgB,aAAa,kBAAkB,iBAAiB;AAU7D,IAAM,iBAAiB,CAAC,EAAE,iBAAiB,YAAY,MAC1D,gBAAgB,aAAa,kBAAkB,MAAM;AAYlD,IAAM,iBAAiB,CAAC,EAAE,gBAAgB,iBAAiB,YAAY,MAC1E,gBAAgB,aACV,eAAe,EAAE,iBAAiB,YAAY,CAAC,IAC/C,cAAc,EAAE,gBAAgB,YAAY,CAAC;AAchD,IAAM,wBAAwB,CAAC,EAAE,gBAAgB,iBAAiB,aAAa,YAAY,MAAM;AAEpG,MAAI,eAAe,iBAAiB,eAAe;AACnD,MAAI,eAAe,kBAAkB,mBAAmB;AAExD,MAAI,gBAAgB,YAAY;AAC5B,mBAAe,iBAAiB,mBAAmB;AACnD,mBAAe,kBAAkB,eAAe;AAAA,EACpD;AAEA,SAAO,EAAE,aAAa,YAAY;AACtC;AAiBO,IAAM,qBAAqB,CAAC,EAAE,gBAAgB,iBAAiB,YAAY,MAAM;AACpF,QAAM,cAAc,eAAe;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,EACJ,CAAC;AACD,QAAM,EAAE,aAAa,YAAY,IAAI,sBAAsB;AAAA,IACvD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ,CAAC;AACD,QAAM,aAAa,cAAc,EAAE,gBAAgB,YAAY,CAAC;AAChE,QAAM,cAAc,eAAe,EAAE,iBAAiB,YAAY,CAAC;AAEnE,SAAO;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACJ;AACJ;AAQO,IAAM,mBAAmB,CAAC,EAAE,OAAO,KAAK,IAAI,MAAM;AACrD,QAAM,QAAQ,QAAQ,QAAQ,MAAM;AAEpC,MAAI,QAAQ,KAAK;AACb,WAAO;AAAA,EACX;AACA,MAAI,OAAO,OAAO,QAAQ,KAAK;AAC3B,WAAO;AAAA,EACX;AAEA,SAAO;AACX;AAYO,IAAM,oBAAoB,CAAC,EAAE,aAAa,OAAO,KAAK,IAAI,MAAM;AACnE,MAAI,MAAM,KAAK;AACX,WAAO;AAAA,EACX;AAEA,MAAI,SAAS,KAAK;
|
|
4
|
+
"sourcesContent": ["import { chain, mapKeys, omit, uniqBy } from 'lodash';\nimport {\n SEMANTIC_SUCCESS,\n SEMANTIC_WARNING,\n SEMANTIC_ERROR,\n} from '@splunk/visualizations-shared/colorConstants';\nimport { formatNumber } from '@splunk/visualizations-shared/numberUtils';\nimport { _ } from '@splunk/ui-utils/i18n';\n\nexport const GAUGE_THICKNESS = 50;\nexport const FILL_THICKNESS = 38;\nconst GRADIENT_STOP_OFFSET_MIN = 0;\nconst GRADIENT_STOP_OFFSET_MAX = 100;\nconst DEFAULT_NUM_OF_TICKS = 5;\nconst MAX_TICK_LABEL_DECIMAL_PLACES = 5;\nconst MAX_VALUE_LABEL_DIGITS_WITHOUT_PERCENT = 6;\nconst MAX_VALUE_LABEL_DIGITS_WITH_PERCENT = 5;\n\n/**\n * get width for the whole gauge viz for horizontal or vertical view\n * @method getGaugeWidth\n * @param {Object} input\n * @param {Number} containerWidth\n * @param {String} orientation\n * @return {Number} width\n */\nexport const getGaugeWidth = ({ containerWidth, orientation }) =>\n orientation === 'vertical' ? GAUGE_THICKNESS : containerWidth * 0.8;\n\n/**\n * get height for the whole gauge viz for horizontal or vertical view\n * @method getGaugeHeight\n * @param {Object} input\n * @param {Number} containerHeight\n * @param {String} orientation\n * @return {Number} height\n */\nexport const getGaugeHeight = ({ containerHeight, orientation }) =>\n orientation === 'vertical' ? containerHeight * 0.8 : GAUGE_THICKNESS;\n\n/**\n * get how long the gauge shoud be.\n * In horizontal view, gauge length equals to gauge width. In vertical view, it equals to gauge height.\n * @method getGaugeLength\n * @param {Object} input\n * @param {Number} input.containerWidth\n * @param {Number} input.containerHeight\n * @param {String} input.orientation\n * @return {Number} gaugeLength\n */\nexport const getGaugeLength = ({ containerWidth, containerHeight, orientation }) =>\n orientation === 'vertical'\n ? getGaugeHeight({ containerHeight, orientation })\n : getGaugeWidth({ containerWidth, orientation });\n\n/**\n * get start x and y for rendering gauge\n * @method getGaugeStartPosition\n * @param {Object} input\n * @param {Number} containerWidth\n * @param {Number} containerHeight\n * @param {Number} gaugeLength\n * @param {String} orientation\n * @return {Object} position\n * @return {Number} position.gaugeStartX\n * @return {Number} position.gaugeStartY\n */\nexport const getGaugeStartPosition = ({ containerWidth, containerHeight, gaugeLength, orientation }) => {\n // for horizontal view\n let gaugeStartX = (containerWidth - gaugeLength) / 2;\n let gaugeStartY = (containerHeight - GAUGE_THICKNESS) / 2;\n\n if (orientation === 'vertical') {\n gaugeStartX = (containerWidth - GAUGE_THICKNESS) / 2;\n gaugeStartY = (containerHeight - gaugeLength) / 2;\n }\n\n return { gaugeStartX, gaugeStartY };\n};\n\n/**\n * get dimensions for the whole gauge viz,\n * which can be useful to calculate background bar and major ticks positions.\n * @method getGaugeDimensions\n * @param {Object} input\n * @param {Number} input.containerWidth\n * @param {Number} input.containerHeight\n * @param {String} input.orientation 'horizontal' or 'vertical'\n * @return {Object} gaugeDimensions\n * @return {Number} gaugeDimensions.gaugeLength how long the gauge shoud be in horizontal or vertical orientation.\n * @return {Number} gaugeDimensions.gaugeStartX start x to render gauge\n * @return {Number} gaugeDimensions.gaugeStartY start y to render gauge\n * @return {Number} gaugeDimensions.gaugeWidth natural width of gauge\n * @return {Number} gaugeDimensions.gaugeHeight natural height of gauge\n */\nexport const getGaugeDimensions = ({ containerWidth, containerHeight, orientation }) => {\n const gaugeLength = getGaugeLength({\n containerWidth,\n containerHeight,\n orientation,\n });\n const { gaugeStartX, gaugeStartY } = getGaugeStartPosition({\n containerWidth,\n containerHeight,\n gaugeLength,\n orientation,\n });\n const gaugeWidth = getGaugeWidth({ containerWidth, orientation });\n const gaugeHeight = getGaugeHeight({ containerHeight, orientation });\n\n return {\n gaugeLength,\n gaugeStartX,\n gaugeStartY,\n gaugeWidth,\n gaugeHeight,\n };\n};\n\n/**\n * if gaugeColor is not specified, auto assign a gauge color to the fill bar\n * based on how much percentage the value is taken between min and max\n * @method assignGaugeColor\n * @params\n * */\nexport const assignGaugeColor = ({ value, min, max }) => {\n const rate = (value - min) / (max - min);\n\n if (rate <= 0.3) {\n return SEMANTIC_SUCCESS;\n }\n if (rate > 0.3 && rate <= 0.6) {\n return SEMANTIC_WARNING;\n }\n\n return SEMANTIC_ERROR;\n};\n\n/**\n * get inner bar length in gauge\n * @method getGaugeBarLength\n * @param {Object} input\n * @param {Number} input.gaugeLength\n * @param {Number} input.value\n * @param {Number} input.min\n * @param {Number} input.max\n * @return {Number} gaugeBarLength\n */\nexport const getGaugeBarLength = ({ gaugeLength, value, min, max }) => {\n if (max < min) {\n return null;\n }\n\n const numericValue = Number(value);\n\n if (!Number.isFinite(numericValue)) {\n return 0;\n }\n\n if (numericValue >= max) {\n return gaugeLength;\n }\n\n if (numericValue < min) {\n return 0;\n }\n\n return (gaugeLength * (numericValue - min)) / (max - min);\n};\n\n/**\n * get x and y position for rendering inner bar in gauge\n * @method getGaugeBarStartPositions\n * @param {Object} input\n * @param {Number} input.gaugeStartX\n * @param {Number} input.gaugeStartY\n * @param {Number} input.gaugeWidth\n * @param {Number} input.gaugeHeight\n * @param {Number} input.gaugeBarLength\n * @param {String} input.orientation\n * @return {Object} position\n * @return {Number} position.gaugeBarX\n * @return {Number} position.gaugeBarY\n */\nexport const getGaugeBarStartPositions = ({\n gaugeStartX,\n gaugeStartY,\n gaugeWidth,\n gaugeHeight,\n gaugeBarLength,\n orientation,\n}) => {\n let gaugeBarX = gaugeStartX;\n let gaugeBarY = gaugeStartY;\n\n if (orientation === 'vertical') {\n gaugeBarX += (gaugeWidth - FILL_THICKNESS) / 2;\n gaugeBarY += gaugeHeight - gaugeBarLength;\n } else {\n gaugeBarY += (gaugeHeight - FILL_THICKNESS) / 2;\n }\n\n return {\n gaugeBarX,\n gaugeBarY,\n };\n};\n\n/**\n * get width of inner bar in gauge\n * @method getGaugeBarWidth\n * @param {Object} input\n * @param {Number} input.gaugeBarLength\n * @param {String} orientation\n * @return {Number} gaugeBarWidth\n */\nexport const getGaugeBarWidth = ({ gaugeBarLength, orientation }) =>\n orientation === 'vertical' ? FILL_THICKNESS : gaugeBarLength;\n\n/**\n * get height of inner bar in gauge\n * @method getGaugeBarWidth\n * @param {Object} input\n * @param {Number} input.gaugeBarLength\n * @param {String} orientation\n * @return {Number} gaugeBarHeight\n */\nexport const getGaugeBarHeight = ({ gaugeBarLength, orientation }) =>\n orientation === 'vertical' ? gaugeBarLength : FILL_THICKNESS;\n\n/**\n * get dimensions for the fill bar in the gauge\n * @method getFillBarDimensions\n * @param {Object} input\n * @param {Number} input.gaugeLength\n * @param {Number} input.gaugeStartX\n * @param {Number} input.gaugeStartY\n * @param {Number} input.gaugeWidth,\n * @param {Number} input.gaugeHeight,\n * @param {Number} input.value,\n * @param {Number} input.min,\n * @param {Number} input.max,\n * @param {String} input.orientation\n * @return {Object} fillBarDimensions\n * @return {Number} fillBarDimensions.fillBarLength\n * @return {Number} fillBarDimensions.fillBarX\n * @return {Number} fillBarDimensions.fillBarY\n * @return {Number} fillBarDimensions.fillBarWidth\n * @return {Number} fillBarDimensions.fillBarHeight\n */\nexport const getFillBarDimensions = ({\n gaugeLength,\n gaugeStartX,\n gaugeStartY,\n gaugeWidth,\n gaugeHeight,\n value,\n min,\n max,\n orientation,\n}) => {\n const gaugeBarLength = getGaugeBarLength({ gaugeLength, value, max, min });\n const { gaugeBarX: fillBarX, gaugeBarY: fillBarY } = getGaugeBarStartPositions({\n gaugeStartX,\n gaugeStartY,\n gaugeWidth,\n gaugeHeight,\n gaugeBarLength,\n orientation,\n });\n const fillBarWidth = getGaugeBarWidth({ gaugeBarLength, orientation });\n const fillBarHeight = getGaugeBarHeight({ gaugeBarLength, orientation });\n\n return {\n fillBarLength: gaugeBarLength,\n fillBarX,\n fillBarY,\n fillBarWidth,\n fillBarHeight,\n };\n};\n\n/**\n * get position x and y for value marker in filler gauge\n * @method getFillerGaugeValueMarkerPositions\n * @param {Object} input\n * @param {Number} input.fillBarX\n * @param {Number} input.fillBarY\n * @param {Number} input.fillBarLength\n * @param {String} input.orientation\n * @return {Object} position\n * @return {Number} position.valueMarkerX\n * @return {Number} position.valueMarkerY\n */\nexport const getFillerGaugeValueMarkerPositions = ({ fillBarX, fillBarY, fillBarLength, orientation }) => {\n let valueMarkerX = fillBarX;\n let valueMarkerY = fillBarY;\n\n if (orientation === 'vertical') {\n valueMarkerX -= (GAUGE_THICKNESS - FILL_THICKNESS) / 4;\n } else {\n valueMarkerX += fillBarLength;\n valueMarkerY -= (GAUGE_THICKNESS - FILL_THICKNESS) / 4;\n }\n\n return {\n valueMarkerX,\n valueMarkerY,\n };\n};\n\n/**\n * get dimensions for the marker bar in the gauge\n * @method getMarkerBarDimensions\n * @param {Object} input\n * @param {Number} input.gaugeLength\n * @param {Number} input.gaugeStartX\n * @param {Number} input.gaugeStartY\n * @param {Number} input.gaugeWidth,\n * @param {Number} input.gaugeHeight,\n * @param {String} input.orientation\n * @return {Object} markerBarDimensions\n * @return {Number} markerBarDimensions.markerBarLength\n * @return {Number} markerBarDimensions.markerBarX\n * @return {Number} markerBarDimensions.markerBarY\n * @return {Number} markerBarDimensions.markerBarWidth\n * @return {Number} markerBarDimensions.markerBarHeight\n */\nexport const getMarkerBarDimensions = ({\n gaugeLength,\n gaugeStartX,\n gaugeStartY,\n gaugeWidth,\n gaugeHeight,\n orientation,\n}) => {\n const gaugeBarLength = gaugeLength; // For marker gauge, inner marker bar spans the entire gauge\n const { gaugeBarX: markerBarX, gaugeBarY: markerBarY } = getGaugeBarStartPositions({\n gaugeStartX,\n gaugeStartY,\n gaugeWidth,\n gaugeHeight,\n gaugeBarLength,\n orientation,\n });\n const markerBarWidth = getGaugeBarWidth({ gaugeBarLength, orientation });\n const markerBarHeight = getGaugeBarHeight({ gaugeBarLength, orientation });\n\n return {\n markerBarLength: gaugeBarLength,\n markerBarX,\n markerBarY,\n markerBarWidth,\n markerBarHeight,\n };\n};\n\n/**\n * get position x and y for value marker in marker gauge\n * @method getMarkerGaugeValueMarkerPositions\n * @param {Object} input\n * @param {Number} input.markerBarX\n * @param {Number} input.markerBarY\n * @param {Number} input.markerBarHeight\n * @param {Number} input.markerBarLength\n * @param {Number} input.value\n * @param {Number} input.min\n * @param {Number} input.max\n * @param {String} input.orientation\n * @return {Object} position\n * @return {Number} position.valueMarkerX\n * @return {Number} position.valueMarkerY\n */\nexport const getMarkerGaugeValueMarkerPositions = ({\n markerBarX,\n markerBarY,\n markerBarHeight,\n markerBarLength: gaugeLength,\n orientation,\n value,\n min,\n max,\n}) => {\n let valueMarkerX = markerBarX;\n let valueMarkerY = markerBarY;\n if (orientation === 'vertical') {\n valueMarkerY += markerBarHeight - getGaugeBarLength({ gaugeLength, value, max, min });\n valueMarkerX -= (GAUGE_THICKNESS - FILL_THICKNESS) / 4;\n } else {\n valueMarkerX += getGaugeBarLength({ gaugeLength, value, max, min });\n valueMarkerY -= (GAUGE_THICKNESS - FILL_THICKNESS) / 4;\n }\n\n return {\n valueMarkerX,\n valueMarkerY,\n };\n};\n\n/**\n * sort the ranges in ascending order\n * @method getSortedRanges\n * @param {Array} ranges\n * @return {Array} sortedRanges\n */\nexport const getSortedRanges = ranges => ranges.sort((a, b) => a.from - b.from);\n\n/**\n * validate whether ranges prop is valid - continuous ranges, range.to < range.from, range.from != range.to\n * @method validateRanges\n * @param {Array} ranges\n * @return {String} error\n */\nexport const validateRanges = ranges => {\n if (!ranges.length) {\n return _('Prop \"ranges\" is missing entries');\n }\n\n // check whether a range has \"from\" >= \"to\" eg: 10 - 10, 100 - 10, -20 - -10 are invalid\n if (ranges.some(range => range.from >= range.to)) {\n return _('Prop \"ranges\" has invalid entries: invalid range');\n }\n\n // check whether ranges have duplicate \"from/to\" eg: 0 - 50, 25 - 50\n if (ranges.length !== uniqBy(ranges, 'to').length || ranges.length !== uniqBy(ranges, 'from').length) {\n return _('Prop \"ranges\" has invalid entries: duplicate values');\n }\n\n const sortedRanges = getSortedRanges(ranges);\n\n // check whether ranges are continuous eg: 0 - 10, 10 - 20, 20 - 30\n for (let i = 1; i < sortedRanges.length; i += 1) {\n if (sortedRanges[i].from !== sortedRanges[i - 1].to) {\n return _('Prop \"ranges\" has invalid entries: discontinuous ranges');\n }\n }\n\n return null;\n};\n\n/**\n * calculate min and max value of gauge\n * @method getGaugeRange\n * @param {Array} ranges\n * @return {Object} gaugeRange\n * @return {Number} gaugeRange.min\n * @return {Number} gaugeRange.max\n */\nexport const getGaugeRange = ranges => {\n const min = Math.min(...ranges.map(range => range.from));\n const max = Math.max(...ranges.map(range => range.to));\n return { min, max };\n};\n\n/**\n * calculate stop offsets for linear gradient\n * @method getGradientStopOffsets\n * @param {Array} ranges\n * @param {String} orientation\n * @return {Array} cumulativeOffsets\n */\nexport const getGradientStopOffsets = ({ ranges, orientation }) => {\n const { min, max } = getGaugeRange(ranges);\n const offsetScale = (GRADIENT_STOP_OFFSET_MAX - GRADIENT_STOP_OFFSET_MIN) / (max - min);\n let offsets = ranges.map(range => Math.abs(range.from - range.to) * offsetScale);\n // When orientation is vertical, since the gauge starts from bottom to top, linear gradient should be reversed\n offsets = orientation === 'vertical' ? offsets.reverse() : offsets;\n const cumulativeOffsets = [];\n offsets.reduce((accumulator, currentValue, idx) => {\n cumulativeOffsets[idx] = accumulator + currentValue;\n return cumulativeOffsets[idx];\n }, 0);\n return cumulativeOffsets;\n};\n\n/**\n * calculate stop colors for linear gradient\n * @method getGradientStopColors\n * @param {Array} ranges\n * @param {String} orientation\n * @return {Array} stopColors\n */\nexport const getGradientStopColors = ({ ranges, orientation }) => {\n const stopColors = ranges.map(range => range.value);\n // When orientation is vertical, since the gauge starts from bottom to top, linear gradient should be reversed\n return orientation === 'vertical' ? stopColors.reverse() : stopColors;\n};\n\n/**\n * calculate linear gradient stops from ranges\n * @method getGradientStops\n * @param {Object} input\n * @param {Array} ranges\n * @param {String} orientation\n * @return {Array} stops\n */\nexport const getGradientStops = ({ ranges, orientation }) => {\n const stops = [];\n const offsets = getGradientStopOffsets({ ranges, orientation });\n const stopColors = getGradientStopColors({ ranges, orientation });\n // Initialize stops with the first color stop\n stops.push({ offset: `${offsets[0]}%`, stopColor: stopColors[0] });\n // Add the remaining color stops with gradient change at each stop\n for (let i = 1; i < ranges.length; i += 1) {\n stops.push(\n { offset: `${offsets[i - 1]}%`, stopColor: stopColors[i] },\n { offset: `${offsets[i]}%`, stopColor: stopColors[i] }\n );\n }\n return stops;\n};\n\n/**\n * calculate linear gradient dimensions\n * @method getGradientDimensions\n * @param {String} orientation\n * @return {Object} dimensions\n * @return {String} dimensions.x1\n * @return {String} dimensions.y1\n * @return {String} dimensions.x2\n * @return {String} dimensions.y2\n */\nexport const getGradientDimensions = orientation => {\n const x1 = '0%';\n const y1 = '0%';\n const x2 = orientation === 'horizontal' ? '100%' : '0%';\n const y2 = orientation === 'horizontal' ? '0%' : '100%';\n return { x1, y1, x2, y2 };\n};\n\ntype NumericInput = number | string;\n\ninterface UniqueDecimalPlacesInput {\n values: number[];\n minimumDecimalPlaces: number;\n}\n\ninterface PercentageFromRangeInput {\n value: number;\n min: number;\n range: number;\n}\n\ninterface NumOfTicksInput {\n min: number;\n max: number;\n majorUnit: number | string;\n usePercentageRange: boolean;\n}\n\ninterface TickLabelFormatterResult {\n numOfTicks: number;\n numericStep: number;\n formatTickLabel: (value: number) => string;\n}\n\ninterface FormatGaugeValueLabelInput {\n value: NumericInput;\n min: number;\n max: number;\n usePercentageValue: boolean;\n}\n\n// Returns the number of fractional digits in a numeric input.\nexport const getDecimalPlaces = (value: NumericInput): number => {\n const numericValue = Number(value);\n if (!Number.isFinite(numericValue)) {\n return 0;\n }\n\n const fractionPart = numericValue.toString().split('.')[1];\n return fractionPart ? fractionPart.length : 0;\n};\n\n// Finds the smallest precision that keeps all rounded tick values unique.\n// This avoids duplicated rendered labels caused by rounding collisions.\nexport const getUniqueDecimalPlaces = ({\n values,\n minimumDecimalPlaces,\n}: UniqueDecimalPlacesInput): number => {\n if (values.length <= 1) {\n return minimumDecimalPlaces;\n }\n\n for (\n let decimalPlaces = minimumDecimalPlaces;\n decimalPlaces <= MAX_TICK_LABEL_DECIMAL_PLACES;\n decimalPlaces += 1\n ) {\n const roundedValues = values.map(value => Number(value.toFixed(decimalPlaces)));\n if (new Set(roundedValues).size === roundedValues.length) {\n return decimalPlaces;\n }\n }\n\n return MAX_TICK_LABEL_DECIMAL_PLACES;\n};\n\n// Converts a value within [min, max] to percentage space.\nexport const getPercentageFromRange = ({ value, min, range }: PercentageFromRangeInput): number => {\n if (range === 0) {\n return 0;\n }\n return ((value - min) / range) * 100;\n};\n\n// Computes interval count from auto mode or explicit majorUnit.\nexport const getNumOfTicks = ({\n min,\n max,\n majorUnit,\n usePercentageRange,\n}: NumOfTicksInput): { numOfTicks: number; isAutoMajorUnit: boolean; majorUnitNumber: number } => {\n const range = max - min;\n const majorUnitNumber = Number(majorUnit);\n const isAutoMajorUnit = majorUnit === 'auto' || Number.isNaN(majorUnitNumber) || majorUnitNumber <= 0;\n\n let numOfTicks = DEFAULT_NUM_OF_TICKS;\n if (!isAutoMajorUnit) {\n numOfTicks = usePercentageRange ? 100 / majorUnitNumber : range / majorUnitNumber;\n }\n\n return { numOfTicks, isAutoMajorUnit, majorUnitNumber };\n};\n\n// Builds a reusable formatter and step size for major tick rendering.\nexport const getTickLabelFormatter = ({\n min,\n max,\n majorUnit,\n usePercentageRange,\n}: NumOfTicksInput): TickLabelFormatterResult => {\n const range = max - min;\n const { numOfTicks, isAutoMajorUnit, majorUnitNumber } = getNumOfTicks({\n min,\n max,\n majorUnit,\n usePercentageRange,\n });\n const numericStep = range / numOfTicks;\n const tickValues = [];\n\n // Materialize all candidate tick values (plus max for uneven divisions).\n for (let i = 0; i <= numOfTicks; i += 1) {\n tickValues.push(min + numericStep * i);\n }\n\n if (!Number.isInteger(numOfTicks)) {\n tickValues.push(max);\n }\n\n const minimumNumericDecimalPlaces = Math.min(\n MAX_TICK_LABEL_DECIMAL_PLACES,\n Math.max(\n getDecimalPlaces(min),\n getDecimalPlaces(max),\n isAutoMajorUnit ? 0 : getDecimalPlaces(majorUnitNumber)\n )\n );\n const numericLabelDecimalPlaces = getUniqueDecimalPlaces({\n values: tickValues,\n minimumDecimalPlaces: minimumNumericDecimalPlaces,\n });\n const percentageLabelDecimalPlaces = getUniqueDecimalPlaces({\n values: tickValues.map(value => getPercentageFromRange({ value, min, range })),\n minimumDecimalPlaces: 0,\n });\n\n // Keep fixed-width decimal formatting when decimals are needed; otherwise use trend formatting.\n const formatTickLabel = value => {\n if (usePercentageRange) {\n const percentageValue = getPercentageFromRange({ value, min, range });\n return `${percentageValue.toFixed(percentageLabelDecimalPlaces)}%`;\n }\n\n const numericLabel = value.toFixed(numericLabelDecimalPlaces);\n if (numericLabel.includes('.')) {\n return numericLabel;\n }\n\n return formatNumber(Number(numericLabel), 0, {\n useThousandSeparators: true,\n useTrendUnits: true,\n }).replace(/k$/, 'K');\n };\n\n return { numOfTicks, numericStep, formatTickLabel };\n};\n\n// Limits decimal places so displayed value length stays within a fixed digit budget.\nconst getDigitsBeforeDecimal = (numericValue: NumericInput): number =>\n Math.abs(Math.trunc(Number(numericValue))).toString().length;\n\nconst getCappedDecimalPlaces = (\n numericValue: NumericInput,\n rawDecimalPlaces: number,\n maxDigits: number\n): number => {\n const digitsBeforeDecimal = getDigitsBeforeDecimal(numericValue);\n const maxDecimalPlaces = Math.max(0, maxDigits - digitsBeforeDecimal);\n return Math.min(rawDecimalPlaces, maxDecimalPlaces);\n};\n\n// Formats the marker value label in number or percentage mode with capped precision.\nexport const formatGaugeValueLabel = ({\n value,\n min,\n max,\n usePercentageValue,\n}: FormatGaugeValueLabelInput): string => {\n const numericValue = Number(value);\n const range = max - min || 1;\n const percentageValue = getPercentageFromRange({ value: numericValue, min, range });\n const trendFormatOptions = {\n useThousandSeparators: true,\n useTrendUnits: true,\n };\n\n if (usePercentageValue) {\n // Use the same number-mode formatting behavior (including K/M/B/T) for percentages.\n const percentageDecimalPlaces = getCappedDecimalPlaces(\n percentageValue,\n 2,\n MAX_VALUE_LABEL_DIGITS_WITH_PERCENT\n );\n return `${formatNumber(percentageValue, percentageDecimalPlaces, trendFormatOptions)}%`;\n }\n\n const valueDecimalPlaces = getCappedDecimalPlaces(\n numericValue,\n getDecimalPlaces(numericValue),\n MAX_VALUE_LABEL_DIGITS_WITHOUT_PERCENT\n );\n return formatNumber(numericValue, valueDecimalPlaces, trendFormatOptions);\n};\n\ninterface GaugeOptions {\n [key: string]: any;\n}\n\n// map for new options names to old option names\nconst gaugeOptionsMapping = {\n majorTickInterval: 'majorUnit',\n gaugeRanges: 'ranges',\n};\n\n/**\n * Helper method to update the option names which can be mapped to pure component options\n * @method mapToOldKey\n * @param {Object} options\n * @returns {Object}\n */\nexport const mapToOldKey = (options: GaugeOptions): GaugeOptions =>\n mapKeys(options, (val, key) => (gaugeOptionsMapping[key] ? gaugeOptionsMapping[key] : key));\n\ntype LabelOrValue = 'label' | 'value';\n\n/**\n * Helper method to map labelDisplay and valueDisplay options to pure component option names\n * @method mapToOldKey\n * @param {string} labelOrValue\n * @param {Object} options\n * @returns {Object}\n */\nexport const mapValueLabelDisplay = (labelOrValue: LabelOrValue, options: GaugeOptions): GaugeOptions => {\n const rangeOrValue: string = labelOrValue === 'value' ? 'Value' : 'Range';\n const showKey: string = labelOrValue === 'value' ? 'showValue' : 'showLabels';\n const percentKey = `usePercentage${rangeOrValue}`;\n const optionString = `${labelOrValue}Display`;\n const newOptions = { ...options };\n if (newOptions[optionString]) {\n if (newOptions[optionString] === 'number') {\n newOptions[showKey] = true;\n newOptions[percentKey] = false;\n } else if (newOptions[optionString] === 'percentage') {\n newOptions[showKey] = true;\n newOptions[percentKey] = true;\n } else {\n newOptions[showKey] = false;\n newOptions[percentKey] = false;\n }\n }\n return omit(newOptions, [optionString]);\n};\n\n/**\n * Chained helper for mapping the option properties (and values) we expose in config.ts into property values that pure component accepts\n * This is for options that has new key name and can not directly be mapped with pure component props\n * @method convertToGaugeProperties\n * @param {Object} originalOptions\n * @returns {Object}\n */\nexport const convertToGaugeProperties = (originalOptions: GaugeOptions): GaugeOptions =>\n chain(mapToOldKey(originalOptions))\n .thru(options => mapValueLabelDisplay('label', options))\n .thru(options => mapValueLabelDisplay('value', options))\n .value();\n", "\nimport * as defaultImport from \"lodash\";\nexport * from \"lodash\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/visualizations-shared/colorConstants\";\nexport * from \"@splunk/visualizations-shared/colorConstants\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/visualizations-shared/numberUtils\";\nexport * from \"@splunk/visualizations-shared/numberUtils\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n", "\nimport * as defaultImport from \"@splunk/ui-utils/i18n\";\nexport * from \"@splunk/ui-utils/i18n\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["defaultImport", "defaultImport", "defaultImport"]
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FixedSizeContainer.d.ts","sourceRoot":"","sources":["../../src/common/hocs/FixedSizeContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAwE/B,UAAU,mBAAmB;IACzB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,QAAA,MAAM,sBAAsB,GAAI,CAAC,SAAS,mBAAmB,EACzD,KAAK,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAC5B,KAAK,CAAC,aAAa,CAAC,CAAC,
|
|
1
|
+
{"version":3,"file":"FixedSizeContainer.d.ts","sourceRoot":"","sources":["../../src/common/hocs/FixedSizeContainer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAwE/B,UAAU,mBAAmB;IACzB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACzB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,QAAA,MAAM,sBAAsB,GAAI,CAAC,SAAS,mBAAmB,EACzD,KAAK,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,KAC5B,KAAK,CAAC,aAAa,CAAC,CAAC,CAoCvB,CAAC;AAEF,eAAe,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pixel height of the paginator bar, matching the value used in the Table
|
|
3
|
+
* styled component SUITableContainer. Exported so callers can share the constant
|
|
4
|
+
* rather than duplicate it.
|
|
5
|
+
*/
|
|
6
|
+
export declare const PAGINATOR_CONTAINER_HEIGHT = 38;
|
|
7
|
+
/**
|
|
8
|
+
* Pixel spacing between the table body and the paginator bar.
|
|
9
|
+
*/
|
|
10
|
+
export declare const PAGINATOR_SPACING = 5;
|
|
11
|
+
interface UseDynamicHeightParams {
|
|
12
|
+
/** Whether the dynamic-height feature is currently enabled. */
|
|
13
|
+
dynamicHeight?: boolean;
|
|
14
|
+
/**
|
|
15
|
+
* Framework-supplied callback that receives the viz's total natural height
|
|
16
|
+
* in pixels. Pass `undefined` to clear a previously reported override
|
|
17
|
+
* (e.g. when dynamic height is disabled).
|
|
18
|
+
*/
|
|
19
|
+
onRequestHeight?: (height: number | undefined) => void;
|
|
20
|
+
/** Whether the paginator is currently active (adds chrome to the measurement). */
|
|
21
|
+
isPaging: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Opaque change signal — re-measuring is triggered whenever this value
|
|
24
|
+
* changes identity (use `tableBody.rows`).
|
|
25
|
+
*/
|
|
26
|
+
rows: unknown;
|
|
27
|
+
/**
|
|
28
|
+
* Opaque change signal — re-measuring is triggered whenever this value
|
|
29
|
+
* changes identity (use the `expandedRowJson` memo from the component).
|
|
30
|
+
*/
|
|
31
|
+
expandedRowJson: unknown;
|
|
32
|
+
}
|
|
33
|
+
interface UseDynamicHeightResult {
|
|
34
|
+
/** Attach to the outermost container element (`VizTableContainer`). */
|
|
35
|
+
containerRef: React.RefObject<HTMLDivElement | null>;
|
|
36
|
+
/** Attach to the scroll-viewport container (`SUITableContainer`). */
|
|
37
|
+
containerRefInner: React.RefObject<HTMLDivElement | null>;
|
|
38
|
+
/**
|
|
39
|
+
* Attach to the SUI Table element via its `elementRef` prop.
|
|
40
|
+
* The hook reaches the inner `<table>` node through this ref.
|
|
41
|
+
*/
|
|
42
|
+
suiTableRef: React.RefObject<HTMLDivElement | null>;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Manages dynamic-height reporting for the Table visualization.
|
|
46
|
+
*
|
|
47
|
+
* Responsibilities:
|
|
48
|
+
* - Measures the table's natural content height (inner `<table>` scrollHeight +
|
|
49
|
+
* container padding + optional paginator chrome) and reports it via
|
|
50
|
+
* `onRequestHeight` whenever content changes size.
|
|
51
|
+
* - Dedupes: only fires `onRequestHeight` when the computed height changes.
|
|
52
|
+
* - Caches the last measured height so that toggling `dynamicHeight` back on
|
|
53
|
+
* can immediately re-report without waiting for a new ResizeObserver entry.
|
|
54
|
+
* - Clears the layout override (reports `undefined`) when `dynamicHeight` flips
|
|
55
|
+
* false, but keeps the cache so re-enabling restores the grown height.
|
|
56
|
+
*
|
|
57
|
+
* The hook owns and returns the three refs that must be attached to DOM nodes
|
|
58
|
+
* by the calling component.
|
|
59
|
+
*
|
|
60
|
+
* **Future seam:** the `onRequestHeight` prop will eventually be replaced by
|
|
61
|
+
* `useDynamicHeightCallback(id)` from `@splunk/dashboard-context` once that hook
|
|
62
|
+
* is available. The internal caching and enable/disable logic already mirrors the
|
|
63
|
+
* framework's `useDynamicHeightReporter` shape to make that swap straightforward.
|
|
64
|
+
*/
|
|
65
|
+
export declare const useDynamicHeight: ({ dynamicHeight, onRequestHeight, isPaging, rows, expandedRowJson, }: UseDynamicHeightParams) => UseDynamicHeightResult;
|
|
66
|
+
export {};
|
|
67
|
+
//# sourceMappingURL=useDynamicHeight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDynamicHeight.d.ts","sourceRoot":"","sources":["../../src/common/hooks/useDynamicHeight.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,eAAO,MAAM,0BAA0B,KAAK,CAAC;AAE7C;;GAEG;AACH,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAEnC,UAAU,sBAAsB;IAC5B,+DAA+D;IAC/D,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;;;OAIG;IACH,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,CAAC;IACvD,kFAAkF;IAClF,QAAQ,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,IAAI,EAAE,OAAO,CAAC;IACd;;;OAGG;IACH,eAAe,EAAE,OAAO,CAAC;CAC5B;AAED,UAAU,sBAAsB;IAC5B,uEAAuE;IACvE,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACrD,qEAAqE;IACrE,iBAAiB,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IAC1D;;;OAGG;IACH,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;CACvD;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,gBAAgB,GAAI,sEAM9B,sBAAsB,KAAG,sBA8F3B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useSorting.d.ts","sourceRoot":"","sources":["../../src/common/hooks/useSorting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,YAAY,CAAC;AAEhC,OAAO,EAAE,cAAc,EAAE,WAAW,EAAiB,MAAM,0BAA0B,CAAC;AAEtF,MAAM,WAAW,UAAU;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,WAAW,CAAC;IAC7B,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,WAAW,CAAA;KAAE,KAAK,IAAI,CAAC;CACrG;AAED,eAAO,MAAM,mBAAmB;;;;GAI9B,CAAC;AAEH,eAAO,MAAM,gBAAgB,GAAI,0CAA0C,cAAc,KAAG,
|
|
1
|
+
{"version":3,"file":"useSorting.d.ts","sourceRoot":"","sources":["../../src/common/hooks/useSorting.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,YAAY,CAAC;AAEhC,OAAO,EAAE,cAAc,EAAE,WAAW,EAAiB,MAAM,0BAA0B,CAAC;AAEtF,MAAM,WAAW,UAAU;IACvB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,WAAW,CAAC;IAC7B,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,WAAW,CAAA;KAAE,KAAK,IAAI,CAAC;CACrG;AAED,eAAO,MAAM,mBAAmB;;;;GAI9B,CAAC;AAEH,eAAO,MAAM,gBAAgB,GAAI,0CAA0C,cAAc,KAAG,UAqC3F,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VizCategory.d.ts","sourceRoot":"","sources":["../../src/common/interfaces/VizCategory.ts"],"names":[],"mappings":"AAAA,oBAAY,WAAW;IACnB,YAAY,iBAAiB;IAC7B,MAAM,WAAW;IACjB,WAAW,gBAAgB;IAC3B,KAAK,UAAU;IACf,QAAQ,aAAa;IACrB,KAAK,UAAU;IACf,aAAa,kBAAkB;IAC/B,UAAU,oBAAoB;IAC9B,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,IAAI,SAAS;IACb,WAAW,gBAAgB;IAC3B,OAAO,YAAY;
|
|
1
|
+
{"version":3,"file":"VizCategory.d.ts","sourceRoot":"","sources":["../../src/common/interfaces/VizCategory.ts"],"names":[],"mappings":"AAAA,oBAAY,WAAW;IACnB,YAAY,iBAAiB;IAC7B,MAAM,WAAW;IACjB,WAAW,gBAAgB;IAC3B,KAAK,UAAU;IACf,QAAQ,aAAa;IACrB,KAAK,UAAU;IACf,aAAa,kBAAkB;IAC/B,UAAU,oBAAoB;IAC9B,MAAM,WAAW;IACjB,IAAI,SAAS;IACb,IAAI,SAAS;IACb,WAAW,gBAAgB;IAC3B,OAAO,YAAY;IACnB,IAAI,SAAS;CAChB"}
|
|
@@ -8,6 +8,13 @@ export interface VizEvent {
|
|
|
8
8
|
* Example: [ 'a', 'b' ] -> { a: { b: event } }
|
|
9
9
|
*/
|
|
10
10
|
parentKeys?: string[];
|
|
11
|
+
/**
|
|
12
|
+
* Configure an event as a default behavior that fires even in edit mode or
|
|
13
|
+
* when the user has not configured any event handlers. 'user' events only
|
|
14
|
+
* fire in view mode once handlers are bound.
|
|
15
|
+
* @default "user"
|
|
16
|
+
*/
|
|
17
|
+
source?: 'default' | 'user';
|
|
11
18
|
};
|
|
12
19
|
}
|
|
13
20
|
//# sourceMappingURL=VizEvent.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VizEvent.d.ts","sourceRoot":"","sources":["../../src/common/interfaces/VizEvent.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG;QACX,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;QACvB;;;;WAIG;QACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"VizEvent.d.ts","sourceRoot":"","sources":["../../src/common/interfaces/VizEvent.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG;QACX,WAAW,EAAE,MAAM,CAAC;QACpB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;QACvB;;;;WAIG;QACH,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;QACtB;;;;;WAKG;QACH,MAAM,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;KAC/B,CAAC;CACL"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dataUtils.d.ts","sourceRoot":"","sources":["../../src/common/utils/dataUtils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE9E,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,eAAO,MAAM,qBAAqB,GAAI,SAAS,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,QAAQ,GAAG,EAAE,KAAG,GAAG,EAmBrF,CAAC;AA4GF,MAAM,MAAM,iBAAiB,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,iBAAiB,EAAE,aAAa,GAAG,SAAS,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"dataUtils.d.ts","sourceRoot":"","sources":["../../src/common/utils/dataUtils.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAE9E,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD,eAAO,MAAM,qBAAqB,GAAI,SAAS,CAAC,MAAM,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,QAAQ,GAAG,EAAE,KAAG,GAAG,EAmBrF,CAAC;AA4GF,MAAM,MAAM,iBAAiB,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,iBAAiB,EAAE,aAAa,GAAG,SAAS,CAAC,CAAC;AAyE3G,eAAO,MAAM,2BAA2B,GAAI,eAAe;IAAE,SAAS,EAAE,SAAS,CAAA;CAAE,YAElF,CAAC;AAEF,eAAO,MAAM,+BAA+B,GAAI,gDAK7C,IAAI,CAAC,iBAAiB,EAAE,aAAa,CAAC,GAAG;IACxC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B,KAAG,MAKH,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,8BAA8B,GAAI,qEAM5C;IACC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,IAAI,CAAC;IAC/C,gBAAgB,EAAE,UAAU,CAAC,kBAAkB,CAAC,GAAG,IAAI,CAAC;IACxD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAClB,KAAG,MAAM,GAAG,IA4CZ,CAAC;AA4FF,eAAO,MAAM,qBAAqB,GAAI,qCAAqC,iBAAiB,+BA8D3F,CAAC"}
|
|
@@ -110,7 +110,7 @@ var largestTriangleThreeBuckets = (data, threshold, preferredDownsampleIndices)
|
|
|
110
110
|
let avgY = 0;
|
|
111
111
|
let avgRangeStart = Math.floor((i + 1) * every) + 1;
|
|
112
112
|
let avgRangeEnd = Math.floor((i + 2) * every) + 1;
|
|
113
|
-
avgRangeEnd = avgRangeEnd
|
|
113
|
+
avgRangeEnd = Math.min(avgRangeEnd, dataLength);
|
|
114
114
|
const avgRangeLength = avgRangeEnd - avgRangeStart;
|
|
115
115
|
for (; avgRangeStart < avgRangeEnd; avgRangeStart++) {
|
|
116
116
|
avgX += Number(data[avgRangeStart][0]);
|
|
@@ -145,9 +145,9 @@ var largestTriangleThreeBuckets = (data, threshold, preferredDownsampleIndices)
|
|
|
145
145
|
};
|
|
146
146
|
var strictlyCoerceYColumn = (column, options) => {
|
|
147
147
|
const isNullCoercionEnabled = options.nullValueDisplay === "zero";
|
|
148
|
-
const canLooselyCoerceSomeValues = column.
|
|
148
|
+
const canLooselyCoerceSomeValues = column.some(
|
|
149
149
|
(value) => (0, numberUtils_exports.startsWithNumber)(`${value}`) || isNullCoercionEnabled && value === null
|
|
150
|
-
)
|
|
150
|
+
);
|
|
151
151
|
const coercedColumn = [];
|
|
152
152
|
const canDownsampleColumn = !column.some((value) => {
|
|
153
153
|
const coercedValue = Number(value);
|
|
@@ -166,7 +166,7 @@ var strictlyCoerceYColumn = (column, options) => {
|
|
|
166
166
|
};
|
|
167
167
|
var strictlyCoerceXColumn = (column, fieldType) => {
|
|
168
168
|
if (fieldType === "number") {
|
|
169
|
-
const coercedXColumn = column.map(
|
|
169
|
+
const coercedXColumn = column.map(Number);
|
|
170
170
|
if (isColumnStrictlyIncreasing(coercedXColumn, fieldType)) {
|
|
171
171
|
return coercedXColumn;
|
|
172
172
|
}
|
|
@@ -220,12 +220,8 @@ var calculateDownsamplingThreshold = ({
|
|
|
220
220
|
}
|
|
221
221
|
const fullSeries = (_c = primaryDataSource == null ? void 0 : primaryDataSource.data) == null ? void 0 : _c.columns[xFieldIndex];
|
|
222
222
|
const downsampledSeries = currentTarget.dataSet.seriesList[downsampledXFieldIndex];
|
|
223
|
-
const firstIndex = fullSeries.
|
|
224
|
-
|
|
225
|
-
});
|
|
226
|
-
const lastIndex = fullSeries.findIndex((x) => {
|
|
227
|
-
return downsampledSeries[endXIndex] === x;
|
|
228
|
-
});
|
|
223
|
+
const firstIndex = fullSeries.indexOf(downsampledSeries[startXIndex]);
|
|
224
|
+
const lastIndex = fullSeries.indexOf(downsampledSeries[endXIndex]);
|
|
229
225
|
if (firstIndex >= 0 && lastIndex >= 0 && firstIndex <= lastIndex) {
|
|
230
226
|
return calculateThresholdOnRangeSelect({
|
|
231
227
|
firstIndex,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/common/utils/dataUtils.ts", "esm-externals:@splunk/visualizations-shared/numberUtils"],
|
|
4
|
-
"sourcesContent": ["import type { FieldEntry } from '@splunk/visualizations-shared/dataSourceUtils';\nimport { startsWithNumber } from '@splunk/visualizations-shared/numberUtils';\nimport type { DashboardVizProps, DataSource, VizConfig } from '../interfaces';\nimport { VizBehavior } from '../interfaces';\nimport { ChartEvent } from '../interfaces/ChartEvent';\n\nexport const convertToArrOfObjects = (columns: (string | any[])[], fields: any[]): any[] => {\n if (!columns?.[0]?.length) return [];\n\n const data = [];\n\n for (let i = 0; i < columns[0].length; i += 1) {\n const newObj = {};\n fields.forEach((field, index) => {\n const fieldName = getFieldName(field);\n if (columns[index][i] === '') {\n newObj[fieldName] = null;\n } else {\n newObj[fieldName] = columns[index][i];\n }\n });\n data.push(newObj);\n }\n\n return data;\n};\n\nconst getFieldName = (field: FieldEntry | string): string => (typeof field === 'string' ? field : field.name);\n\n// LTTB algorithm which can be used to downsample time series data while striving to maintain\n// the spikes and overall shape of the chart\n// Copied from https://github.com/sveinn-steinarsson/flot-downsample/blob/0815010016fc94b1bbc6a010afb8aad13ada6d0d/jquery.flot.downsample.js\n// Modifications include:\n// 1) Convert to modern JavaScript(use const, let, and use array.push to push to last element of array)\n// 2) Convert to camel case\n// 3) Convert to TS and also return the indices of the points that are in the downsampled result.\n// 4) Add a new parameter preferredDownsampleIndices that correspond to the indices of points\n// that should be used in case of a tie of the max area in a bucket\nconst largestTriangleThreeBuckets = (\n data: [Date | number, number][],\n threshold: number,\n preferredDownsampleIndices: Set<number>\n): {\n downsampledData: [Date | number, number][];\n downsampledIndices: number[];\n} => {\n const dataLength = data.length;\n const downsampledIndices = [];\n if (threshold >= dataLength || threshold === 0) {\n const allIndices = data.map((values, index) => index);\n return { downsampledData: data, downsampledIndices: allIndices }; // Nothing to do\n }\n\n const sampled: [Date | number, number][] = [];\n let sampledIndex = 0;\n\n // Bucket size. Leave room for start and end data points\n const every = (dataLength - 2) / (threshold - 2);\n\n let a = 0; // Initially a is the first point in the triangle\n let maxAreaPoint: [Date | number, number];\n let maxArea: number | undefined;\n let area: number | undefined;\n let nextA: number | undefined;\n\n sampled.push(data[a]); // Always add the first point\n downsampledIndices.push(0);\n\n // eslint-disable-next-line no-plusplus\n for (let i = 0; i < threshold - 2; i++) {\n // Calculate point average for next bucket (containing c)\n let avgX = 0;\n let avgY = 0;\n let avgRangeStart = Math.floor((i + 1) * every) + 1;\n let avgRangeEnd = Math.floor((i + 2) * every) + 1;\n avgRangeEnd = avgRangeEnd < dataLength ? avgRangeEnd : dataLength;\n\n const avgRangeLength = avgRangeEnd - avgRangeStart;\n\n // eslint-disable-next-line no-plusplus\n for (; avgRangeStart < avgRangeEnd; avgRangeStart++) {\n avgX += Number(data[avgRangeStart][0]); // * 1 enforces Number (value may be Date)\n avgY += data[avgRangeStart][1] * 1;\n }\n avgX /= avgRangeLength;\n avgY /= avgRangeLength;\n\n // Get the range for this bucket\n let rangeOffs = Math.floor((i + 0) * every) + 1;\n const rangeTo = Math.floor((i + 1) * every) + 1;\n\n // Point a\n const pointAX = Number(data[a][0]); // Enforce Number (value may be Date)\n const pointAY = data[a][1] * 1;\n\n // eslint-disable-next-line no-multi-assign\n maxArea = area = -1;\n let maxAreaIndex = rangeOffs;\n\n // eslint-disable-next-line no-plusplus\n for (; rangeOffs < rangeTo; rangeOffs++) {\n // Calculate triangle area over three buckets\n area =\n Math.abs(\n (pointAX - avgX) * (data[rangeOffs][1] - pointAY) -\n (pointAX - Number(data[rangeOffs][0])) * (avgY - pointAY)\n ) * 0.5;\n // Modification: try to downsample the least amount of points possible when there are multiple series\n // If all points in a bucket have the same area, prioritize the one with an x index\n // that also existed from another series so we don't add another point unnecessarily.\n // By default LTTB picks the leftmost point in the bucket\n if (area > maxArea || (area === maxArea && preferredDownsampleIndices.has(rangeOffs))) {\n maxArea = area;\n maxAreaPoint = data[rangeOffs];\n nextA = rangeOffs; // Next a is this b\n // Modification: save the index of the point with the most area\n maxAreaIndex = rangeOffs;\n }\n }\n\n // eslint-disable-next-line no-plusplus\n sampled[sampledIndex++] = maxAreaPoint; // Pick this point from the bucket\n downsampledIndices.push(maxAreaIndex);\n a = nextA; // This a is the next a (chosen b)\n }\n\n // eslint-disable-next-line no-plusplus\n sampled[sampledIndex++] = data[dataLength - 1]; // Always add last\n downsampledIndices.push(dataLength - 1);\n\n return { downsampledData: sampled, downsampledIndices };\n};\n\nexport type DownsampleOptions = { threshold: number } & Pick<DashboardVizProps, 'dataSources' | 'options'>;\n\ntype CoerceYColumnResult = {\n canDownsampleColumn: boolean;\n canLooselyCoerceSomeValues: boolean;\n coercedColumn: number[];\n};\n\n/**\n * Strictly coerces the entire column to numbers if it only consists of numeric strings or numbers. Also determines\n * if at least one of the values in the column can be loosely coerced to a number.\n * If the column cannot be strictly downsampled (if it contains nulls or non-numeric strings), returns an empty array and\n * returns that it cannot downsample the column.\n */\nconst strictlyCoerceYColumn = (\n column: (string | number)[] | number[],\n options: DownsampleOptions['options']\n): CoerceYColumnResult => {\n const isNullCoercionEnabled = options.nullValueDisplay === 'zero';\n // Splunk charting allows for numbers in formats such as negative hex that\n // Number() does not support and also allows loose coercion of hex numbers (but not other formats)\n // We want to identify columns which contain at least one value that can be loosely coerced\n const canLooselyCoerceSomeValues =\n column.findIndex(\n value => startsWithNumber(`${value}`) || (isNullCoercionEnabled && value === null)\n ) >= 0;\n\n // If not all values in column can be strictly coerced to a number, we do not downsample\n const coercedColumn: number[] = [];\n const canDownsampleColumn = !column.some(value => {\n const coercedValue = Number(value);\n const coerceValueToZero = isNullCoercionEnabled && value === null;\n\n // if it can't be parsed or isn't safe, fail\n if (\n Number.isNaN(coercedValue) ||\n coercedValue <= Number.MIN_SAFE_INTEGER ||\n coercedValue >= Number.MAX_SAFE_INTEGER ||\n (typeof value !== 'string' && typeof value !== 'number' && !coerceValueToZero)\n ) {\n return true;\n }\n // save value and continue to next\n coercedColumn.push(coercedValue);\n return false;\n });\n\n return {\n canDownsampleColumn,\n canLooselyCoerceSomeValues,\n coercedColumn: canDownsampleColumn ? coercedColumn : [],\n };\n};\n\n/**\n * Tries to coerce the x-column to numbers or dates, if it is eligible for downsampling.\n * Only strictly increasing x-columns are eligible for downsampling.\n * If the column is not eligible for downsampling, returns an empty array.\n */\nconst strictlyCoerceXColumn = (column: (string | number)[], fieldType: string): Date[] | number[] => {\n if (fieldType === 'number') {\n const coercedXColumn = column.map(xValue => Number(xValue));\n if (isColumnStrictlyIncreasing(coercedXColumn, fieldType)) {\n return coercedXColumn;\n }\n } else if (fieldType === 'time') {\n const coercedXColumn = column.map(xValue => new Date(xValue));\n if (isColumnStrictlyIncreasing(coercedXColumn, fieldType)) {\n return coercedXColumn;\n }\n }\n return [];\n};\n\nexport const isDownsamplingEnabledForViz = ({ vizConfig }: { vizConfig: VizConfig }) => {\n return vizConfig.supports?.includes(VizBehavior.DOWNSAMPLING);\n};\n\nexport const calculateThresholdOnRangeSelect = ({\n firstIndex,\n lastIndex,\n dataSources,\n width,\n}: Pick<DashboardVizProps, 'dataSources'> & {\n firstIndex: number;\n lastIndex: number;\n width: number | string;\n}): number => {\n const window = lastIndex - firstIndex + 1;\n // eslint-disable-next-line no-unsafe-optional-chaining\n const ratio = Math.round(Number(dataSources?.primary?.data?.columns[0]?.length / window) * 10) / 10;\n return Math.round(ratio * Number(width));\n};\n\n/**\n * Calculates the downsampling threshold based on the range selection. If search zoom is enabled or there is no selection,\n * then returns the width of the visualization.\n *\n * Otherwise calculates the threshold based on the ratio of the window selected compared to the size of the non-downsampled\n * data sources. Returns null if the chart event's dataset does not match the passed in primary data source or if the chart is zoomed\n * in for a categorical chart.\n */\nexport const calculateDownsamplingThreshold = ({\n enableSearchZoom,\n dataSources,\n selectChartEvent,\n width,\n xField,\n}: {\n enableSearchZoom: boolean;\n dataSources: Record<string, DataSource> | null;\n selectChartEvent: ChartEvent<'chartRangeSelect'> | null;\n width: number;\n xField: string;\n}): number | null => {\n if (enableSearchZoom || !selectChartEvent) {\n return Number(width);\n }\n\n const primaryDataSource = dataSources?.primary;\n if (!primaryDataSource) {\n return null;\n }\n\n const { startXIndex, endXIndex, currentTarget } = selectChartEvent;\n\n try {\n const xFieldIndex = primaryDataSource?.data?.fields.findIndex(field => {\n const name = typeof field === 'string' ? field : field.name;\n return name === xField;\n });\n const downsampledXFieldIndex = currentTarget.dataSet?.fields.findIndex(field => field === xField);\n\n if (xFieldIndex === -1 || downsampledXFieldIndex === -1) {\n return null;\n }\n\n const fullSeries = primaryDataSource?.data?.columns[xFieldIndex];\n const downsampledSeries = currentTarget.dataSet.seriesList[downsampledXFieldIndex];\n\n const firstIndex = fullSeries.findIndex(x => {\n return downsampledSeries[startXIndex] === x;\n });\n const lastIndex = fullSeries.findIndex(x => {\n return downsampledSeries[endXIndex] === x;\n });\n\n if (firstIndex >= 0 && lastIndex >= 0 && firstIndex <= lastIndex) {\n return calculateThresholdOnRangeSelect({\n firstIndex,\n lastIndex,\n dataSources,\n width,\n });\n }\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error('Error occurred while setting downsample threshold on range select event', e);\n }\n\n return null;\n};\n\nconst isColumnStrictlyIncreasing = (column: (number | Date)[], fieldType: 'number' | 'time') => {\n return column.every((value, index) => {\n if (fieldType === 'number') {\n if (Number.isNaN(value)) {\n return false;\n }\n }\n\n if (fieldType === 'time') {\n if (Number.isNaN((value as Date).getTime())) {\n return false;\n }\n }\n if (index === 0) {\n return true;\n }\n return value > column[index - 1];\n });\n};\n\n/**\n * Verifies that all of the columns that are displayed in a chart can be downsampled. Valid columns that can be\n * displayed are those that contain at least one number. We can only downsample columns that only consist of numbers.\n *\n * If all columns can be downsampled, returns the x column coerced to time/number and y columns coerced to numbers.\n * If not all columns can be downsampled, then returns empty arrays for both x and y\n */\nconst tryToCoerceAllDisplayedFields = (\n ds: DataSource,\n xField: string,\n yFields: Set<string>,\n fieldTypes: string[],\n options: DownsampleOptions['options']\n): { xColumn: Date[] | number[]; yColumns: number[][] } => {\n let xColumn: Date[] | number[] = [];\n const yColumns: number[][] = [];\n\n const canDownsample = !ds.data.fields.some((field, index) => {\n const fieldName = getFieldName(field);\n const fieldType = fieldTypes[index] ?? 'unknown';\n const column = ds.data.columns[index];\n let hasDisplayedColumnThatCantBeDownsampled = false;\n\n if (fieldName === xField) {\n xColumn = strictlyCoerceXColumn(column, fieldType);\n } else if (yFields.has(fieldName)) {\n const { coercedColumn, canLooselyCoerceSomeValues, canDownsampleColumn } = strictlyCoerceYColumn(\n ds.data.columns[index],\n options\n );\n // do not perform downsampling if a column can possibly be displayed but cannot\n // be downsampled using LTTB\n hasDisplayedColumnThatCantBeDownsampled = canLooselyCoerceSomeValues && !canDownsampleColumn;\n if (hasDisplayedColumnThatCantBeDownsampled) {\n return true;\n }\n if (canDownsampleColumn) {\n yColumns.push(coercedColumn);\n }\n }\n return false;\n });\n\n if (canDownsample) {\n return { xColumn, yColumns };\n }\n return { xColumn: [], yColumns: [] };\n};\n\nconst pickIndicesFromDataSource = (ds: DataSource, indices: Set<number>): DataSource => {\n const sortedIndices = Array.from(indices).sort((a: number, b: number) => a - b);\n const slicedColumns = [];\n ds.data.columns.forEach(column => {\n const slicedColumn = [];\n sortedIndices.forEach(index => {\n slicedColumn.push(column[index]);\n });\n slicedColumns.push(slicedColumn);\n });\n\n // update data columns with downsampled columns\n return {\n ...ds,\n data: {\n ...ds.data,\n columns: slicedColumns,\n },\n };\n};\n\nexport const downsampleDataSources = ({ dataSources, threshold, options }: DownsampleOptions) => {\n const primaryDS = dataSources?.primary;\n // only downsample time series when number of data points are over threshold\n const numPoints = primaryDS?.data?.columns[0]?.length ?? 0;\n if (Number.isNaN(threshold) || numPoints <= threshold || threshold < 2) {\n return dataSources;\n }\n\n const { xField, yFields, fieldTypes } = options;\n if (!xField || !yFields?.length || !fieldTypes?.length) {\n return dataSources;\n }\n\n const nonInternalYFields = new Set<string>(yFields.filter(yField => !yField.startsWith('_')));\n const maxPointsInDownsample = Math.min(nonInternalYFields.size * threshold, numPoints);\n\n // Do not try to downsample if there are too many downsampled pts\n // At the worst case, each series has non-overlapping downsampled pts\n // which will mean that all points will be included in the downsampled result\n // This will just lead to additional overhead due to coercing each\n // x and y field to number\n if (maxPointsInDownsample >= numPoints) {\n return dataSources;\n }\n\n const { xColumn, yColumns } = tryToCoerceAllDisplayedFields(\n primaryDS,\n xField,\n nonInternalYFields,\n fieldTypes,\n options\n );\n\n if (!yColumns.length || !xColumn.length) {\n return dataSources;\n }\n\n const downsampledDataSources = { ...dataSources };\n const downsampledIndices = new Set<number>();\n\n yColumns.forEach((yColumn, columnIndex) => {\n // perform LTTB downsampling for current series, LTTB takes an [x, y] pair\n const xyPair: [Date | number, number][] = yColumn.map((yValue, index) => {\n return [xColumn[index], yValue];\n });\n\n try {\n const { downsampledIndices: downsampledIndicesForSeries } = largestTriangleThreeBuckets(\n xyPair,\n threshold,\n downsampledIndices\n );\n downsampledIndicesForSeries.forEach(downsampleIndex => downsampledIndices.add(downsampleIndex));\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error(`Error occurred while downsampling column ${columnIndex}`, e);\n }\n });\n // update data columns with downsampled columns\n downsampledDataSources.primary = pickIndicesFromDataSource(primaryDS, downsampledIndices);\n\n return downsampledDataSources;\n};\n", "\nimport * as defaultImport from \"@splunk/visualizations-shared/numberUtils\";\nexport * from \"@splunk/visualizations-shared/numberUtils\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AACA,oBAA+B;AAC/B,gCAAc;AACd,IAAO,sBAAS,aAAa,gBAA8B,wBAAU;;;ADG9D,IAAM,wBAAwB,CAAC,SAA6B,WAAyB;AAN5F;AAOI,MAAI,GAAC,wCAAU,OAAV,mBAAc,QAAQ,QAAO,CAAC;AAEnC,QAAM,OAAO,CAAC;AAEd,WAAS,IAAI,GAAG,IAAI,QAAQ,CAAC,EAAE,QAAQ,KAAK,GAAG;AAC3C,UAAM,SAAS,CAAC;AAChB,WAAO,QAAQ,CAAC,OAAO,UAAU;AAC7B,YAAM,YAAY,aAAa,KAAK;AACpC,UAAI,QAAQ,KAAK,EAAE,CAAC,MAAM,IAAI;AAC1B,eAAO,SAAS,IAAI;AAAA,MACxB,OAAO;AACH,eAAO,SAAS,IAAI,QAAQ,KAAK,EAAE,CAAC;AAAA,MACxC;AAAA,IACJ,CAAC;AACD,SAAK,KAAK,MAAM;AAAA,EACpB;AAEA,SAAO;AACX;AAEA,IAAM,eAAe,CAAC,UAAwC,OAAO,UAAU,WAAW,QAAQ,MAAM;AAWxG,IAAM,8BAA8B,CAChC,MACA,WACA,+BAIC;AACD,QAAM,aAAa,KAAK;AACxB,QAAM,qBAAqB,CAAC;AAC5B,MAAI,aAAa,cAAc,cAAc,GAAG;AAC5C,UAAM,aAAa,KAAK,IAAI,CAAC,QAAQ,UAAU,KAAK;AACpD,WAAO,EAAE,iBAAiB,MAAM,oBAAoB,WAAW;AAAA,EACnE;AAEA,QAAM,UAAqC,CAAC;AAC5C,MAAI,eAAe;AAGnB,QAAM,SAAS,aAAa,MAAM,YAAY;AAE9C,MAAI,IAAI;AACR,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,MAAI;AAEJ,UAAQ,KAAK,KAAK,CAAC,CAAC;AACpB,qBAAmB,KAAK,CAAC;AAGzB,WAAS,IAAI,GAAG,IAAI,YAAY,GAAG,KAAK;AAEpC,QAAI,OAAO;AACX,QAAI,OAAO;AACX,QAAI,gBAAgB,KAAK,OAAO,IAAI,KAAK,KAAK,IAAI;AAClD,QAAI,cAAc,KAAK,OAAO,IAAI,KAAK,KAAK,IAAI;AAChD,kBAAc,
|
|
4
|
+
"sourcesContent": ["import type { FieldEntry } from '@splunk/visualizations-shared/dataSourceUtils';\nimport { startsWithNumber } from '@splunk/visualizations-shared/numberUtils';\nimport type { DashboardVizProps, DataSource, VizConfig } from '../interfaces';\nimport { VizBehavior } from '../interfaces';\nimport { ChartEvent } from '../interfaces/ChartEvent';\n\nexport const convertToArrOfObjects = (columns: (string | any[])[], fields: any[]): any[] => {\n if (!columns?.[0]?.length) return [];\n\n const data = [];\n\n for (let i = 0; i < columns[0].length; i += 1) {\n const newObj = {};\n fields.forEach((field, index) => {\n const fieldName = getFieldName(field);\n if (columns[index][i] === '') {\n newObj[fieldName] = null;\n } else {\n newObj[fieldName] = columns[index][i];\n }\n });\n data.push(newObj);\n }\n\n return data;\n};\n\nconst getFieldName = (field: FieldEntry | string): string => (typeof field === 'string' ? field : field.name);\n\n// LTTB algorithm which can be used to downsample time series data while striving to maintain\n// the spikes and overall shape of the chart\n// Copied from https://github.com/sveinn-steinarsson/flot-downsample/blob/0815010016fc94b1bbc6a010afb8aad13ada6d0d/jquery.flot.downsample.js\n// Modifications include:\n// 1) Convert to modern JavaScript(use const, let, and use array.push to push to last element of array)\n// 2) Convert to camel case\n// 3) Convert to TS and also return the indices of the points that are in the downsampled result.\n// 4) Add a new parameter preferredDownsampleIndices that correspond to the indices of points\n// that should be used in case of a tie of the max area in a bucket\nconst largestTriangleThreeBuckets = (\n data: [Date | number, number][],\n threshold: number,\n preferredDownsampleIndices: Set<number>\n): {\n downsampledData: [Date | number, number][];\n downsampledIndices: number[];\n} => {\n const dataLength = data.length;\n const downsampledIndices = [];\n if (threshold >= dataLength || threshold === 0) {\n const allIndices = data.map((values, index) => index);\n return { downsampledData: data, downsampledIndices: allIndices }; // Nothing to do\n }\n\n const sampled: [Date | number, number][] = [];\n let sampledIndex = 0;\n\n // Bucket size. Leave room for start and end data points\n const every = (dataLength - 2) / (threshold - 2);\n\n let a = 0; // Initially a is the first point in the triangle\n let maxAreaPoint: [Date | number, number];\n let maxArea: number | undefined;\n let area: number | undefined;\n let nextA: number | undefined;\n\n sampled.push(data[a]); // Always add the first point\n downsampledIndices.push(0);\n\n // eslint-disable-next-line no-plusplus\n for (let i = 0; i < threshold - 2; i++) {\n // Calculate point average for next bucket (containing c)\n let avgX = 0;\n let avgY = 0;\n let avgRangeStart = Math.floor((i + 1) * every) + 1;\n let avgRangeEnd = Math.floor((i + 2) * every) + 1;\n avgRangeEnd = Math.min(avgRangeEnd, dataLength);\n\n const avgRangeLength = avgRangeEnd - avgRangeStart;\n\n // eslint-disable-next-line no-plusplus\n for (; avgRangeStart < avgRangeEnd; avgRangeStart++) {\n avgX += Number(data[avgRangeStart][0]); // * 1 enforces Number (value may be Date)\n avgY += data[avgRangeStart][1] * 1;\n }\n avgX /= avgRangeLength;\n avgY /= avgRangeLength;\n\n // Get the range for this bucket\n let rangeOffs = Math.floor((i + 0) * every) + 1;\n const rangeTo = Math.floor((i + 1) * every) + 1;\n\n // Point a\n const pointAX = Number(data[a][0]); // Enforce Number (value may be Date)\n const pointAY = data[a][1] * 1;\n\n // eslint-disable-next-line no-multi-assign\n maxArea = area = -1;\n let maxAreaIndex = rangeOffs;\n\n // eslint-disable-next-line no-plusplus\n for (; rangeOffs < rangeTo; rangeOffs++) {\n // Calculate triangle area over three buckets\n area =\n Math.abs(\n (pointAX - avgX) * (data[rangeOffs][1] - pointAY) -\n (pointAX - Number(data[rangeOffs][0])) * (avgY - pointAY)\n ) * 0.5;\n // Modification: try to downsample the least amount of points possible when there are multiple series\n // If all points in a bucket have the same area, prioritize the one with an x index\n // that also existed from another series so we don't add another point unnecessarily.\n // By default LTTB picks the leftmost point in the bucket\n if (area > maxArea || (area === maxArea && preferredDownsampleIndices.has(rangeOffs))) {\n maxArea = area;\n maxAreaPoint = data[rangeOffs];\n nextA = rangeOffs; // Next a is this b\n // Modification: save the index of the point with the most area\n maxAreaIndex = rangeOffs;\n }\n }\n\n // eslint-disable-next-line no-plusplus\n sampled[sampledIndex++] = maxAreaPoint; // Pick this point from the bucket\n downsampledIndices.push(maxAreaIndex);\n a = nextA; // This a is the next a (chosen b)\n }\n\n // eslint-disable-next-line no-plusplus\n sampled[sampledIndex++] = data[dataLength - 1]; // Always add last\n downsampledIndices.push(dataLength - 1);\n\n return { downsampledData: sampled, downsampledIndices };\n};\n\nexport type DownsampleOptions = { threshold: number } & Pick<DashboardVizProps, 'dataSources' | 'options'>;\n\ntype CoerceYColumnResult = {\n canDownsampleColumn: boolean;\n canLooselyCoerceSomeValues: boolean;\n coercedColumn: number[];\n};\n\n/**\n * Strictly coerces the entire column to numbers if it only consists of numeric strings or numbers. Also determines\n * if at least one of the values in the column can be loosely coerced to a number.\n * If the column cannot be strictly downsampled (if it contains nulls or non-numeric strings), returns an empty array and\n * returns that it cannot downsample the column.\n */\nconst strictlyCoerceYColumn = (\n column: (string | number)[] | number[],\n options: DownsampleOptions['options']\n): CoerceYColumnResult => {\n const isNullCoercionEnabled = options.nullValueDisplay === 'zero';\n // Splunk charting allows for numbers in formats such as negative hex that\n // Number() does not support and also allows loose coercion of hex numbers (but not other formats)\n // We want to identify columns which contain at least one value that can be loosely coerced\n const canLooselyCoerceSomeValues = column.some(\n value => startsWithNumber(`${value}`) || (isNullCoercionEnabled && value === null)\n );\n\n // If not all values in column can be strictly coerced to a number, we do not downsample\n const coercedColumn: number[] = [];\n const canDownsampleColumn = !column.some(value => {\n const coercedValue = Number(value);\n const coerceValueToZero = isNullCoercionEnabled && value === null;\n\n // if it can't be parsed or isn't safe, fail\n if (\n Number.isNaN(coercedValue) ||\n coercedValue <= Number.MIN_SAFE_INTEGER ||\n coercedValue >= Number.MAX_SAFE_INTEGER ||\n (typeof value !== 'string' && typeof value !== 'number' && !coerceValueToZero)\n ) {\n return true;\n }\n // save value and continue to next\n coercedColumn.push(coercedValue);\n return false;\n });\n\n return {\n canDownsampleColumn,\n canLooselyCoerceSomeValues,\n coercedColumn: canDownsampleColumn ? coercedColumn : [],\n };\n};\n\n/**\n * Tries to coerce the x-column to numbers or dates, if it is eligible for downsampling.\n * Only strictly increasing x-columns are eligible for downsampling.\n * If the column is not eligible for downsampling, returns an empty array.\n */\nconst strictlyCoerceXColumn = (column: (string | number)[], fieldType: string): Date[] | number[] => {\n if (fieldType === 'number') {\n const coercedXColumn = column.map(Number);\n if (isColumnStrictlyIncreasing(coercedXColumn, fieldType)) {\n return coercedXColumn;\n }\n } else if (fieldType === 'time') {\n const coercedXColumn = column.map(xValue => new Date(xValue));\n if (isColumnStrictlyIncreasing(coercedXColumn, fieldType)) {\n return coercedXColumn;\n }\n }\n return [];\n};\n\nexport const isDownsamplingEnabledForViz = ({ vizConfig }: { vizConfig: VizConfig }) => {\n return vizConfig.supports?.includes(VizBehavior.DOWNSAMPLING);\n};\n\nexport const calculateThresholdOnRangeSelect = ({\n firstIndex,\n lastIndex,\n dataSources,\n width,\n}: Pick<DashboardVizProps, 'dataSources'> & {\n firstIndex: number;\n lastIndex: number;\n width: number | string;\n}): number => {\n const window = lastIndex - firstIndex + 1;\n // eslint-disable-next-line no-unsafe-optional-chaining\n const ratio = Math.round(Number(dataSources?.primary?.data?.columns[0]?.length / window) * 10) / 10;\n return Math.round(ratio * Number(width));\n};\n\n/**\n * Calculates the downsampling threshold based on the range selection. If search zoom is enabled or there is no selection,\n * then returns the width of the visualization.\n *\n * Otherwise calculates the threshold based on the ratio of the window selected compared to the size of the non-downsampled\n * data sources. Returns null if the chart event's dataset does not match the passed in primary data source or if the chart is zoomed\n * in for a categorical chart.\n */\nexport const calculateDownsamplingThreshold = ({\n enableSearchZoom,\n dataSources,\n selectChartEvent,\n width,\n xField,\n}: {\n enableSearchZoom: boolean;\n dataSources: Record<string, DataSource> | null;\n selectChartEvent: ChartEvent<'chartRangeSelect'> | null;\n width: number;\n xField: string;\n}): number | null => {\n if (enableSearchZoom || !selectChartEvent) {\n return Number(width);\n }\n\n const primaryDataSource = dataSources?.primary;\n if (!primaryDataSource) {\n return null;\n }\n\n const { startXIndex, endXIndex, currentTarget } = selectChartEvent;\n\n try {\n const xFieldIndex = primaryDataSource?.data?.fields.findIndex(field => {\n const name = typeof field === 'string' ? field : field.name;\n return name === xField;\n });\n // .indexOf is not usable here: dataSet.fields is a union type (FieldEntry[] & string[]), so indexOf(xField) fails to type-check\n const downsampledXFieldIndex = currentTarget.dataSet?.fields.findIndex(field => field === xField); // NOSONAR typescript:S7753 - see note above\n\n if (xFieldIndex === -1 || downsampledXFieldIndex === -1) {\n return null;\n }\n\n const fullSeries = primaryDataSource?.data?.columns[xFieldIndex];\n const downsampledSeries = currentTarget.dataSet.seriesList[downsampledXFieldIndex];\n\n const firstIndex = fullSeries.indexOf(downsampledSeries[startXIndex]);\n const lastIndex = fullSeries.indexOf(downsampledSeries[endXIndex]);\n\n if (firstIndex >= 0 && lastIndex >= 0 && firstIndex <= lastIndex) {\n return calculateThresholdOnRangeSelect({\n firstIndex,\n lastIndex,\n dataSources,\n width,\n });\n }\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error('Error occurred while setting downsample threshold on range select event', e);\n }\n\n return null;\n};\n\nconst isColumnStrictlyIncreasing = (column: (number | Date)[], fieldType: 'number' | 'time') => {\n return column.every((value, index) => {\n if (fieldType === 'number') {\n if (Number.isNaN(value)) {\n return false;\n }\n }\n\n if (fieldType === 'time') {\n if (Number.isNaN((value as Date).getTime())) {\n return false;\n }\n }\n if (index === 0) {\n return true;\n }\n return value > column[index - 1];\n });\n};\n\n/**\n * Verifies that all of the columns that are displayed in a chart can be downsampled. Valid columns that can be\n * displayed are those that contain at least one number. We can only downsample columns that only consist of numbers.\n *\n * If all columns can be downsampled, returns the x column coerced to time/number and y columns coerced to numbers.\n * If not all columns can be downsampled, then returns empty arrays for both x and y\n */\nconst tryToCoerceAllDisplayedFields = (\n ds: DataSource,\n xField: string,\n yFields: Set<string>,\n fieldTypes: string[],\n options: DownsampleOptions['options']\n): { xColumn: Date[] | number[]; yColumns: number[][] } => {\n let xColumn: Date[] | number[] = [];\n const yColumns: number[][] = [];\n\n const canDownsample = !ds.data.fields.some((field, index) => {\n const fieldName = getFieldName(field);\n const fieldType = fieldTypes[index] ?? 'unknown';\n const column = ds.data.columns[index];\n let hasDisplayedColumnThatCantBeDownsampled = false;\n\n if (fieldName === xField) {\n xColumn = strictlyCoerceXColumn(column, fieldType);\n } else if (yFields.has(fieldName)) {\n const { coercedColumn, canLooselyCoerceSomeValues, canDownsampleColumn } = strictlyCoerceYColumn(\n ds.data.columns[index],\n options\n );\n // do not perform downsampling if a column can possibly be displayed but cannot\n // be downsampled using LTTB\n hasDisplayedColumnThatCantBeDownsampled = canLooselyCoerceSomeValues && !canDownsampleColumn;\n if (hasDisplayedColumnThatCantBeDownsampled) {\n return true;\n }\n if (canDownsampleColumn) {\n yColumns.push(coercedColumn);\n }\n }\n return false;\n });\n\n if (canDownsample) {\n return { xColumn, yColumns };\n }\n return { xColumn: [], yColumns: [] };\n};\n\nconst pickIndicesFromDataSource = (ds: DataSource, indices: Set<number>): DataSource => {\n const sortedIndices = Array.from(indices).sort((a: number, b: number) => a - b);\n const slicedColumns = [];\n ds.data.columns.forEach(column => {\n const slicedColumn = [];\n sortedIndices.forEach(index => {\n slicedColumn.push(column[index]);\n });\n slicedColumns.push(slicedColumn);\n });\n\n // update data columns with downsampled columns\n return {\n ...ds,\n data: {\n ...ds.data,\n columns: slicedColumns,\n },\n };\n};\n\nexport const downsampleDataSources = ({ dataSources, threshold, options }: DownsampleOptions) => {\n const primaryDS = dataSources?.primary;\n // only downsample time series when number of data points are over threshold\n const numPoints = primaryDS?.data?.columns[0]?.length ?? 0;\n if (Number.isNaN(threshold) || numPoints <= threshold || threshold < 2) {\n return dataSources;\n }\n\n const { xField, yFields, fieldTypes } = options;\n if (!xField || !yFields?.length || !fieldTypes?.length) {\n return dataSources;\n }\n\n const nonInternalYFields = new Set<string>(yFields.filter(yField => !yField.startsWith('_')));\n const maxPointsInDownsample = Math.min(nonInternalYFields.size * threshold, numPoints);\n\n // Do not try to downsample if there are too many downsampled pts\n // At the worst case, each series has non-overlapping downsampled pts\n // which will mean that all points will be included in the downsampled result\n // This will just lead to additional overhead due to coercing each\n // x and y field to number\n if (maxPointsInDownsample >= numPoints) {\n return dataSources;\n }\n\n const { xColumn, yColumns } = tryToCoerceAllDisplayedFields(\n primaryDS,\n xField,\n nonInternalYFields,\n fieldTypes,\n options\n );\n\n if (!yColumns.length || !xColumn.length) {\n return dataSources;\n }\n\n const downsampledDataSources = { ...dataSources };\n const downsampledIndices = new Set<number>();\n\n yColumns.forEach((yColumn, columnIndex) => {\n // perform LTTB downsampling for current series, LTTB takes an [x, y] pair\n const xyPair: [Date | number, number][] = yColumn.map((yValue, index) => {\n return [xColumn[index], yValue];\n });\n\n try {\n const { downsampledIndices: downsampledIndicesForSeries } = largestTriangleThreeBuckets(\n xyPair,\n threshold,\n downsampledIndices\n );\n downsampledIndicesForSeries.forEach(downsampleIndex => downsampledIndices.add(downsampleIndex));\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error(`Error occurred while downsampling column ${columnIndex}`, e);\n }\n });\n // update data columns with downsampled columns\n downsampledDataSources.primary = pickIndicesFromDataSource(primaryDS, downsampledIndices);\n\n return downsampledDataSources;\n};\n", "\nimport * as defaultImport from \"@splunk/visualizations-shared/numberUtils\";\nexport * from \"@splunk/visualizations-shared/numberUtils\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -49,10 +49,10 @@ var FeatureFlags_default = "default" in defaultImport ? defaultImport.default :
|
|
|
49
49
|
|
|
50
50
|
// src/common/utils/featureFlagUtils.ts
|
|
51
51
|
var getFeatureFlag = (context, flagName) => {
|
|
52
|
-
if (context && Object.keys(context).
|
|
52
|
+
if (context && Object.keys(context).includes(flagName)) {
|
|
53
53
|
return context[flagName];
|
|
54
54
|
}
|
|
55
|
-
if (Object.keys(FeatureFlags_default).
|
|
55
|
+
if (Object.keys(FeatureFlags_default).includes(flagName)) {
|
|
56
56
|
return FeatureFlags_default[flagName];
|
|
57
57
|
}
|
|
58
58
|
return false;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/common/utils/featureFlagUtils.ts", "esm-externals:@splunk/visualization-context/FeatureFlags"],
|
|
4
|
-
"sourcesContent": ["import * as React from 'react';\nimport FeatureFlags from '@splunk/visualization-context/FeatureFlags';\n\nexport const getFeatureFlag = (\n context: React.Context<any> | null | undefined | Record<keyof typeof FeatureFlags, boolean>,\n flagName: string\n): boolean => {\n // look for feature flag in context first\n if (context && Object.keys(context).
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AACA,oBAA+B;AAC/B,iCAAc;AACd,IAAO,uBAAS,aAAa,gBAA8B,wBAAU;;;ADA9D,IAAM,iBAAiB,CAC1B,SACA,aACU;AAEV,MAAI,WAAW,OAAO,KAAK,OAAO,EAAE,
|
|
4
|
+
"sourcesContent": ["import * as React from 'react';\nimport FeatureFlags from '@splunk/visualization-context/FeatureFlags';\n\nexport const getFeatureFlag = (\n context: React.Context<any> | null | undefined | Record<keyof typeof FeatureFlags, boolean>,\n flagName: string\n): boolean => {\n // look for feature flag in context first\n if (context && Object.keys(context).includes(flagName)) {\n return context[flagName];\n }\n\n // fall back to defaults\n if (Object.keys(FeatureFlags).includes(flagName)) {\n return FeatureFlags[flagName];\n }\n\n // fall back to false\n return false;\n};\n", "\nimport * as defaultImport from \"@splunk/visualization-context/FeatureFlags\";\nexport * from \"@splunk/visualization-context/FeatureFlags\";\nexport default ('default' in defaultImport ? defaultImport.default : defaultImport);\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AACA,oBAA+B;AAC/B,iCAAc;AACd,IAAO,uBAAS,aAAa,gBAA8B,wBAAU;;;ADA9D,IAAM,iBAAiB,CAC1B,SACA,aACU;AAEV,MAAI,WAAW,OAAO,KAAK,OAAO,EAAE,SAAS,QAAQ,GAAG;AACpD,WAAO,QAAQ,QAAQ;AAAA,EAC3B;AAGA,MAAI,OAAO,KAAK,oBAAY,EAAE,SAAS,QAAQ,GAAG;AAC9C,WAAO,qBAAa,QAAQ;AAAA,EAChC;AAGA,SAAO;AACX;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -47,7 +47,7 @@ var getFocusableElements = () => {
|
|
|
47
47
|
return Array.from(document.querySelectorAll(DEFAULT_FOCUSABLE_SELECTORS));
|
|
48
48
|
};
|
|
49
49
|
var isElementHidden = (element) => {
|
|
50
|
-
const computedStyle =
|
|
50
|
+
const computedStyle = globalThis.getComputedStyle(element);
|
|
51
51
|
return element.hasAttribute("hidden") || element.getAttribute("aria-hidden") === "true" || computedStyle.display === "none" || computedStyle.visibility === "hidden";
|
|
52
52
|
};
|
|
53
53
|
var isVisibleFocusableElement = (element) => {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/common/utils/focusUtils.ts"],
|
|
4
|
-
"sourcesContent": ["import * as React from 'react';\n\nconst DEFAULT_FOCUSABLE_SELECTORS = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([disabled]):not([hidden])',\n 'area[href]',\n 'iframe',\n 'object',\n 'embed',\n '[contenteditable]:not([contenteditable=\"false\"])',\n 'summary',\n 'audio[controls]',\n 'video[controls]',\n].join(',');\n\nconst getFocusableElements = (): HTMLElement[] => {\n return Array.from(document.querySelectorAll(DEFAULT_FOCUSABLE_SELECTORS));\n};\n\nconst isElementHidden = (element: HTMLElement): boolean => {\n const computedStyle =
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,IAAM,8BAA8B;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,EAAE,KAAK,GAAG;AAEV,IAAM,uBAAuB,MAAqB;AAC9C,SAAO,MAAM,KAAK,SAAS,iBAAiB,2BAA2B,CAAC;AAC5E;AAEA,IAAM,kBAAkB,CAAC,YAAkC;AACvD,QAAM,gBAAgB,
|
|
4
|
+
"sourcesContent": ["import * as React from 'react';\n\nconst DEFAULT_FOCUSABLE_SELECTORS = [\n 'a[href]',\n 'button:not([disabled])',\n 'input:not([disabled])',\n 'select:not([disabled])',\n 'textarea:not([disabled])',\n '[tabindex]:not([disabled]):not([hidden])',\n 'area[href]',\n 'iframe',\n 'object',\n 'embed',\n '[contenteditable]:not([contenteditable=\"false\"])',\n 'summary',\n 'audio[controls]',\n 'video[controls]',\n].join(',');\n\nconst getFocusableElements = (): HTMLElement[] => {\n return Array.from(document.querySelectorAll(DEFAULT_FOCUSABLE_SELECTORS));\n};\n\nconst isElementHidden = (element: HTMLElement): boolean => {\n const computedStyle = globalThis.getComputedStyle(element);\n\n return (\n element.hasAttribute('hidden') ||\n element.getAttribute('aria-hidden') === 'true' ||\n computedStyle.display === 'none' ||\n computedStyle.visibility === 'hidden'\n );\n};\n\nconst isVisibleFocusableElement = (element: HTMLElement): boolean => {\n let currentElement: HTMLElement | null = element;\n\n while (currentElement) {\n if (isElementHidden(currentElement)) {\n return false;\n }\n\n currentElement = currentElement.parentElement;\n }\n\n return true;\n};\n\nconst resolveTargetElement = (container: ParentNode, selector: string): Element | null => {\n if (container instanceof Element && container.matches(selector)) {\n return container;\n }\n\n return container.querySelector(selector);\n};\n\nconst findFirstFocusableElementAfter = (container: ParentNode, selector: string): HTMLElement | null => {\n const targetElement = resolveTargetElement(container, selector);\n\n if (!targetElement) {\n return null;\n }\n\n return (\n getFocusableElements().find(element => {\n if (targetElement.contains(element)) {\n return false;\n }\n\n const relativePosition = targetElement.compareDocumentPosition(element);\n\n return (\n relativePosition === Node.DOCUMENT_POSITION_FOLLOWING && isVisibleFocusableElement(element)\n );\n }) || null\n );\n};\n\nconst findFirstFocusableElementInside = (container: ParentNode, selector: string): HTMLElement | null => {\n const targetElement = resolveTargetElement(container, selector);\n\n if (!targetElement) {\n return null;\n }\n\n return (\n getFocusableElements().find(element => {\n return (\n element !== targetElement &&\n targetElement.contains(element) &&\n isVisibleFocusableElement(element)\n );\n }) || null\n );\n};\n\nexport const moveFocusOutside = (container: ParentNode, selector: string, event: React.MouseEvent): void => {\n event.preventDefault();\n findFirstFocusableElementAfter(container, selector)?.focus();\n};\n\nexport const moveFocusInto = (container: ParentNode, selector: string, event: React.MouseEvent): void => {\n event.preventDefault();\n findFirstFocusableElementInside(container, selector)?.focus();\n};\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,IAAM,8BAA8B;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ,EAAE,KAAK,GAAG;AAEV,IAAM,uBAAuB,MAAqB;AAC9C,SAAO,MAAM,KAAK,SAAS,iBAAiB,2BAA2B,CAAC;AAC5E;AAEA,IAAM,kBAAkB,CAAC,YAAkC;AACvD,QAAM,gBAAgB,WAAW,iBAAiB,OAAO;AAEzD,SACI,QAAQ,aAAa,QAAQ,KAC7B,QAAQ,aAAa,aAAa,MAAM,UACxC,cAAc,YAAY,UAC1B,cAAc,eAAe;AAErC;AAEA,IAAM,4BAA4B,CAAC,YAAkC;AACjE,MAAI,iBAAqC;AAEzC,SAAO,gBAAgB;AACnB,QAAI,gBAAgB,cAAc,GAAG;AACjC,aAAO;AAAA,IACX;AAEA,qBAAiB,eAAe;AAAA,EACpC;AAEA,SAAO;AACX;AAEA,IAAM,uBAAuB,CAAC,WAAuB,aAAqC;AACtF,MAAI,qBAAqB,WAAW,UAAU,QAAQ,QAAQ,GAAG;AAC7D,WAAO;AAAA,EACX;AAEA,SAAO,UAAU,cAAc,QAAQ;AAC3C;AAEA,IAAM,iCAAiC,CAAC,WAAuB,aAAyC;AACpG,QAAM,gBAAgB,qBAAqB,WAAW,QAAQ;AAE9D,MAAI,CAAC,eAAe;AAChB,WAAO;AAAA,EACX;AAEA,SACI,qBAAqB,EAAE,KAAK,aAAW;AACnC,QAAI,cAAc,SAAS,OAAO,GAAG;AACjC,aAAO;AAAA,IACX;AAEA,UAAM,mBAAmB,cAAc,wBAAwB,OAAO;AAEtE,WACI,qBAAqB,KAAK,+BAA+B,0BAA0B,OAAO;AAAA,EAElG,CAAC,KAAK;AAEd;AAEA,IAAM,kCAAkC,CAAC,WAAuB,aAAyC;AACrG,QAAM,gBAAgB,qBAAqB,WAAW,QAAQ;AAE9D,MAAI,CAAC,eAAe;AAChB,WAAO;AAAA,EACX;AAEA,SACI,qBAAqB,EAAE,KAAK,aAAW;AACnC,WACI,YAAY,iBACZ,cAAc,SAAS,OAAO,KAC9B,0BAA0B,OAAO;AAAA,EAEzC,CAAC,KAAK;AAEd;AAEO,IAAM,mBAAmB,CAAC,WAAuB,UAAkB,UAAkC;AAhG5G;AAiGI,QAAM,eAAe;AACrB,uCAA+B,WAAW,QAAQ,MAAlD,mBAAqD;AACzD;AAEO,IAAM,gBAAgB,CAAC,WAAuB,UAAkB,UAAkC;AArGzG;AAsGI,QAAM,eAAe;AACrB,wCAAgC,WAAW,QAAQ,MAAnD,mBAAsD;AAC1D;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mapUtils.d.ts","sourceRoot":"","sources":["../../src/common/utils/mapUtils.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,kBAAkB,GAAI,WAAM,EAAE,gBAAW,EAAE,YAAO,
|
|
1
|
+
{"version":3,"file":"mapUtils.d.ts","sourceRoot":"","sources":["../../src/common/utils/mapUtils.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,kBAAkB,GAAI,WAAM,EAAE,gBAAW,EAAE,YAAO,QAoD9D,CAAC"}
|