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 766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.requireStylesheet('tracing.tracks.slice_track'); 82da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.require('base.sorted_array_utils'); 106833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennisbase.require('tracing.tracks.heading_track'); 1166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.require('tracing.fast_rect_renderer'); 1266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennisbase.require('tracing.color_scheme'); 132da489cd246702bee5938545b18a6f710ed214bcJamie Gennisbase.require('ui'); 142da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1588448d9ae4dfff1805045790ef5f32495d62abccJeff Brownbase.exportTo('tracing.tracks', function() { 162da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 172da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var palette = tracing.getColorPalette(); 182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 192da489cd246702bee5938545b18a6f710ed214bcJamie Gennis /** 2088448d9ae4dfff1805045790ef5f32495d62abccJeff Brown * A track that displays an array of Slice objects. 212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * @constructor 226833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis * @extends {HeadingTrack} 232da489cd246702bee5938545b18a6f710ed214bcJamie Gennis */ 242da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var SliceTrack = ui.define( 266833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis 'slice-track', tracing.tracks.HeadingTrack); 272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2888448d9ae4dfff1805045790ef5f32495d62abccJeff Brown SliceTrack.prototype = { 292da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 306833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis __proto__: tracing.tracks.HeadingTrack.prototype, 312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis /** 332da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * Should we elide text on trace labels? 342da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * Without eliding, text that is too wide isn't drawn at all. 352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * Disable if you feel this causes a performance problem. 362da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * This is a default value that can be overridden in tracks for testing. 372da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * @const 382da489cd246702bee5938545b18a6f710ed214bcJamie Gennis */ 392da489cd246702bee5938545b18a6f710ed214bcJamie Gennis SHOULD_ELIDE_TEXT: true, 402da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 4166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis decorate: function(viewport) { 426833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis tracing.tracks.HeadingTrack.prototype.decorate.call(this, viewport); 4388448d9ae4dfff1805045790ef5f32495d62abccJeff Brown this.classList.add('slice-track'); 442da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.elidedTitleCache = new ElidedTitleCache(); 452da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.asyncStyle_ = false; 466833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis this.slices_ = null; 472da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 482da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 492da489cd246702bee5938545b18a6f710ed214bcJamie Gennis get asyncStyle() { 502da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return this.asyncStyle_; 512da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 522da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 532da489cd246702bee5938545b18a6f710ed214bcJamie Gennis set asyncStyle(v) { 542da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.asyncStyle_ = !!v; 552da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 562da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 572da489cd246702bee5938545b18a6f710ed214bcJamie Gennis get slices() { 582da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return this.slices_; 592da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 602da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 612da489cd246702bee5938545b18a6f710ed214bcJamie Gennis set slices(slices) { 622da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.slices_ = slices || []; 632da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 642da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 652da489cd246702bee5938545b18a6f710ed214bcJamie Gennis get height() { 662da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return window.getComputedStyle(this).height; 672da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 682da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 692da489cd246702bee5938545b18a6f710ed214bcJamie Gennis set height(height) { 702da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.style.height = height; 712da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 722da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 7366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis get hasVisibleContent() { 7466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return this.slices.length > 0; 7566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis }, 7666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 772da489cd246702bee5938545b18a6f710ed214bcJamie Gennis labelWidth: function(title) { 7866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis return quickMeasureText(this.context(), title) + 2; 792da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 802da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 812da489cd246702bee5938545b18a6f710ed214bcJamie Gennis labelWidthWorld: function(title, pixWidth) { 822da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return this.labelWidth(title) * pixWidth; 832da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 842da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 856833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis draw: function(type, viewLWorld, viewRWorld) { 866833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis switch (type) { 876833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis case tracing.tracks.DrawType.SLICE: 886833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis this.drawSlices_(viewLWorld, viewRWorld); 896833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis break; 906833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis } 916833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis }, 926833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis 936833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis drawSlices_: function(viewLWorld, viewRWorld) { 9466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var ctx = this.context(); 9566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var pixelRatio = window.devicePixelRatio || 1; 962da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 9766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var bounds = this.getBoundingClientRect(); 9866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var height = bounds.height * pixelRatio; 992da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1002da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Culling parameters. 10166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var vp = this.viewport; 1022da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var pixWidth = vp.xViewVectorToWorld(1); 1032da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1042da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Begin rendering in world space. 1052da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.save(); 1062da489cd246702bee5938545b18a6f710ed214bcJamie Gennis vp.applyTransformToCanvas(ctx); 1072da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1082da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Slices. 1092da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (this.asyncStyle_) 1102da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.globalAlpha = 0.25; 1112da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var tr = new tracing.FastRectRenderer(ctx, 2 * pixWidth, 2 * pixWidth, 1122da489cd246702bee5938545b18a6f710ed214bcJamie Gennis palette); 11366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis tr.setYandH(0, height); 1142da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var slices = this.slices_; 11566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var lowSlice = base.findLowIndexInSortedArray( 11666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis slices, 11766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis function(slice) { return slice.start + slice.duration; }, 11866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis viewLWorld); 11966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 1202da489cd246702bee5938545b18a6f710ed214bcJamie Gennis for (var i = lowSlice; i < slices.length; ++i) { 1212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var slice = slices[i]; 1222da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var x = slice.start; 1236833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis if (x > viewRWorld) 1242da489cd246702bee5938545b18a6f710ed214bcJamie Gennis break; 1256833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis 1262da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Less than 0.001 causes short events to disappear when zoomed in. 1272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var w = Math.max(slice.duration, 0.001); 1282da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var colorId = slice.selected ? 1292da489cd246702bee5938545b18a6f710ed214bcJamie Gennis slice.colorId + highlightIdBoost : 1302da489cd246702bee5938545b18a6f710ed214bcJamie Gennis slice.colorId; 1312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (w < pixWidth) 1332da489cd246702bee5938545b18a6f710ed214bcJamie Gennis w = pixWidth; 1342da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (slice.duration > 0) { 1352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis tr.fillRect(x, w, colorId); 1362da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } else { 1372da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Instant: draw a triangle. If zoomed too far, collapse 1382da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // into the FastRectRenderer. 1392da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (pixWidth > 0.001) { 1402da489cd246702bee5938545b18a6f710ed214bcJamie Gennis tr.fillRect(x, pixWidth, colorId); 1412da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } else { 1422da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.fillStyle = palette[colorId]; 1432da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.beginPath(); 14466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis ctx.moveTo(x - (4 * pixWidth), height); 1452da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.lineTo(x, 0); 14666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis ctx.lineTo(x + (4 * pixWidth), height); 1472da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.closePath(); 1482da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.fill(); 1492da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 1502da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 1512da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 1522da489cd246702bee5938545b18a6f710ed214bcJamie Gennis tr.flush(); 1532da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.restore(); 1542da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 1552da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Labels. 15666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (height > 8) { 1572da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.textAlign = 'center'; 1582da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.textBaseline = 'top'; 1592da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.font = (10 * pixelRatio) + 'px sans-serif'; 1602da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.strokeStyle = 'rgb(0,0,0)'; 1612da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ctx.fillStyle = 'rgb(0,0,0)'; 16266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 1632da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Don't render text until until it is 20px wide 1642da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var quickDiscardThresshold = pixWidth * 20; 1652da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var shouldElide = this.SHOULD_ELIDE_TEXT; 1662da489cd246702bee5938545b18a6f710ed214bcJamie Gennis for (var i = lowSlice; i < slices.length; ++i) { 1672da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var slice = slices[i]; 16866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (slice.start > viewRWorld) 1692da489cd246702bee5938545b18a6f710ed214bcJamie Gennis break; 17066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 17166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (slice.duration <= quickDiscardThresshold) 17266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis continue; 17366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 17466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var title = slice.title + 17566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis (slice.didNotFinish ? ' (Did Not Finish)' : ''); 17666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis 17766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var drawnTitle = title; 17866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var drawnWidth = this.labelWidth(drawnTitle); 17966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (shouldElide && 18066a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this.labelWidthWorld(drawnTitle, pixWidth) > slice.duration) { 18166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var elidedValues = this.elidedTitleCache.get( 18266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis this, pixWidth, 18366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis drawnTitle, drawnWidth, 18466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis slice.duration); 18566a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis drawnTitle = elidedValues.string; 18666a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis drawnWidth = elidedValues.width; 1872da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 1882da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 18966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (drawnWidth * pixWidth < slice.duration) { 1902da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 19166a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var cX = vp.xWorldToView(slice.start + 0.5 * slice.duration); 19266a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis ctx.fillText(drawnTitle, cX, 2.5 * pixelRatio, drawnWidth); 19366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 19466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis } 1952da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 1962da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 1972da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 19866a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis addIntersectingItemsInRangeToSelectionInWorldSpace: function( 19966a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis loWX, hiWX, viewPixWidthWorld, selection) { 2002da489cd246702bee5938545b18a6f710ed214bcJamie Gennis function onPickHit(slice) { 2016833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis var hit = selection.addSlice(this, slice); 2026833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis this.decorateHit(hit); 2032da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 20466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis base.iterateOverIntersectingIntervals(this.slices_, 2052da489cd246702bee5938545b18a6f710ed214bcJamie Gennis function(x) { return x.start; }, 2062da489cd246702bee5938545b18a6f710ed214bcJamie Gennis function(x) { return x.duration; }, 2072da489cd246702bee5938545b18a6f710ed214bcJamie Gennis loWX, hiWX, 2086833e18b1d4077bf3a727b4422cc2acdbeee35a7Jamie Gennis onPickHit.bind(this)); 2092da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 2102da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2112da489cd246702bee5938545b18a6f710ed214bcJamie Gennis /** 2122da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * Find the index for the given slice. 2132da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * @return {index} Index of the given slice, or undefined. 2142da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * @private 2152da489cd246702bee5938545b18a6f710ed214bcJamie Gennis */ 2162da489cd246702bee5938545b18a6f710ed214bcJamie Gennis indexOfSlice_: function(slice) { 21766a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis var index = base.findLowIndexInSortedArray(this.slices_, 2182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis function(x) { return x.start; }, 2192da489cd246702bee5938545b18a6f710ed214bcJamie Gennis slice.start); 2202da489cd246702bee5938545b18a6f710ed214bcJamie Gennis while (index < this.slices_.length && 2212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis slice.start == this.slices_[index].start && 2222da489cd246702bee5938545b18a6f710ed214bcJamie Gennis slice.colorId != this.slices_[index].colorId) { 2232da489cd246702bee5938545b18a6f710ed214bcJamie Gennis index++; 2242da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 2252da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return index < this.slices_.length ? index : undefined; 2262da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 2272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2282da489cd246702bee5938545b18a6f710ed214bcJamie Gennis /** 2292da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * Add the item to the left or right of the provided hit, if any, to the 2302da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * selection. 2312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * @param {slice} The current slice. 2322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * @param {Number} offset Number of slices away from the hit to look. 23388448d9ae4dfff1805045790ef5f32495d62abccJeff Brown * @param {Selection} selection The selection to add a hit to, 2342da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * if found. 2352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * @return {boolean} Whether a hit was found. 2362da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * @private 2372da489cd246702bee5938545b18a6f710ed214bcJamie Gennis */ 2382da489cd246702bee5938545b18a6f710ed214bcJamie Gennis addItemNearToProvidedHitToSelection: function(hit, offset, selection) { 2392da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (!hit.slice) 2402da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return false; 2412da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2422da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var index = this.indexOfSlice_(hit.slice); 2432da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (index === undefined) 2442da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return false; 2452da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2462da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var newIndex = index + offset; 2472da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (newIndex < 0 || newIndex >= this.slices_.length) 2482da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return false; 2492da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2502da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var hit = selection.addSlice(this, this.slices_[newIndex]); 2512da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.decorateHit(hit); 2522da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return true; 2532da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }, 2542da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2552da489cd246702bee5938545b18a6f710ed214bcJamie Gennis addAllObjectsMatchingFilterToSelection: function(filter, selection) { 2562da489cd246702bee5938545b18a6f710ed214bcJamie Gennis for (var i = 0; i < this.slices_.length; ++i) { 2572da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (filter.matchSlice(this.slices_[i])) { 2582da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var hit = selection.addSlice(this, this.slices_[i]); 2592da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.decorateHit(hit); 2602da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 2612da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 2622da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 2632da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }; 2642da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2652da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var highlightIdBoost = tracing.getColorPaletteHighlightIdBoost(); 2662da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2672da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // TODO(jrg): possibly obsoleted with the elided string cache. 2682da489cd246702bee5938545b18a6f710ed214bcJamie Gennis // Consider removing. 2692da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var textWidthMap = { }; 2702da489cd246702bee5938545b18a6f710ed214bcJamie Gennis function quickMeasureText(ctx, text) { 2712da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var w = textWidthMap[text]; 2722da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (!w) { 2732da489cd246702bee5938545b18a6f710ed214bcJamie Gennis w = ctx.measureText(text).width; 2742da489cd246702bee5938545b18a6f710ed214bcJamie Gennis textWidthMap[text] = w; 2752da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 2762da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return w; 2772da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 2782da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2792da489cd246702bee5938545b18a6f710ed214bcJamie Gennis /** 2802da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * Cache for elided strings. 2812da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * Moved from the ElidedTitleCache protoype to a "global" for speed 2822da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * (variable reference is 100x faster). 2832da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * key: String we wish to elide. 2842da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * value: Another dict whose key is width 2852da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * and value is an ElidedStringWidthPair. 2862da489cd246702bee5938545b18a6f710ed214bcJamie Gennis */ 2872da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var elidedTitleCacheDict = {}; 2882da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2892da489cd246702bee5938545b18a6f710ed214bcJamie Gennis /** 2902da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * A cache for elided strings. 2912da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * @constructor 2922da489cd246702bee5938545b18a6f710ed214bcJamie Gennis */ 2932da489cd246702bee5938545b18a6f710ed214bcJamie Gennis function ElidedTitleCache() { 2942da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 2952da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 2962da489cd246702bee5938545b18a6f710ed214bcJamie Gennis ElidedTitleCache.prototype = { 2972da489cd246702bee5938545b18a6f710ed214bcJamie Gennis /** 2982da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * Return elided text. 29988448d9ae4dfff1805045790ef5f32495d62abccJeff Brown * @param {track} A slice track or other object that defines 3002da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * functions labelWidth() and labelWidthWorld(). 3012da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * @param {pixWidth} Pixel width. 3022da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * @param {title} Original title text. 3032da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * @param {width} Drawn width in world coords. 3042da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * @param {sliceDuration} Where the title must fit (in world coords). 3052da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * @return {ElidedStringWidthPair} Elided string and width. 3062da489cd246702bee5938545b18a6f710ed214bcJamie Gennis */ 3072da489cd246702bee5938545b18a6f710ed214bcJamie Gennis get: function(track, pixWidth, title, width, sliceDuration) { 3082da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var elidedDict = elidedTitleCacheDict[title]; 3092da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (!elidedDict) { 3102da489cd246702bee5938545b18a6f710ed214bcJamie Gennis elidedDict = {}; 3112da489cd246702bee5938545b18a6f710ed214bcJamie Gennis elidedTitleCacheDict[title] = elidedDict; 3122da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 3132da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var elidedDictForPixWidth = elidedDict[pixWidth]; 3142da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (!elidedDictForPixWidth) { 3152da489cd246702bee5938545b18a6f710ed214bcJamie Gennis elidedDict[pixWidth] = {}; 3162da489cd246702bee5938545b18a6f710ed214bcJamie Gennis elidedDictForPixWidth = elidedDict[pixWidth]; 3172da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 3182da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var stringWidthPair = elidedDictForPixWidth[sliceDuration]; 3192da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (stringWidthPair === undefined) { 3202da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var newtitle = title; 3212da489cd246702bee5938545b18a6f710ed214bcJamie Gennis var elided = false; 3222da489cd246702bee5938545b18a6f710ed214bcJamie Gennis while (track.labelWidthWorld(newtitle, pixWidth) > sliceDuration) { 32366a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis if (newtitle.length * 0.75 < 1) 32466a37686207944273ced825e0e8b6b6375f8c3deJamie Gennis break; 3252da489cd246702bee5938545b18a6f710ed214bcJamie Gennis newtitle = newtitle.substring(0, newtitle.length * 0.75); 3262da489cd246702bee5938545b18a6f710ed214bcJamie Gennis elided = true; 3272da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 3282da489cd246702bee5938545b18a6f710ed214bcJamie Gennis if (elided && newtitle.length > 3) 3292da489cd246702bee5938545b18a6f710ed214bcJamie Gennis newtitle = newtitle.substring(0, newtitle.length - 3) + '...'; 3302da489cd246702bee5938545b18a6f710ed214bcJamie Gennis stringWidthPair = new ElidedStringWidthPair( 3312da489cd246702bee5938545b18a6f710ed214bcJamie Gennis newtitle, 3322da489cd246702bee5938545b18a6f710ed214bcJamie Gennis track.labelWidth(newtitle)); 3332da489cd246702bee5938545b18a6f710ed214bcJamie Gennis elidedDictForPixWidth[sliceDuration] = stringWidthPair; 3342da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 3352da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return stringWidthPair; 3362da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 3372da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }; 3382da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 3392da489cd246702bee5938545b18a6f710ed214bcJamie Gennis /** 3402da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * A pair representing an elided string and world-coordinate width 3412da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * to draw it. 3422da489cd246702bee5938545b18a6f710ed214bcJamie Gennis * @constructor 3432da489cd246702bee5938545b18a6f710ed214bcJamie Gennis */ 3442da489cd246702bee5938545b18a6f710ed214bcJamie Gennis function ElidedStringWidthPair(string, width) { 3452da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.string = string; 3462da489cd246702bee5938545b18a6f710ed214bcJamie Gennis this.width = width; 3472da489cd246702bee5938545b18a6f710ed214bcJamie Gennis } 3482da489cd246702bee5938545b18a6f710ed214bcJamie Gennis 3492da489cd246702bee5938545b18a6f710ed214bcJamie Gennis return { 35088448d9ae4dfff1805045790ef5f32495d62abccJeff Brown SliceTrack: SliceTrack 3512da489cd246702bee5938545b18a6f710ed214bcJamie Gennis }; 3522da489cd246702bee5938545b18a6f710ed214bcJamie Gennis}); 353