(stacks, nodes)
| 2 | // stacks - report.StackSet |
| 3 | // nodes - List of names for each source in report.StackSet |
| 4 | function stackViewer(stacks, nodes) { |
| 5 | 'use strict'; |
| 6 | |
| 7 | // Constants used in rendering. |
| 8 | const ROW = 20; |
| 9 | const PADDING = 2; |
| 10 | const MIN_WIDTH = 4; |
| 11 | const MIN_TEXT_WIDTH = 16; |
| 12 | const TEXT_MARGIN = 2; |
| 13 | const FONT_SIZE = 12; |
| 14 | const MIN_FONT_SIZE = 8; |
| 15 | |
| 16 | // Fields |
| 17 | let pivots = []; // Indices of currently selected data.Sources entries. |
| 18 | let matches = new Set(); // Indices of sources that match search |
| 19 | let elems = new Map(); // Mapping from source index to display elements |
| 20 | let displayList = []; // List of boxes to display. |
| 21 | let actionMenuOn = false; // Is action menu visible? |
| 22 | let actionTarget = null; // Box on which action menu is operating. |
| 23 | let diff = false; // Are we displaying a diff? |
| 24 | let shown = 0; // How many profile values are being displayed? |
| 25 | |
| 26 | for (const stack of stacks.Stacks) { |
| 27 | if (stack.Value < 0) { |
| 28 | diff = true; |
| 29 | break; |
| 30 | } |
| 31 | } |
| 32 | |
| 33 | // Setup to allow measuring text width. |
| 34 | const textSizer = document.createElement('canvas'); |
| 35 | textSizer.id = 'textsizer'; |
| 36 | const textContext = textSizer.getContext('2d'); |
| 37 | |
| 38 | // Get DOM elements. |
| 39 | const chart = find('stack-chart'); |
| 40 | const search = find('search'); |
| 41 | const actions = find('action-menu'); |
| 42 | const actionTitle = find('action-title'); |
| 43 | const leftDetailBox = find('current-details-left'); |
| 44 | const rightDetailBox = find('current-details-right'); |
| 45 | |
| 46 | window.addEventListener('resize', render); |
| 47 | window.addEventListener('popstate', render); |
| 48 | search.addEventListener('keydown', handleSearchKey); |
| 49 | |
| 50 | // Withdraw action menu when clicking outside, or when item selected. |
| 51 | document.addEventListener('mousedown', (e) => { |
| 52 | if (!actions.contains(e.target)) { |
| 53 | hideActionMenu(); |
| 54 | } |
| 55 | }); |
| 56 | actions.addEventListener('click', hideActionMenu); |
| 57 | |
| 58 | // Initialize menus and other general UI elements. |
| 59 | viewer(new URL(window.location.href), nodes, { |
| 60 | hiliter: (n, on) => { return hilite(n, on); }, |
| 61 | current: () => { |
nothing calls this directly
no test coverage detected
searching dependent graphs…