Selaa lähdekoodia

Update view.js (#1240) (#1418)

Lutz Roeder 11 kuukautta sitten
vanhempi
sitoutus
d714c50be9
4 muutettua tiedostoa jossa 124 lisäystä ja 17 poistoa
  1. 4 2
      source/app.js
  2. 6 0
      source/browser.js
  3. 15 9
      source/electron.mjs
  4. 99 6
      source/view.js

+ 4 - 2
source/app.js

@@ -73,6 +73,10 @@ app.Application = class {
             this._dropPaths(event.sender, paths);
             event.returnValue = null;
         });
+        electron.ipcMain.on('update-recents', (event, data) => {
+            this._updateRecents(data.path);
+            event.returnValue = null;
+        });
         electron.ipcMain.on('show-save-dialog', async (event, options) => {
             const owner = event.sender.getOwnerBrowserWindow();
             const argument = {};
@@ -228,7 +232,6 @@ app.Application = class {
         for (const path of paths) {
             if (view) {
                 view.open(path);
-                this._updateRecents(path);
                 view = null;
             } else {
                 this._openPath(path);
@@ -285,7 +288,6 @@ app.Application = class {
         const view = this._views.activeView;
         if (view && view.path) {
             view.open(view.path);
-            this._updateRecents(view.path);
         }
     }
 

+ 6 - 0
source/browser.js

@@ -486,8 +486,14 @@ host.BrowserHost = class {
     async _openContext(context) {
         this._telemetry.set('session_engaged', 1);
         try {
+            const attachment = await this._view.attach(context);
+            if (attachment) {
+                this._view.show(null);
+                return 'context-open-attachment';
+            }
             const model = await this._view.open(context);
             if (model) {
+                this._view.show(null);
                 this.document.title = context.name || context.identifier;
                 return '';
             }

+ 15 - 9
source/electron.mjs

@@ -462,17 +462,23 @@ host.ElectronHost = class {
                 return;
             }
             try {
-                const model = await this._view.open(context);
-                this._view.show(null);
-                const options = { ...this._view.options };
-                if (model) {
-                    options.path = path;
-                    this._title(location.label);
+                const attachment = await this._view.attach(context);
+                if (attachment) {
+                    this._view.show(null);
                 } else {
-                    options.path = path;
-                    this._title('');
+                    const model = await this._view.open(context);
+                    this._view.show(null);
+                    const options = { ...this._view.options };
+                    if (model) {
+                        options.path = path;
+                        this._title(location.label);
+                    } else {
+                        options.path = path;
+                        this._title('');
+                    }
+                    electron.ipcRenderer.send('update-recents', { path });
+                    this.update(options);
                 }
-                this.update(options);
             } catch (error) {
                 const options = { ...this._view.options };
                 if (error) {

+ 99 - 6
source/view.js

@@ -19,6 +19,7 @@ view.View = class {
         };
         this._options = { ...this._defaultOptions };
         this._model = null;
+        this._metrics = new metrics.Metrics();
         this._stack = [];
         this._selection = [];
         this._sidebar = new view.Sidebar(this._host);
@@ -287,6 +288,10 @@ view.View = class {
         return this._model;
     }
 
+    get metrics() {
+        return this._metrics;
+    }
+
     get options() {
         return this._options;
     }
@@ -715,6 +720,13 @@ view.View = class {
         }
     }
 
+    async attach(context) {
+        if (this._model && await this._metrics.open(context)) {
+            return true;
+        }
+        return false;
+    }
+
     async _updateActiveTarget(stack) {
         this._sidebar.close();
         if (this._model) {
@@ -2836,6 +2848,13 @@ view.NodeSidebar = class extends view.ObjectSidebar {
                 this.addArgument(entry.name, entry, 'attribute');
             }
         }
+        const metrics = this._view.metrics.node(node);
+        if (Array.isArray(metrics) && metrics.length > 0) {
+            this.addSection('Metrics');
+            for (const metric of metrics) {
+                this.addArgument(metric.name, metric);
+            }
+        }
     }
 
     addArgument(name, argument, source) {
@@ -3502,6 +3521,13 @@ view.ConnectionSidebar = class extends view.ObjectSidebar {
                 this.addProperty(metadata.name, metadata.value);
             }
         }
+        const metrics = this._view.metrics.value(value);
+        if (Array.isArray(metrics) && metrics.length > 0) {
+            this.addSection('Metrics');
+            for (const argument of metrics) {
+                this.addProperty(argument.name, argument.value);
+            }
+        }
     }
 
     addNodeList(name, list) {
@@ -3604,11 +3630,12 @@ view.TensorSidebar = class extends view.ObjectSidebar {
                 this._tensor = new base.Tensor(tensor);
                 if (!this._tensor.empty) {
                     if (!this._metrics) {
-                        this._metrics = new metrics.Tensor(this._tensor);
+                        const tensor = new metrics.Tensor(this._tensor);
+                        this._metrics = this._view.metrics.tensor(tensor);
                     }
-                    if (this._metrics.metrics.length > 0) {
+                    if (this._metrics.length > 0) {
                         this.addSection('Metrics');
-                        for (const metric of this._metrics.metrics) {
+                        for (const metric of this._metrics) {
                             const value = metric.type === 'percentage' ? `${(metric.value * 100).toFixed(1)}%` : metric.value;
                             this.addProperty(metric.name, [value]);
                         }
@@ -3674,7 +3701,7 @@ view.ModelSidebar = class extends view.ObjectSidebar {
                 this.addProperty(argument.name, argument.value);
             }
         }
-        const metrics = model.metrics;
+        const metrics = this._view.metrics.model(model);
         if (Array.isArray(metrics) && metrics.length > 0) {
             this.addSection('Metrics');
             for (const argument of metrics) {
@@ -3740,7 +3767,7 @@ view.TargetSidebar = class extends view.ObjectSidebar {
                 this.addProperty(argument.name, argument.value);
             }
         }
-        const metrics = target.metrics;
+        const metrics = this._view.metrics.graph(target);
         if (Array.isArray(metrics) && metrics.length > 0) {
             this.addSection('Metrics');
             for (const argument of metrics) {
@@ -5301,6 +5328,67 @@ markdown.Generator = class {
     }
 };
 
+metrics.Metrics = class {
+
+    constructor() {
+        this._metrics = new Map();
+    }
+
+    async open(context) {
+        const content = new view.Context(context);
+        if (content.identifier.toLowerCase().endsWith('.metrics.json')) {
+            const data = await content.peek('json');
+            if (data && data.signature === 'metrics' && Array.isArray(data.metrics)) {
+                this._metrics.clear();
+                for (const metric of data.metrics) {
+                    if (metric.kind && 'target' in metric) {
+                        const key = `${metric.kind}::${metric.target}`;
+                        if (!this._metrics.has(key)) {
+                            this._metrics.set(key, new Map());
+                        }
+                        const entries = this._metrics.get(key);
+                        entries.set(metric.name, { value: metric.value, type: metric.type });
+                    }
+                }
+                return true;
+            }
+        }
+        return false;
+    }
+
+    metrics(entries, type, name) {
+        const result = new Map(entries.map((metric) => [metric.name, metric]));
+        const key = `${type}::${name}`;
+        if (this._metrics.has(key)) {
+            for (const [name, metric] of this._metrics.get(key)) {
+                result.set(name, new metrics.Argument(name, metric.value, metric.type || 'attribute'));
+            }
+        }
+        return Array.from(result.values());
+    }
+
+    model(value) {
+        return this.metrics(value.metrics || [], 'model', '');
+    }
+
+    graph(value) {
+        return this.metrics(value.metrics || [], 'graph', value.name || '');
+    }
+
+    node(value) {
+        return this.metrics(value.metrics || [], 'node', value.name);
+    }
+
+    value(value) {
+        const name = (value.name || '').split('\n').shift();
+        return this.metrics(value.metrics || [], 'value', name);
+    }
+
+    tensor(value) {
+        return this.metrics(value.metrics || [], 'tensor', value.name);
+    }
+};
+
 metrics.Argument = class {
 
     constructor(name, value, type) {
@@ -5317,6 +5405,10 @@ metrics.Tensor = class {
         this._metrics = null;
     }
 
+    get name() {
+        return this._tensor.name || '';
+    }
+
     get metrics() {
         if (this._metrics === null) {
             this._metrics = [];
@@ -6026,6 +6118,7 @@ view.ModelFactoryService = class {
                     { name: 'Netron metadata', tags: ['[].name', '[].category'] },
                     { name: 'Netron test data', tags: ['[].type', '[].target', '[].source', '[].format', '[].link'] },
                     { name: 'Netron configuration', tags: ['recents', 'consent'] },
+                    { name: 'Netron metrics data', tags: ['signature', 'metrics'] },
                     { name: 'Darkflow metadata', tags: ['net', 'type', 'model'] },
                     { name: 'keras-yolo2 configuration', tags: ['model', 'train', 'valid'] },
                     { name: 'Vulkan SwiftShader ICD manifest', tags: ['file_format_version', 'ICD'] },
@@ -6063,7 +6156,7 @@ view.ModelFactoryService = class {
                     { name: 'Jupyter Notebook data', tags: ['cells', 'nbformat'] },
                     { name: 'Kaggle credentials', tags: ['username','key'] },
                     { name: '.NET runtime configuration', tags: ['runtimeOptions.configProperties'] },
-                    { name: '.NET dependency manifest', tags: ['runtimeTarget', 'targets', 'libraries'] }
+                    { name: '.NET dependency manifest', tags: ['runtimeTarget', 'targets', 'libraries'] },
                 ];
                 const match = (obj, tag) => {
                     if (tag.startsWith('[].')) {