From 5534d92d76e55fc3c3464e23f9114a4a927c0db4 Mon Sep 17 00:00:00 2001 From: Gordon Smith Date: Tue, 14 Nov 2023 08:27:02 +0100 Subject: [PATCH] HPCC-30772 Add "Download DOT" to metrics Signed-off-by: Gordon Smith --- esp/src/src-react/components/Metrics.tsx | 130 +++++++++++++---------- esp/src/src-react/util/metricGraph.ts | 2 +- esp/src/src/nls/hpcc.ts | 1 + 3 files changed, 75 insertions(+), 58 deletions(-) diff --git a/esp/src/src-react/components/Metrics.tsx b/esp/src/src-react/components/Metrics.tsx index 1292c779860..717533a92ca 100644 --- a/esp/src/src-react/components/Metrics.tsx +++ b/esp/src/src-react/components/Metrics.tsx @@ -154,63 +154,6 @@ export const Metrics: React.FunctionComponent = ({ pushUrl(`/workunits/${wuid}/metrics/${selection}`); }, [wuid, selection]); - // Command Bar --- - const buttons = React.useMemo((): ICommandBarItemProps[] => [ - { - key: "refresh", text: nlsHPCC.Refresh, iconProps: { iconName: "Refresh" }, - onClick: () => refresh() - }, - { - key: "hotspot", text: nlsHPCC.Hotspots, iconProps: { iconName: "SpeedHigh" }, - disabled: !hotspots, onClick: () => onHotspot() - }, - { key: "divider_1", itemType: ContextualMenuItemType.Divider, onRender: () => }, - { - key: "timeline", text: nlsHPCC.Timeline, canCheck: true, checked: showTimeline, iconProps: { iconName: "TimelineProgress" }, - onClick: () => { - setShowTimeline(!showTimeline); - } - }, - { - key: "options", text: nlsHPCC.Options, iconProps: { iconName: "Settings" }, - onClick: () => { - setOptions({ ...options, layout: dockpanel.layout() }); - setShowMetricOptions(true); - } - } - ], [dockpanel, hotspots, onHotspot, options, refresh, setOptions, showTimeline]); - - const formatColumns = React.useMemo((): Utility.ColumnMap => { - const copyColumns: Utility.ColumnMap = {}; - for (const key in columns) { - copyColumns[key] = { - field: key, - label: key - }; - } - return copyColumns; - }, [columns]); - - const rightButtons = React.useMemo((): ICommandBarItemProps[] => [ - { - key: "copy", text: nlsHPCC.CopyToClipboard, disabled: !metrics.length || !navigator?.clipboard?.writeText, iconOnly: true, iconProps: { iconName: "Copy" }, - onClick: () => { - const tsv = Utility.formatAsDelim(formatColumns, metrics, "\t"); - navigator?.clipboard?.writeText(tsv); - } - }, - { - key: "download", text: nlsHPCC.DownloadToCSV, disabled: !metrics.length, iconOnly: true, iconProps: { iconName: "Download" }, - onClick: () => { - const csv = Utility.formatAsDelim(formatColumns, metrics, ","); - Utility.downloadText(csv, `metrics-${wuid}.csv`); - } - }, { - key: "fullscreen", title: nlsHPCC.MaximizeRestore, iconProps: { iconName: fullscreen ? "ChromeRestore" : "FullScreen" }, - onClick: () => setFullscreen(!fullscreen) - } - ], [formatColumns, fullscreen, metrics, wuid]); - // Timeline --- const timeline = useConst(() => new WUTimelinePatched() .maxZoom(Number.MAX_SAFE_INTEGER) @@ -548,6 +491,79 @@ export const Metrics: React.FunctionComponent = ({ saveOptions(); }, [options, saveOptions, setOptions]); + // Command Bar --- + const buttons = React.useMemo((): ICommandBarItemProps[] => [ + { + key: "refresh", text: nlsHPCC.Refresh, iconProps: { iconName: "Refresh" }, + onClick: () => refresh() + }, + { + key: "hotspot", text: nlsHPCC.Hotspots, iconProps: { iconName: "SpeedHigh" }, + disabled: !hotspots, onClick: () => onHotspot() + }, + { key: "divider_1", itemType: ContextualMenuItemType.Divider, onRender: () => }, + { + key: "timeline", text: nlsHPCC.Timeline, canCheck: true, checked: showTimeline, iconProps: { iconName: "TimelineProgress" }, + onClick: () => { + setShowTimeline(!showTimeline); + } + }, + { + key: "options", text: nlsHPCC.Options, iconProps: { iconName: "Settings" }, + onClick: () => { + setOptions({ ...options, layout: dockpanel.layout() }); + setShowMetricOptions(true); + } + } + ], [dockpanel, hotspots, onHotspot, options, refresh, setOptions, showTimeline]); + + const formatColumns = React.useMemo((): Utility.ColumnMap => { + const copyColumns: Utility.ColumnMap = {}; + for (const key in columns) { + copyColumns[key] = { + field: key, + label: key + }; + } + return copyColumns; + }, [columns]); + + const rightButtons = React.useMemo((): ICommandBarItemProps[] => [ + { + key: "copy", text: nlsHPCC.CopyToClipboard, disabled: !metrics.length || !navigator?.clipboard?.writeText, iconOnly: true, iconProps: { iconName: "Copy" }, + onClick: () => { + const tsv = Utility.formatAsDelim(formatColumns, metrics, "\t"); + navigator?.clipboard?.writeText(tsv); + } + }, + { + key: "download", text: nlsHPCC.DownloadToCSV, disabled: !metrics.length, iconOnly: true, iconProps: { iconName: "Download" }, + subMenuProps: { + items: [{ + key: "downloadCSV", + text: nlsHPCC.DownloadToCSV, + iconProps: { iconName: "Table" }, + onClick: () => { + const csv = Utility.formatAsDelim(formatColumns, metrics, ","); + Utility.downloadText(csv, `metrics-${wuid}.csv`); + } + }, + { + key: "downloadDOT", + text: nlsHPCC.DownloadToDOT, + iconProps: { iconName: "Relationship" }, + onClick: () => { + const dot = metricGraph.graphTpl(selectedMetrics, options); + Utility.downloadText(dot, `metrics-${wuid}.dot`); + } + }] + } + }, { + key: "fullscreen", title: nlsHPCC.MaximizeRestore, iconProps: { iconName: fullscreen ? "ChromeRestore" : "FullScreen" }, + onClick: () => setFullscreen(!fullscreen) + } + ], [formatColumns, fullscreen, metricGraph, metrics, options, selectedMetrics, wuid]); + return diff --git a/esp/src/src-react/util/metricGraph.ts b/esp/src/src-react/util/metricGraph.ts index fb6bbae9cc6..de0cd30df87 100644 --- a/esp/src/src-react/util/metricGraph.ts +++ b/esp/src/src-react/util/metricGraph.ts @@ -177,7 +177,7 @@ export class MetricGraph extends Graph2 { }); data.forEach((scope: IScope) => { - if (scope.type === "edge") { + if (scope.type === "edge" && scope.IdSource !== undefined && scope.IdTarget !== undefined) { if (!this.vertexExists(this._activityIndex[(scope as IScopeEdge).IdSource])) logger.warning(`Missing vertex: ${(scope as IScopeEdge).IdSource}`); else if (!this.vertexExists(this._activityIndex[(scope as IScopeEdge).IdTarget])) { diff --git a/esp/src/src/nls/hpcc.ts b/esp/src/src/nls/hpcc.ts index d244520eb63..1fe2ef88fde 100644 --- a/esp/src/src/nls/hpcc.ts +++ b/esp/src/src/nls/hpcc.ts @@ -254,6 +254,7 @@ export = { Downloads: "Downloads", DownloadToCSV: "Download to CSV", DownloadToCSVNonFlatWarning: "Please note: downloading files containing nested datasets as comma-separated data may not be formatted as expected", + DownloadToDOT: "Download to DOT", DownloadSelectionAsCSV: "Download selection as CSV", DropZone: "Drop Zone", DueToInctivity: "You will be logged out of all ECL Watch sessions in 3 minutes due to inactivity.",