Completed
Push — master ( 04c18b...a5a3aa )
by Chris
01:18
created

jsondash.getJSON   B

Complexity

Conditions 5
Paths 6

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 5
dl 0
loc 20
rs 8.8571
c 4
b 0
f 0
nc 6
nop 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
 * [getDynamicWidth Return the width for a container that has no specified width
34
 * (e.g. grid mode)]
35
 */
36
jsondash.getDynamicWidth = function(container, config) {
37
    if(isNaN(config.width)) {
38
        return d3.round(container.node().getBoundingClientRect().width);
39
    }
40
    return parseInt(config.width, 10);
41
};
42
43
/**
44
 * [getDiameter Calculate a valid diameter for a circular widget,
45
 * based on width/height to ensure the size never goes out of the container bounds.]
46
 */
47
jsondash.getDiameter = function(container, config) {
48
    var width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width;
49
    return d3.min([d3.round(width), config.height]);
50
};
51
52
/**
53
 * Handler for all vega-lite specifications
54
 */
55
jsondash.handlers.handleVegaLite = function(container, config) {
56
    'use strict';
57
    container.selectAll('.chart-container').remove();
58
    container.append('div').classed({'chart-container': true});
59
60
    jsondash.getJSON(container, config.dataSource, function(error, vlspec){
61
        var SCALE_FACTOR = 0.7; // very important to get sizing jusst right.
62
        var selector = '[data-guid="' + config.guid + '"] .chart-container';
63
        var width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width;
64
        var size = d3.max([config.height, width]);
65
        var overrides = {
66
            width: ~~(size * SCALE_FACTOR),
67
            height: ~~(config.height * SCALE_FACTOR)
68
        };
69
        var embedSpec = {
70
            mode: 'vega-lite',
71
            spec: $.extend({}, vlspec, overrides)
72
        };
73
        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...
74
            // Callback receiving the View instance and parsed Vega spec
75
            // result.view is the View, which resides under the '#vis' element
76
            if(error) {
77
                throw new Error('Error loading chart: ' + error);
78
            }
79
            // Change look of default buttons
80
            container.select('.vega-actions')
81
                .classed({'btn-group': true})
82
                .selectAll('a')
83
                .classed({'btn btn-xs btn-default': true});
84
85
            // Look for callbacks potentially registered for third party code.
86
            jsondash.api.runCallbacks(container, config);
87
            jsondash.unload(container);
88
        });
89
    });
90
};
91
92
/**
93
 * Handlers for various widget types. The method signatures are always the same,
94
 * but each handler can handle them differently.
95
 */
96
jsondash.handlers.handleYoutube = function(container, config) {
97
    // Clean up all previous.
98
    'use strict';
99
    container.selectAll('iframe').remove();
100
101
    function getAttr(prop, props) {
102
        // Return the propery from a list of properties for the iframe.
103
        // e.g. getAttr('width', ["width="900""]) --> "900"
104
        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...
105
            return k.startsWith(prop);
106
        })[0];
107
    }
108
109
110
    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...
111
    var parts = config.dataSource.split(' ');
112
    var yt_width = parseInt(getAttr('width', parts).split('=')[1].replace(/"/gi, ''), 10);
113
    var height = parseInt(getAttr('height', parts).split('=')[1].replace(/"/gi, ''), 10);
114
    var width = isNaN(config.width) ? '100%' : yt_width;
115
    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 110. 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...
116
117
    // In the case of YouTube, we have to override the config dimensions
118
    // as this will be wonky when the aspect ratio is calculated. We will
119
    // defer to YouTube calculations instead.
120
    container.append('iframe')
121
        .attr('width', width)
122
        .attr('height', height)
123
        .attr('src', url)
124
        .attr('allowfullscreen', true)
125
        .attr('frameborder', 0);
126
    // Look for callbacks potentially registered for third party code.
127
    jsondash.api.runCallbacks(container, config);
128
    jsondash.unload(container);
129
};
130
131
/**
132
 * [handleGraph creates graphs using the dot format
133
 * spec with d3 and dagre-d3]
134
 */
135
jsondash.handlers.handleGraph = function(container, config) {
136
    'use strict';
137
    jsondash.getJSON(container, config.dataSource, function(error, data){
138
        container.selectAll('.chart-graph').remove();
139
        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...
140
        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...
141
        var svg = container.append('svg').classed({'chart-graph': true});
142
        var svg_group = svg.append('g');
143
        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...
144
        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...
145
        // Create the renderer
146
        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...
147
        render(svg_group, g);
148
        bbox = svg.node().getBBox();
149
        svg.attr('width', bbox.width)
150
            .attr('height', bbox.height);
151
        // Look for callbacks potentially registered for third party code.
152
        jsondash.api.runCallbacks(container, config);
153
        jsondash.unload(container);
154
    });
155
};
156
157
/**
158
 * [handleWordCloud create word clouds using the d3-cloud extension.]
159
 */
160
jsondash.handlers.handleWordCloud = function(container, config) {
161
    'use strict';
162
    jsondash.getJSON(container, config.dataSource, function(error, data){
163
        container.selectAll('.wordcloud').remove();
164
        var h     = config.height - jsondash.config.WIDGET_MARGIN_Y;
165
        var w     = config.width - jsondash.config.WIDGET_MARGIN_X;
166
        var svg   = container.append('svg').classed({'wordcloud': true});
167
        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...
168
        var cloud = d3.layout.cloud;
169
        var words = data.map(function(d) {
170
            return {text: d.text, size: d.size};
171
        });
172
        var layout = cloud()
173
            .size([w, h])
174
            .words(words)
175
            .padding(4)
176
            .rotate(function() {return ~~(Math.random() * 1) * 90;})
177
            .font('Arial')
178
            .fontSize(function(d) {return d.size;})
179
            .on('end', draw);
180
181
        layout.start();
182
183
        function draw(words) {
184
          svg
185
              .attr('width', layout.size()[0])
186
              .attr('height', layout.size()[1])
187
            .append('g')
188
              .attr('transform', 'translate(' + layout.size()[0] / 2 + ',' + layout.size()[1] / 2 + ')')
189
            .selectAll('text').data(words)
190
            .enter().append('text')
191
              .style('font-size', function(d) { return d.size + 'px'; })
192
              .style('font-family', 'arial')
193
              .style('fill', function(d, i) { return "#000"; })
0 ignored issues
show
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...
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...
194
              .attr('text-anchor', 'middle')
195
              .attr('transform', function(d) {
196
                return 'translate(' + [d.x, d.y] + ')rotate(' + d.rotate + ')';
197
              })
198
              .text(function(d) { return d.text; });
199
        }
200
201
        // Look for callbacks potentially registered for third party code.
202
        jsondash.api.runCallbacks(container, config);
203
        jsondash.unload(container);
204
    });
205
};
206
207
jsondash.handlers.handleC3 = function(container, config) {
208
    var _width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width;
209
    'use strict';
210
    var init_config = {
211
        bindto: '[data-guid="' + config.guid + '"] .chart-container',
212
        legend: {
213
            show: true
214
        },
215
        size: {
216
            height: config.height - jsondash.config.WIDGET_MARGIN_Y,
217
            width: _width - jsondash.config.WIDGET_MARGIN_X
218
        },
219
        data: {
220
            type: config.type,
221
            url: config.dataSource,
222
            mimeType: 'json'
223
        },
224
        onrendered: function(){
225
            // Look for callbacks potentially registered for third party code.
226
            jsondash.api.runCallbacks(container, config);
227
            jsondash.unload(container);
228
        }
229
    };
230
    if(jsondash.util.isOverride(config)) {
231
        // Just use the raw payload for this widgets' options.
232
        jsondash.getJSON(container, config.dataSource, function(error, data){
233
            // Keep existing options if not specified.
234
            config = $.extend(init_config, data);
235
            c3.generate(init_config);
236
        });
237
        return;
238
    }
239
    if(config.type === 'timeseries') {
240
        init_config.axis = {
241
            x: {type: 'timeseries'}
242
        };
243
        // Map the corresponding data key and list of dates
244
        // to the `x` property.
245
        init_config.data.x = 'dates';
246
    }
247
    c3.generate(init_config);
248
};
249
250
jsondash.handlers.handleD3 = function(container, config) {
251
    'use strict';
252
    // Clean up all D3 charts in one step.
253
    container.selectAll('svg').remove();
254
    // Handle specific types.
255
    if(config.type === 'radial-dendrogram') { return jsondash.handlers.handleRadialDendrogram(container, config); }
256
    if(config.type === 'dendrogram') { return jsondash.handlers.handleDendrogram(container, config); }
257
    if(config.type === 'voronoi') { return jsondash.handlers.handleVoronoi(container, config); }
258
    if(config.type === 'treemap') { return jsondash.handlers.handleTreemap(container, config); }
259
    if(config.type === 'circlepack') { return jsondash.handlers.handleCirclePack(container, config); }
260
    throw new Error('Unknown type: ' + config.type);
261
};
262
263
jsondash.handlers.handleCirclePack = function(container, config) {
264
    'use strict';
265
    // Adapted from https://bl.ocks.org/mbostock/4063530
266
    var margin = jsondash.config.WIDGET_MARGIN_Y;
267
    var diameter = jsondash.getDiameter(container, config) - margin;
268
    var format = d3.format(',d');
269
    var pack = d3.layout.pack()
270
        .size([diameter, diameter])
271
        .value(function(d) { return d.size; });
272
273
    var svg = container
274
        .append('svg')
275
        .attr('width', diameter)
276
        .attr('height', diameter)
277
        .append('g');
278
279
    jsondash.getJSON(container, config.dataSource, function(error, data) {
280
        var node = svg.datum(data).selectAll('.node')
281
        .data(pack.nodes)
282
        .enter().append('g')
283
        .attr('class', function(d) { return d.children ? 'node' : 'leaf node'; })
284
        .attr('transform', function(d) { return 'translate(' + d.x + ',' + d.y + ')'; });
285
286
        node.append('title')
287
        .text(function(d) { return d.name + (d.children ? '' : ': ' + format(d.size)); });
288
289
        node.append('circle')
290
        .attr('r', function(d) { return d.r; });
291
292
        node.filter(function(d) { return !d.children; }).append('text')
293
        .attr('dy', '.3em')
294
        .style('text-anchor', 'middle')
295
        .text(function(d) { return d.name.substring(0, d.r / 3); });
296
        // Look for callbacks potentially registered for third party code.
297
        jsondash.api.runCallbacks(container, config);
298
        jsondash.unload(container);
299
    });
300
    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...
301
};
302
303
jsondash.handlers.handleTreemap = function(container, config) {
304
    'use strict';
305
    // Adapted from http://bl.ocks.org/mbostock/4063582
306
    var margin = {
0 ignored issues
show
Unused Code introduced by
The variable margin seems to be never used. Consider removing it.
Loading history...
307
        top: jsondash.config.WIDGET_MARGIN_Y / 2,
308
        bottom: jsondash.config.WIDGET_MARGIN_Y / 2,
309
        left: jsondash.config.WIDGET_MARGIN_X / 2,
310
        right: jsondash.config.WIDGET_MARGIN_X / 2
311
    };
312
    var _width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width;
313
    var width = _width - jsondash.config.WIDGET_MARGIN_X;
314
    var height = config.height - jsondash.config.WIDGET_MARGIN_Y;
315
    var color = d3.scale.category20c();
316
    var treemap = d3.layout.treemap()
317
        .size([width, height])
318
        .sticky(true)
319
        .value(function(d) { return d.size; });
320
    // Cleanup
321
    container.selectAll('.treemap').remove();
322
    var div = container
323
        .append('div')
324
        .classed({treemap: true, 'chart-centered': true})
325
        .style('position', 'relative')
326
        .style('width', width + 'px')
327
        .style('height', height + 'px');
328
329
    jsondash.getJSON(container, config.dataSource, function(error, root) {
330
        var node = div.datum(root).selectAll('.node')
331
            .data(treemap.nodes)
332
            .enter().append('div')
333
            .attr('class', 'node')
334
            .call(position)
335
            .style('border', '1px solid white')
336
            .style('font', '10px sans-serif')
337
            .style('line-height', '12px')
338
            .style('overflow', 'hidden')
339
            .style('position', 'absolute')
340
            .style('text-indent', '2px')
341
            .style('background', function(d) {
342
                return d.children ? color(d.name) : null;
343
            })
344
            .text(function(d) {
345
                return d.children ? null : d.name;
346
            });
347
        d3.selectAll('input').on('change', function change() {
348
            var value = this.value === 'count'
349
            ? function() { return 1; }
350
            : function(d) { return d.size;};
351
            node
352
            .data(treemap.value(value).nodes)
353
            .transition()
354
            .duration(1500)
355
            .call(position);
356
        });
357
        // Look for callbacks potentially registered for third party code.
358
        jsondash.api.runCallbacks(container, config);
359
        jsondash.unload(container);
360
    });
361
362
    function position() {
363
        this.style('left', function(d) { return d.x + 'px'; })
364
            .style('top', function(d) { return d.y + 'px'; })
365
            .style('width', function(d) { return Math.max(0, d.dx - 1) + 'px'; })
366
            .style('height', function(d) { return Math.max(0, d.dy - 1) + 'px'; });
367
    }
368
};
369
370
jsondash.handlers.handleRadialDendrogram = function(container, config) {
371
    'use strict';
372
    // Code taken (and refactored for use here) from:
373
    // https://bl.ocks.org/mbostock/4339607
374
    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...
375
    var radius = jsondash.getDiameter(container, config);
376
    var cluster = d3.layout.cluster()
377
        .size([360, radius / 2 - 150]); // reduce size relative to `radius`
378
    var diagonal = d3.svg.diagonal.radial()
379
        .projection(function(d) { return [d.y, d.x / 180 * Math.PI]; });
380
    var svg = container.append('svg')
381
        .attr('width', radius)
382
        .attr('height', radius);
383
    var g = svg.append('g');
384
    g.attr('transform', 'translate(' + radius / 2 + ',' + radius / 2 + ')');
385
386
    jsondash.getJSON(container, config.dataSource, function(error, root) {
387
        if (error) { throw error; }
388
        var nodes = cluster.nodes(root);
389
        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...
390
            .data(cluster.links(nodes))
391
            .enter().append('path')
392
            .attr('class', 'link')
393
            .attr('d', diagonal);
394
        var node = g.selectAll('g.node')
395
            .data(nodes)
396
            .enter().append('g')
397
            .attr('class', 'node')
398
            .attr('transform', function(d) { return 'rotate(' + (d.x - 90) + ')translate(' + d.y + ')'; });
399
        node.append('circle')
400
            .attr('r', 4.5);
401
        node.append('text')
402
            .attr('dy', '.31em')
403
            .attr('text-anchor', function(d) { return d.x < 180 ? 'start' : 'end'; })
404
            .attr('transform', function(d) { return d.x < 180 ? 'translate(8)' : 'rotate(180)translate(-8)'; })
405
            .text(function(d) { return d.name; });
406
        // Look for callbacks potentially registered for third party code.
407
        jsondash.api.runCallbacks(container, config);
408
        jsondash.unload(container);
409
    });
410
    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...
411
};
412
413
jsondash.handlers.handleDendrogram = function(container, config) {
414
    'use strict';
415
    var _width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width;
416
    // A general padding for the svg inside of the widget.
417
    // The cluster dendrogram will also need to have padding itself, so
418
    // the bounds are not clipped in the svg.
419
    var svg_pad = 20;
420
    var width = _width - svg_pad;
421
    var height = config.height - svg_pad;
422
    var PADDING = width / 4;
423
    var cluster = d3.layout.cluster()
424
        .size([height * 0.85, width - PADDING]);
425
    var diagonal = d3.svg.diagonal()
426
        .projection(function(d) { return [d.y, d.x]; });
427
    var svg = container
428
        .append('svg')
429
        .attr('width', width)
430
        .attr('height', height);
431
    var g = svg.append('g')
432
        .attr('transform', 'translate(40, 0)');
433
434
    jsondash.getJSON(container, config.dataSource, function(error, root) {
435
        var nodes = cluster.nodes(root);
436
        var links = cluster.links(nodes);
437
        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...
438
        .data(links)
439
        .enter().append('path')
440
        .attr('class', 'link')
441
        .attr('d', diagonal);
442
443
        var node = g.selectAll('.node')
444
        .data(nodes)
445
        .enter().append('g')
446
        .attr('class', 'node')
447
        .attr('transform', function(d) { return 'translate(' + d.y + ',' + d.x + ')'; });
448
449
        node.append('circle').attr('r', 4.5);
450
        node.append('text')
451
        .attr('dx', function(d) { return d.children ? -8 : 8; })
452
        .attr('dy', 3)
453
        .style('text-anchor', function(d) { return d.children ? 'end' : 'start'; })
454
        .text(function(d) { return d.name; });
455
456
        // Look for callbacks potentially registered for third party code.
457
        jsondash.api.runCallbacks(container, config);
458
        jsondash.unload(container);
459
    });
460
};
461
462
jsondash.handlers.handleVoronoi = function(container, config) {
463
    'use strict';
464
    jsondash.getJSON(container, config.dataSource, function(error, data){
465
        var _width   = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width;
466
        var width    = _width - jsondash.config.WIDGET_MARGIN_X;
467
        var height   = config.height - jsondash.config.WIDGET_MARGIN_Y;
468
        var vertices = data;
469
        var voronoi  = d3.geom.voronoi().clipExtent([[0, 0], [width, height]]);
470
        // Cleanup
471
        container.selectAll('svg').remove();
472
        var svg = container
473
            .append('svg')
474
            .attr('width', width)
475
            .attr('height', height);
476
        var path = svg.append('g').selectAll('path');
477
        svg.selectAll('circle')
478
            .data(vertices.slice(1))
479
            .enter().append('circle')
480
            .attr('transform', function(d) { return 'translate(' + d + ')'; })
481
            .attr('r', 1.5);
482
            redraw();
483
484
        function redraw() {
485
            path = path.data(voronoi(vertices), jsondash.util.polygon);
486
            path.exit().remove();
487
            path.enter().append('path')
488
            .attr('class', function(d, i) { return 'q' + (i % 9) + '-9'; })
489
            .attr('d', jsondash.util.polygon);
490
            path.order();
491
        }
492
        // Look for callbacks potentially registered for third party code.
493
        jsondash.api.runCallbacks(container, config);
494
        jsondash.unload(container);
495
    });
496
};
497
498
jsondash.handlers.handleSparkline = function(container, config) {
499
    'use strict';
500
    // Clean up old canvas elements
501
    container.selectAll('.sparkline-container').remove();
502
    var sparkline_type = config.type.split('-')[1];
503
    var spark = container
504
        .append('div')
505
        .classed({
506
            'sparkline-container': true,
507
            'text-center': true
508
        });
509
    spark = $(spark[0]);
510
    jsondash.getJSON(container, config.dataSource, function(data){
511
        var opts = {
512
            type: sparkline_type,
513
            width: config.width - jsondash.config.WIDGET_MARGIN_X,
514
            height: config.height - jsondash.config.WIDGET_MARGIN_Y
515
        };
516
        spark.sparkline(data, opts);
517
        // Look for callbacks potentially registered for third party code.
518
        jsondash.api.runCallbacks(container, config);
519
        jsondash.unload(container);
520
    });
521
};
522
523
jsondash.handlers.handleDataTable = function(container, config) {
524
    'use strict';
525
    // Clean up old tables if they exist, during reloading.
526
    container.selectAll('.dataTables_wrapper').remove();
527
    jsondash.getJSON(container, config.dataSource, function(error, res) {
528
        var keys = d3.keys(res[0]).map(function(d){
529
            return {data: d, title: d};
530
        });
531
        container
532
            .append('table')
533
            .classed({
534
                table: true,
535
                'table-striped': true,
536
                'table-bordered': true,
537
                'table-condensed': true
538
            });
539
        var opts = config.override ? res : {data: res, columns: keys};
540
        $(container.select('table')[0]).dataTable(opts).css({width: 'auto'});
541
        // Look for callbacks potentially registered for third party code.
542
        jsondash.api.runCallbacks(container, config);
543
        jsondash.unload(container);
544
    });
545
};
546
547
jsondash.handlers.handleSingleNum = function(container, config) {
548
    'use strict';
549
    container.selectAll('.singlenum').remove();
550
    jsondash.getJSON(container, config.dataSource, function(error, res){
551
        var data = res.data.data ? res.data.data : res.data;
552
        var num = container.select('.chart-container').append('div')
553
            .classed({singlenum: true})
554
            .text(data);
555
        data = String(data);
556
        // Add red or green, depending on if the number appears to be pos/neg.
557
        if(!res.noformat) {
558
            num.classed({
559
                'text-danger': data.startsWith('-'),
560
                'text-success': !data.startsWith('-')
561
            });
562
        }
563
        // Allow custom colors.
564
        if(res.color && res.noformat) {
565
            num.style('color', res.color);
566
        }
567
        // Get title height to offset box.
568
        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...
569
            .select('.widget-title')
570
            .node()
571
            .getBoundingClientRect()
572
            .height;
573
        var h = config.height - jsondash.config.WIDGET_MARGIN_Y;
574
        num.style({
575
            'line-height': h + 'px',
576
            height: h + 'px',
577
            width: config.width - jsondash.config.WIDGET_MARGIN_X
578
        });
579
        var digits = String(data).length;
580
        var size = jsondash.util.getDigitSize()(digits);
581
        num.style('font-size', size + 'px');
582
        // Look for callbacks potentially registered for third party code.
583
        jsondash.api.runCallbacks(container, config);
584
        jsondash.unload(container);
585
    });
586
};
587
588
jsondash.handlers.handleTimeline = function(container, config) {
589
    'use strict';
590
    jsondash.getJSON(container, config.dataSource, function(data){
591
        container.append('div').attr('id', 'widget-' + config.guid);
592
        var timeline = new TL.Timeline('widget-' + config.guid, data);
0 ignored issues
show
Unused Code introduced by
The variable timeline seems to be never used. Consider removing it.
Loading history...
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...
593
        // Look for callbacks potentially registered for third party code.
594
        jsondash.api.runCallbacks(container, config);
595
        jsondash.unload(container);
596
    });
597
};
598
599
jsondash.handlers.handleIframe = function(container, config) {
600
    'use strict';
601
    container.selectAll('iframe').remove();
602
    var iframe = container.append('iframe');
603
    iframe.attr({
604
        border: 0,
605
        src: config.dataSource,
606
        height: config.height - jsondash.config.WIDGET_MARGIN_Y,
607
        width: isNaN(config.width) ? '100%' : config.width - jsondash.config.WIDGET_MARGIN_X
608
    });
609
    // Look for callbacks potentially registered for third party code.
610
    jsondash.api.runCallbacks(container, config);
611
    jsondash.unload(container);
612
};
613
614
jsondash.handlers.handleCustom = function(container, config) {
615
    'use strict';
616
    container.selectAll('.custom-container').remove();
617
    $.get(config.dataSource, function(html){
618
        container.append('div').classed({'custom-container': true}).html(html);
619
        // Look for callbacks potentially registered for third party code.
620
        jsondash.api.runCallbacks(container, config);
621
        jsondash.unload(container);
622
    });
623
};
624
625
jsondash.handlers.handleVenn = function(container, config) {
626
    'use strict';
627
    container.selectAll('.venn').remove();
628
    jsondash.getJSON(container, config.dataSource, function(error, data){
629
        var chart = venn.VennDiagram();
630
        var cont = container
631
            .append('div')
632
            .classed({venn: true});
633
        cont.datum(data).call(chart);
634
        cont.select('svg')
635
            .attr('width', config.width - jsondash.config.WIDGET_MARGIN_X)
636
            .attr('height', config.height - jsondash.config.WIDGET_MARGIN_Y);
637
        // Look for callbacks potentially registered for third party code.
638
        jsondash.api.runCallbacks(container, config);
639
        jsondash.unload(container);
640
    });
641
};
642
643
jsondash.handlers.handlePlotly = function(container, config) {
644
    'use strict';
645
    var id = 'plotly-' + config.guid;
646
    var _width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width;
647
    container.selectAll('.plotly-container').remove();
648
    container.append('div')
649
        .classed({'plotly-container': true})
650
        .attr('id', id);
651
    jsondash.getJSON(container, config.dataSource, function(error, data){
652
        var plotly_wrapper =  d3.select('#' + id);
653
        delete data.layout.height;
654
        delete data.layout.width;
655
        data.layout.margin = {l: 20, r: 20, b: 20, t: 50};
656
        if(config.override) {
657
            Plotly.plot(id, data.data, data.layout || {}, data.options || {});
658
        } else {
659
            Plotly.plot(id, data);
660
        }
661
       plotly_wrapper.select('.svg-container').style({
662
            'margin': '0 auto',
663
            'width': isNaN(config.width) ? '100%' : config.width,
664
            'height': config.height
665
        });
666
        plotly_wrapper.select('#scene').style({
667
            'width': _width,
668
            'height': config.height
669
        });
670
        // Look for callbacks potentially registered for third party code.
671
        jsondash.api.runCallbacks(container, config);
672
        jsondash.unload(container);
673
    });
674
};
675