UNPKG

2.98 kBJavaScriptView Raw
1'use strict'
2
3const d3 = require('./d3.js')
4const icons = require('./icons.js')
5const categories = require('./categories.js')
6const EventEmitter = require('events')
7
8function getTextNodeBoundingRect (textNode) {
9 const range = document.createRange()
10 range.selectNode(textNode)
11 return range.getBoundingClientRect()
12}
13
14class Issue {
15 constructor (id, detected, title) {
16 this.graphId = `graph-${id}`
17 this.detected = detected
18 this.title = title
19 }
20}
21
22class Alert extends EventEmitter {
23 constructor () {
24 super()
25
26 this.analysis = null
27 this.fullTitleWidth = null
28
29 this.container = d3.select('#alert')
30 this.container.classed('open', true)
31
32 this.summary = this.container.append('div')
33 .classed('summary', true)
34
35 this.alert = this.summary.append('svg')
36 .classed('alert', true)
37 .call(icons.insertIcon('warning'))
38
39 this.title = this.summary.append('div')
40 .classed('title', true)
41
42 this.titleTextNode = document.createTextNode('')
43 this.title.node().appendChild(this.titleTextNode)
44
45 this.details = this.container.append('ul')
46 .classed('details', true)
47 }
48
49 _setTitleText (title) {
50 this.titleTextNode.textContent = `Detected ${title}`
51 }
52
53 setData (data) {
54 this.analysis = data.analysis
55
56 // Set issue marker
57 const content = categories.getContent(this.analysis.issueCategory)
58 this.container.classed('has-issue', content.issue)
59
60 // Set items
61 const issues = this.analysis.issues
62 const memory = issues.memory.external !== 'none' ||
63 issues.memory.heapTotal !== 'none' ||
64 issues.memory.heapUsage !== 'none' ||
65 issues.memory.rss !== 'none'
66
67 const issuesAsData = [
68 new Issue('cpu', issues.cpu !== 'none', 'CPU Usage'),
69 new Issue('memory', memory, 'Memory Usage'),
70 new Issue('delay', issues.delay !== 'none', 'Event Loop Delay'),
71 new Issue('handles', issues.handles !== 'none', 'Active Handles')
72 ].filter((issue) => issue.detected)
73
74 this.details
75 .selectAll('li')
76 .data(issuesAsData)
77 .enter()
78 .append('li')
79 .on('click', (d) => this.emit('click', d.graphId))
80 .on('mouseover', (d) => this.emit('hover-in', d.graphId))
81 .on('mouseout', (d) => this.emit('hover-out', d.graphId))
82 .append('span')
83 .text((d) => d.title)
84
85 // Set title text now, such that the width is calculated correctly
86 this._setTitleText(content.title)
87 this.fullTitleWidth = getTextNodeBoundingRect(this.titleTextNode).width
88 }
89
90 draw () {
91 const content = categories.getContent(this.analysis.issueCategory)
92
93 // If there is not enough space, shorten the title text
94 const titleNode = this.title.node()
95 if (parseInt(window.getComputedStyle(titleNode).width) < this.fullTitleWidth) {
96 this._setTitleText(content.issue ? 'issue' : 'no issue')
97 } else {
98 this._setTitleText(content.title)
99 }
100 }
101}
102
103module.exports = new Alert()