diff --git a/dep-graph/dep-graph/src/app/app.ts b/dep-graph/dep-graph/src/app/app.ts index 9f6b1e9915..efa5380e9f 100644 --- a/dep-graph/dep-graph/src/app/app.ts +++ b/dep-graph/dep-graph/src/app/app.ts @@ -2,10 +2,11 @@ import type { DepGraphClientResponse } from '@nrwl/workspace/src/command-line/dep-graph'; import { fromEvent } from 'rxjs'; import { startWith } from 'rxjs/operators'; +import tippy from 'tippy.js'; import { DebuggerPanel } from './debugger-panel'; import { useGraphService } from './graph.service'; import { useDepGraphService } from './machines/dep-graph.service'; -import { DepGraphUIEvents, DepGraphSend } from './machines/interfaces'; +import { DepGraphSend } from './machines/interfaces'; import { AppConfig, DEFAULT_CONFIG, ProjectGraphService } from './models'; import { SidebarComponent } from './ui-sidebar/sidebar'; @@ -18,6 +19,8 @@ export class AppComponent { private send: DepGraphSend; + private downloadImageButton: HTMLButtonElement; + constructor( private config: AppConfig = DEFAULT_CONFIG, private projectGraphService: ProjectGraphService @@ -27,8 +30,14 @@ export class AppComponent { state$.subscribe((state) => { if (state.context.selectedProjects.length !== 0) { document.getElementById('no-projects-chosen').style.display = 'none'; + if (this.downloadImageButton) { + this.downloadImageButton.classList.remove('opacity-0'); + } } else { document.getElementById('no-projects-chosen').style.display = 'flex'; + if (this.downloadImageButton) { + this.downloadImageButton.classList.add('opacity-0'); + } } }); @@ -43,6 +52,33 @@ export class AppComponent { 5000 ); } + + this.downloadImageButton = document.querySelector( + '[data-cy="downloadImageButton"]' + ); + + this.downloadImageButton.addEventListener('click', () => { + const graph = useGraphService(); + const data = graph.getImage(); + + var downloadLink = document.createElement('a'); + downloadLink.href = data; + downloadLink.download = 'graph.png'; + // this is necessary as link.click() does not work on the latest firefox + downloadLink.dispatchEvent( + new MouseEvent('click', { + bubbles: true, + cancelable: true, + view: window, + }) + ); + }); + + tippy(this.downloadImageButton, { + content: 'Download Graph as PNG', + placement: 'right', + theme: 'nx', + }); } private async loadProjectGraph(projectGraphId: string) { diff --git a/dep-graph/dep-graph/src/app/graph.service.ts b/dep-graph/dep-graph/src/app/graph.service.ts index eced47c014..8a0334580c 100644 --- a/dep-graph/dep-graph/src/app/graph.service.ts +++ b/dep-graph/dep-graph/src/app/graph.service.ts @@ -7,7 +7,7 @@ export function useGraphService(): GraphService { if (!graphService) { graphService = new GraphService( new GraphTooltipService(), - 'graph-container' + 'cytoscape-graph' ); } diff --git a/dep-graph/dep-graph/src/app/graph.ts b/dep-graph/dep-graph/src/app/graph.ts index dfa2f9d31c..c594795575 100644 --- a/dep-graph/dep-graph/src/app/graph.ts +++ b/dep-graph/dep-graph/src/app/graph.ts @@ -281,6 +281,10 @@ export class GraphService { this.listenForProjectNodeHovers(); } + getImage() { + return this.renderGraph.png({ bg: '#fff', full: true }); + } + private includeProjectsByDepth( projects: cy.NodeCollection | cy.NodeSingular, depth: number = -1 diff --git a/dep-graph/dep-graph/src/app/ui-sidebar/display-options-panel.ts b/dep-graph/dep-graph/src/app/ui-sidebar/display-options-panel.ts index d1c5508844..3db236220d 100644 --- a/dep-graph/dep-graph/src/app/ui-sidebar/display-options-panel.ts +++ b/dep-graph/dep-graph/src/app/ui-sidebar/display-options-panel.ts @@ -1,3 +1,4 @@ +import { useGraphService } from '../graph.service'; import { useDepGraphService } from '../machines/dep-graph.service'; import { DepGraphSend } from '../machines/interfaces'; import { removeChildrenFromContainer } from '../util'; diff --git a/dep-graph/dep-graph/src/index.html b/dep-graph/dep-graph/src/index.html index 2610b921f2..a53bfeb3af 100644 --- a/dep-graph/dep-graph/src/index.html +++ b/dep-graph/dep-graph/src/index.html @@ -142,7 +142,47 @@

Please select projects in the sidebar.

-
+
+
+ +
diff --git a/dep-graph/dep-graph/src/styles.scss b/dep-graph/dep-graph/src/styles.scss index 3b298c4bd9..0a0d006916 100644 --- a/dep-graph/dep-graph/src/styles.scss +++ b/dep-graph/dep-graph/src/styles.scss @@ -29,7 +29,6 @@ html { box-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.05); background-color: white; color: hsla(217, 19%, 27%, 1); - margin-bottom: 1rem; padding: 0.375rem; min-width: 250px; @@ -37,9 +36,14 @@ html { padding: 0.375rem; } - &[data-placement^='top'] > .tippy-arrow::before { - border-top-color: $gray; + &[data-placement^='top'] { + margin-bottom: 1rem; + + & > .tippy-arrow::before { + border-top-color: $gray; + } } + &[data-placement^='bottom'] > .tippy-arrow::before { border-bottom-color: $gray; } @@ -95,7 +99,8 @@ html { justify-content: center; } -#graph-container { +#graph-container, +#cytoscape-graph { width: 100%; height: 100%; }