未验证 提交 35257d3d 编写于 作者: P Peter Pan 提交者: GitHub

graph page improvement (#729)

* feat: graph supports vertical and horizontal direction

* chore: update dependencies
上级 0bc58a72
......@@ -38,12 +38,12 @@
"version": "yarn format && git add -A"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "3.7.0",
"@typescript-eslint/parser": "3.7.0",
"@typescript-eslint/eslint-plugin": "3.7.1",
"@typescript-eslint/parser": "3.7.1",
"eslint": "7.5.0",
"eslint-config-prettier": "6.11.0",
"eslint-plugin-prettier": "3.1.4",
"eslint-plugin-react": "7.20.3",
"eslint-plugin-react": "7.20.4",
"eslint-plugin-react-hooks": "4.0.8",
"husky": "4.2.5",
"lerna": "3.22.1",
......
......@@ -41,7 +41,7 @@
"yargs": "15.4.1"
},
"devDependencies": {
"@types/node": "14.0.24",
"@types/node": "14.0.26",
"@types/yargs": "15.0.5",
"cross-env": "7.0.2",
"ts-node": "8.10.2",
......
......@@ -18,6 +18,8 @@ const Wrapper = styled.div`
justify-content: space-between;
padding: ${em(8)} ${em(10)};
line-height: 1.5;
box-sizing: content-box;
min-height: 1em;
> .argument-text {
flex: auto;
......
......@@ -88,6 +88,7 @@ type GraphProps = {
showAttributes: boolean;
showInitializers: boolean;
showNames: boolean;
horizontal: boolean;
onRendered?: () => unknown;
onSearch?: (data: SearchResult) => unknown;
onShowModelProperties?: (data: Properties) => unknown;
......@@ -103,6 +104,7 @@ const Graph = React.forwardRef<GraphRef, GraphProps>(
showAttributes,
showInitializers,
showNames,
horizontal,
onRendered,
onSearch,
onShowModelProperties,
......@@ -188,6 +190,11 @@ const Graph = React.forwardRef<GraphRef, GraphProps>(
ready
]);
useEffect(() => (ready && dispatch('toggle-names', showNames)) || undefined, [dispatch, showNames, ready]);
useEffect(() => (ready && dispatch('toggle-direction', horizontal)) || undefined, [
dispatch,
horizontal,
ready
]);
useImperativeHandle(ref, () => ({
export(type) {
......
......@@ -72,7 +72,7 @@ const RadioButton = <T extends unknown>({
const onChange = useContext(EventContext);
const onClick = useCallback(() => {
if (value && onChange && groupValue !== value) {
if (value != null && onChange && groupValue !== value) {
onChange(value);
}
}, [value, onChange, groupValue]);
......
......@@ -67,14 +67,14 @@
"devDependencies": {
"@babel/core": "7.10.5",
"@types/d3-format": "1.3.1",
"@types/echarts": "4.6.3",
"@types/echarts": "4.6.4",
"@types/enzyme": "3.10.5",
"@types/enzyme-adapter-react-16": "1.0.6",
"@types/file-saver": "2.0.1",
"@types/jest": "26.0.5",
"@types/jest": "26.0.7",
"@types/lodash": "4.14.158",
"@types/mime-types": "2.1.0",
"@types/node": "14.0.24",
"@types/node": "14.0.26",
"@types/nprogress": "0.2.0",
"@types/react": "16.9.43",
"@types/react-dom": "16.9.8",
......@@ -87,14 +87,14 @@
"copy-webpack-plugin": "6.0.3",
"core-js": "3.6.5",
"cross-env": "7.0.2",
"css-loader": "3.6.0",
"css-loader": "4.0.0",
"enhanced-resolve": "4.3.0",
"enzyme": "3.11.0",
"enzyme-adapter-react-16": "1.15.2",
"enzyme-to-json": "3.5.0",
"jest": "26.1.0",
"ora": "4.0.5",
"ts-jest": "26.1.3",
"ts-jest": "26.1.4",
"typescript": "3.9.7",
"worker-plugin": "4.0.3"
},
......
......@@ -14,6 +14,8 @@ import HashLoader from 'react-spinners/HashLoader';
import ModelPropertiesDialog from '~/components/GraphPage/ModelPropertiesDialog';
import NodeDocumentationSidebar from '~/components/GraphPage/NodeDocumentationSidebar';
import NodePropertiesSidebar from '~/components/GraphPage/NodePropertiesSidebar';
import RadioButton from '~/components/RadioButton';
import RadioGroup from '~/components/RadioGroup';
import Search from '~/components/GraphPage/Search';
import Title from '~/components/Title';
import Uploader from '~/components/GraphPage/Uploader';
......@@ -101,6 +103,7 @@ const Graph: NextI18NextPage = () => {
const [showAttributes, setShowAttributes] = useState(false);
const [showInitializers, setShowInitializers] = useState(true);
const [showNames, setShowNames] = useState(false);
const [horizontal, setHorizontal] = useState(false);
const [modelData, setModelData] = useState<Properties | null>(null);
const [nodeData, setNodeData] = useState<Properties | null>(null);
......@@ -183,6 +186,14 @@ const Graph: NextI18NextPage = () => {
</div>
</Field>
</AsideSection>
<AsideSection>
<Field label={t('graph:direction')}>
<RadioGroup value={horizontal} onChange={setHorizontal}>
<RadioButton value={false}>{t('graph:vertical')}</RadioButton>
<RadioButton value={true}>{t('graph:horizontal')}</RadioButton>
</RadioGroup>
</Field>
</AsideSection>
<AsideSection>
<Field label={t('graph:export-file')}>
<ExportButtonWrapper>
......@@ -210,6 +221,7 @@ const Graph: NextI18NextPage = () => {
showAttributes,
showInitializers,
showNames,
horizontal,
rendered,
loading,
nodeData,
......@@ -235,6 +247,7 @@ const Graph: NextI18NextPage = () => {
showAttributes={showAttributes}
showInitializers={showInitializers}
showNames={showNames}
horizontal={horizontal}
onRendered={() => setRendered(true)}
onSearch={data => setSearchResult(data)}
onShowModelProperties={data => setModelData(data)}
......
{
"change-model": "Change Model",
"direction": "Direction",
"display-data": "Select Display Data",
"documentation": {
"attributes": "Attributes",
......@@ -16,6 +17,7 @@
"export-file": "Export File",
"export-png": "PNG",
"export-svg": "SVG",
"horizontal": "Horizontal",
"model-properties": "Model Properties",
"node-documentation": "Documentation",
"node-properties": "Node Properties",
......@@ -47,6 +49,7 @@
"supported-model-list": "PaddlePaddle, ONNX, Keras, Core ML, Caffe, Caffe2, Darknet, MXNet, ncnn, TensorFlow Lite",
"upload-model": "Upload Model",
"upload-tip": "Click or Drop file here to view neural network models",
"vertical": "Vertical",
"zoom-in": "Zoom In",
"zoom-out": "Zoom Out"
}
{
"change-model": "更换模型",
"direction": "方向",
"display-data": "选择展示数据",
"documentation": {
"attributes": "属性",
......@@ -16,6 +17,7 @@
"export-file": "导出文件",
"export-png": "PNG",
"export-svg": "SVG",
"horizontal": "水平",
"model-properties": "模型属性",
"node-documentation": "文档",
"node-properties": "节点属性",
......@@ -47,6 +49,7 @@
"supported-model-list": "PaddlePaddle、ONNX、Keras、Core ML、Caffe、Caffe2、Darknet、MXNet、ncnn、TensorFlow Lite",
"upload-model": "上传模型",
"upload-tip": "点击或拖拽文件到页面上传模型,进行结构展示",
"vertical": "垂直",
"zoom-in": "放大",
"zoom-out": "缩小"
}
......@@ -37,7 +37,7 @@
"dependencies": {
"detect-node": "2.0.4",
"hoist-non-react-statics": "3.3.2",
"i18next": "19.6.2",
"i18next": "19.6.3",
"i18next-browser-languagedetector": "5.0.0",
"i18next-fs-backend": "1.0.7",
"i18next-http-backend": "1.0.17",
......@@ -50,7 +50,7 @@
"devDependencies": {
"@types/express": "4.17.7",
"@types/hoist-non-react-statics": "3.3.1",
"@types/node": "14.0.24",
"@types/node": "14.0.26",
"@types/react": "16.9.43",
"@types/react-dom": "16.9.8",
"typescript": "3.9.7"
......
......@@ -39,7 +39,7 @@
"devDependencies": {
"@types/express": "4.17.7",
"@types/faker": "4.1.12",
"@types/node": "14.0.24",
"@types/node": "14.0.26",
"cpy-cli": "3.1.1",
"rimraf": "3.0.2",
"typescript": "3.9.7"
......
......@@ -42,7 +42,7 @@
"devDependencies": {
"autoprefixer": "9.8.5",
"copy-webpack-plugin": "6.0.3",
"css-loader": "3.6.0",
"css-loader": "4.0.0",
"html-webpack-plugin": "4.3.0",
"mini-css-extract-plugin": "0.9.0",
"postcss-loader": "3.0.0",
......
......@@ -60,6 +60,8 @@ host.BrowserHost = class {
return this._view.toggleInitializers(data);
case 'toggle-names':
return this._view.toggleNames(data);
case 'toggle-direction':
return this._view.toggleDirection(data);
case 'export':
return this._view.export(`${document.title}.${data}`);
case 'search':
......@@ -151,10 +153,6 @@ host.BrowserHost = class {
return this._request(url, null, encoding);
}
openURL(url) {
window.open(url, '_target');
}
_changeFiles(files) {
if (files && files.length) {
files = Array.from(files);
......
window.base = require('netron/src/base');
window.flatbuffers = require('flatbuffers').flatbuffers;
window.flatbuffers = require('netron/src/flatbuffers');
window.long = {
Long: require('long')
};
......
/* jshint esversion: 6 */
/* eslint "indent": [ "error", 4, { "SwitchCase": 1 } ] */
const sidebar = {};
const long = {Long: require('long')};
const marked = require('marked');
......@@ -43,7 +40,7 @@ sidebar.NodeSidebar = class {
const attributes = node.attributes;
if (attributes && attributes.length > 0) {
let sortedAttributes = node.attributes.slice();
const sortedAttributes = node.attributes.slice();
sortedAttributes.sort((a, b) => {
const au = a.name.toUpperCase();
const bu = b.name.toUpperCase();
......@@ -90,7 +87,7 @@ sidebar.NodeSidebar = class {
}
_addProperty(name, value) {
let item = new sidebar.NameValueView(this._host, name, value);
const item = new sidebar.NameValueView(this._host, name, value);
this._properties.push(item.render());
}
......@@ -122,9 +119,6 @@ sidebar.NodeSidebar = class {
if (value && long.Long.isLong(value)) {
return value.toString();
}
if (value && long.Long.isLong(value)) {
return value.toString();
}
if (Number.isNaN(value)) {
return 'NaN';
}
......@@ -161,7 +155,7 @@ sidebar.NodeSidebar = class {
value = value.slice(0, 1000);
ellipsis = true;
}
let array = value.map(item => {
const array = value.map(item => {
if (item && long.Long.isLong(item)) {
return item.toString();
}
......@@ -184,7 +178,7 @@ sidebar.NodeSidebar = class {
if (value !== Object(value)) {
return value.toString();
}
let list = [];
const list = [];
const keys = Object.keys(value).filter(key => !key.startsWith('__') && !key.endsWith('__'));
if (keys.length == 1) {
list.push(sidebar.NodeSidebar.formatAttributeValue(value[Object.keys(value)[0]], null, true));
......@@ -194,7 +188,7 @@ sidebar.NodeSidebar = class {
}
}
let objectType = value.__type__;
if (!objectType && value.constructor.name && value.constructor.name && value.constructor.name !== 'Object') {
if (!objectType && value.constructor.name && value.constructor.name !== 'Object') {
objectType = value.constructor.name;
}
if (objectType) {
......@@ -530,9 +524,9 @@ sidebar.ModelSidebar = class {
this._addProperty('runtime', new sidebar.ValueTextView(this._host, this._model.runtime));
}
let metadata = this._model.metadata;
const metadata = this._model.metadata;
if (metadata) {
for (const property of this._model.metadata) {
for (const property of metadata) {
this._addProperty(property.name, new sidebar.ValueTextView(this._host, property.value));
}
}
......@@ -598,7 +592,7 @@ sidebar.ModelSidebar = class {
}
_addProperty(name, value) {
let item = new sidebar.NameValueView(this._host, name, value);
const item = new sidebar.NameValueView(this._host, name, value);
this._properties.push(item.render());
}
......
......@@ -66,7 +66,12 @@ module.exports = {
to: file,
transform: content => {
try {
const result = Terser.minify(content.toString());
// It is important to keep class names and function names after compressing
// Netron relies on Class.constructor.name and Function.prototype.name to show attribute's value
const result = Terser.minify(content.toString(), {
keep_classnames: true,
keep_fnames: true
});
if (result.error) {
throw result.error;
}
......
......@@ -46,7 +46,7 @@
},
"devDependencies": {
"@types/express": "4.17.7",
"@types/node": "14.0.24",
"@types/node": "14.0.26",
"@types/shelljs": "0.8.8",
"@types/webpack": "4.41.21",
"@types/webpack-dev-middleware": "3.7.1",
......
......@@ -31,7 +31,7 @@
"test": "echo \"Error: no test specified\" && exit 0; #"
},
"devDependencies": {
"@types/node": "14.0.24",
"@types/node": "14.0.26",
"@types/rimraf": "3.0.0",
"@visualdl/core": "2.0.0-beta.49",
"cross-env": "7.0.2",
......
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册