1<!DOCTYPE html>
2<!--
3Copyright (c) 2014 The Chromium Authors. All rights reserved.
4Use of this source code is governed by a BSD-style license that can be
5found in the LICENSE file.
6-->
7<link rel="import" href="/tracing/base/base.html">
8<link rel="import" href="/tracing/base/color.html">
9<link rel="import" href="/tracing/base/iteration_helpers.html">
10<script>
11'use strict';
12
13/**
14 * @fileoverview Provides color scheme related functions.
15 */
16tr.exportTo('tr.b', function() {
17  // Basic constants...
18  var generalPurposeColors = [
19    new tr.b.Color(122, 98, 135),
20    new tr.b.Color(150, 83, 105),
21    new tr.b.Color(44, 56, 189),
22    new tr.b.Color(99, 86, 147),
23    new tr.b.Color(104, 129, 107),
24    new tr.b.Color(130, 178, 55),
25    new tr.b.Color(87, 109, 147),
26    new tr.b.Color(111, 145, 88),
27    new tr.b.Color(81, 152, 131),
28    new tr.b.Color(142, 91, 111),
29    new tr.b.Color(81, 163, 70),
30    new tr.b.Color(148, 94, 86),
31    new tr.b.Color(144, 89, 118),
32    new tr.b.Color(83, 150, 97),
33    new tr.b.Color(105, 94, 139),
34    new tr.b.Color(89, 144, 122),
35    new tr.b.Color(105, 119, 128),
36    new tr.b.Color(96, 128, 137),
37    new tr.b.Color(145, 88, 145),
38    new tr.b.Color(88, 145, 144),
39    new tr.b.Color(90, 100, 143),
40    new tr.b.Color(121, 97, 136),
41    new tr.b.Color(111, 160, 73),
42    new tr.b.Color(112, 91, 142),
43    new tr.b.Color(86, 147, 86),
44    new tr.b.Color(63, 100, 170),
45    new tr.b.Color(81, 152, 107),
46    new tr.b.Color(60, 164, 173),
47    new tr.b.Color(143, 72, 161),
48    new tr.b.Color(159, 74, 86)];
49
50  var reservedColorsByName = {
51    thread_state_uninterruptible: new tr.b.Color(182, 125, 143),
52    thread_state_iowait: new tr.b.Color(255, 140, 0),
53    thread_state_running: new tr.b.Color(126, 200, 148),
54    thread_state_runnable: new tr.b.Color(133, 160, 210),
55    thread_state_sleeping: new tr.b.Color(240, 240, 240),
56    thread_state_unknown: new tr.b.Color(199, 155, 125),
57
58    light_memory_dump: new tr.b.Color(0, 0, 180),
59    detailed_memory_dump: new tr.b.Color(180, 0, 180),
60
61    generic_work: new tr.b.Color(125, 125, 125),
62
63    good: new tr.b.Color(0, 125, 0),
64    bad: new tr.b.Color(180, 125, 0),
65    terrible: new tr.b.Color(180, 0, 0),
66
67    black: new tr.b.Color(0, 0, 0),
68
69    rail_response: new tr.b.Color(67, 135, 253),
70    rail_animation: new tr.b.Color(244, 74, 63),
71    rail_idle: new tr.b.Color(238, 142, 0),
72    rail_load: new tr.b.Color(13, 168, 97),
73
74    used_memory_column: new tr.b.Color(0, 0, 255),
75    older_used_memory_column: new tr.b.Color(153, 204, 255),
76    tracing_memory_column: new tr.b.Color(153, 153, 153),
77
78    heap_dump_stack_frame: new tr.b.Color(128, 128, 128),
79    heap_dump_object_type: new tr.b.Color(0, 0, 255),
80
81    cq_build_running: new tr.b.Color(255, 255, 119),
82    cq_build_passed: new tr.b.Color(153, 238, 102),
83    cq_build_failed: new tr.b.Color(238, 136, 136),
84    cq_build_abandoned: new tr.b.Color(187, 187, 187),
85
86    cq_build_attempt_runnig: new tr.b.Color(222, 222, 75),
87    cq_build_attempt_passed: new tr.b.Color(103, 218, 35),
88    cq_build_attempt_failed: new tr.b.Color(197, 81, 81)
89  };
90
91  // Some constants we'll need for later lookups.
92  var numGeneralPurposeColorIds = generalPurposeColors.length;
93  var numReservedColorIds = tr.b.dictionaryLength(reservedColorsByName);
94  var numColorsPerVariant = numGeneralPurposeColorIds + numReservedColorIds;
95
96  function ColorScheme() {
97  }
98
99  /*
100   * A flat array of tr.b.Color values of the palette, and their variants.
101   *
102   * This array is made up of a set of base colors, repeated N times to form
103   * a set of variants on that base color.
104   *
105   * Within the base colors, there are "general purpose" colors,
106   * which can be used for random color selection, and
107   * reserved colors, which are used when specific colors
108   * need to be used, e.g. where red is desired.
109   *
110   * The variants are automatically generated from the base colors. The 0th
111   * variant is the default apeparance of the color, and the varaiants are
112   * mutations of that color, e.g. several brightening levels and desaturations.
113   *
114   * For example, a very simple version of this array looks like the following:
115   *     0: Generic Color 0
116   *     1: Generic Color 1
117   *     2: Named Color 'foo'
118   *     3: Brightened Generic Color 0
119   *     4: Brightened Generic Color 1
120   *     5: Brightened Named Color 'foo'
121   */
122  var paletteBase = [];
123  paletteBase.push.apply(paletteBase, generalPurposeColors);
124  paletteBase.push.apply(paletteBase,
125                         tr.b.dictionaryValues(reservedColorsByName));
126  ColorScheme.colors = [];
127  ColorScheme.properties = {};
128  ColorScheme.properties = {
129    numColorsPerVariant: numColorsPerVariant
130  };
131
132  function pushVariant(func) {
133    var variantColors = paletteBase.map(func);
134    ColorScheme.colors.push.apply(ColorScheme.colors, variantColors);
135  }
136
137  // Basic colors.
138  pushVariant(function(c) { return c; });
139
140  // Brightened variants.
141  ColorScheme.properties.brightenedOffsets = [];
142  ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);
143  pushVariant(function(c) {
144    return c.lighten(0.3, 0.9);
145  });
146
147  ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);
148  pushVariant(function(c) {
149    return c.lighten(0.48, 0.9);
150  });
151
152  ColorScheme.properties.brightenedOffsets.push(ColorScheme.colors.length);
153  pushVariant(function(c) {
154    return c.lighten(0.65, 0.9);
155  });
156
157
158  // Desaturated variants.
159  ColorScheme.properties.dimmedOffsets = [];
160  ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);
161  pushVariant(function(c) {
162    return c.desaturate();
163  });
164  ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);
165  pushVariant(function(c) {
166    return c.desaturate(0.5);
167  });
168  ColorScheme.properties.dimmedOffsets.push(ColorScheme.colors.length);
169  pushVariant(function(c) {
170    return c.desaturate(0.3);
171  });
172
173  /**
174   * A toString'd representation of ColorScheme.colors.
175   */
176  ColorScheme.colorsAsStrings = ColorScheme.colors.map(function(c) {
177    return c.toString();
178  });
179
180  // Build reservedColorNameToIdMap.
181  var reservedColorNameToIdMap = (function() {
182    var m = {};
183    var i = generalPurposeColors.length;
184    tr.b.iterItems(reservedColorsByName, function(key, value) {
185      m[key] = i++;
186    });
187    return m;
188  })();
189
190  /**
191   * @param {String} name The color name.
192   * @return {Number} The color ID for the given color name.
193   */
194  ColorScheme.getColorIdForReservedName = function(name) {
195    var id = reservedColorNameToIdMap[name];
196    if (id === undefined)
197      throw new Error('Unrecognized color ') + name;
198    return id;
199  };
200
201  ColorScheme.getColorForReservedNameAsString = function(reservedName) {
202    var id = ColorScheme.getColorIdForReservedName(reservedName);
203    return ColorScheme.colorsAsStrings[id];
204  };
205
206  /**
207   * Computes a simplistic hashcode of the provide name. Used to chose colors
208   * for slices.
209   * @param {string} name The string to hash.
210   */
211  ColorScheme.getStringHash = function(name) {
212    var hash = 0;
213    for (var i = 0; i < name.length; ++i)
214      hash = (hash + 37 * hash + 11 * name.charCodeAt(i)) % 0xFFFFFFFF;
215    return hash;
216  };
217
218  // Previously computed string color IDs. They are based on a stable hash, so
219  // it is safe to save them throughout the program time.
220  var stringColorIdCache = {};
221
222  /**
223   * @return {Number} A color ID that is stably associated to the provided via
224   * the getStringHash method. The color ID will be chosen from the general
225   * purpose ID space only, e.g. no reserved ID will be used.
226   */
227  ColorScheme.getColorIdForGeneralPurposeString = function(string) {
228    if (stringColorIdCache[string] === undefined) {
229      var hash = ColorScheme.getStringHash(string);
230      stringColorIdCache[string] = hash % numGeneralPurposeColorIds;
231    }
232    return stringColorIdCache[string];
233  };
234
235  return {
236    ColorScheme: ColorScheme
237  };
238});
239</script>
240