1424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 2424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 3424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// found in the LICENSE file. 4424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 5424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)/** 6424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * This is a view class showing tree-menu. 758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) * @param {Object} profiler Must have addListener method. 8424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * @construct 9424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) */ 1058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)var MenuView = function(profiler) { 1158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) this.profiler_ = profiler; 1258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) this.placeholder_ = '#category-menu'; 1358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Update graph view and menu view when profiler model changed. 1558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) profiler.addListener('changed', this.redraw_.bind(this)); 1658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) profiler.addListener('changed:selected', this.selectNode_.bind(this)); 1758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}; 1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)/** 2058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) * Highlight the node being selected. 211e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) * @param {string|null} id Model id. 221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) * @param {Object} pos Clicked position. Not used 2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) * @private 2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) */ 2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)MenuView.prototype.selectNode_ = function(id) { 2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) var $tree = this.$tree_; 271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 281e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (id == null) { 291e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) $tree.tree('selectNode', null); 301e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return; 311e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) } 321e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) var node = $tree.tree('getNodeById', id); 3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) $tree.tree('selectNode', node); 35424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}; 36424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 37424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)/** 38424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) * Update menu view when model updated. 3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) * @param {Array.<Object>} models 4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) * @private 41424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) */ 4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)MenuView.prototype.redraw_ = function(models) { 43424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) function convert(origin, target) { 44424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) target.label = origin.name; 4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) target.id = origin.id; 46424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 47424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if ('children' in origin) { 48424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) target.children = []; 49424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) origin.children.forEach(function(originChild) { 50424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) var targetChild = {}; 51424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) target.children.push(targetChild); 52424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) convert(originChild, targetChild); 53424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) }); 54424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 55424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 56424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 571e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) function merge(origin, target) { 581e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!('children' in origin)) 591e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return; 601e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (!('children' in target)) { 611e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) target.children = origin.children; 62424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) return; 63424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 651e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) origin.children.forEach(function(child) { 661e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Find child with the same label in target tree. 671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) var index = target.children.reduce(function(previous, current, index) { 681e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (child.label === current.label) 691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return index; 701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return previous; 711e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) }, -1); 721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (index === -1) 731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) target.children.push(child); 741e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) else 751e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) merge(child, target.children[index]); 761e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) }); 7758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 7858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) var self = this; 80424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 81424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Merge trees in all snapshots. 82424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) var union = null; 8358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) models.forEach(function(model) { 8458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) var data = {}; 8558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) convert(model, data); 86424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!union) 8758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) union = data; 88424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) else 891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) merge(data, union); 90424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) }); 91424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 92424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Draw breakdown menu. 9358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) var data = [union]; 9458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (!this.$tree_) { 9558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) this.$tree_ = $(this.placeholder_).tree({ 9658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) data: data, 9758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) autoOpen: true, 9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) onCreateLi: function(node, $li) { 9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // TODO(junjianx): Add checkbox to decide the breakdown visibility. 10058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) }); 10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) // Delegate events 10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) this.$tree_.bind('tree.click', function(event) { 10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) event.preventDefault(); 10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) self.profiler_.setSelected(event.node.id); 10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) }); 1081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) this.$tree_.bind('tree.close', function(event) { 1091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) event.preventDefault(); 1101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.profiler_.unsetSub(event.node.id); 1111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) self.profiler_.setSelected(event.node.id); 1121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) }); 11358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } else { 11458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) this.$tree_.tree('loadData', data); 11558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 116424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}; 117