Completed
Push — master ( 77a482...bbe50c )
by Chris
01:42
created

jsondash.handlers.handleVegaLite   B

Complexity

Conditions 2
Paths 1

Size

Total Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 2
dl 0
loc 30
rs 8.8571
c 2
b 0
f 0
nc 1
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
    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
    'use strict';
199
    var init_config = {
200
        bindto: '[data-guid="' + config.guid + '"] .chart-container',
201
        legend: {
202
            show: true
203
        },
204
        size: {
205
            height: config.height - jsondash.config.WIDGET_MARGIN_Y,
206
            width: config.width - jsondash.config.WIDGET_MARGIN_X
207
        },
208
        data: {
209
            type: config.type,
210
            url: config.dataSource,
211
            mimeType: 'json'
212
        },
213
        onrendered: function(){
214
            // Look for callbacks potentially registered for third party code.
215
            jsondash.api.runCallbacks(container, config);
216
            jsondash.unload(container);
217
        }
218
    };
219
    if(jsondash.util.isOverride(config)) {
220
        // Just use the raw payload for this widgets' options.
221
        jsondash.getJSON(container, config.dataSource, function(error, data){
222
            // Keep existing options if not specified.
223
            config = $.extend(init_config, data);
224
            c3.generate(init_config);
225
        });
226
        return;
227
    }
228
    if(config.type === 'timeseries') {
229
        init_config.axis = {
230
            x: {type: 'timeseries'}
231
        };
232
        // Map the corresponding data key and list of dates
233
        // to the `x` property.
234
        init_config.data.x = 'dates';
235
    }
236
    c3.generate(init_config);
237
};
238
239
jsondash.handlers.handleD3 = function(container, config) {
240
    'use strict';
241
    // Clean up all D3 charts in one step.
242
    container.selectAll('svg').remove();
243
    // Handle specific types.
244
    if(config.type === 'radial-dendrogram') { return jsondash.handlers.handleRadialDendrogram(container, config); }
245
    if(config.type === 'dendrogram') { return jsondash.handlers.handleDendrogram(container, config); }
246
    if(config.type === 'voronoi') { return jsondash.handlers.handleVoronoi(container, config); }
247
    if(config.type === 'treemap') { return jsondash.handlers.handleTreemap(container, config); }
248
    if(config.type === 'circlepack') { return jsondash.handlers.handleCirclePack(container, config); }
249
    throw new Error('Unknown type: ' + config.type);
250
};
251
252
jsondash.handlers.handleCirclePack = function(container, config) {
253
    'use strict';
254
    // Adapted from https://bl.ocks.org/mbostock/4063530
255
    var margin = jsondash.config.WIDGET_MARGIN_Y;
256
    var diameter = jsondash.getDiameter(container, config) - margin;
257
    var format = d3.format(',d');
258
    var pack = d3.layout.pack()
259
        .size([diameter, diameter])
260
        .value(function(d) { return d.size; });
261
262
    var svg = container
263
        .append('svg')
264
        .attr('width', diameter)
265
        .attr('height', diameter)
266
        .append('g');
267
268
    jsondash.getJSON(container, config.dataSource, function(error, data) {
269
        var node = svg.datum(data).selectAll('.node')
270
        .data(pack.nodes)
271
        .enter().append('g')
272
        .attr('class', function(d) { return d.children ? 'node' : 'leaf node'; })
273
        .attr('transform', function(d) { return 'translate(' + d.x + ',' + d.y + ')'; });
274
275
        node.append('title')
276
        .text(function(d) { return d.name + (d.children ? '' : ': ' + format(d.size)); });
277
278
        node.append('circle')
279
        .attr('r', function(d) { return d.r; });
280
281
        node.filter(function(d) { return !d.children; }).append('text')
282
        .attr('dy', '.3em')
283
        .style('text-anchor', 'middle')
284
        .text(function(d) { return d.name.substring(0, d.r / 3); });
285
        // Look for callbacks potentially registered for third party code.
286
        jsondash.api.runCallbacks(container, config);
287
        jsondash.unload(container);
288
    });
289
    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...
290
};
291
292
jsondash.handlers.handleTreemap = function(container, config) {
293
    'use strict';
294
    // Adapted from http://bl.ocks.org/mbostock/4063582
295
    var margin = {
0 ignored issues
show
Unused Code introduced by
The variable margin seems to be never used. Consider removing it.
Loading history...
296
        top: jsondash.config.WIDGET_MARGIN_Y / 2,
297
        bottom: jsondash.config.WIDGET_MARGIN_Y / 2,
298
        left: jsondash.config.WIDGET_MARGIN_X / 2,
299
        right: jsondash.config.WIDGET_MARGIN_X / 2
300
    };
301
    var _width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width;
302
    var width = _width - jsondash.config.WIDGET_MARGIN_X;
303
    var height = config.height - jsondash.config.WIDGET_MARGIN_Y;
304
    var color = d3.scale.category20c();
305
    var treemap = d3.layout.treemap()
306
        .size([width, height])
307
        .sticky(true)
308
        .value(function(d) { return d.size; });
309
    // Cleanup
310
    container.selectAll('.treemap').remove();
311
    var div = container
312
        .append('div')
313
        .classed({treemap: true, 'chart-centered': true})
314
        .style('position', 'relative')
315
        .style('width', width + 'px')
316
        .style('height', height + 'px');
317
318
    jsondash.getJSON(container, config.dataSource, function(error, root) {
319
        var node = div.datum(root).selectAll('.node')
320
            .data(treemap.nodes)
321
            .enter().append('div')
322
            .attr('class', 'node')
323
            .call(position)
324
            .style('border', '1px solid white')
325
            .style('font', '10px sans-serif')
326
            .style('line-height', '12px')
327
            .style('overflow', 'hidden')
328
            .style('position', 'absolute')
329
            .style('text-indent', '2px')
330
            .style('background', function(d) {
331
                return d.children ? color(d.name) : null;
332
            })
333
            .text(function(d) {
334
                return d.children ? null : d.name;
335
            });
336
        d3.selectAll('input').on('change', function change() {
337
            var value = this.value === 'count'
338
            ? function() { return 1; }
339
            : function(d) { return d.size;};
340
            node
341
            .data(treemap.value(value).nodes)
342
            .transition()
343
            .duration(1500)
344
            .call(position);
345
        });
346
        // Look for callbacks potentially registered for third party code.
347
        jsondash.api.runCallbacks(container, config);
348
        jsondash.unload(container);
349
    });
350
351
    function position() {
352
        this.style('left', function(d) { return d.x + 'px'; })
353
            .style('top', function(d) { return d.y + 'px'; })
354
            .style('width', function(d) { return Math.max(0, d.dx - 1) + 'px'; })
355
            .style('height', function(d) { return Math.max(0, d.dy - 1) + 'px'; });
356
    }
357
};
358
359
jsondash.handlers.handleRadialDendrogram = function(container, config) {
360
    'use strict';
361
    // Code taken (and refactored for use here) from:
362
    // https://bl.ocks.org/mbostock/4339607
363
    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...
364
    var radius = jsondash.getDiameter(container, config);
365
    var cluster = d3.layout.cluster()
366
        .size([360, radius / 2 - 150]); // reduce size relative to `radius`
367
    var diagonal = d3.svg.diagonal.radial()
368
        .projection(function(d) { return [d.y, d.x / 180 * Math.PI]; });
369
    var svg = container.append('svg')
370
        .attr('width', radius)
371
        .attr('height', radius);
372
    var g = svg.append('g');
373
    g.attr('transform', 'translate(' + radius / 2 + ',' + radius / 2 + ')');
374
375
    jsondash.getJSON(container, config.dataSource, function(error, root) {
376
        if (error) { throw error; }
377
        var nodes = cluster.nodes(root);
378
        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...
379
            .data(cluster.links(nodes))
380
            .enter().append('path')
381
            .attr('class', 'link')
382
            .attr('d', diagonal);
383
        var node = g.selectAll('g.node')
384
            .data(nodes)
385
            .enter().append('g')
386
            .attr('class', 'node')
387
            .attr('transform', function(d) { return 'rotate(' + (d.x - 90) + ')translate(' + d.y + ')'; });
388
        node.append('circle')
389
            .attr('r', 4.5);
390
        node.append('text')
391
            .attr('dy', '.31em')
392
            .attr('text-anchor', function(d) { return d.x < 180 ? 'start' : 'end'; })
393
            .attr('transform', function(d) { return d.x < 180 ? 'translate(8)' : 'rotate(180)translate(-8)'; })
394
            .text(function(d) { return d.name; });
395
        // Look for callbacks potentially registered for third party code.
396
        jsondash.api.runCallbacks(container, config);
397
        jsondash.unload(container);
398
    });
399
    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...
400
};
401
402
jsondash.handlers.handleDendrogram = function(container, config) {
403
    'use strict';
404
    var _width = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width;
405
    // A general padding for the svg inside of the widget.
406
    // The cluster dendrogram will also need to have padding itself, so
407
    // the bounds are not clipped in the svg.
408
    var svg_pad = 20;
409
    var width = _width - svg_pad;
410
    var height = config.height - svg_pad;
411
    var PADDING = width / 4;
412
    var cluster = d3.layout.cluster()
413
        .size([height * 0.85, width - PADDING]);
414
    var diagonal = d3.svg.diagonal()
415
        .projection(function(d) { return [d.y, d.x]; });
416
    var svg = container
417
        .append('svg')
418
        .attr('width', width)
419
        .attr('height', height);
420
    var g = svg.append('g')
421
        .attr('transform', 'translate(40, 0)');
422
423
    jsondash.getJSON(container, config.dataSource, function(error, root) {
424
        var nodes = cluster.nodes(root);
425
        var links = cluster.links(nodes);
426
        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...
427
        .data(links)
428
        .enter().append('path')
429
        .attr('class', 'link')
430
        .attr('d', diagonal);
431
432
        var node = g.selectAll('.node')
433
        .data(nodes)
434
        .enter().append('g')
435
        .attr('class', 'node')
436
        .attr('transform', function(d) { return 'translate(' + d.y + ',' + d.x + ')'; });
437
438
        node.append('circle').attr('r', 4.5);
439
        node.append('text')
440
        .attr('dx', function(d) { return d.children ? -8 : 8; })
441
        .attr('dy', 3)
442
        .style('text-anchor', function(d) { return d.children ? 'end' : 'start'; })
443
        .text(function(d) { return d.name; });
444
445
        // Look for callbacks potentially registered for third party code.
446
        jsondash.api.runCallbacks(container, config);
447
        jsondash.unload(container);
448
    });
449
};
450
451
jsondash.handlers.handleVoronoi = function(container, config) {
452
    'use strict';
453
    jsondash.getJSON(container, config.dataSource, function(error, data){
454
        var _width   = isNaN(config.width) ? jsondash.getDynamicWidth(container, config) : config.width;
455
        var width    = _width - jsondash.config.WIDGET_MARGIN_X;
456
        var height   = config.height - jsondash.config.WIDGET_MARGIN_Y;
457
        var vertices = data;
458
        var voronoi  = d3.geom.voronoi().clipExtent([[0, 0], [width, height]]);
459
        // Cleanup
460
        container.selectAll('svg').remove();
461
        var svg = container
462
            .append('svg')
463
            .attr('width', width)
464
            .attr('height', height);
465
        var path = svg.append('g').selectAll('path');
466
        svg.selectAll('circle')
467
            .data(vertices.slice(1))
468
            .enter().append('circle')
469
            .attr('transform', function(d) { return 'translate(' + d + ')'; })
470
            .attr('r', 1.5);
471
            redraw();
472
473
        function redraw() {
474
            path = path.data(voronoi(vertices), jsondash.util.polygon);
475
            path.exit().remove();
476
            path.enter().append('path')
477
            .attr('class', function(d, i) { return 'q' + (i % 9) + '-9'; })
478
            .attr('d', jsondash.util.polygon);
479
            path.order();
480
        }
481
        // Look for callbacks potentially registered for third party code.
482
        jsondash.api.runCallbacks(container, config);
483
        jsondash.unload(container);
484
    });
485
};
486
487
jsondash.handlers.handleSparkline = function(container, config) {
488
    'use strict';
489
    // Clean up old canvas elements
490
    container.selectAll('.sparkline-container').remove();
491
    var sparkline_type = config.type.split('-')[1];
492
    var spark = container
493
        .append('div')
494
        .classed({
495
            'sparkline-container': true,
496
            'text-center': true
497
        });
498
    spark = $(spark[0]);
499
    jsondash.getJSON(container, config.dataSource, function(data){
500
        var opts = {
501
            type: sparkline_type,
502
            width: config.width - jsondash.config.WIDGET_MARGIN_X,
503
            height: config.height - jsondash.config.WIDGET_MARGIN_Y
504
        };
505
        spark.sparkline(data, opts);
506
        // Look for callbacks potentially registered for third party code.
507
        jsondash.api.runCallbacks(container, config);
508
        jsondash.unload(container);
509
    });
510
};
511
512
jsondash.handlers.handleDataTable = function(container, config) {
513
    'use strict';
514
    // Clean up old tables if they exist, during reloading.
515
    container.selectAll('.dataTables_wrapper').remove();
516
    jsondash.getJSON(container, config.dataSource, function(error, res) {
517
        var keys = d3.keys(res[0]).map(function(d){
518
            return {data: d, title: d};
519
        });
520
        container
521
            .append('table')
522
            .classed({
523
                table: true,
524
                'table-striped': true,
525
                'table-bordered': true,
526
                'table-condensed': true
527
            });
528
        var opts = config.override ? res : {data: res, columns: keys};
529
        $(container.select('table')[0]).dataTable(opts).css({width: 'auto'});
530
        // Look for callbacks potentially registered for third party code.
531
        jsondash.api.runCallbacks(container, config);
532
        jsondash.unload(container);
533
    });
534
};
535
536
jsondash.handlers.handleSingleNum = function(container, config) {
537
    'use strict';
538
    container.selectAll('.singlenum').remove();
539
    jsondash.getJSON(container, config.dataSource, function(error, res){
540
        var data = res.data.data ? res.data.data : res.data;
541
        var num = container.select('.chart-container').append('div')
542
            .classed({singlenum: true})
543
            .text(data);
544
        data = String(data);
545
        // Add red or green, depending on if the number appears to be pos/neg.
546
        if(!res.noformat) {
547
            num.classed({
548
                'text-danger': data.startsWith('-'),
549
                'text-success': !data.startsWith('-')
550
            });
551
        }
552
        // Allow custom colors.
553
        if(res.color && res.noformat) {
554
            num.style('color', res.color);
555
        }
556
        // Get title height to offset box.
557
        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...
558
            .select('.widget-title')
559
            .node()
560
            .getBoundingClientRect()
561
            .height;
562
        var h = config.height - jsondash.config.WIDGET_MARGIN_Y;
563
        num.style({
564
            'line-height': h + 'px',
565
            height: h + 'px',
566
            width: config.width - jsondash.config.WIDGET_MARGIN_X
567
        });
568
        var digits = String(data).length;
569
        var size = jsondash.util.getDigitSize()(digits);
570
        num.style('font-size', size + 'px');
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.handleTimeline = function(container, config) {
578
    'use strict';
579
    jsondash.getJSON(container, config.dataSource, function(data){
580
        container.append('div').attr('id', 'widget-' + config.guid);
581
        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...
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.handleIframe = function(container, config) {
589
    'use strict';
590
    container.selectAll('iframe').remove();
591
    var iframe = container.append('iframe');
592
    iframe.attr({
593
        border: 0,
594
        src: config.dataSource,
595
        height: config.height - jsondash.config.WIDGET_MARGIN_Y,
596
        width: config.width - jsondash.config.WIDGET_MARGIN_X
597
    });
598
    // Look for callbacks potentially registered for third party code.
599
    jsondash.api.runCallbacks(container, config);
600
    jsondash.unload(container);
601
};
602
603
jsondash.handlers.handleCustom = function(container, config) {
604
    'use strict';
605
    container.selectAll('.custom-container').remove();
606
    $.get(config.dataSource, function(html){
607
        container.append('div').classed({'custom-container': true}).html(html);
608
        // Look for callbacks potentially registered for third party code.
609
        jsondash.api.runCallbacks(container, config);
610
        jsondash.unload(container);
611
    });
612
};
613
614
jsondash.handlers.handleVenn = function(container, config) {
615
    'use strict';
616
    container.selectAll('.venn').remove();
617
    jsondash.getJSON(container, config.dataSource, function(error, data){
618
        var chart = venn.VennDiagram();
619
        var cont = container
620
            .append('div')
621
            .classed({venn: true});
622
        cont.datum(data).call(chart);
623
        cont.select('svg')
624
            .attr('width', config.width - jsondash.config.WIDGET_MARGIN_X)
625
            .attr('height', config.height - jsondash.config.WIDGET_MARGIN_Y);
626
        // Look for callbacks potentially registered for third party code.
627
        jsondash.api.runCallbacks(container, config);
628
        jsondash.unload(container);
629
    });
630
};
631
632
jsondash.handlers.handlePlotly = function(container, config) {
633
    'use strict';
634
    var id = 'plotly-' + config.guid;
635
    container.selectAll('.plotly-container').remove();
636
    container.append('div')
637
        .classed({'plotly-container': true})
638
        .attr('id', id);
639
    jsondash.getJSON(container, config.dataSource, function(error, data){
640
        var plotly_wrapper =  d3.select('#' + id);
641
        delete data.layout.height;
642
        delete data.layout.width;
643
        data.layout.margin = {l: 20, r: 20, b: 20, t: 50};
644
        if(config.override) {
645
            Plotly.plot(id, data.data, data.layout || {}, data.options || {});
646
        } else {
647
            Plotly.plot(id, data);
648
        }
649
       plotly_wrapper.select('.svg-container').style({
650
            'margin': '0 auto',
651
            'width': isNaN(config.width) ? '100%' : config.width,
652
            'height': config.height
653
        });
654
        plotly_wrapper.select('#scene').style({
655
            'width': isNaN(config.width) ? '100%' : config.width,
656
            'height': config.height
657
        });
658
        // Look for callbacks potentially registered for third party code.
659
        jsondash.api.runCallbacks(container, config);
660
        jsondash.unload(container);
661
    });
662
};
663