Completed
Push — master ( 066dd2...eed2c7 )
by Chris
01:25
created

jsondash.handlers.handlePlotly   A

Complexity

Conditions 3
Paths 10

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

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