Skip to content

Commit

Permalink
fix: fullscreen & export png (#703)
Browse files Browse the repository at this point in the history
* fix: fullscreen & export png

* fix: remove log
  • Loading branch information
mizy authored Dec 8, 2023
1 parent 9fb3ed7 commit c0f9b03
Show file tree
Hide file tree
Showing 15 changed files with 335 additions and 140 deletions.
6 changes: 6 additions & 0 deletions app/pages/Console/OutputBox/ForceGraph/index.module.less
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
@import '@app/common.less';

.forceGraphCanvas {
height: 100%;
}

.forceGraph {
position: relative;
width: 100%;
height: 100%;
flex: auto;
overflow: hidden;
}

.graphLoading {
position: absolute;
top: 50%;
Expand All @@ -19,6 +22,7 @@
position: absolute;
right: 20px;
bottom: 20px;

:global {
.anticon {
width: 38px;
Expand All @@ -30,9 +34,11 @@
align-items: center;
justify-content: center;
cursor: pointer;

svg {
color: @darkBlue;
}

&:not(:last-child) {
margin-right: 8px;
}
Expand Down
3 changes: 2 additions & 1 deletion app/pages/Console/OutputBox/ForceGraph/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ interface IProps {
spaceVidType: string;
space: string;
onGraphInit: (graph: GraphStore) => void;
style?: React.CSSProperties;
}
const ForceGraphBox = (props: IProps) => {
const [uuid] = useState(uuidv4());
Expand Down Expand Up @@ -53,7 +54,7 @@ const ForceGraphBox = (props: IProps) => {
const { nodes, links, nodesSelected, linksSelected } = currentGraph || {};
const selected = nodesSelected && (nodesSelected.size > 0 || linksSelected.size > 0);
return (
<div className={styles.forceGraphCanvas}>
<div className={styles.forceGraphCanvas} style={props.style}>
{loading && <Spin className={styles.graphLoading} />}
<div id={uuid} className={styles.forceGraph} ref={grapfDomRef} />
{currentGraph && (
Expand Down
22 changes: 18 additions & 4 deletions app/pages/Console/OutputBox/index.module.less
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@

> :global(span.anticon) {
cursor: pointer;

svg {
color: @darkBlue;
width: 22px;
Expand Down Expand Up @@ -84,7 +85,7 @@
overflow: auto;

.outputTab {
height: 100%;
height: 300px;

&> :global(.ant-tabs-nav) {
width: 80px;
Expand Down Expand Up @@ -130,10 +131,11 @@
position: relative;
background-color: #fff;
overflow: auto;

:global {
.ant-tabs-content {
height: 100%;

.ant-table,
.ant-pagination {
margin: 20px;
Expand Down Expand Up @@ -184,12 +186,10 @@
.btns {
display: flex;
align-items: center;
padding-right: 24px;

svg {
width: 24px;
height: 24px;
margin-right: 16px;
}

button:not(:last-child) {
Expand Down Expand Up @@ -227,4 +227,18 @@
color: rgba(0, 0, 0, 0.25);
}
}
}

.fullscreen {
position: fixed;
z-index: 888;
width: 100vw;
height: calc(100vh - 60px);
left: 0;
top: 60px;
margin: 0;

.tabContainer .outputTab {
height: 100%;
}
}
86 changes: 61 additions & 25 deletions app/pages/Console/OutputBox/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { Button, Table, Tabs, Tooltip, Popover } from 'antd';
import { BigNumber } from 'bignumber.js';
import { useCallback, useEffect, useState, useMemo } from 'react';
import { useCallback, useEffect, useState, useMemo, useRef } from 'react';
import { observer } from 'mobx-react-lite';
import { useStore } from '@app/stores';
import { trackEvent } from '@app/utils/stat';
import { v4 as uuidv4 } from 'uuid';
import Icon from '@app/components/Icon';
import { parseSubGraph } from '@app/utils/parseData';
import cls from 'classnames';
import domtoimage from 'dom-to-image';
import { GraphStore } from '@app/stores/graph';
import { useI18n } from '@vesoft-inc/i18n';
import type { HistoryResult } from '@app/stores/console';
Expand All @@ -31,6 +32,7 @@ const OutputBox = (props: IProps) => {
const { console } = useStore();
const { intl } = useI18n();
const [visible, setVisible] = useState(true);
const nowOutputRef = useRef<HTMLDivElement>(null);
const { results, update, favorites, saveFavorite, deleteFavorite, getFavoriteList, updateResultsStorage } = console;
const { code, data, message, gql, space, spaceVidType } = result;
const [columns, setColumns] = useState<any>([]);
Expand All @@ -39,6 +41,7 @@ const OutputBox = (props: IProps) => {
const [showGraph, setShowGraph] = useState(false);
const [graph, setGraph] = useState<GraphStore | null>(null);
const [tab, setTab] = useState('');
const [fullscreen, setFullscreen] = useState(false);

const initData = useCallback(() => {
let _columns = [] as any;
Expand Down Expand Up @@ -162,8 +165,8 @@ const OutputBox = (props: IProps) => {
link.click();
};

const downloadPng = () => {
if (graph) {
const downloadPng = async () => {
if (graph && tab === 'graph') {
let canvas = graph.twoGraph.canvas;
const shadowCanvas = document.createElement('canvas');
shadowCanvas.width = canvas.width;
Expand All @@ -183,7 +186,16 @@ const OutputBox = (props: IProps) => {
window.URL.revokeObjectURL(url);
});
}, 0);
} else {
// use canvg to convert svg to canvas
const svg = nowOutputRef.current?.querySelector('.ve-editor');
const url = await domtoimage.toPng(svg, { bgcolor: '#ddd' });
const a = document.createElement('a');
a.href = url;
a.download = 'explain-graph.png';
a.click();
}

trackEvent('console', 'export_graph_png');
};

Expand Down Expand Up @@ -262,7 +274,12 @@ const OutputBox = (props: IProps) => {
{intl.get('console.planTree')}
</>
),
children: <Explain style={{ height: 600 }} data={dataSource.map((item) => convertExplainData(item))} />,
children: (
<Explain
style={{ height: fullscreen ? window.innerHeight - 190 : 300 }}
data={dataSource.map((item) => convertExplainData(item))}
/>
),
},

resultSuccess &&
Expand All @@ -274,7 +291,12 @@ const OutputBox = (props: IProps) => {
{intl.get('console.planTree')}
</>
),
children: <Explain style={{ height: 600 }} data={dataSource.map((item) => convertExplainData(item))} />,
children: (
<Explain
style={{ height: fullscreen ? window.innerHeight - 190 : 300 }}
data={dataSource.map((item) => convertExplainData(item))}
/>
),
},
showGraph && {
key: 'graph',
Expand All @@ -284,7 +306,17 @@ const OutputBox = (props: IProps) => {
{intl.get('common.graph')}
</>
),
children: <ForceGraph space={space} data={dataSource} spaceVidType={spaceVidType} onGraphInit={setGraph} />,
children: (
<ForceGraph
style={{
height: fullscreen ? window.innerHeight - 190 : 300,
}}
space={space}
data={dataSource}
spaceVidType={spaceVidType}
onGraphInit={setGraph}
/>
),
},
!resultSuccess && {
key: 'log',
Expand All @@ -297,9 +329,12 @@ const OutputBox = (props: IProps) => {
children: <div className={styles.errContainer}>{message}</div>,
},
].filter(Boolean);
}, [gql, data, dataSource, columns]);
}, [gql, data, dataSource, columns, fullscreen]);
const onFullScreen = () => {
setFullscreen(!fullscreen);
};
return (
<div className={styles.outputBox}>
<div className={styles.outputBox + ` ${fullscreen ? `${styles.fullscreen}` : ''}`} ref={nowOutputRef}>
<div className={styles.outputHeader}>
<p
className={cls(styles.gql, { [styles.errorInfo]: !resultSuccess })}
Expand Down Expand Up @@ -328,12 +363,7 @@ const OutputBox = (props: IProps) => {
<Button type="link" className={styles.downloadItem} onClick={downloadCsv}>
{intl.get('schema.csvDownload')}
</Button>
<Button
disabled={!graph || tab !== 'graph'}
type="link"
className={styles.downloadItem}
onClick={downloadPng}
>
<Button disabled={tab === 'table'} type="link" className={styles.downloadItem} onClick={downloadPng}>
{intl.get('schema.pngDownload')}
</Button>
</>
Expand All @@ -357,18 +387,24 @@ const OutputBox = (props: IProps) => {
items={items}
/>
</div>
{resultSuccess && data.timeCost !== undefined && (
<div className={styles.outputFooter} onClick={handleRemoveMenu}>
<span>{`${intl.get('console.execTime')} ${data.timeCost / 1000000} (s)`}</span>
<div className={styles.btns}>
{onExplorer && !!space && (
<Button className="primaryBtn" type="text" onClick={handleExplore}>
{intl.get('common.openInExplore')}
</Button>
)}
</div>
<div className={styles.outputFooter} onClick={handleRemoveMenu}>
<span>
{resultSuccess &&
data.timeCost !== undefined &&
`${intl.get('console.execTime')} ${data.timeCost / 1000000} (s)`}
</span>
<div className={styles.btns}>
{onExplorer && !!space && (
<Button className="primaryBtn" type="text" onClick={handleExplore}>
{intl.get('common.openInExplore')}
</Button>
)}
<Icon
type={fullscreen ? 'icon-vesoft-arrow-collapse-all' : 'icon-vesoft-arrow-expand-all'}
onClick={onFullScreen}
/>
</div>
)}
</div>
</>
)}
</div>
Expand Down
Loading

0 comments on commit c0f9b03

Please sign in to comment.