1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 * This is a view class showing tree-menu.
7 * @param {Object} profiler Must have addListener method.
10 var MenuView = function(profiler
) {
11 this.profiler_
= profiler
;
12 this.placeholder_
= '#category-menu';
14 // Update graph view and menu view when profiler model changed.
15 profiler
.addListener('changed', this.redraw_
.bind(this));
16 profiler
.addListener('changed:selected', this.selectNode_
.bind(this));
20 * Highlight the node being selected.
21 * @param {string|null} id Model id.
22 * @param {Object} pos Clicked position. Not used
25 MenuView
.prototype.selectNode_ = function(id
) {
26 var $tree
= this.$tree_
;
29 $tree
.tree('selectNode', null);
33 var node
= $tree
.tree('getNodeById', id
);
34 $tree
.tree('selectNode', node
);
38 * Update menu view when model updated.
39 * @param {Array.<Object>} models
42 MenuView
.prototype.redraw_ = function(models
) {
43 function convert(origin
, target
) {
44 target
.label
= origin
.name
;
45 target
.id
= origin
.id
;
47 if ('children' in origin
) {
49 origin
.children
.forEach(function(originChild
) {
51 target
.children
.push(targetChild
);
52 convert(originChild
, targetChild
);
57 function merge(origin
, target
) {
58 if (!('children' in origin
))
60 if (!('children' in target
)) {
61 target
.children
= origin
.children
;
65 origin
.children
.forEach(function(child
) {
66 // Find child with the same label in target tree.
67 var index
= target
.children
.reduce(function(previous
, current
, index
) {
68 if (child
.label
=== current
.label
)
73 target
.children
.push(child
);
75 merge(child
, target
.children
[index
]);
81 // Merge trees in all snapshots.
83 models
.forEach(function(model
) {
92 // Draw breakdown menu.
95 this.$tree_
= $(this.placeholder_
).tree({
98 onCreateLi: function(node
, $li
) {
99 // TODO(junjianx): Add checkbox to decide the breakdown visibility.
104 this.$tree_
.bind('tree.click', function(event
) {
105 event
.preventDefault();
106 self
.profiler_
.setSelected(event
.node
.id
);
108 this.$tree_
.bind('tree.close', function(event
) {
109 event
.preventDefault();
110 self
.profiler_
.unsetSub(event
.node
.id
);
111 self
.profiler_
.setSelected(event
.node
.id
);
114 this.$tree_
.tree('loadData', data
);