1 | /** global: jsondash */ |
||
2 | /** global: c3 */ |
||
3 | /** global: d3 */ |
||
4 | /** global: venn */ |
||
5 | /** global: Plotly */ |
||
6 | |||
7 | jsondash.handleRes = function(error, data, container) { |
||
8 | var err_msg = ''; |
||
9 | if(error) { |
||
10 | err_msg = 'Error: ' + error.status + ' ' + error.statusText; |
||
11 | } |
||
12 | else if(!data) { |
||
13 | err_msg = 'No data was found (invalid response).'; |
||
14 | } |
||
15 | if(error || !data) { |
||
16 | container.classed({error: true}); |
||
17 | container.select('.error-overlay') |
||
18 | .classed({hidden: false}) |
||
19 | .select('.alert') |
||
20 | .text(err_msg); |
||
21 | jsondash.unload(container); |
||
22 | } |
||
23 | }; |
||
24 | jsondash.getJSON = function(container, config, callback) { |
||
25 | var url = config.dataSource; |
||
26 | var cached = config.cachedData; |
||
27 | var err_msg = null; |
||
0 ignored issues
–
show
Unused Code
introduced
by
Loading history...
|
|||
28 | if(!url) throw new Error('Invalid URL: ' + url); |
||
0 ignored issues
–
show
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.
Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later. Consider: if (a > 0)
b = 42;
If you or someone else later decides to put another statement in, only the first statement will be executed. if (a > 0)
console.log("a > 0");
b = 42;
In this case the statement if (a > 0) {
console.log("a > 0");
b = 42;
}
ensures that the proper code will be executed conditionally no matter how many statements are added or removed.
Loading history...
|
|||
29 | if(cached && cached !== null && cached !== undefined) { |
||
30 | // Ensure this is not re-used for this cycle. It's somewhat of a pseudo-cache in that sense. |
||
31 | config.cachedData = null; |
||
32 | return callback(null, cached); |
||
33 | } |
||
34 | d3.json(url, function(error, data){ |
||
35 | jsondash.handleRes(error, data, container); |
||
36 | if(error || !data) { |
||
37 | return; |
||
38 | } |
||
39 | callback(error, config.key && data.multicharts[config.key] ? data.multicharts[config.key] : data); |
||
40 | }); |
||
0 ignored issues
–
show
|
|||
41 | }; |
||
42 | |||
43 | |||
44 | /** |
||
45 | * [getTitleBarHeight Return the height for a chart containers titlebar, |
||
46 | * plus any other computed box model properties. |
||
47 | */ |
||
48 | jsondash.getTitleBarHeight = function(container) { |
||
49 | var titlebar = container.select('.widget-title'); |
||
50 | var titlebar_height = titlebar.node().getBoundingClientRect().height; |
||
51 | var titlebar_padding = parseInt(titlebar.style('padding-bottom').replace('px', ''), 10); |
||
52 | return titlebar_height + titlebar_padding; |
||
53 | }; |
||
54 | |||
55 | /** |
||
56 | * [getDynamicWidth Return the width for a container that has no specified width |
||
57 | * (e.g. grid mode)] |
||
58 | */ |
||
59 | jsondash.getDynamicWidth = function(container, config) { |
||
60 | if(isNaN(config.width)) { |
||
61 | return d3.round(container.node().getBoundingClientRect().width); |
||
62 | } |
||
63 | return parseInt(config.width, 10); |
||
64 | }; |
||
65 | |||
66 | |||
67 | /** |
||
68 | * [getDiameter Calculate a valid diameter for a circular widget, |
||
69 | * based on width/height to ensure the size never goes out of the container bounds.] |
||
70 | */ |
||
71 | jsondash.getDiameter = function(container, config) { |
||
72 | var width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width; |
||
73 | return d3.min([d3.round(width), config.height]); |
||
74 | }; |
||
75 | |||
76 | /** |
||
77 | * Handler for all sigma.js specifications |
||
78 | */ |
||
79 | jsondash.handlers.handleSigma = function(container, config) { |
||
80 | 'use strict'; |
||
81 | var _width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width; |
||
82 | // Titlebar + padding + a bit extra to account for the bottom. |
||
83 | var titlebar_offset = jsondash.getTitleBarHeight(container) * 1.2; |
||
84 | // Sigmajs just assumes an ID for the querySelector, so we need to add one |
||
85 | // to the child container. |
||
86 | var new_id = 'sigma-' + jsondash.util.guid(); |
||
87 | var width = (_width - 10) + 'px'; |
||
88 | var height = (config.height - titlebar_offset) + 'px'; |
||
89 | container |
||
90 | .select('.chart-container') |
||
91 | .attr('id', new_id) |
||
92 | .classed(jsondash.util.getCSSClasses(config)) |
||
93 | .style({ |
||
94 | width: width, |
||
95 | height: height |
||
96 | }); |
||
97 | jsondash.getJSON(container, config, function(error, data){ |
||
98 | var sig = new sigma({ |
||
0 ignored issues
–
show
The variable
sigma seems to be never declared. If this is a global, consider adding a /** global: sigma */ comment.
This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed. To learn more about declaring variables in Javascript, see the MDN.
Loading history...
|
|||
99 | graph: data, |
||
100 | width: width, |
||
101 | height: height, |
||
102 | container: new_id |
||
103 | }); |
||
104 | // Look for callbacks potentially registered for third party code. |
||
105 | jsondash.api.runCallbacks(container, config); |
||
106 | jsondash.unload(container); |
||
107 | }); |
||
108 | }; |
||
109 | |||
110 | /** |
||
111 | * [handleFlameGraph handler for flameGraph plugin] |
||
112 | */ |
||
113 | jsondash.handlers.handleFlameGraph = function(container, config) { |
||
114 | jsondash.getJSON(container, config, function(_, data){ |
||
115 | var padding = 60; |
||
116 | var _width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width; |
||
117 | var flamegraph = d3.flameGraph() |
||
118 | .width(_width - padding) |
||
119 | .height(config.height - padding); |
||
120 | container.datum(data).call(flamegraph); |
||
121 | // Look for callbacks potentially registered for third party code. |
||
122 | jsondash.api.runCallbacks(container, config); |
||
123 | jsondash.unload(container); |
||
124 | }); |
||
125 | }; |
||
126 | |||
127 | /** |
||
128 | * Handler for all cytoscape specifications |
||
129 | */ |
||
130 | jsondash.handlers.handleCytoscape = function(container, config) { |
||
131 | 'use strict'; |
||
132 | var _width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width; |
||
133 | // Titlebar + padding + a bit extra to account for the bottom. |
||
134 | var titlebar_offset = jsondash.getTitleBarHeight(container) * 1.2; |
||
135 | container |
||
136 | .select('.chart-container') |
||
137 | .classed(jsondash.util.getCSSClasses(config)) |
||
138 | .style({ |
||
139 | width: (_width - 10) + 'px', |
||
140 | height: (config.height - titlebar_offset) + 'px' |
||
141 | }); |
||
142 | jsondash.getJSON(container, config, function(error, cyspec){ |
||
143 | // the `document.getElementByID` declaration in the cytoscape |
||
144 | // spec is not serializable so we will ignore anything user |
||
145 | // sent and just drop our selector in place of it. |
||
146 | var override = { |
||
147 | container: document.querySelector('[data-guid="' + config.guid + '"] .chart-container'), |
||
148 | // We intentionally override w/h with null values, |
||
149 | // so the graph is forced to be |
||
150 | // constrained to the parent dimensions. |
||
151 | layout: { |
||
152 | width: null, |
||
153 | height: null |
||
154 | }, |
||
155 | }; |
||
156 | var spec = $.extend(cyspec, override); |
||
157 | var cy = cytoscape(spec); |
||
0 ignored issues
–
show
|
|||
158 | // Look for callbacks potentially registered for third party code. |
||
159 | jsondash.api.runCallbacks(container, config); |
||
160 | jsondash.unload(container); |
||
161 | }); |
||
162 | }; |
||
163 | |||
164 | /** |
||
165 | * Handler for all vega-lite specifications |
||
166 | */ |
||
167 | jsondash.handlers.handleVegaLite = function(container, config) { |
||
168 | 'use strict'; |
||
169 | jsondash.getJSON(container, config, function(error, vlspec){ |
||
170 | var SCALE_FACTOR = 0.7; // very important to get sizing jusst right. |
||
171 | var selector = '[data-guid="' + config.guid + '"] .chart-container'; |
||
172 | var width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width; |
||
173 | var size = d3.max([config.height, width]); |
||
174 | var overrides = { |
||
175 | width: ~~(size * SCALE_FACTOR), |
||
176 | height: ~~(config.height * SCALE_FACTOR) |
||
177 | }; |
||
178 | var embedSpec = { |
||
179 | mode: 'vega-lite', |
||
180 | spec: $.extend({}, vlspec, overrides) |
||
181 | }; |
||
182 | d3.select(selector).classed(jsondash.util.getCSSClasses(config)) |
||
183 | vg.embed(selector, embedSpec, function(error, result) { |
||
0 ignored issues
–
show
The variable
vg seems to be never declared. If this is a global, consider adding a /** global: vg */ comment.
This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed. To learn more about declaring variables in Javascript, see the MDN.
Loading history...
|
|||
184 | // Callback receiving the View instance and parsed Vega spec |
||
185 | // result.view is the View, which resides under the '#vis' element |
||
186 | if(error) { |
||
187 | throw new Error('Error loading chart: ' + error); |
||
188 | } |
||
189 | // Change look of default buttons |
||
190 | container.select('.vega-actions') |
||
191 | .classed({'btn-group': true}) |
||
192 | .selectAll('a') |
||
193 | .classed({'btn btn-xs btn-default': true}); |
||
194 | // Look for callbacks potentially registered for third party code. |
||
195 | jsondash.api.runCallbacks(container, config); |
||
196 | jsondash.unload(container); |
||
197 | }); |
||
198 | }); |
||
199 | }; |
||
200 | |||
201 | /** |
||
202 | * Handlers for various widget types. The method signatures are always the same, |
||
203 | * but each handler can handle them differently. |
||
204 | */ |
||
205 | jsondash.handlers.handleYoutube = function(container, config) { |
||
206 | // Clean up all previous. |
||
207 | 'use strict'; |
||
208 | function getAttr(prop, props) { |
||
209 | // Return the propery from a list of properties for the iframe. |
||
210 | // e.g. getAttr('width', ["width="900""]) --> "900" |
||
211 | return props.filter(function(k, v){ |
||
0 ignored issues
–
show
|
|||
212 | return k.startsWith(prop); |
||
213 | })[0]; |
||
214 | } |
||
215 | |||
216 | |||
217 | var url = config.dataSource; |
||
0 ignored issues
–
show
|
|||
218 | var parts = config.dataSource.split(' '); |
||
219 | var yt_width = parseInt(getAttr('width', parts).split('=')[1].replace(/"/gi, ''), 10); |
||
220 | var height = parseInt(getAttr('height', parts).split('=')[1].replace(/"/gi, ''), 10); |
||
221 | var width = isNaN(config.width) ? '100%' : yt_width; |
||
222 | var url = getAttr('src', parts).replace('src=', '').replace(/"/gi, ''); |
||
0 ignored issues
–
show
Comprehensibility
Naming
Best Practice
introduced
by
The variable
url already seems to be declared on line 217 . Consider using another variable name or omitting the var keyword.
This check looks for variables that are declared in multiple lines. There may be several reasons for this. In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs. If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.
Loading history...
|
|||
223 | |||
224 | // In the case of YouTube, we have to override the config dimensions |
||
225 | // as this will be wonky when the aspect ratio is calculated. We will |
||
226 | // defer to YouTube calculations instead. |
||
227 | container |
||
228 | .select('.chart-container') |
||
229 | .append('iframe') |
||
230 | .classed(jsondash.util.getCSSClasses(config)) |
||
231 | .attr('width', width) |
||
232 | .attr('height', height) |
||
233 | .attr('src', url) |
||
234 | .attr('allowfullscreen', true) |
||
235 | .attr('frameborder', 0); |
||
236 | // Look for callbacks potentially registered for third party code. |
||
237 | jsondash.api.runCallbacks(container, config); |
||
238 | jsondash.unload(container); |
||
239 | }; |
||
240 | |||
241 | /** |
||
242 | * [handleGraph creates graphs using the dot format |
||
243 | * spec with d3 and dagre-d3] |
||
244 | */ |
||
245 | jsondash.handlers.handleGraph = function(container, config) { |
||
246 | 'use strict'; |
||
247 | jsondash.getJSON(container, config, function(error, data){ |
||
248 | var h = config.height - jsondash.config.WIDGET_MARGIN_Y; |
||
0 ignored issues
–
show
|
|||
249 | var w = config.width - jsondash.config.WIDGET_MARGIN_X; |
||
0 ignored issues
–
show
|
|||
250 | var svg = container |
||
251 | .select('.chart-container') |
||
252 | .append('svg') |
||
253 | .classed(jsondash.util.getCSSClasses(config)) |
||
254 | .classed({'chart-graph': true}); |
||
255 | var svg_group = svg.append('g'); |
||
256 | var g = graphlibDot.read(data.graph); |
||
0 ignored issues
–
show
The variable
graphlibDot seems to be never declared. If this is a global, consider adding a /** global: graphlibDot */ comment.
This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed. To learn more about declaring variables in Javascript, see the MDN.
Loading history...
|
|||
257 | var bbox = null; |
||
0 ignored issues
–
show
|
|||
258 | // Create the renderer |
||
259 | var render = new dagreD3.render(); |
||
0 ignored issues
–
show
The variable
dagreD3 seems to be never declared. If this is a global, consider adding a /** global: dagreD3 */ comment.
This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed. To learn more about declaring variables in Javascript, see the MDN.
Loading history...
|
|||
260 | render(svg_group, g); |
||
261 | bbox = svg.node().getBBox(); |
||
262 | svg.attr('width', bbox.width) |
||
263 | .attr('height', bbox.height); |
||
264 | // Look for callbacks potentially registered for third party code. |
||
265 | jsondash.api.runCallbacks(container, config); |
||
266 | jsondash.unload(container); |
||
267 | }); |
||
268 | }; |
||
269 | |||
270 | /** |
||
271 | * [handleWordCloud create word clouds using the d3-cloud extension.] |
||
272 | */ |
||
273 | jsondash.handlers.handleWordCloud = function(container, config) { |
||
274 | 'use strict'; |
||
275 | jsondash.getJSON(container, config, function(error, data){ |
||
276 | var h = config.height - jsondash.config.WIDGET_MARGIN_Y; |
||
277 | var w = config.width - jsondash.config.WIDGET_MARGIN_X; |
||
278 | var svg = container |
||
279 | .select('.chart-container') |
||
280 | .append('svg') |
||
281 | .classed(jsondash.util.getCSSClasses(config)) |
||
282 | .classed({'wordcloud': true}); |
||
283 | var fill = d3.scale.category20(); |
||
0 ignored issues
–
show
|
|||
284 | var cloud = d3.layout.cloud; |
||
285 | var words = data.map(function(d) { |
||
286 | return {text: d.text, size: d.size}; |
||
287 | }); |
||
288 | var layout = cloud() |
||
289 | .size([w, h]) |
||
290 | .words(words) |
||
291 | .padding(4) |
||
292 | .rotate(function() {return ~~(Math.random() * 1) * 90;}) |
||
293 | .font('Arial') |
||
294 | .fontSize(function(d) {return d.size;}) |
||
295 | .on('end', draw); |
||
296 | |||
297 | layout.start(); |
||
298 | |||
299 | function draw(words) { |
||
300 | svg |
||
301 | .attr('width', layout.size()[0]) |
||
302 | .attr('height', layout.size()[1]) |
||
303 | .append('g') |
||
304 | .attr('transform', 'translate(' + layout.size()[0] / 2 + ',' + layout.size()[1] / 2 + ')') |
||
305 | .selectAll('text').data(words) |
||
306 | .enter().append('text') |
||
307 | .style('font-size', function(d) { return d.size + 'px'; }) |
||
308 | .style('font-family', 'arial') |
||
309 | .style('fill', function(d, i) { return "#000"; }) |
||
0 ignored issues
–
show
|
|||
310 | .attr('text-anchor', 'middle') |
||
311 | .attr('transform', function(d) { |
||
312 | return 'translate(' + [d.x, d.y] + ')rotate(' + d.rotate + ')'; |
||
313 | }) |
||
314 | .text(function(d) { return d.text; }); |
||
315 | } |
||
316 | |||
317 | // Look for callbacks potentially registered for third party code. |
||
318 | jsondash.api.runCallbacks(container, config); |
||
319 | jsondash.unload(container); |
||
320 | }); |
||
321 | }; |
||
322 | |||
323 | jsondash.handlers.handleC3 = function(container, config) { |
||
324 | var _width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width; |
||
325 | 'use strict'; |
||
326 | var init_config = { |
||
327 | bindto: '[data-guid="' + config.guid + '"] .chart-container', |
||
328 | legend: { |
||
329 | show: true |
||
330 | }, |
||
331 | size: { |
||
332 | height: config.height - jsondash.config.WIDGET_MARGIN_Y, |
||
333 | width: _width - jsondash.config.WIDGET_MARGIN_X |
||
334 | }, |
||
335 | data: {}, |
||
336 | onrendered: function(){ |
||
337 | // Look for callbacks potentially registered for third party code. |
||
338 | jsondash.api.runCallbacks(container, config); |
||
339 | jsondash.unload(container); |
||
340 | } |
||
341 | }; |
||
342 | |||
343 | container |
||
344 | .select('.chart-container') |
||
345 | .classed(jsondash.util.getCSSClasses(config)) |
||
346 | |||
347 | /** |
||
348 | * [normalizeData Transform data from a standardized jsondash |
||
349 | * format into one suitable for c3.] |
||
350 | */ |
||
351 | function normalizeData(data, type) { |
||
352 | // For most cases, we build out N columns into ['label', 0, 1, 2, 3] format |
||
353 | // from data in format: {'foo': [1, 2]} or format {'foo': 1} |
||
354 | var cols = []; |
||
355 | if(type === 'donut' || type === 'gauge' || type === 'pie') { |
||
356 | $.each(data, function(label, val){ |
||
357 | cols.push([label, val]); |
||
358 | }); |
||
359 | return cols; |
||
360 | } |
||
361 | if(type === 'timeseries') { |
||
362 | var dates = ['x']; |
||
363 | data.dates.map(function(date, _){ |
||
0 ignored issues
–
show
|
|||
364 | dates.push(date); |
||
365 | }); |
||
366 | cols.push(dates); |
||
367 | } |
||
368 | $.each(data, function(label, vals){ |
||
369 | if(label !== 'dates') { |
||
370 | var newarr = [label]; |
||
371 | vals.map(function(val, _){ |
||
0 ignored issues
–
show
|
|||
372 | newarr.push(val); |
||
373 | }); |
||
374 | cols.push(newarr); |
||
375 | } |
||
376 | }); |
||
377 | return cols; |
||
378 | } |
||
379 | |||
380 | jsondash.getJSON(container, config, function(error, data){ |
||
381 | if(jsondash.util.isOverride(config)) { |
||
382 | // Just use the raw payload for this widgets' options. |
||
383 | // Keep existing options if not specified. |
||
384 | init_config = $.extend(init_config, data); |
||
385 | } else { |
||
386 | if(config.type === 'timeseries') { |
||
387 | // Map the corresponding data key and list of dates |
||
388 | // to the `x` property. |
||
389 | init_config.axis = { |
||
390 | x: {type: 'timeseries'} |
||
391 | }; |
||
392 | init_config.data.x = 'x'; |
||
393 | } else { |
||
394 | init_config.data.type = config.type; |
||
395 | } |
||
396 | init_config.data.columns = normalizeData(data, config.type); |
||
397 | } |
||
398 | c3.generate(init_config); |
||
399 | }); |
||
400 | }; |
||
401 | |||
402 | jsondash.handlers.handleBasic = function(container, config) { |
||
403 | 'use strict'; |
||
404 | if(config.type === 'numbergroup') { return jsondash.handlers.handleNumbersGroup(container, config); } |
||
405 | if(config.type === 'number') { return jsondash.handlers.handleSingleNum(container, config); } |
||
406 | if(config.type === 'iframe') { return jsondash.handlers.handleIframe(container, config); } |
||
407 | if(config.type === 'image') { return jsondash.handlers.handleImage(container, config); } |
||
408 | if(config.type === 'youtube') { return jsondash.handlers.handleYoutube(container, config); } |
||
409 | if(config.type === 'custom') { return jsondash.handlers.handleCustom(container, config); } |
||
0 ignored issues
–
show
There is no return statement if
config.type === "custom" is false . Are you sure this is correct? If so, consider adding return; explicitly.
This check looks for functions where a Consider this little piece of code function isBig(a) {
if (a > 5000) {
return "yes";
}
}
console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined
The function This behaviour may not be what you had intended. In any case, you can add a
Loading history...
|
|||
410 | }; |
||
411 | |||
412 | jsondash.handlers.handleD3 = function(container, config) { |
||
413 | 'use strict'; |
||
414 | // Handle specific types. |
||
415 | if(config.type === 'radial-dendrogram') { return jsondash.handlers.handleRadialDendrogram(container, config); } |
||
416 | if(config.type === 'dendrogram') { return jsondash.handlers.handleDendrogram(container, config); } |
||
417 | if(config.type === 'voronoi') { return jsondash.handlers.handleVoronoi(container, config); } |
||
418 | if(config.type === 'treemap') { return jsondash.handlers.handleTreemap(container, config); } |
||
419 | if(config.type === 'circlepack') { return jsondash.handlers.handleCirclePack(container, config); } |
||
0 ignored issues
–
show
There is no return statement if
config.type === "circlepack" is false . Are you sure this is correct? If so, consider adding return; explicitly.
This check looks for functions where a Consider this little piece of code function isBig(a) {
if (a > 5000) {
return "yes";
}
}
console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined
The function This behaviour may not be what you had intended. In any case, you can add a
Loading history...
|
|||
420 | }; |
||
421 | |||
422 | jsondash.handlers.handleCirclePack = function(container, config) { |
||
423 | 'use strict'; |
||
424 | // Adapted from https://bl.ocks.org/mbostock/4063530 |
||
425 | var margin = jsondash.config.WIDGET_MARGIN_Y; |
||
426 | var diameter = jsondash.getDiameter(container, config) - margin; |
||
427 | var format = d3.format(',d'); |
||
428 | var pack = d3.layout.pack() |
||
429 | .size([diameter, diameter]) |
||
430 | .value(function(d) { return d.size; }); |
||
431 | var svg = container |
||
432 | .select('.chart-container') |
||
433 | .append('svg') |
||
434 | .classed(jsondash.util.getCSSClasses(config)) |
||
435 | .attr('width', diameter) |
||
436 | .attr('height', diameter) |
||
437 | .append('g'); |
||
438 | |||
439 | jsondash.getJSON(container, config, function(error, data) { |
||
440 | var node = svg.datum(data).selectAll('.node') |
||
441 | .data(pack.nodes) |
||
442 | .enter().append('g') |
||
443 | .attr('class', function(d) { return d.children ? 'node' : 'leaf node'; }) |
||
444 | .attr('transform', function(d) { return 'translate(' + d.x + ',' + d.y + ')'; }); |
||
445 | |||
446 | node.append('title') |
||
447 | .text(function(d) { return d.name + (d.children ? '' : ': ' + format(d.size)); }); |
||
448 | |||
449 | node.append('circle') |
||
450 | .attr('r', function(d) { return d.r; }); |
||
451 | |||
452 | node.filter(function(d) { return !d.children; }).append('text') |
||
453 | .attr('dy', '.3em') |
||
454 | .style('text-anchor', 'middle') |
||
455 | .text(function(d) { return d.name.substring(0, d.r / 3); }); |
||
456 | // Look for callbacks potentially registered for third party code. |
||
457 | jsondash.api.runCallbacks(container, config); |
||
458 | jsondash.unload(container); |
||
459 | }); |
||
460 | d3.select(self.frameElement).style("height", diameter + "px"); |
||
0 ignored issues
–
show
The variable
self seems to be never declared. If this is a global, consider adding a /** global: self */ comment.
This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed. To learn more about declaring variables in Javascript, see the MDN.
Loading history...
|
|||
461 | }; |
||
462 | |||
463 | jsondash.handlers.handleTreemap = function(container, config) { |
||
464 | 'use strict'; |
||
465 | // Adapted from http://bl.ocks.org/mbostock/4063582 |
||
466 | var margin = { |
||
0 ignored issues
–
show
|
|||
467 | top: jsondash.config.WIDGET_MARGIN_Y / 2, |
||
468 | bottom: jsondash.config.WIDGET_MARGIN_Y / 2, |
||
469 | left: jsondash.config.WIDGET_MARGIN_X / 2, |
||
470 | right: jsondash.config.WIDGET_MARGIN_X / 2 |
||
471 | }; |
||
472 | var _width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width; |
||
473 | var width = _width - jsondash.config.WIDGET_MARGIN_X; |
||
474 | var height = config.height - jsondash.config.WIDGET_MARGIN_Y; |
||
475 | var color = d3.scale.category20c(); |
||
476 | var treemap = d3.layout.treemap() |
||
477 | .size([width, height]) |
||
478 | .sticky(true) |
||
479 | .value(function(d) { return d.size; }); |
||
480 | var div = container |
||
481 | .select('.chart-container') |
||
482 | .append('div') |
||
483 | .classed(jsondash.util.getCSSClasses(config)) |
||
484 | .classed({treemap: true, 'chart-centered': true}) |
||
485 | .style('position', 'relative') |
||
486 | .style('width', width + 'px') |
||
487 | .style('height', height + 'px'); |
||
488 | |||
489 | jsondash.getJSON(container, config, function(error, root) { |
||
490 | var node = div.datum(root).selectAll('.node') |
||
491 | .data(treemap.nodes) |
||
492 | .enter().append('div') |
||
493 | .attr('class', 'node') |
||
494 | .call(position) |
||
495 | .style('border', '1px solid white') |
||
496 | .style('font', '10px sans-serif') |
||
497 | .style('line-height', '12px') |
||
498 | .style('overflow', 'hidden') |
||
499 | .style('position', 'absolute') |
||
500 | .style('text-indent', '2px') |
||
501 | .style('background', function(d) { |
||
502 | return d.children ? color(d.name) : null; |
||
503 | }) |
||
504 | .text(function(d) { |
||
505 | return d.children ? null : d.name; |
||
506 | }); |
||
507 | d3.selectAll('input').on('change', function change() { |
||
508 | var value = this.value === 'count' |
||
509 | ? function() { return 1; } |
||
510 | : function(d) { return d.size;}; |
||
511 | node |
||
512 | .data(treemap.value(value).nodes) |
||
513 | .transition() |
||
514 | .duration(1500) |
||
515 | .call(position); |
||
516 | }); |
||
517 | // Look for callbacks potentially registered for third party code. |
||
518 | jsondash.api.runCallbacks(container, config); |
||
519 | jsondash.unload(container); |
||
520 | }); |
||
521 | |||
522 | function position() { |
||
523 | this.style('left', function(d) { return d.x + 'px'; }) |
||
524 | .style('top', function(d) { return d.y + 'px'; }) |
||
525 | .style('width', function(d) { return Math.max(0, d.dx - 1) + 'px'; }) |
||
526 | .style('height', function(d) { return Math.max(0, d.dy - 1) + 'px'; }); |
||
527 | } |
||
528 | }; |
||
529 | |||
530 | jsondash.handlers.handleRadialDendrogram = function(container, config) { |
||
531 | 'use strict'; |
||
532 | // Code taken (and refactored for use here) from: |
||
533 | // https://bl.ocks.org/mbostock/4339607 |
||
534 | var _width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width; |
||
0 ignored issues
–
show
|
|||
535 | var radius = jsondash.getDiameter(container, config); |
||
536 | var cluster = d3.layout.cluster() |
||
537 | .size([360, radius / 2 - 150]); // reduce size relative to `radius` |
||
538 | var diagonal = d3.svg.diagonal.radial() |
||
539 | .projection(function(d) { return [d.y, d.x / 180 * Math.PI]; }); |
||
540 | var svg = container |
||
541 | .select('.chart-container') |
||
542 | .append('svg') |
||
543 | .classed(jsondash.util.getCSSClasses(config)) |
||
544 | .attr('width', radius) |
||
545 | .attr('height', radius); |
||
546 | var g = svg.append('g'); |
||
547 | g.attr('transform', 'translate(' + radius / 2 + ',' + radius / 2 + ')'); |
||
548 | |||
549 | jsondash.getJSON(container, config, function(error, root) { |
||
550 | if (error) { throw error; } |
||
551 | var nodes = cluster.nodes(root); |
||
552 | var link = g.selectAll('path.link') |
||
0 ignored issues
–
show
|
|||
553 | .data(cluster.links(nodes)) |
||
554 | .enter().append('path') |
||
555 | .attr('class', 'link') |
||
556 | .attr('d', diagonal); |
||
557 | var node = g.selectAll('g.node') |
||
558 | .data(nodes) |
||
559 | .enter().append('g') |
||
560 | .attr('class', 'node') |
||
561 | .attr('transform', function(d) { return 'rotate(' + (d.x - 90) + ')translate(' + d.y + ')'; }); |
||
562 | node.append('circle') |
||
563 | .attr('r', 4.5); |
||
564 | node.append('text') |
||
565 | .attr('dy', '.31em') |
||
566 | .attr('text-anchor', function(d) { return d.x < 180 ? 'start' : 'end'; }) |
||
567 | .attr('transform', function(d) { return d.x < 180 ? 'translate(8)' : 'rotate(180)translate(-8)'; }) |
||
568 | .text(function(d) { return d.name; }); |
||
569 | // Look for callbacks potentially registered for third party code. |
||
570 | jsondash.api.runCallbacks(container, config); |
||
571 | jsondash.unload(container); |
||
572 | }); |
||
573 | d3.select(self.frameElement).style('height', radius * 2 + 'px'); |
||
0 ignored issues
–
show
The variable
self seems to be never declared. If this is a global, consider adding a /** global: self */ comment.
This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed. To learn more about declaring variables in Javascript, see the MDN.
Loading history...
|
|||
574 | }; |
||
575 | |||
576 | jsondash.handlers.handleDendrogram = function(container, config) { |
||
577 | 'use strict'; |
||
578 | var _width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width; |
||
579 | // A general padding for the svg inside of the widget. |
||
580 | // The cluster dendrogram will also need to have padding itself, so |
||
581 | // the bounds are not clipped in the svg. |
||
582 | var svg_pad = 20; |
||
583 | var width = _width - svg_pad; |
||
584 | var height = config.height - svg_pad; |
||
585 | var PADDING = width / 4; |
||
586 | var cluster = d3.layout.cluster() |
||
587 | .size([height * 0.85, width - PADDING]); |
||
588 | var diagonal = d3.svg.diagonal() |
||
589 | .projection(function(d) { return [d.y, d.x]; }); |
||
590 | var svg = container |
||
591 | .select('.chart-container') |
||
592 | .append('svg') |
||
593 | .classed(jsondash.util.getCSSClasses(config)) |
||
594 | .attr('width', width) |
||
595 | .attr('height', height); |
||
596 | var g = svg.append('g') |
||
597 | .attr('transform', 'translate(40, 0)'); |
||
598 | |||
599 | jsondash.getJSON(container, config, function(error, root) { |
||
600 | var nodes = cluster.nodes(root); |
||
601 | var links = cluster.links(nodes); |
||
602 | var link = g.selectAll('.link') |
||
0 ignored issues
–
show
|
|||
603 | .data(links) |
||
604 | .enter().append('path') |
||
605 | .attr('class', 'link') |
||
606 | .attr('d', diagonal); |
||
607 | |||
608 | var node = g.selectAll('.node') |
||
609 | .data(nodes) |
||
610 | .enter().append('g') |
||
611 | .attr('class', 'node') |
||
612 | .attr('transform', function(d) { return 'translate(' + d.y + ',' + d.x + ')'; }); |
||
613 | |||
614 | node.append('circle').attr('r', 4.5); |
||
615 | node.append('text') |
||
616 | .attr('dx', function(d) { return d.children ? -8 : 8; }) |
||
617 | .attr('dy', 3) |
||
618 | .style('text-anchor', function(d) { return d.children ? 'end' : 'start'; }) |
||
619 | .text(function(d) { return d.name; }); |
||
620 | |||
621 | // Look for callbacks potentially registered for third party code. |
||
622 | jsondash.api.runCallbacks(container, config); |
||
623 | jsondash.unload(container); |
||
624 | }); |
||
625 | }; |
||
626 | |||
627 | jsondash.handlers.handleVoronoi = function(container, config) { |
||
628 | 'use strict'; |
||
629 | jsondash.getJSON(container, config, function(error, data){ |
||
630 | var _width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width; |
||
631 | var width = _width - jsondash.config.WIDGET_MARGIN_X; |
||
632 | var height = config.height - jsondash.config.WIDGET_MARGIN_Y; |
||
633 | var vertices = data; |
||
634 | var voronoi = d3.geom.voronoi().clipExtent([[0, 0], [width, height]]); |
||
635 | var svg = container |
||
636 | .select('.chart-container') |
||
637 | .append('svg') |
||
638 | .classed(jsondash.util.getCSSClasses(config)) |
||
639 | .attr('width', width) |
||
640 | .attr('height', height); |
||
641 | var path = svg.append('g').selectAll('path'); |
||
642 | svg.selectAll('circle') |
||
643 | .data(vertices.slice(1)) |
||
644 | .enter().append('circle') |
||
645 | .attr('transform', function(d) { return 'translate(' + d + ')'; }) |
||
646 | .attr('r', 1.5); |
||
647 | redraw(); |
||
648 | |||
649 | function redraw() { |
||
650 | path = path.data(voronoi(vertices), jsondash.util.polygon); |
||
651 | path.exit().remove(); |
||
652 | path.enter().append('path') |
||
653 | .attr('class', function(d, i) { return 'q' + (i % 9) + '-9'; }) |
||
654 | .attr('d', jsondash.util.polygon); |
||
655 | path.order(); |
||
656 | } |
||
657 | // Look for callbacks potentially registered for third party code. |
||
658 | jsondash.api.runCallbacks(container, config); |
||
659 | jsondash.unload(container); |
||
660 | }); |
||
661 | }; |
||
662 | |||
663 | jsondash.handlers.handleSparkline = function(container, config) { |
||
664 | 'use strict'; |
||
665 | var sparkline_type = config.type.split('-')[1]; |
||
666 | var spark = container |
||
667 | .select('.chart-container') |
||
668 | .append('div') |
||
669 | .classed(jsondash.util.getCSSClasses(config)) |
||
670 | .classed({ |
||
671 | 'sparkline-container': true, |
||
672 | 'text-center': true |
||
673 | }); |
||
674 | spark = $(spark[0]); |
||
675 | jsondash.getJSON(container, config, function(data){ |
||
676 | var opts = { |
||
677 | type: sparkline_type, |
||
678 | width: config.width - jsondash.config.WIDGET_MARGIN_X, |
||
679 | height: config.height - jsondash.config.WIDGET_MARGIN_Y |
||
680 | }; |
||
681 | spark.sparkline(data, opts); |
||
682 | // Look for callbacks potentially registered for third party code. |
||
683 | jsondash.api.runCallbacks(container, config); |
||
684 | jsondash.unload(container); |
||
685 | }); |
||
686 | }; |
||
687 | |||
688 | jsondash.handlers.handleDataTable = function(container, config) { |
||
689 | 'use strict'; |
||
690 | jsondash.getJSON(container, config, function(error, res) { |
||
691 | var keys = d3.keys(res[0]).map(function(d){ |
||
692 | return {data: d, title: d}; |
||
693 | }); |
||
694 | var titlebar_offset = jsondash.getTitleBarHeight(container) * 2.5; |
||
0 ignored issues
–
show
|
|||
695 | var table_class_defaults = ['table', 'table-bordered', 'table-striped']; |
||
696 | var classes = jsondash.util.getCSSClasses(config, table_class_defaults); |
||
697 | container |
||
698 | .select('.chart-container') |
||
699 | .append('table') |
||
700 | .classed(classes); |
||
701 | var opts = config.override ? res : {data: res, columns: keys}; |
||
702 | $(container.select('table')[0]) |
||
703 | .dataTable(opts).css({ |
||
704 | width: 'auto', |
||
705 | }); |
||
706 | // Look for callbacks potentially registered for third party code. |
||
707 | jsondash.api.runCallbacks(container, config); |
||
708 | jsondash.unload(container); |
||
709 | }); |
||
710 | }; |
||
711 | |||
712 | jsondash.handlers.handleNumbersGroup = function(container, config) { |
||
713 | 'use strict'; |
||
714 | var scale = d3.scale.linear() |
||
715 | .clamp(true) |
||
716 | .domain([1, 20]) // min/max digits length |
||
717 | .range([80, 30]); // max/min font-size |
||
718 | |||
719 | function getStylesForColumn(d) { |
||
720 | var digits = String(d.data).length + String(d.units ? d.units : '').length; |
||
721 | var size = ~~scale(digits); |
||
722 | var styles = 'font-size: ' + size + 'px;'; |
||
723 | if(d.color && d.noformat !== false) { |
||
724 | styles += 'color: ' + d.color + ';'; |
||
725 | } |
||
726 | return styles; |
||
727 | } |
||
728 | |||
729 | jsondash.getJSON(container, config, function(error, data){ |
||
730 | container |
||
731 | .select('.chart-container') |
||
732 | .append('table') |
||
733 | .classed({numgroup: true, 'table': true}) |
||
734 | .classed(jsondash.util.getCSSClasses(config)) |
||
735 | .append('tr') |
||
736 | .selectAll('td') |
||
737 | .data(data) |
||
738 | .enter() |
||
739 | .append('td') |
||
740 | .attr('width', function(d, i){ |
||
0 ignored issues
–
show
|
|||
741 | return d.width !== null && d.width !== undefined ? d.width : null; |
||
742 | }) |
||
743 | .attr('class', function(d, i){ |
||
0 ignored issues
–
show
|
|||
744 | if(!d.noformat) { |
||
0 ignored issues
–
show
There is no return statement if
!d.noformat is false . Are you sure this is correct? If so, consider adding return; explicitly.
This check looks for functions where a Consider this little piece of code function isBig(a) {
if (a > 5000) {
return "yes";
}
}
console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined
The function This behaviour may not be what you had intended. In any case, you can add a
Loading history...
|
|||
745 | var classes = ''; |
||
746 | classes += typeof d === 'string' && d.startsWith('-') ? 'text-danger' : ''; |
||
747 | classes += typeof d === 'string' && !d.startsWith('-') ? 'text-success' : ''; |
||
748 | return classes; |
||
749 | } |
||
750 | }) |
||
751 | .html(function(d, i){ |
||
0 ignored issues
–
show
|
|||
752 | var styles = getStylesForColumn(d); |
||
753 | var title = '<p class="numgroup-title">' + d.title + '</p>'; |
||
754 | var units = d.units ? '<span class="numgroup-val-units"> ' + d.units + '</span>' : ''; |
||
755 | var num = '<h4 class="numgroup-val" style="' + styles + '">' + d.data + units + '</h4>'; |
||
756 | var desc = '<small class="numgroup-desc">' + (d.description ? d.description : '') + '</small>'; |
||
757 | return title + desc + num; |
||
758 | }); |
||
759 | // Look for callbacks potentially registered for third party code. |
||
760 | jsondash.api.runCallbacks(container, config); |
||
761 | jsondash.unload(container); |
||
762 | }); |
||
763 | }; |
||
764 | |||
765 | jsondash.handlers.handleSingleNum = function(container, config) { |
||
766 | 'use strict'; |
||
767 | jsondash.getJSON(container, config, function(error, res){ |
||
768 | var data = res.data.data ? res.data.data : res.data; |
||
769 | var num = container |
||
770 | .select('.chart-container') |
||
771 | .append('div') |
||
772 | .classed({singlenum: true}) |
||
773 | .classed(jsondash.util.getCSSClasses(config)) |
||
774 | .text(data); |
||
775 | data = String(data); |
||
776 | // Add red or green, depending on if the number appears to be pos/neg. |
||
777 | if(!res.noformat) { |
||
778 | num.classed({ |
||
779 | 'text-danger': data.startsWith('-'), |
||
780 | 'text-success': !data.startsWith('-') |
||
781 | }); |
||
782 | } |
||
783 | // Allow custom colors. |
||
784 | if(res.color && res.noformat) { |
||
785 | num.style('color', res.color); |
||
786 | } |
||
787 | // Get title height to offset box. |
||
788 | var title_h = container |
||
0 ignored issues
–
show
|
|||
789 | .select('.widget-title') |
||
790 | .node() |
||
791 | .getBoundingClientRect() |
||
792 | .height; |
||
793 | var h = config.height - jsondash.config.WIDGET_MARGIN_Y; |
||
794 | num.style({ |
||
795 | 'line-height': h + 'px', |
||
796 | height: h + 'px', |
||
797 | width: config.width - jsondash.config.WIDGET_MARGIN_X |
||
798 | }); |
||
799 | var digits = String(data).length; |
||
800 | var size = jsondash.util.getDigitSize()(digits); |
||
801 | num.style('font-size', size + 'px'); |
||
802 | // Look for callbacks potentially registered for third party code. |
||
803 | jsondash.api.runCallbacks(container, config); |
||
804 | jsondash.unload(container); |
||
805 | }); |
||
806 | }; |
||
807 | |||
808 | jsondash.handlers.handleTimeline = function(container, config) { |
||
809 | 'use strict'; |
||
810 | jsondash.getJSON(container, config, function(data){ |
||
811 | container |
||
812 | .append('div') |
||
813 | .classed(jsondash.util.getCSSClasses(config)) |
||
814 | .attr('id', 'widget-' + config.guid); |
||
815 | var timeline = new TL.Timeline('widget-' + config.guid, data); |
||
0 ignored issues
–
show
The variable
TL seems to be never declared. If this is a global, consider adding a /** global: TL */ comment.
This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed. To learn more about declaring variables in Javascript, see the MDN.
Loading history...
|
|||
816 | // Look for callbacks potentially registered for third party code. |
||
817 | jsondash.api.runCallbacks(container, config); |
||
818 | jsondash.unload(container); |
||
819 | }); |
||
820 | }; |
||
821 | |||
822 | /** |
||
823 | * [handleImage Embed an image src directly.] |
||
824 | */ |
||
825 | jsondash.handlers.handleImage = function(container, config) { |
||
826 | 'use strict'; |
||
827 | var img = container.select('.chart-container').append('img'); |
||
828 | var height = (config.height - jsondash.config.WIDGET_MARGIN_Y) + 'px'; |
||
829 | img.attr({ |
||
830 | src: config.dataSource, |
||
831 | height: height |
||
832 | }); |
||
833 | img.classed({img: true}); |
||
834 | img.classed(jsondash.util.getCSSClasses(config)); |
||
835 | // Look for callbacks potentially registered for third party code. |
||
836 | jsondash.api.runCallbacks(container, config); |
||
837 | jsondash.unload(container); |
||
838 | }; |
||
839 | |||
840 | jsondash.handlers.handleIframe = function(container, config) { |
||
841 | 'use strict'; |
||
842 | var iframe = container |
||
843 | .select('.chart-container') |
||
844 | .append('iframe'); |
||
845 | iframe.attr({ |
||
846 | border: 0, |
||
847 | src: config.dataSource, |
||
848 | height: config.height - jsondash.config.WIDGET_MARGIN_Y, |
||
849 | width: isNaN(config.width) ? '100%' : config.width - jsondash.config.WIDGET_MARGIN_X |
||
850 | }); |
||
851 | iframe.classed(jsondash.util.getCSSClasses(config)); |
||
852 | // Look for callbacks potentially registered for third party code. |
||
853 | jsondash.api.runCallbacks(container, config); |
||
854 | jsondash.unload(container); |
||
855 | }; |
||
856 | |||
857 | jsondash.handlers.handleCustom = function(container, config) { |
||
858 | 'use strict'; |
||
859 | $.get(config.dataSource, function(html){ |
||
860 | container |
||
861 | .select('.chart-container') |
||
862 | .append('div') |
||
863 | .classed({'custom-container': true}) |
||
864 | .classed(jsondash.util.getCSSClasses(config)) |
||
865 | .html(html); |
||
866 | // Look for callbacks potentially registered for third party code. |
||
867 | jsondash.api.runCallbacks(container, config); |
||
868 | jsondash.unload(container); |
||
869 | }); |
||
870 | }; |
||
871 | |||
872 | jsondash.handlers.handleVenn = function(container, config) { |
||
873 | 'use strict'; |
||
874 | jsondash.getJSON(container, config, function(error, data){ |
||
875 | var chart = venn.VennDiagram(); |
||
876 | var cont = container |
||
877 | .select('.chart-container') |
||
878 | .append('div') |
||
879 | .classed(jsondash.util.getCSSClasses(config)) |
||
880 | .classed({venn: true}); |
||
881 | cont.datum(data).call(chart); |
||
882 | cont.select('svg') |
||
883 | .attr('width', config.width - jsondash.config.WIDGET_MARGIN_X) |
||
884 | .attr('height', config.height - jsondash.config.WIDGET_MARGIN_Y); |
||
885 | // Look for callbacks potentially registered for third party code. |
||
886 | jsondash.api.runCallbacks(container, config); |
||
887 | jsondash.unload(container); |
||
888 | }); |
||
889 | }; |
||
890 | |||
891 | jsondash.handlers.handlePlotly = function(container, config) { |
||
892 | 'use strict'; |
||
893 | var id = 'plotly-' + config.guid; |
||
894 | var _width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width; |
||
895 | container |
||
896 | .select('.chart-container') |
||
897 | .append('div') |
||
898 | .classed(jsondash.util.getCSSClasses(config)) |
||
899 | .classed({'plotly-container': true}) |
||
900 | .attr('id', id); |
||
901 | jsondash.getJSON(container, config, function(error, data){ |
||
902 | var plotly_wrapper = d3.select('#' + id); |
||
903 | delete data.layout.height; |
||
904 | delete data.layout.width; |
||
905 | data.layout.margin = {l: 20, r: 20, b: 20, t: 50}; |
||
906 | if(config.override) { |
||
907 | Plotly.plot(id, data.data, data.layout || {}, data.options || {}); |
||
908 | } else { |
||
909 | Plotly.plot(id, data); |
||
910 | } |
||
911 | plotly_wrapper.select('.svg-container').style({ |
||
912 | 'margin': '0 auto', |
||
913 | 'width': isNaN(config.width) ? '100%' : config.width, |
||
914 | 'height': config.height |
||
915 | }); |
||
916 | plotly_wrapper.select('#scene').style({ |
||
917 | 'width': _width, |
||
918 | 'height': config.height |
||
919 | }); |
||
920 | // Look for callbacks potentially registered for third party code. |
||
921 | jsondash.api.runCallbacks(container, config); |
||
922 | jsondash.unload(container); |
||
923 | }); |
||
924 | }; |
||
925 |