12da489cd246702bee5938545b18a6f710ed214bcJamie Gennis// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22da489cd246702bee5938545b18a6f710ed214bcJamie Gennis// Use of this source code is governed by a BSD-style license that can be 32da489cd246702bee5938545b18a6f710ed214bcJamie Gennis// found in the LICENSE file. 42da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 52da489cd246702bee5938545b18a6f710ed214bcJamie Gennis'use strict'; 62da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 72da489cd246702bee5938545b18a6f710ed214bcJamie Gennisbase.require('tracks.timeline_container_track'); 82da489cd246702bee5938545b18a6f710ed214bcJamie Gennisbase.require('sorted_array_utils'); 92da489cd246702bee5938545b18a6f710ed214bcJamie Gennisbase.require('ui'); 102da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 112da489cd246702bee5938545b18a6f710ed214bcJamie Gennisbase.exportTo('tracks', function() { 122da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 132da489cd246702bee5938545b18a6f710ed214bcJamie Gennis /** 142da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * A track that displays a TimelineSliceGroup. 152da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * @constructor 162da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * @extends {TimelineContainerTrack} 172da489cd246702bee5938545b18a6f710ed214bcJamie Gennis */ 182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 192da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var TimelineSliceGroupTrack = base.ui.define(tracks.TimelineContainerTrack); 202da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis TimelineSliceGroupTrack.prototype = { 222da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 232da489cd246702bee5938545b18a6f710ed214bcJamie Gennis __proto__: tracks.TimelineContainerTrack.prototype, 242da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 252da489cd246702bee5938545b18a6f710ed214bcJamie Gennis decorate: function() { 262da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.classList.add('timeline-slice-group-track'); 272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 282da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 292da489cd246702bee5938545b18a6f710ed214bcJamie Gennis get group() { 302da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return this.group_; 312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 332da489cd246702bee5938545b18a6f710ed214bcJamie Gennis set group(g) { 342da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.group_ = g; 352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.updateChildTracks_(); 362da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 372da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 382da489cd246702bee5938545b18a6f710ed214bcJamie Gennis set heading(h) { 392da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (this.tracks_.length) 402da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.tracks_[0].heading = h; 412da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 422da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 432da489cd246702bee5938545b18a6f710ed214bcJamie Gennis set tooltip(t) { 442da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (this.tracks_.length) 452da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.tracks_[0].tooltip = t; 462da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 472da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 482da489cd246702bee5938545b18a6f710ed214bcJamie Gennis set decorateHit(f) { 492da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.decorateHit_ = f; 502da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.updateChildTracks_(); 512da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 522da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 532da489cd246702bee5938545b18a6f710ed214bcJamie Gennis applyCategoryFilter_: function() { 542da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.updateChildTracks_(); 552da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 562da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 572da489cd246702bee5938545b18a6f710ed214bcJamie Gennis addSliceTrack_: function(slices) { 582da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var track = new tracks.TimelineSliceTrack(); 592da489cd246702bee5938545b18a6f710ed214bcJamie Gennis track.slices = slices; 602da489cd246702bee5938545b18a6f710ed214bcJamie Gennis track.decorateHit = this.decorateHit_; 612da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.addTrack_(track); 622da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return track; 632da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 642da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 652da489cd246702bee5938545b18a6f710ed214bcJamie Gennis updateChildTracks_: function() { 662da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (!this.group_) { 672da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.visible = false; 682da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return; 692da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 702da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 712da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var slices = tracing.filterSliceArray(this.categoryFilter, 722da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.group_.slices); 732da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (!slices.length) { 742da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.visible = false; 752da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return; 762da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 772da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.visible = true; 782da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 792da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (this.areArrayContentsSame_(this.filteredSlices_, slices)) 802da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return; 812da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 822da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.filteredSlices_ = slices; 832da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.detach(); 842da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.subRows_ = this.buildSubRows_(slices); 852da489cd246702bee5938545b18a6f710ed214bcJamie Gennis for (var srI = 0; srI < this.subRows_.length; srI++) { 862da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (this.subRows_[srI].length) { 872da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.addSliceTrack_(this.subRows_[srI]); 882da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 892da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 902da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 912da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 922da489cd246702bee5938545b18a6f710ed214bcJamie Gennis /** 932da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * Breaks up the list of slices into N rows, each of which is a list of 942da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * slices that are non overlapping. 952da489cd246702bee5938545b18a6f710ed214bcJamie Gennis */ 962da489cd246702bee5938545b18a6f710ed214bcJamie Gennis buildSubRows_: function(slices) { 972da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // This function works by walking through slices by start time. 982da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 992da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // The basic idea here is to insert each slice as deep into the subrow 1002da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // list as it can go such that every subSlice is fully contained by its 1012da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // parent slice. 1022da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 1032da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Visually, if we start with this: 1042da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 0: [ a ] 1052da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 1: [ b ] 1062da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 2: [c][d] 1072da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 1082da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // To place this slice: 1092da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // [e] 1102da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // We first check row 2's last item, [d]. [e] wont fit into [d] (they dont 1112da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // even intersect). So we go to row 1. That gives us [b], and [d] wont fit 1122da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // into that either. So, we go to row 0 and its last slice, [a]. That can 1132da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // completely contain [e], so that means we should add [e] as a subchild 1142da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // of [a]. That puts it on row 1, yielding: 1152da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 0: [ a ] 1162da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 1: [ b ][e] 1172da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 2: [c][d] 1182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 1192da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // If we then get this slice: 1202da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // [f] 1212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // We do the same deepest-to-shallowest walk of the subrows trying to fit 1222da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // it. This time, it doesn't fit in any open slice. So, we simply append 1232da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // it to row 0: 1242da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 0: [ a ] [f] 1252da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 1: [ b ][e] 1262da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // 2: [c][d] 1272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (!slices.length) 1282da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return []; 1292da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1302da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var ops = []; 1312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis for (var i = 0; i < slices.length; i++) { 1322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (slices[i].subSlices) 1332da489cd246702bee5938545b18a6f710ed214bcJamie Gennis slices[i].subSlices.splice(0, 1342da489cd246702bee5938545b18a6f710ed214bcJamie Gennis slices[i].subSlices.length); 1352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ops.push(i); 1362da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 1372da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1382da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ops.sort(function(ix, iy) { 1392da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var x = slices[ix]; 1402da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var y = slices[iy]; 1412da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (x.start != y.start) 1422da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return x.start - y.start; 1436e58f015d94bedc1072f08b30f0a5a6ac6e653efJamie Gennis 1446e58f015d94bedc1072f08b30f0a5a6ac6e653efJamie Gennis // Elements get inserted into the slices array in order of when the 1456e58f015d94bedc1072f08b30f0a5a6ac6e653efJamie Gennis // slices end. Because slices must be properly nested, we break 1466e58f015d94bedc1072f08b30f0a5a6ac6e653efJamie Gennis // start-time ties by assuming that the elements appearing earlier in 1476e58f015d94bedc1072f08b30f0a5a6ac6e653efJamie Gennis // the slices array (and thus ending earlier) start later. 1486e58f015d94bedc1072f08b30f0a5a6ac6e653efJamie Gennis return iy - ix; 1492da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }); 1502da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1512da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var subRows = [[]]; 1522da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.badSlices_ = []; // TODO(simonjam): Connect this again. 1532da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1542da489cd246702bee5938545b18a6f710ed214bcJamie Gennis for (var i = 0; i < ops.length; i++) { 1552da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var op = ops[i]; 1562da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var slice = slices[op]; 1572da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1582da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Try to fit the slice into the existing subrows. 1592da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var inserted = false; 1602da489cd246702bee5938545b18a6f710ed214bcJamie Gennis for (var j = subRows.length - 1; j >= 0; j--) { 1612da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (subRows[j].length == 0) 1622da489cd246702bee5938545b18a6f710ed214bcJamie Gennis continue; 1632da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1642da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var insertedSlice = subRows[j][subRows[j].length - 1]; 1652da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (slice.start < insertedSlice.start) { 1662da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.badSlices_.push(slice); 1672da489cd246702bee5938545b18a6f710ed214bcJamie Gennis inserted = true; 1682da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 1692da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (slice.start >= insertedSlice.start && 1702da489cd246702bee5938545b18a6f710ed214bcJamie Gennis slice.end <= insertedSlice.end) { 1712da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Insert it into subRow j + 1. 1722da489cd246702bee5938545b18a6f710ed214bcJamie Gennis while (subRows.length <= j + 1) 1732da489cd246702bee5938545b18a6f710ed214bcJamie Gennis subRows.push([]); 1742da489cd246702bee5938545b18a6f710ed214bcJamie Gennis subRows[j + 1].push(slice); 1752da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (insertedSlice.subSlices) 1762da489cd246702bee5938545b18a6f710ed214bcJamie Gennis insertedSlice.subSlices.push(slice); 1772da489cd246702bee5938545b18a6f710ed214bcJamie Gennis inserted = true; 1782da489cd246702bee5938545b18a6f710ed214bcJamie Gennis break; 1792da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 1802da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 1812da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (inserted) 1822da489cd246702bee5938545b18a6f710ed214bcJamie Gennis continue; 1832da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1842da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Append it to subRow[0] as a root. 1852da489cd246702bee5938545b18a6f710ed214bcJamie Gennis subRows[0].push(slice); 1862da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 1872da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1882da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return subRows; 1892da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 1902da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1912da489cd246702bee5938545b18a6f710ed214bcJamie Gennis areArrayContentsSame_: function(a, b) { 1922da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (!a || !b) 1932da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return false; 1942da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (!a.length || !b.length) 1952da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return false; 1962da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (a.length != b.length) 1972da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return false; 1982da489cd246702bee5938545b18a6f710ed214bcJamie Gennis for (var i = 0; i < a.length; ++i) { 1992da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (a[i] != b[i]) 2002da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return false; 2012da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 2022da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return true; 2032da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 2042da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }; 2052da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2062da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return { 2072da489cd246702bee5938545b18a6f710ed214bcJamie Gennis TimelineSliceGroupTrack: TimelineSliceGroupTrack 2082da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }; 2092da489cd246702bee5938545b18a6f710ed214bcJamie Gennis}); 210