Completed
Push — master ( e44fcc...66a6f6 )
by Chris
01:19
created

jsondash.handlers.handleDataTable   B

Complexity

Conditions 1
Paths 2

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
cc 1
c 3
b 1
f 0
nc 2
nop 2
dl 0
loc 27
rs 8.8571

1 Function

Rating   Name   Duplication   Size   Complexity  
B 0 24 2
1
/** global: jsondash */
2
/** global: c3 */
3
/** global: d3 */
4
/** global: venn */
5
/** global: Plotly */
6
7
jsondash.getJSON = function(container, url, callback) {
8
    if(!url) throw new Error('Invalid URL: ' + url);
0 ignored issues
show
Coding Style Best Practice introduced by
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 b = 42 will always be executed, while the logging statement will be executed conditionally.

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...
9
    var err_msg = null;
10
    d3.json(url, function(error, data){
11
        if(error) {
12
            jsondash.unload(container);
13
            err_msg = 'Error: ' + error.status + ' ' + error.statusText;
14
        }
15
        else if(!data) {
16
            jsondash.unload(container);
17
            err_msg = 'No data was found (invalid response).';
18
        }
19
        if(error || !data) {
20
            container.classed({error: true});
21
            container.select('.error-overlay')
22
                .classed({hidden: false})
23
                .select('.alert')
24
                .text(err_msg);
25
            jsondash.unload(container);
26
            return;
27
        }
28
        callback(error, data);
29
    });
30
};
31
32
33
/**
34
 * [getTitleBarHeight Return the height for a chart containers titlebar,
35
 *     plus any other computed box model properties.
36
 */
37
jsondash.getTitleBarHeight = function(container) {
38
    var titlebar = container.select('.widget-title');
39
    var titlebar_height = titlebar.node().getBoundingClientRect().height;
40
    var titlebar_padding = parseInt(titlebar.style('padding-bottom').replace('px', ''), 10);
41
    return titlebar_height + titlebar_padding;
42
};
43
44
/**
45
 * [getDynamicWidth Return the width for a container that has no specified width
46
 * (e.g. grid mode)]
47
 */
48
jsondash.getDynamicWidth = function(container, config) {
49
    if(isNaN(config.width)) {
50
        return d3.round(container.node().getBoundingClientRect().width);
51
    }
52
    return parseInt(config.width, 10);
53
};
54
55
56
/**
57
 * [getDiameter Calculate a valid diameter for a circular widget,
58
 * based on width/height to ensure the size never goes out of the container bounds.]
59
 */
60
jsondash.getDiameter = function(container, config) {
61
    var width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width;
62
    return d3.min([d3.round(width), config.height]);
63
};
64
65
/**
66
 * Handler for all sigma.js specifications
67
 */
68
jsondash.handlers.handleSigma = function(container, config) {
69
    'use strict';
70
    var _width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width;
71
    // Titlebar + padding + a bit extra to account for the bottom.
72
    var titlebar_offset = jsondash.getTitleBarHeight(container) * 1.2;
73
    // Sigmajs just assumes an ID for the querySelector, so we need to add one
74
    // to the child container.
75
    var new_id = 'sigma-' + jsondash.util.guid();
76
    var width = (_width - 10) + 'px';
77
    var height = (config.height - titlebar_offset) + 'px';
78
    container
79
        .select('.chart-container')
80
        .attr('id', new_id)
81
        .style({
82
        width: width,
83
        height: height
84
    });
85
    jsondash.getJSON(container, config.dataSource, function(error, data){
86
        var sig = new sigma({
0 ignored issues
show
Bug introduced by
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...
Coding Style Best Practice introduced by
By convention, constructors like sigma should be capitalized.
Loading history...
Unused Code introduced by
The variable sig seems to be never used. Consider removing it.
Loading history...
87
          graph: data,
88
          width: width,
89
          height: height,
90
          container: new_id
91
        });
92
        // Look for callbacks potentially registered for third party code.
93
        jsondash.api.runCallbacks(container, config);
94
        jsondash.unload(container);
95
    });
96
};
97
98
/**
99
 * Handler for all cytoscape specifications
100
 */
101
jsondash.handlers.handleCytoscape = function(container, config) {
102
    'use strict';
103
    var _width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width;
104
    // Titlebar + padding + a bit extra to account for the bottom.
105
    var titlebar_offset = jsondash.getTitleBarHeight(container) * 1.2;
106
    container
107
        .select('.chart-container')
108
        .style({
109
        width: (_width - 10) + 'px',
110
        height: (config.height - titlebar_offset) + 'px'
111
    });
112
    jsondash.getJSON(container, config.dataSource, function(error, cyspec){
113
        // the `document.getElementByID` declaration in the cytoscape
114
        // spec is not serializable so we will ignore anything user
115
        // sent and just drop our selector in place of it.
116
        var override = {
117
            container: document.querySelector('[data-guid="' + config.guid + '"] .chart-container'),
118
            // We intentionally override w/h with null values,
119
            // so the graph is forced to be
120
            // constrained to the parent dimensions.
121
            layout: {
122
                width: null,
123
                height: null
124
            },
125
        };
126
        var spec = $.extend(cyspec, override);
127
        console.log(spec);
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
128
        var cy = cytoscape(spec);
0 ignored issues
show
Unused Code introduced by
The variable cy seems to be never used. Consider removing it.
Loading history...
129
        // Look for callbacks potentially registered for third party code.
130
        jsondash.api.runCallbacks(container, config);
131
        jsondash.unload(container);
132
    });
133
};
134
135
/**
136
 * Handler for all vega-lite specifications
137
 */
138
jsondash.handlers.handleVegaLite = function(container, config) {
139
    'use strict';
140
    jsondash.getJSON(container, config.dataSource, function(error, vlspec){
141
        var SCALE_FACTOR = 0.7; // very important to get sizing jusst right.
142
        var selector = '[data-guid="' + config.guid + '"] .chart-container';
143
        var width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width;
144
        var size = d3.max([config.height, width]);
145
        var overrides = {
146
            width: ~~(size * SCALE_FACTOR),
147
            height: ~~(config.height * SCALE_FACTOR)
148
        };
149
        var embedSpec = {
150
            mode: 'vega-lite',
151
            spec: $.extend({}, vlspec, overrides)
152
        };
153
        vg.embed(selector, embedSpec, function(error, result) {
0 ignored issues
show
Bug introduced by
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...
Unused Code introduced by
The parameter result is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
154
            // Callback receiving the View instance and parsed Vega spec
155
            // result.view is the View, which resides under the '#vis' element
156
            if(error) {
157
                throw new Error('Error loading chart: ' + error);
158
            }
159
            // Change look of default buttons
160
            container.select('.vega-actions')
161
                .classed({'btn-group': true})
162
                .selectAll('a')
163
                .classed({'btn btn-xs btn-default': true});
164
            // Look for callbacks potentially registered for third party code.
165
            jsondash.api.runCallbacks(container, config);
166
            jsondash.unload(container);
167
        });
168
    });
169
};
170
171
/**
172
 * Handlers for various widget types. The method signatures are always the same,
173
 * but each handler can handle them differently.
174
 */
175
jsondash.handlers.handleYoutube = function(container, config) {
176
    // Clean up all previous.
177
    'use strict';
178
    function getAttr(prop, props) {
179
        // Return the propery from a list of properties for the iframe.
180
        // e.g. getAttr('width', ["width="900""]) --> "900"
181
        return props.filter(function(k, v){
0 ignored issues
show
Unused Code introduced by
The parameter v is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
182
            return k.startsWith(prop);
183
        })[0];
184
    }
185
186
187
    var url = config.dataSource;
0 ignored issues
show
Unused Code introduced by
The assignment to variable url seems to be never used. Consider removing it.
Loading history...
188
    var parts = config.dataSource.split(' ');
189
    var yt_width = parseInt(getAttr('width', parts).split('=')[1].replace(/"/gi, ''), 10);
190
    var height = parseInt(getAttr('height', parts).split('=')[1].replace(/"/gi, ''), 10);
191
    var width = isNaN(config.width) ? '100%' : yt_width;
192
    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 187. 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...
193
194
    // In the case of YouTube, we have to override the config dimensions
195
    // as this will be wonky when the aspect ratio is calculated. We will
196
    // defer to YouTube calculations instead.
197
    container
198
        .select('.chart-container')
199
        .append('iframe')
200
        .attr('width', width)
201
        .attr('height', height)
202
        .attr('src', url)
203
        .attr('allowfullscreen', true)
204
        .attr('frameborder', 0);
205
    // Look for callbacks potentially registered for third party code.
206
    jsondash.api.runCallbacks(container, config);
207
    jsondash.unload(container);
208
};
209
210
/**
211
 * [handleGraph creates graphs using the dot format
212
 * spec with d3 and dagre-d3]
213
 */
214
jsondash.handlers.handleGraph = function(container, config) {
215
    'use strict';
216
    jsondash.getJSON(container, config.dataSource, function(error, data){
217
        var h = config.height - jsondash.config.WIDGET_MARGIN_Y;
0 ignored issues
show
Unused Code introduced by
The variable h seems to be never used. Consider removing it.
Loading history...
218
        var w = config.width - jsondash.config.WIDGET_MARGIN_X;
0 ignored issues
show
Unused Code introduced by
The variable w seems to be never used. Consider removing it.
Loading history...
219
        var svg = container
220
            .select('.chart-container')
221
            .append('svg')
222
            .classed({'chart-graph': true});
223
        var svg_group = svg.append('g');
224
        var g = graphlibDot.read(data.graph);
0 ignored issues
show
Bug introduced by
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...
225
        var bbox = null;
0 ignored issues
show
Unused Code introduced by
The assignment to bbox seems to be never used. If you intend to free memory here, this is not necessary since the variable leaves the scope anyway.
Loading history...
226
        // Create the renderer
227
        var render = new dagreD3.render();
0 ignored issues
show
Bug introduced by
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...
228
        render(svg_group, g);
229
        bbox = svg.node().getBBox();
230
        svg.attr('width', bbox.width)
231
            .attr('height', bbox.height);
232
        // Look for callbacks potentially registered for third party code.
233
        jsondash.api.runCallbacks(container, config);
234
        jsondash.unload(container);
235
    });
236
};
237
238
/**
239
 * [handleWordCloud create word clouds using the d3-cloud extension.]
240
 */
241
jsondash.handlers.handleWordCloud = function(container, config) {
242
    'use strict';
243
    jsondash.getJSON(container, config.dataSource, function(error, data){
244
        var h     = config.height - jsondash.config.WIDGET_MARGIN_Y;
245
        var w     = config.width - jsondash.config.WIDGET_MARGIN_X;
246
        var svg   = container
247
            .select('.chart-container')
248
            .append('svg')
249
            .classed({'wordcloud': true});
250
        var fill  = d3.scale.category20();
0 ignored issues
show
Unused Code introduced by
The variable fill seems to be never used. Consider removing it.
Loading history...
251
        var cloud = d3.layout.cloud;
252
        var words = data.map(function(d) {
253
            return {text: d.text, size: d.size};
254
        });
255
        var layout = cloud()
256
            .size([w, h])
257
            .words(words)
258
            .padding(4)
259
            .rotate(function() {return ~~(Math.random() * 1) * 90;})
260
            .font('Arial')
261
            .fontSize(function(d) {return d.size;})
262
            .on('end', draw);
263
264
        layout.start();
265
266
        function draw(words) {
267
          svg
268
              .attr('width', layout.size()[0])
269
              .attr('height', layout.size()[1])
270
            .append('g')
271
              .attr('transform', 'translate(' + layout.size()[0] / 2 + ',' + layout.size()[1] / 2 + ')')
272
            .selectAll('text').data(words)
273
            .enter().append('text')
274
              .style('font-size', function(d) { return d.size + 'px'; })
275
              .style('font-family', 'arial')
276
              .style('fill', function(d, i) { return "#000"; })
0 ignored issues
show
Unused Code introduced by
The parameter i is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter d is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
277
              .attr('text-anchor', 'middle')
278
              .attr('transform', function(d) {
279
                return 'translate(' + [d.x, d.y] + ')rotate(' + d.rotate + ')';
280
              })
281
              .text(function(d) { return d.text; });
282
        }
283
284
        // Look for callbacks potentially registered for third party code.
285
        jsondash.api.runCallbacks(container, config);
286
        jsondash.unload(container);
287
    });
288
};
289
290
jsondash.handlers.handleC3 = function(container, config) {
291
    var _width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width;
292
    'use strict';
293
    var init_config = {
294
        bindto: '[data-guid="' + config.guid + '"] .chart-container',
295
        legend: {
296
            show: true
297
        },
298
        size: {
299
            height: config.height - jsondash.config.WIDGET_MARGIN_Y,
300
            width: _width - jsondash.config.WIDGET_MARGIN_X
301
        },
302
        data: {},
303
        onrendered: function(){
304
            // Look for callbacks potentially registered for third party code.
305
            jsondash.api.runCallbacks(container, config);
306
            jsondash.unload(container);
307
        }
308
    };
309
310
    /**
311
     * [normalizeData Transform data from a standardized jsondash
312
     *     format into one suitable for c3.]
313
     */
314
    function normalizeData(data, type) {
315
        // For most cases, we build out N columns into ['label', 0, 1, 2, 3] format
316
        // from data in format: {'foo': [1, 2]} or format {'foo': 1}
317
        var cols = [];
318
        if(type === 'donut' || type === 'gauge' || type === 'pie') {
319
            $.each(data, function(label, val){
320
                cols.push([label, val]);
321
            });
322
            return cols;
323
        }
324
        if(type === 'timeseries') {
325
            var dates = ['x'];
326
            data.dates.map(function(date, _){
0 ignored issues
show
Unused Code introduced by
The parameter _ is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
327
                dates.push(date);
328
            });
329
            cols.push(dates);
330
        }
331
        $.each(data, function(label, vals){
332
            if(label !== 'dates') {
333
                var newarr = [label];
334
                vals.map(function(val, _){
0 ignored issues
show
Unused Code introduced by
The parameter _ is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
335
                    newarr.push(val);
336
                });
337
                cols.push(newarr);
338
            }
339
        });
340
        return cols;
341
    }
342
343
    jsondash.getJSON(container, config.dataSource, function(error, data){
344
        if(jsondash.util.isOverride(config)) {
345
            // Just use the raw payload for this widgets' options.
346
            // Keep existing options if not specified.
347
            init_config = $.extend(init_config, data);
348
        } else {
349
            if(config.type === 'timeseries') {
350
                // Map the corresponding data key and list of dates
351
                // to the `x` property.
352
                init_config.axis = {
353
                    x: {type: 'timeseries'}
354
                };
355
                init_config.data.x = 'x';
356
            } else {
357
                init_config.data.type = config.type;
358
            }
359
            init_config.data.columns = normalizeData(data, config.type);
360
        }
361
        c3.generate(init_config);
362
    });
363
};
364
365
jsondash.handlers.handleD3 = function(container, config) {
366
    'use strict';
367
    // Handle specific types.
368
    if(config.type === 'radial-dendrogram') { return jsondash.handlers.handleRadialDendrogram(container, config); }
369
    if(config.type === 'dendrogram') { return jsondash.handlers.handleDendrogram(container, config); }
370
    if(config.type === 'voronoi') { return jsondash.handlers.handleVoronoi(container, config); }
371
    if(config.type === 'treemap') { return jsondash.handlers.handleTreemap(container, config); }
372
    if(config.type === 'circlepack') { return jsondash.handlers.handleCirclePack(container, config); }
373
    throw new Error('Unknown type: ' + config.type);
374
};
375
376
jsondash.handlers.handleCirclePack = function(container, config) {
377
    'use strict';
378
    // Adapted from https://bl.ocks.org/mbostock/4063530
379
    var margin = jsondash.config.WIDGET_MARGIN_Y;
380
    var diameter = jsondash.getDiameter(container, config) - margin;
381
    var format = d3.format(',d');
382
    var pack = d3.layout.pack()
383
        .size([diameter, diameter])
384
        .value(function(d) { return d.size; });
385
    var svg = container
386
        .select('.chart-container')
387
        .append('svg')
388
        .attr('width', diameter)
389
        .attr('height', diameter)
390
        .append('g');
391
392
    jsondash.getJSON(container, config.dataSource, function(error, data) {
393
        var node = svg.datum(data).selectAll('.node')
394
        .data(pack.nodes)
395
        .enter().append('g')
396
        .attr('class', function(d) { return d.children ? 'node' : 'leaf node'; })
397
        .attr('transform', function(d) { return 'translate(' + d.x + ',' + d.y + ')'; });
398
399
        node.append('title')
400
        .text(function(d) { return d.name + (d.children ? '' : ': ' + format(d.size)); });
401
402
        node.append('circle')
403
        .attr('r', function(d) { return d.r; });
404
405
        node.filter(function(d) { return !d.children; }).append('text')
406
        .attr('dy', '.3em')
407
        .style('text-anchor', 'middle')
408
        .text(function(d) { return d.name.substring(0, d.r / 3); });
409
        // Look for callbacks potentially registered for third party code.
410
        jsondash.api.runCallbacks(container, config);
411
        jsondash.unload(container);
412
    });
413
    d3.select(self.frameElement).style("height", diameter + "px");
0 ignored issues
show
Bug introduced by
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...
414
};
415
416
jsondash.handlers.handleTreemap = function(container, config) {
417
    'use strict';
418
    // Adapted from http://bl.ocks.org/mbostock/4063582
419
    var margin = {
0 ignored issues
show
Unused Code introduced by
The variable margin seems to be never used. Consider removing it.
Loading history...
420
        top: jsondash.config.WIDGET_MARGIN_Y / 2,
421
        bottom: jsondash.config.WIDGET_MARGIN_Y / 2,
422
        left: jsondash.config.WIDGET_MARGIN_X / 2,
423
        right: jsondash.config.WIDGET_MARGIN_X / 2
424
    };
425
    var _width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width;
426
    var width = _width - jsondash.config.WIDGET_MARGIN_X;
427
    var height = config.height - jsondash.config.WIDGET_MARGIN_Y;
428
    var color = d3.scale.category20c();
429
    var treemap = d3.layout.treemap()
430
        .size([width, height])
431
        .sticky(true)
432
        .value(function(d) { return d.size; });
433
    var div = container
434
        .select('.chart-container')
435
        .append('div')
436
        .classed({treemap: true, 'chart-centered': true})
437
        .style('position', 'relative')
438
        .style('width', width + 'px')
439
        .style('height', height + 'px');
440
441
    jsondash.getJSON(container, config.dataSource, function(error, root) {
442
        var node = div.datum(root).selectAll('.node')
443
            .data(treemap.nodes)
444
            .enter().append('div')
445
            .attr('class', 'node')
446
            .call(position)
447
            .style('border', '1px solid white')
448
            .style('font', '10px sans-serif')
449
            .style('line-height', '12px')
450
            .style('overflow', 'hidden')
451
            .style('position', 'absolute')
452
            .style('text-indent', '2px')
453
            .style('background', function(d) {
454
                return d.children ? color(d.name) : null;
455
            })
456
            .text(function(d) {
457
                return d.children ? null : d.name;
458
            });
459
        d3.selectAll('input').on('change', function change() {
460
            var value = this.value === 'count'
461
            ? function() { return 1; }
462
            : function(d) { return d.size;};
463
            node
464
            .data(treemap.value(value).nodes)
465
            .transition()
466
            .duration(1500)
467
            .call(position);
468
        });
469
        // Look for callbacks potentially registered for third party code.
470
        jsondash.api.runCallbacks(container, config);
471
        jsondash.unload(container);
472
    });
473
474
    function position() {
475
        this.style('left', function(d) { return d.x + 'px'; })
476
            .style('top', function(d) { return d.y + 'px'; })
477
            .style('width', function(d) { return Math.max(0, d.dx - 1) + 'px'; })
478
            .style('height', function(d) { return Math.max(0, d.dy - 1) + 'px'; });
479
    }
480
};
481
482
jsondash.handlers.handleRadialDendrogram = function(container, config) {
483
    'use strict';
484
    // Code taken (and refactored for use here) from:
485
    // https://bl.ocks.org/mbostock/4339607
486
    var _width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width;
0 ignored issues
show
Unused Code introduced by
The variable _width seems to be never used. Consider removing it.
Loading history...
487
    var radius = jsondash.getDiameter(container, config);
488
    var cluster = d3.layout.cluster()
489
        .size([360, radius / 2 - 150]); // reduce size relative to `radius`
490
    var diagonal = d3.svg.diagonal.radial()
491
        .projection(function(d) { return [d.y, d.x / 180 * Math.PI]; });
492
    var svg = container
493
        .select('.chart-container')
494
        .append('svg')
495
        .attr('width', radius)
496
        .attr('height', radius);
497
    var g = svg.append('g');
498
    g.attr('transform', 'translate(' + radius / 2 + ',' + radius / 2 + ')');
499
500
    jsondash.getJSON(container, config.dataSource, function(error, root) {
501
        if (error) { throw error; }
502
        var nodes = cluster.nodes(root);
503
        var link = g.selectAll('path.link')
0 ignored issues
show
Unused Code introduced by
The variable link seems to be never used. Consider removing it.
Loading history...
504
            .data(cluster.links(nodes))
505
            .enter().append('path')
506
            .attr('class', 'link')
507
            .attr('d', diagonal);
508
        var node = g.selectAll('g.node')
509
            .data(nodes)
510
            .enter().append('g')
511
            .attr('class', 'node')
512
            .attr('transform', function(d) { return 'rotate(' + (d.x - 90) + ')translate(' + d.y + ')'; });
513
        node.append('circle')
514
            .attr('r', 4.5);
515
        node.append('text')
516
            .attr('dy', '.31em')
517
            .attr('text-anchor', function(d) { return d.x < 180 ? 'start' : 'end'; })
518
            .attr('transform', function(d) { return d.x < 180 ? 'translate(8)' : 'rotate(180)translate(-8)'; })
519
            .text(function(d) { return d.name; });
520
        // Look for callbacks potentially registered for third party code.
521
        jsondash.api.runCallbacks(container, config);
522
        jsondash.unload(container);
523
    });
524
    d3.select(self.frameElement).style('height', radius * 2 + 'px');
0 ignored issues
show
Bug introduced by
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...
525
};
526
527
jsondash.handlers.handleDendrogram = function(container, config) {
528
    'use strict';
529
    var _width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width;
530
    // A general padding for the svg inside of the widget.
531
    // The cluster dendrogram will also need to have padding itself, so
532
    // the bounds are not clipped in the svg.
533
    var svg_pad = 20;
534
    var width = _width - svg_pad;
535
    var height = config.height - svg_pad;
536
    var PADDING = width / 4;
537
    var cluster = d3.layout.cluster()
538
        .size([height * 0.85, width - PADDING]);
539
    var diagonal = d3.svg.diagonal()
540
        .projection(function(d) { return [d.y, d.x]; });
541
    var svg = container
542
        .select('.chart-container')
543
        .append('svg')
544
        .attr('width', width)
545
        .attr('height', height);
546
    var g = svg.append('g')
547
        .attr('transform', 'translate(40, 0)');
548
549
    jsondash.getJSON(container, config.dataSource, function(error, root) {
550
        var nodes = cluster.nodes(root);
551
        var links = cluster.links(nodes);
552
        var link = g.selectAll('.link')
0 ignored issues
show
Unused Code introduced by
The variable link seems to be never used. Consider removing it.
Loading history...
553
        .data(links)
554
        .enter().append('path')
555
        .attr('class', 'link')
556
        .attr('d', diagonal);
557
558
        var node = g.selectAll('.node')
559
        .data(nodes)
560
        .enter().append('g')
561
        .attr('class', 'node')
562
        .attr('transform', function(d) { return 'translate(' + d.y + ',' + d.x + ')'; });
563
564
        node.append('circle').attr('r', 4.5);
565
        node.append('text')
566
        .attr('dx', function(d) { return d.children ? -8 : 8; })
567
        .attr('dy', 3)
568
        .style('text-anchor', function(d) { return d.children ? 'end' : 'start'; })
569
        .text(function(d) { return d.name; });
570
571
        // Look for callbacks potentially registered for third party code.
572
        jsondash.api.runCallbacks(container, config);
573
        jsondash.unload(container);
574
    });
575
};
576
577
jsondash.handlers.handleVoronoi = function(container, config) {
578
    'use strict';
579
    jsondash.getJSON(container, config.dataSource, function(error, data){
580
        var _width   = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width;
581
        var width    = _width - jsondash.config.WIDGET_MARGIN_X;
582
        var height   = config.height - jsondash.config.WIDGET_MARGIN_Y;
583
        var vertices = data;
584
        var voronoi  = d3.geom.voronoi().clipExtent([[0, 0], [width, height]]);
585
        var svg = container
586
            .select('.chart-container')
587
            .append('svg')
588
            .attr('width', width)
589
            .attr('height', height);
590
        var path = svg.append('g').selectAll('path');
591
        svg.selectAll('circle')
592
            .data(vertices.slice(1))
593
            .enter().append('circle')
594
            .attr('transform', function(d) { return 'translate(' + d + ')'; })
595
            .attr('r', 1.5);
596
            redraw();
597
598
        function redraw() {
599
            path = path.data(voronoi(vertices), jsondash.util.polygon);
600
            path.exit().remove();
601
            path.enter().append('path')
602
            .attr('class', function(d, i) { return 'q' + (i % 9) + '-9'; })
603
            .attr('d', jsondash.util.polygon);
604
            path.order();
605
        }
606
        // Look for callbacks potentially registered for third party code.
607
        jsondash.api.runCallbacks(container, config);
608
        jsondash.unload(container);
609
    });
610
};
611
612
jsondash.handlers.handleSparkline = function(container, config) {
613
    'use strict';
614
    var sparkline_type = config.type.split('-')[1];
615
    var spark = container
616
        .select('.chart-container')
617
        .append('div')
618
        .classed({
619
            'sparkline-container': true,
620
            'text-center': true
621
        });
622
    spark = $(spark[0]);
623
    jsondash.getJSON(container, config.dataSource, function(data){
624
        var opts = {
625
            type: sparkline_type,
626
            width: config.width - jsondash.config.WIDGET_MARGIN_X,
627
            height: config.height - jsondash.config.WIDGET_MARGIN_Y
628
        };
629
        spark.sparkline(data, opts);
630
        // Look for callbacks potentially registered for third party code.
631
        jsondash.api.runCallbacks(container, config);
632
        jsondash.unload(container);
633
    });
634
};
635
636
jsondash.handlers.handleDataTable = function(container, config) {
637
    'use strict';
638
    jsondash.getJSON(container, config.dataSource, function(error, res) {
639
        var keys = d3.keys(res[0]).map(function(d){
640
            return {data: d, title: d};
641
        });
642
        var titlebar_offset = jsondash.getTitleBarHeight(container) * 2.2;
643
        container
644
            .select('.chart-container')
645
            .append('table')
646
            .classed({
647
                table: true,
648
                'table-striped': true,
649
                'table-bordered': true,
650
                'table-condensed': true
651
            });
652
        var opts = config.override ? res : {data: res, columns: keys};
653
        $(container.select('table')[0])
654
            .dataTable(opts).css({
655
                width: 'auto',
656
                height: $(container[0]).innerHeight() - titlebar_offset
657
        });
658
        // Look for callbacks potentially registered for third party code.
659
        jsondash.api.runCallbacks(container, config);
660
        jsondash.unload(container);
661
    });
662
};
663
664
jsondash.handlers.handleSingleNum = function(container, config) {
665
    'use strict';
666
    jsondash.getJSON(container, config.dataSource, function(error, res){
667
        var data = res.data.data ? res.data.data : res.data;
668
        var num = container
669
            .select('.chart-container')
670
            .append('div')
671
            .classed({singlenum: true})
672
            .text(data);
673
        data = String(data);
674
        // Add red or green, depending on if the number appears to be pos/neg.
675
        if(!res.noformat) {
676
            num.classed({
677
                'text-danger': data.startsWith('-'),
678
                'text-success': !data.startsWith('-')
679
            });
680
        }
681
        // Allow custom colors.
682
        if(res.color && res.noformat) {
683
            num.style('color', res.color);
684
        }
685
        // Get title height to offset box.
686
        var title_h = container
0 ignored issues
show
Unused Code introduced by
The variable title_h seems to be never used. Consider removing it.
Loading history...
687
            .select('.widget-title')
688
            .node()
689
            .getBoundingClientRect()
690
            .height;
691
        var h = config.height - jsondash.config.WIDGET_MARGIN_Y;
692
        num.style({
693
            'line-height': h + 'px',
694
            height: h + 'px',
695
            width: config.width - jsondash.config.WIDGET_MARGIN_X
696
        });
697
        var digits = String(data).length;
698
        var size = jsondash.util.getDigitSize()(digits);
699
        num.style('font-size', size + 'px');
700
        // Look for callbacks potentially registered for third party code.
701
        jsondash.api.runCallbacks(container, config);
702
        jsondash.unload(container);
703
    });
704
};
705
706
jsondash.handlers.handleTimeline = function(container, config) {
707
    'use strict';
708
    jsondash.getJSON(container, config.dataSource, function(data){
709
        container.append('div').attr('id', 'widget-' + config.guid);
710
        var timeline = new TL.Timeline('widget-' + config.guid, data);
0 ignored issues
show
Bug introduced by
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...
Unused Code introduced by
The variable timeline seems to be never used. Consider removing it.
Loading history...
711
        // Look for callbacks potentially registered for third party code.
712
        jsondash.api.runCallbacks(container, config);
713
        jsondash.unload(container);
714
    });
715
};
716
717
/**
718
 * [handleImage Embed an image src directly.]
719
 */
720
jsondash.handlers.handleImage = function(container, config) {
721
    'use strict';
722
    var img = container.select('.chart-container').append('img');
723
    var height = (config.height - jsondash.config.WIDGET_MARGIN_Y) + 'px';
724
    img.attr({
725
        src: config.dataSource,
726
        height: height
727
    });
728
    img.classed({img: true});
729
    // Look for callbacks potentially registered for third party code.
730
    jsondash.api.runCallbacks(container, config);
731
    jsondash.unload(container);
732
};
733
734
jsondash.handlers.handleIframe = function(container, config) {
735
    'use strict';
736
    var iframe = container
737
        .select('.chart-container')
738
        .append('iframe');
739
    iframe.attr({
740
        border: 0,
741
        src: config.dataSource,
742
        height: config.height - jsondash.config.WIDGET_MARGIN_Y,
743
        width: isNaN(config.width) ? '100%' : config.width - jsondash.config.WIDGET_MARGIN_X
744
    });
745
    // Look for callbacks potentially registered for third party code.
746
    jsondash.api.runCallbacks(container, config);
747
    jsondash.unload(container);
748
};
749
750
jsondash.handlers.handleCustom = function(container, config) {
751
    'use strict';
752
    $.get(config.dataSource, function(html){
753
        container
754
            .select('.chart-container')
755
            .append('div')
756
            .classed({'custom-container': true})
757
            .html(html);
758
        // Look for callbacks potentially registered for third party code.
759
        jsondash.api.runCallbacks(container, config);
760
        jsondash.unload(container);
761
    });
762
};
763
764
jsondash.handlers.handleVenn = function(container, config) {
765
    'use strict';
766
    jsondash.getJSON(container, config.dataSource, function(error, data){
767
        var chart = venn.VennDiagram();
768
        var cont = container
769
            .select('.chart-container')
770
            .append('div')
771
            .classed({venn: true});
772
        cont.datum(data).call(chart);
773
        cont.select('svg')
774
            .attr('width', config.width - jsondash.config.WIDGET_MARGIN_X)
775
            .attr('height', config.height - jsondash.config.WIDGET_MARGIN_Y);
776
        // Look for callbacks potentially registered for third party code.
777
        jsondash.api.runCallbacks(container, config);
778
        jsondash.unload(container);
779
    });
780
};
781
782
jsondash.handlers.handlePlotly = function(container, config) {
783
    'use strict';
784
    var id = 'plotly-' + config.guid;
785
    var _width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width;
786
    container
787
        .select('.chart-container')
788
        .append('div')
789
        .classed({'plotly-container': true})
790
        .attr('id', id);
791
    jsondash.getJSON(container, config.dataSource, function(error, data){
792
        var plotly_wrapper =  d3.select('#' + id);
793
        delete data.layout.height;
794
        delete data.layout.width;
795
        data.layout.margin = {l: 20, r: 20, b: 20, t: 50};
796
        if(config.override) {
797
            Plotly.plot(id, data.data, data.layout || {}, data.options || {});
798
        } else {
799
            Plotly.plot(id, data);
800
        }
801
       plotly_wrapper.select('.svg-container').style({
802
            'margin': '0 auto',
803
            'width': isNaN(config.width) ? '100%' : config.width,
804
            'height': config.height
805
        });
806
        plotly_wrapper.select('#scene').style({
807
            'width': _width,
808
            'height': config.height
809
        });
810
        // Look for callbacks potentially registered for third party code.
811
        jsondash.api.runCallbacks(container, config);
812
        jsondash.unload(container);
813
    });
814
};
815