From 67d8a95524b02c4c25d8b958e73b760c77c4f834 Mon Sep 17 00:00:00 2001 From: samussiah Date: Thu, 9 May 2019 17:28:54 -0400 Subject: [PATCH 01/12] tweaking histogram code --- build/webcharts.js | 3208 ++++++----------- .../consolidateData/transformData/makeNest.js | 6 +- test-page/histogram/index.html | 22 + test-page/histogram/index.js | 69 + 4 files changed, 1101 insertions(+), 2204 deletions(-) create mode 100644 test-page/histogram/index.html create mode 100644 test-page/histogram/index.js diff --git a/build/webcharts.js b/build/webcharts.js index 24ad10e..f72f128 100644 --- a/build/webcharts.js +++ b/build/webcharts.js @@ -1,11 +1,9 @@ -(function(global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' - ? (module.exports = factory(require('d3'))) - : typeof define === 'function' && define.amd - ? define(['d3'], factory) - : (global.webCharts = factory(global.d3)); -})(typeof self !== 'undefined' ? self : this, function(d3) { - 'use strict'; +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('d3')) : + typeof define === 'function' && define.amd ? define(['d3'], factory) : + global.webCharts = factory(global.d3); +}(typeof self !== 'undefined' ? self : this, function (d3) { 'use strict'; + var version = '1.11.5'; function init(data) { @@ -14,17 +12,9 @@ var test = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; if (d3.select(this.div).select('.loader').empty()) { - d3 - .select(this.div) - .insert('div', ':first-child') - .attr('class', 'loader') - .selectAll('.blockG') - .data(d3.range(8)) - .enter() - .append('div') - .attr('class', function(d) { - return 'blockG rotate' + (d + 1); - }); + d3.select(this.div).insert('div', ':first-child').attr('class', 'loader').selectAll('.blockG').data(d3.range(8)).enter().append('div').attr('class', function (d) { + return 'blockG rotate' + (d + 1); + }); } this.wrap.attr('class', 'wc-chart'); @@ -48,10 +38,8 @@ //make sure container is visible (has height and width) before trying to initialize var visible = d3.select(_this.div).property('offsetWidth') > 0 || test; if (!visible) { - console.warn( - 'The chart cannot be initialized inside an element with 0 width. The chart will be initialized as soon as the container element is given a width > 0.' - ); - var onVisible = setInterval(function(i) { + console.warn('The chart cannot be initialized inside an element with 0 width. The chart will be initialized as soon as the container element is given a width > 0.'); + var onVisible = setInterval(function (i) { var visible_now = d3.select(_this.div).property('offsetWidth') > 0; if (visible_now) { _this.layout(); @@ -92,48 +80,32 @@ requiredVars.push('this.config.color_by'); requiredCols.push(this.config.color_by); } - if (this.config.marks) - this.config.marks.forEach(function(e, i) { - if (e.per && e.per.length) { - e.per.forEach(function(p, j) { - requiredVars.push('this.config.marks[' + i + '].per[' + j + ']'); - requiredCols.push(p); - }); - } - if (e.split) { - requiredVars.push('this.config.marks[' + i + '].split'); - requiredCols.push(e.split); - } - if (e.values) { - for (var value in e.values) { - requiredVars.push('this.config.marks[' + i + "].values['" + value + "']"); - requiredCols.push(value); - } + if (this.config.marks) this.config.marks.forEach(function (e, i) { + if (e.per && e.per.length) { + e.per.forEach(function (p, j) { + requiredVars.push('this.config.marks[' + i + '].per[' + j + ']'); + requiredCols.push(p); + }); + } + if (e.split) { + requiredVars.push('this.config.marks[' + i + '].split'); + requiredCols.push(e.split); + } + if (e.values) { + for (var value in e.values) { + requiredVars.push('this.config.marks[' + i + "].values['" + value + "']"); + requiredCols.push(value); } - }); + } + }); var missingDataField = false; - requiredCols.forEach(function(e, i) { + requiredCols.forEach(function (e, i) { if (colnames.indexOf(e) < 0) { missingDataField = true; d3.select(_this.div).select('.loader').remove(); - _this.wrap - .append('div') - .style('color', 'red') - .html( - 'The value "' + - e + - '" for the ' + - requiredVars[i] + - ' setting does not match any column in the provided dataset.' - ); - throw new Error( - 'Error in settings object: The value "' + - e + - '" for the ' + - requiredVars[i] + - ' setting does not match any column in the provided dataset.' - ); + _this.wrap.append('div').style('color', 'red').html('The value "' + e + '" for the ' + requiredVars[i] + ' setting does not match any column in the provided dataset.'); + throw new Error('Error in settings object: The value "' + e + '" for the ' + requiredVars[i] + ' setting does not match any column in the provided dataset.'); } }); @@ -145,94 +117,61 @@ } function addSVG() { - this.svg = this.wrap - .append('svg') - .datum(function() { - return null; - }) // prevent data inheritance - .attr({ - class: 'wc-svg', - xmlns: 'http://www.w3.org/2000/svg', - version: '1.1', - xlink: 'http://www.w3.org/1999/xlink' - }) - .append('g') - .style('display', 'inline-block'); + this.svg = this.wrap.append('svg').datum(function () { + return null; + }) // prevent data inheritance + .attr({ + class: 'wc-svg', + xmlns: 'http://www.w3.org/2000/svg', + version: '1.1', + xlink: 'http://www.w3.org/1999/xlink' + }).append('g').style('display', 'inline-block'); } function addDefs() { var defs = this.svg.append('defs'); //Add pattern. - defs - .append('pattern') - .attr({ - id: 'diagonal-stripes', - x: 0, - y: 0, - width: 3, - height: 8, - patternUnits: 'userSpaceOnUse', - patternTransform: 'rotate(30)' - }) - .append('rect') - .attr({ - x: '0', - y: '0', - width: '2', - height: '8' - }) - .style({ - stroke: 'none', - fill: 'black' - }); + defs.append('pattern').attr({ + id: 'diagonal-stripes', + x: 0, + y: 0, + width: 3, + height: 8, + patternUnits: 'userSpaceOnUse', + patternTransform: 'rotate(30)' + }).append('rect').attr({ + x: '0', + y: '0', + width: '2', + height: '8' + }).style({ + stroke: 'none', + fill: 'black' + }); //Add clipPath. defs.append('clipPath').attr('id', this.id).append('rect').attr('class', 'plotting-area'); } function addXAxis() { - this.svg - .append('g') - .attr('class', 'x axis') - .append('text') - .attr('class', 'axis-title') - .attr('dy', '-.35em') - .attr('text-anchor', 'middle'); + this.svg.append('g').attr('class', 'x axis').append('text').attr('class', 'axis-title').attr('dy', '-.35em').attr('text-anchor', 'middle'); } function addYAxis() { - this.svg - .append('g') - .attr('class', 'y axis') - .append('text') - .attr('class', 'axis-title') - .attr('transform', 'rotate(-90)') - .attr('dy', '.75em') - .attr('text-anchor', 'middle'); + this.svg.append('g').attr('class', 'y axis').append('text').attr('class', 'axis-title').attr('transform', 'rotate(-90)').attr('dy', '.75em').attr('text-anchor', 'middle'); } function addOverlay() { - this.overlay = this.svg - .append('rect') - .attr('class', 'overlay') - .attr('opacity', 0) - .attr('fill', 'none') - .style('pointer-events', 'all'); + this.overlay = this.svg.append('rect').attr('class', 'overlay').attr('opacity', 0).attr('fill', 'none').style('pointer-events', 'all'); } function addLegend() { //The legend is contained in the parent object of multiples so each multiple does not need its own legend. - if (!this.parent) - this.wrap - .append('ul') - .datum(function() { - return null; - }) // prevent data inheritance - .attr('class', 'legend') - .style('vertical-align', 'top') - .append('span') - .attr('class', 'legend-title'); + if (!this.parent) this.wrap.append('ul').datum(function () { + return null; + }) // prevent data inheritance + .attr('class', 'legend').style('vertical-align', 'top').append('span').attr('class', 'legend-title'); } function clearLoader() { @@ -268,9 +207,7 @@ // warn the user about the perils of "processed_data" if (processed_data) { - console.warn( - "Drawing the chart using user-defined 'processed_data', this is an experimental, untested feature." - ); + console.warn("Drawing the chart using user-defined 'processed_data', this is an experimental, untested feature."); } //Call consolidateData - this applies filters from controls and prepares data for each set of marks. @@ -285,38 +222,24 @@ this.setColorScale(); var max_width = config.max_width ? config.max_width : div_width; - this.raw_width = config.x.type === 'ordinal' && +config.x.range_band - ? (+config.x.range_band + config.x.range_band * config.padding) * this.x_dom.length - : config.resizable ? max_width : config.width ? config.width : div_width; - this.raw_height = config.y.type === 'ordinal' && +config.y.range_band - ? (+config.y.range_band + config.y.range_band * config.padding) * this.y_dom.length - : config.resizable - ? max_width * (1 / config.aspect) - : config.height ? config.height : div_width * (1 / config.aspect); - - var pseudo_width = this.svg.select('.overlay').attr('width') - ? this.svg.select('.overlay').attr('width') - : this.raw_width; - var pseudo_height = this.svg.select('.overlay').attr('height') - ? this.svg.select('.overlay').attr('height') - : this.raw_height; - - this.svg.select('.x.axis').select('.axis-title').text(function(d) { - return typeof config.x.label === 'string' - ? config.x.label - : typeof config.x.label === 'function' ? config.x.label.call(_this) : null; + this.raw_width = config.x.type === 'ordinal' && +config.x.range_band ? (+config.x.range_band + config.x.range_band * config.padding) * this.x_dom.length : config.resizable ? max_width : config.width ? config.width : div_width; + this.raw_height = config.y.type === 'ordinal' && +config.y.range_band ? (+config.y.range_band + config.y.range_band * config.padding) * this.y_dom.length : config.resizable ? max_width * (1 / config.aspect) : config.height ? config.height : div_width * (1 / config.aspect); + + var pseudo_width = this.svg.select('.overlay').attr('width') ? this.svg.select('.overlay').attr('width') : this.raw_width; + var pseudo_height = this.svg.select('.overlay').attr('height') ? this.svg.select('.overlay').attr('height') : this.raw_height; + + this.svg.select('.x.axis').select('.axis-title').text(function (d) { + return typeof config.x.label === 'string' ? config.x.label : typeof config.x.label === 'function' ? config.x.label.call(_this) : null; }); - this.svg.select('.y.axis').select('.axis-title').text(function(d) { - return typeof config.y.label === 'string' - ? config.y.label - : typeof config.y.label === 'function' ? config.y.label.call(_this) : null; + this.svg.select('.y.axis').select('.axis-title').text(function (d) { + return typeof config.y.label === 'string' ? config.y.label : typeof config.y.label === 'function' ? config.y.label.call(_this) : null; }); this.xScaleAxis(pseudo_width); this.yScaleAxis(pseudo_height); if (config.resizable && typeof window !== 'undefined') { - d3.select(window).on('resize.' + this.element + this.id, function() { + d3.select(window).on('resize.' + this.element + this.id, function () { chart.resize(); }); } else if (typeof window !== 'undefined') { @@ -341,8 +264,8 @@ i = void 0, j = void 0; - while ((i = (j = t.charAt(x++)).charCodeAt(0))) { - var m = i == 46 || (i >= 48 && i <= 57); + while (i = (j = t.charAt(x++)).charCodeAt(0)) { + var m = i == 46 || i >= 48 && i <= 57; if (m !== n) { tz[++y] = ''; n = m; @@ -382,101 +305,49 @@ this[axis + '_dom'] = this.config[axis].domain; } else if (this.config[axis].order) { //data-driven domain with user-defined domain order - this[axis + '_dom'] = d3 - .set( - d3.merge( - this.marks.map(function(mark) { - return mark[axis + '_dom']; - }) - ) - ) - .values() - .sort(function(a, b) { - return d3.ascending( - _this.config[axis].order.indexOf(a), - _this.config[axis].order.indexOf(b) - ); - }); - } else if ( - this.config[axis].sort && - this.config[axis].sort === 'alphabetical-ascending' - ) { + this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { + return mark[axis + '_dom']; + }))).values().sort(function (a, b) { + return d3.ascending(_this.config[axis].order.indexOf(a), _this.config[axis].order.indexOf(b)); + }); + } else if (this.config[axis].sort && this.config[axis].sort === 'alphabetical-ascending') { //data-driven domain with user-defined domain sort algorithm that sorts the axis //alphanumerically, first to last - this[axis + '_dom'] = d3 - .set( - d3.merge( - this.marks.map(function(mark) { - return mark[axis + '_dom']; - }) - ) - ) - .values() - .sort(naturalSorter); - } else if ( - ['time', 'linear'].indexOf(this.config[otherAxis].type) > -1 && - this.config[axis].sort === 'earliest' - ) { + this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { + return mark[axis + '_dom']; + }))).values().sort(naturalSorter); + } else if (['time', 'linear'].indexOf(this.config[otherAxis].type) > -1 && this.config[axis].sort === 'earliest') { //data-driven domain plotted against a time or linear axis that sorts the axis values //by earliest event/datum; generally used with timeline charts - this[axis + '_dom'] = d3 - .nest() - .key(function(d) { - return d[_this.config[axis].column]; - }) - .rollup(function(d) { - return d - .map(function(m) { - return m[_this.config[otherAxis].column]; - }) - .filter(function(f) { - return f instanceof Date; - }); - }) - .entries(this.filtered_data) - .sort(function(a, b) { - return d3.min(b.values) - d3.min(a.values); - }) - .map(function(m) { - return m.key; + this[axis + '_dom'] = d3.nest().key(function (d) { + return d[_this.config[axis].column]; + }).rollup(function (d) { + return d.map(function (m) { + return m[_this.config[otherAxis].column]; + }).filter(function (f) { + return f instanceof Date; }); - } else if ( - !this.config[axis].sort || - this.config[axis].sort === 'alphabetical-descending' - ) { + }).entries(this.filtered_data).sort(function (a, b) { + return d3.min(b.values) - d3.min(a.values); + }).map(function (m) { + return m.key; + }); + } else if (!this.config[axis].sort || this.config[axis].sort === 'alphabetical-descending') { //data-driven domain with default/user-defined domain sort algorithm that sorts the //axis alphanumerically, last to first - this[axis + '_dom'] = d3 - .set( - d3.merge( - this.marks.map(function(mark) { - return mark[axis + '_dom']; - }) - ) - ) - .values() - .sort(naturalSorter) - .reverse(); + this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { + return mark[axis + '_dom']; + }))).values().sort(naturalSorter).reverse(); } else { //data-driven domain with an invalid user-defined sort algorithm that captures a unique //set of values as they appear in the data - this[axis + '_dom'] = d3 - .set( - d3.merge( - this.marks.map(function(mark) { - return mark[axis + '_dom']; - }) - ) - ) - .values(); + this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { + return mark[axis + '_dom']; + }))).values(); } - } else if ( - this.config.marks - .map(function(m) { - return m['summarize' + axis.toUpperCase()] === 'percent'; - }) - .indexOf(true) > -1 - ) { + } else if (this.config.marks.map(function (m) { + return m['summarize' + axis.toUpperCase()] === 'percent'; + }).indexOf(true) > -1) { //rate domains run from 0 to 1 this[axis + '_dom'] = [0, 1]; } else { @@ -484,26 +355,13 @@ //TODO: they should really run from the minimum to the maximum summarized value, e.g. a //TODO: means over time chart should plot over the range of the means, not the range of the //TODO: raw data - this[axis + '_dom'] = d3.extent( - d3.merge( - this.marks.map(function(mark) { - return mark[axis + '_dom']; - }) - ) - ); + this[axis + '_dom'] = d3.extent(d3.merge(this.marks.map(function (mark) { + return mark[axis + '_dom']; + }))); } //Give the domain a range when the range of the variable is 0. - if ( - this.config[axis].type === 'linear' && - this[axis + '_dom'][0] === this[axis + '_dom'][1] - ) - this[axis + '_dom'] = this[axis + '_dom'][0] !== 0 - ? [ - this[axis + '_dom'][0] - this[axis + '_dom'][0] * 0.01, - this[axis + '_dom'][1] + this[axis + '_dom'][1] * 0.01 - ] - : [-1, 1]; + if (this.config[axis].type === 'linear' && this[axis + '_dom'][0] === this[axis + '_dom'][1]) this[axis + '_dom'] = this[axis + '_dom'][0] !== 0 ? [this[axis + '_dom'][0] - this[axis + '_dom'][0] * 0.01, this[axis + '_dom'][1] + this[axis + '_dom'][1] * 0.01] : [-1, 1]; return this[axis + '_dom']; } @@ -516,31 +374,25 @@ //Apply filters from associated controls objects to raw data. this.filtered_data = raw; if (this.filters.length) { - this.filters.forEach(function(filter) { - _this.filtered_data = _this.filtered_data.filter(function(d) { - return filter.all === true && filter.index === 0 - ? d - : filter.val instanceof Array - ? filter.val.indexOf(d[filter.col]) > -1 - : d[filter.col] === filter.val; + this.filters.forEach(function (filter) { + _this.filtered_data = _this.filtered_data.filter(function (d) { + return filter.all === true && filter.index === 0 ? d : filter.val instanceof Array ? filter.val.indexOf(d[filter.col]) > -1 : d[filter.col] === filter.val; }); }); } //Summarize data for each mark. - this.config.marks.forEach(function(mark, i) { + this.config.marks.forEach(function (mark, i) { if (mark.type !== 'bar') { mark.arrange = null; mark.split = null; } - var mark_info = mark.per - ? _this.transformData(raw, mark) - : { - data: [], - x_dom: [], - y_dom: [] - }; + var mark_info = mark.per ? _this.transformData(raw, mark) : { + data: [], + x_dom: [], + y_dom: [] + }; _this.marks[i] = { id: mark.id, @@ -571,12 +423,8 @@ this.config.x = this.config.x || {}; this.config.y = this.config.y || {}; - this.config.x.label = this.config.x.label !== undefined - ? this.config.x.label - : this.config.x.column; - this.config.y.label = this.config.y.label !== undefined - ? this.config.y.label - : this.config.y.column; + this.config.x.label = this.config.x.label !== undefined ? this.config.x.label : this.config.x.column; + this.config.y.label = this.config.y.label !== undefined ? this.config.y.label : this.config.y.column; this.config.x.sort = this.config.x.sort || 'alphabetical-ascending'; this.config.y.sort = this.config.y.sort || 'alphabetical-descending'; @@ -589,16 +437,10 @@ this.config.margin = this.config.margin || {}; this.config.legend = this.config.legend || {}; - this.config.legend.label = this.config.legend.label !== undefined - ? this.config.legend.label - : this.config.color_by; - this.config.legend.location = this.config.legend.location !== undefined - ? this.config.legend.location - : 'bottom'; - this.config.marks = this.config.marks && this.config.marks.length - ? this.config.marks - : [{}]; - this.config.marks.forEach(function(m, i) { + this.config.legend.label = this.config.legend.label !== undefined ? this.config.legend.label : this.config.color_by; + this.config.legend.location = this.config.legend.location !== undefined ? this.config.legend.location : 'bottom'; + this.config.marks = this.config.marks && this.config.marks.length ? this.config.marks : [{}]; + this.config.marks.forEach(function (m, i) { m.id = m.id ? m.id : 'mark' + (i + 1); }); @@ -611,23 +453,10 @@ this.config.aspect = this.config.aspect || 1.33; - this.config.colors = this.config.colors || [ - 'rgb(102,194,165)', - 'rgb(252,141,98)', - 'rgb(141,160,203)', - 'rgb(231,138,195)', - 'rgb(166,216,84)', - 'rgb(255,217,47)', - 'rgb(229,196,148)', - 'rgb(179,179,179)' - ]; - - this.config.scale_text = this.config.scale_text === undefined - ? true - : this.config.scale_text; - this.config.transitions = this.config.transitions === undefined - ? true - : this.config.transitions; + this.config.colors = this.config.colors || ['rgb(102,194,165)', 'rgb(252,141,98)', 'rgb(141,160,203)', 'rgb(231,138,195)', 'rgb(166,216,84)', 'rgb(255,217,47)', 'rgb(229,196,148)', 'rgb(179,179,179)']; + + this.config.scale_text = this.config.scale_text === undefined ? true : this.config.scale_text; + this.config.transitions = this.config.transitions === undefined ? true : this.config.transitions; } function cleanData(mark, raw) { @@ -636,68 +465,50 @@ var dateConvert = d3.time.format(this.config.date_format); var clean = raw; // only use data for the current mark - clean = mark.per && mark.per.length - ? clean.filter(function(f) { - return f[mark.per[0]] !== undefined; - }) - : clean; + clean = mark.per && mark.per.length ? clean.filter(function (f) { + return f[mark.per[0]] !== undefined; + }) : clean; // Make sure data has x and y values if (this.config.x.column) { - clean = clean.filter(function(f) { + clean = clean.filter(function (f) { return [undefined, null].indexOf(f[_this.config.x.column]) < 0; }); } if (this.config.y.column) { - clean = clean.filter(function(f) { + clean = clean.filter(function (f) { return [undefined, null].indexOf(f[_this.config.y.column]) < 0; }); } //check that x and y have the correct formats if (this.config.x.type === 'time') { - clean = clean.filter(function(f) { - return f[_this.config.x.column] instanceof Date - ? f[_this.config.x.column] - : dateConvert.parse(f[_this.config.x.column]); + clean = clean.filter(function (f) { + return f[_this.config.x.column] instanceof Date ? f[_this.config.x.column] : dateConvert.parse(f[_this.config.x.column]); }); - clean.forEach(function(e) { - return (e[_this.config.x.column] = e[_this.config.x.column] instanceof Date - ? e[_this.config.x.column] - : dateConvert.parse(e[_this.config.x.column])); + clean.forEach(function (e) { + return e[_this.config.x.column] = e[_this.config.x.column] instanceof Date ? e[_this.config.x.column] : dateConvert.parse(e[_this.config.x.column]); }); } if (this.config.y.type === 'time') { - clean = clean.filter(function(f) { - return f[_this.config.y.column] instanceof Date - ? f[_this.config.y.column] - : dateConvert.parse(f[_this.config.y.column]); + clean = clean.filter(function (f) { + return f[_this.config.y.column] instanceof Date ? f[_this.config.y.column] : dateConvert.parse(f[_this.config.y.column]); }); - clean.forEach(function(e) { - return (e[_this.config.y.column] = e[_this.config.y.column] instanceof Date - ? e[_this.config.y.column] - : dateConvert.parse(e[_this.config.y.column])); + clean.forEach(function (e) { + return e[_this.config.y.column] = e[_this.config.y.column] instanceof Date ? e[_this.config.y.column] : dateConvert.parse(e[_this.config.y.column]); }); } - if ( - (this.config.x.type === 'linear' || this.config.x.type === 'log') && - this.config.x.column - ) { - clean = clean.filter(function(f) { - return mark.summarizeX !== 'count' && mark.summarizeX !== 'percent' - ? !(isNaN(f[_this.config.x.column]) || /^\s*$/.test(f[_this.config.x.column])) // is or coerces to a number and is not a string that coerces to 0 - : f; + if ((this.config.x.type === 'linear' || this.config.x.type === 'log') && this.config.x.column) { + clean = clean.filter(function (f) { + return mark.summarizeX !== 'count' && mark.summarizeX !== 'percent' ? !(isNaN(f[_this.config.x.column]) || /^\s*$/.test(f[_this.config.x.column])) // is or coerces to a number and is not a string that coerces to 0 + : f; }); } - if ( - (this.config.y.type === 'linear' || this.config.y.type === 'log') && - this.config.y.column - ) { - clean = clean.filter(function(f) { - return mark.summarizeY !== 'count' && mark.summarizeY !== 'percent' - ? !(isNaN(f[_this.config.y.column]) || /^\s*$/.test(f[_this.config.y.column])) // is or coerces to a number and is not a string that coerces to 0 - : f; + if ((this.config.y.type === 'linear' || this.config.y.type === 'log') && this.config.y.column) { + clean = clean.filter(function (f) { + return mark.summarizeY !== 'count' && mark.summarizeY !== 'percent' ? !(isNaN(f[_this.config.y.column]) || /^\s*$/.test(f[_this.config.y.column])) // is or coerces to a number and is not a string that coerces to 0 + : f; }); } @@ -715,21 +526,17 @@ function summarize(vals) { var operation = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'mean'; - var nvals = vals - .filter(function(f) { - return +f || +f === 0; - }) - .map(function(m) { - return +m; - }); + var nvals = vals.filter(function (f) { + return +f || +f === 0; + }).map(function (m) { + return +m; + }); if (operation === 'cumulative') { return null; } - var mathed = operation === 'count' - ? vals.length - : operation === 'percent' ? vals.length : stats[operation](nvals); + var mathed = operation === 'count' ? vals.length : operation === 'percent' ? vals.length : stats[operation](nvals); return mathed; } @@ -742,125 +549,75 @@ var this_nest = d3.nest(); var totalOrder = void 0; - if ( - (this.config.x.type === 'linear' && this.config.x.bin) || - (this.config.y.type === 'linear' && this.config.y.bin) - ) { + if (this.config.x.type === 'linear' && this.config.x.bin || this.config.y.type === 'linear' && this.config.y.bin) { var xy = this.config.x.type === 'linear' && this.config.x.bin ? 'x' : 'y'; - var quant = d3.scale - .quantile() - .domain( - d3.extent( - entries.map(function(m) { - return +m[_this.config[xy].column]; - }) - ) - ) - .range(d3.range(+this.config[xy].bin)); - - entries.forEach(function(e) { - return (e.wc_bin = quant(e[_this.config[xy].column])); + var quant = d3.scale.quantile().domain(this.config[xy].behavior !== 'flex' && this.config[xy].domain ? this.config[xy].domain : d3.extent(entries.map(function (m) { + return +m[_this.config[xy].column]; + }))).range(d3.range(+this.config[xy].bin)); + + entries.forEach(function (e) { + return e.wc_bin = quant(e[_this.config[xy].column]); }); - this_nest.key(function(d) { + this_nest.key(function (d) { return quant.invertExtent(d.wc_bin); }); } else { - this_nest.key(function(d) { - return mark.per - .map(function(m) { - return d[m]; - }) - .join(' '); + this_nest.key(function (d) { + return mark.per.map(function (m) { + return d[m]; + }).join(' '); }); } if (sublevel) { - this_nest.key(function(d) { + this_nest.key(function (d) { return d[sublevel]; }); - this_nest.sortKeys(function(a, b) { - return _this.config.x.type === 'time' - ? d3.ascending(new Date(a), new Date(b)) - : _this.config.x.order - ? d3.ascending( - _this.config.x.order.indexOf(a), - _this.config.x.order.indexOf(b) - ) - : sublevel === _this.config.color_by && _this.config.legend.order - ? d3.ascending( - _this.config.legend.order.indexOf(a), - _this.config.legend.order.indexOf(b) - ) - : _this.config.x.type === 'ordinal' || _this.config.y.type === 'ordinal' - ? naturalSorter(a, b) - : d3.ascending(+a, +b); + this_nest.sortKeys(function (a, b) { + return _this.config.x.type === 'time' ? d3.ascending(new Date(a), new Date(b)) : _this.config.x.order ? d3.ascending(_this.config.x.order.indexOf(a), _this.config.x.order.indexOf(b)) : sublevel === _this.config.color_by && _this.config.legend.order ? d3.ascending(_this.config.legend.order.indexOf(a), _this.config.legend.order.indexOf(b)) : _this.config.x.type === 'ordinal' || _this.config.y.type === 'ordinal' ? naturalSorter(a, b) : d3.ascending(+a, +b); }); } - this_nest.rollup(function(r) { + this_nest.rollup(function (r) { var obj = { raw: r }; - var y_vals = r - .map(function(m) { - return m[_this.config.y.column]; - }) - .sort(d3.ascending); - var x_vals = r - .map(function(m) { - return m[_this.config.x.column]; - }) - .sort(d3.ascending); - obj.x = _this.config.x.type === 'ordinal' - ? r[0][_this.config.x.column] - : summarize(x_vals, mark.summarizeX); - obj.y = _this.config.y.type === 'ordinal' - ? r[0][_this.config.y.column] - : summarize(y_vals, mark.summarizeY); - - obj.x_q25 = _this.config.error_bars && _this.config.y.type === 'ordinal' - ? d3.quantile(x_vals, 0.25) - : obj.x; - obj.x_q75 = _this.config.error_bars && _this.config.y.type === 'ordinal' - ? d3.quantile(x_vals, 0.75) - : obj.x; + var y_vals = r.map(function (m) { + return m[_this.config.y.column]; + }).sort(d3.ascending); + var x_vals = r.map(function (m) { + return m[_this.config.x.column]; + }).sort(d3.ascending); + obj.x = _this.config.x.type === 'ordinal' ? r[0][_this.config.x.column] : summarize(x_vals, mark.summarizeX); + obj.y = _this.config.y.type === 'ordinal' ? r[0][_this.config.y.column] : summarize(y_vals, mark.summarizeY); + + obj.x_q25 = _this.config.error_bars && _this.config.y.type === 'ordinal' ? d3.quantile(x_vals, 0.25) : obj.x; + obj.x_q75 = _this.config.error_bars && _this.config.y.type === 'ordinal' ? d3.quantile(x_vals, 0.75) : obj.x; obj.y_q25 = _this.config.error_bars ? d3.quantile(y_vals, 0.25) : obj.y; obj.y_q75 = _this.config.error_bars ? d3.quantile(y_vals, 0.75) : obj.y; dom_xs.push([obj.x_q25, obj.x_q75, obj.x]); dom_ys.push([obj.y_q25, obj.y_q75, obj.y]); if (mark.summarizeY === 'cumulative') { - var interm = entries.filter(function(f) { - return _this.config.x.type === 'time' - ? new Date(f[_this.config.x.column]) <= - new Date(r[0][_this.config.x.column]) - : +f[_this.config.x.column] <= +r[0][_this.config.x.column]; + var interm = entries.filter(function (f) { + return _this.config.x.type === 'time' ? new Date(f[_this.config.x.column]) <= new Date(r[0][_this.config.x.column]) : +f[_this.config.x.column] <= +r[0][_this.config.x.column]; }); if (mark.per.length) { - interm = interm.filter(function(f) { + interm = interm.filter(function (f) { return f[mark.per[0]] === r[0][mark.per[0]]; }); } - var cumul = _this.config.x.type === 'time' - ? interm.length - : d3.sum( - interm.map(function(m) { - return +m[_this.config.y.column] || +m[_this.config.y.column] === 0 - ? +m[_this.config.y.column] - : 1; - }) - ); + var cumul = _this.config.x.type === 'time' ? interm.length : d3.sum(interm.map(function (m) { + return +m[_this.config.y.column] || +m[_this.config.y.column] === 0 ? +m[_this.config.y.column] : 1; + })); dom_ys.push([cumul]); obj.y = cumul; } if (mark.summarizeX === 'cumulative') { - var _interm = entries.filter(function(f) { - return _this.config.y.type === 'time' - ? new Date(f[_this.config.y.column]) <= - new Date(r[0][_this.config.y.column]) - : +f[_this.config.y.column] <= +r[0][_this.config.y.column]; + var _interm = entries.filter(function (f) { + return _this.config.y.type === 'time' ? new Date(f[_this.config.y.column]) <= new Date(r[0][_this.config.y.column]) : +f[_this.config.y.column] <= +r[0][_this.config.y.column]; }); if (mark.per.length) { - _interm = _interm.filter(function(f) { + _interm = _interm.filter(function (f) { return f[mark.per[0]] === r[0][mark.per[0]]; }); } @@ -878,31 +635,19 @@ if (sublevel && mark.type === 'bar' && mark.split) { //calculate percentages in bars - test.forEach(function(e) { - var axis = _this.config.x.type === 'ordinal' || - (_this.config.x.type === 'linear' && _this.config.x.bin) - ? 'y' - : 'x'; - e.total = d3.sum( - e.values.map(function(m) { - return +m.values[axis]; - }) - ); + test.forEach(function (e) { + var axis = _this.config.x.type === 'ordinal' || _this.config.x.type === 'linear' && _this.config.x.bin ? 'y' : 'x'; + e.total = d3.sum(e.values.map(function (m) { + return +m.values[axis]; + })); var counter = 0; - e.values.forEach(function(v, i) { - if ( - _this.config.x.type === 'ordinal' || - (_this.config.x.type === 'linear' && _this.config.x.bin) - ) { - v.values.y = mark.summarizeY === 'percent' - ? v.values.y / e.total - : v.values.y || 0; + e.values.forEach(function (v, i) { + if (_this.config.x.type === 'ordinal' || _this.config.x.type === 'linear' && _this.config.x.bin) { + v.values.y = mark.summarizeY === 'percent' ? v.values.y / e.total : v.values.y || 0; counter += +v.values.y; v.values.start = e.values[i - 1] ? counter : v.values.y; } else { - v.values.x = mark.summarizeX === 'percent' - ? v.values.x / e.total - : v.values.x || 0; + v.values.x = mark.summarizeX === 'percent' ? v.values.x / e.total : v.values.x || 0; v.values.start = counter; counter += +v.values.x; } @@ -910,59 +655,36 @@ }); if (mark.arrange === 'stacked') { - if ( - this.config.x.type === 'ordinal' || - (this.config.x.type === 'linear' && this.config.x.bin) - ) { - dom_y = d3.extent( - test.map(function(m) { - return m.total; - }) - ); + if (this.config.x.type === 'ordinal' || this.config.x.type === 'linear' && this.config.x.bin) { + dom_y = d3.extent(test.map(function (m) { + return m.total; + })); } - if ( - this.config.y.type === 'ordinal' || - (this.config.y.type === 'linear' && this.config.y.bin) - ) { - dom_x = d3.extent( - test.map(function(m) { - return m.total; - }) - ); + if (this.config.y.type === 'ordinal' || this.config.y.type === 'linear' && this.config.y.bin) { + dom_x = d3.extent(test.map(function (m) { + return m.total; + })); } } } else { - var axis = this.config.x.type === 'ordinal' || - (this.config.x.type === 'linear' && this.config.x.bin) - ? 'y' - : 'x'; - test.forEach(function(e) { - return (e.total = e.values[axis]); + var axis = this.config.x.type === 'ordinal' || this.config.x.type === 'linear' && this.config.x.bin ? 'y' : 'x'; + test.forEach(function (e) { + return e.total = e.values[axis]; }); } - if ( - (this.config.x.sort === 'total-ascending' && this.config.x.type == 'ordinal') || - (this.config.y.sort === 'total-descending' && this.config.y.type == 'ordinal') - ) { - totalOrder = test - .sort(function(a, b) { - return d3.ascending(a.total, b.total); - }) - .map(function(m) { - return m.key; - }); - } else if ( - (this.config.x.sort === 'total-descending' && this.config.x.type == 'ordinal') || - (this.config.y.sort === 'total-ascending' && this.config.y.type == 'ordinal') - ) { - totalOrder = test - .sort(function(a, b) { - return d3.descending(+a.total, +b.total); - }) - .map(function(m) { - return m.key; - }); + if (this.config.x.sort === 'total-ascending' && this.config.x.type == 'ordinal' || this.config.y.sort === 'total-descending' && this.config.y.type == 'ordinal') { + totalOrder = test.sort(function (a, b) { + return d3.ascending(a.total, b.total); + }).map(function (m) { + return m.key; + }); + } else if (this.config.x.sort === 'total-descending' && this.config.x.type == 'ordinal' || this.config.y.sort === 'total-ascending' && this.config.y.type == 'ordinal') { + totalOrder = test.sort(function (a, b) { + return d3.descending(+a.total, +b.total); + }).map(function (m) { + return m.key; + }); } return { nested: test, dom_x: dom_x, dom_y: dom_y, totalOrder: totalOrder }; @@ -986,9 +708,7 @@ var config = this.config; var x_behavior = config.x.behavior || 'raw'; var y_behavior = config.y.behavior || 'raw'; - var sublevel = mark.type === 'line' - ? config.x.column - : mark.type === 'bar' && mark.split ? mark.split : null; + var sublevel = mark.type === 'line' ? config.x.column : mark.type === 'bar' && mark.split ? mark.split : null; ////////////////////////////////////////////////////////////////////////////////// // DATA PREP @@ -999,127 +719,73 @@ //prepare nested data required for bar charts var raw_nest = void 0; if (mark.type === 'bar') { - raw_nest = mark.arrange !== 'stacked' - ? makeNest.call(this, mark, cleaned, sublevel) - : makeNest.call(this, mark, cleaned); + raw_nest = mark.arrange !== 'stacked' ? makeNest.call(this, mark, cleaned, sublevel) : makeNest.call(this, mark, cleaned); } else if (mark.summarizeX === 'count' || mark.summarizeY === 'count') { raw_nest = makeNest.call(this, mark, cleaned); } // Get the domain for the mark based on the raw data - var raw_dom_x = mark.summarizeX === 'cumulative' - ? [0, cleaned.length] - : config.x.type === 'ordinal' - ? d3 - .set( - cleaned.map(function(m) { - return m[config.x.column]; - }) - ) - .values() - .filter(function(f) { - return f; - }) - : mark.split && mark.arrange !== 'stacked' - ? d3.extent( - d3.merge( - raw_nest.nested.map(function(m) { - return m.values.map(function(p) { - return p.values.raw.length; - }); - }) - ) - ) - : mark.summarizeX === 'count' - ? d3.extent( - raw_nest.nested.map(function(m) { - return m.values.raw.length; - }) - ) - : d3.extent( - cleaned - .map(function(m) { - return +m[config.x.column]; - }) - .filter(function(f) { - return +f || +f === 0; - }) - ); - - var raw_dom_y = mark.summarizeY === 'cumulative' - ? [0, cleaned.length] - : config.y.type === 'ordinal' - ? d3 - .set( - cleaned.map(function(m) { - return m[config.y.column]; - }) - ) - .values() - .filter(function(f) { - return f; - }) - : mark.split && mark.arrange !== 'stacked' - ? d3.extent( - d3.merge( - raw_nest.nested.map(function(m) { - return m.values.map(function(p) { - return p.values.raw.length; - }); - }) - ) - ) - : mark.summarizeY === 'count' - ? d3.extent( - raw_nest.nested.map(function(m) { - return m.values.raw.length; - }) - ) - : d3.extent( - cleaned - .map(function(m) { - return +m[config.y.column]; - }) - .filter(function(f) { - return +f || +f === 0; - }) - ); + var raw_dom_x = mark.summarizeX === 'cumulative' ? [0, cleaned.length] : config.x.type === 'ordinal' ? d3.set(cleaned.map(function (m) { + return m[config.x.column]; + })).values().filter(function (f) { + return f; + }) : mark.split && mark.arrange !== 'stacked' ? d3.extent(d3.merge(raw_nest.nested.map(function (m) { + return m.values.map(function (p) { + return p.values.raw.length; + }); + }))) : mark.summarizeX === 'count' ? d3.extent(raw_nest.nested.map(function (m) { + return m.values.raw.length; + })) : d3.extent(cleaned.map(function (m) { + return +m[config.x.column]; + }).filter(function (f) { + return +f || +f === 0; + })); + + var raw_dom_y = mark.summarizeY === 'cumulative' ? [0, cleaned.length] : config.y.type === 'ordinal' ? d3.set(cleaned.map(function (m) { + return m[config.y.column]; + })).values().filter(function (f) { + return f; + }) : mark.split && mark.arrange !== 'stacked' ? d3.extent(d3.merge(raw_nest.nested.map(function (m) { + return m.values.map(function (p) { + return p.values.raw.length; + }); + }))) : mark.summarizeY === 'count' ? d3.extent(raw_nest.nested.map(function (m) { + return m.values.raw.length; + })) : d3.extent(cleaned.map(function (m) { + return +m[config.y.column]; + }).filter(function (f) { + return +f || +f === 0; + })); var filtered = cleaned; var filt1_xs = []; var filt1_ys = []; if (this.filters.length) { - this.filters.forEach(function(e) { - filtered = filtered.filter(function(d) { - return e.all === true && e.index === 0 - ? d - : e.val instanceof Array - ? e.val.indexOf(d[e.col]) > -1 - : d[e.col] === e.val; + this.filters.forEach(function (e) { + filtered = filtered.filter(function (d) { + return e.all === true && e.index === 0 ? d : e.val instanceof Array ? e.val.indexOf(d[e.col]) > -1 : d[e.col] === e.val; }); }); //get domain for all non-All values of first filter if (config.x.behavior === 'firstfilter' || config.y.behavior === 'firstfilter') { - this.filters[0].choices - .filter(function(f) { - return f !== 'All'; - }) - .forEach(function(e) { - var perfilter = cleaned.filter(function(f) { - return f[_this.filters[0].col] === e; - }); - var filt_nested = makeNest.call(_this, mark, perfilter, sublevel); - filt1_xs.push(filt_nested.dom_x); - filt1_ys.push(filt_nested.dom_y); + this.filters[0].choices.filter(function (f) { + return f !== 'All'; + }).forEach(function (e) { + var perfilter = cleaned.filter(function (f) { + return f[_this.filters[0].col] === e; }); + var filt_nested = makeNest.call(_this, mark, perfilter, sublevel); + filt1_xs.push(filt_nested.dom_x); + filt1_ys.push(filt_nested.dom_y); + }); } } //filter on mark-specific instructions if (mark.values) { var _loop = function _loop(a) { - filtered = filtered.filter(function(f) { + filtered = filtered.filter(function (f) { return mark.values[a].indexOf(f[a]) > -1; }); }; @@ -1145,112 +811,43 @@ } //several criteria must be met in order to use the 'firstfilter' domain - var nonall = Boolean( - this.filters.length && - this.filters[0].val !== 'All' && - this.filters.slice(1).filter(function(f) { - return f.val === 'All'; - }).length === - this.filters.length - 1 - ); - - var pre_x_dom = !this.filters.length - ? flex_dom_x - : x_behavior === 'raw' - ? raw_dom_x - : nonall && x_behavior === 'firstfilter' ? filt1_dom_x : flex_dom_x; - var pre_y_dom = !this.filters.length - ? flex_dom_y - : y_behavior === 'raw' - ? raw_dom_y - : nonall && y_behavior === 'firstfilter' ? filt1_dom_y : flex_dom_y; - - var x_dom = config.x_dom - ? config.x_dom - : config.x.type === 'ordinal' && config.x.behavior === 'flex' - ? d3 - .set( - filtered.map(function(m) { - return m[config.x.column]; - }) - ) - .values() - : config.x.type === 'ordinal' - ? d3 - .set( - cleaned.map(function(m) { - return m[config.x.column]; - }) - ) - .values() - : pre_x_dom; - - var y_dom = config.y_dom - ? config.y_dom - : config.y.type === 'ordinal' && config.y.behavior === 'flex' - ? d3 - .set( - filtered.map(function(m) { - return m[config.y.column]; - }) - ) - .values() - : config.y.type === 'ordinal' - ? d3 - .set( - cleaned.map(function(m) { - return m[config.y.column]; - }) - ) - .values() - : pre_y_dom; + var nonall = Boolean(this.filters.length && this.filters[0].val !== 'All' && this.filters.slice(1).filter(function (f) { + return f.val === 'All'; + }).length === this.filters.length - 1); + + var pre_x_dom = !this.filters.length ? flex_dom_x : x_behavior === 'raw' ? raw_dom_x : nonall && x_behavior === 'firstfilter' ? filt1_dom_x : flex_dom_x; + var pre_y_dom = !this.filters.length ? flex_dom_y : y_behavior === 'raw' ? raw_dom_y : nonall && y_behavior === 'firstfilter' ? filt1_dom_y : flex_dom_y; + + var x_dom = config.x_dom ? config.x_dom : config.x.type === 'ordinal' && config.x.behavior === 'flex' ? d3.set(filtered.map(function (m) { + return m[config.x.column]; + })).values() : config.x.type === 'ordinal' ? d3.set(cleaned.map(function (m) { + return m[config.x.column]; + })).values() : pre_x_dom; + + var y_dom = config.y_dom ? config.y_dom : config.y.type === 'ordinal' && config.y.behavior === 'flex' ? d3.set(filtered.map(function (m) { + return m[config.y.column]; + })).values() : config.y.type === 'ordinal' ? d3.set(cleaned.map(function (m) { + return m[config.y.column]; + })).values() : pre_y_dom; //set lower limit of linear domain to 0 when other axis is ordinal and mark type is set to 'bar', provided no values are negative if (mark.type === 'bar') { - if ( - config.x.behavior !== 'flex' && - config.x.type === 'linear' && - config.y.type === 'ordinal' && - raw_dom_x[0] >= 0 - ) - x_dom[0] = 0; - - if ( - config.y.behavior !== 'flex' && - config.x.type === 'ordinal' && - config.y.type === 'linear' && - raw_dom_y[0] >= 0 - ) - y_dom[0] = 0; + if (config.x.behavior !== 'flex' && config.x.type === 'linear' && config.y.type === 'ordinal' && raw_dom_x[0] >= 0) x_dom[0] = 0; + + if (config.y.behavior !== 'flex' && config.x.type === 'ordinal' && config.y.type === 'linear' && raw_dom_y[0] >= 0) y_dom[0] = 0; } //update domains with those specified in the config - if ( - config.x.domain && - (config.x.domain[0] || config.x.domain[0] === 0) && - !isNaN(+config.x.domain[0]) - ) { + if (config.x.domain && (config.x.domain[0] || config.x.domain[0] === 0) && !isNaN(+config.x.domain[0])) { x_dom[0] = config.x.domain[0]; } - if ( - config.x.domain && - (config.x.domain[1] || config.x.domain[1] === 0) && - !isNaN(+config.x.domain[1]) - ) { + if (config.x.domain && (config.x.domain[1] || config.x.domain[1] === 0) && !isNaN(+config.x.domain[1])) { x_dom[1] = config.x.domain[1]; } - if ( - config.y.domain && - (config.y.domain[0] || config.y.domain[0] === 0) && - !isNaN(+config.y.domain[0]) - ) { + if (config.y.domain && (config.y.domain[0] || config.y.domain[0] === 0) && !isNaN(+config.y.domain[0])) { y_dom[0] = config.y.domain[0]; } - if ( - config.y.domain && - (config.y.domain[1] || config.y.domain[1] === 0) && - !isNaN(+config.y.domain[1]) - ) { + if (config.y.domain && (config.y.domain[1] || config.y.domain[1] === 0) && !isNaN(+config.y.domain[1])) { y_dom[1] = config.y.domain[1]; } @@ -1271,24 +868,15 @@ function setColorScale() { var config = this.config; var data = config.legend.behavior === 'flex' ? this.filtered_data : this.raw_data; - var colordom = Array.isArray(config.color_dom) && config.color_dom.length - ? config.color_dom.slice() - : d3 - .set( - data.map(function(m) { - return m[config.color_by]; - }) - ) - .values() - .filter(function(f) { - return f && f !== 'undefined'; - }); - - if (config.legend.order) - colordom.sort(function(a, b) { - return d3.ascending(config.legend.order.indexOf(a), config.legend.order.indexOf(b)); - }); - else colordom.sort(naturalSorter); + var colordom = Array.isArray(config.color_dom) && config.color_dom.length ? config.color_dom.slice() : d3.set(data.map(function (m) { + return m[config.color_by]; + })).values().filter(function (f) { + return f && f !== 'undefined'; + }); + + if (config.legend.order) colordom.sort(function (a, b) { + return d3.ascending(config.legend.order.indexOf(a), config.legend.order.indexOf(b)); + });else colordom.sort(naturalSorter); this.colorScale = d3.scale.ordinal().domain(colordom).range(config.colors); } @@ -1324,29 +912,11 @@ x.range([0, +max_range]).clamp(Boolean(config.x.clamp)); } - var xFormat = config.x.format - ? config.x.format - : config.marks - .map(function(m) { - return m.summarizeX === 'percent'; - }) - .indexOf(true) > -1 - ? '0%' - : type === 'time' ? '%x' : '.0f'; + var xFormat = config.x.format ? config.x.format : config.marks.map(function (m) { + return m.summarizeX === 'percent'; + }).indexOf(true) > -1 ? '0%' : type === 'time' ? '%x' : '.0f'; var tick_count = Math.max(2, Math.min(max_range / 80, 8)); - var xAxis = d3.svg - .axis() - .scale(x) - .orient(config.x.location) - .ticks(tick_count) - .tickFormat( - type === 'ordinal' - ? null - : type === 'time' ? d3.time.format(xFormat) : d3.format(xFormat) - ) - .tickValues(config.x.ticks ? config.x.ticks : null) - .innerTickSize(6) - .outerTickSize(3); + var xAxis = d3.svg.axis().scale(x).orient(config.x.location).ticks(tick_count).tickFormat(type === 'ordinal' ? null : type === 'time' ? d3.time.format(xFormat) : d3.format(xFormat)).tickValues(config.x.ticks ? config.x.ticks : null).innerTickSize(6).outerTickSize(3); this.svg.select('g.x.axis').attr('class', 'x axis ' + type); this.x = x; @@ -1383,29 +953,11 @@ y.range([+max_range, 0]).clamp(Boolean(config.y_clamp)); } - var yFormat = config.y.format - ? config.y.format - : config.marks - .map(function(m) { - return m.summarizeY === 'percent'; - }) - .indexOf(true) > -1 - ? '0%' - : '.0f'; + var yFormat = config.y.format ? config.y.format : config.marks.map(function (m) { + return m.summarizeY === 'percent'; + }).indexOf(true) > -1 ? '0%' : '.0f'; var tick_count = Math.max(2, Math.min(max_range / 80, 8)); - var yAxis = d3.svg - .axis() - .scale(y) - .orient('left') - .ticks(tick_count) - .tickFormat( - type === 'ordinal' - ? null - : type === 'time' ? d3.time.format(yFormat) : d3.format(yFormat) - ) - .tickValues(config.y.ticks ? config.y.ticks : null) - .innerTickSize(6) - .outerTickSize(3); + var yAxis = d3.svg.axis().scale(y).orient('left').ticks(tick_count).tickFormat(type === 'ordinal' ? null : type === 'time' ? d3.time.format(yFormat) : d3.format(yFormat)).tickValues(config.y.ticks ? config.y.ticks : null).innerTickSize(6).outerTickSize(3); this.svg.select('g.y.axis').attr('class', 'y axis ' + type); @@ -1419,45 +971,22 @@ var aspect2 = 1 / config.aspect; var div_width = parseInt(this.wrap.style('width')); var max_width = config.max_width ? config.max_width : div_width; - var preWidth = !config.resizable - ? config.width - : !max_width || div_width < max_width ? div_width : this.raw_width; + var preWidth = !config.resizable ? config.width : !max_width || div_width < max_width ? div_width : this.raw_width; this.textSize(preWidth); this.margin = this.setMargins(); - var svg_width = config.x.type === 'ordinal' && +config.x.range_band - ? this.raw_width + this.margin.left + this.margin.right - : !config.resizable - ? this.raw_width - : !config.max_width || div_width < config.max_width ? div_width : this.raw_width; + var svg_width = config.x.type === 'ordinal' && +config.x.range_band ? this.raw_width + this.margin.left + this.margin.right : !config.resizable ? this.raw_width : !config.max_width || div_width < config.max_width ? div_width : this.raw_width; this.plot_width = svg_width - this.margin.left - this.margin.right; - var svg_height = config.y.type === 'ordinal' && +config.y.range_band - ? this.raw_height + this.margin.top + this.margin.bottom - : !config.resizable && config.height - ? config.height - : !config.resizable ? svg_width * aspect2 : this.plot_width * aspect2; + var svg_height = config.y.type === 'ordinal' && +config.y.range_band ? this.raw_height + this.margin.top + this.margin.bottom : !config.resizable && config.height ? config.height : !config.resizable ? svg_width * aspect2 : this.plot_width * aspect2; this.plot_height = svg_height - this.margin.top - this.margin.bottom; - d3 - .select(this.svg.node().parentNode) - .attr('width', svg_width) - .attr('height', svg_height) - .select('g') - .attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')'); - - this.svg - .select('.overlay') - .attr('width', this.plot_width) - .attr('height', this.plot_height) - .classed('zoomable', config.zoomable); - - this.svg - .select('.plotting-area') - .attr('width', this.plot_width) - .attr('height', this.plot_height + 1) - .attr('transform', 'translate(0, -1)'); + d3.select(this.svg.node().parentNode).attr('width', svg_width).attr('height', svg_height).select('g').attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')'); + + this.svg.select('.overlay').attr('width', this.plot_width).attr('height', this.plot_height).classed('zoomable', config.zoomable); + + this.svg.select('.plotting-area').attr('width', this.plot_width).attr('height', this.plot_height + 1).attr('transform', 'translate(0, -1)'); this.xScaleAxis(); this.yScaleAxis(); @@ -1475,23 +1004,11 @@ var gYAxisTrans = config.transitions ? g_y_axis.transition() : g_y_axis; gYAxisTrans.call(this.yAxis); - x_axis_label.attr( - 'transform', - 'translate(' + this.plot_width / 2 + ',' + (this.margin.bottom - 2) + ')' - ); + x_axis_label.attr('transform', 'translate(' + this.plot_width / 2 + ',' + (this.margin.bottom - 2) + ')'); y_axis_label.attr('x', -1 * this.plot_height / 2).attr('y', -1 * this.margin.left); - this.svg - .selectAll('.axis .domain') - .attr({ - fill: 'none', - stroke: '#ccc', - 'stroke-width': 1, - 'shape-rendering': 'crispEdges' - }); - this.svg - .selectAll('.axis .tick line') - .attr({ stroke: '#eee', 'stroke-width': 1, 'shape-rendering': 'crispEdges' }); + this.svg.selectAll('.axis .domain').attr({ fill: 'none', stroke: '#ccc', 'stroke-width': 1, 'shape-rendering': 'crispEdges' }); + this.svg.selectAll('.axis .tick line').attr({ stroke: '#eee', 'stroke-width': 1, 'shape-rendering': 'crispEdges' }); this.drawGridlines(); @@ -1540,17 +1057,13 @@ function setMargins() { var _this = this; - var y_ticks = this.yAxis.tickFormat() - ? this.y.domain().map(function(m) { - return _this.yAxis.tickFormat()(m); - }) - : this.y.domain(); - - var max_y_text_length = d3.max( - y_ticks.map(function(m) { - return String(m).length; - }) - ); + var y_ticks = this.yAxis.tickFormat() ? this.y.domain().map(function (m) { + return _this.yAxis.tickFormat()(m); + }) : this.y.domain(); + + var max_y_text_length = d3.max(y_ticks.map(function (m) { + return String(m).length; + })); if (this.config.y_format && this.config.y_format.indexOf('%') > -1) { max_y_text_length += 1; } @@ -1560,8 +1073,7 @@ var font_size = parseInt(this.wrap.style('font-size')); var x_second = this.config.x2_interval ? 1 : 0; var y_margin = max_y_text_length * font_size * 0.5 + font_size * y_label_on * 1.5 || 8; - var x_margin = - font_size + font_size / 1.5 + font_size * x_label_on + font_size * x_second || 8; + var x_margin = font_size + font_size / 1.5 + font_size * x_label_on + font_size * x_second || 8; y_margin += 6; x_margin += 3; @@ -1569,9 +1081,7 @@ return { top: this.config.margin && this.config.margin.top ? this.config.margin.top : 8, right: this.config.margin && this.config.margin.right ? this.config.margin.right : 16, - bottom: this.config.margin && this.config.margin.bottom - ? this.config.margin.bottom - : x_margin, + bottom: this.config.margin && this.config.margin.bottom ? this.config.margin.bottom : x_margin, left: this.config.margin && this.config.margin.left ? this.config.margin.left : y_margin }; } @@ -1581,10 +1091,8 @@ if (this.config.gridlines) { this.svg.select('.y.axis').selectAll('.tick line').attr('x1', 0); this.svg.select('.x.axis').selectAll('.tick line').attr('y1', 0); - if (this.config.gridlines === 'y' || this.config.gridlines === 'xy') - this.svg.select('.y.axis').selectAll('.tick line').attr('x1', this.plot_width); - if (this.config.gridlines === 'x' || this.config.gridlines === 'xy') - this.svg.select('.x.axis').selectAll('.tick line').attr('y1', -this.plot_height); + if (this.config.gridlines === 'y' || this.config.gridlines === 'xy') this.svg.select('.y.axis').selectAll('.tick line').attr('x1', this.plot_width); + if (this.config.gridlines === 'x' || this.config.gridlines === 'xy') this.svg.select('.x.axis').selectAll('.tick line').attr('y1', -this.plot_height); } else { this.svg.select('.y.axis').selectAll('.tick line').attr('x1', 0); this.svg.select('.x.axis').selectAll('.tick line').attr('y1', 0); @@ -1592,23 +1100,15 @@ } function makeLegend() { - var scale = arguments.length > 0 && arguments[0] !== undefined - ? arguments[0] - : this.colorScale; + var scale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.colorScale; var label = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; var custom_data = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; var config = this.config; - config.legend.mark = config.legend.mark - ? config.legend.mark - : config.marks.length && config.marks[0].type === 'bar' - ? 'square' - : config.marks.length ? config.marks[0].type : 'square'; + config.legend.mark = config.legend.mark ? config.legend.mark : config.marks.length && config.marks[0].type === 'bar' ? 'square' : config.marks.length ? config.marks[0].type : 'square'; - var legend_label = label - ? label - : typeof config.legend.label === 'string' ? config.legend.label : ''; + var legend_label = label ? label : typeof config.legend.label === 'string' ? config.legend.label : ''; var legendOriginal = this.legend || this.wrap.select('.legend'); var legend = legendOriginal; @@ -1623,12 +1123,7 @@ } else { //multiples - keep legend outside of individual charts' wraps if (this.config.legend.location === 'top' || this.config.legend.location === 'left') { - this.parent.wrap - .node() - .insertBefore( - legendOriginal.node(), - this.parent.wrap.select('.wc-chart').node() - ); + this.parent.wrap.node().insertBefore(legendOriginal.node(), this.parent.wrap.select('.wc-chart').node()); } else { this.parent.wrap.node().appendChild(legendOriginal.node()); } @@ -1636,65 +1131,40 @@ legend.style('padding', 0); - var legend_data = - custom_data || - scale - .domain() - .slice(0) - .filter(function(f) { - return f !== undefined && f !== null; - }) - .map(function(m) { - return { label: m, mark: config.legend.mark }; - }); + var legend_data = custom_data || scale.domain().slice(0).filter(function (f) { + return f !== undefined && f !== null; + }).map(function (m) { + return { label: m, mark: config.legend.mark }; + }); - legend - .select('.legend-title') - .text(legend_label) - .style('display', legend_label ? 'inline' : 'none') - .style('margin-right', '1em'); + legend.select('.legend-title').text(legend_label).style('display', legend_label ? 'inline' : 'none').style('margin-right', '1em'); - var leg_parts = legend.selectAll('.legend-item').data(legend_data, function(d) { + var leg_parts = legend.selectAll('.legend-item').data(legend_data, function (d) { return d.label + d.mark; }); leg_parts.exit().remove(); - var legendPartDisplay = this.config.legend.location === 'bottom' || - this.config.legend.location === 'top' - ? 'inline-block' - : 'block'; - var new_parts = leg_parts - .enter() - .append('li') - .attr('class', 'legend-item') - .style({ 'list-style-type': 'none', 'margin-right': '1em' }); - new_parts.append('span').attr('class', 'legend-mark-text').style('color', function(d) { + var legendPartDisplay = this.config.legend.location === 'bottom' || this.config.legend.location === 'top' ? 'inline-block' : 'block'; + var new_parts = leg_parts.enter().append('li').attr('class', 'legend-item').style({ 'list-style-type': 'none', 'margin-right': '1em' }); + new_parts.append('span').attr('class', 'legend-mark-text').style('color', function (d) { return scale(d.label); }); - new_parts - .append('svg') - .attr('class', 'legend-color-block') - .attr('width', '1.1em') - .attr('height', '1.1em') - .style({ - position: 'relative', - top: '0.2em' - }); + new_parts.append('svg').attr('class', 'legend-color-block').attr('width', '1.1em').attr('height', '1.1em').style({ + position: 'relative', + top: '0.2em' + }); leg_parts.style('display', legendPartDisplay); if (config.legend.order) { - leg_parts.sort(function(a, b) { - return d3.ascending( - config.legend.order.indexOf(a.label), - config.legend.order.indexOf(b.label) - ); + leg_parts.sort(function (a, b) { + return d3.ascending(config.legend.order.indexOf(a.label), config.legend.order.indexOf(b.label)); }); } leg_parts.selectAll('.legend-color-block').select('.legend-mark').remove(); - leg_parts.selectAll('.legend-color-block').each(function(e) { + leg_parts.selectAll('.legend-color-block').each(function (e) { var svg = d3.select(this); if (e.mark === 'circle') { svg.append('circle').attr({ @@ -1722,33 +1192,20 @@ }); } }); - leg_parts - .selectAll('.legend-color-block') - .select('.legend-mark') - .attr('fill', function(d) { - return d.color || scale(d.label); - }) - .attr('stroke', function(d) { - return d.color || scale(d.label); - }) - .each(function(e) { - d3.select(this).attr(e.attributes); - }); + leg_parts.selectAll('.legend-color-block').select('.legend-mark').attr('fill', function (d) { + return d.color || scale(d.label); + }).attr('stroke', function (d) { + return d.color || scale(d.label); + }).each(function (e) { + d3.select(this).attr(e.attributes); + }); - new_parts - .append('span') - .attr('class', 'legend-label') - .style('margin-left', '0.25em') - .text(function(d) { - return d.label; - }); + new_parts.append('span').attr('class', 'legend-label').style('margin-left', '0.25em').text(function (d) { + return d.label; + }); if (scale.domain().length > 0) { - var legendDisplay = (this.config.legend.location === 'bottom' || - this.config.legend.location === 'top') && - !this.parent - ? 'block' - : 'inline-block'; + var legendDisplay = (this.config.legend.location === 'bottom' || this.config.legend.location === 'top') && !this.parent ? 'block' : 'inline-block'; legend.style('display', legendDisplay); } else { legend.style('display', 'none'); @@ -1758,67 +1215,42 @@ } function updateDataMarks() { - this.drawBars( - this.marks.filter(function(f) { - return f.type === 'bar'; - }) - ); - this.drawLines( - this.marks.filter(function(f) { - return f.type === 'line'; - }) - ); - this.drawPoints( - this.marks.filter(function(f) { - return f.type === 'circle'; - }) - ); - this.drawText( - this.marks.filter(function(f) { - return f.type === 'text'; - }) - ); + this.drawBars(this.marks.filter(function (f) { + return f.type === 'bar'; + })); + this.drawLines(this.marks.filter(function (f) { + return f.type === 'line'; + })); + this.drawPoints(this.marks.filter(function (f) { + return f.type === 'circle'; + })); + this.drawText(this.marks.filter(function (f) { + return f.type === 'text'; + })); this.marks.supergroups = this.svg.selectAll('g.supergroup'); } function drawArea(area_drawer, area_data, datum_accessor) { - var class_match = arguments.length > 3 && arguments[3] !== undefined - ? arguments[3] - : 'chart-area'; + var class_match = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'chart-area'; var _this = this; var bind_accessor = arguments[4]; - var attr_accessor = arguments.length > 5 && arguments[5] !== undefined - ? arguments[5] - : function(d) { - return d; - }; + var attr_accessor = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : function (d) { + return d; + }; var area_grps = this.svg.selectAll('.' + class_match).data(area_data, bind_accessor); area_grps.exit().remove(); - area_grps - .enter() - .append('g') - .attr('class', function(d) { - return class_match + ' ' + d.key; - }) - .append('path'); - - var areaPaths = area_grps - .select('path') - .datum(datum_accessor) - .attr('fill', function(d) { - var d_attr = attr_accessor(d); - return d_attr ? _this.colorScale(d_attr[_this.config.color_by]) : null; - }) - .attr( - 'fill-opacity', - this.config.fill_opacity || this.config.fill_opacity === 0 - ? this.config.fill_opacity - : 0.3 - ); + area_grps.enter().append('g').attr('class', function (d) { + return class_match + ' ' + d.key; + }).append('path'); + + var areaPaths = area_grps.select('path').datum(datum_accessor).attr('fill', function (d) { + var d_attr = attr_accessor(d); + return d_attr ? _this.colorScale(d_attr[_this.config.color_by]) : null; + }).attr('fill-opacity', this.config.fill_opacity || this.config.fill_opacity === 0 ? this.config.fill_opacity : 0.3); //don't transition if config says not to var areaPathTransitions = this.config.transitions ? areaPaths.transition() : areaPaths; @@ -1835,32 +1267,27 @@ var rawData = this.raw_data; var config = this.config; - var bar_supergroups = this.svg.selectAll('.bar-supergroup').data(marks, function(d, i) { + var bar_supergroups = this.svg.selectAll('.bar-supergroup').data(marks, function (d, i) { return i + '-' + d.per.join('-'); }); - bar_supergroups.enter().append('g').attr('class', function(d) { + bar_supergroups.enter().append('g').attr('class', function (d) { return 'supergroup bar-supergroup ' + d.id; }); bar_supergroups.exit().remove(); - var bar_groups = bar_supergroups.selectAll('.bar-group').data( - function(d) { - return d.data; - }, - function(d) { - return d.key; - } - ); + var bar_groups = bar_supergroups.selectAll('.bar-group').data(function (d) { + return d.data; + }, function (d) { + return d.key; + }); var old_bar_groups = bar_groups.exit(); var nu_bar_groups = void 0; var bars = void 0; - var oldBarsTrans = config.transitions - ? old_bar_groups.selectAll('.bar').transition() - : old_bar_groups.selectAll('.bar'); + var oldBarsTrans = config.transitions ? old_bar_groups.selectAll('.bar').transition() : old_bar_groups.selectAll('.bar'); var oldBarGroupsTrans = config.transitions ? old_bar_groups.transition() : old_bar_groups; if (config.x.type === 'ordinal') { @@ -1868,327 +1295,207 @@ oldBarGroupsTrans.remove(); - nu_bar_groups = bar_groups.enter().append('g').attr('class', function(d) { + nu_bar_groups = bar_groups.enter().append('g').attr('class', function (d) { return 'bar-group ' + d.key; }); nu_bar_groups.append('title'); - bars = bar_groups.selectAll('rect').data( - function(d) { - return d.values instanceof Array - ? d.values.sort(function(a, b) { - return ( - _this.colorScale.domain().indexOf(b.key) - - _this.colorScale.domain().indexOf(a.key) - ); - }) - : [d]; - }, - function(d) { - return d.key; - } - ); + bars = bar_groups.selectAll('rect').data(function (d) { + return d.values instanceof Array ? d.values.sort(function (a, b) { + return _this.colorScale.domain().indexOf(b.key) - _this.colorScale.domain().indexOf(a.key); + }) : [d]; + }, function (d) { + return d.key; + }); var exitBars = config.transitions ? bars.exit().transition() : bars.exit(); exitBars.attr('y', this.y(0)).attr('height', 0).remove(); - bars - .enter() - .append('rect') - .attr('class', function(d) { - return 'wc-data-mark bar ' + d.key; - }) - .style('clip-path', 'url(#' + chart.id + ')') - .attr('y', this.y(0)) - .attr('height', 0) - .append('title'); - - bars - .attr('shape-rendering', 'crispEdges') - .attr('stroke', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }) - .attr('fill', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); + bars.enter().append('rect').attr('class', function (d) { + return 'wc-data-mark bar ' + d.key; + }).style('clip-path', 'url(#' + chart.id + ')').attr('y', this.y(0)).attr('height', 0).append('title'); + + bars.attr('shape-rendering', 'crispEdges').attr('stroke', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }).attr('fill', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); - bars.each(function(d) { + bars.each(function (d) { var mark = d3.select(this.parentNode.parentNode).datum(); d.tooltip = mark.tooltip; - d.arrange = mark.split && mark.arrange - ? mark.arrange - : mark.split ? 'grouped' : null; - d.subcats = config.legend.order - ? config.legend.order.slice().reverse() - : mark.values && mark.values[mark.split] - ? mark.values[mark.split] - : d3 - .set( - rawData.map(function(m) { - return m[mark.split]; - }) - ) - .values(); + d.arrange = mark.split && mark.arrange ? mark.arrange : mark.split ? 'grouped' : null; + d.subcats = config.legend.order ? config.legend.order.slice().reverse() : mark.values && mark.values[mark.split] ? mark.values[mark.split] : d3.set(rawData.map(function (m) { + return m[mark.split]; + })).values(); d3.select(this).attr(mark.attributes); }); - var xformat = config.marks - .map(function(m) { - return m.summarizeX === 'percent'; - }) - .indexOf(true) > -1 - ? d3.format('0%') - : d3.format(config.x.format); - var yformat = config.marks - .map(function(m) { - return m.summarizeY === 'percent'; - }) - .indexOf(true) > -1 - ? d3.format('0%') - : d3.format(config.y.format); - bars.select('title').text(function(d) { + var xformat = config.marks.map(function (m) { + return m.summarizeX === 'percent'; + }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.x.format); + var yformat = config.marks.map(function (m) { + return m.summarizeY === 'percent'; + }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.y.format); + bars.select('title').text(function (d) { var tt = d.tooltip || ''; - return tt - .replace(/\$x/g, xformat(d.values.x)) - .replace(/\$y/g, yformat(d.values.y)) - .replace(/\[(.+?)\]/g, function(str, orig) { - return d.values.raw[0][orig]; - }); + return tt.replace(/\$x/g, xformat(d.values.x)).replace(/\$y/g, yformat(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { + return d.values.raw[0][orig]; + }); }); var barsTrans = config.transitions ? bars.transition() : bars; - barsTrans - .attr('x', function(d) { - var position = void 0; - if (!d.arrange || d.arrange === 'stacked') { - return _this.x(d.values.x); - } else if (d.arrange === 'nested') { - var _position = d.subcats.indexOf(d.key); - var offset = _position - ? _this.x.rangeBand() / (d.subcats.length * 0.75) / _position - : _this.x.rangeBand(); - return _this.x(d.values.x) + (_this.x.rangeBand() - offset) / 2; - } else { - position = d.subcats.indexOf(d.key); - return ( - _this.x(d.values.x) + _this.x.rangeBand() / d.subcats.length * position - ); - } - }) - .attr('y', function(d) { - if (d.arrange !== 'stacked') { - return _this.y(d.values.y); - } else { - return _this.y(d.values.start); - } - }) - .attr('width', function(d) { - if (!d.arrange || d.arrange === 'stacked') { - return _this.x.rangeBand(); - } else if (d.arrange === 'nested') { - var position = d.subcats.indexOf(d.key); - return position - ? _this.x.rangeBand() / (d.subcats.length * 0.75) / position - : _this.x.rangeBand(); - } else { - return _this.x.rangeBand() / d.subcats.length; - } - }) - .attr('height', function(d) { - return _this.y(0) - _this.y(d.values.y); - }); + barsTrans.attr('x', function (d) { + var position = void 0; + if (!d.arrange || d.arrange === 'stacked') { + return _this.x(d.values.x); + } else if (d.arrange === 'nested') { + var _position = d.subcats.indexOf(d.key); + var offset = _position ? _this.x.rangeBand() / (d.subcats.length * 0.75) / _position : _this.x.rangeBand(); + return _this.x(d.values.x) + (_this.x.rangeBand() - offset) / 2; + } else { + position = d.subcats.indexOf(d.key); + return _this.x(d.values.x) + _this.x.rangeBand() / d.subcats.length * position; + } + }).attr('y', function (d) { + if (d.arrange !== 'stacked') { + return _this.y(d.values.y); + } else { + return _this.y(d.values.start); + } + }).attr('width', function (d) { + if (!d.arrange || d.arrange === 'stacked') { + return _this.x.rangeBand(); + } else if (d.arrange === 'nested') { + var position = d.subcats.indexOf(d.key); + return position ? _this.x.rangeBand() / (d.subcats.length * 0.75) / position : _this.x.rangeBand(); + } else { + return _this.x.rangeBand() / d.subcats.length; + } + }).attr('height', function (d) { + return _this.y(0) - _this.y(d.values.y); + }); } else if (config.y.type === 'ordinal') { oldBarsTrans.attr('x', this.x(0)).attr('width', 0); oldBarGroupsTrans.remove(); - nu_bar_groups = bar_groups.enter().append('g').attr('class', function(d) { + nu_bar_groups = bar_groups.enter().append('g').attr('class', function (d) { return 'bar-group ' + d.key; }); nu_bar_groups.append('title'); - bars = bar_groups.selectAll('rect').data( - function(d) { - return d.values instanceof Array - ? d.values.sort(function(a, b) { - return ( - _this.colorScale.domain().indexOf(b.key) - - _this.colorScale.domain().indexOf(a.key) - ); - }) - : [d]; - }, - function(d) { - return d.key; - } - ); + bars = bar_groups.selectAll('rect').data(function (d) { + return d.values instanceof Array ? d.values.sort(function (a, b) { + return _this.colorScale.domain().indexOf(b.key) - _this.colorScale.domain().indexOf(a.key); + }) : [d]; + }, function (d) { + return d.key; + }); var _exitBars = config.transitions ? bars.exit().transition() : bars.exit(); _exitBars.attr('x', this.x(0)).attr('width', 0).remove(); - bars - .enter() - .append('rect') - .attr('class', function(d) { - return 'wc-data-mark bar ' + d.key; - }) - .style('clip-path', 'url(#' + chart.id + ')') - .attr('x', this.x(0)) - .attr('width', 0) - .append('title'); - - bars - .attr('shape-rendering', 'crispEdges') - .attr('stroke', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }) - .attr('fill', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); + bars.enter().append('rect').attr('class', function (d) { + return 'wc-data-mark bar ' + d.key; + }).style('clip-path', 'url(#' + chart.id + ')').attr('x', this.x(0)).attr('width', 0).append('title'); + + bars.attr('shape-rendering', 'crispEdges').attr('stroke', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }).attr('fill', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); - bars.each(function(d) { + bars.each(function (d) { var mark = d3.select(this.parentNode.parentNode).datum(); - d.arrange = mark.split && mark.arrange - ? mark.arrange - : mark.split ? 'grouped' : null; - d.subcats = config.legend.order - ? config.legend.order.slice().reverse() - : mark.values && mark.values[mark.split] - ? mark.values[mark.split] - : d3 - .set( - rawData.map(function(m) { - return m[mark.split]; - }) - ) - .values(); + d.arrange = mark.split && mark.arrange ? mark.arrange : mark.split ? 'grouped' : null; + d.subcats = config.legend.order ? config.legend.order.slice().reverse() : mark.values && mark.values[mark.split] ? mark.values[mark.split] : d3.set(rawData.map(function (m) { + return m[mark.split]; + })).values(); d.tooltip = mark.tooltip; d3.select(this).attr(mark.attributes); }); - var _xformat = config.marks - .map(function(m) { - return m.summarizeX === 'percent'; - }) - .indexOf(true) > -1 - ? d3.format('0%') - : d3.format(config.x.format); - var _yformat = config.marks - .map(function(m) { - return m.summarizeY === 'percent'; - }) - .indexOf(true) > -1 - ? d3.format('0%') - : d3.format(config.y.format); - bars.select('title').text(function(d) { + var _xformat = config.marks.map(function (m) { + return m.summarizeX === 'percent'; + }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.x.format); + var _yformat = config.marks.map(function (m) { + return m.summarizeY === 'percent'; + }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.y.format); + bars.select('title').text(function (d) { var tt = d.tooltip || ''; - return tt - .replace(/\$x/g, _xformat(d.values.x)) - .replace(/\$y/g, _yformat(d.values.y)) - .replace(/\[(.+?)\]/g, function(str, orig) { - return d.values.raw[0][orig]; - }); + return tt.replace(/\$x/g, _xformat(d.values.x)).replace(/\$y/g, _yformat(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { + return d.values.raw[0][orig]; + }); }); var _barsTrans = config.transitions ? bars.transition() : bars; - _barsTrans - .attr('x', function(d) { - if (d.arrange === 'stacked' || !d.arrange) { - return d.values.start !== undefined ? _this.x(d.values.start) : _this.x(0); - } else { - return _this.x(0); - } - }) - .attr('y', function(d) { - if (d.arrange === 'nested') { - var position = d.subcats.indexOf(d.key); - var offset = position - ? _this.y.rangeBand() / (d.subcats.length * 0.75) / position - : _this.y.rangeBand(); - return _this.y(d.values.y) + (_this.y.rangeBand() - offset) / 2; - } else if (d.arrange === 'grouped') { - var _position2 = d.subcats.indexOf(d.key); - return ( - _this.y(d.values.y) + - _this.y.rangeBand() / d.subcats.length * _position2 - ); - } else { - return _this.y(d.values.y); - } - }) - .attr('width', function(d) { - return _this.x(d.values.x) - _this.x(0); - }) - .attr('height', function(d) { - if (config.y.type === 'quantile') { - return 20; - } else if (d.arrange === 'nested') { - var position = d.subcats.indexOf(d.key); - return position - ? _this.y.rangeBand() / (d.subcats.length * 0.75) / position - : _this.y.rangeBand(); - } else if (d.arrange === 'grouped') { - return _this.y.rangeBand() / d.subcats.length; - } else { - return _this.y.rangeBand(); - } - }); + _barsTrans.attr('x', function (d) { + if (d.arrange === 'stacked' || !d.arrange) { + return d.values.start !== undefined ? _this.x(d.values.start) : _this.x(0); + } else { + return _this.x(0); + } + }).attr('y', function (d) { + if (d.arrange === 'nested') { + var position = d.subcats.indexOf(d.key); + var offset = position ? _this.y.rangeBand() / (d.subcats.length * 0.75) / position : _this.y.rangeBand(); + return _this.y(d.values.y) + (_this.y.rangeBand() - offset) / 2; + } else if (d.arrange === 'grouped') { + var _position2 = d.subcats.indexOf(d.key); + return _this.y(d.values.y) + _this.y.rangeBand() / d.subcats.length * _position2; + } else { + return _this.y(d.values.y); + } + }).attr('width', function (d) { + return _this.x(d.values.x) - _this.x(0); + }).attr('height', function (d) { + if (config.y.type === 'quantile') { + return 20; + } else if (d.arrange === 'nested') { + var position = d.subcats.indexOf(d.key); + return position ? _this.y.rangeBand() / (d.subcats.length * 0.75) / position : _this.y.rangeBand(); + } else if (d.arrange === 'grouped') { + return _this.y.rangeBand() / d.subcats.length; + } else { + return _this.y.rangeBand(); + } + }); } else if (['linear', 'log'].indexOf(config.x.type) > -1 && config.x.bin) { oldBarsTrans.attr('y', this.y(0)).attr('height', 0); oldBarGroupsTrans.remove(); - nu_bar_groups = bar_groups.enter().append('g').attr('class', function(d) { + nu_bar_groups = bar_groups.enter().append('g').attr('class', function (d) { return 'bar-group ' + d.key; }); nu_bar_groups.append('title'); - bars = bar_groups.selectAll('rect').data( - function(d) { - return d.values instanceof Array ? d.values : [d]; - }, - function(d) { - return d.key; - } - ); + bars = bar_groups.selectAll('rect').data(function (d) { + return d.values instanceof Array ? d.values : [d]; + }, function (d) { + return d.key; + }); var _exitBars2 = config.transitions ? bars.exit().transition() : bars.exit(); _exitBars2.attr('y', this.y(0)).attr('height', 0).remove(); - bars - .enter() - .append('rect') - .attr('class', function(d) { - return 'wc-data-mark bar ' + d.key; - }) - .style('clip-path', 'url(#' + chart.id + ')') - .attr('y', this.y(0)) - .attr('height', 0) - .append('title'); - - bars - .attr('shape-rendering', 'crispEdges') - .attr('stroke', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }) - .attr('fill', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); + bars.enter().append('rect').attr('class', function (d) { + return 'wc-data-mark bar ' + d.key; + }).style('clip-path', 'url(#' + chart.id + ')').attr('y', this.y(0)).attr('height', 0).append('title'); + + bars.attr('shape-rendering', 'crispEdges').attr('stroke', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }).attr('fill', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); - bars.each(function(d) { + bars.each(function (d) { var mark = d3.select(this.parentNode.parentNode).datum(); d.arrange = mark.split ? mark.arrange : null; - d.subcats = config.legend.order - ? config.legend.order.slice().reverse() - : mark.values && mark.values[mark.split] - ? mark.values[mark.split] - : d3 - .set( - rawData.map(function(m) { - return m[mark.split]; - }) - ) - .values(); + d.subcats = config.legend.order ? config.legend.order.slice().reverse() : mark.values && mark.values[mark.split] ? mark.values[mark.split] : d3.set(rawData.map(function (m) { + return m[mark.split]; + })).values(); d3.select(this).attr(mark.attributes); var parent = d3.select(this.parentNode).datum(); - var rangeSet = parent.key.split(',').map(function(m) { + var rangeSet = parent.key.split(',').map(function (m) { return +m; }); d.rangeLow = d3.min(rangeSet); @@ -2196,108 +1503,68 @@ d.tooltip = mark.tooltip; }); - var _xformat2 = config.marks - .map(function(m) { - return m.summarizeX === 'percent'; - }) - .indexOf(true) > -1 - ? d3.format('0%') - : d3.format(config.x.format); - var _yformat2 = config.marks - .map(function(m) { - return m.summarizeY === 'percent'; - }) - .indexOf(true) > -1 - ? d3.format('0%') - : d3.format(config.y.format); - bars.select('title').text(function(d) { + var _xformat2 = config.marks.map(function (m) { + return m.summarizeX === 'percent'; + }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.x.format); + var _yformat2 = config.marks.map(function (m) { + return m.summarizeY === 'percent'; + }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.y.format); + bars.select('title').text(function (d) { var tt = d.tooltip || ''; - return tt - .replace(/\$x/g, _xformat2(d.values.x)) - .replace(/\$y/g, _yformat2(d.values.y)) - .replace(/\[(.+?)\]/g, function(str, orig) { - return d.values.raw[0][orig]; - }); + return tt.replace(/\$x/g, _xformat2(d.values.x)).replace(/\$y/g, _yformat2(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { + return d.values.raw[0][orig]; + }); }); var _barsTrans2 = config.transitions ? bars.transition() : bars; - _barsTrans2 - .attr('x', function(d) { - return _this.x(d.rangeLow); - }) - .attr('y', function(d) { - if (d.arrange !== 'stacked') { - return _this.y(d.values.y); - } else { - return _this.y(d.values.start); - } - }) - .attr('width', function(d) { - return _this.x(d.rangeHigh) - _this.x(d.rangeLow); - }) - .attr('height', function(d) { - return _this.y(0) - _this.y(d.values.y); - }); - } else if ( - ['linear', 'log'].indexOf(config.y.type) > -1 && - config.y.type === 'linear' && - config.y.bin - ) { + _barsTrans2.attr('x', function (d) { + return _this.x(d.rangeLow); + }).attr('y', function (d) { + if (d.arrange !== 'stacked') { + return _this.y(d.values.y); + } else { + return _this.y(d.values.start); + } + }).attr('width', function (d) { + return _this.x(d.rangeHigh) - _this.x(d.rangeLow); + }).attr('height', function (d) { + return _this.y(0) - _this.y(d.values.y); + }); + } else if (['linear', 'log'].indexOf(config.y.type) > -1 && config.y.type === 'linear' && config.y.bin) { oldBarsTrans.attr('x', this.x(0)).attr('width', 0); oldBarGroupsTrans.remove(); - nu_bar_groups = bar_groups.enter().append('g').attr('class', function(d) { + nu_bar_groups = bar_groups.enter().append('g').attr('class', function (d) { return 'bar-group ' + d.key; }); nu_bar_groups.append('title'); - bars = bar_groups.selectAll('rect').data( - function(d) { - return d.values instanceof Array ? d.values : [d]; - }, - function(d) { - return d.key; - } - ); + bars = bar_groups.selectAll('rect').data(function (d) { + return d.values instanceof Array ? d.values : [d]; + }, function (d) { + return d.key; + }); var _exitBars3 = config.transitions ? bars.exit().transition() : bars.exit(); _exitBars3.attr('x', this.x(0)).attr('width', 0).remove(); - bars - .enter() - .append('rect') - .attr('class', function(d) { - return 'wc-data-mark bar ' + d.key; - }) - .style('clip-path', 'url(#' + chart.id + ')') - .attr('x', this.x(0)) - .attr('width', 0) - .append('title'); - - bars - .attr('shape-rendering', 'crispEdges') - .attr('stroke', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }) - .attr('fill', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); + bars.enter().append('rect').attr('class', function (d) { + return 'wc-data-mark bar ' + d.key; + }).style('clip-path', 'url(#' + chart.id + ')').attr('x', this.x(0)).attr('width', 0).append('title'); - bars.each(function(d) { + bars.attr('shape-rendering', 'crispEdges').attr('stroke', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }).attr('fill', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); + + bars.each(function (d) { var mark = d3.select(this.parentNode.parentNode).datum(); d.arrange = mark.split ? mark.arrange : null; - d.subcats = config.legend.order - ? config.legend.order.slice().reverse() - : mark.values && mark.values[mark.split] - ? mark.values[mark.split] - : d3 - .set( - rawData.map(function(m) { - return m[mark.split]; - }) - ) - .values(); + d.subcats = config.legend.order ? config.legend.order.slice().reverse() : mark.values && mark.values[mark.split] ? mark.values[mark.split] : d3.set(rawData.map(function (m) { + return m[mark.split]; + })).values(); var parent = d3.select(this.parentNode).datum(); - var rangeSet = parent.key.split(',').map(function(m) { + var rangeSet = parent.key.split(',').map(function (m) { return +m; }); d.rangeLow = d3.min(rangeSet); @@ -2305,48 +1572,33 @@ d.tooltip = mark.tooltip; }); - var _xformat3 = config.marks - .map(function(m) { - return m.summarizeX === 'percent'; - }) - .indexOf(true) > -1 - ? d3.format('0%') - : d3.format(config.x.format); - var _yformat3 = config.marks - .map(function(m) { - return m.summarizeY === 'percent'; - }) - .indexOf(true) > -1 - ? d3.format('0%') - : d3.format(config.y.format); - bars.select('title').text(function(d) { + var _xformat3 = config.marks.map(function (m) { + return m.summarizeX === 'percent'; + }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.x.format); + var _yformat3 = config.marks.map(function (m) { + return m.summarizeY === 'percent'; + }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.y.format); + bars.select('title').text(function (d) { var tt = d.tooltip || ''; - return tt - .replace(/\$x/g, _xformat3(d.values.x)) - .replace(/\$y/g, _yformat3(d.values.y)) - .replace(/\[(.+?)\]/g, function(str, orig) { - return d.values.raw[0][orig]; - }); + return tt.replace(/\$x/g, _xformat3(d.values.x)).replace(/\$y/g, _yformat3(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { + return d.values.raw[0][orig]; + }); }); var _barsTrans3 = config.transitions ? bars.transition() : bars; - _barsTrans3 - .attr('x', function(d) { - if (d.arrange === 'stacked') { - return _this.x(d.values.start); - } else { - return _this.x(0); - } - }) - .attr('y', function(d) { - return _this.y(d.rangeHigh); - }) - .attr('width', function(d) { - return _this.x(d.values.x); - }) - .attr('height', function(d) { - return _this.y(d.rangeLow) - _this.y(d.rangeHigh); - }); + _barsTrans3.attr('x', function (d) { + if (d.arrange === 'stacked') { + return _this.x(d.values.start); + } else { + return _this.x(0); + } + }).attr('y', function (d) { + return _this.y(d.rangeHigh); + }).attr('width', function (d) { + return _this.x(d.values.x); + }).attr('height', function (d) { + return _this.y(d.rangeLow) - _this.y(d.rangeHigh); + }); } else { oldBarsTrans.attr('y', this.y(0)).attr('height', 0); oldBarGroupsTrans.remove(); @@ -2354,7 +1606,7 @@ } //Link to the d3.selection from the data - bar_supergroups.each(function(d) { + bar_supergroups.each(function (d) { d.supergroup = d3.select(this); d.groups = d.supergroup.selectAll('.bar-group'); }); @@ -2365,92 +1617,59 @@ var chart = this; var config = this.config; - var line = d3.svg - .line() - .interpolate(config.interpolate) - .x(function(d) { - return config.x.type === 'linear' || config.x.type == 'log' - ? _this.x(+d.values.x) - : config.x.type === 'time' - ? _this.x(new Date(d.values.x)) - : _this.x(d.values.x) + _this.x.rangeBand() / 2; - }) - .y(function(d) { - return config.y.type === 'linear' || config.y.type == 'log' - ? _this.y(+d.values.y) - : config.y.type === 'time' - ? _this.y(new Date(d.values.y)) - : _this.y(d.values.y) + _this.y.rangeBand() / 2; - }); + var line = d3.svg.line().interpolate(config.interpolate).x(function (d) { + return config.x.type === 'linear' || config.x.type == 'log' ? _this.x(+d.values.x) : config.x.type === 'time' ? _this.x(new Date(d.values.x)) : _this.x(d.values.x) + _this.x.rangeBand() / 2; + }).y(function (d) { + return config.y.type === 'linear' || config.y.type == 'log' ? _this.y(+d.values.y) : config.y.type === 'time' ? _this.y(new Date(d.values.y)) : _this.y(d.values.y) + _this.y.rangeBand() / 2; + }); - var line_supergroups = this.svg.selectAll('.line-supergroup').data(marks, function(d, i) { + var line_supergroups = this.svg.selectAll('.line-supergroup').data(marks, function (d, i) { return i + '-' + d.per.join('-'); }); - line_supergroups.enter().append('g').attr('class', function(d) { + line_supergroups.enter().append('g').attr('class', function (d) { return 'supergroup line-supergroup ' + d.id; }); line_supergroups.exit().remove(); - var line_grps = line_supergroups.selectAll('.line').data( - function(d) { - return d.data; - }, - function(d) { - return d.key; - } - ); + var line_grps = line_supergroups.selectAll('.line').data(function (d) { + return d.data; + }, function (d) { + return d.key; + }); line_grps.exit().remove(); - var nu_line_grps = line_grps.enter().append('g').attr('class', function(d) { + var nu_line_grps = line_grps.enter().append('g').attr('class', function (d) { return d.key + ' line'; }); nu_line_grps.append('path'); nu_line_grps.append('title'); - var linePaths = line_grps - .select('path') - .attr('class', 'wc-data-mark') - .style('clip-path', 'url(#' + chart.id + ')') - .datum(function(d) { - return d.values; - }) - .attr('stroke', function(d) { - return _this.colorScale(d[0].values.raw[0][config.color_by]); - }) - .attr( - 'stroke-width', - config.stroke_width ? config.stroke_width : config.flex_stroke_width - ) - .attr('stroke-linecap', 'round') - .attr('fill', 'none'); + var linePaths = line_grps.select('path').attr('class', 'wc-data-mark').style('clip-path', 'url(#' + chart.id + ')').datum(function (d) { + return d.values; + }).attr('stroke', function (d) { + return _this.colorScale(d[0].values.raw[0][config.color_by]); + }).attr('stroke-width', config.stroke_width ? config.stroke_width : config.flex_stroke_width).attr('stroke-linecap', 'round').attr('fill', 'none'); var linePathsTrans = config.transitions ? linePaths.transition() : linePaths; linePathsTrans.attr('d', line); - line_grps.each(function(d) { + line_grps.each(function (d) { var mark = d3.select(this.parentNode).datum(); d.tooltip = mark.tooltip; d3.select(this).select('path').attr(mark.attributes); }); - line_grps.select('title').text(function(d) { + line_grps.select('title').text(function (d) { var tt = d.tooltip || ''; - var xformat = config.x.summary === 'percent' - ? d3.format('0%') - : d3.format(config.x.format); - var yformat = config.y.summary === 'percent' - ? d3.format('0%') - : d3.format(config.y.format); - return tt - .replace(/\$x/g, xformat(d.values.x)) - .replace(/\$y/g, yformat(d.values.y)) - .replace(/\[(.+?)\]/g, function(str, orig) { - return d.values[0].values.raw[0][orig]; - }); + var xformat = config.x.summary === 'percent' ? d3.format('0%') : d3.format(config.x.format); + var yformat = config.y.summary === 'percent' ? d3.format('0%') : d3.format(config.y.format); + return tt.replace(/\$x/g, xformat(d.values.x)).replace(/\$y/g, yformat(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { + return d.values[0].values.raw[0][orig]; + }); }); //Link to the d3.selection from the data - line_supergroups.each(function(d) { + line_supergroups.each(function (d) { d.supergroup = d3.select(this); d.groups = d.supergroup.selectAll('g.line'); d.paths = d.groups.select('path'); @@ -2464,104 +1683,69 @@ var chart = this; var config = this.config; - var point_supergroups = this.svg.selectAll('.point-supergroup').data(marks, function(d, i) { + var point_supergroups = this.svg.selectAll('.point-supergroup').data(marks, function (d, i) { return i + '-' + d.per.join('-'); }); - point_supergroups.enter().append('g').attr('class', function(d) { + point_supergroups.enter().append('g').attr('class', function (d) { return 'supergroup point-supergroup ' + d.id; }); point_supergroups.exit().remove(); - var points = point_supergroups.selectAll('.point').data( - function(d) { - return d.data; - }, - function(d) { - return d.key; - } - ); + var points = point_supergroups.selectAll('.point').data(function (d) { + return d.data; + }, function (d) { + return d.key; + }); var oldPoints = points.exit(); - var oldPointsTrans = config.transitions - ? oldPoints.selectAll('circle').transition() - : oldPoints.selectAll('circle'); + var oldPointsTrans = config.transitions ? oldPoints.selectAll('circle').transition() : oldPoints.selectAll('circle'); oldPointsTrans.attr('r', 0); var oldPointGroupTrans = config.transitions ? oldPoints.transition() : oldPoints; oldPointGroupTrans.remove(); - var nupoints = points.enter().append('g').attr('class', function(d) { + var nupoints = points.enter().append('g').attr('class', function (d) { return d.key + ' point'; }); nupoints.append('circle').attr('class', 'wc-data-mark').attr('r', 0); nupoints.append('title'); //static attributes - points - .select('circle') - .style('clip-path', 'url(#' + chart.id + ')') - .attr( - 'fill-opacity', - config.fill_opacity || config.fill_opacity === 0 ? config.fill_opacity : 0.6 - ) - .attr('fill', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }) - .attr('stroke', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); + points.select('circle').style('clip-path', 'url(#' + chart.id + ')').attr('fill-opacity', config.fill_opacity || config.fill_opacity === 0 ? config.fill_opacity : 0.6).attr('fill', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }).attr('stroke', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); //attach mark info - points.each(function(d) { + points.each(function (d) { var mark = d3.select(this.parentNode).datum(); d.mark = mark; d3.select(this).select('circle').attr(mark.attributes); }); //animated attributes - var pointsTrans = config.transitions - ? points.select('circle').transition() - : points.select('circle'); - pointsTrans - .attr('r', function(d) { - return d.mark.radius || config.flex_point_size; - }) - .attr('cx', function(d) { - var x_pos = _this.x(d.values.x) || 0; - return config.x.type === 'ordinal' ? x_pos + _this.x.rangeBand() / 2 : x_pos; - }) - .attr('cy', function(d) { - var y_pos = _this.y(d.values.y) || 0; - return config.y.type === 'ordinal' ? y_pos + _this.y.rangeBand() / 2 : y_pos; - }); + var pointsTrans = config.transitions ? points.select('circle').transition() : points.select('circle'); + pointsTrans.attr('r', function (d) { + return d.mark.radius || config.flex_point_size; + }).attr('cx', function (d) { + var x_pos = _this.x(d.values.x) || 0; + return config.x.type === 'ordinal' ? x_pos + _this.x.rangeBand() / 2 : x_pos; + }).attr('cy', function (d) { + var y_pos = _this.y(d.values.y) || 0; + return config.y.type === 'ordinal' ? y_pos + _this.y.rangeBand() / 2 : y_pos; + }); - points.select('title').text(function(d) { + points.select('title').text(function (d) { var tt = d.mark.tooltip || ''; - var xformat = config.x.summary === 'percent' - ? d3.format('0%') - : config.x.type === 'time' - ? d3.time.format(config.x.format) - : d3.format(config.x.format); - var yformat = config.y.summary === 'percent' - ? d3.format('0%') - : config.y.type === 'time' - ? d3.time.format(config.y.format) - : d3.format(config.y.format); - return tt - .replace( - /\$x/g, - config.x.type === 'time' ? xformat(new Date(d.values.x)) : xformat(d.values.x) - ) - .replace( - /\$y/g, - config.y.type === 'time' ? yformat(new Date(d.values.y)) : yformat(d.values.y) - ) - .replace(/\[(.+?)\]/g, function(str, orig) { - return d.values.raw[0][orig]; - }); + var xformat = config.x.summary === 'percent' ? d3.format('0%') : config.x.type === 'time' ? d3.time.format(config.x.format) : d3.format(config.x.format); + var yformat = config.y.summary === 'percent' ? d3.format('0%') : config.y.type === 'time' ? d3.time.format(config.y.format) : d3.format(config.y.format); + return tt.replace(/\$x/g, config.x.type === 'time' ? xformat(new Date(d.values.x)) : xformat(d.values.x)).replace(/\$y/g, config.y.type === 'time' ? yformat(new Date(d.values.y)) : yformat(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { + return d.values.raw[0][orig]; + }); }); //Link to the d3.selection from the data - point_supergroups.each(function(d) { + point_supergroups.each(function (d) { d.supergroup = d3.select(this); d.groups = d.supergroup.selectAll('g.point'); d.circles = d.groups.select('circle'); @@ -2576,24 +1760,21 @@ var chart = this; var config = this.config; - var textSupergroups = this.svg.selectAll('.text-supergroup').data(marks, function(d, i) { + var textSupergroups = this.svg.selectAll('.text-supergroup').data(marks, function (d, i) { return i + '-' + d.per.join('-'); }); - textSupergroups.enter().append('g').attr('class', function(d) { + textSupergroups.enter().append('g').attr('class', function (d) { return 'supergroup text-supergroup ' + d.id; }); textSupergroups.exit().remove(); - var texts = textSupergroups.selectAll('.text').data( - function(d) { - return d.data; - }, - function(d) { - return d.key; - } - ); + var texts = textSupergroups.selectAll('.text').data(function (d) { + return d.data; + }, function (d) { + return d.key; + }); var oldTexts = texts.exit(); // don't need to transition position of outgoing text @@ -2602,7 +1783,7 @@ var oldTextGroupTrans = config.transitions ? oldTexts.transition() : oldTexts; oldTextGroupTrans.remove(); - var nutexts = texts.enter().append('g').attr('class', function(d) { + var nutexts = texts.enter().append('g').attr('class', function (d) { return d.key + ' text'; }); nutexts.append('text').attr('class', 'wc-data-mark'); @@ -2616,46 +1797,25 @@ texts.each(attachMarks); // parse text like tooltips - texts.select('text').style('clip-path', 'url(#' + chart.id + ')').text(function(d) { + texts.select('text').style('clip-path', 'url(#' + chart.id + ')').text(function (d) { var tt = d.mark.text || ''; - var xformat = config.x.summary === 'percent' - ? d3.format('0%') - : config.x.type === 'time' - ? d3.time.format(config.x.format) - : d3.format(config.x.format); - var yformat = config.y.summary === 'percent' - ? d3.format('0%') - : config.y.type === 'time' - ? d3.time.format(config.y.format) - : d3.format(config.y.format); - return tt - .replace( - /\$x/g, - config.x.type === 'time' ? xformat(new Date(d.values.x)) : xformat(d.values.x) - ) - .replace( - /\$y/g, - config.y.type === 'time' ? yformat(new Date(d.values.y)) : yformat(d.values.y) - ) - .replace(/\[(.+?)\]/g, function(str, orig) { - return d.values.raw[0][orig]; - }); + var xformat = config.x.summary === 'percent' ? d3.format('0%') : config.x.type === 'time' ? d3.time.format(config.x.format) : d3.format(config.x.format); + var yformat = config.y.summary === 'percent' ? d3.format('0%') : config.y.type === 'time' ? d3.time.format(config.y.format) : d3.format(config.y.format); + return tt.replace(/\$x/g, config.x.type === 'time' ? xformat(new Date(d.values.x)) : xformat(d.values.x)).replace(/\$y/g, config.y.type === 'time' ? yformat(new Date(d.values.y)) : yformat(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { + return d.values.raw[0][orig]; + }); }); // animated attributes - var textsTrans = config.transitions - ? texts.select('text').transition() - : texts.select('text'); - textsTrans - .attr('x', function(d) { - var xPos = _this.x(d.values.x) || 0; - return config.x.type === 'ordinal' ? xPos + _this.x.rangeBand() / 2 : xPos; - }) - .attr('y', function(d) { - var yPos = _this.y(d.values.y) || 0; - return config.y.type === 'ordinal' ? yPos + _this.y.rangeBand() / 2 : yPos; - }); + var textsTrans = config.transitions ? texts.select('text').transition() : texts.select('text'); + textsTrans.attr('x', function (d) { + var xPos = _this.x(d.values.x) || 0; + return config.x.type === 'ordinal' ? xPos + _this.x.rangeBand() / 2 : xPos; + }).attr('y', function (d) { + var yPos = _this.y(d.values.y) || 0; + return config.y.type === 'ordinal' ? yPos + _this.y.rangeBand() / 2 : yPos; + }); //add a reference to the selection from it's data - textSupergroups.each(function(d) { + textSupergroups.each(function (d) { d.supergroup = d3.select(this); d.groups = d.supergroup.selectAll('g.text'); d.texts = d.groups.select('text'); @@ -2664,9 +1824,7 @@ } function destroy() { - var destroyControls = arguments.length > 0 && arguments[0] !== undefined - ? arguments[0] - : true; + var destroyControls = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; //run onDestroy callback this.events.onDestroy.call(this); @@ -2747,16 +1905,8 @@ onDestroy: function onDestroy() {} }; - thisChart.on = function(event, callback) { - var possible_events = [ - 'init', - 'layout', - 'preprocess', - 'datatransform', - 'draw', - 'resize', - 'destroy' - ]; + thisChart.on = function (event, callback) { + var possible_events = ['init', 'layout', 'preprocess', 'datatransform', 'draw', 'resize', 'destroy']; if (possible_events.indexOf(event) < 0) { return; } @@ -2776,9 +1926,9 @@ function changeOption(option, value, callback, draw) { var _this = this; - this.targets.forEach(function(target) { + this.targets.forEach(function (target) { if (option instanceof Array) { - option.forEach(function(o) { + option.forEach(function (o) { return _this.stringAccessor(target.config, o, value); }); } else { @@ -2797,13 +1947,8 @@ var colNames = d3.keys(dataset[0]); - this.config.inputs.forEach(function(input, i) { - if (input.type === 'subsetter' && colNames.indexOf(input.value_col) === -1) - throw new Error( - 'Error in settings object: the value "' + - input.value_col + - '" does not match any column in the provided dataset.' - ); + this.config.inputs.forEach(function (input, i) { + if (input.type === 'subsetter' && colNames.indexOf(input.value_col) === -1) throw new Error('Error in settings object: the value "' + input.value_col + '" does not match any column in the provided dataset.'); //Draw the chart when a control changes unless the user specifies otherwise. input.draw = input.draw === undefined ? true : input.draw; @@ -2813,10 +1958,9 @@ function controlUpdate() { var _this = this; - if (this.config.inputs && this.config.inputs.length && this.config.inputs[0]) - this.config.inputs.forEach(function(input) { - return _this.makeControlItem(input); - }); + if (this.config.inputs && this.config.inputs.length && this.config.inputs[0]) this.config.inputs.forEach(function (input) { + return _this.makeControlItem(input); + }); } function destroy$1() { @@ -2837,21 +1981,13 @@ } function makeControlItem(control) { - var control_wrap = this.wrap - .append('div') - .attr('class', 'control-group') - .classed('inline', control.inline) - .datum(control); + var control_wrap = this.wrap.append('div').attr('class', 'control-group').classed('inline', control.inline).datum(control); //Add control label span. - var ctrl_label = control_wrap - .append('span') - .attr('class', 'wc-control-label') - .text(control.label); + var ctrl_label = control_wrap.append('span').attr('class', 'wc-control-label').text(control.label); //Add control _Required_ text to control label span. - if (control.required) - ctrl_label.append('span').attr('class', 'label label-required').text('Required'); + if (control.required) ctrl_label.append('span').attr('class', 'label label-required').text('Required'); //Add control description span. control_wrap.append('span').attr('class', 'span-description').text(control.description); @@ -2873,9 +2009,7 @@ } else if (control.type === 'subsetter') { this.makeSubsetterControl(control, control_wrap); } else { - throw new Error( - 'Each control must have a type! Choose from: "text", "number", "list", "dropdown", "btngroup", "checkbox", "radio", or "subsetter".' - ); + throw new Error('Each control must have a type! Choose from: "text", "number", "list", "dropdown", "btngroup", "checkbox", "radio", or "subsetter".'); } } @@ -2886,21 +2020,14 @@ var btn_wrap = control_wrap.append('div').attr('class', 'btn-group'); - var changers = btn_wrap - .selectAll('button') - .data(option_data) - .enter() - .append('button') - .attr('class', 'btn btn-default btn-sm') - .text(function(d) { - return d; - }) - .classed('btn-primary', function(d) { - return _this.stringAccessor(_this.targets[0].config, control.option) === d; - }); + var changers = btn_wrap.selectAll('button').data(option_data).enter().append('button').attr('class', 'btn btn-default btn-sm').text(function (d) { + return d; + }).classed('btn-primary', function (d) { + return _this.stringAccessor(_this.targets[0].config, control.option) === d; + }); - changers.on('click', function(d) { - changers.each(function(e) { + changers.on('click', function (d) { + changers.each(function (e) { d3.select(this).classed('btn-primary', e === d); }); _this.changeOption(control.option, d, control.callback, control.draw); @@ -2910,16 +2037,11 @@ function makeCheckboxControl(control, control_wrap) { var _this = this; - var changer = control_wrap - .append('input') - .attr('type', 'checkbox') - .attr('class', 'changer') - .datum(control) - .property('checked', function(d) { - return _this.stringAccessor(_this.targets[0].config, control.option); - }); + var changer = control_wrap.append('input').attr('type', 'checkbox').attr('class', 'changer').datum(control).property('checked', function (d) { + return _this.stringAccessor(_this.targets[0].config, control.option); + }); - changer.on('change', function(d) { + changer.on('change', function (d) { var value = changer.property('checked'); _this.changeOption(d.option, value, control.callback, control.draw); }); @@ -2929,54 +2051,33 @@ var _this = this; var mainOption = control.option || control.options[0]; - var changer = control_wrap - .append('select') - .attr('class', 'changer') - .attr('multiple', control.multiple ? true : null) - .datum(control); - - var opt_values = control.values && control.values instanceof Array - ? control.values - : control.values - ? d3 - .set( - this.data.map(function(m) { - return m[_this.targets[0].config[control.values]]; - }) - ) - .values() - : d3.keys(this.data[0]); + var changer = control_wrap.append('select').attr('class', 'changer').attr('multiple', control.multiple ? true : null).datum(control); + + var opt_values = control.values && control.values instanceof Array ? control.values : control.values ? d3.set(this.data.map(function (m) { + return m[_this.targets[0].config[control.values]]; + })).values() : d3.keys(this.data[0]); if (!control.require || control.none) { opt_values.unshift('None'); } - var options = changer - .selectAll('option') - .data(opt_values) - .enter() - .append('option') - .text(function(d) { - return d; - }) - .property('selected', function(d) { - return _this.stringAccessor(_this.targets[0].config, mainOption) === d; - }); + var options = changer.selectAll('option').data(opt_values).enter().append('option').text(function (d) { + return d; + }).property('selected', function (d) { + return _this.stringAccessor(_this.targets[0].config, mainOption) === d; + }); - changer.on('change', function(d) { + changer.on('change', function (d) { var value = changer.property('value') === 'None' ? null : changer.property('value'); if (control.multiple) { - value = options - .filter(function(f) { - return d3.select(this).property('selected'); - })[0] - .map(function(m) { - return d3.select(m).property('value'); - }) - .filter(function(f) { - return f !== 'None'; - }); + value = options.filter(function (f) { + return d3.select(this).property('selected'); + })[0].map(function (m) { + return d3.select(m).property('value'); + }).filter(function (f) { + return f !== 'None'; + }); } if (control.options) { @@ -2992,21 +2093,14 @@ function makeListControl(control, control_wrap) { var _this = this; - var changer = control_wrap - .append('input') - .attr('type', 'text') - .attr('class', 'changer') - .datum(control) - .property('value', function(d) { - return _this.stringAccessor(_this.targets[0].config, control.option); - }); + var changer = control_wrap.append('input').attr('type', 'text').attr('class', 'changer').datum(control).property('value', function (d) { + return _this.stringAccessor(_this.targets[0].config, control.option); + }); - changer.on('change', function(d) { - var value = changer.property('value') - ? changer.property('value').split(',').map(function(m) { - return m.trim(); - }) - : null; + changer.on('change', function (d) { + var value = changer.property('value') ? changer.property('value').split(',').map(function (m) { + return m.trim(); + }) : null; _this.changeOption(control.option, value, control.callback, control.draw); }); } @@ -3014,19 +2108,11 @@ function makeNumberControl(control, control_wrap) { var _this = this; - var changer = control_wrap - .append('input') - .attr('type', 'number') - .attr('min', control.min !== undefined ? control.min : 0) - .attr('max', control.max) - .attr('step', control.step || 1) - .attr('class', 'changer') - .datum(control) - .property('value', function(d) { - return _this.stringAccessor(_this.targets[0].config, control.option); - }); + var changer = control_wrap.append('input').attr('type', 'number').attr('min', control.min !== undefined ? control.min : 0).attr('max', control.max).attr('step', control.step || 1).attr('class', 'changer').datum(control).property('value', function (d) { + return _this.stringAccessor(_this.targets[0].config, control.option); + }); - changer.on('change', function(d) { + changer.on('change', function (d) { var value = +changer.property('value'); _this.changeOption(control.option, value, control.callback, control.draw); }); @@ -3035,29 +2121,17 @@ function makeRadioControl(control, control_wrap) { var _this = this; - var changers = control_wrap - .selectAll('label') - .data(control.values || d3.keys(this.data[0])) - .enter() - .append('label') - .attr('class', 'radio') - .text(function(d, i) { - return control.relabels ? control.relabels[i] : d; - }) - .append('input') - .attr('type', 'radio') - .attr('class', 'changer') - .attr('name', control.option.replace('.', '-') + '-' + this.targets[0].id) - .property('value', function(d) { - return d; - }) - .property('checked', function(d) { - return _this.stringAccessor(_this.targets[0].config, control.option) === d; - }); + var changers = control_wrap.selectAll('label').data(control.values || d3.keys(this.data[0])).enter().append('label').attr('class', 'radio').text(function (d, i) { + return control.relabels ? control.relabels[i] : d; + }).append('input').attr('type', 'radio').attr('class', 'changer').attr('name', control.option.replace('.', '-') + '-' + this.targets[0].id).property('value', function (d) { + return d; + }).property('checked', function (d) { + return _this.stringAccessor(_this.targets[0].config, control.option) === d; + }); - changers.on('change', function(d) { + changers.on('change', function (d) { var value = null; - changers.each(function(c) { + changers.each(function (c) { if (d3.select(this).property('checked')) { value = d3.select(this).property('value') === 'none' ? null : c; } @@ -3070,27 +2144,14 @@ var targets = this.targets; // associated charts and tables. //dropdown selection - var changer = control_wrap - .append('select') - .classed('changer', true) - .attr('multiple', control.multiple ? true : null) - .datum(control); + var changer = control_wrap.append('select').classed('changer', true).attr('multiple', control.multiple ? true : null).datum(control); //dropdown option data - var option_data = control.values - ? control.values - : d3 - .set( - this.data - .map(function(m) { - return m[control.value_col]; - }) - .filter(function(f) { - return f; - }) - ) - .values() - .sort(naturalSorter); // only sort when values are derived + var option_data = control.values ? control.values : d3.set(this.data.map(function (m) { + return m[control.value_col]; + }).filter(function (f) { + return f; + })).values().sort(naturalSorter); // only sort when values are derived //initial dropdown option control.start = control.start ? control.start : control.loose ? option_data[0] : null; @@ -3107,26 +2168,17 @@ control.loose = !control.loose && control.start ? true : control.loose; //dropdown options selection - var options = changer - .selectAll('option') - .data(option_data) - .enter() - .append('option') - .text(function(d) { - return d; - }) - .property('selected', function(d) { - return d === control.start; - }); + var options = changer.selectAll('option').data(option_data).enter().append('option').text(function (d) { + return d; + }).property('selected', function (d) { + return d === control.start; + }); //define filter object for each associated target - targets.forEach(function(e) { - var match = e.filters - .slice() - .map(function(m) { - return m.col === control.value_col; - }) - .indexOf(true); + targets.forEach(function (e) { + var match = e.filters.slice().map(function (m) { + return m.col === control.value_col; + }).indexOf(true); if (match > -1) { e.filters[match] = { col: control.value_col, @@ -3150,7 +2202,7 @@ function setSubsetter(target, obj) { var match = -1; - target.filters.forEach(function(e, i) { + target.filters.forEach(function (e, i) { if (e.col === obj.col) { match = i; } @@ -3161,15 +2213,13 @@ } //add event listener to control - changer.on('change', function(d) { + changer.on('change', function (d) { if (control.multiple) { - var values = options - .filter(function(f) { - return d3.select(this).property('selected'); - })[0] - .map(function(m) { - return d3.select(m).property('text'); - }); + var values = options.filter(function (f) { + return d3.select(this).property('selected'); + })[0].map(function (m) { + return d3.select(m).property('text'); + }); var new_filter = { col: control.value_col, @@ -3179,7 +2229,7 @@ loose: control.loose, all: control.all }; - targets.forEach(function(e) { + targets.forEach(function (e) { setSubsetter(e, new_filter); //call callback function if provided if (control.callback) { @@ -3198,7 +2248,7 @@ loose: control.loose, all: control.all }; - targets.forEach(function(e) { + targets.forEach(function (e) { setSubsetter(e, _new_filter); //call callback function if provided if (control.callback) { @@ -3213,16 +2263,11 @@ function makeTextControl(control, control_wrap) { var _this = this; - var changer = control_wrap - .append('input') - .attr('type', 'text') - .attr('class', 'changer') - .datum(control) - .property('value', function(d) { - return _this.stringAccessor(_this.targets[0].config, control.option); - }); + var changer = control_wrap.append('input').attr('type', 'text').attr('class', 'changer').datum(control).property('value', function (d) { + return _this.stringAccessor(_this.targets[0].config, control.option); + }); - changer.on('change', function(d) { + changer.on('change', function (d) { var value = changer.property('value'); _this.changeOption(control.option, value, control.callback, control.draw); }); @@ -3280,10 +2325,7 @@ if (config.location === 'bottom') { thisControls.wrap = d3.select(element).append('div').attr('class', 'wc-controls'); } else { - thisControls.wrap = d3 - .select(element) - .insert('div', ':first-child') - .attr('class', 'wc-controls'); + thisControls.wrap = d3.select(element).insert('div', ':first-child').attr('class', 'wc-controls'); } thisControls.wrap.datum(thisControls); @@ -3296,32 +2338,17 @@ //If there are filters, return a filtered data array of the raw data. //Otherwise return the raw data. - if ( - this.filters && - this.filters.some(function(filter) { - return ( - (typeof filter.val === 'string' && - !(filter.all === true && filter.index === 0)) || - (Array.isArray(filter.val) && filter.val.length < filter.choices.length) - ); - }) - ) { + if (this.filters && this.filters.some(function (filter) { + return typeof filter.val === 'string' && !(filter.all === true && filter.index === 0) || Array.isArray(filter.val) && filter.val.length < filter.choices.length; + })) { this.data.filtered = this.data.raw; - this.filters - .filter(function(filter) { - return ( - (typeof filter.val === 'string' && - !(filter.all === true && filter.index === 0)) || - (Array.isArray(filter.val) && filter.val.length < filter.choices.length) - ); - }) - .forEach(function(filter) { - _this.data.filtered = _this.data.filtered.filter(function(d) { - return Array.isArray(filter.val) - ? filter.val.indexOf(d[filter.col]) > -1 - : filter.val === d[filter.col]; - }); + this.filters.filter(function (filter) { + return typeof filter.val === 'string' && !(filter.all === true && filter.index === 0) || Array.isArray(filter.val) && filter.val.length < filter.choices.length; + }).forEach(function (filter) { + _this.data.filtered = _this.data.filtered.filter(function (d) { + return Array.isArray(filter.val) ? filter.val.indexOf(d[filter.col]) > -1 : filter.val === d[filter.col]; }); + }); } else this.data.filtered = this.data.raw; } @@ -3338,20 +2365,17 @@ if (this.searchable.searchTerm) { //Determine which rows contain input text. - this.data.searched = this.data.filtered.filter(function(d) { + this.data.searched = this.data.filtered.filter(function (d) { var match = false; - Object.keys(d) - .filter(function(key) { - return _this.config.cols.indexOf(key) > -1; - }) - .forEach(function(var_name) { - if (match === false) { - var cellText = '' + d[var_name]; - match = - cellText.toLowerCase().indexOf(_this.searchable.searchTerm) > -1; - } - }); + Object.keys(d).filter(function (key) { + return _this.config.cols.indexOf(key) > -1; + }).forEach(function (var_name) { + if (match === false) { + var cellText = '' + d[var_name]; + match = cellText.toLowerCase().indexOf(_this.searchable.searchTerm) > -1; + } + }); return match; }); @@ -3368,12 +2392,9 @@ \------------------------------------------------------------------------------------------------*/ // Warn if overriding existing method - if (Array.prototype.equals) - console.warn( - "Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code." - ); + if (Array.prototype.equals) console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code."); // attach the .equals method to Array's prototype to call it on any array - Array.prototype.equals = function(array) { + Array.prototype.equals = function (array) { // if the other array is a falsy value, return if (!array) return false; @@ -3397,7 +2418,7 @@ function checkFilters() { if (this.filters) { - this.currentFilters = this.filters.map(function(filter) { + this.currentFilters = this.filters.map(function (filter) { return filter.val; }); @@ -3415,24 +2436,19 @@ function updateTableHeaders() { var _this = this; - this.thead_cells = this.thead - .select('tr') - .selectAll('th') - .data(this.config.headers, function(d) { - return d; - }); + this.thead_cells = this.thead.select('tr').selectAll('th').data(this.config.headers, function (d) { + return d; + }); this.thead_cells.exit().remove(); this.thead_cells.enter().append('th'); - this.thead_cells - .sort(function(a, b) { - return _this.config.headers.indexOf(a) - _this.config.headers.indexOf(b); - }) - .attr('class', function(d) { - return _this.config.cols[_this.config.headers.indexOf(d)]; - }) // associate column header with column name - .text(function(d) { - return d; - }); + this.thead_cells.sort(function (a, b) { + return _this.config.headers.indexOf(a) - _this.config.headers.indexOf(b); + }).attr('class', function (d) { + return _this.config.cols[_this.config.headers.indexOf(d)]; + }) // associate column header with column name + .text(function (d) { + return d; + }); } function drawTableBody() { @@ -3444,77 +2460,51 @@ var rows = this.tbody.selectAll('tr').data(this.data.processing).enter().append('tr'); //Define table body cells. - var cells = rows.selectAll('td').data(function(d) { - return _this.config.cols.map(function(key) { + var cells = rows.selectAll('td').data(function (d) { + return _this.config.cols.map(function (key) { return { col: key, text: d[key] }; }); }); cells.exit().remove(); cells.enter().append('td'); - cells - .sort(function(a, b) { - return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); - }) - .attr('class', function(d) { - return d.col; - }) - .each(function(d) { - var cell = d3.select(this); - - //Apply text in data as html or as plain text. - if (table.config.as_html) { - cell.html(d.text); - } else { - cell.text(d.text); - } - }); + cells.sort(function (a, b) { + return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); + }).attr('class', function (d) { + return d.col; + }).each(function (d) { + var cell = d3.select(this); + + //Apply text in data as html or as plain text. + if (table.config.as_html) { + cell.html(d.text); + } else { + cell.text(d.text); + } + }); } function dynamicLayout() { var widths = { table: this.table.select('thead').node().offsetWidth, - top: - this.wrap.select('.table-top .searchable-container').node().offsetWidth + - this.wrap.select('.table-top .sortable-container').node().offsetWidth, - bottom: - this.wrap.select('.table-bottom .pagination-container').node().offsetWidth + - this.wrap.select('.table-bottom .exportable-container').node().offsetWidth + top: this.wrap.select('.table-top .searchable-container').node().offsetWidth + this.wrap.select('.table-top .sortable-container').node().offsetWidth, + bottom: this.wrap.select('.table-bottom .pagination-container').node().offsetWidth + this.wrap.select('.table-bottom .exportable-container').node().offsetWidth }; - if ( - widths.table < Math.max(widths.top, widths.bottom) && - this.config.layout === 'horizontal' - ) { + if (widths.table < Math.max(widths.top, widths.bottom) && this.config.layout === 'horizontal') { this.config.layout = 'vertical'; - this.wrap - .style('display', 'inline-block') - .selectAll('.table-top,.table-bottom') - .style('display', 'inline-block') - .selectAll('.interactivity') - .style({ - display: 'block', - clear: 'both' - }); - } else if ( - widths.table >= Math.max(widths.top, widths.bottom) && - this.config.layout === 'vertical' - ) { + this.wrap.style('display', 'inline-block').selectAll('.table-top,.table-bottom').style('display', 'inline-block').selectAll('.interactivity').style({ + display: 'block', + clear: 'both' + }); + } else if (widths.table >= Math.max(widths.top, widths.bottom) && this.config.layout === 'vertical') { this.config.layout = 'horizontal'; - this.wrap - .style('display', 'table') - .selectAll('.table-top,.table-bottom') - .style('display', 'block') - .selectAll('.interactivity') - .style({ - display: 'inline-block', - float: function float() { - return d3.select(this).classed('searchable-container') || - d3.select(this).classed('pagination-container') - ? 'right' - : null; - }, - clear: null - }); + this.wrap.style('display', 'table').selectAll('.table-top,.table-bottom').style('display', 'block').selectAll('.interactivity').style({ + display: 'inline-block', + float: function float() { + return d3.select(this).classed('searchable-container') || d3.select(this).classed('pagination-container') ? 'right' : null; + }, + clear: null + }); } } @@ -3529,8 +2519,7 @@ if (!passed_data) //Apply filters if data is not passed to table.draw(). - applyFilters.call(this); - else + applyFilters.call(this);else //Otherwise update data object. updateDataObject.call(this); @@ -3540,16 +2529,7 @@ //Filter data on search term if it exists and set data to searched data. applySearchTerm.call(this); - this.searchable.wrap - .select('.nNrecords') - .text( - this.data.processing.length === this.data.raw.length - ? this.data.raw.length + ' records displayed' - : this.data.processing.length + - '/' + - this.data.raw.length + - ' records displayed' - ); + this.searchable.wrap.select('.nNrecords').text(this.data.processing.length === this.data.raw.length ? this.data.raw.length + ' records displayed' : this.data.processing.length + '/' + this.data.raw.length + ' records displayed'); //Update table headers. updateTableHeaders.call(this); @@ -3559,35 +2539,27 @@ //Print a note that no data was selected for empty tables. if (this.data.processing.length === 0) { - this.tbody - .append('tr') - .classed('no-data', true) - .append('td') - .attr('colspan', this.config.cols.length) - .text('No data selected.'); + this.tbody.append('tr').classed('no-data', true).append('td').attr('colspan', this.config.cols.length).text('No data selected.'); //Bind table filtered/searched data to table container. this.data.current = this.data.processing; this.table.datum(this.table.current); //Add export. - if (this.config.exportable) - this.config.exports.forEach(function(fmt) { - _this.exportable.exports[fmt].call(_this, _this.data.processing); - }); + if (this.config.exportable) this.config.exports.forEach(function (fmt) { + _this.exportable.exports[fmt].call(_this, _this.data.processing); + }); //Add pagination. - if (this.config.pagination) - this.pagination.addPagination.call(this, this.data.processing); + if (this.config.pagination) this.pagination.addPagination.call(this, this.data.processing); } else { //Sort data. if (this.config.sortable) { - this.thead.selectAll('th').on('click', function(header) { + this.thead.selectAll('th').on('click', function (header) { table.sortable.onClick.call(table, this, header); }); - if (this.sortable.order.length) - this.sortable.sortData.call(this, this.data.processing); + if (this.sortable.order.length) this.sortable.sortData.call(this, this.data.processing); } //Bind table filtered/searched data to table container. @@ -3595,17 +2567,16 @@ this.table.datum(this.data.current); //Add export. - if (this.config.exportable) - this.config.exports.forEach(function(fmt) { - _this.exportable.exports[fmt].call(_this, _this.data.processing); - }); + if (this.config.exportable) this.config.exports.forEach(function (fmt) { + _this.exportable.exports[fmt].call(_this, _this.data.processing); + }); //Add pagination. if (this.config.pagination) { this.pagination.addPagination.call(this, this.data.processing); //Apply pagination. - this.data.processing = this.data.processing.filter(function(d, i) { + this.data.processing = this.data.processing.filter(function (d, i) { return _this.config.startIndex <= i && i < _this.config.endIndex; }); } @@ -3625,24 +2596,15 @@ function layout$2() { var context = this; - this.searchable.wrap = this.wrap - .select('.table-top') - .append('div') - .classed('interactivity searchable-container', true) - .classed('hidden', !this.config.searchable); + this.searchable.wrap = this.wrap.select('.table-top').append('div').classed('interactivity searchable-container', true).classed('hidden', !this.config.searchable); this.searchable.wrap.append('div').classed('search', true); - this.searchable.wrap - .select('.search') - .append('input') - .classed('search-box', true) - .attr('placeholder', 'Search') - .on('input', function() { - context.searchable.searchTerm = this.value.toLowerCase() || null; - context.config.activePage = 0; - context.config.startIndex = context.config.activePage * context.config.nRowsPerPage; // first row shown - context.config.endIndex = context.config.startIndex + context.config.nRowsPerPage; // last row shown - context.draw(); - }); + this.searchable.wrap.select('.search').append('input').classed('search-box', true).attr('placeholder', 'Search').on('input', function () { + context.searchable.searchTerm = this.value.toLowerCase() || null; + context.config.activePage = 0; + context.config.startIndex = context.config.activePage * context.config.nRowsPerPage; // first row shown + context.config.endIndex = context.config.startIndex + context.config.nRowsPerPage; // last row shown + context.draw(); + }); this.searchable.wrap.select('.search').append('span').classed('nNrecords', true); } @@ -3655,55 +2617,32 @@ function layout$3() { var _this = this; - this.exportable.wrap = this.wrap - .select('.table-bottom') - .append('div') - .classed('interactivity exportable-container', true) - .classed('hidden', !this.config.exportable); + this.exportable.wrap = this.wrap.select('.table-bottom').append('div').classed('interactivity exportable-container', true).classed('hidden', !this.config.exportable); this.exportable.wrap.append('span').text('Export:'); - if (this.config.exports && this.config.exports.length) - this.config.exports.forEach(function(fmt) { - _this.exportable.wrap - .append('a') - .classed('wc-button export', true) - .attr({ - id: fmt - }) - .style( - !_this.test && navigator.msSaveBlob - ? { - cursor: 'pointer', - 'text-decoration': 'underline', - color: 'blue' - } - : null - ) - .text(fmt.toUpperCase()); - }); + if (this.config.exports && this.config.exports.length) this.config.exports.forEach(function (fmt) { + _this.exportable.wrap.append('a').classed('wc-button export', true).attr({ + id: fmt + }).style(!_this.test && navigator.msSaveBlob ? { + cursor: 'pointer', + 'text-decoration': 'underline', + color: 'blue' + } : null).text(fmt.toUpperCase()); + }); } function download(fileType, data) { //transform blob array into a blob of characters var blob = new Blob(data, { - type: fileType === 'csv' - ? 'text/csv;charset=utf-8;' - : fileType === 'xlsx' - ? 'application/octet-stream' - : console.warn('File type not supported: ' + fileType) + type: fileType === 'csv' ? 'text/csv;charset=utf-8;' : fileType === 'xlsx' ? 'application/octet-stream' : console.warn('File type not supported: ' + fileType) }); - var fileName = - 'webchartsTableExport_' + - d3.time.format('%Y-%m-%dT%H-%M-%S')(new Date()) + - '.' + - fileType; + var fileName = 'webchartsTableExport_' + d3.time.format('%Y-%m-%dT%H-%M-%S')(new Date()) + '.' + fileType; var link = this.wrap.select('.export#' + fileType); if (navigator.msSaveBlob) //IE - navigator.msSaveBlob(blob, fileName); - else if (link.node().download !== undefined) { + navigator.msSaveBlob(blob, fileName);else if (link.node().download !== undefined) { //21st century browsers var url = URL.createObjectURL(blob); link.node().setAttribute('href', url); @@ -3714,18 +2653,18 @@ function csv(data) { var _this = this; - this.wrap.select('.export#csv').on('click', function() { + this.wrap.select('.export#csv').on('click', function () { var CSVarray = []; //add headers to CSV array - var headers = _this.config.headers.map(function(header) { + var headers = _this.config.headers.map(function (header) { return '"' + header.replace(/"/g, '""') + '"'; }); CSVarray.push(headers); //add rows to CSV array - data.forEach(function(d, i) { - var row = _this.config.cols.map(function(col) { + data.forEach(function (d, i) { + var row = _this.config.cols.map(function (col) { var value = d[col]; if (typeof value === 'string') value = value.replace(/"/g, '""'); @@ -3744,21 +2683,19 @@ function xlsx(data) { var _this = this; - this.wrap.select('.export#xlsx').on('click', function() { + this.wrap.select('.export#xlsx').on('click', function () { var sheetName = 'Selected Data'; var options = { bookType: 'xlsx', bookSST: true, type: 'binary' }; - var arrayOfArrays = data.map(function(d) { - return Object.keys(d) - .filter(function(key) { - return _this.config.cols.indexOf(key) > -1; - }) - .map(function(key) { - return d[key]; - }); + var arrayOfArrays = data.map(function (d) { + return Object.keys(d).filter(function (key) { + return _this.config.cols.indexOf(key) > -1; + }).map(function (key) { + return d[key]; + }); }); // convert data from array of objects to array of arrays. var workbook = { SheetNames: [sheetName], @@ -3767,9 +2704,7 @@ var cols = []; //Convert headers and data from array of arrays to sheet. - workbook.Sheets[sheetName] = XLSX.utils.aoa_to_sheet( - [_this.config.headers].concat(arrayOfArrays) - ); + workbook.Sheets[sheetName] = XLSX.utils.aoa_to_sheet([_this.config.headers].concat(arrayOfArrays)); //Add filters to spreadsheet. workbook.Sheets[sheetName]['!autofilter'] = { @@ -3777,7 +2712,7 @@ }; //Define column widths in spreadsheet. - _this.table.selectAll('thead tr th').each(function() { + _this.table.selectAll('thead tr th').each(function () { cols.push({ wpx: this.offsetWidth }); }); workbook.Sheets[sheetName]['!cols'] = cols; @@ -3789,8 +2724,7 @@ for (var i = 0; i !== s.length; ++i) { view[i] = s.charCodeAt(i) & 0xff; - } - return buffer; + }return buffer; }; // convert spreadsheet to binary or something, i don't know //Download .xlsx file. @@ -3811,16 +2745,10 @@ } function layout$4() { + //Add sort container. - this.sortable.wrap = this.wrap - .select('.table-top') - .append('div') - .classed('interactivity sortable-container', true) - .classed('hidden', !this.config.sortable); - this.sortable.wrap - .append('div') - .classed('instruction', true) - .text('Click column headers to sort.'); + this.sortable.wrap = this.wrap.select('.table-top').append('div').classed('interactivity sortable-container', true).classed('hidden', !this.config.sortable); + this.sortable.wrap.append('div').classed('instruction', true).text('Click column headers to sort.'); } function onClick(th, header) { @@ -3829,7 +2757,7 @@ col = this.config.cols[this.config.headers.indexOf(header)]; //Check if column is already a part of current sort order. - var sortItem = this.sortable.order.filter(function(item) { + var sortItem = this.sortable.order.filter(function (item) { return item.col === col; })[0]; @@ -3838,11 +2766,7 @@ sortItem = { col: col, direction: 'ascending', - wrap: this.sortable.wrap - .append('div') - .datum({ key: col }) - .classed('wc-button sort-box', true) - .text(header) + wrap: this.sortable.wrap.append('div').datum({ key: col }).classed('wc-button sort-box', true).text(header) }; sortItem.wrap.append('span').classed('sort-direction', true).html('↓'); sortItem.wrap.append('span').classed('remove-sort', true).html('❌'); @@ -3850,34 +2774,25 @@ } else { //Otherwise reverse its sort direction. sortItem.direction = sortItem.direction === 'ascending' ? 'descending' : 'ascending'; - sortItem.wrap - .select('span.sort-direction') - .html(sortItem.direction === 'ascending' ? '↓' : '↑'); + sortItem.wrap.select('span.sort-direction').html(sortItem.direction === 'ascending' ? '↓' : '↑'); } //Hide sort instructions. this.sortable.wrap.select('.instruction').classed('hidden', true); //Add sort container deletion functionality. - this.sortable.order.forEach(function(item, i) { - item.wrap.on('click', function(d) { + this.sortable.order.forEach(function (item, i) { + item.wrap.on('click', function (d) { //Remove column's sort container. d3.select(this).remove(); //Remove column from sort. - context.sortable.order.splice( - context.sortable.order - .map(function(d) { - return d.col; - }) - .indexOf(d.key), - 1 - ); + context.sortable.order.splice(context.sortable.order.map(function (d) { + return d.col; + }).indexOf(d.key), 1); //Display sorting instruction. - context.sortable.wrap - .select('.instruction') - .classed('hidden', context.sortable.order.length); + context.sortable.wrap.select('.instruction').classed('hidden', context.sortable.order.length); //Redraw chart. context.draw(); @@ -3891,24 +2806,15 @@ function sortData(data) { var _this = this; - data = data.sort(function(a, b) { + data = data.sort(function (a, b) { var order = 0; - _this.sortable.order.forEach(function(item) { + _this.sortable.order.forEach(function (item) { var aCell = a[item.col], bCell = b[item.col]; if (order === 0) { - if ( - (item.direction === 'ascending' && aCell < bCell) || - (item.direction === 'descending' && aCell > bCell) - ) - order = -1; - else if ( - (item.direction === 'ascending' && aCell > bCell) || - (item.direction === 'descending' && aCell < bCell) - ) - order = 1; + if (item.direction === 'ascending' && aCell < bCell || item.direction === 'descending' && aCell > bCell) order = -1;else if (item.direction === 'ascending' && aCell > bCell || item.direction === 'descending' && aCell < bCell) order = 1; } }); @@ -3926,11 +2832,7 @@ } function layout$5() { - this.pagination.wrap = this.wrap - .select('.table-bottom') - .append('div') - .classed('interactivity pagination-container', true) - .classed('hidden', !this.config.pagination); + this.pagination.wrap = this.wrap.select('.table-bottom').append('div').classed('interactivity pagination-container', true).classed('hidden', !this.config.pagination); } function updatePagination() { @@ -3940,11 +2842,9 @@ this.pagination.links.classed('active', false); //Set to active the selected page link. - var activePage = this.pagination.links - .filter(function(link) { - return +link.rel === +_this.config.activePage; - }) - .classed('active', true); + var activePage = this.pagination.links.filter(function (link) { + return +link.rel === +_this.config.activePage; + }).classed('active', true); //Define and draw selected page. this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; @@ -3962,28 +2862,15 @@ this.pagination.wrap.selectAll('a,span').remove(); var _loop = function _loop(i) { - _this.pagination.wrap - .append('a') - .datum({ rel: i }) - .attr({ - rel: i - }) - .text(i + 1) - .classed('wc-button page-link', true) - .classed('active', function(d) { - return d.rel == _this.config.activePage; - }) - .classed('hidden', function() { - return _this.config.activePage < _this.config.nPageLinksDisplayed - ? i >= _this.config.nPageLinksDisplayed // first nPageLinksDisplayed pages - : _this.config.activePage >= - _this.config.nPages - _this.config.nPageLinksDisplayed - ? i < _this.config.nPages - _this.config.nPageLinksDisplayed // last nPageLinksDisplayed pages - : i < - _this.config.activePage - - (Math.ceil(_this.config.nPageLinksDisplayed / 2) - 1) || - _this.config.activePage + _this.config.nPageLinksDisplayed / 2 < i; // nPageLinksDisplayed < activePage or activePage < (nPages - nPageLinksDisplayed) - }); + _this.pagination.wrap.append('a').datum({ rel: i }).attr({ + rel: i + }).text(i + 1).classed('wc-button page-link', true).classed('active', function (d) { + return d.rel == _this.config.activePage; + }).classed('hidden', function () { + return _this.config.activePage < _this.config.nPageLinksDisplayed ? i >= _this.config.nPageLinksDisplayed // first nPageLinksDisplayed pages + : _this.config.activePage >= _this.config.nPages - _this.config.nPageLinksDisplayed ? i < _this.config.nPages - _this.config.nPageLinksDisplayed // last nPageLinksDisplayed pages + : i < _this.config.activePage - (Math.ceil(_this.config.nPageLinksDisplayed / 2) - 1) || _this.config.activePage + _this.config.nPageLinksDisplayed / 2 < i; // nPageLinksDisplayed < activePage or activePage < (nPages - nPageLinksDisplayed) + }); }; for (var i = 0; i < this.config.nPages; i++) { @@ -4003,69 +2890,28 @@ Left side \-------------------------------------------------------------------------------------------**/ - this.pagination.wrap - .insert('span', ':first-child') - .classed('dot-dot-dot', true) - .text('...') - .classed('hidden', this.config.activePage < this.config.nPageLinksDisplayed); - - this.pagination.prev = this.pagination.wrap - .insert('a', ':first-child') - .classed('wc-button arrow-link wc-left', true) - .classed('hidden', this.config.activePage == 0) - .attr({ - rel: prev - }) - .text('<'); - - this.pagination.doublePrev = this.pagination.wrap - .insert('a', ':first-child') - .classed('wc-button arrow-link wc-left double', true) - .classed('hidden', this.config.activePage == 0) - .attr({ - rel: 0 - }) - .text('<<'); + this.pagination.wrap.insert('span', ':first-child').classed('dot-dot-dot', true).text('...').classed('hidden', this.config.activePage < this.config.nPageLinksDisplayed); + + this.pagination.prev = this.pagination.wrap.insert('a', ':first-child').classed('wc-button arrow-link wc-left', true).classed('hidden', this.config.activePage == 0).attr({ + rel: prev + }).text('<'); + + this.pagination.doublePrev = this.pagination.wrap.insert('a', ':first-child').classed('wc-button arrow-link wc-left double', true).classed('hidden', this.config.activePage == 0).attr({ + rel: 0 + }).text('<<'); /**-------------------------------------------------------------------------------------------\ Right side \-------------------------------------------------------------------------------------------**/ - this.pagination.wrap - .append('span') - .classed('dot-dot-dot', true) - .text('...') - .classed( - 'hidden', - this.config.activePage >= - Math.max( - this.config.nPageLinksDisplayed, - this.config.nPages - this.config.nPageLinksDisplayed - ) || this.config.nPages <= this.config.nPageLinksDisplayed - ); - this.pagination.next = this.pagination.wrap - .append('a') - .classed('wc-button arrow-link wc-right', true) - .classed( - 'hidden', - this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0 - ) - .attr({ - rel: next - }) - .text('>'); - - this.pagination.doubleNext = this.pagination.wrap - .append('a') - .classed('wc-button arrow-link wc-right double', true) - .classed( - 'hidden', - this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0 - ) - .attr({ - rel: this.config.nPages - 1 - }) - .text('>>'); + this.pagination.wrap.append('span').classed('dot-dot-dot', true).text('...').classed('hidden', this.config.activePage >= Math.max(this.config.nPageLinksDisplayed, this.config.nPages - this.config.nPageLinksDisplayed) || this.config.nPages <= this.config.nPageLinksDisplayed); + this.pagination.next = this.pagination.wrap.append('a').classed('wc-button arrow-link wc-right', true).classed('hidden', this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0).attr({ + rel: next + }).text('>'); + + this.pagination.doubleNext = this.pagination.wrap.append('a').classed('wc-button arrow-link wc-right double', true).classed('hidden', this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0).attr({ + rel: this.config.nPages - 1 + }).text('>>'); this.pagination.arrows = this.pagination.wrap.selectAll('a.arrow-link'); this.pagination.doubleArrows = this.pagination.wrap.selectAll('a.double-arrow-link'); @@ -4086,7 +2932,7 @@ addLinks.call(this); //Render a different page on click. - this.pagination.links.on('click', function() { + this.pagination.links.on('click', function () { context.config.activePage = +d3.select(this).attr('rel'); updatePagination.call(context); }); @@ -4095,25 +2941,17 @@ addArrows.call(this); //Render a different page on click. - this.pagination.arrows.on('click', function() { + this.pagination.arrows.on('click', function () { if (context.config.activePage !== +d3.select(this).attr('rel')) { context.config.activePage = +d3.select(this).attr('rel'); - context.pagination.prev.attr( - 'rel', - context.config.activePage > 0 ? context.config.activePage - 1 : 0 - ); - context.pagination.next.attr( - 'rel', - context.config.activePage < context.config.nPages - ? context.config.activePage + 1 - : context.config.nPages - 1 - ); + context.pagination.prev.attr('rel', context.config.activePage > 0 ? context.config.activePage - 1 : 0); + context.pagination.next.attr('rel', context.config.activePage < context.config.nPages ? context.config.activePage + 1 : context.config.nPages - 1); updatePagination.call(context); } }); //Render a different page on click. - this.pagination.doubleArrows.on('click', function() { + this.pagination.doubleArrows.on('click', function () { context.config.activePage = +d3.select(this).attr('rel'); updatePagination.call(context); }); @@ -4146,17 +2984,9 @@ this.test = test; if (d3.select(this.div).select('.loader').empty()) { - d3 - .select(this.div) - .insert('div', ':first-child') - .attr('class', 'loader') - .selectAll('.blockG') - .data(d3.range(8)) - .enter() - .append('div') - .attr('class', function(d) { - return 'blockG rotate' + (d + 1); - }); + d3.select(this.div).insert('div', ':first-child').attr('class', 'loader').selectAll('.blockG').data(d3.range(8)).enter().append('div').attr('class', function (d) { + return 'blockG rotate' + (d + 1); + }); } //Define default settings. @@ -4196,10 +3026,8 @@ //make sure container is visible (has height and width) before trying to initialize var visible = d3.select(_this.div).property('offsetWidth') > 0 || test; if (!visible) { - console.warn( - 'The table cannot be initialized inside an element with 0 width. The table will be initialized as soon as the container element is given a width > 0.' - ); - var onVisible = setInterval(function(i) { + console.warn('The table cannot be initialized inside an element with 0 width. The table will be initialized as soon as the container element is given a width > 0.'); + var onVisible = setInterval(function (i) { var visible_now = d3.select(_this.div).property('offsetWidth') > 0; if (visible_now) { _this.layout(); @@ -4257,9 +3085,7 @@ } function destroy$2() { - var destroyControls = arguments.length > 0 && arguments[0] !== undefined - ? arguments[0] - : false; + var destroyControls = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; //run onDestroy callback this.events.onDestroy.call(this); @@ -4276,20 +3102,14 @@ function setDefault(setting) { var _default_ = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - this.config[setting] = this.config[setting] !== undefined - ? this.config[setting] - : _default_; + this.config[setting] = this.config[setting] !== undefined ? this.config[setting] : _default_; } function setDefaults$1(firstItem) { //Set data-driven defaults. if (this.config.cols instanceof Array && this.config.headers instanceof Array) { if (this.config.cols.length === 0) delete this.config.cols; - if ( - this.config.headers.length === 0 || - this.config.headers.length !== this.config.cols.length - ) - delete this.config.headers; + if (this.config.headers.length === 0 || this.config.headers.length !== this.config.cols.length) delete this.config.headers; } this.config.cols = this.config.cols || d3.keys(firstItem); @@ -4322,7 +3142,7 @@ this.config.headers = this.config.headers || this.config.cols; if (this.config.keep) { - this.config.keep.forEach(function(e) { + this.config.keep.forEach(function (e) { if (_this.config.cols.indexOf(e) === -1) { _this.config.cols.unshift(e); } @@ -4332,9 +3152,9 @@ var filtered = data; if (this.filters.length) { - this.filters.forEach(function(e) { + this.filters.forEach(function (e) { var is_array = e.val instanceof Array; - filtered = filtered.filter(function(d) { + filtered = filtered.filter(function (d) { if (is_array) { return e.val.indexOf(d[e.col]) !== -1; } else { @@ -4344,36 +3164,30 @@ }); } - var slimmed = d3 - .nest() - .key(function(d) { - if (_this.config.row_per) { - return _this.config.row_per - .map(function(m) { - return d[m]; - }) - .join(' '); - } else { - return d; - } - }) - .rollup(function(r) { - if (_this.config.dataManipulate) { - r = _this.config.dataManipulate(r); + var slimmed = d3.nest().key(function (d) { + if (_this.config.row_per) { + return _this.config.row_per.map(function (m) { + return d[m]; + }).join(' '); + } else { + return d; + } + }).rollup(function (r) { + if (_this.config.dataManipulate) { + r = _this.config.dataManipulate(r); + } + var nuarr = r.map(function (m) { + var arr = []; + for (var x in m) { + arr.push({ col: x, text: m[x] }); } - var nuarr = r.map(function(m) { - var arr = []; - for (var x in m) { - arr.push({ col: x, text: m[x] }); - } - arr.sort(function(a, b) { - return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); - }); - return { cells: arr, raw: m }; + arr.sort(function (a, b) { + return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); }); - return nuarr; - }) - .entries(filtered); + return { cells: arr, raw: m }; + }); + return nuarr; + }).entries(filtered); this.data.current = slimmed.length ? slimmed : [{ key: null, values: [] }]; // dummy nested data array @@ -4388,8 +3202,8 @@ if (config.row_per) { var rev_order = config.row_per.slice(0).reverse(); - rev_order.forEach(function(e) { - tbodies.sort(function(a, b) { + rev_order.forEach(function (e) { + tbodies.sort(function (a, b) { return a.values[0].raw[e] - b.values[0].raw[e]; }); }); @@ -4397,15 +3211,11 @@ //Delete text from columns with repeated values? if (config.row_per) { - rows - .filter(function(f, i) { - return i > 0; - }) - .selectAll('td') - .filter(function(f) { - return config.row_per.indexOf(f.col) > -1; - }) - .text(''); + rows.filter(function (f, i) { + return i > 0; + }).selectAll('td').filter(function (f) { + return config.row_per.indexOf(f.col) > -1; + }).text(''); } return this.data.current; @@ -4447,7 +3257,7 @@ onDestroy: function onDestroy() {} }; - thisTable.on = function(event, callback) { + thisTable.on = function (event, callback) { var possible_events = ['init', 'layout', 'preprocess', 'draw', 'destroy']; if (possible_events.indexOf(event) < 0) { return; @@ -4473,22 +3283,17 @@ chart.multiples = []; function goAhead(data) { - var split_vals = d3 - .set( - data.map(function(m) { - return m[split_by]; - }) - ) - .values() - .filter(function(f) { - return f; - }); + var split_vals = d3.set(data.map(function (m) { + return m[split_by]; + })).values().filter(function (f) { + return f; + }); if (order) { - split_vals = split_vals.sort(function(a, b) { + split_vals = split_vals.sort(function (a, b) { return d3.ascending(order.indexOf(a), order.indexOf(b)); }); } - split_vals.forEach(function(e) { + split_vals.forEach(function (e) { var mchart = createChart(chart.wrap.node(), chart.config, chart.controls); chart.multiples.push(mchart); mchart.parent = chart; @@ -4504,14 +3309,10 @@ } function getValType(data, variable) { - var var_vals = d3 - .set( - data.map(function(m) { - return m[variable]; - }) - ) - .values(); - var vals_numbers = var_vals.filter(function(f) { + var var_vals = d3.set(data.map(function (m) { + return m[variable]; + })).values(); + var vals_numbers = var_vals.filter(function (f) { return +f || +f === 0; }); @@ -4525,8 +3326,8 @@ function lengthenRaw(data, columns) { var my_data = []; - data.forEach(function(e) { - columns.forEach(function(g) { + data.forEach(function (e) { + columns.forEach(function (g) { var obj = Object.create(e); obj.wc_category = g; obj.wc_value = e[g]; @@ -4554,4 +3355,5 @@ }; return index; -}); + +})); diff --git a/src/chart/draw/consolidateData/transformData/makeNest.js b/src/chart/draw/consolidateData/transformData/makeNest.js index eacdd38..d12da32 100644 --- a/src/chart/draw/consolidateData/transformData/makeNest.js +++ b/src/chart/draw/consolidateData/transformData/makeNest.js @@ -15,7 +15,11 @@ export default function makeNest(mark, entries, sublevel) { let xy = this.config.x.type === 'linear' && this.config.x.bin ? 'x' : 'y'; let quant = scale .quantile() - .domain(extent(entries.map(m => +m[this.config[xy].column]))) + .domain( + this.config[xy].behavior !== 'flex' && this.config[xy].domain + ? this.config[xy].domain + : extent(entries.map(m => +m[this.config[xy].column])) + ) .range(range(+this.config[xy].bin)); entries.forEach(e => (e.wc_bin = quant(e[this.config[xy].column]))); diff --git a/test-page/histogram/index.html b/test-page/histogram/index.html new file mode 100644 index 0000000..5e99b0b --- /dev/null +++ b/test-page/histogram/index.html @@ -0,0 +1,22 @@ + + + + Webcharts - Histogram + + + + + + + + + + + +
Webcharts
+
Histogram
+
+ + + + diff --git a/test-page/histogram/index.js b/test-page/histogram/index.js new file mode 100644 index 0000000..f51e70b --- /dev/null +++ b/test-page/histogram/index.js @@ -0,0 +1,69 @@ +const settings = { + x: { + type: 'linear', + column: 'sepal length', + label: 'Sepal Length', + bin: 15, + format: '.1f', + domain: [3, 10], + //behavior: 'flex' + }, + y: { + type: 'linear', + label: '# of Observations', + behavior: 'flex', + domain: [0], + }, + marks: [ + { + type: 'bar', + per: ['sepal length'], + summarizeY: 'count', + tooltip: '$y observations around $x', + }, + ], + aspect: 3, + gridlines: 'y', +}; + +const controls = new webCharts.createControls( + '#container', + { + inputs: [ + { + type: 'subsetter', + value_col: 'species', + label: 'Species', + }, + //{ + // type: 'radio', + // option: 'x.domain.0', + // label: 'X-domain Lower Limit', + // values: ['minimum',0], + //}, + //{ + // type: 'radio', + // option: 'y.domain.0', + // label: 'Y-domain Lower Limit', + // values: ['minimum',0], + //}, + ], + }, +); + +const chart = new webCharts.createChart( + '#container', + settings, + controls, +); + +d3.csv( + 'https://cdn.jsdelivr.net/gh/RhoInc/data-library/data/miscellaneous/iris.csv', + function(d,i) { + d.seq = i; + return d; + }, + function(data) { + chart.init(data); + } +); From fac08b4761b92e5249289ea2c1104550f275660e Mon Sep 17 00:00:00 2001 From: Spencer Childress Date: Fri, 10 May 2019 16:51:46 -0400 Subject: [PATCH 02/12] add test cases for histograms --- build/webcharts.js | 3231 +++++++++++------ build/webcharts.min.js | 6 +- package-lock.json | 4 +- package.json | 2 +- src/chart/draw/consolidateData.js | 19 +- .../consolidateData/transformData/makeNest.js | 10 +- test-page/histogram/index.js | 124 +- test-page/histograms/index.html | 22 + test-page/histograms/index.js | 111 + test/chart/cleanData.js | 37 +- test/chart/createChart.js | 6 +- test/chart/histogram.js | 32 + test/chart/rangeBand.js | 4 +- test/chart/rendering.js | 132 +- test/chart/runTests.js | 7 +- test/chart/setDomain.js | 12 +- test/chart/transformData.js | 15 +- test/controls/createControls.js | 6 +- test/multiply/multiply.js | 4 +- .../chart-config/barchart_vertical.json | 2 +- test/samples/histogram.js | 19 + test/samples/irisSettings.js | 24 +- test/table/bindTableToDOM.js | 3 +- test/table/runTests.js | 20 +- test/testNewUnitTests.js | 2 +- 25 files changed, 2653 insertions(+), 1201 deletions(-) create mode 100644 test-page/histograms/index.html create mode 100644 test-page/histograms/index.js create mode 100644 test/chart/histogram.js create mode 100644 test/samples/histogram.js diff --git a/build/webcharts.js b/build/webcharts.js index f72f128..78f1214 100644 --- a/build/webcharts.js +++ b/build/webcharts.js @@ -1,9 +1,11 @@ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('d3')) : - typeof define === 'function' && define.amd ? define(['d3'], factory) : - global.webCharts = factory(global.d3); -}(typeof self !== 'undefined' ? self : this, function (d3) { 'use strict'; - +(function(global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + ? (module.exports = factory(require('d3'))) + : typeof define === 'function' && define.amd + ? define(['d3'], factory) + : (global.webCharts = factory(global.d3)); +})(typeof self !== 'undefined' ? self : this, function(d3) { + 'use strict'; var version = '1.11.5'; function init(data) { @@ -12,9 +14,17 @@ var test = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; if (d3.select(this.div).select('.loader').empty()) { - d3.select(this.div).insert('div', ':first-child').attr('class', 'loader').selectAll('.blockG').data(d3.range(8)).enter().append('div').attr('class', function (d) { - return 'blockG rotate' + (d + 1); - }); + d3 + .select(this.div) + .insert('div', ':first-child') + .attr('class', 'loader') + .selectAll('.blockG') + .data(d3.range(8)) + .enter() + .append('div') + .attr('class', function(d) { + return 'blockG rotate' + (d + 1); + }); } this.wrap.attr('class', 'wc-chart'); @@ -38,8 +48,10 @@ //make sure container is visible (has height and width) before trying to initialize var visible = d3.select(_this.div).property('offsetWidth') > 0 || test; if (!visible) { - console.warn('The chart cannot be initialized inside an element with 0 width. The chart will be initialized as soon as the container element is given a width > 0.'); - var onVisible = setInterval(function (i) { + console.warn( + 'The chart cannot be initialized inside an element with 0 width. The chart will be initialized as soon as the container element is given a width > 0.' + ); + var onVisible = setInterval(function(i) { var visible_now = d3.select(_this.div).property('offsetWidth') > 0; if (visible_now) { _this.layout(); @@ -80,32 +92,48 @@ requiredVars.push('this.config.color_by'); requiredCols.push(this.config.color_by); } - if (this.config.marks) this.config.marks.forEach(function (e, i) { - if (e.per && e.per.length) { - e.per.forEach(function (p, j) { - requiredVars.push('this.config.marks[' + i + '].per[' + j + ']'); - requiredCols.push(p); - }); - } - if (e.split) { - requiredVars.push('this.config.marks[' + i + '].split'); - requiredCols.push(e.split); - } - if (e.values) { - for (var value in e.values) { - requiredVars.push('this.config.marks[' + i + "].values['" + value + "']"); - requiredCols.push(value); + if (this.config.marks) + this.config.marks.forEach(function(e, i) { + if (e.per && e.per.length) { + e.per.forEach(function(p, j) { + requiredVars.push('this.config.marks[' + i + '].per[' + j + ']'); + requiredCols.push(p); + }); } - } - }); + if (e.split) { + requiredVars.push('this.config.marks[' + i + '].split'); + requiredCols.push(e.split); + } + if (e.values) { + for (var value in e.values) { + requiredVars.push('this.config.marks[' + i + "].values['" + value + "']"); + requiredCols.push(value); + } + } + }); var missingDataField = false; - requiredCols.forEach(function (e, i) { + requiredCols.forEach(function(e, i) { if (colnames.indexOf(e) < 0) { missingDataField = true; d3.select(_this.div).select('.loader').remove(); - _this.wrap.append('div').style('color', 'red').html('The value "' + e + '" for the ' + requiredVars[i] + ' setting does not match any column in the provided dataset.'); - throw new Error('Error in settings object: The value "' + e + '" for the ' + requiredVars[i] + ' setting does not match any column in the provided dataset.'); + _this.wrap + .append('div') + .style('color', 'red') + .html( + 'The value "' + + e + + '" for the ' + + requiredVars[i] + + ' setting does not match any column in the provided dataset.' + ); + throw new Error( + 'Error in settings object: The value "' + + e + + '" for the ' + + requiredVars[i] + + ' setting does not match any column in the provided dataset.' + ); } }); @@ -117,61 +145,94 @@ } function addSVG() { - this.svg = this.wrap.append('svg').datum(function () { - return null; - }) // prevent data inheritance - .attr({ - class: 'wc-svg', - xmlns: 'http://www.w3.org/2000/svg', - version: '1.1', - xlink: 'http://www.w3.org/1999/xlink' - }).append('g').style('display', 'inline-block'); + this.svg = this.wrap + .append('svg') + .datum(function() { + return null; + }) // prevent data inheritance + .attr({ + class: 'wc-svg', + xmlns: 'http://www.w3.org/2000/svg', + version: '1.1', + xlink: 'http://www.w3.org/1999/xlink' + }) + .append('g') + .style('display', 'inline-block'); } function addDefs() { var defs = this.svg.append('defs'); //Add pattern. - defs.append('pattern').attr({ - id: 'diagonal-stripes', - x: 0, - y: 0, - width: 3, - height: 8, - patternUnits: 'userSpaceOnUse', - patternTransform: 'rotate(30)' - }).append('rect').attr({ - x: '0', - y: '0', - width: '2', - height: '8' - }).style({ - stroke: 'none', - fill: 'black' - }); + defs + .append('pattern') + .attr({ + id: 'diagonal-stripes', + x: 0, + y: 0, + width: 3, + height: 8, + patternUnits: 'userSpaceOnUse', + patternTransform: 'rotate(30)' + }) + .append('rect') + .attr({ + x: '0', + y: '0', + width: '2', + height: '8' + }) + .style({ + stroke: 'none', + fill: 'black' + }); //Add clipPath. defs.append('clipPath').attr('id', this.id).append('rect').attr('class', 'plotting-area'); } function addXAxis() { - this.svg.append('g').attr('class', 'x axis').append('text').attr('class', 'axis-title').attr('dy', '-.35em').attr('text-anchor', 'middle'); + this.svg + .append('g') + .attr('class', 'x axis') + .append('text') + .attr('class', 'axis-title') + .attr('dy', '-.35em') + .attr('text-anchor', 'middle'); } function addYAxis() { - this.svg.append('g').attr('class', 'y axis').append('text').attr('class', 'axis-title').attr('transform', 'rotate(-90)').attr('dy', '.75em').attr('text-anchor', 'middle'); + this.svg + .append('g') + .attr('class', 'y axis') + .append('text') + .attr('class', 'axis-title') + .attr('transform', 'rotate(-90)') + .attr('dy', '.75em') + .attr('text-anchor', 'middle'); } function addOverlay() { - this.overlay = this.svg.append('rect').attr('class', 'overlay').attr('opacity', 0).attr('fill', 'none').style('pointer-events', 'all'); + this.overlay = this.svg + .append('rect') + .attr('class', 'overlay') + .attr('opacity', 0) + .attr('fill', 'none') + .style('pointer-events', 'all'); } function addLegend() { //The legend is contained in the parent object of multiples so each multiple does not need its own legend. - if (!this.parent) this.wrap.append('ul').datum(function () { - return null; - }) // prevent data inheritance - .attr('class', 'legend').style('vertical-align', 'top').append('span').attr('class', 'legend-title'); + if (!this.parent) + this.wrap + .append('ul') + .datum(function() { + return null; + }) // prevent data inheritance + .attr('class', 'legend') + .style('vertical-align', 'top') + .append('span') + .attr('class', 'legend-title'); } function clearLoader() { @@ -207,7 +268,9 @@ // warn the user about the perils of "processed_data" if (processed_data) { - console.warn("Drawing the chart using user-defined 'processed_data', this is an experimental, untested feature."); + console.warn( + "Drawing the chart using user-defined 'processed_data', this is an experimental, untested feature." + ); } //Call consolidateData - this applies filters from controls and prepares data for each set of marks. @@ -222,24 +285,38 @@ this.setColorScale(); var max_width = config.max_width ? config.max_width : div_width; - this.raw_width = config.x.type === 'ordinal' && +config.x.range_band ? (+config.x.range_band + config.x.range_band * config.padding) * this.x_dom.length : config.resizable ? max_width : config.width ? config.width : div_width; - this.raw_height = config.y.type === 'ordinal' && +config.y.range_band ? (+config.y.range_band + config.y.range_band * config.padding) * this.y_dom.length : config.resizable ? max_width * (1 / config.aspect) : config.height ? config.height : div_width * (1 / config.aspect); - - var pseudo_width = this.svg.select('.overlay').attr('width') ? this.svg.select('.overlay').attr('width') : this.raw_width; - var pseudo_height = this.svg.select('.overlay').attr('height') ? this.svg.select('.overlay').attr('height') : this.raw_height; - - this.svg.select('.x.axis').select('.axis-title').text(function (d) { - return typeof config.x.label === 'string' ? config.x.label : typeof config.x.label === 'function' ? config.x.label.call(_this) : null; + this.raw_width = config.x.type === 'ordinal' && +config.x.range_band + ? (+config.x.range_band + config.x.range_band * config.padding) * this.x_dom.length + : config.resizable ? max_width : config.width ? config.width : div_width; + this.raw_height = config.y.type === 'ordinal' && +config.y.range_band + ? (+config.y.range_band + config.y.range_band * config.padding) * this.y_dom.length + : config.resizable + ? max_width * (1 / config.aspect) + : config.height ? config.height : div_width * (1 / config.aspect); + + var pseudo_width = this.svg.select('.overlay').attr('width') + ? this.svg.select('.overlay').attr('width') + : this.raw_width; + var pseudo_height = this.svg.select('.overlay').attr('height') + ? this.svg.select('.overlay').attr('height') + : this.raw_height; + + this.svg.select('.x.axis').select('.axis-title').text(function(d) { + return typeof config.x.label === 'string' + ? config.x.label + : typeof config.x.label === 'function' ? config.x.label.call(_this) : null; }); - this.svg.select('.y.axis').select('.axis-title').text(function (d) { - return typeof config.y.label === 'string' ? config.y.label : typeof config.y.label === 'function' ? config.y.label.call(_this) : null; + this.svg.select('.y.axis').select('.axis-title').text(function(d) { + return typeof config.y.label === 'string' + ? config.y.label + : typeof config.y.label === 'function' ? config.y.label.call(_this) : null; }); this.xScaleAxis(pseudo_width); this.yScaleAxis(pseudo_height); if (config.resizable && typeof window !== 'undefined') { - d3.select(window).on('resize.' + this.element + this.id, function () { + d3.select(window).on('resize.' + this.element + this.id, function() { chart.resize(); }); } else if (typeof window !== 'undefined') { @@ -264,8 +341,8 @@ i = void 0, j = void 0; - while (i = (j = t.charAt(x++)).charCodeAt(0)) { - var m = i == 46 || i >= 48 && i <= 57; + while ((i = (j = t.charAt(x++)).charCodeAt(0))) { + var m = i == 46 || (i >= 48 && i <= 57); if (m !== n) { tz[++y] = ''; n = m; @@ -305,49 +382,101 @@ this[axis + '_dom'] = this.config[axis].domain; } else if (this.config[axis].order) { //data-driven domain with user-defined domain order - this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { - return mark[axis + '_dom']; - }))).values().sort(function (a, b) { - return d3.ascending(_this.config[axis].order.indexOf(a), _this.config[axis].order.indexOf(b)); - }); - } else if (this.config[axis].sort && this.config[axis].sort === 'alphabetical-ascending') { + this[axis + '_dom'] = d3 + .set( + d3.merge( + this.marks.map(function(mark) { + return mark[axis + '_dom']; + }) + ) + ) + .values() + .sort(function(a, b) { + return d3.ascending( + _this.config[axis].order.indexOf(a), + _this.config[axis].order.indexOf(b) + ); + }); + } else if ( + this.config[axis].sort && + this.config[axis].sort === 'alphabetical-ascending' + ) { //data-driven domain with user-defined domain sort algorithm that sorts the axis //alphanumerically, first to last - this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { - return mark[axis + '_dom']; - }))).values().sort(naturalSorter); - } else if (['time', 'linear'].indexOf(this.config[otherAxis].type) > -1 && this.config[axis].sort === 'earliest') { + this[axis + '_dom'] = d3 + .set( + d3.merge( + this.marks.map(function(mark) { + return mark[axis + '_dom']; + }) + ) + ) + .values() + .sort(naturalSorter); + } else if ( + ['time', 'linear'].indexOf(this.config[otherAxis].type) > -1 && + this.config[axis].sort === 'earliest' + ) { //data-driven domain plotted against a time or linear axis that sorts the axis values //by earliest event/datum; generally used with timeline charts - this[axis + '_dom'] = d3.nest().key(function (d) { - return d[_this.config[axis].column]; - }).rollup(function (d) { - return d.map(function (m) { - return m[_this.config[otherAxis].column]; - }).filter(function (f) { - return f instanceof Date; + this[axis + '_dom'] = d3 + .nest() + .key(function(d) { + return d[_this.config[axis].column]; + }) + .rollup(function(d) { + return d + .map(function(m) { + return m[_this.config[otherAxis].column]; + }) + .filter(function(f) { + return f instanceof Date; + }); + }) + .entries(this.filtered_data) + .sort(function(a, b) { + return d3.min(b.values) - d3.min(a.values); + }) + .map(function(m) { + return m.key; }); - }).entries(this.filtered_data).sort(function (a, b) { - return d3.min(b.values) - d3.min(a.values); - }).map(function (m) { - return m.key; - }); - } else if (!this.config[axis].sort || this.config[axis].sort === 'alphabetical-descending') { + } else if ( + !this.config[axis].sort || + this.config[axis].sort === 'alphabetical-descending' + ) { //data-driven domain with default/user-defined domain sort algorithm that sorts the //axis alphanumerically, last to first - this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { - return mark[axis + '_dom']; - }))).values().sort(naturalSorter).reverse(); + this[axis + '_dom'] = d3 + .set( + d3.merge( + this.marks.map(function(mark) { + return mark[axis + '_dom']; + }) + ) + ) + .values() + .sort(naturalSorter) + .reverse(); } else { //data-driven domain with an invalid user-defined sort algorithm that captures a unique //set of values as they appear in the data - this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { - return mark[axis + '_dom']; - }))).values(); + this[axis + '_dom'] = d3 + .set( + d3.merge( + this.marks.map(function(mark) { + return mark[axis + '_dom']; + }) + ) + ) + .values(); } - } else if (this.config.marks.map(function (m) { - return m['summarize' + axis.toUpperCase()] === 'percent'; - }).indexOf(true) > -1) { + } else if ( + this.config.marks + .map(function(m) { + return m['summarize' + axis.toUpperCase()] === 'percent'; + }) + .indexOf(true) > -1 + ) { //rate domains run from 0 to 1 this[axis + '_dom'] = [0, 1]; } else { @@ -355,13 +484,26 @@ //TODO: they should really run from the minimum to the maximum summarized value, e.g. a //TODO: means over time chart should plot over the range of the means, not the range of the //TODO: raw data - this[axis + '_dom'] = d3.extent(d3.merge(this.marks.map(function (mark) { - return mark[axis + '_dom']; - }))); + this[axis + '_dom'] = d3.extent( + d3.merge( + this.marks.map(function(mark) { + return mark[axis + '_dom']; + }) + ) + ); } //Give the domain a range when the range of the variable is 0. - if (this.config[axis].type === 'linear' && this[axis + '_dom'][0] === this[axis + '_dom'][1]) this[axis + '_dom'] = this[axis + '_dom'][0] !== 0 ? [this[axis + '_dom'][0] - this[axis + '_dom'][0] * 0.01, this[axis + '_dom'][1] + this[axis + '_dom'][1] * 0.01] : [-1, 1]; + if ( + this.config[axis].type === 'linear' && + this[axis + '_dom'][0] === this[axis + '_dom'][1] + ) + this[axis + '_dom'] = this[axis + '_dom'][0] !== 0 + ? [ + this[axis + '_dom'][0] - this[axis + '_dom'][0] * 0.01, + this[axis + '_dom'][1] + this[axis + '_dom'][1] * 0.01 + ] + : [-1, 1]; return this[axis + '_dom']; } @@ -374,44 +516,33 @@ //Apply filters from associated controls objects to raw data. this.filtered_data = raw; if (this.filters.length) { - this.filters.forEach(function (filter) { - _this.filtered_data = _this.filtered_data.filter(function (d) { - return filter.all === true && filter.index === 0 ? d : filter.val instanceof Array ? filter.val.indexOf(d[filter.col]) > -1 : d[filter.col] === filter.val; + this.filters.forEach(function(filter) { + _this.filtered_data = _this.filtered_data.filter(function(d) { + return filter.all === true && filter.index === 0 + ? d + : filter.val instanceof Array + ? filter.val.indexOf(d[filter.col]) > -1 + : d[filter.col] === filter.val; }); }); } //Summarize data for each mark. - this.config.marks.forEach(function (mark, i) { + this.config.marks.forEach(function(mark, i) { if (mark.type !== 'bar') { mark.arrange = null; mark.split = null; } - var mark_info = mark.per ? _this.transformData(raw, mark) : { - data: [], - x_dom: [], - y_dom: [] - }; + var mark_info = mark.per + ? _this.transformData(raw, mark) + : { + data: [], + x_dom: [], + y_dom: [] + }; - _this.marks[i] = { - id: mark.id, - type: mark.type, - per: mark.per, - data: mark_info.data, - x_dom: mark_info.x_dom, - y_dom: mark_info.y_dom, - split: mark.split, - text: mark.text, - arrange: mark.arrange, - order: mark.order, - summarizeX: mark.summarizeX, - summarizeY: mark.summarizeY, - tooltip: mark.tooltip, - radius: mark.radius, - attributes: mark.attributes, - values: mark.values - }; + _this.marks[i] = Object.assign({}, mark, mark_info); }); //Set domains given extents of summarized mark data. @@ -423,8 +554,12 @@ this.config.x = this.config.x || {}; this.config.y = this.config.y || {}; - this.config.x.label = this.config.x.label !== undefined ? this.config.x.label : this.config.x.column; - this.config.y.label = this.config.y.label !== undefined ? this.config.y.label : this.config.y.column; + this.config.x.label = this.config.x.label !== undefined + ? this.config.x.label + : this.config.x.column; + this.config.y.label = this.config.y.label !== undefined + ? this.config.y.label + : this.config.y.column; this.config.x.sort = this.config.x.sort || 'alphabetical-ascending'; this.config.y.sort = this.config.y.sort || 'alphabetical-descending'; @@ -437,10 +572,16 @@ this.config.margin = this.config.margin || {}; this.config.legend = this.config.legend || {}; - this.config.legend.label = this.config.legend.label !== undefined ? this.config.legend.label : this.config.color_by; - this.config.legend.location = this.config.legend.location !== undefined ? this.config.legend.location : 'bottom'; - this.config.marks = this.config.marks && this.config.marks.length ? this.config.marks : [{}]; - this.config.marks.forEach(function (m, i) { + this.config.legend.label = this.config.legend.label !== undefined + ? this.config.legend.label + : this.config.color_by; + this.config.legend.location = this.config.legend.location !== undefined + ? this.config.legend.location + : 'bottom'; + this.config.marks = this.config.marks && this.config.marks.length + ? this.config.marks + : [{}]; + this.config.marks.forEach(function(m, i) { m.id = m.id ? m.id : 'mark' + (i + 1); }); @@ -453,10 +594,23 @@ this.config.aspect = this.config.aspect || 1.33; - this.config.colors = this.config.colors || ['rgb(102,194,165)', 'rgb(252,141,98)', 'rgb(141,160,203)', 'rgb(231,138,195)', 'rgb(166,216,84)', 'rgb(255,217,47)', 'rgb(229,196,148)', 'rgb(179,179,179)']; - - this.config.scale_text = this.config.scale_text === undefined ? true : this.config.scale_text; - this.config.transitions = this.config.transitions === undefined ? true : this.config.transitions; + this.config.colors = this.config.colors || [ + 'rgb(102,194,165)', + 'rgb(252,141,98)', + 'rgb(141,160,203)', + 'rgb(231,138,195)', + 'rgb(166,216,84)', + 'rgb(255,217,47)', + 'rgb(229,196,148)', + 'rgb(179,179,179)' + ]; + + this.config.scale_text = this.config.scale_text === undefined + ? true + : this.config.scale_text; + this.config.transitions = this.config.transitions === undefined + ? true + : this.config.transitions; } function cleanData(mark, raw) { @@ -465,50 +619,68 @@ var dateConvert = d3.time.format(this.config.date_format); var clean = raw; // only use data for the current mark - clean = mark.per && mark.per.length ? clean.filter(function (f) { - return f[mark.per[0]] !== undefined; - }) : clean; + clean = mark.per && mark.per.length + ? clean.filter(function(f) { + return f[mark.per[0]] !== undefined; + }) + : clean; // Make sure data has x and y values if (this.config.x.column) { - clean = clean.filter(function (f) { + clean = clean.filter(function(f) { return [undefined, null].indexOf(f[_this.config.x.column]) < 0; }); } if (this.config.y.column) { - clean = clean.filter(function (f) { + clean = clean.filter(function(f) { return [undefined, null].indexOf(f[_this.config.y.column]) < 0; }); } //check that x and y have the correct formats if (this.config.x.type === 'time') { - clean = clean.filter(function (f) { - return f[_this.config.x.column] instanceof Date ? f[_this.config.x.column] : dateConvert.parse(f[_this.config.x.column]); + clean = clean.filter(function(f) { + return f[_this.config.x.column] instanceof Date + ? f[_this.config.x.column] + : dateConvert.parse(f[_this.config.x.column]); }); - clean.forEach(function (e) { - return e[_this.config.x.column] = e[_this.config.x.column] instanceof Date ? e[_this.config.x.column] : dateConvert.parse(e[_this.config.x.column]); + clean.forEach(function(e) { + return (e[_this.config.x.column] = e[_this.config.x.column] instanceof Date + ? e[_this.config.x.column] + : dateConvert.parse(e[_this.config.x.column])); }); } if (this.config.y.type === 'time') { - clean = clean.filter(function (f) { - return f[_this.config.y.column] instanceof Date ? f[_this.config.y.column] : dateConvert.parse(f[_this.config.y.column]); + clean = clean.filter(function(f) { + return f[_this.config.y.column] instanceof Date + ? f[_this.config.y.column] + : dateConvert.parse(f[_this.config.y.column]); }); - clean.forEach(function (e) { - return e[_this.config.y.column] = e[_this.config.y.column] instanceof Date ? e[_this.config.y.column] : dateConvert.parse(e[_this.config.y.column]); + clean.forEach(function(e) { + return (e[_this.config.y.column] = e[_this.config.y.column] instanceof Date + ? e[_this.config.y.column] + : dateConvert.parse(e[_this.config.y.column])); }); } - if ((this.config.x.type === 'linear' || this.config.x.type === 'log') && this.config.x.column) { - clean = clean.filter(function (f) { - return mark.summarizeX !== 'count' && mark.summarizeX !== 'percent' ? !(isNaN(f[_this.config.x.column]) || /^\s*$/.test(f[_this.config.x.column])) // is or coerces to a number and is not a string that coerces to 0 - : f; + if ( + (this.config.x.type === 'linear' || this.config.x.type === 'log') && + this.config.x.column + ) { + clean = clean.filter(function(f) { + return mark.summarizeX !== 'count' && mark.summarizeX !== 'percent' + ? !(isNaN(f[_this.config.x.column]) || /^\s*$/.test(f[_this.config.x.column])) // is or coerces to a number and is not a string that coerces to 0 + : f; }); } - if ((this.config.y.type === 'linear' || this.config.y.type === 'log') && this.config.y.column) { - clean = clean.filter(function (f) { - return mark.summarizeY !== 'count' && mark.summarizeY !== 'percent' ? !(isNaN(f[_this.config.y.column]) || /^\s*$/.test(f[_this.config.y.column])) // is or coerces to a number and is not a string that coerces to 0 - : f; + if ( + (this.config.y.type === 'linear' || this.config.y.type === 'log') && + this.config.y.column + ) { + clean = clean.filter(function(f) { + return mark.summarizeY !== 'count' && mark.summarizeY !== 'percent' + ? !(isNaN(f[_this.config.y.column]) || /^\s*$/.test(f[_this.config.y.column])) // is or coerces to a number and is not a string that coerces to 0 + : f; }); } @@ -526,17 +698,21 @@ function summarize(vals) { var operation = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'mean'; - var nvals = vals.filter(function (f) { - return +f || +f === 0; - }).map(function (m) { - return +m; - }); + var nvals = vals + .filter(function(f) { + return +f || +f === 0; + }) + .map(function(m) { + return +m; + }); if (operation === 'cumulative') { return null; } - var mathed = operation === 'count' ? vals.length : operation === 'percent' ? vals.length : stats[operation](nvals); + var mathed = operation === 'count' + ? vals.length + : operation === 'percent' ? vals.length : stats[operation](nvals); return mathed; } @@ -549,75 +725,127 @@ var this_nest = d3.nest(); var totalOrder = void 0; - if (this.config.x.type === 'linear' && this.config.x.bin || this.config.y.type === 'linear' && this.config.y.bin) { + if ( + (this.config.x.type === 'linear' && this.config.x.bin) || + (this.config.y.type === 'linear' && this.config.y.bin) + ) { var xy = this.config.x.type === 'linear' && this.config.x.bin ? 'x' : 'y'; - var quant = d3.scale.quantile().domain(this.config[xy].behavior !== 'flex' && this.config[xy].domain ? this.config[xy].domain : d3.extent(entries.map(function (m) { - return +m[_this.config[xy].column]; - }))).range(d3.range(+this.config[xy].bin)); - - entries.forEach(function (e) { - return e.wc_bin = quant(e[_this.config[xy].column]); + mark.quant = d3.scale + .quantile() + .domain( + this.config[xy].domain + ? this.config[xy].domain + : d3.extent( + entries.map(function(m) { + return +m[_this.config[xy].column]; + }) + ) + ) + .range(d3.range(+this.config[xy].bin)); + + entries.forEach(function(e) { + return (e.wc_bin = mark.quant(e[_this.config[xy].column])); }); - this_nest.key(function (d) { - return quant.invertExtent(d.wc_bin); + this_nest.key(function(d) { + return mark.quant.invertExtent(d.wc_bin); }); } else { - this_nest.key(function (d) { - return mark.per.map(function (m) { - return d[m]; - }).join(' '); + this_nest.key(function(d) { + return mark.per + .map(function(m) { + return d[m]; + }) + .join(' '); }); } if (sublevel) { - this_nest.key(function (d) { + this_nest.key(function(d) { return d[sublevel]; }); - this_nest.sortKeys(function (a, b) { - return _this.config.x.type === 'time' ? d3.ascending(new Date(a), new Date(b)) : _this.config.x.order ? d3.ascending(_this.config.x.order.indexOf(a), _this.config.x.order.indexOf(b)) : sublevel === _this.config.color_by && _this.config.legend.order ? d3.ascending(_this.config.legend.order.indexOf(a), _this.config.legend.order.indexOf(b)) : _this.config.x.type === 'ordinal' || _this.config.y.type === 'ordinal' ? naturalSorter(a, b) : d3.ascending(+a, +b); + this_nest.sortKeys(function(a, b) { + return _this.config.x.type === 'time' + ? d3.ascending(new Date(a), new Date(b)) + : _this.config.x.order + ? d3.ascending( + _this.config.x.order.indexOf(a), + _this.config.x.order.indexOf(b) + ) + : sublevel === _this.config.color_by && _this.config.legend.order + ? d3.ascending( + _this.config.legend.order.indexOf(a), + _this.config.legend.order.indexOf(b) + ) + : _this.config.x.type === 'ordinal' || _this.config.y.type === 'ordinal' + ? naturalSorter(a, b) + : d3.ascending(+a, +b); }); } - this_nest.rollup(function (r) { + this_nest.rollup(function(r) { var obj = { raw: r }; - var y_vals = r.map(function (m) { - return m[_this.config.y.column]; - }).sort(d3.ascending); - var x_vals = r.map(function (m) { - return m[_this.config.x.column]; - }).sort(d3.ascending); - obj.x = _this.config.x.type === 'ordinal' ? r[0][_this.config.x.column] : summarize(x_vals, mark.summarizeX); - obj.y = _this.config.y.type === 'ordinal' ? r[0][_this.config.y.column] : summarize(y_vals, mark.summarizeY); - - obj.x_q25 = _this.config.error_bars && _this.config.y.type === 'ordinal' ? d3.quantile(x_vals, 0.25) : obj.x; - obj.x_q75 = _this.config.error_bars && _this.config.y.type === 'ordinal' ? d3.quantile(x_vals, 0.75) : obj.x; + var y_vals = r + .map(function(m) { + return m[_this.config.y.column]; + }) + .sort(d3.ascending); + var x_vals = r + .map(function(m) { + return m[_this.config.x.column]; + }) + .sort(d3.ascending); + obj.x = _this.config.x.type === 'ordinal' + ? r[0][_this.config.x.column] + : summarize(x_vals, mark.summarizeX); + obj.y = _this.config.y.type === 'ordinal' + ? r[0][_this.config.y.column] + : summarize(y_vals, mark.summarizeY); + + obj.x_q25 = _this.config.error_bars && _this.config.y.type === 'ordinal' + ? d3.quantile(x_vals, 0.25) + : obj.x; + obj.x_q75 = _this.config.error_bars && _this.config.y.type === 'ordinal' + ? d3.quantile(x_vals, 0.75) + : obj.x; obj.y_q25 = _this.config.error_bars ? d3.quantile(y_vals, 0.25) : obj.y; obj.y_q75 = _this.config.error_bars ? d3.quantile(y_vals, 0.75) : obj.y; dom_xs.push([obj.x_q25, obj.x_q75, obj.x]); dom_ys.push([obj.y_q25, obj.y_q75, obj.y]); if (mark.summarizeY === 'cumulative') { - var interm = entries.filter(function (f) { - return _this.config.x.type === 'time' ? new Date(f[_this.config.x.column]) <= new Date(r[0][_this.config.x.column]) : +f[_this.config.x.column] <= +r[0][_this.config.x.column]; + var interm = entries.filter(function(f) { + return _this.config.x.type === 'time' + ? new Date(f[_this.config.x.column]) <= + new Date(r[0][_this.config.x.column]) + : +f[_this.config.x.column] <= +r[0][_this.config.x.column]; }); if (mark.per.length) { - interm = interm.filter(function (f) { + interm = interm.filter(function(f) { return f[mark.per[0]] === r[0][mark.per[0]]; }); } - var cumul = _this.config.x.type === 'time' ? interm.length : d3.sum(interm.map(function (m) { - return +m[_this.config.y.column] || +m[_this.config.y.column] === 0 ? +m[_this.config.y.column] : 1; - })); + var cumul = _this.config.x.type === 'time' + ? interm.length + : d3.sum( + interm.map(function(m) { + return +m[_this.config.y.column] || +m[_this.config.y.column] === 0 + ? +m[_this.config.y.column] + : 1; + }) + ); dom_ys.push([cumul]); obj.y = cumul; } if (mark.summarizeX === 'cumulative') { - var _interm = entries.filter(function (f) { - return _this.config.y.type === 'time' ? new Date(f[_this.config.y.column]) <= new Date(r[0][_this.config.y.column]) : +f[_this.config.y.column] <= +r[0][_this.config.y.column]; + var _interm = entries.filter(function(f) { + return _this.config.y.type === 'time' + ? new Date(f[_this.config.y.column]) <= + new Date(r[0][_this.config.y.column]) + : +f[_this.config.y.column] <= +r[0][_this.config.y.column]; }); if (mark.per.length) { - _interm = _interm.filter(function (f) { + _interm = _interm.filter(function(f) { return f[mark.per[0]] === r[0][mark.per[0]]; }); } @@ -635,19 +863,31 @@ if (sublevel && mark.type === 'bar' && mark.split) { //calculate percentages in bars - test.forEach(function (e) { - var axis = _this.config.x.type === 'ordinal' || _this.config.x.type === 'linear' && _this.config.x.bin ? 'y' : 'x'; - e.total = d3.sum(e.values.map(function (m) { - return +m.values[axis]; - })); + test.forEach(function(e) { + var axis = _this.config.x.type === 'ordinal' || + (_this.config.x.type === 'linear' && _this.config.x.bin) + ? 'y' + : 'x'; + e.total = d3.sum( + e.values.map(function(m) { + return +m.values[axis]; + }) + ); var counter = 0; - e.values.forEach(function (v, i) { - if (_this.config.x.type === 'ordinal' || _this.config.x.type === 'linear' && _this.config.x.bin) { - v.values.y = mark.summarizeY === 'percent' ? v.values.y / e.total : v.values.y || 0; + e.values.forEach(function(v, i) { + if ( + _this.config.x.type === 'ordinal' || + (_this.config.x.type === 'linear' && _this.config.x.bin) + ) { + v.values.y = mark.summarizeY === 'percent' + ? v.values.y / e.total + : v.values.y || 0; counter += +v.values.y; v.values.start = e.values[i - 1] ? counter : v.values.y; } else { - v.values.x = mark.summarizeX === 'percent' ? v.values.x / e.total : v.values.x || 0; + v.values.x = mark.summarizeX === 'percent' + ? v.values.x / e.total + : v.values.x || 0; v.values.start = counter; counter += +v.values.x; } @@ -655,36 +895,59 @@ }); if (mark.arrange === 'stacked') { - if (this.config.x.type === 'ordinal' || this.config.x.type === 'linear' && this.config.x.bin) { - dom_y = d3.extent(test.map(function (m) { - return m.total; - })); + if ( + this.config.x.type === 'ordinal' || + (this.config.x.type === 'linear' && this.config.x.bin) + ) { + dom_y = d3.extent( + test.map(function(m) { + return m.total; + }) + ); } - if (this.config.y.type === 'ordinal' || this.config.y.type === 'linear' && this.config.y.bin) { - dom_x = d3.extent(test.map(function (m) { - return m.total; - })); + if ( + this.config.y.type === 'ordinal' || + (this.config.y.type === 'linear' && this.config.y.bin) + ) { + dom_x = d3.extent( + test.map(function(m) { + return m.total; + }) + ); } } } else { - var axis = this.config.x.type === 'ordinal' || this.config.x.type === 'linear' && this.config.x.bin ? 'y' : 'x'; - test.forEach(function (e) { - return e.total = e.values[axis]; + var axis = this.config.x.type === 'ordinal' || + (this.config.x.type === 'linear' && this.config.x.bin) + ? 'y' + : 'x'; + test.forEach(function(e) { + return (e.total = e.values[axis]); }); } - if (this.config.x.sort === 'total-ascending' && this.config.x.type == 'ordinal' || this.config.y.sort === 'total-descending' && this.config.y.type == 'ordinal') { - totalOrder = test.sort(function (a, b) { - return d3.ascending(a.total, b.total); - }).map(function (m) { - return m.key; - }); - } else if (this.config.x.sort === 'total-descending' && this.config.x.type == 'ordinal' || this.config.y.sort === 'total-ascending' && this.config.y.type == 'ordinal') { - totalOrder = test.sort(function (a, b) { - return d3.descending(+a.total, +b.total); - }).map(function (m) { - return m.key; - }); + if ( + (this.config.x.sort === 'total-ascending' && this.config.x.type == 'ordinal') || + (this.config.y.sort === 'total-descending' && this.config.y.type == 'ordinal') + ) { + totalOrder = test + .sort(function(a, b) { + return d3.ascending(a.total, b.total); + }) + .map(function(m) { + return m.key; + }); + } else if ( + (this.config.x.sort === 'total-descending' && this.config.x.type == 'ordinal') || + (this.config.y.sort === 'total-ascending' && this.config.y.type == 'ordinal') + ) { + totalOrder = test + .sort(function(a, b) { + return d3.descending(+a.total, +b.total); + }) + .map(function(m) { + return m.key; + }); } return { nested: test, dom_x: dom_x, dom_y: dom_y, totalOrder: totalOrder }; @@ -708,7 +971,9 @@ var config = this.config; var x_behavior = config.x.behavior || 'raw'; var y_behavior = config.y.behavior || 'raw'; - var sublevel = mark.type === 'line' ? config.x.column : mark.type === 'bar' && mark.split ? mark.split : null; + var sublevel = mark.type === 'line' + ? config.x.column + : mark.type === 'bar' && mark.split ? mark.split : null; ////////////////////////////////////////////////////////////////////////////////// // DATA PREP @@ -719,73 +984,127 @@ //prepare nested data required for bar charts var raw_nest = void 0; if (mark.type === 'bar') { - raw_nest = mark.arrange !== 'stacked' ? makeNest.call(this, mark, cleaned, sublevel) : makeNest.call(this, mark, cleaned); + raw_nest = mark.arrange !== 'stacked' + ? makeNest.call(this, mark, cleaned, sublevel) + : makeNest.call(this, mark, cleaned); } else if (mark.summarizeX === 'count' || mark.summarizeY === 'count') { raw_nest = makeNest.call(this, mark, cleaned); } // Get the domain for the mark based on the raw data - var raw_dom_x = mark.summarizeX === 'cumulative' ? [0, cleaned.length] : config.x.type === 'ordinal' ? d3.set(cleaned.map(function (m) { - return m[config.x.column]; - })).values().filter(function (f) { - return f; - }) : mark.split && mark.arrange !== 'stacked' ? d3.extent(d3.merge(raw_nest.nested.map(function (m) { - return m.values.map(function (p) { - return p.values.raw.length; - }); - }))) : mark.summarizeX === 'count' ? d3.extent(raw_nest.nested.map(function (m) { - return m.values.raw.length; - })) : d3.extent(cleaned.map(function (m) { - return +m[config.x.column]; - }).filter(function (f) { - return +f || +f === 0; - })); - - var raw_dom_y = mark.summarizeY === 'cumulative' ? [0, cleaned.length] : config.y.type === 'ordinal' ? d3.set(cleaned.map(function (m) { - return m[config.y.column]; - })).values().filter(function (f) { - return f; - }) : mark.split && mark.arrange !== 'stacked' ? d3.extent(d3.merge(raw_nest.nested.map(function (m) { - return m.values.map(function (p) { - return p.values.raw.length; - }); - }))) : mark.summarizeY === 'count' ? d3.extent(raw_nest.nested.map(function (m) { - return m.values.raw.length; - })) : d3.extent(cleaned.map(function (m) { - return +m[config.y.column]; - }).filter(function (f) { - return +f || +f === 0; - })); + var raw_dom_x = mark.summarizeX === 'cumulative' + ? [0, cleaned.length] + : config.x.type === 'ordinal' + ? d3 + .set( + cleaned.map(function(m) { + return m[config.x.column]; + }) + ) + .values() + .filter(function(f) { + return f; + }) + : mark.split && mark.arrange !== 'stacked' + ? d3.extent( + d3.merge( + raw_nest.nested.map(function(m) { + return m.values.map(function(p) { + return p.values.raw.length; + }); + }) + ) + ) + : mark.summarizeX === 'count' + ? d3.extent( + raw_nest.nested.map(function(m) { + return m.values.raw.length; + }) + ) + : d3.extent( + cleaned + .map(function(m) { + return +m[config.x.column]; + }) + .filter(function(f) { + return +f || +f === 0; + }) + ); + + var raw_dom_y = mark.summarizeY === 'cumulative' + ? [0, cleaned.length] + : config.y.type === 'ordinal' + ? d3 + .set( + cleaned.map(function(m) { + return m[config.y.column]; + }) + ) + .values() + .filter(function(f) { + return f; + }) + : mark.split && mark.arrange !== 'stacked' + ? d3.extent( + d3.merge( + raw_nest.nested.map(function(m) { + return m.values.map(function(p) { + return p.values.raw.length; + }); + }) + ) + ) + : mark.summarizeY === 'count' + ? d3.extent( + raw_nest.nested.map(function(m) { + return m.values.raw.length; + }) + ) + : d3.extent( + cleaned + .map(function(m) { + return +m[config.y.column]; + }) + .filter(function(f) { + return +f || +f === 0; + }) + ); var filtered = cleaned; var filt1_xs = []; var filt1_ys = []; if (this.filters.length) { - this.filters.forEach(function (e) { - filtered = filtered.filter(function (d) { - return e.all === true && e.index === 0 ? d : e.val instanceof Array ? e.val.indexOf(d[e.col]) > -1 : d[e.col] === e.val; + this.filters.forEach(function(e) { + filtered = filtered.filter(function(d) { + return e.all === true && e.index === 0 + ? d + : e.val instanceof Array + ? e.val.indexOf(d[e.col]) > -1 + : d[e.col] === e.val; }); }); //get domain for all non-All values of first filter if (config.x.behavior === 'firstfilter' || config.y.behavior === 'firstfilter') { - this.filters[0].choices.filter(function (f) { - return f !== 'All'; - }).forEach(function (e) { - var perfilter = cleaned.filter(function (f) { - return f[_this.filters[0].col] === e; + this.filters[0].choices + .filter(function(f) { + return f !== 'All'; + }) + .forEach(function(e) { + var perfilter = cleaned.filter(function(f) { + return f[_this.filters[0].col] === e; + }); + var filt_nested = makeNest.call(_this, mark, perfilter, sublevel); + filt1_xs.push(filt_nested.dom_x); + filt1_ys.push(filt_nested.dom_y); }); - var filt_nested = makeNest.call(_this, mark, perfilter, sublevel); - filt1_xs.push(filt_nested.dom_x); - filt1_ys.push(filt_nested.dom_y); - }); } } //filter on mark-specific instructions if (mark.values) { var _loop = function _loop(a) { - filtered = filtered.filter(function (f) { + filtered = filtered.filter(function(f) { return mark.values[a].indexOf(f[a]) > -1; }); }; @@ -811,43 +1130,112 @@ } //several criteria must be met in order to use the 'firstfilter' domain - var nonall = Boolean(this.filters.length && this.filters[0].val !== 'All' && this.filters.slice(1).filter(function (f) { - return f.val === 'All'; - }).length === this.filters.length - 1); - - var pre_x_dom = !this.filters.length ? flex_dom_x : x_behavior === 'raw' ? raw_dom_x : nonall && x_behavior === 'firstfilter' ? filt1_dom_x : flex_dom_x; - var pre_y_dom = !this.filters.length ? flex_dom_y : y_behavior === 'raw' ? raw_dom_y : nonall && y_behavior === 'firstfilter' ? filt1_dom_y : flex_dom_y; - - var x_dom = config.x_dom ? config.x_dom : config.x.type === 'ordinal' && config.x.behavior === 'flex' ? d3.set(filtered.map(function (m) { - return m[config.x.column]; - })).values() : config.x.type === 'ordinal' ? d3.set(cleaned.map(function (m) { - return m[config.x.column]; - })).values() : pre_x_dom; - - var y_dom = config.y_dom ? config.y_dom : config.y.type === 'ordinal' && config.y.behavior === 'flex' ? d3.set(filtered.map(function (m) { - return m[config.y.column]; - })).values() : config.y.type === 'ordinal' ? d3.set(cleaned.map(function (m) { - return m[config.y.column]; - })).values() : pre_y_dom; + var nonall = Boolean( + this.filters.length && + this.filters[0].val !== 'All' && + this.filters.slice(1).filter(function(f) { + return f.val === 'All'; + }).length === + this.filters.length - 1 + ); + + var pre_x_dom = !this.filters.length + ? flex_dom_x + : x_behavior === 'raw' + ? raw_dom_x + : nonall && x_behavior === 'firstfilter' ? filt1_dom_x : flex_dom_x; + var pre_y_dom = !this.filters.length + ? flex_dom_y + : y_behavior === 'raw' + ? raw_dom_y + : nonall && y_behavior === 'firstfilter' ? filt1_dom_y : flex_dom_y; + + var x_dom = config.x_dom + ? config.x_dom + : config.x.type === 'ordinal' && config.x.behavior === 'flex' + ? d3 + .set( + filtered.map(function(m) { + return m[config.x.column]; + }) + ) + .values() + : config.x.type === 'ordinal' + ? d3 + .set( + cleaned.map(function(m) { + return m[config.x.column]; + }) + ) + .values() + : pre_x_dom; + + var y_dom = config.y_dom + ? config.y_dom + : config.y.type === 'ordinal' && config.y.behavior === 'flex' + ? d3 + .set( + filtered.map(function(m) { + return m[config.y.column]; + }) + ) + .values() + : config.y.type === 'ordinal' + ? d3 + .set( + cleaned.map(function(m) { + return m[config.y.column]; + }) + ) + .values() + : pre_y_dom; //set lower limit of linear domain to 0 when other axis is ordinal and mark type is set to 'bar', provided no values are negative if (mark.type === 'bar') { - if (config.x.behavior !== 'flex' && config.x.type === 'linear' && config.y.type === 'ordinal' && raw_dom_x[0] >= 0) x_dom[0] = 0; - - if (config.y.behavior !== 'flex' && config.x.type === 'ordinal' && config.y.type === 'linear' && raw_dom_y[0] >= 0) y_dom[0] = 0; + if ( + config.x.behavior !== 'flex' && + config.x.type === 'linear' && + config.y.type === 'ordinal' && + raw_dom_x[0] >= 0 + ) + x_dom[0] = 0; + + if ( + config.y.behavior !== 'flex' && + config.x.type === 'ordinal' && + config.y.type === 'linear' && + raw_dom_y[0] >= 0 + ) + y_dom[0] = 0; } //update domains with those specified in the config - if (config.x.domain && (config.x.domain[0] || config.x.domain[0] === 0) && !isNaN(+config.x.domain[0])) { + if ( + config.x.domain && + (config.x.domain[0] || config.x.domain[0] === 0) && + !isNaN(+config.x.domain[0]) + ) { x_dom[0] = config.x.domain[0]; } - if (config.x.domain && (config.x.domain[1] || config.x.domain[1] === 0) && !isNaN(+config.x.domain[1])) { + if ( + config.x.domain && + (config.x.domain[1] || config.x.domain[1] === 0) && + !isNaN(+config.x.domain[1]) + ) { x_dom[1] = config.x.domain[1]; } - if (config.y.domain && (config.y.domain[0] || config.y.domain[0] === 0) && !isNaN(+config.y.domain[0])) { + if ( + config.y.domain && + (config.y.domain[0] || config.y.domain[0] === 0) && + !isNaN(+config.y.domain[0]) + ) { y_dom[0] = config.y.domain[0]; } - if (config.y.domain && (config.y.domain[1] || config.y.domain[1] === 0) && !isNaN(+config.y.domain[1])) { + if ( + config.y.domain && + (config.y.domain[1] || config.y.domain[1] === 0) && + !isNaN(+config.y.domain[1]) + ) { y_dom[1] = config.y.domain[1]; } @@ -868,15 +1256,24 @@ function setColorScale() { var config = this.config; var data = config.legend.behavior === 'flex' ? this.filtered_data : this.raw_data; - var colordom = Array.isArray(config.color_dom) && config.color_dom.length ? config.color_dom.slice() : d3.set(data.map(function (m) { - return m[config.color_by]; - })).values().filter(function (f) { - return f && f !== 'undefined'; - }); - - if (config.legend.order) colordom.sort(function (a, b) { - return d3.ascending(config.legend.order.indexOf(a), config.legend.order.indexOf(b)); - });else colordom.sort(naturalSorter); + var colordom = Array.isArray(config.color_dom) && config.color_dom.length + ? config.color_dom.slice() + : d3 + .set( + data.map(function(m) { + return m[config.color_by]; + }) + ) + .values() + .filter(function(f) { + return f && f !== 'undefined'; + }); + + if (config.legend.order) + colordom.sort(function(a, b) { + return d3.ascending(config.legend.order.indexOf(a), config.legend.order.indexOf(b)); + }); + else colordom.sort(naturalSorter); this.colorScale = d3.scale.ordinal().domain(colordom).range(config.colors); } @@ -912,11 +1309,29 @@ x.range([0, +max_range]).clamp(Boolean(config.x.clamp)); } - var xFormat = config.x.format ? config.x.format : config.marks.map(function (m) { - return m.summarizeX === 'percent'; - }).indexOf(true) > -1 ? '0%' : type === 'time' ? '%x' : '.0f'; + var xFormat = config.x.format + ? config.x.format + : config.marks + .map(function(m) { + return m.summarizeX === 'percent'; + }) + .indexOf(true) > -1 + ? '0%' + : type === 'time' ? '%x' : '.0f'; var tick_count = Math.max(2, Math.min(max_range / 80, 8)); - var xAxis = d3.svg.axis().scale(x).orient(config.x.location).ticks(tick_count).tickFormat(type === 'ordinal' ? null : type === 'time' ? d3.time.format(xFormat) : d3.format(xFormat)).tickValues(config.x.ticks ? config.x.ticks : null).innerTickSize(6).outerTickSize(3); + var xAxis = d3.svg + .axis() + .scale(x) + .orient(config.x.location) + .ticks(tick_count) + .tickFormat( + type === 'ordinal' + ? null + : type === 'time' ? d3.time.format(xFormat) : d3.format(xFormat) + ) + .tickValues(config.x.ticks ? config.x.ticks : null) + .innerTickSize(6) + .outerTickSize(3); this.svg.select('g.x.axis').attr('class', 'x axis ' + type); this.x = x; @@ -953,11 +1368,29 @@ y.range([+max_range, 0]).clamp(Boolean(config.y_clamp)); } - var yFormat = config.y.format ? config.y.format : config.marks.map(function (m) { - return m.summarizeY === 'percent'; - }).indexOf(true) > -1 ? '0%' : '.0f'; + var yFormat = config.y.format + ? config.y.format + : config.marks + .map(function(m) { + return m.summarizeY === 'percent'; + }) + .indexOf(true) > -1 + ? '0%' + : '.0f'; var tick_count = Math.max(2, Math.min(max_range / 80, 8)); - var yAxis = d3.svg.axis().scale(y).orient('left').ticks(tick_count).tickFormat(type === 'ordinal' ? null : type === 'time' ? d3.time.format(yFormat) : d3.format(yFormat)).tickValues(config.y.ticks ? config.y.ticks : null).innerTickSize(6).outerTickSize(3); + var yAxis = d3.svg + .axis() + .scale(y) + .orient('left') + .ticks(tick_count) + .tickFormat( + type === 'ordinal' + ? null + : type === 'time' ? d3.time.format(yFormat) : d3.format(yFormat) + ) + .tickValues(config.y.ticks ? config.y.ticks : null) + .innerTickSize(6) + .outerTickSize(3); this.svg.select('g.y.axis').attr('class', 'y axis ' + type); @@ -971,22 +1404,45 @@ var aspect2 = 1 / config.aspect; var div_width = parseInt(this.wrap.style('width')); var max_width = config.max_width ? config.max_width : div_width; - var preWidth = !config.resizable ? config.width : !max_width || div_width < max_width ? div_width : this.raw_width; + var preWidth = !config.resizable + ? config.width + : !max_width || div_width < max_width ? div_width : this.raw_width; this.textSize(preWidth); this.margin = this.setMargins(); - var svg_width = config.x.type === 'ordinal' && +config.x.range_band ? this.raw_width + this.margin.left + this.margin.right : !config.resizable ? this.raw_width : !config.max_width || div_width < config.max_width ? div_width : this.raw_width; + var svg_width = config.x.type === 'ordinal' && +config.x.range_band + ? this.raw_width + this.margin.left + this.margin.right + : !config.resizable + ? this.raw_width + : !config.max_width || div_width < config.max_width ? div_width : this.raw_width; this.plot_width = svg_width - this.margin.left - this.margin.right; - var svg_height = config.y.type === 'ordinal' && +config.y.range_band ? this.raw_height + this.margin.top + this.margin.bottom : !config.resizable && config.height ? config.height : !config.resizable ? svg_width * aspect2 : this.plot_width * aspect2; + var svg_height = config.y.type === 'ordinal' && +config.y.range_band + ? this.raw_height + this.margin.top + this.margin.bottom + : !config.resizable && config.height + ? config.height + : !config.resizable ? svg_width * aspect2 : this.plot_width * aspect2; this.plot_height = svg_height - this.margin.top - this.margin.bottom; - d3.select(this.svg.node().parentNode).attr('width', svg_width).attr('height', svg_height).select('g').attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')'); - - this.svg.select('.overlay').attr('width', this.plot_width).attr('height', this.plot_height).classed('zoomable', config.zoomable); - - this.svg.select('.plotting-area').attr('width', this.plot_width).attr('height', this.plot_height + 1).attr('transform', 'translate(0, -1)'); + d3 + .select(this.svg.node().parentNode) + .attr('width', svg_width) + .attr('height', svg_height) + .select('g') + .attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')'); + + this.svg + .select('.overlay') + .attr('width', this.plot_width) + .attr('height', this.plot_height) + .classed('zoomable', config.zoomable); + + this.svg + .select('.plotting-area') + .attr('width', this.plot_width) + .attr('height', this.plot_height + 1) + .attr('transform', 'translate(0, -1)'); this.xScaleAxis(); this.yScaleAxis(); @@ -1004,11 +1460,23 @@ var gYAxisTrans = config.transitions ? g_y_axis.transition() : g_y_axis; gYAxisTrans.call(this.yAxis); - x_axis_label.attr('transform', 'translate(' + this.plot_width / 2 + ',' + (this.margin.bottom - 2) + ')'); + x_axis_label.attr( + 'transform', + 'translate(' + this.plot_width / 2 + ',' + (this.margin.bottom - 2) + ')' + ); y_axis_label.attr('x', -1 * this.plot_height / 2).attr('y', -1 * this.margin.left); - this.svg.selectAll('.axis .domain').attr({ fill: 'none', stroke: '#ccc', 'stroke-width': 1, 'shape-rendering': 'crispEdges' }); - this.svg.selectAll('.axis .tick line').attr({ stroke: '#eee', 'stroke-width': 1, 'shape-rendering': 'crispEdges' }); + this.svg + .selectAll('.axis .domain') + .attr({ + fill: 'none', + stroke: '#ccc', + 'stroke-width': 1, + 'shape-rendering': 'crispEdges' + }); + this.svg + .selectAll('.axis .tick line') + .attr({ stroke: '#eee', 'stroke-width': 1, 'shape-rendering': 'crispEdges' }); this.drawGridlines(); @@ -1057,13 +1525,17 @@ function setMargins() { var _this = this; - var y_ticks = this.yAxis.tickFormat() ? this.y.domain().map(function (m) { - return _this.yAxis.tickFormat()(m); - }) : this.y.domain(); - - var max_y_text_length = d3.max(y_ticks.map(function (m) { - return String(m).length; - })); + var y_ticks = this.yAxis.tickFormat() + ? this.y.domain().map(function(m) { + return _this.yAxis.tickFormat()(m); + }) + : this.y.domain(); + + var max_y_text_length = d3.max( + y_ticks.map(function(m) { + return String(m).length; + }) + ); if (this.config.y_format && this.config.y_format.indexOf('%') > -1) { max_y_text_length += 1; } @@ -1073,7 +1545,8 @@ var font_size = parseInt(this.wrap.style('font-size')); var x_second = this.config.x2_interval ? 1 : 0; var y_margin = max_y_text_length * font_size * 0.5 + font_size * y_label_on * 1.5 || 8; - var x_margin = font_size + font_size / 1.5 + font_size * x_label_on + font_size * x_second || 8; + var x_margin = + font_size + font_size / 1.5 + font_size * x_label_on + font_size * x_second || 8; y_margin += 6; x_margin += 3; @@ -1081,7 +1554,9 @@ return { top: this.config.margin && this.config.margin.top ? this.config.margin.top : 8, right: this.config.margin && this.config.margin.right ? this.config.margin.right : 16, - bottom: this.config.margin && this.config.margin.bottom ? this.config.margin.bottom : x_margin, + bottom: this.config.margin && this.config.margin.bottom + ? this.config.margin.bottom + : x_margin, left: this.config.margin && this.config.margin.left ? this.config.margin.left : y_margin }; } @@ -1091,8 +1566,10 @@ if (this.config.gridlines) { this.svg.select('.y.axis').selectAll('.tick line').attr('x1', 0); this.svg.select('.x.axis').selectAll('.tick line').attr('y1', 0); - if (this.config.gridlines === 'y' || this.config.gridlines === 'xy') this.svg.select('.y.axis').selectAll('.tick line').attr('x1', this.plot_width); - if (this.config.gridlines === 'x' || this.config.gridlines === 'xy') this.svg.select('.x.axis').selectAll('.tick line').attr('y1', -this.plot_height); + if (this.config.gridlines === 'y' || this.config.gridlines === 'xy') + this.svg.select('.y.axis').selectAll('.tick line').attr('x1', this.plot_width); + if (this.config.gridlines === 'x' || this.config.gridlines === 'xy') + this.svg.select('.x.axis').selectAll('.tick line').attr('y1', -this.plot_height); } else { this.svg.select('.y.axis').selectAll('.tick line').attr('x1', 0); this.svg.select('.x.axis').selectAll('.tick line').attr('y1', 0); @@ -1100,15 +1577,23 @@ } function makeLegend() { - var scale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.colorScale; + var scale = arguments.length > 0 && arguments[0] !== undefined + ? arguments[0] + : this.colorScale; var label = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; var custom_data = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; var config = this.config; - config.legend.mark = config.legend.mark ? config.legend.mark : config.marks.length && config.marks[0].type === 'bar' ? 'square' : config.marks.length ? config.marks[0].type : 'square'; + config.legend.mark = config.legend.mark + ? config.legend.mark + : config.marks.length && config.marks[0].type === 'bar' + ? 'square' + : config.marks.length ? config.marks[0].type : 'square'; - var legend_label = label ? label : typeof config.legend.label === 'string' ? config.legend.label : ''; + var legend_label = label + ? label + : typeof config.legend.label === 'string' ? config.legend.label : ''; var legendOriginal = this.legend || this.wrap.select('.legend'); var legend = legendOriginal; @@ -1123,7 +1608,12 @@ } else { //multiples - keep legend outside of individual charts' wraps if (this.config.legend.location === 'top' || this.config.legend.location === 'left') { - this.parent.wrap.node().insertBefore(legendOriginal.node(), this.parent.wrap.select('.wc-chart').node()); + this.parent.wrap + .node() + .insertBefore( + legendOriginal.node(), + this.parent.wrap.select('.wc-chart').node() + ); } else { this.parent.wrap.node().appendChild(legendOriginal.node()); } @@ -1131,40 +1621,65 @@ legend.style('padding', 0); - var legend_data = custom_data || scale.domain().slice(0).filter(function (f) { - return f !== undefined && f !== null; - }).map(function (m) { - return { label: m, mark: config.legend.mark }; - }); + var legend_data = + custom_data || + scale + .domain() + .slice(0) + .filter(function(f) { + return f !== undefined && f !== null; + }) + .map(function(m) { + return { label: m, mark: config.legend.mark }; + }); - legend.select('.legend-title').text(legend_label).style('display', legend_label ? 'inline' : 'none').style('margin-right', '1em'); + legend + .select('.legend-title') + .text(legend_label) + .style('display', legend_label ? 'inline' : 'none') + .style('margin-right', '1em'); - var leg_parts = legend.selectAll('.legend-item').data(legend_data, function (d) { + var leg_parts = legend.selectAll('.legend-item').data(legend_data, function(d) { return d.label + d.mark; }); leg_parts.exit().remove(); - var legendPartDisplay = this.config.legend.location === 'bottom' || this.config.legend.location === 'top' ? 'inline-block' : 'block'; - var new_parts = leg_parts.enter().append('li').attr('class', 'legend-item').style({ 'list-style-type': 'none', 'margin-right': '1em' }); - new_parts.append('span').attr('class', 'legend-mark-text').style('color', function (d) { + var legendPartDisplay = this.config.legend.location === 'bottom' || + this.config.legend.location === 'top' + ? 'inline-block' + : 'block'; + var new_parts = leg_parts + .enter() + .append('li') + .attr('class', 'legend-item') + .style({ 'list-style-type': 'none', 'margin-right': '1em' }); + new_parts.append('span').attr('class', 'legend-mark-text').style('color', function(d) { return scale(d.label); }); - new_parts.append('svg').attr('class', 'legend-color-block').attr('width', '1.1em').attr('height', '1.1em').style({ - position: 'relative', - top: '0.2em' - }); + new_parts + .append('svg') + .attr('class', 'legend-color-block') + .attr('width', '1.1em') + .attr('height', '1.1em') + .style({ + position: 'relative', + top: '0.2em' + }); leg_parts.style('display', legendPartDisplay); if (config.legend.order) { - leg_parts.sort(function (a, b) { - return d3.ascending(config.legend.order.indexOf(a.label), config.legend.order.indexOf(b.label)); + leg_parts.sort(function(a, b) { + return d3.ascending( + config.legend.order.indexOf(a.label), + config.legend.order.indexOf(b.label) + ); }); } leg_parts.selectAll('.legend-color-block').select('.legend-mark').remove(); - leg_parts.selectAll('.legend-color-block').each(function (e) { + leg_parts.selectAll('.legend-color-block').each(function(e) { var svg = d3.select(this); if (e.mark === 'circle') { svg.append('circle').attr({ @@ -1192,20 +1707,33 @@ }); } }); - leg_parts.selectAll('.legend-color-block').select('.legend-mark').attr('fill', function (d) { - return d.color || scale(d.label); - }).attr('stroke', function (d) { - return d.color || scale(d.label); - }).each(function (e) { - d3.select(this).attr(e.attributes); - }); + leg_parts + .selectAll('.legend-color-block') + .select('.legend-mark') + .attr('fill', function(d) { + return d.color || scale(d.label); + }) + .attr('stroke', function(d) { + return d.color || scale(d.label); + }) + .each(function(e) { + d3.select(this).attr(e.attributes); + }); - new_parts.append('span').attr('class', 'legend-label').style('margin-left', '0.25em').text(function (d) { - return d.label; - }); + new_parts + .append('span') + .attr('class', 'legend-label') + .style('margin-left', '0.25em') + .text(function(d) { + return d.label; + }); if (scale.domain().length > 0) { - var legendDisplay = (this.config.legend.location === 'bottom' || this.config.legend.location === 'top') && !this.parent ? 'block' : 'inline-block'; + var legendDisplay = (this.config.legend.location === 'bottom' || + this.config.legend.location === 'top') && + !this.parent + ? 'block' + : 'inline-block'; legend.style('display', legendDisplay); } else { legend.style('display', 'none'); @@ -1215,42 +1743,67 @@ } function updateDataMarks() { - this.drawBars(this.marks.filter(function (f) { - return f.type === 'bar'; - })); - this.drawLines(this.marks.filter(function (f) { - return f.type === 'line'; - })); - this.drawPoints(this.marks.filter(function (f) { - return f.type === 'circle'; - })); - this.drawText(this.marks.filter(function (f) { - return f.type === 'text'; - })); + this.drawBars( + this.marks.filter(function(f) { + return f.type === 'bar'; + }) + ); + this.drawLines( + this.marks.filter(function(f) { + return f.type === 'line'; + }) + ); + this.drawPoints( + this.marks.filter(function(f) { + return f.type === 'circle'; + }) + ); + this.drawText( + this.marks.filter(function(f) { + return f.type === 'text'; + }) + ); this.marks.supergroups = this.svg.selectAll('g.supergroup'); } function drawArea(area_drawer, area_data, datum_accessor) { - var class_match = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'chart-area'; + var class_match = arguments.length > 3 && arguments[3] !== undefined + ? arguments[3] + : 'chart-area'; var _this = this; var bind_accessor = arguments[4]; - var attr_accessor = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : function (d) { - return d; - }; + var attr_accessor = arguments.length > 5 && arguments[5] !== undefined + ? arguments[5] + : function(d) { + return d; + }; var area_grps = this.svg.selectAll('.' + class_match).data(area_data, bind_accessor); area_grps.exit().remove(); - area_grps.enter().append('g').attr('class', function (d) { - return class_match + ' ' + d.key; - }).append('path'); - - var areaPaths = area_grps.select('path').datum(datum_accessor).attr('fill', function (d) { - var d_attr = attr_accessor(d); - return d_attr ? _this.colorScale(d_attr[_this.config.color_by]) : null; - }).attr('fill-opacity', this.config.fill_opacity || this.config.fill_opacity === 0 ? this.config.fill_opacity : 0.3); + area_grps + .enter() + .append('g') + .attr('class', function(d) { + return class_match + ' ' + d.key; + }) + .append('path'); + + var areaPaths = area_grps + .select('path') + .datum(datum_accessor) + .attr('fill', function(d) { + var d_attr = attr_accessor(d); + return d_attr ? _this.colorScale(d_attr[_this.config.color_by]) : null; + }) + .attr( + 'fill-opacity', + this.config.fill_opacity || this.config.fill_opacity === 0 + ? this.config.fill_opacity + : 0.3 + ); //don't transition if config says not to var areaPathTransitions = this.config.transitions ? areaPaths.transition() : areaPaths; @@ -1267,27 +1820,32 @@ var rawData = this.raw_data; var config = this.config; - var bar_supergroups = this.svg.selectAll('.bar-supergroup').data(marks, function (d, i) { + var bar_supergroups = this.svg.selectAll('.bar-supergroup').data(marks, function(d, i) { return i + '-' + d.per.join('-'); }); - bar_supergroups.enter().append('g').attr('class', function (d) { + bar_supergroups.enter().append('g').attr('class', function(d) { return 'supergroup bar-supergroup ' + d.id; }); bar_supergroups.exit().remove(); - var bar_groups = bar_supergroups.selectAll('.bar-group').data(function (d) { - return d.data; - }, function (d) { - return d.key; - }); + var bar_groups = bar_supergroups.selectAll('.bar-group').data( + function(d) { + return d.data; + }, + function(d) { + return d.key; + } + ); var old_bar_groups = bar_groups.exit(); var nu_bar_groups = void 0; var bars = void 0; - var oldBarsTrans = config.transitions ? old_bar_groups.selectAll('.bar').transition() : old_bar_groups.selectAll('.bar'); + var oldBarsTrans = config.transitions + ? old_bar_groups.selectAll('.bar').transition() + : old_bar_groups.selectAll('.bar'); var oldBarGroupsTrans = config.transitions ? old_bar_groups.transition() : old_bar_groups; if (config.x.type === 'ordinal') { @@ -1295,207 +1853,327 @@ oldBarGroupsTrans.remove(); - nu_bar_groups = bar_groups.enter().append('g').attr('class', function (d) { + nu_bar_groups = bar_groups.enter().append('g').attr('class', function(d) { return 'bar-group ' + d.key; }); nu_bar_groups.append('title'); - bars = bar_groups.selectAll('rect').data(function (d) { - return d.values instanceof Array ? d.values.sort(function (a, b) { - return _this.colorScale.domain().indexOf(b.key) - _this.colorScale.domain().indexOf(a.key); - }) : [d]; - }, function (d) { - return d.key; - }); + bars = bar_groups.selectAll('rect').data( + function(d) { + return d.values instanceof Array + ? d.values.sort(function(a, b) { + return ( + _this.colorScale.domain().indexOf(b.key) - + _this.colorScale.domain().indexOf(a.key) + ); + }) + : [d]; + }, + function(d) { + return d.key; + } + ); var exitBars = config.transitions ? bars.exit().transition() : bars.exit(); exitBars.attr('y', this.y(0)).attr('height', 0).remove(); - bars.enter().append('rect').attr('class', function (d) { - return 'wc-data-mark bar ' + d.key; - }).style('clip-path', 'url(#' + chart.id + ')').attr('y', this.y(0)).attr('height', 0).append('title'); - - bars.attr('shape-rendering', 'crispEdges').attr('stroke', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }).attr('fill', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); + bars + .enter() + .append('rect') + .attr('class', function(d) { + return 'wc-data-mark bar ' + d.key; + }) + .style('clip-path', 'url(#' + chart.id + ')') + .attr('y', this.y(0)) + .attr('height', 0) + .append('title'); + + bars + .attr('shape-rendering', 'crispEdges') + .attr('stroke', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }) + .attr('fill', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); - bars.each(function (d) { + bars.each(function(d) { var mark = d3.select(this.parentNode.parentNode).datum(); d.tooltip = mark.tooltip; - d.arrange = mark.split && mark.arrange ? mark.arrange : mark.split ? 'grouped' : null; - d.subcats = config.legend.order ? config.legend.order.slice().reverse() : mark.values && mark.values[mark.split] ? mark.values[mark.split] : d3.set(rawData.map(function (m) { - return m[mark.split]; - })).values(); + d.arrange = mark.split && mark.arrange + ? mark.arrange + : mark.split ? 'grouped' : null; + d.subcats = config.legend.order + ? config.legend.order.slice().reverse() + : mark.values && mark.values[mark.split] + ? mark.values[mark.split] + : d3 + .set( + rawData.map(function(m) { + return m[mark.split]; + }) + ) + .values(); d3.select(this).attr(mark.attributes); }); - var xformat = config.marks.map(function (m) { - return m.summarizeX === 'percent'; - }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.x.format); - var yformat = config.marks.map(function (m) { - return m.summarizeY === 'percent'; - }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.y.format); - bars.select('title').text(function (d) { + var xformat = config.marks + .map(function(m) { + return m.summarizeX === 'percent'; + }) + .indexOf(true) > -1 + ? d3.format('0%') + : d3.format(config.x.format); + var yformat = config.marks + .map(function(m) { + return m.summarizeY === 'percent'; + }) + .indexOf(true) > -1 + ? d3.format('0%') + : d3.format(config.y.format); + bars.select('title').text(function(d) { var tt = d.tooltip || ''; - return tt.replace(/\$x/g, xformat(d.values.x)).replace(/\$y/g, yformat(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { - return d.values.raw[0][orig]; - }); + return tt + .replace(/\$x/g, xformat(d.values.x)) + .replace(/\$y/g, yformat(d.values.y)) + .replace(/\[(.+?)\]/g, function(str, orig) { + return d.values.raw[0][orig]; + }); }); var barsTrans = config.transitions ? bars.transition() : bars; - barsTrans.attr('x', function (d) { - var position = void 0; - if (!d.arrange || d.arrange === 'stacked') { - return _this.x(d.values.x); - } else if (d.arrange === 'nested') { - var _position = d.subcats.indexOf(d.key); - var offset = _position ? _this.x.rangeBand() / (d.subcats.length * 0.75) / _position : _this.x.rangeBand(); - return _this.x(d.values.x) + (_this.x.rangeBand() - offset) / 2; - } else { - position = d.subcats.indexOf(d.key); - return _this.x(d.values.x) + _this.x.rangeBand() / d.subcats.length * position; - } - }).attr('y', function (d) { - if (d.arrange !== 'stacked') { - return _this.y(d.values.y); - } else { - return _this.y(d.values.start); - } - }).attr('width', function (d) { - if (!d.arrange || d.arrange === 'stacked') { - return _this.x.rangeBand(); - } else if (d.arrange === 'nested') { - var position = d.subcats.indexOf(d.key); - return position ? _this.x.rangeBand() / (d.subcats.length * 0.75) / position : _this.x.rangeBand(); - } else { - return _this.x.rangeBand() / d.subcats.length; - } - }).attr('height', function (d) { - return _this.y(0) - _this.y(d.values.y); - }); + barsTrans + .attr('x', function(d) { + var position = void 0; + if (!d.arrange || d.arrange === 'stacked') { + return _this.x(d.values.x); + } else if (d.arrange === 'nested') { + var _position = d.subcats.indexOf(d.key); + var offset = _position + ? _this.x.rangeBand() / (d.subcats.length * 0.75) / _position + : _this.x.rangeBand(); + return _this.x(d.values.x) + (_this.x.rangeBand() - offset) / 2; + } else { + position = d.subcats.indexOf(d.key); + return ( + _this.x(d.values.x) + _this.x.rangeBand() / d.subcats.length * position + ); + } + }) + .attr('y', function(d) { + if (d.arrange !== 'stacked') { + return _this.y(d.values.y); + } else { + return _this.y(d.values.start); + } + }) + .attr('width', function(d) { + if (!d.arrange || d.arrange === 'stacked') { + return _this.x.rangeBand(); + } else if (d.arrange === 'nested') { + var position = d.subcats.indexOf(d.key); + return position + ? _this.x.rangeBand() / (d.subcats.length * 0.75) / position + : _this.x.rangeBand(); + } else { + return _this.x.rangeBand() / d.subcats.length; + } + }) + .attr('height', function(d) { + return _this.y(0) - _this.y(d.values.y); + }); } else if (config.y.type === 'ordinal') { oldBarsTrans.attr('x', this.x(0)).attr('width', 0); oldBarGroupsTrans.remove(); - nu_bar_groups = bar_groups.enter().append('g').attr('class', function (d) { + nu_bar_groups = bar_groups.enter().append('g').attr('class', function(d) { return 'bar-group ' + d.key; }); nu_bar_groups.append('title'); - bars = bar_groups.selectAll('rect').data(function (d) { - return d.values instanceof Array ? d.values.sort(function (a, b) { - return _this.colorScale.domain().indexOf(b.key) - _this.colorScale.domain().indexOf(a.key); - }) : [d]; - }, function (d) { - return d.key; - }); + bars = bar_groups.selectAll('rect').data( + function(d) { + return d.values instanceof Array + ? d.values.sort(function(a, b) { + return ( + _this.colorScale.domain().indexOf(b.key) - + _this.colorScale.domain().indexOf(a.key) + ); + }) + : [d]; + }, + function(d) { + return d.key; + } + ); var _exitBars = config.transitions ? bars.exit().transition() : bars.exit(); _exitBars.attr('x', this.x(0)).attr('width', 0).remove(); - bars.enter().append('rect').attr('class', function (d) { - return 'wc-data-mark bar ' + d.key; - }).style('clip-path', 'url(#' + chart.id + ')').attr('x', this.x(0)).attr('width', 0).append('title'); - - bars.attr('shape-rendering', 'crispEdges').attr('stroke', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }).attr('fill', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); + bars + .enter() + .append('rect') + .attr('class', function(d) { + return 'wc-data-mark bar ' + d.key; + }) + .style('clip-path', 'url(#' + chart.id + ')') + .attr('x', this.x(0)) + .attr('width', 0) + .append('title'); + + bars + .attr('shape-rendering', 'crispEdges') + .attr('stroke', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }) + .attr('fill', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); - bars.each(function (d) { + bars.each(function(d) { var mark = d3.select(this.parentNode.parentNode).datum(); - d.arrange = mark.split && mark.arrange ? mark.arrange : mark.split ? 'grouped' : null; - d.subcats = config.legend.order ? config.legend.order.slice().reverse() : mark.values && mark.values[mark.split] ? mark.values[mark.split] : d3.set(rawData.map(function (m) { - return m[mark.split]; - })).values(); + d.arrange = mark.split && mark.arrange + ? mark.arrange + : mark.split ? 'grouped' : null; + d.subcats = config.legend.order + ? config.legend.order.slice().reverse() + : mark.values && mark.values[mark.split] + ? mark.values[mark.split] + : d3 + .set( + rawData.map(function(m) { + return m[mark.split]; + }) + ) + .values(); d.tooltip = mark.tooltip; d3.select(this).attr(mark.attributes); }); - var _xformat = config.marks.map(function (m) { - return m.summarizeX === 'percent'; - }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.x.format); - var _yformat = config.marks.map(function (m) { - return m.summarizeY === 'percent'; - }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.y.format); - bars.select('title').text(function (d) { + var _xformat = config.marks + .map(function(m) { + return m.summarizeX === 'percent'; + }) + .indexOf(true) > -1 + ? d3.format('0%') + : d3.format(config.x.format); + var _yformat = config.marks + .map(function(m) { + return m.summarizeY === 'percent'; + }) + .indexOf(true) > -1 + ? d3.format('0%') + : d3.format(config.y.format); + bars.select('title').text(function(d) { var tt = d.tooltip || ''; - return tt.replace(/\$x/g, _xformat(d.values.x)).replace(/\$y/g, _yformat(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { - return d.values.raw[0][orig]; - }); + return tt + .replace(/\$x/g, _xformat(d.values.x)) + .replace(/\$y/g, _yformat(d.values.y)) + .replace(/\[(.+?)\]/g, function(str, orig) { + return d.values.raw[0][orig]; + }); }); var _barsTrans = config.transitions ? bars.transition() : bars; - _barsTrans.attr('x', function (d) { - if (d.arrange === 'stacked' || !d.arrange) { - return d.values.start !== undefined ? _this.x(d.values.start) : _this.x(0); - } else { - return _this.x(0); - } - }).attr('y', function (d) { - if (d.arrange === 'nested') { - var position = d.subcats.indexOf(d.key); - var offset = position ? _this.y.rangeBand() / (d.subcats.length * 0.75) / position : _this.y.rangeBand(); - return _this.y(d.values.y) + (_this.y.rangeBand() - offset) / 2; - } else if (d.arrange === 'grouped') { - var _position2 = d.subcats.indexOf(d.key); - return _this.y(d.values.y) + _this.y.rangeBand() / d.subcats.length * _position2; - } else { - return _this.y(d.values.y); - } - }).attr('width', function (d) { - return _this.x(d.values.x) - _this.x(0); - }).attr('height', function (d) { - if (config.y.type === 'quantile') { - return 20; - } else if (d.arrange === 'nested') { - var position = d.subcats.indexOf(d.key); - return position ? _this.y.rangeBand() / (d.subcats.length * 0.75) / position : _this.y.rangeBand(); - } else if (d.arrange === 'grouped') { - return _this.y.rangeBand() / d.subcats.length; - } else { - return _this.y.rangeBand(); - } - }); + _barsTrans + .attr('x', function(d) { + if (d.arrange === 'stacked' || !d.arrange) { + return d.values.start !== undefined ? _this.x(d.values.start) : _this.x(0); + } else { + return _this.x(0); + } + }) + .attr('y', function(d) { + if (d.arrange === 'nested') { + var position = d.subcats.indexOf(d.key); + var offset = position + ? _this.y.rangeBand() / (d.subcats.length * 0.75) / position + : _this.y.rangeBand(); + return _this.y(d.values.y) + (_this.y.rangeBand() - offset) / 2; + } else if (d.arrange === 'grouped') { + var _position2 = d.subcats.indexOf(d.key); + return ( + _this.y(d.values.y) + + _this.y.rangeBand() / d.subcats.length * _position2 + ); + } else { + return _this.y(d.values.y); + } + }) + .attr('width', function(d) { + return _this.x(d.values.x) - _this.x(0); + }) + .attr('height', function(d) { + if (config.y.type === 'quantile') { + return 20; + } else if (d.arrange === 'nested') { + var position = d.subcats.indexOf(d.key); + return position + ? _this.y.rangeBand() / (d.subcats.length * 0.75) / position + : _this.y.rangeBand(); + } else if (d.arrange === 'grouped') { + return _this.y.rangeBand() / d.subcats.length; + } else { + return _this.y.rangeBand(); + } + }); } else if (['linear', 'log'].indexOf(config.x.type) > -1 && config.x.bin) { oldBarsTrans.attr('y', this.y(0)).attr('height', 0); oldBarGroupsTrans.remove(); - nu_bar_groups = bar_groups.enter().append('g').attr('class', function (d) { + nu_bar_groups = bar_groups.enter().append('g').attr('class', function(d) { return 'bar-group ' + d.key; }); nu_bar_groups.append('title'); - bars = bar_groups.selectAll('rect').data(function (d) { - return d.values instanceof Array ? d.values : [d]; - }, function (d) { - return d.key; - }); + bars = bar_groups.selectAll('rect').data( + function(d) { + return d.values instanceof Array ? d.values : [d]; + }, + function(d) { + return d.key; + } + ); var _exitBars2 = config.transitions ? bars.exit().transition() : bars.exit(); _exitBars2.attr('y', this.y(0)).attr('height', 0).remove(); - bars.enter().append('rect').attr('class', function (d) { - return 'wc-data-mark bar ' + d.key; - }).style('clip-path', 'url(#' + chart.id + ')').attr('y', this.y(0)).attr('height', 0).append('title'); - - bars.attr('shape-rendering', 'crispEdges').attr('stroke', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }).attr('fill', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); + bars + .enter() + .append('rect') + .attr('class', function(d) { + return 'wc-data-mark bar ' + d.key; + }) + .style('clip-path', 'url(#' + chart.id + ')') + .attr('y', this.y(0)) + .attr('height', 0) + .append('title'); + + bars + .attr('shape-rendering', 'crispEdges') + .attr('stroke', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }) + .attr('fill', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); - bars.each(function (d) { + bars.each(function(d) { var mark = d3.select(this.parentNode.parentNode).datum(); d.arrange = mark.split ? mark.arrange : null; - d.subcats = config.legend.order ? config.legend.order.slice().reverse() : mark.values && mark.values[mark.split] ? mark.values[mark.split] : d3.set(rawData.map(function (m) { - return m[mark.split]; - })).values(); + d.subcats = config.legend.order + ? config.legend.order.slice().reverse() + : mark.values && mark.values[mark.split] + ? mark.values[mark.split] + : d3 + .set( + rawData.map(function(m) { + return m[mark.split]; + }) + ) + .values(); d3.select(this).attr(mark.attributes); var parent = d3.select(this.parentNode).datum(); - var rangeSet = parent.key.split(',').map(function (m) { + var rangeSet = parent.key.split(',').map(function(m) { return +m; }); d.rangeLow = d3.min(rangeSet); @@ -1503,68 +2181,108 @@ d.tooltip = mark.tooltip; }); - var _xformat2 = config.marks.map(function (m) { - return m.summarizeX === 'percent'; - }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.x.format); - var _yformat2 = config.marks.map(function (m) { - return m.summarizeY === 'percent'; - }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.y.format); - bars.select('title').text(function (d) { + var _xformat2 = config.marks + .map(function(m) { + return m.summarizeX === 'percent'; + }) + .indexOf(true) > -1 + ? d3.format('0%') + : d3.format(config.x.format); + var _yformat2 = config.marks + .map(function(m) { + return m.summarizeY === 'percent'; + }) + .indexOf(true) > -1 + ? d3.format('0%') + : d3.format(config.y.format); + bars.select('title').text(function(d) { var tt = d.tooltip || ''; - return tt.replace(/\$x/g, _xformat2(d.values.x)).replace(/\$y/g, _yformat2(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { - return d.values.raw[0][orig]; - }); + return tt + .replace(/\$x/g, _xformat2(d.values.x)) + .replace(/\$y/g, _yformat2(d.values.y)) + .replace(/\[(.+?)\]/g, function(str, orig) { + return d.values.raw[0][orig]; + }); }); var _barsTrans2 = config.transitions ? bars.transition() : bars; - _barsTrans2.attr('x', function (d) { - return _this.x(d.rangeLow); - }).attr('y', function (d) { - if (d.arrange !== 'stacked') { - return _this.y(d.values.y); - } else { - return _this.y(d.values.start); - } - }).attr('width', function (d) { - return _this.x(d.rangeHigh) - _this.x(d.rangeLow); - }).attr('height', function (d) { - return _this.y(0) - _this.y(d.values.y); - }); - } else if (['linear', 'log'].indexOf(config.y.type) > -1 && config.y.type === 'linear' && config.y.bin) { + _barsTrans2 + .attr('x', function(d) { + return _this.x(d.rangeLow); + }) + .attr('y', function(d) { + if (d.arrange !== 'stacked') { + return _this.y(d.values.y); + } else { + return _this.y(d.values.start); + } + }) + .attr('width', function(d) { + return _this.x(d.rangeHigh) - _this.x(d.rangeLow); + }) + .attr('height', function(d) { + return _this.y(0) - _this.y(d.values.y); + }); + } else if ( + ['linear', 'log'].indexOf(config.y.type) > -1 && + config.y.type === 'linear' && + config.y.bin + ) { oldBarsTrans.attr('x', this.x(0)).attr('width', 0); oldBarGroupsTrans.remove(); - nu_bar_groups = bar_groups.enter().append('g').attr('class', function (d) { + nu_bar_groups = bar_groups.enter().append('g').attr('class', function(d) { return 'bar-group ' + d.key; }); nu_bar_groups.append('title'); - bars = bar_groups.selectAll('rect').data(function (d) { - return d.values instanceof Array ? d.values : [d]; - }, function (d) { - return d.key; - }); + bars = bar_groups.selectAll('rect').data( + function(d) { + return d.values instanceof Array ? d.values : [d]; + }, + function(d) { + return d.key; + } + ); var _exitBars3 = config.transitions ? bars.exit().transition() : bars.exit(); _exitBars3.attr('x', this.x(0)).attr('width', 0).remove(); - bars.enter().append('rect').attr('class', function (d) { - return 'wc-data-mark bar ' + d.key; - }).style('clip-path', 'url(#' + chart.id + ')').attr('x', this.x(0)).attr('width', 0).append('title'); - - bars.attr('shape-rendering', 'crispEdges').attr('stroke', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }).attr('fill', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); + bars + .enter() + .append('rect') + .attr('class', function(d) { + return 'wc-data-mark bar ' + d.key; + }) + .style('clip-path', 'url(#' + chart.id + ')') + .attr('x', this.x(0)) + .attr('width', 0) + .append('title'); + + bars + .attr('shape-rendering', 'crispEdges') + .attr('stroke', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }) + .attr('fill', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); - bars.each(function (d) { + bars.each(function(d) { var mark = d3.select(this.parentNode.parentNode).datum(); d.arrange = mark.split ? mark.arrange : null; - d.subcats = config.legend.order ? config.legend.order.slice().reverse() : mark.values && mark.values[mark.split] ? mark.values[mark.split] : d3.set(rawData.map(function (m) { - return m[mark.split]; - })).values(); + d.subcats = config.legend.order + ? config.legend.order.slice().reverse() + : mark.values && mark.values[mark.split] + ? mark.values[mark.split] + : d3 + .set( + rawData.map(function(m) { + return m[mark.split]; + }) + ) + .values(); var parent = d3.select(this.parentNode).datum(); - var rangeSet = parent.key.split(',').map(function (m) { + var rangeSet = parent.key.split(',').map(function(m) { return +m; }); d.rangeLow = d3.min(rangeSet); @@ -1572,33 +2290,48 @@ d.tooltip = mark.tooltip; }); - var _xformat3 = config.marks.map(function (m) { - return m.summarizeX === 'percent'; - }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.x.format); - var _yformat3 = config.marks.map(function (m) { - return m.summarizeY === 'percent'; - }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.y.format); - bars.select('title').text(function (d) { + var _xformat3 = config.marks + .map(function(m) { + return m.summarizeX === 'percent'; + }) + .indexOf(true) > -1 + ? d3.format('0%') + : d3.format(config.x.format); + var _yformat3 = config.marks + .map(function(m) { + return m.summarizeY === 'percent'; + }) + .indexOf(true) > -1 + ? d3.format('0%') + : d3.format(config.y.format); + bars.select('title').text(function(d) { var tt = d.tooltip || ''; - return tt.replace(/\$x/g, _xformat3(d.values.x)).replace(/\$y/g, _yformat3(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { - return d.values.raw[0][orig]; - }); + return tt + .replace(/\$x/g, _xformat3(d.values.x)) + .replace(/\$y/g, _yformat3(d.values.y)) + .replace(/\[(.+?)\]/g, function(str, orig) { + return d.values.raw[0][orig]; + }); }); var _barsTrans3 = config.transitions ? bars.transition() : bars; - _barsTrans3.attr('x', function (d) { - if (d.arrange === 'stacked') { - return _this.x(d.values.start); - } else { - return _this.x(0); - } - }).attr('y', function (d) { - return _this.y(d.rangeHigh); - }).attr('width', function (d) { - return _this.x(d.values.x); - }).attr('height', function (d) { - return _this.y(d.rangeLow) - _this.y(d.rangeHigh); - }); + _barsTrans3 + .attr('x', function(d) { + if (d.arrange === 'stacked') { + return _this.x(d.values.start); + } else { + return _this.x(0); + } + }) + .attr('y', function(d) { + return _this.y(d.rangeHigh); + }) + .attr('width', function(d) { + return _this.x(d.values.x); + }) + .attr('height', function(d) { + return _this.y(d.rangeLow) - _this.y(d.rangeHigh); + }); } else { oldBarsTrans.attr('y', this.y(0)).attr('height', 0); oldBarGroupsTrans.remove(); @@ -1606,7 +2339,7 @@ } //Link to the d3.selection from the data - bar_supergroups.each(function (d) { + bar_supergroups.each(function(d) { d.supergroup = d3.select(this); d.groups = d.supergroup.selectAll('.bar-group'); }); @@ -1617,59 +2350,92 @@ var chart = this; var config = this.config; - var line = d3.svg.line().interpolate(config.interpolate).x(function (d) { - return config.x.type === 'linear' || config.x.type == 'log' ? _this.x(+d.values.x) : config.x.type === 'time' ? _this.x(new Date(d.values.x)) : _this.x(d.values.x) + _this.x.rangeBand() / 2; - }).y(function (d) { - return config.y.type === 'linear' || config.y.type == 'log' ? _this.y(+d.values.y) : config.y.type === 'time' ? _this.y(new Date(d.values.y)) : _this.y(d.values.y) + _this.y.rangeBand() / 2; - }); + var line = d3.svg + .line() + .interpolate(config.interpolate) + .x(function(d) { + return config.x.type === 'linear' || config.x.type == 'log' + ? _this.x(+d.values.x) + : config.x.type === 'time' + ? _this.x(new Date(d.values.x)) + : _this.x(d.values.x) + _this.x.rangeBand() / 2; + }) + .y(function(d) { + return config.y.type === 'linear' || config.y.type == 'log' + ? _this.y(+d.values.y) + : config.y.type === 'time' + ? _this.y(new Date(d.values.y)) + : _this.y(d.values.y) + _this.y.rangeBand() / 2; + }); - var line_supergroups = this.svg.selectAll('.line-supergroup').data(marks, function (d, i) { + var line_supergroups = this.svg.selectAll('.line-supergroup').data(marks, function(d, i) { return i + '-' + d.per.join('-'); }); - line_supergroups.enter().append('g').attr('class', function (d) { + line_supergroups.enter().append('g').attr('class', function(d) { return 'supergroup line-supergroup ' + d.id; }); line_supergroups.exit().remove(); - var line_grps = line_supergroups.selectAll('.line').data(function (d) { - return d.data; - }, function (d) { - return d.key; - }); + var line_grps = line_supergroups.selectAll('.line').data( + function(d) { + return d.data; + }, + function(d) { + return d.key; + } + ); line_grps.exit().remove(); - var nu_line_grps = line_grps.enter().append('g').attr('class', function (d) { + var nu_line_grps = line_grps.enter().append('g').attr('class', function(d) { return d.key + ' line'; }); nu_line_grps.append('path'); nu_line_grps.append('title'); - var linePaths = line_grps.select('path').attr('class', 'wc-data-mark').style('clip-path', 'url(#' + chart.id + ')').datum(function (d) { - return d.values; - }).attr('stroke', function (d) { - return _this.colorScale(d[0].values.raw[0][config.color_by]); - }).attr('stroke-width', config.stroke_width ? config.stroke_width : config.flex_stroke_width).attr('stroke-linecap', 'round').attr('fill', 'none'); + var linePaths = line_grps + .select('path') + .attr('class', 'wc-data-mark') + .style('clip-path', 'url(#' + chart.id + ')') + .datum(function(d) { + return d.values; + }) + .attr('stroke', function(d) { + return _this.colorScale(d[0].values.raw[0][config.color_by]); + }) + .attr( + 'stroke-width', + config.stroke_width ? config.stroke_width : config.flex_stroke_width + ) + .attr('stroke-linecap', 'round') + .attr('fill', 'none'); var linePathsTrans = config.transitions ? linePaths.transition() : linePaths; linePathsTrans.attr('d', line); - line_grps.each(function (d) { + line_grps.each(function(d) { var mark = d3.select(this.parentNode).datum(); d.tooltip = mark.tooltip; d3.select(this).select('path').attr(mark.attributes); }); - line_grps.select('title').text(function (d) { + line_grps.select('title').text(function(d) { var tt = d.tooltip || ''; - var xformat = config.x.summary === 'percent' ? d3.format('0%') : d3.format(config.x.format); - var yformat = config.y.summary === 'percent' ? d3.format('0%') : d3.format(config.y.format); - return tt.replace(/\$x/g, xformat(d.values.x)).replace(/\$y/g, yformat(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { - return d.values[0].values.raw[0][orig]; - }); + var xformat = config.x.summary === 'percent' + ? d3.format('0%') + : d3.format(config.x.format); + var yformat = config.y.summary === 'percent' + ? d3.format('0%') + : d3.format(config.y.format); + return tt + .replace(/\$x/g, xformat(d.values.x)) + .replace(/\$y/g, yformat(d.values.y)) + .replace(/\[(.+?)\]/g, function(str, orig) { + return d.values[0].values.raw[0][orig]; + }); }); //Link to the d3.selection from the data - line_supergroups.each(function (d) { + line_supergroups.each(function(d) { d.supergroup = d3.select(this); d.groups = d.supergroup.selectAll('g.line'); d.paths = d.groups.select('path'); @@ -1683,69 +2449,104 @@ var chart = this; var config = this.config; - var point_supergroups = this.svg.selectAll('.point-supergroup').data(marks, function (d, i) { + var point_supergroups = this.svg.selectAll('.point-supergroup').data(marks, function(d, i) { return i + '-' + d.per.join('-'); }); - point_supergroups.enter().append('g').attr('class', function (d) { + point_supergroups.enter().append('g').attr('class', function(d) { return 'supergroup point-supergroup ' + d.id; }); point_supergroups.exit().remove(); - var points = point_supergroups.selectAll('.point').data(function (d) { - return d.data; - }, function (d) { - return d.key; - }); + var points = point_supergroups.selectAll('.point').data( + function(d) { + return d.data; + }, + function(d) { + return d.key; + } + ); var oldPoints = points.exit(); - var oldPointsTrans = config.transitions ? oldPoints.selectAll('circle').transition() : oldPoints.selectAll('circle'); + var oldPointsTrans = config.transitions + ? oldPoints.selectAll('circle').transition() + : oldPoints.selectAll('circle'); oldPointsTrans.attr('r', 0); var oldPointGroupTrans = config.transitions ? oldPoints.transition() : oldPoints; oldPointGroupTrans.remove(); - var nupoints = points.enter().append('g').attr('class', function (d) { + var nupoints = points.enter().append('g').attr('class', function(d) { return d.key + ' point'; }); nupoints.append('circle').attr('class', 'wc-data-mark').attr('r', 0); nupoints.append('title'); //static attributes - points.select('circle').style('clip-path', 'url(#' + chart.id + ')').attr('fill-opacity', config.fill_opacity || config.fill_opacity === 0 ? config.fill_opacity : 0.6).attr('fill', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }).attr('stroke', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); + points + .select('circle') + .style('clip-path', 'url(#' + chart.id + ')') + .attr( + 'fill-opacity', + config.fill_opacity || config.fill_opacity === 0 ? config.fill_opacity : 0.6 + ) + .attr('fill', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }) + .attr('stroke', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); //attach mark info - points.each(function (d) { + points.each(function(d) { var mark = d3.select(this.parentNode).datum(); d.mark = mark; d3.select(this).select('circle').attr(mark.attributes); }); //animated attributes - var pointsTrans = config.transitions ? points.select('circle').transition() : points.select('circle'); - pointsTrans.attr('r', function (d) { - return d.mark.radius || config.flex_point_size; - }).attr('cx', function (d) { - var x_pos = _this.x(d.values.x) || 0; - return config.x.type === 'ordinal' ? x_pos + _this.x.rangeBand() / 2 : x_pos; - }).attr('cy', function (d) { - var y_pos = _this.y(d.values.y) || 0; - return config.y.type === 'ordinal' ? y_pos + _this.y.rangeBand() / 2 : y_pos; - }); + var pointsTrans = config.transitions + ? points.select('circle').transition() + : points.select('circle'); + pointsTrans + .attr('r', function(d) { + return d.mark.radius || config.flex_point_size; + }) + .attr('cx', function(d) { + var x_pos = _this.x(d.values.x) || 0; + return config.x.type === 'ordinal' ? x_pos + _this.x.rangeBand() / 2 : x_pos; + }) + .attr('cy', function(d) { + var y_pos = _this.y(d.values.y) || 0; + return config.y.type === 'ordinal' ? y_pos + _this.y.rangeBand() / 2 : y_pos; + }); - points.select('title').text(function (d) { + points.select('title').text(function(d) { var tt = d.mark.tooltip || ''; - var xformat = config.x.summary === 'percent' ? d3.format('0%') : config.x.type === 'time' ? d3.time.format(config.x.format) : d3.format(config.x.format); - var yformat = config.y.summary === 'percent' ? d3.format('0%') : config.y.type === 'time' ? d3.time.format(config.y.format) : d3.format(config.y.format); - return tt.replace(/\$x/g, config.x.type === 'time' ? xformat(new Date(d.values.x)) : xformat(d.values.x)).replace(/\$y/g, config.y.type === 'time' ? yformat(new Date(d.values.y)) : yformat(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { - return d.values.raw[0][orig]; - }); + var xformat = config.x.summary === 'percent' + ? d3.format('0%') + : config.x.type === 'time' + ? d3.time.format(config.x.format) + : d3.format(config.x.format); + var yformat = config.y.summary === 'percent' + ? d3.format('0%') + : config.y.type === 'time' + ? d3.time.format(config.y.format) + : d3.format(config.y.format); + return tt + .replace( + /\$x/g, + config.x.type === 'time' ? xformat(new Date(d.values.x)) : xformat(d.values.x) + ) + .replace( + /\$y/g, + config.y.type === 'time' ? yformat(new Date(d.values.y)) : yformat(d.values.y) + ) + .replace(/\[(.+?)\]/g, function(str, orig) { + return d.values.raw[0][orig]; + }); }); //Link to the d3.selection from the data - point_supergroups.each(function (d) { + point_supergroups.each(function(d) { d.supergroup = d3.select(this); d.groups = d.supergroup.selectAll('g.point'); d.circles = d.groups.select('circle'); @@ -1760,21 +2561,24 @@ var chart = this; var config = this.config; - var textSupergroups = this.svg.selectAll('.text-supergroup').data(marks, function (d, i) { + var textSupergroups = this.svg.selectAll('.text-supergroup').data(marks, function(d, i) { return i + '-' + d.per.join('-'); }); - textSupergroups.enter().append('g').attr('class', function (d) { + textSupergroups.enter().append('g').attr('class', function(d) { return 'supergroup text-supergroup ' + d.id; }); textSupergroups.exit().remove(); - var texts = textSupergroups.selectAll('.text').data(function (d) { - return d.data; - }, function (d) { - return d.key; - }); + var texts = textSupergroups.selectAll('.text').data( + function(d) { + return d.data; + }, + function(d) { + return d.key; + } + ); var oldTexts = texts.exit(); // don't need to transition position of outgoing text @@ -1783,7 +2587,7 @@ var oldTextGroupTrans = config.transitions ? oldTexts.transition() : oldTexts; oldTextGroupTrans.remove(); - var nutexts = texts.enter().append('g').attr('class', function (d) { + var nutexts = texts.enter().append('g').attr('class', function(d) { return d.key + ' text'; }); nutexts.append('text').attr('class', 'wc-data-mark'); @@ -1797,25 +2601,46 @@ texts.each(attachMarks); // parse text like tooltips - texts.select('text').style('clip-path', 'url(#' + chart.id + ')').text(function (d) { + texts.select('text').style('clip-path', 'url(#' + chart.id + ')').text(function(d) { var tt = d.mark.text || ''; - var xformat = config.x.summary === 'percent' ? d3.format('0%') : config.x.type === 'time' ? d3.time.format(config.x.format) : d3.format(config.x.format); - var yformat = config.y.summary === 'percent' ? d3.format('0%') : config.y.type === 'time' ? d3.time.format(config.y.format) : d3.format(config.y.format); - return tt.replace(/\$x/g, config.x.type === 'time' ? xformat(new Date(d.values.x)) : xformat(d.values.x)).replace(/\$y/g, config.y.type === 'time' ? yformat(new Date(d.values.y)) : yformat(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { - return d.values.raw[0][orig]; - }); + var xformat = config.x.summary === 'percent' + ? d3.format('0%') + : config.x.type === 'time' + ? d3.time.format(config.x.format) + : d3.format(config.x.format); + var yformat = config.y.summary === 'percent' + ? d3.format('0%') + : config.y.type === 'time' + ? d3.time.format(config.y.format) + : d3.format(config.y.format); + return tt + .replace( + /\$x/g, + config.x.type === 'time' ? xformat(new Date(d.values.x)) : xformat(d.values.x) + ) + .replace( + /\$y/g, + config.y.type === 'time' ? yformat(new Date(d.values.y)) : yformat(d.values.y) + ) + .replace(/\[(.+?)\]/g, function(str, orig) { + return d.values.raw[0][orig]; + }); }); // animated attributes - var textsTrans = config.transitions ? texts.select('text').transition() : texts.select('text'); - textsTrans.attr('x', function (d) { - var xPos = _this.x(d.values.x) || 0; - return config.x.type === 'ordinal' ? xPos + _this.x.rangeBand() / 2 : xPos; - }).attr('y', function (d) { - var yPos = _this.y(d.values.y) || 0; - return config.y.type === 'ordinal' ? yPos + _this.y.rangeBand() / 2 : yPos; - }); + var textsTrans = config.transitions + ? texts.select('text').transition() + : texts.select('text'); + textsTrans + .attr('x', function(d) { + var xPos = _this.x(d.values.x) || 0; + return config.x.type === 'ordinal' ? xPos + _this.x.rangeBand() / 2 : xPos; + }) + .attr('y', function(d) { + var yPos = _this.y(d.values.y) || 0; + return config.y.type === 'ordinal' ? yPos + _this.y.rangeBand() / 2 : yPos; + }); //add a reference to the selection from it's data - textSupergroups.each(function (d) { + textSupergroups.each(function(d) { d.supergroup = d3.select(this); d.groups = d.supergroup.selectAll('g.text'); d.texts = d.groups.select('text'); @@ -1824,7 +2649,9 @@ } function destroy() { - var destroyControls = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + var destroyControls = arguments.length > 0 && arguments[0] !== undefined + ? arguments[0] + : true; //run onDestroy callback this.events.onDestroy.call(this); @@ -1905,8 +2732,16 @@ onDestroy: function onDestroy() {} }; - thisChart.on = function (event, callback) { - var possible_events = ['init', 'layout', 'preprocess', 'datatransform', 'draw', 'resize', 'destroy']; + thisChart.on = function(event, callback) { + var possible_events = [ + 'init', + 'layout', + 'preprocess', + 'datatransform', + 'draw', + 'resize', + 'destroy' + ]; if (possible_events.indexOf(event) < 0) { return; } @@ -1926,9 +2761,9 @@ function changeOption(option, value, callback, draw) { var _this = this; - this.targets.forEach(function (target) { + this.targets.forEach(function(target) { if (option instanceof Array) { - option.forEach(function (o) { + option.forEach(function(o) { return _this.stringAccessor(target.config, o, value); }); } else { @@ -1947,8 +2782,13 @@ var colNames = d3.keys(dataset[0]); - this.config.inputs.forEach(function (input, i) { - if (input.type === 'subsetter' && colNames.indexOf(input.value_col) === -1) throw new Error('Error in settings object: the value "' + input.value_col + '" does not match any column in the provided dataset.'); + this.config.inputs.forEach(function(input, i) { + if (input.type === 'subsetter' && colNames.indexOf(input.value_col) === -1) + throw new Error( + 'Error in settings object: the value "' + + input.value_col + + '" does not match any column in the provided dataset.' + ); //Draw the chart when a control changes unless the user specifies otherwise. input.draw = input.draw === undefined ? true : input.draw; @@ -1958,9 +2798,10 @@ function controlUpdate() { var _this = this; - if (this.config.inputs && this.config.inputs.length && this.config.inputs[0]) this.config.inputs.forEach(function (input) { - return _this.makeControlItem(input); - }); + if (this.config.inputs && this.config.inputs.length && this.config.inputs[0]) + this.config.inputs.forEach(function(input) { + return _this.makeControlItem(input); + }); } function destroy$1() { @@ -1981,13 +2822,21 @@ } function makeControlItem(control) { - var control_wrap = this.wrap.append('div').attr('class', 'control-group').classed('inline', control.inline).datum(control); + var control_wrap = this.wrap + .append('div') + .attr('class', 'control-group') + .classed('inline', control.inline) + .datum(control); //Add control label span. - var ctrl_label = control_wrap.append('span').attr('class', 'wc-control-label').text(control.label); + var ctrl_label = control_wrap + .append('span') + .attr('class', 'wc-control-label') + .text(control.label); //Add control _Required_ text to control label span. - if (control.required) ctrl_label.append('span').attr('class', 'label label-required').text('Required'); + if (control.required) + ctrl_label.append('span').attr('class', 'label label-required').text('Required'); //Add control description span. control_wrap.append('span').attr('class', 'span-description').text(control.description); @@ -2009,7 +2858,9 @@ } else if (control.type === 'subsetter') { this.makeSubsetterControl(control, control_wrap); } else { - throw new Error('Each control must have a type! Choose from: "text", "number", "list", "dropdown", "btngroup", "checkbox", "radio", or "subsetter".'); + throw new Error( + 'Each control must have a type! Choose from: "text", "number", "list", "dropdown", "btngroup", "checkbox", "radio", or "subsetter".' + ); } } @@ -2020,14 +2871,21 @@ var btn_wrap = control_wrap.append('div').attr('class', 'btn-group'); - var changers = btn_wrap.selectAll('button').data(option_data).enter().append('button').attr('class', 'btn btn-default btn-sm').text(function (d) { - return d; - }).classed('btn-primary', function (d) { - return _this.stringAccessor(_this.targets[0].config, control.option) === d; - }); + var changers = btn_wrap + .selectAll('button') + .data(option_data) + .enter() + .append('button') + .attr('class', 'btn btn-default btn-sm') + .text(function(d) { + return d; + }) + .classed('btn-primary', function(d) { + return _this.stringAccessor(_this.targets[0].config, control.option) === d; + }); - changers.on('click', function (d) { - changers.each(function (e) { + changers.on('click', function(d) { + changers.each(function(e) { d3.select(this).classed('btn-primary', e === d); }); _this.changeOption(control.option, d, control.callback, control.draw); @@ -2037,11 +2895,16 @@ function makeCheckboxControl(control, control_wrap) { var _this = this; - var changer = control_wrap.append('input').attr('type', 'checkbox').attr('class', 'changer').datum(control).property('checked', function (d) { - return _this.stringAccessor(_this.targets[0].config, control.option); - }); + var changer = control_wrap + .append('input') + .attr('type', 'checkbox') + .attr('class', 'changer') + .datum(control) + .property('checked', function(d) { + return _this.stringAccessor(_this.targets[0].config, control.option); + }); - changer.on('change', function (d) { + changer.on('change', function(d) { var value = changer.property('checked'); _this.changeOption(d.option, value, control.callback, control.draw); }); @@ -2051,33 +2914,54 @@ var _this = this; var mainOption = control.option || control.options[0]; - var changer = control_wrap.append('select').attr('class', 'changer').attr('multiple', control.multiple ? true : null).datum(control); - - var opt_values = control.values && control.values instanceof Array ? control.values : control.values ? d3.set(this.data.map(function (m) { - return m[_this.targets[0].config[control.values]]; - })).values() : d3.keys(this.data[0]); + var changer = control_wrap + .append('select') + .attr('class', 'changer') + .attr('multiple', control.multiple ? true : null) + .datum(control); + + var opt_values = control.values && control.values instanceof Array + ? control.values + : control.values + ? d3 + .set( + this.data.map(function(m) { + return m[_this.targets[0].config[control.values]]; + }) + ) + .values() + : d3.keys(this.data[0]); if (!control.require || control.none) { opt_values.unshift('None'); } - var options = changer.selectAll('option').data(opt_values).enter().append('option').text(function (d) { - return d; - }).property('selected', function (d) { - return _this.stringAccessor(_this.targets[0].config, mainOption) === d; - }); + var options = changer + .selectAll('option') + .data(opt_values) + .enter() + .append('option') + .text(function(d) { + return d; + }) + .property('selected', function(d) { + return _this.stringAccessor(_this.targets[0].config, mainOption) === d; + }); - changer.on('change', function (d) { + changer.on('change', function(d) { var value = changer.property('value') === 'None' ? null : changer.property('value'); if (control.multiple) { - value = options.filter(function (f) { - return d3.select(this).property('selected'); - })[0].map(function (m) { - return d3.select(m).property('value'); - }).filter(function (f) { - return f !== 'None'; - }); + value = options + .filter(function(f) { + return d3.select(this).property('selected'); + })[0] + .map(function(m) { + return d3.select(m).property('value'); + }) + .filter(function(f) { + return f !== 'None'; + }); } if (control.options) { @@ -2093,14 +2977,21 @@ function makeListControl(control, control_wrap) { var _this = this; - var changer = control_wrap.append('input').attr('type', 'text').attr('class', 'changer').datum(control).property('value', function (d) { - return _this.stringAccessor(_this.targets[0].config, control.option); - }); + var changer = control_wrap + .append('input') + .attr('type', 'text') + .attr('class', 'changer') + .datum(control) + .property('value', function(d) { + return _this.stringAccessor(_this.targets[0].config, control.option); + }); - changer.on('change', function (d) { - var value = changer.property('value') ? changer.property('value').split(',').map(function (m) { - return m.trim(); - }) : null; + changer.on('change', function(d) { + var value = changer.property('value') + ? changer.property('value').split(',').map(function(m) { + return m.trim(); + }) + : null; _this.changeOption(control.option, value, control.callback, control.draw); }); } @@ -2108,11 +2999,19 @@ function makeNumberControl(control, control_wrap) { var _this = this; - var changer = control_wrap.append('input').attr('type', 'number').attr('min', control.min !== undefined ? control.min : 0).attr('max', control.max).attr('step', control.step || 1).attr('class', 'changer').datum(control).property('value', function (d) { - return _this.stringAccessor(_this.targets[0].config, control.option); - }); + var changer = control_wrap + .append('input') + .attr('type', 'number') + .attr('min', control.min !== undefined ? control.min : 0) + .attr('max', control.max) + .attr('step', control.step || 1) + .attr('class', 'changer') + .datum(control) + .property('value', function(d) { + return _this.stringAccessor(_this.targets[0].config, control.option); + }); - changer.on('change', function (d) { + changer.on('change', function(d) { var value = +changer.property('value'); _this.changeOption(control.option, value, control.callback, control.draw); }); @@ -2121,17 +3020,29 @@ function makeRadioControl(control, control_wrap) { var _this = this; - var changers = control_wrap.selectAll('label').data(control.values || d3.keys(this.data[0])).enter().append('label').attr('class', 'radio').text(function (d, i) { - return control.relabels ? control.relabels[i] : d; - }).append('input').attr('type', 'radio').attr('class', 'changer').attr('name', control.option.replace('.', '-') + '-' + this.targets[0].id).property('value', function (d) { - return d; - }).property('checked', function (d) { - return _this.stringAccessor(_this.targets[0].config, control.option) === d; - }); + var changers = control_wrap + .selectAll('label') + .data(control.values || d3.keys(this.data[0])) + .enter() + .append('label') + .attr('class', 'radio') + .text(function(d, i) { + return control.relabels ? control.relabels[i] : d; + }) + .append('input') + .attr('type', 'radio') + .attr('class', 'changer') + .attr('name', control.option.replace('.', '-') + '-' + this.targets[0].id) + .property('value', function(d) { + return d; + }) + .property('checked', function(d) { + return _this.stringAccessor(_this.targets[0].config, control.option) === d; + }); - changers.on('change', function (d) { + changers.on('change', function(d) { var value = null; - changers.each(function (c) { + changers.each(function(c) { if (d3.select(this).property('checked')) { value = d3.select(this).property('value') === 'none' ? null : c; } @@ -2144,14 +3055,27 @@ var targets = this.targets; // associated charts and tables. //dropdown selection - var changer = control_wrap.append('select').classed('changer', true).attr('multiple', control.multiple ? true : null).datum(control); + var changer = control_wrap + .append('select') + .classed('changer', true) + .attr('multiple', control.multiple ? true : null) + .datum(control); //dropdown option data - var option_data = control.values ? control.values : d3.set(this.data.map(function (m) { - return m[control.value_col]; - }).filter(function (f) { - return f; - })).values().sort(naturalSorter); // only sort when values are derived + var option_data = control.values + ? control.values + : d3 + .set( + this.data + .map(function(m) { + return m[control.value_col]; + }) + .filter(function(f) { + return f; + }) + ) + .values() + .sort(naturalSorter); // only sort when values are derived //initial dropdown option control.start = control.start ? control.start : control.loose ? option_data[0] : null; @@ -2168,17 +3092,26 @@ control.loose = !control.loose && control.start ? true : control.loose; //dropdown options selection - var options = changer.selectAll('option').data(option_data).enter().append('option').text(function (d) { - return d; - }).property('selected', function (d) { - return d === control.start; - }); + var options = changer + .selectAll('option') + .data(option_data) + .enter() + .append('option') + .text(function(d) { + return d; + }) + .property('selected', function(d) { + return d === control.start; + }); //define filter object for each associated target - targets.forEach(function (e) { - var match = e.filters.slice().map(function (m) { - return m.col === control.value_col; - }).indexOf(true); + targets.forEach(function(e) { + var match = e.filters + .slice() + .map(function(m) { + return m.col === control.value_col; + }) + .indexOf(true); if (match > -1) { e.filters[match] = { col: control.value_col, @@ -2202,7 +3135,7 @@ function setSubsetter(target, obj) { var match = -1; - target.filters.forEach(function (e, i) { + target.filters.forEach(function(e, i) { if (e.col === obj.col) { match = i; } @@ -2213,13 +3146,15 @@ } //add event listener to control - changer.on('change', function (d) { + changer.on('change', function(d) { if (control.multiple) { - var values = options.filter(function (f) { - return d3.select(this).property('selected'); - })[0].map(function (m) { - return d3.select(m).property('text'); - }); + var values = options + .filter(function(f) { + return d3.select(this).property('selected'); + })[0] + .map(function(m) { + return d3.select(m).property('text'); + }); var new_filter = { col: control.value_col, @@ -2229,7 +3164,7 @@ loose: control.loose, all: control.all }; - targets.forEach(function (e) { + targets.forEach(function(e) { setSubsetter(e, new_filter); //call callback function if provided if (control.callback) { @@ -2248,7 +3183,7 @@ loose: control.loose, all: control.all }; - targets.forEach(function (e) { + targets.forEach(function(e) { setSubsetter(e, _new_filter); //call callback function if provided if (control.callback) { @@ -2263,11 +3198,16 @@ function makeTextControl(control, control_wrap) { var _this = this; - var changer = control_wrap.append('input').attr('type', 'text').attr('class', 'changer').datum(control).property('value', function (d) { - return _this.stringAccessor(_this.targets[0].config, control.option); - }); + var changer = control_wrap + .append('input') + .attr('type', 'text') + .attr('class', 'changer') + .datum(control) + .property('value', function(d) { + return _this.stringAccessor(_this.targets[0].config, control.option); + }); - changer.on('change', function (d) { + changer.on('change', function(d) { var value = changer.property('value'); _this.changeOption(control.option, value, control.callback, control.draw); }); @@ -2325,7 +3265,10 @@ if (config.location === 'bottom') { thisControls.wrap = d3.select(element).append('div').attr('class', 'wc-controls'); } else { - thisControls.wrap = d3.select(element).insert('div', ':first-child').attr('class', 'wc-controls'); + thisControls.wrap = d3 + .select(element) + .insert('div', ':first-child') + .attr('class', 'wc-controls'); } thisControls.wrap.datum(thisControls); @@ -2338,17 +3281,32 @@ //If there are filters, return a filtered data array of the raw data. //Otherwise return the raw data. - if (this.filters && this.filters.some(function (filter) { - return typeof filter.val === 'string' && !(filter.all === true && filter.index === 0) || Array.isArray(filter.val) && filter.val.length < filter.choices.length; - })) { + if ( + this.filters && + this.filters.some(function(filter) { + return ( + (typeof filter.val === 'string' && + !(filter.all === true && filter.index === 0)) || + (Array.isArray(filter.val) && filter.val.length < filter.choices.length) + ); + }) + ) { this.data.filtered = this.data.raw; - this.filters.filter(function (filter) { - return typeof filter.val === 'string' && !(filter.all === true && filter.index === 0) || Array.isArray(filter.val) && filter.val.length < filter.choices.length; - }).forEach(function (filter) { - _this.data.filtered = _this.data.filtered.filter(function (d) { - return Array.isArray(filter.val) ? filter.val.indexOf(d[filter.col]) > -1 : filter.val === d[filter.col]; + this.filters + .filter(function(filter) { + return ( + (typeof filter.val === 'string' && + !(filter.all === true && filter.index === 0)) || + (Array.isArray(filter.val) && filter.val.length < filter.choices.length) + ); + }) + .forEach(function(filter) { + _this.data.filtered = _this.data.filtered.filter(function(d) { + return Array.isArray(filter.val) + ? filter.val.indexOf(d[filter.col]) > -1 + : filter.val === d[filter.col]; + }); }); - }); } else this.data.filtered = this.data.raw; } @@ -2365,17 +3323,20 @@ if (this.searchable.searchTerm) { //Determine which rows contain input text. - this.data.searched = this.data.filtered.filter(function (d) { + this.data.searched = this.data.filtered.filter(function(d) { var match = false; - Object.keys(d).filter(function (key) { - return _this.config.cols.indexOf(key) > -1; - }).forEach(function (var_name) { - if (match === false) { - var cellText = '' + d[var_name]; - match = cellText.toLowerCase().indexOf(_this.searchable.searchTerm) > -1; - } - }); + Object.keys(d) + .filter(function(key) { + return _this.config.cols.indexOf(key) > -1; + }) + .forEach(function(var_name) { + if (match === false) { + var cellText = '' + d[var_name]; + match = + cellText.toLowerCase().indexOf(_this.searchable.searchTerm) > -1; + } + }); return match; }); @@ -2392,9 +3353,12 @@ \------------------------------------------------------------------------------------------------*/ // Warn if overriding existing method - if (Array.prototype.equals) console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code."); + if (Array.prototype.equals) + console.warn( + "Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code." + ); // attach the .equals method to Array's prototype to call it on any array - Array.prototype.equals = function (array) { + Array.prototype.equals = function(array) { // if the other array is a falsy value, return if (!array) return false; @@ -2418,7 +3382,7 @@ function checkFilters() { if (this.filters) { - this.currentFilters = this.filters.map(function (filter) { + this.currentFilters = this.filters.map(function(filter) { return filter.val; }); @@ -2436,19 +3400,24 @@ function updateTableHeaders() { var _this = this; - this.thead_cells = this.thead.select('tr').selectAll('th').data(this.config.headers, function (d) { - return d; - }); + this.thead_cells = this.thead + .select('tr') + .selectAll('th') + .data(this.config.headers, function(d) { + return d; + }); this.thead_cells.exit().remove(); this.thead_cells.enter().append('th'); - this.thead_cells.sort(function (a, b) { - return _this.config.headers.indexOf(a) - _this.config.headers.indexOf(b); - }).attr('class', function (d) { - return _this.config.cols[_this.config.headers.indexOf(d)]; - }) // associate column header with column name - .text(function (d) { - return d; - }); + this.thead_cells + .sort(function(a, b) { + return _this.config.headers.indexOf(a) - _this.config.headers.indexOf(b); + }) + .attr('class', function(d) { + return _this.config.cols[_this.config.headers.indexOf(d)]; + }) // associate column header with column name + .text(function(d) { + return d; + }); } function drawTableBody() { @@ -2460,51 +3429,77 @@ var rows = this.tbody.selectAll('tr').data(this.data.processing).enter().append('tr'); //Define table body cells. - var cells = rows.selectAll('td').data(function (d) { - return _this.config.cols.map(function (key) { + var cells = rows.selectAll('td').data(function(d) { + return _this.config.cols.map(function(key) { return { col: key, text: d[key] }; }); }); cells.exit().remove(); cells.enter().append('td'); - cells.sort(function (a, b) { - return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); - }).attr('class', function (d) { - return d.col; - }).each(function (d) { - var cell = d3.select(this); - - //Apply text in data as html or as plain text. - if (table.config.as_html) { - cell.html(d.text); - } else { - cell.text(d.text); - } - }); + cells + .sort(function(a, b) { + return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); + }) + .attr('class', function(d) { + return d.col; + }) + .each(function(d) { + var cell = d3.select(this); + + //Apply text in data as html or as plain text. + if (table.config.as_html) { + cell.html(d.text); + } else { + cell.text(d.text); + } + }); } function dynamicLayout() { var widths = { table: this.table.select('thead').node().offsetWidth, - top: this.wrap.select('.table-top .searchable-container').node().offsetWidth + this.wrap.select('.table-top .sortable-container').node().offsetWidth, - bottom: this.wrap.select('.table-bottom .pagination-container').node().offsetWidth + this.wrap.select('.table-bottom .exportable-container').node().offsetWidth + top: + this.wrap.select('.table-top .searchable-container').node().offsetWidth + + this.wrap.select('.table-top .sortable-container').node().offsetWidth, + bottom: + this.wrap.select('.table-bottom .pagination-container').node().offsetWidth + + this.wrap.select('.table-bottom .exportable-container').node().offsetWidth }; - if (widths.table < Math.max(widths.top, widths.bottom) && this.config.layout === 'horizontal') { + if ( + widths.table < Math.max(widths.top, widths.bottom) && + this.config.layout === 'horizontal' + ) { this.config.layout = 'vertical'; - this.wrap.style('display', 'inline-block').selectAll('.table-top,.table-bottom').style('display', 'inline-block').selectAll('.interactivity').style({ - display: 'block', - clear: 'both' - }); - } else if (widths.table >= Math.max(widths.top, widths.bottom) && this.config.layout === 'vertical') { + this.wrap + .style('display', 'inline-block') + .selectAll('.table-top,.table-bottom') + .style('display', 'inline-block') + .selectAll('.interactivity') + .style({ + display: 'block', + clear: 'both' + }); + } else if ( + widths.table >= Math.max(widths.top, widths.bottom) && + this.config.layout === 'vertical' + ) { this.config.layout = 'horizontal'; - this.wrap.style('display', 'table').selectAll('.table-top,.table-bottom').style('display', 'block').selectAll('.interactivity').style({ - display: 'inline-block', - float: function float() { - return d3.select(this).classed('searchable-container') || d3.select(this).classed('pagination-container') ? 'right' : null; - }, - clear: null - }); + this.wrap + .style('display', 'table') + .selectAll('.table-top,.table-bottom') + .style('display', 'block') + .selectAll('.interactivity') + .style({ + display: 'inline-block', + float: function float() { + return d3.select(this).classed('searchable-container') || + d3.select(this).classed('pagination-container') + ? 'right' + : null; + }, + clear: null + }); } } @@ -2519,7 +3514,8 @@ if (!passed_data) //Apply filters if data is not passed to table.draw(). - applyFilters.call(this);else + applyFilters.call(this); + else //Otherwise update data object. updateDataObject.call(this); @@ -2529,7 +3525,16 @@ //Filter data on search term if it exists and set data to searched data. applySearchTerm.call(this); - this.searchable.wrap.select('.nNrecords').text(this.data.processing.length === this.data.raw.length ? this.data.raw.length + ' records displayed' : this.data.processing.length + '/' + this.data.raw.length + ' records displayed'); + this.searchable.wrap + .select('.nNrecords') + .text( + this.data.processing.length === this.data.raw.length + ? this.data.raw.length + ' records displayed' + : this.data.processing.length + + '/' + + this.data.raw.length + + ' records displayed' + ); //Update table headers. updateTableHeaders.call(this); @@ -2539,27 +3544,35 @@ //Print a note that no data was selected for empty tables. if (this.data.processing.length === 0) { - this.tbody.append('tr').classed('no-data', true).append('td').attr('colspan', this.config.cols.length).text('No data selected.'); + this.tbody + .append('tr') + .classed('no-data', true) + .append('td') + .attr('colspan', this.config.cols.length) + .text('No data selected.'); //Bind table filtered/searched data to table container. this.data.current = this.data.processing; this.table.datum(this.table.current); //Add export. - if (this.config.exportable) this.config.exports.forEach(function (fmt) { - _this.exportable.exports[fmt].call(_this, _this.data.processing); - }); + if (this.config.exportable) + this.config.exports.forEach(function(fmt) { + _this.exportable.exports[fmt].call(_this, _this.data.processing); + }); //Add pagination. - if (this.config.pagination) this.pagination.addPagination.call(this, this.data.processing); + if (this.config.pagination) + this.pagination.addPagination.call(this, this.data.processing); } else { //Sort data. if (this.config.sortable) { - this.thead.selectAll('th').on('click', function (header) { + this.thead.selectAll('th').on('click', function(header) { table.sortable.onClick.call(table, this, header); }); - if (this.sortable.order.length) this.sortable.sortData.call(this, this.data.processing); + if (this.sortable.order.length) + this.sortable.sortData.call(this, this.data.processing); } //Bind table filtered/searched data to table container. @@ -2567,16 +3580,17 @@ this.table.datum(this.data.current); //Add export. - if (this.config.exportable) this.config.exports.forEach(function (fmt) { - _this.exportable.exports[fmt].call(_this, _this.data.processing); - }); + if (this.config.exportable) + this.config.exports.forEach(function(fmt) { + _this.exportable.exports[fmt].call(_this, _this.data.processing); + }); //Add pagination. if (this.config.pagination) { this.pagination.addPagination.call(this, this.data.processing); //Apply pagination. - this.data.processing = this.data.processing.filter(function (d, i) { + this.data.processing = this.data.processing.filter(function(d, i) { return _this.config.startIndex <= i && i < _this.config.endIndex; }); } @@ -2596,15 +3610,24 @@ function layout$2() { var context = this; - this.searchable.wrap = this.wrap.select('.table-top').append('div').classed('interactivity searchable-container', true).classed('hidden', !this.config.searchable); + this.searchable.wrap = this.wrap + .select('.table-top') + .append('div') + .classed('interactivity searchable-container', true) + .classed('hidden', !this.config.searchable); this.searchable.wrap.append('div').classed('search', true); - this.searchable.wrap.select('.search').append('input').classed('search-box', true).attr('placeholder', 'Search').on('input', function () { - context.searchable.searchTerm = this.value.toLowerCase() || null; - context.config.activePage = 0; - context.config.startIndex = context.config.activePage * context.config.nRowsPerPage; // first row shown - context.config.endIndex = context.config.startIndex + context.config.nRowsPerPage; // last row shown - context.draw(); - }); + this.searchable.wrap + .select('.search') + .append('input') + .classed('search-box', true) + .attr('placeholder', 'Search') + .on('input', function() { + context.searchable.searchTerm = this.value.toLowerCase() || null; + context.config.activePage = 0; + context.config.startIndex = context.config.activePage * context.config.nRowsPerPage; // first row shown + context.config.endIndex = context.config.startIndex + context.config.nRowsPerPage; // last row shown + context.draw(); + }); this.searchable.wrap.select('.search').append('span').classed('nNrecords', true); } @@ -2617,32 +3640,55 @@ function layout$3() { var _this = this; - this.exportable.wrap = this.wrap.select('.table-bottom').append('div').classed('interactivity exportable-container', true).classed('hidden', !this.config.exportable); + this.exportable.wrap = this.wrap + .select('.table-bottom') + .append('div') + .classed('interactivity exportable-container', true) + .classed('hidden', !this.config.exportable); this.exportable.wrap.append('span').text('Export:'); - if (this.config.exports && this.config.exports.length) this.config.exports.forEach(function (fmt) { - _this.exportable.wrap.append('a').classed('wc-button export', true).attr({ - id: fmt - }).style(!_this.test && navigator.msSaveBlob ? { - cursor: 'pointer', - 'text-decoration': 'underline', - color: 'blue' - } : null).text(fmt.toUpperCase()); - }); + if (this.config.exports && this.config.exports.length) + this.config.exports.forEach(function(fmt) { + _this.exportable.wrap + .append('a') + .classed('wc-button export', true) + .attr({ + id: fmt + }) + .style( + !_this.test && navigator.msSaveBlob + ? { + cursor: 'pointer', + 'text-decoration': 'underline', + color: 'blue' + } + : null + ) + .text(fmt.toUpperCase()); + }); } function download(fileType, data) { //transform blob array into a blob of characters var blob = new Blob(data, { - type: fileType === 'csv' ? 'text/csv;charset=utf-8;' : fileType === 'xlsx' ? 'application/octet-stream' : console.warn('File type not supported: ' + fileType) + type: fileType === 'csv' + ? 'text/csv;charset=utf-8;' + : fileType === 'xlsx' + ? 'application/octet-stream' + : console.warn('File type not supported: ' + fileType) }); - var fileName = 'webchartsTableExport_' + d3.time.format('%Y-%m-%dT%H-%M-%S')(new Date()) + '.' + fileType; + var fileName = + 'webchartsTableExport_' + + d3.time.format('%Y-%m-%dT%H-%M-%S')(new Date()) + + '.' + + fileType; var link = this.wrap.select('.export#' + fileType); if (navigator.msSaveBlob) //IE - navigator.msSaveBlob(blob, fileName);else if (link.node().download !== undefined) { + navigator.msSaveBlob(blob, fileName); + else if (link.node().download !== undefined) { //21st century browsers var url = URL.createObjectURL(blob); link.node().setAttribute('href', url); @@ -2653,18 +3699,18 @@ function csv(data) { var _this = this; - this.wrap.select('.export#csv').on('click', function () { + this.wrap.select('.export#csv').on('click', function() { var CSVarray = []; //add headers to CSV array - var headers = _this.config.headers.map(function (header) { + var headers = _this.config.headers.map(function(header) { return '"' + header.replace(/"/g, '""') + '"'; }); CSVarray.push(headers); //add rows to CSV array - data.forEach(function (d, i) { - var row = _this.config.cols.map(function (col) { + data.forEach(function(d, i) { + var row = _this.config.cols.map(function(col) { var value = d[col]; if (typeof value === 'string') value = value.replace(/"/g, '""'); @@ -2683,19 +3729,21 @@ function xlsx(data) { var _this = this; - this.wrap.select('.export#xlsx').on('click', function () { + this.wrap.select('.export#xlsx').on('click', function() { var sheetName = 'Selected Data'; var options = { bookType: 'xlsx', bookSST: true, type: 'binary' }; - var arrayOfArrays = data.map(function (d) { - return Object.keys(d).filter(function (key) { - return _this.config.cols.indexOf(key) > -1; - }).map(function (key) { - return d[key]; - }); + var arrayOfArrays = data.map(function(d) { + return Object.keys(d) + .filter(function(key) { + return _this.config.cols.indexOf(key) > -1; + }) + .map(function(key) { + return d[key]; + }); }); // convert data from array of objects to array of arrays. var workbook = { SheetNames: [sheetName], @@ -2704,7 +3752,9 @@ var cols = []; //Convert headers and data from array of arrays to sheet. - workbook.Sheets[sheetName] = XLSX.utils.aoa_to_sheet([_this.config.headers].concat(arrayOfArrays)); + workbook.Sheets[sheetName] = XLSX.utils.aoa_to_sheet( + [_this.config.headers].concat(arrayOfArrays) + ); //Add filters to spreadsheet. workbook.Sheets[sheetName]['!autofilter'] = { @@ -2712,7 +3762,7 @@ }; //Define column widths in spreadsheet. - _this.table.selectAll('thead tr th').each(function () { + _this.table.selectAll('thead tr th').each(function() { cols.push({ wpx: this.offsetWidth }); }); workbook.Sheets[sheetName]['!cols'] = cols; @@ -2724,7 +3774,8 @@ for (var i = 0; i !== s.length; ++i) { view[i] = s.charCodeAt(i) & 0xff; - }return buffer; + } + return buffer; }; // convert spreadsheet to binary or something, i don't know //Download .xlsx file. @@ -2745,10 +3796,16 @@ } function layout$4() { - //Add sort container. - this.sortable.wrap = this.wrap.select('.table-top').append('div').classed('interactivity sortable-container', true).classed('hidden', !this.config.sortable); - this.sortable.wrap.append('div').classed('instruction', true).text('Click column headers to sort.'); + this.sortable.wrap = this.wrap + .select('.table-top') + .append('div') + .classed('interactivity sortable-container', true) + .classed('hidden', !this.config.sortable); + this.sortable.wrap + .append('div') + .classed('instruction', true) + .text('Click column headers to sort.'); } function onClick(th, header) { @@ -2757,7 +3814,7 @@ col = this.config.cols[this.config.headers.indexOf(header)]; //Check if column is already a part of current sort order. - var sortItem = this.sortable.order.filter(function (item) { + var sortItem = this.sortable.order.filter(function(item) { return item.col === col; })[0]; @@ -2766,7 +3823,11 @@ sortItem = { col: col, direction: 'ascending', - wrap: this.sortable.wrap.append('div').datum({ key: col }).classed('wc-button sort-box', true).text(header) + wrap: this.sortable.wrap + .append('div') + .datum({ key: col }) + .classed('wc-button sort-box', true) + .text(header) }; sortItem.wrap.append('span').classed('sort-direction', true).html('↓'); sortItem.wrap.append('span').classed('remove-sort', true).html('❌'); @@ -2774,25 +3835,34 @@ } else { //Otherwise reverse its sort direction. sortItem.direction = sortItem.direction === 'ascending' ? 'descending' : 'ascending'; - sortItem.wrap.select('span.sort-direction').html(sortItem.direction === 'ascending' ? '↓' : '↑'); + sortItem.wrap + .select('span.sort-direction') + .html(sortItem.direction === 'ascending' ? '↓' : '↑'); } //Hide sort instructions. this.sortable.wrap.select('.instruction').classed('hidden', true); //Add sort container deletion functionality. - this.sortable.order.forEach(function (item, i) { - item.wrap.on('click', function (d) { + this.sortable.order.forEach(function(item, i) { + item.wrap.on('click', function(d) { //Remove column's sort container. d3.select(this).remove(); //Remove column from sort. - context.sortable.order.splice(context.sortable.order.map(function (d) { - return d.col; - }).indexOf(d.key), 1); + context.sortable.order.splice( + context.sortable.order + .map(function(d) { + return d.col; + }) + .indexOf(d.key), + 1 + ); //Display sorting instruction. - context.sortable.wrap.select('.instruction').classed('hidden', context.sortable.order.length); + context.sortable.wrap + .select('.instruction') + .classed('hidden', context.sortable.order.length); //Redraw chart. context.draw(); @@ -2806,15 +3876,24 @@ function sortData(data) { var _this = this; - data = data.sort(function (a, b) { + data = data.sort(function(a, b) { var order = 0; - _this.sortable.order.forEach(function (item) { + _this.sortable.order.forEach(function(item) { var aCell = a[item.col], bCell = b[item.col]; if (order === 0) { - if (item.direction === 'ascending' && aCell < bCell || item.direction === 'descending' && aCell > bCell) order = -1;else if (item.direction === 'ascending' && aCell > bCell || item.direction === 'descending' && aCell < bCell) order = 1; + if ( + (item.direction === 'ascending' && aCell < bCell) || + (item.direction === 'descending' && aCell > bCell) + ) + order = -1; + else if ( + (item.direction === 'ascending' && aCell > bCell) || + (item.direction === 'descending' && aCell < bCell) + ) + order = 1; } }); @@ -2832,7 +3911,11 @@ } function layout$5() { - this.pagination.wrap = this.wrap.select('.table-bottom').append('div').classed('interactivity pagination-container', true).classed('hidden', !this.config.pagination); + this.pagination.wrap = this.wrap + .select('.table-bottom') + .append('div') + .classed('interactivity pagination-container', true) + .classed('hidden', !this.config.pagination); } function updatePagination() { @@ -2842,9 +3925,11 @@ this.pagination.links.classed('active', false); //Set to active the selected page link. - var activePage = this.pagination.links.filter(function (link) { - return +link.rel === +_this.config.activePage; - }).classed('active', true); + var activePage = this.pagination.links + .filter(function(link) { + return +link.rel === +_this.config.activePage; + }) + .classed('active', true); //Define and draw selected page. this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; @@ -2862,15 +3947,28 @@ this.pagination.wrap.selectAll('a,span').remove(); var _loop = function _loop(i) { - _this.pagination.wrap.append('a').datum({ rel: i }).attr({ - rel: i - }).text(i + 1).classed('wc-button page-link', true).classed('active', function (d) { - return d.rel == _this.config.activePage; - }).classed('hidden', function () { - return _this.config.activePage < _this.config.nPageLinksDisplayed ? i >= _this.config.nPageLinksDisplayed // first nPageLinksDisplayed pages - : _this.config.activePage >= _this.config.nPages - _this.config.nPageLinksDisplayed ? i < _this.config.nPages - _this.config.nPageLinksDisplayed // last nPageLinksDisplayed pages - : i < _this.config.activePage - (Math.ceil(_this.config.nPageLinksDisplayed / 2) - 1) || _this.config.activePage + _this.config.nPageLinksDisplayed / 2 < i; // nPageLinksDisplayed < activePage or activePage < (nPages - nPageLinksDisplayed) - }); + _this.pagination.wrap + .append('a') + .datum({ rel: i }) + .attr({ + rel: i + }) + .text(i + 1) + .classed('wc-button page-link', true) + .classed('active', function(d) { + return d.rel == _this.config.activePage; + }) + .classed('hidden', function() { + return _this.config.activePage < _this.config.nPageLinksDisplayed + ? i >= _this.config.nPageLinksDisplayed // first nPageLinksDisplayed pages + : _this.config.activePage >= + _this.config.nPages - _this.config.nPageLinksDisplayed + ? i < _this.config.nPages - _this.config.nPageLinksDisplayed // last nPageLinksDisplayed pages + : i < + _this.config.activePage - + (Math.ceil(_this.config.nPageLinksDisplayed / 2) - 1) || + _this.config.activePage + _this.config.nPageLinksDisplayed / 2 < i; // nPageLinksDisplayed < activePage or activePage < (nPages - nPageLinksDisplayed) + }); }; for (var i = 0; i < this.config.nPages; i++) { @@ -2890,28 +3988,69 @@ Left side \-------------------------------------------------------------------------------------------**/ - this.pagination.wrap.insert('span', ':first-child').classed('dot-dot-dot', true).text('...').classed('hidden', this.config.activePage < this.config.nPageLinksDisplayed); - - this.pagination.prev = this.pagination.wrap.insert('a', ':first-child').classed('wc-button arrow-link wc-left', true).classed('hidden', this.config.activePage == 0).attr({ - rel: prev - }).text('<'); - - this.pagination.doublePrev = this.pagination.wrap.insert('a', ':first-child').classed('wc-button arrow-link wc-left double', true).classed('hidden', this.config.activePage == 0).attr({ - rel: 0 - }).text('<<'); + this.pagination.wrap + .insert('span', ':first-child') + .classed('dot-dot-dot', true) + .text('...') + .classed('hidden', this.config.activePage < this.config.nPageLinksDisplayed); + + this.pagination.prev = this.pagination.wrap + .insert('a', ':first-child') + .classed('wc-button arrow-link wc-left', true) + .classed('hidden', this.config.activePage == 0) + .attr({ + rel: prev + }) + .text('<'); + + this.pagination.doublePrev = this.pagination.wrap + .insert('a', ':first-child') + .classed('wc-button arrow-link wc-left double', true) + .classed('hidden', this.config.activePage == 0) + .attr({ + rel: 0 + }) + .text('<<'); /**-------------------------------------------------------------------------------------------\ Right side \-------------------------------------------------------------------------------------------**/ - this.pagination.wrap.append('span').classed('dot-dot-dot', true).text('...').classed('hidden', this.config.activePage >= Math.max(this.config.nPageLinksDisplayed, this.config.nPages - this.config.nPageLinksDisplayed) || this.config.nPages <= this.config.nPageLinksDisplayed); - this.pagination.next = this.pagination.wrap.append('a').classed('wc-button arrow-link wc-right', true).classed('hidden', this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0).attr({ - rel: next - }).text('>'); - - this.pagination.doubleNext = this.pagination.wrap.append('a').classed('wc-button arrow-link wc-right double', true).classed('hidden', this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0).attr({ - rel: this.config.nPages - 1 - }).text('>>'); + this.pagination.wrap + .append('span') + .classed('dot-dot-dot', true) + .text('...') + .classed( + 'hidden', + this.config.activePage >= + Math.max( + this.config.nPageLinksDisplayed, + this.config.nPages - this.config.nPageLinksDisplayed + ) || this.config.nPages <= this.config.nPageLinksDisplayed + ); + this.pagination.next = this.pagination.wrap + .append('a') + .classed('wc-button arrow-link wc-right', true) + .classed( + 'hidden', + this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0 + ) + .attr({ + rel: next + }) + .text('>'); + + this.pagination.doubleNext = this.pagination.wrap + .append('a') + .classed('wc-button arrow-link wc-right double', true) + .classed( + 'hidden', + this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0 + ) + .attr({ + rel: this.config.nPages - 1 + }) + .text('>>'); this.pagination.arrows = this.pagination.wrap.selectAll('a.arrow-link'); this.pagination.doubleArrows = this.pagination.wrap.selectAll('a.double-arrow-link'); @@ -2932,7 +4071,7 @@ addLinks.call(this); //Render a different page on click. - this.pagination.links.on('click', function () { + this.pagination.links.on('click', function() { context.config.activePage = +d3.select(this).attr('rel'); updatePagination.call(context); }); @@ -2941,17 +4080,25 @@ addArrows.call(this); //Render a different page on click. - this.pagination.arrows.on('click', function () { + this.pagination.arrows.on('click', function() { if (context.config.activePage !== +d3.select(this).attr('rel')) { context.config.activePage = +d3.select(this).attr('rel'); - context.pagination.prev.attr('rel', context.config.activePage > 0 ? context.config.activePage - 1 : 0); - context.pagination.next.attr('rel', context.config.activePage < context.config.nPages ? context.config.activePage + 1 : context.config.nPages - 1); + context.pagination.prev.attr( + 'rel', + context.config.activePage > 0 ? context.config.activePage - 1 : 0 + ); + context.pagination.next.attr( + 'rel', + context.config.activePage < context.config.nPages + ? context.config.activePage + 1 + : context.config.nPages - 1 + ); updatePagination.call(context); } }); //Render a different page on click. - this.pagination.doubleArrows.on('click', function () { + this.pagination.doubleArrows.on('click', function() { context.config.activePage = +d3.select(this).attr('rel'); updatePagination.call(context); }); @@ -2984,9 +4131,17 @@ this.test = test; if (d3.select(this.div).select('.loader').empty()) { - d3.select(this.div).insert('div', ':first-child').attr('class', 'loader').selectAll('.blockG').data(d3.range(8)).enter().append('div').attr('class', function (d) { - return 'blockG rotate' + (d + 1); - }); + d3 + .select(this.div) + .insert('div', ':first-child') + .attr('class', 'loader') + .selectAll('.blockG') + .data(d3.range(8)) + .enter() + .append('div') + .attr('class', function(d) { + return 'blockG rotate' + (d + 1); + }); } //Define default settings. @@ -3026,8 +4181,10 @@ //make sure container is visible (has height and width) before trying to initialize var visible = d3.select(_this.div).property('offsetWidth') > 0 || test; if (!visible) { - console.warn('The table cannot be initialized inside an element with 0 width. The table will be initialized as soon as the container element is given a width > 0.'); - var onVisible = setInterval(function (i) { + console.warn( + 'The table cannot be initialized inside an element with 0 width. The table will be initialized as soon as the container element is given a width > 0.' + ); + var onVisible = setInterval(function(i) { var visible_now = d3.select(_this.div).property('offsetWidth') > 0; if (visible_now) { _this.layout(); @@ -3085,7 +4242,9 @@ } function destroy$2() { - var destroyControls = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var destroyControls = arguments.length > 0 && arguments[0] !== undefined + ? arguments[0] + : false; //run onDestroy callback this.events.onDestroy.call(this); @@ -3102,14 +4261,20 @@ function setDefault(setting) { var _default_ = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - this.config[setting] = this.config[setting] !== undefined ? this.config[setting] : _default_; + this.config[setting] = this.config[setting] !== undefined + ? this.config[setting] + : _default_; } function setDefaults$1(firstItem) { //Set data-driven defaults. if (this.config.cols instanceof Array && this.config.headers instanceof Array) { if (this.config.cols.length === 0) delete this.config.cols; - if (this.config.headers.length === 0 || this.config.headers.length !== this.config.cols.length) delete this.config.headers; + if ( + this.config.headers.length === 0 || + this.config.headers.length !== this.config.cols.length + ) + delete this.config.headers; } this.config.cols = this.config.cols || d3.keys(firstItem); @@ -3142,7 +4307,7 @@ this.config.headers = this.config.headers || this.config.cols; if (this.config.keep) { - this.config.keep.forEach(function (e) { + this.config.keep.forEach(function(e) { if (_this.config.cols.indexOf(e) === -1) { _this.config.cols.unshift(e); } @@ -3152,9 +4317,9 @@ var filtered = data; if (this.filters.length) { - this.filters.forEach(function (e) { + this.filters.forEach(function(e) { var is_array = e.val instanceof Array; - filtered = filtered.filter(function (d) { + filtered = filtered.filter(function(d) { if (is_array) { return e.val.indexOf(d[e.col]) !== -1; } else { @@ -3164,30 +4329,36 @@ }); } - var slimmed = d3.nest().key(function (d) { - if (_this.config.row_per) { - return _this.config.row_per.map(function (m) { - return d[m]; - }).join(' '); - } else { - return d; - } - }).rollup(function (r) { - if (_this.config.dataManipulate) { - r = _this.config.dataManipulate(r); - } - var nuarr = r.map(function (m) { - var arr = []; - for (var x in m) { - arr.push({ col: x, text: m[x] }); + var slimmed = d3 + .nest() + .key(function(d) { + if (_this.config.row_per) { + return _this.config.row_per + .map(function(m) { + return d[m]; + }) + .join(' '); + } else { + return d; + } + }) + .rollup(function(r) { + if (_this.config.dataManipulate) { + r = _this.config.dataManipulate(r); } - arr.sort(function (a, b) { - return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); + var nuarr = r.map(function(m) { + var arr = []; + for (var x in m) { + arr.push({ col: x, text: m[x] }); + } + arr.sort(function(a, b) { + return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); + }); + return { cells: arr, raw: m }; }); - return { cells: arr, raw: m }; - }); - return nuarr; - }).entries(filtered); + return nuarr; + }) + .entries(filtered); this.data.current = slimmed.length ? slimmed : [{ key: null, values: [] }]; // dummy nested data array @@ -3202,8 +4373,8 @@ if (config.row_per) { var rev_order = config.row_per.slice(0).reverse(); - rev_order.forEach(function (e) { - tbodies.sort(function (a, b) { + rev_order.forEach(function(e) { + tbodies.sort(function(a, b) { return a.values[0].raw[e] - b.values[0].raw[e]; }); }); @@ -3211,11 +4382,15 @@ //Delete text from columns with repeated values? if (config.row_per) { - rows.filter(function (f, i) { - return i > 0; - }).selectAll('td').filter(function (f) { - return config.row_per.indexOf(f.col) > -1; - }).text(''); + rows + .filter(function(f, i) { + return i > 0; + }) + .selectAll('td') + .filter(function(f) { + return config.row_per.indexOf(f.col) > -1; + }) + .text(''); } return this.data.current; @@ -3257,7 +4432,7 @@ onDestroy: function onDestroy() {} }; - thisTable.on = function (event, callback) { + thisTable.on = function(event, callback) { var possible_events = ['init', 'layout', 'preprocess', 'draw', 'destroy']; if (possible_events.indexOf(event) < 0) { return; @@ -3283,17 +4458,22 @@ chart.multiples = []; function goAhead(data) { - var split_vals = d3.set(data.map(function (m) { - return m[split_by]; - })).values().filter(function (f) { - return f; - }); + var split_vals = d3 + .set( + data.map(function(m) { + return m[split_by]; + }) + ) + .values() + .filter(function(f) { + return f; + }); if (order) { - split_vals = split_vals.sort(function (a, b) { + split_vals = split_vals.sort(function(a, b) { return d3.ascending(order.indexOf(a), order.indexOf(b)); }); } - split_vals.forEach(function (e) { + split_vals.forEach(function(e) { var mchart = createChart(chart.wrap.node(), chart.config, chart.controls); chart.multiples.push(mchart); mchart.parent = chart; @@ -3309,10 +4489,14 @@ } function getValType(data, variable) { - var var_vals = d3.set(data.map(function (m) { - return m[variable]; - })).values(); - var vals_numbers = var_vals.filter(function (f) { + var var_vals = d3 + .set( + data.map(function(m) { + return m[variable]; + }) + ) + .values(); + var vals_numbers = var_vals.filter(function(f) { return +f || +f === 0; }); @@ -3326,8 +4510,8 @@ function lengthenRaw(data, columns) { var my_data = []; - data.forEach(function (e) { - columns.forEach(function (g) { + data.forEach(function(e) { + columns.forEach(function(g) { var obj = Object.create(e); obj.wc_category = g; obj.wc_value = e[g]; @@ -3355,5 +4539,4 @@ }; return index; - -})); +}); diff --git a/build/webcharts.min.js b/build/webcharts.min.js index caaf525..dcd9d01 100644 --- a/build/webcharts.min.js +++ b/build/webcharts.min.js @@ -1,3 +1,3 @@ -(function(global,factory){typeof exports==="object"&&typeof module!=="undefined"?module.exports=factory(require("d3")):typeof define==="function"&&define.amd?define(["d3"],factory):global.webCharts=factory(global.d3)})(typeof self!=="undefined"?self:this,function(d3){"use strict";var version="1.11.5";function init(data){var _this=this;var test=arguments.length>1&&arguments[1]!==undefined?arguments[1]:false;if(d3.select(this.div).select(".loader").empty()){d3.select(this.div).insert("div",":first-child").attr("class","loader").selectAll(".blockG").data(d3.range(8)).enter().append("div").attr("class",function(d){return"blockG rotate"+(d+1)})}this.wrap.attr("class","wc-chart");this.setDefaults();this.raw_data=data;this.initial_data=data;var startup=function startup(data){if(_this.controls){_this.controls.targets.push(_this);if(!_this.controls.ready){_this.controls.init(_this.raw_data)}else{_this.controls.layout()}}var visible=d3.select(_this.div).property("offsetWidth")>0||test;if(!visible){console.warn("The chart cannot be initialized inside an element with 0 width. The chart will be initialized as soon as the container element is given a width > 0.");var onVisible=setInterval(function(i){var visible_now=d3.select(_this.div).property("offsetWidth")>0;if(visible_now){_this.layout();_this.draw();clearInterval(onVisible)}},500)}else{_this.layout();_this.draw()}};this.events.onInit.call(this);if(this.raw_data.length){this.checkRequired(this.raw_data)}startup(data);return this}function checkRequired(data){var _this=this;var colnames=Object.keys(data[0]);var requiredVars=[];var requiredCols=[];if(this.config.x&&this.config.x.column){requiredVars.push("this.config.x.column");requiredCols.push(this.config.x.column)}if(this.config.y&&this.config.y.column){requiredVars.push("this.config.y.column");requiredCols.push(this.config.y.column)}if(this.config.color_by){requiredVars.push("this.config.color_by");requiredCols.push(this.config.color_by)}if(this.config.marks)this.config.marks.forEach(function(e,i){if(e.per&&e.per.length){e.per.forEach(function(p,j){requiredVars.push("this.config.marks["+i+"].per["+j+"]");requiredCols.push(p)})}if(e.split){requiredVars.push("this.config.marks["+i+"].split");requiredCols.push(e.split)}if(e.values){for(var value in e.values){requiredVars.push("this.config.marks["+i+"].values['"+value+"']");requiredCols.push(value)}}});var missingDataField=false;requiredCols.forEach(function(e,i){if(colnames.indexOf(e)<0){missingDataField=true;d3.select(_this.div).select(".loader").remove();_this.wrap.append("div").style("color","red").html('The value "'+e+'" for the '+requiredVars[i]+" setting does not match any column in the provided dataset.");throw new Error('Error in settings object: The value "'+e+'" for the '+requiredVars[i]+" setting does not match any column in the provided dataset.")}});return{missingDataField:missingDataField,dataFieldArguments:requiredVars,requiredDataFields:requiredCols}}function addSVG(){this.svg=this.wrap.append("svg").datum(function(){return null}).attr({class:"wc-svg",xmlns:"http://www.w3.org/2000/svg",version:"1.1",xlink:"http://www.w3.org/1999/xlink"}).append("g").style("display","inline-block")}function addDefs(){var defs=this.svg.append("defs");defs.append("pattern").attr({id:"diagonal-stripes",x:0,y:0,width:3,height:8,patternUnits:"userSpaceOnUse",patternTransform:"rotate(30)"}).append("rect").attr({x:"0",y:"0",width:"2",height:"8"}).style({stroke:"none",fill:"black"});defs.append("clipPath").attr("id",this.id).append("rect").attr("class","plotting-area")}function addXAxis(){this.svg.append("g").attr("class","x axis").append("text").attr("class","axis-title").attr("dy","-.35em").attr("text-anchor","middle")}function addYAxis(){this.svg.append("g").attr("class","y axis").append("text").attr("class","axis-title").attr("transform","rotate(-90)").attr("dy",".75em").attr("text-anchor","middle")}function addOverlay(){this.overlay=this.svg.append("rect").attr("class","overlay").attr("opacity",0).attr("fill","none").style("pointer-events","all")}function addLegend(){if(!this.parent)this.wrap.append("ul").datum(function(){return null}).attr("class","legend").style("vertical-align","top").append("span").attr("class","legend-title")}function clearLoader(){d3.select(this.div).select(".loader").remove()}function layout(){addSVG.call(this);addDefs.call(this);addXAxis.call(this);addYAxis.call(this);addOverlay.call(this);addLegend.call(this);clearLoader.call(this);this.events.onLayout.call(this)}function draw(raw_data,processed_data){var _this=this;var chart=this;var config=this.config;this.events.onPreprocess.call(this);var raw=raw_data?raw_data:this.raw_data?this.raw_data:[];if(processed_data){console.warn("Drawing the chart using user-defined 'processed_data', this is an experimental, untested feature.")}this.consolidateData(raw);var div_width=parseInt(this.wrap.style("width"));this.setColorScale();var max_width=config.max_width?config.max_width:div_width;this.raw_width=config.x.type==="ordinal"&&+config.x.range_band?(+config.x.range_band+config.x.range_band*config.padding)*this.x_dom.length:config.resizable?max_width:config.width?config.width:div_width;this.raw_height=config.y.type==="ordinal"&&+config.y.range_band?(+config.y.range_band+config.y.range_band*config.padding)*this.y_dom.length:config.resizable?max_width*(1/config.aspect):config.height?config.height:div_width*(1/config.aspect);var pseudo_width=this.svg.select(".overlay").attr("width")?this.svg.select(".overlay").attr("width"):this.raw_width;var pseudo_height=this.svg.select(".overlay").attr("height")?this.svg.select(".overlay").attr("height"):this.raw_height;this.svg.select(".x.axis").select(".axis-title").text(function(d){return typeof config.x.label==="string"?config.x.label:typeof config.x.label==="function"?config.x.label.call(_this):null});this.svg.select(".y.axis").select(".axis-title").text(function(d){return typeof config.y.label==="string"?config.y.label:typeof config.y.label==="function"?config.y.label.call(_this):null});this.xScaleAxis(pseudo_width);this.yScaleAxis(pseudo_height);if(config.resizable&&typeof window!=="undefined"){d3.select(window).on("resize."+this.element+this.id,function(){chart.resize()})}else if(typeof window!=="undefined"){d3.select(window).on("resize."+this.element+this.id,null)}this.events.onDraw.call(this);this.resize()}function naturalSorter(a,b){function chunkify(t){var tz=[];var x=0,y=-1,n=0,i=void 0,j=void 0;while(i=(j=t.charAt(x++)).charCodeAt(0)){var m=i==46||i>=48&&i<=57;if(m!==n){tz[++y]="";n=m}tz[y]+=j}return tz}var aa=chunkify(a.toLowerCase());var bb=chunkify(b.toLowerCase());for(var x=0;aa[x]&&bb[x];x++){if(aa[x]!==bb[x]){var c=Number(aa[x]),d=Number(bb[x]);if(c==aa[x]&&d==bb[x]){return c-d}else{return aa[x]>bb[x]?1:-1}}}return aa.length-bb.length}function setDomain(axis){var _this=this;var otherAxis=axis==="x"?"y":"x";if(this.config[axis].type==="ordinal"){if(this.config[axis].domain){this[axis+"_dom"]=this.config[axis].domain}else if(this.config[axis].order){this[axis+"_dom"]=d3.set(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]}))).values().sort(function(a,b){return d3.ascending(_this.config[axis].order.indexOf(a),_this.config[axis].order.indexOf(b))})}else if(this.config[axis].sort&&this.config[axis].sort==="alphabetical-ascending"){this[axis+"_dom"]=d3.set(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]}))).values().sort(naturalSorter)}else if(["time","linear"].indexOf(this.config[otherAxis].type)>-1&&this.config[axis].sort==="earliest"){this[axis+"_dom"]=d3.nest().key(function(d){return d[_this.config[axis].column]}).rollup(function(d){return d.map(function(m){return m[_this.config[otherAxis].column]}).filter(function(f){return f instanceof Date})}).entries(this.filtered_data).sort(function(a,b){return d3.min(b.values)-d3.min(a.values)}).map(function(m){return m.key})}else if(!this.config[axis].sort||this.config[axis].sort==="alphabetical-descending"){this[axis+"_dom"]=d3.set(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]}))).values().sort(naturalSorter).reverse()}else{this[axis+"_dom"]=d3.set(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]}))).values()}}else if(this.config.marks.map(function(m){return m["summarize"+axis.toUpperCase()]==="percent"}).indexOf(true)>-1){this[axis+"_dom"]=[0,1]}else{this[axis+"_dom"]=d3.extent(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]})))}if(this.config[axis].type==="linear"&&this[axis+"_dom"][0]===this[axis+"_dom"][1])this[axis+"_dom"]=this[axis+"_dom"][0]!==0?[this[axis+"_dom"][0]-this[axis+"_dom"][0]*.01,this[axis+"_dom"][1]+this[axis+"_dom"][1]*.01]:[-1,1];return this[axis+"_dom"]}function consolidateData(raw){var _this=this;this.setDefaults();this.filtered_data=raw;if(this.filters.length){this.filters.forEach(function(filter){_this.filtered_data=_this.filtered_data.filter(function(d){return filter.all===true&&filter.index===0?d:filter.val instanceof Array?filter.val.indexOf(d[filter.col])>-1:d[filter.col]===filter.val})})}this.config.marks.forEach(function(mark,i){if(mark.type!=="bar"){mark.arrange=null;mark.split=null}var mark_info=mark.per?_this.transformData(raw,mark):{data:[],x_dom:[],y_dom:[]};_this.marks[i]={id:mark.id,type:mark.type,per:mark.per,data:mark_info.data,x_dom:mark_info.x_dom,y_dom:mark_info.y_dom,split:mark.split,text:mark.text,arrange:mark.arrange,order:mark.order,summarizeX:mark.summarizeX,summarizeY:mark.summarizeY,tooltip:mark.tooltip,radius:mark.radius,attributes:mark.attributes,values:mark.values}});setDomain.call(this,"x");setDomain.call(this,"y")}function setDefaults(){this.config.x=this.config.x||{};this.config.y=this.config.y||{};this.config.x.label=this.config.x.label!==undefined?this.config.x.label:this.config.x.column;this.config.y.label=this.config.y.label!==undefined?this.config.y.label:this.config.y.column;this.config.x.sort=this.config.x.sort||"alphabetical-ascending";this.config.y.sort=this.config.y.sort||"alphabetical-descending";this.config.x.type=this.config.x.type||"linear";this.config.y.type=this.config.y.type||"linear";this.config.x.range_band=this.config.x.range_band||this.config.range_band;this.config.y.range_band=this.config.y.range_band||this.config.range_band;this.config.margin=this.config.margin||{};this.config.legend=this.config.legend||{};this.config.legend.label=this.config.legend.label!==undefined?this.config.legend.label:this.config.color_by;this.config.legend.location=this.config.legend.location!==undefined?this.config.legend.location:"bottom";this.config.marks=this.config.marks&&this.config.marks.length?this.config.marks:[{}];this.config.marks.forEach(function(m,i){m.id=m.id?m.id:"mark"+(i+1)});this.config.date_format=this.config.date_format||"%x";this.config.padding=this.config.padding!==undefined?this.config.padding:.3;this.config.outer_pad=this.config.outer_pad!==undefined?this.config.outer_pad:.1;this.config.resizable=this.config.resizable!==undefined?this.config.resizable:true;this.config.aspect=this.config.aspect||1.33;this.config.colors=this.config.colors||["rgb(102,194,165)","rgb(252,141,98)","rgb(141,160,203)","rgb(231,138,195)","rgb(166,216,84)","rgb(255,217,47)","rgb(229,196,148)","rgb(179,179,179)"];this.config.scale_text=this.config.scale_text===undefined?true:this.config.scale_text;this.config.transitions=this.config.transitions===undefined?true:this.config.transitions}function cleanData(mark,raw){var _this=this;var dateConvert=d3.time.format(this.config.date_format);var clean=raw;clean=mark.per&&mark.per.length?clean.filter(function(f){return f[mark.per[0]]!==undefined}):clean;if(this.config.x.column){clean=clean.filter(function(f){return[undefined,null].indexOf(f[_this.config.x.column])<0})}if(this.config.y.column){clean=clean.filter(function(f){return[undefined,null].indexOf(f[_this.config.y.column])<0})}if(this.config.x.type==="time"){clean=clean.filter(function(f){return f[_this.config.x.column]instanceof Date?f[_this.config.x.column]:dateConvert.parse(f[_this.config.x.column])});clean.forEach(function(e){return e[_this.config.x.column]=e[_this.config.x.column]instanceof Date?e[_this.config.x.column]:dateConvert.parse(e[_this.config.x.column])})}if(this.config.y.type==="time"){clean=clean.filter(function(f){return f[_this.config.y.column]instanceof Date?f[_this.config.y.column]:dateConvert.parse(f[_this.config.y.column])});clean.forEach(function(e){return e[_this.config.y.column]=e[_this.config.y.column]instanceof Date?e[_this.config.y.column]:dateConvert.parse(e[_this.config.y.column])})}if((this.config.x.type==="linear"||this.config.x.type==="log")&&this.config.x.column){clean=clean.filter(function(f){return mark.summarizeX!=="count"&&mark.summarizeX!=="percent"?!(isNaN(f[_this.config.x.column])||/^\s*$/.test(f[_this.config.x.column])):f})}if((this.config.y.type==="linear"||this.config.y.type==="log")&&this.config.y.column){clean=clean.filter(function(f){return mark.summarizeY!=="count"&&mark.summarizeY!=="percent"?!(isNaN(f[_this.config.y.column])||/^\s*$/.test(f[_this.config.y.column])):f})}return clean}var stats={mean:d3.mean,min:d3.min,max:d3.max,median:d3.median,sum:d3.sum};function summarize(vals){var operation=arguments.length>1&&arguments[1]!==undefined?arguments[1]:"mean";var nvals=vals.filter(function(f){return+f||+f===0}).map(function(m){return+m});if(operation==="cumulative"){return null}var mathed=operation==="count"?vals.length:operation==="percent"?vals.length:stats[operation](nvals);return mathed}function makeNest(mark,entries,sublevel){var _this=this;var dom_xs=[];var dom_ys=[];var this_nest=d3.nest();var totalOrder=void 0;if(this.config.x.type==="linear"&&this.config.x.bin||this.config.y.type==="linear"&&this.config.y.bin){var xy=this.config.x.type==="linear"&&this.config.x.bin?"x":"y";var quant=d3.scale.quantile().domain(d3.extent(entries.map(function(m){return+m[_this.config[xy].column]}))).range(d3.range(+this.config[xy].bin));entries.forEach(function(e){return e.wc_bin=quant(e[_this.config[xy].column])});this_nest.key(function(d){return quant.invertExtent(d.wc_bin)})}else{this_nest.key(function(d){return mark.per.map(function(m){return d[m]}).join(" ")})}if(sublevel){this_nest.key(function(d){return d[sublevel]});this_nest.sortKeys(function(a,b){return _this.config.x.type==="time"?d3.ascending(new Date(a),new Date(b)):_this.config.x.order?d3.ascending(_this.config.x.order.indexOf(a),_this.config.x.order.indexOf(b)):sublevel===_this.config.color_by&&_this.config.legend.order?d3.ascending(_this.config.legend.order.indexOf(a),_this.config.legend.order.indexOf(b)):_this.config.x.type==="ordinal"||_this.config.y.type==="ordinal"?naturalSorter(a,b):d3.ascending(+a,+b)})}this_nest.rollup(function(r){var obj={raw:r};var y_vals=r.map(function(m){return m[_this.config.y.column]}).sort(d3.ascending);var x_vals=r.map(function(m){return m[_this.config.x.column]}).sort(d3.ascending);obj.x=_this.config.x.type==="ordinal"?r[0][_this.config.x.column]:summarize(x_vals,mark.summarizeX);obj.y=_this.config.y.type==="ordinal"?r[0][_this.config.y.column]:summarize(y_vals,mark.summarizeY);obj.x_q25=_this.config.error_bars&&_this.config.y.type==="ordinal"?d3.quantile(x_vals,.25):obj.x;obj.x_q75=_this.config.error_bars&&_this.config.y.type==="ordinal"?d3.quantile(x_vals,.75):obj.x;obj.y_q25=_this.config.error_bars?d3.quantile(y_vals,.25):obj.y;obj.y_q75=_this.config.error_bars?d3.quantile(y_vals,.75):obj.y;dom_xs.push([obj.x_q25,obj.x_q75,obj.x]);dom_ys.push([obj.y_q25,obj.y_q75,obj.y]);if(mark.summarizeY==="cumulative"){var interm=entries.filter(function(f){return _this.config.x.type==="time"?new Date(f[_this.config.x.column])<=new Date(r[0][_this.config.x.column]):+f[_this.config.x.column]<=+r[0][_this.config.x.column]});if(mark.per.length){interm=interm.filter(function(f){return f[mark.per[0]]===r[0][mark.per[0]]})}var cumul=_this.config.x.type==="time"?interm.length:d3.sum(interm.map(function(m){return+m[_this.config.y.column]||+m[_this.config.y.column]===0?+m[_this.config.y.column]:1}));dom_ys.push([cumul]);obj.y=cumul}if(mark.summarizeX==="cumulative"){var _interm=entries.filter(function(f){return _this.config.y.type==="time"?new Date(f[_this.config.y.column])<=new Date(r[0][_this.config.y.column]):+f[_this.config.y.column]<=+r[0][_this.config.y.column]});if(mark.per.length){_interm=_interm.filter(function(f){return f[mark.per[0]]===r[0][mark.per[0]]})}dom_xs.push([_interm.length]);obj.x=_interm.length}return obj});var test=this_nest.entries(entries);var dom_x=d3.extent(d3.merge(dom_xs));var dom_y=d3.extent(d3.merge(dom_ys));if(sublevel&&mark.type==="bar"&&mark.split){test.forEach(function(e){var axis=_this.config.x.type==="ordinal"||_this.config.x.type==="linear"&&_this.config.x.bin?"y":"x";e.total=d3.sum(e.values.map(function(m){return+m.values[axis]}));var counter=0;e.values.forEach(function(v,i){if(_this.config.x.type==="ordinal"||_this.config.x.type==="linear"&&_this.config.x.bin){v.values.y=mark.summarizeY==="percent"?v.values.y/e.total:v.values.y||0;counter+=+v.values.y;v.values.start=e.values[i-1]?counter:v.values.y}else{v.values.x=mark.summarizeX==="percent"?v.values.x/e.total:v.values.x||0;v.values.start=counter;counter+=+v.values.x}})});if(mark.arrange==="stacked"){if(this.config.x.type==="ordinal"||this.config.x.type==="linear"&&this.config.x.bin){dom_y=d3.extent(test.map(function(m){return m.total}))}if(this.config.y.type==="ordinal"||this.config.y.type==="linear"&&this.config.y.bin){dom_x=d3.extent(test.map(function(m){return m.total}))}}}else{var axis=this.config.x.type==="ordinal"||this.config.x.type==="linear"&&this.config.x.bin?"y":"x";test.forEach(function(e){return e.total=e.values[axis]})}if(this.config.x.sort==="total-ascending"&&this.config.x.type=="ordinal"||this.config.y.sort==="total-descending"&&this.config.y.type=="ordinal"){totalOrder=test.sort(function(a,b){return d3.ascending(a.total,b.total)}).map(function(m){return m.key})}else if(this.config.x.sort==="total-descending"&&this.config.x.type=="ordinal"||this.config.y.sort==="total-ascending"&&this.config.y.type=="ordinal"){totalOrder=test.sort(function(a,b){return d3.descending(+a.total,+b.total)}).map(function(m){return m.key})}return{nested:test,dom_x:dom_x,dom_y:dom_y,totalOrder:totalOrder}}function transformData(raw,mark){var _this=this;var config=this.config;var x_behavior=config.x.behavior||"raw";var y_behavior=config.y.behavior||"raw";var sublevel=mark.type==="line"?config.x.column:mark.type==="bar"&&mark.split?mark.split:null;var cleaned=cleanData.call(this,mark,raw);var raw_nest=void 0;if(mark.type==="bar"){raw_nest=mark.arrange!=="stacked"?makeNest.call(this,mark,cleaned,sublevel):makeNest.call(this,mark,cleaned)}else if(mark.summarizeX==="count"||mark.summarizeY==="count"){raw_nest=makeNest.call(this,mark,cleaned)}var raw_dom_x=mark.summarizeX==="cumulative"?[0,cleaned.length]:config.x.type==="ordinal"?d3.set(cleaned.map(function(m){return m[config.x.column]})).values().filter(function(f){return f}):mark.split&&mark.arrange!=="stacked"?d3.extent(d3.merge(raw_nest.nested.map(function(m){return m.values.map(function(p){return p.values.raw.length})}))):mark.summarizeX==="count"?d3.extent(raw_nest.nested.map(function(m){return m.values.raw.length})):d3.extent(cleaned.map(function(m){return+m[config.x.column]}).filter(function(f){return+f||+f===0}));var raw_dom_y=mark.summarizeY==="cumulative"?[0,cleaned.length]:config.y.type==="ordinal"?d3.set(cleaned.map(function(m){return m[config.y.column]})).values().filter(function(f){return f}):mark.split&&mark.arrange!=="stacked"?d3.extent(d3.merge(raw_nest.nested.map(function(m){return m.values.map(function(p){return p.values.raw.length})}))):mark.summarizeY==="count"?d3.extent(raw_nest.nested.map(function(m){return m.values.raw.length})):d3.extent(cleaned.map(function(m){return+m[config.y.column]}).filter(function(f){return+f||+f===0}));var filtered=cleaned;var filt1_xs=[];var filt1_ys=[];if(this.filters.length){this.filters.forEach(function(e){filtered=filtered.filter(function(d){return e.all===true&&e.index===0?d:e.val instanceof Array?e.val.indexOf(d[e.col])>-1:d[e.col]===e.val})});if(config.x.behavior==="firstfilter"||config.y.behavior==="firstfilter"){this.filters[0].choices.filter(function(f){return f!=="All"}).forEach(function(e){var perfilter=cleaned.filter(function(f){return f[_this.filters[0].col]===e});var filt_nested=makeNest.call(_this,mark,perfilter,sublevel);filt1_xs.push(filt_nested.dom_x);filt1_ys.push(filt_nested.dom_y)})}}if(mark.values){var _loop=function _loop(a){filtered=filtered.filter(function(f){return mark.values[a].indexOf(f[a])>-1})};for(var a in mark.values){_loop(a)}}var filt1_dom_x=d3.extent(d3.merge(filt1_xs));var filt1_dom_y=d3.extent(d3.merge(filt1_ys));var current_nested=makeNest.call(this,mark,filtered,sublevel);var flex_dom_x=current_nested.dom_x;var flex_dom_y=current_nested.dom_y;if(mark.type==="bar"){if(config.y.type==="ordinal"&&mark.summarizeX==="count"){config.x.domain=config.x.domain?[0,config.x.domain[1]]:[0,null]}else if(config.x.type==="ordinal"&&mark.summarizeY==="count"){config.y.domain=config.y.domain?[0,config.y.domain[1]]:[0,null]}}var nonall=Boolean(this.filters.length&&this.filters[0].val!=="All"&&this.filters.slice(1).filter(function(f){return f.val==="All"}).length===this.filters.length-1);var pre_x_dom=!this.filters.length?flex_dom_x:x_behavior==="raw"?raw_dom_x:nonall&&x_behavior==="firstfilter"?filt1_dom_x:flex_dom_x;var pre_y_dom=!this.filters.length?flex_dom_y:y_behavior==="raw"?raw_dom_y:nonall&&y_behavior==="firstfilter"?filt1_dom_y:flex_dom_y;var x_dom=config.x_dom?config.x_dom:config.x.type==="ordinal"&&config.x.behavior==="flex"?d3.set(filtered.map(function(m){return m[config.x.column]})).values():config.x.type==="ordinal"?d3.set(cleaned.map(function(m){return m[config.x.column]})).values():pre_x_dom;var y_dom=config.y_dom?config.y_dom:config.y.type==="ordinal"&&config.y.behavior==="flex"?d3.set(filtered.map(function(m){return m[config.y.column]})).values():config.y.type==="ordinal"?d3.set(cleaned.map(function(m){return m[config.y.column]})).values():pre_y_dom;if(mark.type==="bar"){if(config.x.behavior!=="flex"&&config.x.type==="linear"&&config.y.type==="ordinal"&&raw_dom_x[0]>=0)x_dom[0]=0;if(config.y.behavior!=="flex"&&config.x.type==="ordinal"&&config.y.type==="linear"&&raw_dom_y[0]>=0)y_dom[0]=0}if(config.x.domain&&(config.x.domain[0]||config.x.domain[0]===0)&&!isNaN(+config.x.domain[0])){x_dom[0]=config.x.domain[0]}if(config.x.domain&&(config.x.domain[1]||config.x.domain[1]===0)&&!isNaN(+config.x.domain[1])){x_dom[1]=config.x.domain[1]}if(config.y.domain&&(config.y.domain[0]||config.y.domain[0]===0)&&!isNaN(+config.y.domain[0])){y_dom[0]=config.y.domain[0]}if(config.y.domain&&(config.y.domain[1]||config.y.domain[1]===0)&&!isNaN(+config.y.domain[1])){y_dom[1]=config.y.domain[1]}if(config.x.type==="ordinal"&&!config.x.order){config.x.order=current_nested.totalOrder}if(config.y.type==="ordinal"&&!config.y.order){config.y.order=current_nested.totalOrder}this.current_data=current_nested.nested;this.events.onDatatransform.call(this);return{config:mark,data:current_nested.nested,x_dom:x_dom,y_dom:y_dom}}function setColorScale(){var config=this.config;var data=config.legend.behavior==="flex"?this.filtered_data:this.raw_data;var colordom=Array.isArray(config.color_dom)&&config.color_dom.length?config.color_dom.slice():d3.set(data.map(function(m){return m[config.color_by]})).values().filter(function(f){return f&&f!=="undefined"});if(config.legend.order)colordom.sort(function(a,b){return d3.ascending(config.legend.order.indexOf(a),config.legend.order.indexOf(b))});else colordom.sort(naturalSorter);this.colorScale=d3.scale.ordinal().domain(colordom).range(config.colors)}function xScaleAxis(max_range,domain,type){if(max_range===undefined){max_range=this.plot_width}if(domain===undefined){domain=this.x_dom}if(type===undefined){type=this.config.x.type}var config=this.config;var x=void 0;if(type==="log"){x=d3.scale.log()}else if(type==="ordinal"){x=d3.scale.ordinal()}else if(type==="time"){x=d3.time.scale()}else{x=d3.scale.linear()}x.domain(domain);if(type==="ordinal"){x.rangeBands([0,+max_range],config.padding,config.outer_pad)}else{x.range([0,+max_range]).clamp(Boolean(config.x.clamp))}var xFormat=config.x.format?config.x.format:config.marks.map(function(m){return m.summarizeX==="percent"}).indexOf(true)>-1?"0%":type==="time"?"%x":".0f";var tick_count=Math.max(2,Math.min(max_range/80,8));var xAxis=d3.svg.axis().scale(x).orient(config.x.location).ticks(tick_count).tickFormat(type==="ordinal"?null:type==="time"?d3.time.format(xFormat):d3.format(xFormat)).tickValues(config.x.ticks?config.x.ticks:null).innerTickSize(6).outerTickSize(3);this.svg.select("g.x.axis").attr("class","x axis "+type);this.x=x;this.xAxis=xAxis}function yScaleAxis(max_range,domain,type){if(max_range===undefined){max_range=this.plot_height}if(domain===undefined){domain=this.y_dom}if(type===undefined){type=this.config.y.type}var config=this.config;var y=void 0;if(type==="log"){y=d3.scale.log()}else if(type==="ordinal"){y=d3.scale.ordinal()}else if(type==="time"){y=d3.time.scale()}else{y=d3.scale.linear()}y.domain(domain);if(type==="ordinal"){y.rangeBands([+max_range,0],config.padding,config.outer_pad)}else{y.range([+max_range,0]).clamp(Boolean(config.y_clamp))}var yFormat=config.y.format?config.y.format:config.marks.map(function(m){return m.summarizeY==="percent"}).indexOf(true)>-1?"0%":".0f";var tick_count=Math.max(2,Math.min(max_range/80,8));var yAxis=d3.svg.axis().scale(y).orient("left").ticks(tick_count).tickFormat(type==="ordinal"?null:type==="time"?d3.time.format(yFormat):d3.format(yFormat)).tickValues(config.y.ticks?config.y.ticks:null).innerTickSize(6).outerTickSize(3);this.svg.select("g.y.axis").attr("class","y axis "+type);this.y=y;this.yAxis=yAxis}function resize(){var config=this.config;var aspect2=1/config.aspect;var div_width=parseInt(this.wrap.style("width"));var max_width=config.max_width?config.max_width:div_width;var preWidth=!config.resizable?config.width:!max_width||div_width=600){font_size="14px";point_size=4;stroke_width=2}else if(width>450&&width<600){font_size="12px";point_size=3;stroke_width=2}else if(width>300&&width<450){font_size="10px";point_size=2;stroke_width=2}else if(width<=300){font_size="10px";point_size=2;stroke_width=1}this.wrap.style("font-size",font_size);this.config.flex_point_size=point_size;this.config.flex_stroke_width=stroke_width}function setMargins(){var _this=this;var y_ticks=this.yAxis.tickFormat()?this.y.domain().map(function(m){return _this.yAxis.tickFormat()(m)}):this.y.domain();var max_y_text_length=d3.max(y_ticks.map(function(m){return String(m).length}));if(this.config.y_format&&this.config.y_format.indexOf("%")>-1){max_y_text_length+=1}max_y_text_length=Math.max(2,max_y_text_length);var x_label_on=this.config.x.label?1.5:0;var y_label_on=this.config.y.label?1.5:.25;var font_size=parseInt(this.wrap.style("font-size"));var x_second=this.config.x2_interval?1:0;var y_margin=max_y_text_length*font_size*.5+font_size*y_label_on*1.5||8;var x_margin=font_size+font_size/1.5+font_size*x_label_on+font_size*x_second||8;y_margin+=6;x_margin+=3;return{top:this.config.margin&&this.config.margin.top?this.config.margin.top:8,right:this.config.margin&&this.config.margin.right?this.config.margin.right:16,bottom:this.config.margin&&this.config.margin.bottom?this.config.margin.bottom:x_margin,left:this.config.margin&&this.config.margin.left?this.config.margin.left:y_margin}}function drawGridLines(){this.wrap.classed("gridlines",this.config.gridlines);if(this.config.gridlines){this.svg.select(".y.axis").selectAll(".tick line").attr("x1",0);this.svg.select(".x.axis").selectAll(".tick line").attr("y1",0);if(this.config.gridlines==="y"||this.config.gridlines==="xy")this.svg.select(".y.axis").selectAll(".tick line").attr("x1",this.plot_width);if(this.config.gridlines==="x"||this.config.gridlines==="xy")this.svg.select(".x.axis").selectAll(".tick line").attr("y1",-this.plot_height)}else{this.svg.select(".y.axis").selectAll(".tick line").attr("x1",0);this.svg.select(".x.axis").selectAll(".tick line").attr("y1",0)}}function makeLegend(){var scale=arguments.length>0&&arguments[0]!==undefined?arguments[0]:this.colorScale;var label=arguments.length>1&&arguments[1]!==undefined?arguments[1]:"";var custom_data=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;var config=this.config;config.legend.mark=config.legend.mark?config.legend.mark:config.marks.length&&config.marks[0].type==="bar"?"square":config.marks.length?config.marks[0].type:"square";var legend_label=label?label:typeof config.legend.label==="string"?config.legend.label:"";var legendOriginal=this.legend||this.wrap.select(".legend");var legend=legendOriginal;if(!this.parent){if(this.config.legend.location==="top"||this.config.legend.location==="left"){this.wrap.node().insertBefore(legendOriginal.node(),this.svg.node().parentNode)}else{this.wrap.node().appendChild(legendOriginal.node())}}else{if(this.config.legend.location==="top"||this.config.legend.location==="left"){this.parent.wrap.node().insertBefore(legendOriginal.node(),this.parent.wrap.select(".wc-chart").node())}else{this.parent.wrap.node().appendChild(legendOriginal.node())}}legend.style("padding",0);var legend_data=custom_data||scale.domain().slice(0).filter(function(f){return f!==undefined&&f!==null}).map(function(m){return{label:m,mark:config.legend.mark}});legend.select(".legend-title").text(legend_label).style("display",legend_label?"inline":"none").style("margin-right","1em");var leg_parts=legend.selectAll(".legend-item").data(legend_data,function(d){ -return d.label+d.mark});leg_parts.exit().remove();var legendPartDisplay=this.config.legend.location==="bottom"||this.config.legend.location==="top"?"inline-block":"block";var new_parts=leg_parts.enter().append("li").attr("class","legend-item").style({"list-style-type":"none","margin-right":"1em"});new_parts.append("span").attr("class","legend-mark-text").style("color",function(d){return scale(d.label)});new_parts.append("svg").attr("class","legend-color-block").attr("width","1.1em").attr("height","1.1em").style({position:"relative",top:"0.2em"});leg_parts.style("display",legendPartDisplay);if(config.legend.order){leg_parts.sort(function(a,b){return d3.ascending(config.legend.order.indexOf(a.label),config.legend.order.indexOf(b.label))})}leg_parts.selectAll(".legend-color-block").select(".legend-mark").remove();leg_parts.selectAll(".legend-color-block").each(function(e){var svg=d3.select(this);if(e.mark==="circle"){svg.append("circle").attr({cx:".5em",cy:".5em",r:".45em",class:"legend-mark"})}else if(e.mark==="line"){svg.append("line").attr({x1:0,y1:".5em",x2:"1em",y2:".5em","stroke-width":2,"shape-rendering":"crispEdges",class:"legend-mark"})}else if(e.mark==="square"){svg.append("rect").attr({height:"1em",width:"1em",class:"legend-mark","shape-rendering":"crispEdges"})}});leg_parts.selectAll(".legend-color-block").select(".legend-mark").attr("fill",function(d){return d.color||scale(d.label)}).attr("stroke",function(d){return d.color||scale(d.label)}).each(function(e){d3.select(this).attr(e.attributes)});new_parts.append("span").attr("class","legend-label").style("margin-left","0.25em").text(function(d){return d.label});if(scale.domain().length>0){var legendDisplay=(this.config.legend.location==="bottom"||this.config.legend.location==="top")&&!this.parent?"block":"inline-block";legend.style("display",legendDisplay)}else{legend.style("display","none")}this.legend=legend}function updateDataMarks(){this.drawBars(this.marks.filter(function(f){return f.type==="bar"}));this.drawLines(this.marks.filter(function(f){return f.type==="line"}));this.drawPoints(this.marks.filter(function(f){return f.type==="circle"}));this.drawText(this.marks.filter(function(f){return f.type==="text"}));this.marks.supergroups=this.svg.selectAll("g.supergroup")}function drawArea(area_drawer,area_data,datum_accessor){var class_match=arguments.length>3&&arguments[3]!==undefined?arguments[3]:"chart-area";var _this=this;var bind_accessor=arguments[4];var attr_accessor=arguments.length>5&&arguments[5]!==undefined?arguments[5]:function(d){return d};var area_grps=this.svg.selectAll("."+class_match).data(area_data,bind_accessor);area_grps.exit().remove();area_grps.enter().append("g").attr("class",function(d){return class_match+" "+d.key}).append("path");var areaPaths=area_grps.select("path").datum(datum_accessor).attr("fill",function(d){var d_attr=attr_accessor(d);return d_attr?_this.colorScale(d_attr[_this.config.color_by]):null}).attr("fill-opacity",this.config.fill_opacity||this.config.fill_opacity===0?this.config.fill_opacity:.3);var areaPathTransitions=this.config.transitions?areaPaths.transition():areaPaths;areaPathTransitions.attr("d",area_drawer);return area_grps}function drawBars(marks){var _this=this;var chart=this;var rawData=this.raw_data;var config=this.config;var bar_supergroups=this.svg.selectAll(".bar-supergroup").data(marks,function(d,i){return i+"-"+d.per.join("-")});bar_supergroups.enter().append("g").attr("class",function(d){return"supergroup bar-supergroup "+d.id});bar_supergroups.exit().remove();var bar_groups=bar_supergroups.selectAll(".bar-group").data(function(d){return d.data},function(d){return d.key});var old_bar_groups=bar_groups.exit();var nu_bar_groups=void 0;var bars=void 0;var oldBarsTrans=config.transitions?old_bar_groups.selectAll(".bar").transition():old_bar_groups.selectAll(".bar");var oldBarGroupsTrans=config.transitions?old_bar_groups.transition():old_bar_groups;if(config.x.type==="ordinal"){oldBarsTrans.attr("y",this.y(0)).attr("height",0);oldBarGroupsTrans.remove();nu_bar_groups=bar_groups.enter().append("g").attr("class",function(d){return"bar-group "+d.key});nu_bar_groups.append("title");bars=bar_groups.selectAll("rect").data(function(d){return d.values instanceof Array?d.values.sort(function(a,b){return _this.colorScale.domain().indexOf(b.key)-_this.colorScale.domain().indexOf(a.key)}):[d]},function(d){return d.key});var exitBars=config.transitions?bars.exit().transition():bars.exit();exitBars.attr("y",this.y(0)).attr("height",0).remove();bars.enter().append("rect").attr("class",function(d){return"wc-data-mark bar "+d.key}).style("clip-path","url(#"+chart.id+")").attr("y",this.y(0)).attr("height",0).append("title");bars.attr("shape-rendering","crispEdges").attr("stroke",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])});bars.each(function(d){var mark=d3.select(this.parentNode.parentNode).datum();d.tooltip=mark.tooltip;d.arrange=mark.split&&mark.arrange?mark.arrange:mark.split?"grouped":null;d.subcats=config.legend.order?config.legend.order.slice().reverse():mark.values&&mark.values[mark.split]?mark.values[mark.split]:d3.set(rawData.map(function(m){return m[mark.split]})).values();d3.select(this).attr(mark.attributes)});var xformat=config.marks.map(function(m){return m.summarizeX==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.x.format);var yformat=config.marks.map(function(m){return m.summarizeY==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.y.format);bars.select("title").text(function(d){var tt=d.tooltip||"";return tt.replace(/\$x/g,xformat(d.values.x)).replace(/\$y/g,yformat(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});var barsTrans=config.transitions?bars.transition():bars;barsTrans.attr("x",function(d){var position=void 0;if(!d.arrange||d.arrange==="stacked"){return _this.x(d.values.x)}else if(d.arrange==="nested"){var _position=d.subcats.indexOf(d.key);var offset=_position?_this.x.rangeBand()/(d.subcats.length*.75)/_position:_this.x.rangeBand();return _this.x(d.values.x)+(_this.x.rangeBand()-offset)/2}else{position=d.subcats.indexOf(d.key);return _this.x(d.values.x)+_this.x.rangeBand()/d.subcats.length*position}}).attr("y",function(d){if(d.arrange!=="stacked"){return _this.y(d.values.y)}else{return _this.y(d.values.start)}}).attr("width",function(d){if(!d.arrange||d.arrange==="stacked"){return _this.x.rangeBand()}else if(d.arrange==="nested"){var position=d.subcats.indexOf(d.key);return position?_this.x.rangeBand()/(d.subcats.length*.75)/position:_this.x.rangeBand()}else{return _this.x.rangeBand()/d.subcats.length}}).attr("height",function(d){return _this.y(0)-_this.y(d.values.y)})}else if(config.y.type==="ordinal"){oldBarsTrans.attr("x",this.x(0)).attr("width",0);oldBarGroupsTrans.remove();nu_bar_groups=bar_groups.enter().append("g").attr("class",function(d){return"bar-group "+d.key});nu_bar_groups.append("title");bars=bar_groups.selectAll("rect").data(function(d){return d.values instanceof Array?d.values.sort(function(a,b){return _this.colorScale.domain().indexOf(b.key)-_this.colorScale.domain().indexOf(a.key)}):[d]},function(d){return d.key});var _exitBars=config.transitions?bars.exit().transition():bars.exit();_exitBars.attr("x",this.x(0)).attr("width",0).remove();bars.enter().append("rect").attr("class",function(d){return"wc-data-mark bar "+d.key}).style("clip-path","url(#"+chart.id+")").attr("x",this.x(0)).attr("width",0).append("title");bars.attr("shape-rendering","crispEdges").attr("stroke",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])});bars.each(function(d){var mark=d3.select(this.parentNode.parentNode).datum();d.arrange=mark.split&&mark.arrange?mark.arrange:mark.split?"grouped":null;d.subcats=config.legend.order?config.legend.order.slice().reverse():mark.values&&mark.values[mark.split]?mark.values[mark.split]:d3.set(rawData.map(function(m){return m[mark.split]})).values();d.tooltip=mark.tooltip;d3.select(this).attr(mark.attributes)});var _xformat=config.marks.map(function(m){return m.summarizeX==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.x.format);var _yformat=config.marks.map(function(m){return m.summarizeY==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.y.format);bars.select("title").text(function(d){var tt=d.tooltip||"";return tt.replace(/\$x/g,_xformat(d.values.x)).replace(/\$y/g,_yformat(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});var _barsTrans=config.transitions?bars.transition():bars;_barsTrans.attr("x",function(d){if(d.arrange==="stacked"||!d.arrange){return d.values.start!==undefined?_this.x(d.values.start):_this.x(0)}else{return _this.x(0)}}).attr("y",function(d){if(d.arrange==="nested"){var position=d.subcats.indexOf(d.key);var offset=position?_this.y.rangeBand()/(d.subcats.length*.75)/position:_this.y.rangeBand();return _this.y(d.values.y)+(_this.y.rangeBand()-offset)/2}else if(d.arrange==="grouped"){var _position2=d.subcats.indexOf(d.key);return _this.y(d.values.y)+_this.y.rangeBand()/d.subcats.length*_position2}else{return _this.y(d.values.y)}}).attr("width",function(d){return _this.x(d.values.x)-_this.x(0)}).attr("height",function(d){if(config.y.type==="quantile"){return 20}else if(d.arrange==="nested"){var position=d.subcats.indexOf(d.key);return position?_this.y.rangeBand()/(d.subcats.length*.75)/position:_this.y.rangeBand()}else if(d.arrange==="grouped"){return _this.y.rangeBand()/d.subcats.length}else{return _this.y.rangeBand()}})}else if(["linear","log"].indexOf(config.x.type)>-1&&config.x.bin){oldBarsTrans.attr("y",this.y(0)).attr("height",0);oldBarGroupsTrans.remove();nu_bar_groups=bar_groups.enter().append("g").attr("class",function(d){return"bar-group "+d.key});nu_bar_groups.append("title");bars=bar_groups.selectAll("rect").data(function(d){return d.values instanceof Array?d.values:[d]},function(d){return d.key});var _exitBars2=config.transitions?bars.exit().transition():bars.exit();_exitBars2.attr("y",this.y(0)).attr("height",0).remove();bars.enter().append("rect").attr("class",function(d){return"wc-data-mark bar "+d.key}).style("clip-path","url(#"+chart.id+")").attr("y",this.y(0)).attr("height",0).append("title");bars.attr("shape-rendering","crispEdges").attr("stroke",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])});bars.each(function(d){var mark=d3.select(this.parentNode.parentNode).datum();d.arrange=mark.split?mark.arrange:null;d.subcats=config.legend.order?config.legend.order.slice().reverse():mark.values&&mark.values[mark.split]?mark.values[mark.split]:d3.set(rawData.map(function(m){return m[mark.split]})).values();d3.select(this).attr(mark.attributes);var parent=d3.select(this.parentNode).datum();var rangeSet=parent.key.split(",").map(function(m){return+m});d.rangeLow=d3.min(rangeSet);d.rangeHigh=d3.max(rangeSet);d.tooltip=mark.tooltip});var _xformat2=config.marks.map(function(m){return m.summarizeX==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.x.format);var _yformat2=config.marks.map(function(m){return m.summarizeY==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.y.format);bars.select("title").text(function(d){var tt=d.tooltip||"";return tt.replace(/\$x/g,_xformat2(d.values.x)).replace(/\$y/g,_yformat2(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});var _barsTrans2=config.transitions?bars.transition():bars;_barsTrans2.attr("x",function(d){return _this.x(d.rangeLow)}).attr("y",function(d){if(d.arrange!=="stacked"){return _this.y(d.values.y)}else{return _this.y(d.values.start)}}).attr("width",function(d){return _this.x(d.rangeHigh)-_this.x(d.rangeLow)}).attr("height",function(d){return _this.y(0)-_this.y(d.values.y)})}else if(["linear","log"].indexOf(config.y.type)>-1&&config.y.type==="linear"&&config.y.bin){oldBarsTrans.attr("x",this.x(0)).attr("width",0);oldBarGroupsTrans.remove();nu_bar_groups=bar_groups.enter().append("g").attr("class",function(d){return"bar-group "+d.key});nu_bar_groups.append("title");bars=bar_groups.selectAll("rect").data(function(d){return d.values instanceof Array?d.values:[d]},function(d){return d.key});var _exitBars3=config.transitions?bars.exit().transition():bars.exit();_exitBars3.attr("x",this.x(0)).attr("width",0).remove();bars.enter().append("rect").attr("class",function(d){return"wc-data-mark bar "+d.key}).style("clip-path","url(#"+chart.id+")").attr("x",this.x(0)).attr("width",0).append("title");bars.attr("shape-rendering","crispEdges").attr("stroke",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])});bars.each(function(d){var mark=d3.select(this.parentNode.parentNode).datum();d.arrange=mark.split?mark.arrange:null;d.subcats=config.legend.order?config.legend.order.slice().reverse():mark.values&&mark.values[mark.split]?mark.values[mark.split]:d3.set(rawData.map(function(m){return m[mark.split]})).values();var parent=d3.select(this.parentNode).datum();var rangeSet=parent.key.split(",").map(function(m){return+m});d.rangeLow=d3.min(rangeSet);d.rangeHigh=d3.max(rangeSet);d.tooltip=mark.tooltip});var _xformat3=config.marks.map(function(m){return m.summarizeX==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.x.format);var _yformat3=config.marks.map(function(m){return m.summarizeY==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.y.format);bars.select("title").text(function(d){var tt=d.tooltip||"";return tt.replace(/\$x/g,_xformat3(d.values.x)).replace(/\$y/g,_yformat3(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});var _barsTrans3=config.transitions?bars.transition():bars;_barsTrans3.attr("x",function(d){if(d.arrange==="stacked"){return _this.x(d.values.start)}else{return _this.x(0)}}).attr("y",function(d){return _this.y(d.rangeHigh)}).attr("width",function(d){return _this.x(d.values.x)}).attr("height",function(d){return _this.y(d.rangeLow)-_this.y(d.rangeHigh)})}else{oldBarsTrans.attr("y",this.y(0)).attr("height",0);oldBarGroupsTrans.remove();bar_supergroups.remove()}bar_supergroups.each(function(d){d.supergroup=d3.select(this);d.groups=d.supergroup.selectAll(".bar-group")})}function drawLines(marks){var _this=this;var chart=this;var config=this.config;var line=d3.svg.line().interpolate(config.interpolate).x(function(d){return config.x.type==="linear"||config.x.type=="log"?_this.x(+d.values.x):config.x.type==="time"?_this.x(new Date(d.values.x)):_this.x(d.values.x)+_this.x.rangeBand()/2}).y(function(d){return config.y.type==="linear"||config.y.type=="log"?_this.y(+d.values.y):config.y.type==="time"?_this.y(new Date(d.values.y)):_this.y(d.values.y)+_this.y.rangeBand()/2});var line_supergroups=this.svg.selectAll(".line-supergroup").data(marks,function(d,i){return i+"-"+d.per.join("-")});line_supergroups.enter().append("g").attr("class",function(d){return"supergroup line-supergroup "+d.id});line_supergroups.exit().remove();var line_grps=line_supergroups.selectAll(".line").data(function(d){return d.data},function(d){return d.key});line_grps.exit().remove();var nu_line_grps=line_grps.enter().append("g").attr("class",function(d){return d.key+" line"});nu_line_grps.append("path");nu_line_grps.append("title");var linePaths=line_grps.select("path").attr("class","wc-data-mark").style("clip-path","url(#"+chart.id+")").datum(function(d){return d.values}).attr("stroke",function(d){return _this.colorScale(d[0].values.raw[0][config.color_by])}).attr("stroke-width",config.stroke_width?config.stroke_width:config.flex_stroke_width).attr("stroke-linecap","round").attr("fill","none");var linePathsTrans=config.transitions?linePaths.transition():linePaths;linePathsTrans.attr("d",line);line_grps.each(function(d){var mark=d3.select(this.parentNode).datum();d.tooltip=mark.tooltip;d3.select(this).select("path").attr(mark.attributes)});line_grps.select("title").text(function(d){var tt=d.tooltip||"";var xformat=config.x.summary==="percent"?d3.format("0%"):d3.format(config.x.format);var yformat=config.y.summary==="percent"?d3.format("0%"):d3.format(config.y.format);return tt.replace(/\$x/g,xformat(d.values.x)).replace(/\$y/g,yformat(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values[0].values.raw[0][orig]})});line_supergroups.each(function(d){d.supergroup=d3.select(this);d.groups=d.supergroup.selectAll("g.line");d.paths=d.groups.select("path")});return line_grps}function drawPoints(marks){var _this=this;var chart=this;var config=this.config;var point_supergroups=this.svg.selectAll(".point-supergroup").data(marks,function(d,i){return i+"-"+d.per.join("-")});point_supergroups.enter().append("g").attr("class",function(d){return"supergroup point-supergroup "+d.id});point_supergroups.exit().remove();var points=point_supergroups.selectAll(".point").data(function(d){return d.data},function(d){return d.key});var oldPoints=points.exit();var oldPointsTrans=config.transitions?oldPoints.selectAll("circle").transition():oldPoints.selectAll("circle");oldPointsTrans.attr("r",0);var oldPointGroupTrans=config.transitions?oldPoints.transition():oldPoints;oldPointGroupTrans.remove();var nupoints=points.enter().append("g").attr("class",function(d){return d.key+" point"});nupoints.append("circle").attr("class","wc-data-mark").attr("r",0);nupoints.append("title");points.select("circle").style("clip-path","url(#"+chart.id+")").attr("fill-opacity",config.fill_opacity||config.fill_opacity===0?config.fill_opacity:.6).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).attr("stroke",function(d){return _this.colorScale(d.values.raw[0][config.color_by])});points.each(function(d){var mark=d3.select(this.parentNode).datum();d.mark=mark;d3.select(this).select("circle").attr(mark.attributes)});var pointsTrans=config.transitions?points.select("circle").transition():points.select("circle");pointsTrans.attr("r",function(d){return d.mark.radius||config.flex_point_size}).attr("cx",function(d){var x_pos=_this.x(d.values.x)||0;return config.x.type==="ordinal"?x_pos+_this.x.rangeBand()/2:x_pos}).attr("cy",function(d){var y_pos=_this.y(d.values.y)||0;return config.y.type==="ordinal"?y_pos+_this.y.rangeBand()/2:y_pos});points.select("title").text(function(d){var tt=d.mark.tooltip||"";var xformat=config.x.summary==="percent"?d3.format("0%"):config.x.type==="time"?d3.time.format(config.x.format):d3.format(config.x.format);var yformat=config.y.summary==="percent"?d3.format("0%"):config.y.type==="time"?d3.time.format(config.y.format):d3.format(config.y.format);return tt.replace(/\$x/g,config.x.type==="time"?xformat(new Date(d.values.x)):xformat(d.values.x)).replace(/\$y/g,config.y.type==="time"?yformat(new Date(d.values.y)):yformat(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});point_supergroups.each(function(d){d.supergroup=d3.select(this);d.groups=d.supergroup.selectAll("g.point");d.circles=d.groups.select("circle")});return points}function drawText(marks){var _this=this;var chart=this;var config=this.config;var textSupergroups=this.svg.selectAll(".text-supergroup").data(marks,function(d,i){return i+"-"+d.per.join("-")});textSupergroups.enter().append("g").attr("class",function(d){return"supergroup text-supergroup "+d.id});textSupergroups.exit().remove();var texts=textSupergroups.selectAll(".text").data(function(d){return d.data},function(d){return d.key});var oldTexts=texts.exit();var oldTextGroupTrans=config.transitions?oldTexts.transition():oldTexts;oldTextGroupTrans.remove();var nutexts=texts.enter().append("g").attr("class",function(d){return d.key+" text"});nutexts.append("text").attr("class","wc-data-mark");function attachMarks(d){d.mark=d3.select(this.parentNode).datum();d3.select(this).select("text").attr(d.mark.attributes)}texts.each(attachMarks);texts.select("text").style("clip-path","url(#"+chart.id+")").text(function(d){var tt=d.mark.text||"";var xformat=config.x.summary==="percent"?d3.format("0%"):config.x.type==="time"?d3.time.format(config.x.format):d3.format(config.x.format);var yformat=config.y.summary==="percent"?d3.format("0%"):config.y.type==="time"?d3.time.format(config.y.format):d3.format(config.y.format);return tt.replace(/\$x/g,config.x.type==="time"?xformat(new Date(d.values.x)):xformat(d.values.x)).replace(/\$y/g,config.y.type==="time"?yformat(new Date(d.values.y)):yformat(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});var textsTrans=config.transitions?texts.select("text").transition():texts.select("text");textsTrans.attr("x",function(d){var xPos=_this.x(d.values.x)||0;return config.x.type==="ordinal"?xPos+_this.x.rangeBand()/2:xPos}).attr("y",function(d){var yPos=_this.y(d.values.y)||0;return config.y.type==="ordinal"?yPos+_this.y.rangeBand()/2:yPos});textSupergroups.each(function(d){d.supergroup=d3.select(this);d.groups=d.supergroup.selectAll("g.text");d.texts=d.groups.select("text")});return texts}function destroy(){var destroyControls=arguments.length>0&&arguments[0]!==undefined?arguments[0]:true;this.events.onDestroy.call(this);var context=this;d3.select(window).on("resize."+context.element+context.id,null);if(destroyControls&&this.controls){this.controls.destroy()}this.wrap.remove()}var chartProto={raw_data:[],config:{}};var chart=Object.create(chartProto,{checkRequired:{value:checkRequired},consolidateData:{value:consolidateData},draw:{value:draw},destroy:{value:destroy},drawArea:{value:drawArea},drawBars:{value:drawBars},drawGridlines:{value:drawGridLines},drawLines:{value:drawLines},drawPoints:{value:drawPoints},drawText:{value:drawText},init:{value:init},layout:{value:layout},makeLegend:{value:makeLegend},resize:{value:resize},setColorScale:{value:setColorScale},setDefaults:{value:setDefaults},setMargins:{value:setMargins},textSize:{value:textSize},transformData:{value:transformData},updateDataMarks:{value:updateDataMarks},xScaleAxis:{value:xScaleAxis},yScaleAxis:{value:yScaleAxis}});var chartCount=0;function createChart(){var element=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"body";var config=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var controls=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;var thisChart=Object.create(chart);thisChart.div=element;thisChart.config=Object.create(config);thisChart.controls=controls;thisChart.raw_data=[];thisChart.filters=[];thisChart.marks=[];thisChart.wrap=d3.select(thisChart.div).append("div").datum(thisChart);thisChart.events={onInit:function onInit(){},onLayout:function onLayout(){},onPreprocess:function onPreprocess(){},onDatatransform:function onDatatransform(){},onDraw:function onDraw(){},onResize:function onResize(){},onDestroy:function onDestroy(){}};thisChart.on=function(event,callback){var possible_events=["init","layout","preprocess","datatransform","draw","resize","destroy"];if(possible_events.indexOf(event)<0){return}if(callback){thisChart.events["on"+event.charAt(0).toUpperCase()+event.slice(1)]=callback}};chartCount++;thisChart.id=chartCount;return thisChart}function changeOption(option,value,callback,draw){var _this=this;this.targets.forEach(function(target){if(option instanceof Array){option.forEach(function(o){return _this.stringAccessor(target.config,o,value)})}else{_this.stringAccessor(target.config,option,value)}if(callback){callback()}if(draw)target.draw()})}function checkRequired$1(dataset){if(!dataset[0]||!this.config.inputs)return;var colNames=d3.keys(dataset[0]);this.config.inputs.forEach(function(input,i){if(input.type==="subsetter"&&colNames.indexOf(input.value_col)===-1)throw new Error('Error in settings object: the value "'+input.value_col+'" does not match any column in the provided dataset.');input.draw=input.draw===undefined?true:input.draw})}function controlUpdate(){var _this=this;if(this.config.inputs&&this.config.inputs.length&&this.config.inputs[0])this.config.inputs.forEach(function(input){return _this.makeControlItem(input)})}function destroy$1(){this.wrap.remove()}function init$1(data){this.data=data;if(!this.config.builder)this.checkRequired(this.data);this.layout()}function layout$1(){this.wrap.selectAll("*").remove();this.ready=true;this.controlUpdate()}function makeControlItem(control){var control_wrap=this.wrap.append("div").attr("class","control-group").classed("inline",control.inline).datum(control);var ctrl_label=control_wrap.append("span").attr("class","wc-control-label").text(control.label);if(control.required)ctrl_label.append("span").attr("class","label label-required").text("Required");control_wrap.append("span").attr("class","span-description").text(control.description);if(control.type==="text"){this.makeTextControl(control,control_wrap)}else if(control.type==="number"){this.makeNumberControl(control,control_wrap)}else if(control.type==="list"){this.makeListControl(control,control_wrap)}else if(control.type==="dropdown"){this.makeDropdownControl(control,control_wrap)}else if(control.type==="btngroup"){this.makeBtnGroupControl(control,control_wrap)}else if(control.type==="checkbox"){this.makeCheckboxControl(control,control_wrap)}else if(control.type==="radio"){this.makeRadioControl(control,control_wrap)}else if(control.type==="subsetter"){this.makeSubsetterControl(control,control_wrap)}else{throw new Error('Each control must have a type! Choose from: "text", "number", "list", "dropdown", "btngroup", "checkbox", "radio", or "subsetter".')}}function makeBtnGroupControl(control,control_wrap){var _this=this;var option_data=control.values?control.values:d3.keys(this.data[0]);var btn_wrap=control_wrap.append("div").attr("class","btn-group");var changers=btn_wrap.selectAll("button").data(option_data).enter().append("button").attr("class","btn btn-default btn-sm").text(function(d){return d}).classed("btn-primary",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)===d});changers.on("click",function(d){changers.each(function(e){d3.select(this).classed("btn-primary",e===d)});_this.changeOption(control.option,d,control.callback,control.draw)})}function makeCheckboxControl(control,control_wrap){var _this=this;var changer=control_wrap.append("input").attr("type","checkbox").attr("class","changer").datum(control).property("checked",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)});changer.on("change",function(d){var value=changer.property("checked");_this.changeOption(d.option,value,control.callback,control.draw)})}function makeDropdownControl(control,control_wrap){var _this=this;var mainOption=control.option||control.options[0];var changer=control_wrap.append("select").attr("class","changer").attr("multiple",control.multiple?true:null).datum(control);var opt_values=control.values&&control.values instanceof Array?control.values:control.values?d3.set(this.data.map(function(m){return m[_this.targets[0].config[control.values]]})).values():d3.keys(this.data[0]);if(!control.require||control.none){opt_values.unshift("None")}var options=changer.selectAll("option").data(opt_values).enter().append("option").text(function(d){return d}).property("selected",function(d){return _this.stringAccessor(_this.targets[0].config,mainOption)===d});changer.on("change",function(d){var value=changer.property("value")==="None"?null:changer.property("value");if(control.multiple){value=options.filter(function(f){return d3.select(this).property("selected")})[0].map(function(m){return d3.select(m).property("value")}).filter(function(f){return f!=="None"})}if(control.options){_this.changeOption(control.options,value,control.callback,control.draw)}else{_this.changeOption(control.option,value,control.callback,control.draw)}});return changer}function makeListControl(control,control_wrap){var _this=this;var changer=control_wrap.append("input").attr("type","text").attr("class","changer").datum(control).property("value",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)});changer.on("change",function(d){var value=changer.property("value")?changer.property("value").split(",").map(function(m){return m.trim()}):null;_this.changeOption(control.option,value,control.callback,control.draw)})}function makeNumberControl(control,control_wrap){var _this=this;var changer=control_wrap.append("input").attr("type","number").attr("min",control.min!==undefined?control.min:0).attr("max",control.max).attr("step",control.step||1).attr("class","changer").datum(control).property("value",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)});changer.on("change",function(d){var value=+changer.property("value");_this.changeOption(control.option,value,control.callback,control.draw)})}function makeRadioControl(control,control_wrap){var _this=this;var changers=control_wrap.selectAll("label").data(control.values||d3.keys(this.data[0])).enter().append("label").attr("class","radio").text(function(d,i){return control.relabels?control.relabels[i]:d}).append("input").attr("type","radio").attr("class","changer").attr("name",control.option.replace(".","-")+"-"+this.targets[0].id).property("value",function(d){return d}).property("checked",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)===d});changers.on("change",function(d){var value=null;changers.each(function(c){if(d3.select(this).property("checked")){value=d3.select(this).property("value")==="none"?null:c}});_this.changeOption(control.option,value,control.callback,control.draw)})}function makeSubsetterControl(control,control_wrap){var targets=this.targets;var changer=control_wrap.append("select").classed("changer",true).attr("multiple",control.multiple?true:null).datum(control);var option_data=control.values?control.values:d3.set(this.data.map(function(m){return m[control.value_col]}).filter(function(f){return f})).values().sort(naturalSorter);control.start=control.start?control.start:control.loose?option_data[0]:null;if(!control.multiple&&!control.start){option_data.unshift("All");control.all=true}else{control.all=false}control.loose=!control.loose&&control.start?true:control.loose;var options=changer.selectAll("option").data(option_data).enter().append("option").text(function(d){return d}).property("selected",function(d){return d===control.start});targets.forEach(function(e){var match=e.filters.slice().map(function(m){return m.col===control.value_col}).indexOf(true);if(match>-1){e.filters[match]={col:control.value_col,val:control.start?control.start:!control.multiple?"All":option_data,index:0,choices:option_data,loose:control.loose,all:control.all}}else{e.filters.push({col:control.value_col,val:control.start?control.start:!control.multiple?"All":option_data,index:0,choices:option_data,loose:control.loose,all:control.all})}});function setSubsetter(target,obj){var match=-1;target.filters.forEach(function(e,i){if(e.col===obj.col){match=i}});if(match>-1){target.filters[match]=obj}}changer.on("change",function(d){if(control.multiple){var values=options.filter(function(f){return d3.select(this).property("selected")})[0].map(function(m){return d3.select(m).property("text")});var new_filter={col:control.value_col,val:values,index:null,choices:option_data,loose:control.loose,all:control.all};targets.forEach(function(e){setSubsetter(e,new_filter);if(control.callback){control.callback()}if(control.draw)e.draw()})}else{var value=d3.select(this).select("option:checked").property("text");var index=d3.select(this).select("option:checked").property("index");var _new_filter={col:control.value_col,val:value,index:index,choices:option_data,loose:control.loose,all:control.all};targets.forEach(function(e){setSubsetter(e,_new_filter);if(control.callback){control.callback()}e.draw() -})}})}function makeTextControl(control,control_wrap){var _this=this;var changer=control_wrap.append("input").attr("type","text").attr("class","changer").datum(control).property("value",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)});changer.on("change",function(d){var value=changer.property("value");_this.changeOption(control.option,value,control.callback,control.draw)})}function stringAccessor(o,s,v){s=s.replace(/\[(\w+)\]/g,".$1");s=s.replace(/^\./,"");var a=s.split(".");for(var i=0,n=a.length;i0&&arguments[0]!==undefined?arguments[0]:"body";var config=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var thisControls=Object.create(controls);thisControls.div=element;thisControls.config=Object.create(config);thisControls.config.inputs=thisControls.config.inputs||[];thisControls.targets=[];if(config.location==="bottom"){thisControls.wrap=d3.select(element).append("div").attr("class","wc-controls")}else{thisControls.wrap=d3.select(element).insert("div",":first-child").attr("class","wc-controls")}thisControls.wrap.datum(thisControls);return thisControls}function applyFilters(){var _this=this;if(this.filters&&this.filters.some(function(filter){return typeof filter.val==="string"&&!(filter.all===true&&filter.index===0)||Array.isArray(filter.val)&&filter.val.length-1:filter.val===d[filter.col]})})}else this.data.filtered=this.data.raw}function updateDataObject(){this.data.raw=this.data.passed;this.data.filtered=this.data.passed;this.config.activePage=0;this.config.startIndex=this.config.activePage*this.config.nRowsPerPage;this.config.endIndex=this.config.startIndex+this.config.nRowsPerPage}function applySearchTerm(data){var _this=this;if(this.searchable.searchTerm){this.data.searched=this.data.filtered.filter(function(d){var match=false;Object.keys(d).filter(function(key){return _this.config.cols.indexOf(key)>-1}).forEach(function(var_name){if(match===false){var cellText=""+d[var_name];match=cellText.toLowerCase().indexOf(_this.searchable.searchTerm)>-1}});return match});this.data.processing=this.data.searched}else{delete this.data.searched;this.data.processing=this.data.filtered}}if(Array.prototype.equals)console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code.");Array.prototype.equals=function(array){if(!array)return false;if(this.length!=array.length)return false;for(var i=0,l=this.length;i=Math.max(widths.top,widths.bottom)&&this.config.layout==="vertical"){this.config.layout="horizontal";this.wrap.style("display","table").selectAll(".table-top,.table-bottom").style("display","block").selectAll(".interactivity").style({display:"inline-block",float:function float(){return d3.select(this).classed("searchable-container")||d3.select(this).classed("pagination-container")?"right":null},clear:null})}}function draw$1(passed_data){var _this=this;var table=this;var config=this.config;this.data.passed=passed_data;this.events.onPreprocess.call(this);if(!passed_data)applyFilters.call(this);else updateDataObject.call(this);checkFilters.call(this);applySearchTerm.call(this);this.searchable.wrap.select(".nNrecords").text(this.data.processing.length===this.data.raw.length?this.data.raw.length+" records displayed":this.data.processing.length+"/"+this.data.raw.length+" records displayed");updateTableHeaders.call(this);this.tbody.selectAll("tr").remove();if(this.data.processing.length===0){this.tbody.append("tr").classed("no-data",true).append("td").attr("colspan",this.config.cols.length).text("No data selected.");this.data.current=this.data.processing;this.table.datum(this.table.current);if(this.config.exportable)this.config.exports.forEach(function(fmt){_this.exportable.exports[fmt].call(_this,_this.data.processing)});if(this.config.pagination)this.pagination.addPagination.call(this,this.data.processing)}else{if(this.config.sortable){this.thead.selectAll("th").on("click",function(header){table.sortable.onClick.call(table,this,header)});if(this.sortable.order.length)this.sortable.sortData.call(this,this.data.processing)}this.data.current=this.data.processing;this.table.datum(this.data.current);if(this.config.exportable)this.config.exports.forEach(function(fmt){_this.exportable.exports[fmt].call(_this,_this.data.processing)});if(this.config.pagination){this.pagination.addPagination.call(this,this.data.processing);this.data.processing=this.data.processing.filter(function(d,i){return _this.config.startIndex<=i&&i<_this.config.endIndex})}drawTableBody.call(this)}if(this.config.dynamicPositioning){dynamicLayout.call(this)}this.events.onDraw.call(this)}function layout$2(){var context=this;this.searchable.wrap=this.wrap.select(".table-top").append("div").classed("interactivity searchable-container",true).classed("hidden",!this.config.searchable);this.searchable.wrap.append("div").classed("search",true);this.searchable.wrap.select(".search").append("input").classed("search-box",true).attr("placeholder","Search").on("input",function(){context.searchable.searchTerm=this.value.toLowerCase()||null;context.config.activePage=0;context.config.startIndex=context.config.activePage*context.config.nRowsPerPage;context.config.endIndex=context.config.startIndex+context.config.nRowsPerPage;context.draw()});this.searchable.wrap.select(".search").append("span").classed("nNrecords",true)}function searchable(){return{layout:layout$2}}function layout$3(){var _this=this;this.exportable.wrap=this.wrap.select(".table-bottom").append("div").classed("interactivity exportable-container",true).classed("hidden",!this.config.exportable);this.exportable.wrap.append("span").text("Export:");if(this.config.exports&&this.config.exports.length)this.config.exports.forEach(function(fmt){_this.exportable.wrap.append("a").classed("wc-button export",true).attr({id:fmt}).style(!_this.test&&navigator.msSaveBlob?{cursor:"pointer","text-decoration":"underline",color:"blue"}:null).text(fmt.toUpperCase())})}function download(fileType,data){var blob=new Blob(data,{type:fileType==="csv"?"text/csv;charset=utf-8;":fileType==="xlsx"?"application/octet-stream":console.warn("File type not supported: "+fileType)});var fileName="webchartsTableExport_"+d3.time.format("%Y-%m-%dT%H-%M-%S")(new Date)+"."+fileType;var link=this.wrap.select(".export#"+fileType);if(navigator.msSaveBlob)navigator.msSaveBlob(blob,fileName);else if(link.node().download!==undefined){var url=URL.createObjectURL(blob);link.node().setAttribute("href",url);link.node().setAttribute("download",fileName)}}function csv(data){var _this=this;this.wrap.select(".export#csv").on("click",function(){var CSVarray=[];var headers=_this.config.headers.map(function(header){return'"'+header.replace(/"/g,'""')+'"'});CSVarray.push(headers);data.forEach(function(d,i){var row=_this.config.cols.map(function(col){var value=d[col];if(typeof value==="string")value=value.replace(/"/g,'""');return'"'+value+'"'});CSVarray.push(row)});download.call(_this,"csv",[CSVarray.join("\n")])})}function xlsx(data){var _this=this;this.wrap.select(".export#xlsx").on("click",function(){var sheetName="Selected Data";var options={bookType:"xlsx",bookSST:true,type:"binary"};var arrayOfArrays=data.map(function(d){return Object.keys(d).filter(function(key){return _this.config.cols.indexOf(key)>-1}).map(function(key){return d[key]})});var workbook={SheetNames:[sheetName],Sheets:{}};var cols=[];workbook.Sheets[sheetName]=XLSX.utils.aoa_to_sheet([_this.config.headers].concat(arrayOfArrays));workbook.Sheets[sheetName]["!autofilter"]={ref:"A1:"+String.fromCharCode(64+_this.config.cols.length)+(data.length+1)};_this.table.selectAll("thead tr th").each(function(){cols.push({wpx:this.offsetWidth})});workbook.Sheets[sheetName]["!cols"]=cols;var xlsx=XLSX.write(workbook,options);var s2ab=function s2ab(s){var buffer=new ArrayBuffer(s.length),view=new Uint8Array(buffer);for(var i=0;i!==s.length;++i){view[i]=s.charCodeAt(i)&255}return buffer};download.call(_this,"xlsx",[s2ab(xlsx)])})}var exports$1={csv:csv,xlsx:xlsx};function exportable(){return{layout:layout$3,exports:exports$1}}function layout$4(){this.sortable.wrap=this.wrap.select(".table-top").append("div").classed("interactivity sortable-container",true).classed("hidden",!this.config.sortable);this.sortable.wrap.append("div").classed("instruction",true).text("Click column headers to sort.")}function onClick(th,header){var context=this,selection=d3.select(th),col=this.config.cols[this.config.headers.indexOf(header)];var sortItem=this.sortable.order.filter(function(item){return item.col===col})[0];if(!sortItem){sortItem={col:col,direction:"ascending",wrap:this.sortable.wrap.append("div").datum({key:col}).classed("wc-button sort-box",true).text(header)};sortItem.wrap.append("span").classed("sort-direction",true).html("↓");sortItem.wrap.append("span").classed("remove-sort",true).html("❌");this.sortable.order.push(sortItem)}else{sortItem.direction=sortItem.direction==="ascending"?"descending":"ascending";sortItem.wrap.select("span.sort-direction").html(sortItem.direction==="ascending"?"↓":"↑")}this.sortable.wrap.select(".instruction").classed("hidden",true);this.sortable.order.forEach(function(item,i){item.wrap.on("click",function(d){d3.select(this).remove();context.sortable.order.splice(context.sortable.order.map(function(d){return d.col}).indexOf(d.key),1);context.sortable.wrap.select(".instruction").classed("hidden",context.sortable.order.length);context.draw()})});this.draw()}function sortData(data){var _this=this;data=data.sort(function(a,b){var order=0;_this.sortable.order.forEach(function(item){var aCell=a[item.col],bCell=b[item.col];if(order===0){if(item.direction==="ascending"&&aCellbCell)order=-1;else if(item.direction==="ascending"&&aCell>bCell||item.direction==="descending"&&aCell=_this.config.nPageLinksDisplayed:_this.config.activePage>=_this.config.nPages-_this.config.nPageLinksDisplayed?i<_this.config.nPages-_this.config.nPageLinksDisplayed:i<_this.config.activePage-(Math.ceil(_this.config.nPageLinksDisplayed/2)-1)||_this.config.activePage+_this.config.nPageLinksDisplayed/2=this.config.nPages)next=this.config.nPages-1;this.pagination.wrap.insert("span",":first-child").classed("dot-dot-dot",true).text("...").classed("hidden",this.config.activePage=Math.max(this.config.nPageLinksDisplayed,this.config.nPages-this.config.nPageLinksDisplayed)||this.config.nPages<=this.config.nPageLinksDisplayed);this.pagination.next=this.pagination.wrap.append("a").classed("wc-button arrow-link wc-right",true).classed("hidden",this.config.activePage==this.config.nPages-1||this.config.nPages==0).attr({rel:next}).text(">");this.pagination.doubleNext=this.pagination.wrap.append("a").classed("wc-button arrow-link wc-right double",true).classed("hidden",this.config.activePage==this.config.nPages-1||this.config.nPages==0).attr({rel:this.config.nPages-1}).text(">>");this.pagination.arrows=this.pagination.wrap.selectAll("a.arrow-link");this.pagination.doubleArrows=this.pagination.wrap.selectAll("a.double-arrow-link")}function addPagination(data){var context=this;this.config.nRows=data.length;this.config.nPages=Math.ceil(this.config.nRows/this.config.nRowsPerPage);this.config.paginationHidden=this.config.nPages===1;this.pagination.wrap.classed("hidden",this.config.paginationHidden);addLinks.call(this);this.pagination.links.on("click",function(){context.config.activePage=+d3.select(this).attr("rel");updatePagination.call(context)});addArrows.call(this);this.pagination.arrows.on("click",function(){if(context.config.activePage!==+d3.select(this).attr("rel")){context.config.activePage=+d3.select(this).attr("rel");context.pagination.prev.attr("rel",context.config.activePage>0?context.config.activePage-1:0);context.pagination.next.attr("rel",context.config.activePage1&&arguments[1]!==undefined?arguments[1]:false;this.test=test;if(d3.select(this.div).select(".loader").empty()){d3.select(this.div).insert("div",":first-child").attr("class","loader").selectAll(".blockG").data(d3.range(8)).enter().append("div").attr("class",function(d){return"blockG rotate"+(d+1)})}this.setDefaults.call(this,data[0]);this.wrap.classed("wc-chart",true).classed("wc-table",this.config.applyCSS);this.data={raw:data};this.searchable=searchable.call(this);this.sortable=sortable.call(this);this.pagination=pagination.call(this);this.exportable=exportable.call(this);var startup=function startup(data){if(_this.controls){_this.controls.targets.push(_this);if(!_this.controls.ready){_this.controls.init(_this.data.raw)}else{_this.controls.layout()}}var visible=d3.select(_this.div).property("offsetWidth")>0||test;if(!visible){console.warn("The table cannot be initialized inside an element with 0 width. The table will be initialized as soon as the container element is given a width > 0.");var onVisible=setInterval(function(i){var visible_now=d3.select(_this.div).property("offsetWidth")>0;if(visible_now){_this.layout();_this.wrap.datum(_this);_this.draw();clearInterval(onVisible)}},500)}else{_this.layout();_this.wrap.datum(_this);_this.draw()}};this.events.onInit.call(this);if(this.data.raw.length){this.checkRequired(this.data.raw)}startup(data);return this}function layout$6(){d3.select(this.div).select(".loader").remove();this.wrap.append("div").classed("table-top",true);this.searchable.layout.call(this);this.sortable.layout.call(this);this.table=this.wrap.append("table").classed("table",this.config.bootstrap);this.thead=this.table.append("thead");this.thead.append("tr");this.tbody=this.table.append("tbody");this.wrap.append("div").classed("table-bottom",true);this.pagination.layout.call(this);this.exportable.layout.call(this);this.events.onLayout.call(this)}function destroy$2(){var destroyControls=arguments.length>0&&arguments[0]!==undefined?arguments[0]:false;this.events.onDestroy.call(this);if(destroyControls&&this.controls){this.controls.destroy()}this.wrap.remove()}function setDefault(setting){var _default_=arguments.length>1&&arguments[1]!==undefined?arguments[1]:true;this.config[setting]=this.config[setting]!==undefined?this.config[setting]:_default_}function setDefaults$1(firstItem){if(this.config.cols instanceof Array&&this.config.headers instanceof Array){if(this.config.cols.length===0)delete this.config.cols;if(this.config.headers.length===0||this.config.headers.length!==this.config.cols.length)delete this.config.headers}this.config.cols=this.config.cols||d3.keys(firstItem);this.config.headers=this.config.headers||this.config.cols;this.config.layout="horizontal";setDefault.call(this,"searchable");setDefault.call(this,"exportable");setDefault.call(this,"exports",["csv"]);setDefault.call(this,"sortable");setDefault.call(this,"pagination");setDefault.call(this,"nRowsPerPage",10);setDefault.call(this,"nPageLinksDisplayed",5);setDefault.call(this,"applyCSS");setDefault.call(this,"dynamicPositioning")}function transformData$1(processed_data){var _this=this;this.data.processed=this.transformData(this.wrap.datum);if(!data){return}this.config.cols=this.config.cols||d3.keys(data[0]);this.config.headers=this.config.headers||this.config.cols;if(this.config.keep){this.config.keep.forEach(function(e){if(_this.config.cols.indexOf(e)===-1){_this.config.cols.unshift(e)}})}var filtered=data;if(this.filters.length){this.filters.forEach(function(e){var is_array=e.val instanceof Array;filtered=filtered.filter(function(d){if(is_array){return e.val.indexOf(d[e.col])!==-1}else{return e.val!=="All"?d[e.col]===e.val:d}})})}var slimmed=d3.nest().key(function(d){if(_this.config.row_per){return _this.config.row_per.map(function(m){return d[m]}).join(" ")}else{return d}}).rollup(function(r){if(_this.config.dataManipulate){r=_this.config.dataManipulate(r)}var nuarr=r.map(function(m){var arr=[];for(var x in m){arr.push({col:x,text:m[x]})}arr.sort(function(a,b){return _this.config.cols.indexOf(a.col)-_this.config.cols.indexOf(b.col)});return{cells:arr,raw:m}});return nuarr}).entries(filtered);this.data.current=slimmed.length?slimmed:[{key:null,values:[]}];this.pagination.wrap.selectAll("*").remove();this.events.onDatatransform.call(this);if(config.row_per){var rev_order=config.row_per.slice(0).reverse();rev_order.forEach(function(e){tbodies.sort(function(a,b){return a.values[0].raw[e]-b.values[0].raw[e]})})}if(config.row_per){rows.filter(function(f,i){return i>0}).selectAll("td").filter(function(f){return config.row_per.indexOf(f.col)>-1}).text("")}return this.data.current}var table=Object.create(chart,{draw:{value:draw$1},init:{value:init$2},layout:{value:layout$6},setDefaults:{value:setDefaults$1},transformData:{value:transformData$1},destroy:{value:destroy$2}});function createTable(){var element=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"body";var config=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var controls=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;var thisTable=Object.create(table);thisTable.div=element;thisTable.config=Object.create(config);thisTable.controls=controls;thisTable.filters=[];thisTable.required_cols=[];thisTable.wrap=d3.select(thisTable.div).append("div").datum(thisTable);thisTable.events={onInit:function onInit(){},onLayout:function onLayout(){},onPreprocess:function onPreprocess(){},onDraw:function onDraw(){},onDestroy:function onDestroy(){}};thisTable.on=function(event,callback){var possible_events=["init","layout","preprocess","draw","destroy"];if(possible_events.indexOf(event)<0){return}if(callback){thisTable.events["on"+event.charAt(0).toUpperCase()+event.slice(1)]=callback}};return thisTable}function multiply(chart,data,split_by,order){var test=arguments.length>4&&arguments[4]!==undefined?arguments[4]:false;chart.wrap.classed("wc-layout wc-small-multiples",true).classed("wc-chart",false);chart.master_legend=chart.wrap.append("ul").attr("class","legend");chart.master_legend.append("span").classed("legend-title",true);chart.multiples=[];function goAhead(data){var split_vals=d3.set(data.map(function(m){return m[split_by]})).values().filter(function(f){return f});if(order){split_vals=split_vals.sort(function(a,b){return d3.ascending(order.indexOf(a),order.indexOf(b))})}split_vals.forEach(function(e){var mchart=createChart(chart.wrap.node(),chart.config,chart.controls);chart.multiples.push(mchart);mchart.parent=chart;mchart.events=chart.events;mchart.legend=chart.master_legend;mchart.filters.unshift({col:split_by,val:e,choices:split_vals});mchart.wrap.insert("span","svg").attr("class","wc-chart-title").text(e);mchart.init(data,test)})}goAhead(data)}function getValType(data,variable){var var_vals=d3.set(data.map(function(m){return m[variable]})).values();var vals_numbers=var_vals.filter(function(f){return+f||+f===0});if(var_vals.length===vals_numbers.length&&var_vals.length>4){return"continuous"}else{return"categorical"}}function lengthenRaw(data,columns){var my_data=[];data.forEach(function(e){columns.forEach(function(g){var obj=Object.create(e);obj.wc_category=g;obj.wc_value=e[g];my_data.push(obj)})});return my_data}var dataOps={getValType:getValType,lengthenRaw:lengthenRaw,naturalSorter:naturalSorter,summarize:summarize};var index={version:version,createChart:createChart,createControls:createControls,createTable:createTable,multiply:multiply,dataOps:dataOps};return index}); +(function(global,factory){typeof exports==="object"&&typeof module!=="undefined"?module.exports=factory(require("d3")):typeof define==="function"&&define.amd?define(["d3"],factory):global.webCharts=factory(global.d3)})(typeof self!=="undefined"?self:this,function(d3){"use strict";var version="1.11.5";function init(data){var _this=this;var test=arguments.length>1&&arguments[1]!==undefined?arguments[1]:false;if(d3.select(this.div).select(".loader").empty()){d3.select(this.div).insert("div",":first-child").attr("class","loader").selectAll(".blockG").data(d3.range(8)).enter().append("div").attr("class",function(d){return"blockG rotate"+(d+1)})}this.wrap.attr("class","wc-chart");this.setDefaults();this.raw_data=data;this.initial_data=data;var startup=function startup(data){if(_this.controls){_this.controls.targets.push(_this);if(!_this.controls.ready){_this.controls.init(_this.raw_data)}else{_this.controls.layout()}}var visible=d3.select(_this.div).property("offsetWidth")>0||test;if(!visible){console.warn("The chart cannot be initialized inside an element with 0 width. The chart will be initialized as soon as the container element is given a width > 0.");var onVisible=setInterval(function(i){var visible_now=d3.select(_this.div).property("offsetWidth")>0;if(visible_now){_this.layout();_this.draw();clearInterval(onVisible)}},500)}else{_this.layout();_this.draw()}};this.events.onInit.call(this);if(this.raw_data.length){this.checkRequired(this.raw_data)}startup(data);return this}function checkRequired(data){var _this=this;var colnames=Object.keys(data[0]);var requiredVars=[];var requiredCols=[];if(this.config.x&&this.config.x.column){requiredVars.push("this.config.x.column");requiredCols.push(this.config.x.column)}if(this.config.y&&this.config.y.column){requiredVars.push("this.config.y.column");requiredCols.push(this.config.y.column)}if(this.config.color_by){requiredVars.push("this.config.color_by");requiredCols.push(this.config.color_by)}if(this.config.marks)this.config.marks.forEach(function(e,i){if(e.per&&e.per.length){e.per.forEach(function(p,j){requiredVars.push("this.config.marks["+i+"].per["+j+"]");requiredCols.push(p)})}if(e.split){requiredVars.push("this.config.marks["+i+"].split");requiredCols.push(e.split)}if(e.values){for(var value in e.values){requiredVars.push("this.config.marks["+i+"].values['"+value+"']");requiredCols.push(value)}}});var missingDataField=false;requiredCols.forEach(function(e,i){if(colnames.indexOf(e)<0){missingDataField=true;d3.select(_this.div).select(".loader").remove();_this.wrap.append("div").style("color","red").html('The value "'+e+'" for the '+requiredVars[i]+" setting does not match any column in the provided dataset.");throw new Error('Error in settings object: The value "'+e+'" for the '+requiredVars[i]+" setting does not match any column in the provided dataset.")}});return{missingDataField:missingDataField,dataFieldArguments:requiredVars,requiredDataFields:requiredCols}}function addSVG(){this.svg=this.wrap.append("svg").datum(function(){return null}).attr({class:"wc-svg",xmlns:"http://www.w3.org/2000/svg",version:"1.1",xlink:"http://www.w3.org/1999/xlink"}).append("g").style("display","inline-block")}function addDefs(){var defs=this.svg.append("defs");defs.append("pattern").attr({id:"diagonal-stripes",x:0,y:0,width:3,height:8,patternUnits:"userSpaceOnUse",patternTransform:"rotate(30)"}).append("rect").attr({x:"0",y:"0",width:"2",height:"8"}).style({stroke:"none",fill:"black"});defs.append("clipPath").attr("id",this.id).append("rect").attr("class","plotting-area")}function addXAxis(){this.svg.append("g").attr("class","x axis").append("text").attr("class","axis-title").attr("dy","-.35em").attr("text-anchor","middle")}function addYAxis(){this.svg.append("g").attr("class","y axis").append("text").attr("class","axis-title").attr("transform","rotate(-90)").attr("dy",".75em").attr("text-anchor","middle")}function addOverlay(){this.overlay=this.svg.append("rect").attr("class","overlay").attr("opacity",0).attr("fill","none").style("pointer-events","all")}function addLegend(){if(!this.parent)this.wrap.append("ul").datum(function(){return null}).attr("class","legend").style("vertical-align","top").append("span").attr("class","legend-title")}function clearLoader(){d3.select(this.div).select(".loader").remove()}function layout(){addSVG.call(this);addDefs.call(this);addXAxis.call(this);addYAxis.call(this);addOverlay.call(this);addLegend.call(this);clearLoader.call(this);this.events.onLayout.call(this)}function draw(raw_data,processed_data){var _this=this;var chart=this;var config=this.config;this.events.onPreprocess.call(this);var raw=raw_data?raw_data:this.raw_data?this.raw_data:[];if(processed_data){console.warn("Drawing the chart using user-defined 'processed_data', this is an experimental, untested feature.")}this.consolidateData(raw);var div_width=parseInt(this.wrap.style("width"));this.setColorScale();var max_width=config.max_width?config.max_width:div_width;this.raw_width=config.x.type==="ordinal"&&+config.x.range_band?(+config.x.range_band+config.x.range_band*config.padding)*this.x_dom.length:config.resizable?max_width:config.width?config.width:div_width;this.raw_height=config.y.type==="ordinal"&&+config.y.range_band?(+config.y.range_band+config.y.range_band*config.padding)*this.y_dom.length:config.resizable?max_width*(1/config.aspect):config.height?config.height:div_width*(1/config.aspect);var pseudo_width=this.svg.select(".overlay").attr("width")?this.svg.select(".overlay").attr("width"):this.raw_width;var pseudo_height=this.svg.select(".overlay").attr("height")?this.svg.select(".overlay").attr("height"):this.raw_height;this.svg.select(".x.axis").select(".axis-title").text(function(d){return typeof config.x.label==="string"?config.x.label:typeof config.x.label==="function"?config.x.label.call(_this):null});this.svg.select(".y.axis").select(".axis-title").text(function(d){return typeof config.y.label==="string"?config.y.label:typeof config.y.label==="function"?config.y.label.call(_this):null});this.xScaleAxis(pseudo_width);this.yScaleAxis(pseudo_height);if(config.resizable&&typeof window!=="undefined"){d3.select(window).on("resize."+this.element+this.id,function(){chart.resize()})}else if(typeof window!=="undefined"){d3.select(window).on("resize."+this.element+this.id,null)}this.events.onDraw.call(this);this.resize()}function naturalSorter(a,b){function chunkify(t){var tz=[];var x=0,y=-1,n=0,i=void 0,j=void 0;while(i=(j=t.charAt(x++)).charCodeAt(0)){var m=i==46||i>=48&&i<=57;if(m!==n){tz[++y]="";n=m}tz[y]+=j}return tz}var aa=chunkify(a.toLowerCase());var bb=chunkify(b.toLowerCase());for(var x=0;aa[x]&&bb[x];x++){if(aa[x]!==bb[x]){var c=Number(aa[x]),d=Number(bb[x]);if(c==aa[x]&&d==bb[x]){return c-d}else{return aa[x]>bb[x]?1:-1}}}return aa.length-bb.length}function setDomain(axis){var _this=this;var otherAxis=axis==="x"?"y":"x";if(this.config[axis].type==="ordinal"){if(this.config[axis].domain){this[axis+"_dom"]=this.config[axis].domain}else if(this.config[axis].order){this[axis+"_dom"]=d3.set(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]}))).values().sort(function(a,b){return d3.ascending(_this.config[axis].order.indexOf(a),_this.config[axis].order.indexOf(b))})}else if(this.config[axis].sort&&this.config[axis].sort==="alphabetical-ascending"){this[axis+"_dom"]=d3.set(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]}))).values().sort(naturalSorter)}else if(["time","linear"].indexOf(this.config[otherAxis].type)>-1&&this.config[axis].sort==="earliest"){this[axis+"_dom"]=d3.nest().key(function(d){return d[_this.config[axis].column]}).rollup(function(d){return d.map(function(m){return m[_this.config[otherAxis].column]}).filter(function(f){return f instanceof Date})}).entries(this.filtered_data).sort(function(a,b){return d3.min(b.values)-d3.min(a.values)}).map(function(m){return m.key})}else if(!this.config[axis].sort||this.config[axis].sort==="alphabetical-descending"){this[axis+"_dom"]=d3.set(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]}))).values().sort(naturalSorter).reverse()}else{this[axis+"_dom"]=d3.set(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]}))).values()}}else if(this.config.marks.map(function(m){return m["summarize"+axis.toUpperCase()]==="percent"}).indexOf(true)>-1){this[axis+"_dom"]=[0,1]}else{this[axis+"_dom"]=d3.extent(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]})))}if(this.config[axis].type==="linear"&&this[axis+"_dom"][0]===this[axis+"_dom"][1])this[axis+"_dom"]=this[axis+"_dom"][0]!==0?[this[axis+"_dom"][0]-this[axis+"_dom"][0]*.01,this[axis+"_dom"][1]+this[axis+"_dom"][1]*.01]:[-1,1];return this[axis+"_dom"]}function consolidateData(raw){var _this=this;this.setDefaults();this.filtered_data=raw;if(this.filters.length){this.filters.forEach(function(filter){_this.filtered_data=_this.filtered_data.filter(function(d){return filter.all===true&&filter.index===0?d:filter.val instanceof Array?filter.val.indexOf(d[filter.col])>-1:d[filter.col]===filter.val})})}this.config.marks.forEach(function(mark,i){if(mark.type!=="bar"){mark.arrange=null;mark.split=null}var mark_info=mark.per?_this.transformData(raw,mark):{data:[],x_dom:[],y_dom:[]};_this.marks[i]=Object.assign({},mark,mark_info)});setDomain.call(this,"x");setDomain.call(this,"y")}function setDefaults(){this.config.x=this.config.x||{};this.config.y=this.config.y||{};this.config.x.label=this.config.x.label!==undefined?this.config.x.label:this.config.x.column;this.config.y.label=this.config.y.label!==undefined?this.config.y.label:this.config.y.column;this.config.x.sort=this.config.x.sort||"alphabetical-ascending";this.config.y.sort=this.config.y.sort||"alphabetical-descending";this.config.x.type=this.config.x.type||"linear";this.config.y.type=this.config.y.type||"linear";this.config.x.range_band=this.config.x.range_band||this.config.range_band;this.config.y.range_band=this.config.y.range_band||this.config.range_band;this.config.margin=this.config.margin||{};this.config.legend=this.config.legend||{};this.config.legend.label=this.config.legend.label!==undefined?this.config.legend.label:this.config.color_by;this.config.legend.location=this.config.legend.location!==undefined?this.config.legend.location:"bottom";this.config.marks=this.config.marks&&this.config.marks.length?this.config.marks:[{}];this.config.marks.forEach(function(m,i){m.id=m.id?m.id:"mark"+(i+1)});this.config.date_format=this.config.date_format||"%x";this.config.padding=this.config.padding!==undefined?this.config.padding:.3;this.config.outer_pad=this.config.outer_pad!==undefined?this.config.outer_pad:.1;this.config.resizable=this.config.resizable!==undefined?this.config.resizable:true;this.config.aspect=this.config.aspect||1.33;this.config.colors=this.config.colors||["rgb(102,194,165)","rgb(252,141,98)","rgb(141,160,203)","rgb(231,138,195)","rgb(166,216,84)","rgb(255,217,47)","rgb(229,196,148)","rgb(179,179,179)"];this.config.scale_text=this.config.scale_text===undefined?true:this.config.scale_text;this.config.transitions=this.config.transitions===undefined?true:this.config.transitions}function cleanData(mark,raw){var _this=this;var dateConvert=d3.time.format(this.config.date_format);var clean=raw;clean=mark.per&&mark.per.length?clean.filter(function(f){return f[mark.per[0]]!==undefined}):clean;if(this.config.x.column){clean=clean.filter(function(f){return[undefined,null].indexOf(f[_this.config.x.column])<0})}if(this.config.y.column){clean=clean.filter(function(f){return[undefined,null].indexOf(f[_this.config.y.column])<0})}if(this.config.x.type==="time"){clean=clean.filter(function(f){return f[_this.config.x.column]instanceof Date?f[_this.config.x.column]:dateConvert.parse(f[_this.config.x.column])});clean.forEach(function(e){return e[_this.config.x.column]=e[_this.config.x.column]instanceof Date?e[_this.config.x.column]:dateConvert.parse(e[_this.config.x.column])})}if(this.config.y.type==="time"){clean=clean.filter(function(f){return f[_this.config.y.column]instanceof Date?f[_this.config.y.column]:dateConvert.parse(f[_this.config.y.column])});clean.forEach(function(e){return e[_this.config.y.column]=e[_this.config.y.column]instanceof Date?e[_this.config.y.column]:dateConvert.parse(e[_this.config.y.column])})}if((this.config.x.type==="linear"||this.config.x.type==="log")&&this.config.x.column){clean=clean.filter(function(f){return mark.summarizeX!=="count"&&mark.summarizeX!=="percent"?!(isNaN(f[_this.config.x.column])||/^\s*$/.test(f[_this.config.x.column])):f})}if((this.config.y.type==="linear"||this.config.y.type==="log")&&this.config.y.column){clean=clean.filter(function(f){return mark.summarizeY!=="count"&&mark.summarizeY!=="percent"?!(isNaN(f[_this.config.y.column])||/^\s*$/.test(f[_this.config.y.column])):f})}return clean}var stats={mean:d3.mean,min:d3.min,max:d3.max,median:d3.median,sum:d3.sum};function summarize(vals){var operation=arguments.length>1&&arguments[1]!==undefined?arguments[1]:"mean";var nvals=vals.filter(function(f){return+f||+f===0}).map(function(m){return+m});if(operation==="cumulative"){return null}var mathed=operation==="count"?vals.length:operation==="percent"?vals.length:stats[operation](nvals);return mathed}function makeNest(mark,entries,sublevel){var _this=this;var dom_xs=[];var dom_ys=[];var this_nest=d3.nest();var totalOrder=void 0;if(this.config.x.type==="linear"&&this.config.x.bin||this.config.y.type==="linear"&&this.config.y.bin){var xy=this.config.x.type==="linear"&&this.config.x.bin?"x":"y";mark.quant=d3.scale.quantile().domain(this.config[xy].domain?this.config[xy].domain:d3.extent(entries.map(function(m){return+m[_this.config[xy].column]}))).range(d3.range(+this.config[xy].bin));entries.forEach(function(e){return e.wc_bin=mark.quant(e[_this.config[xy].column])});this_nest.key(function(d){return mark.quant.invertExtent(d.wc_bin)})}else{this_nest.key(function(d){return mark.per.map(function(m){return d[m]}).join(" ")})}if(sublevel){this_nest.key(function(d){return d[sublevel]});this_nest.sortKeys(function(a,b){return _this.config.x.type==="time"?d3.ascending(new Date(a),new Date(b)):_this.config.x.order?d3.ascending(_this.config.x.order.indexOf(a),_this.config.x.order.indexOf(b)):sublevel===_this.config.color_by&&_this.config.legend.order?d3.ascending(_this.config.legend.order.indexOf(a),_this.config.legend.order.indexOf(b)):_this.config.x.type==="ordinal"||_this.config.y.type==="ordinal"?naturalSorter(a,b):d3.ascending(+a,+b)})}this_nest.rollup(function(r){var obj={raw:r};var y_vals=r.map(function(m){return m[_this.config.y.column]}).sort(d3.ascending);var x_vals=r.map(function(m){return m[_this.config.x.column]}).sort(d3.ascending);obj.x=_this.config.x.type==="ordinal"?r[0][_this.config.x.column]:summarize(x_vals,mark.summarizeX);obj.y=_this.config.y.type==="ordinal"?r[0][_this.config.y.column]:summarize(y_vals,mark.summarizeY);obj.x_q25=_this.config.error_bars&&_this.config.y.type==="ordinal"?d3.quantile(x_vals,.25):obj.x;obj.x_q75=_this.config.error_bars&&_this.config.y.type==="ordinal"?d3.quantile(x_vals,.75):obj.x;obj.y_q25=_this.config.error_bars?d3.quantile(y_vals,.25):obj.y;obj.y_q75=_this.config.error_bars?d3.quantile(y_vals,.75):obj.y;dom_xs.push([obj.x_q25,obj.x_q75,obj.x]);dom_ys.push([obj.y_q25,obj.y_q75,obj.y]);if(mark.summarizeY==="cumulative"){var interm=entries.filter(function(f){return _this.config.x.type==="time"?new Date(f[_this.config.x.column])<=new Date(r[0][_this.config.x.column]):+f[_this.config.x.column]<=+r[0][_this.config.x.column]});if(mark.per.length){interm=interm.filter(function(f){return f[mark.per[0]]===r[0][mark.per[0]]})}var cumul=_this.config.x.type==="time"?interm.length:d3.sum(interm.map(function(m){return+m[_this.config.y.column]||+m[_this.config.y.column]===0?+m[_this.config.y.column]:1}));dom_ys.push([cumul]);obj.y=cumul}if(mark.summarizeX==="cumulative"){var _interm=entries.filter(function(f){return _this.config.y.type==="time"?new Date(f[_this.config.y.column])<=new Date(r[0][_this.config.y.column]):+f[_this.config.y.column]<=+r[0][_this.config.y.column]});if(mark.per.length){_interm=_interm.filter(function(f){return f[mark.per[0]]===r[0][mark.per[0]]})}dom_xs.push([_interm.length]);obj.x=_interm.length}return obj});var test=this_nest.entries(entries);var dom_x=d3.extent(d3.merge(dom_xs));var dom_y=d3.extent(d3.merge(dom_ys));if(sublevel&&mark.type==="bar"&&mark.split){test.forEach(function(e){var axis=_this.config.x.type==="ordinal"||_this.config.x.type==="linear"&&_this.config.x.bin?"y":"x";e.total=d3.sum(e.values.map(function(m){return+m.values[axis]}));var counter=0;e.values.forEach(function(v,i){if(_this.config.x.type==="ordinal"||_this.config.x.type==="linear"&&_this.config.x.bin){v.values.y=mark.summarizeY==="percent"?v.values.y/e.total:v.values.y||0;counter+=+v.values.y;v.values.start=e.values[i-1]?counter:v.values.y}else{v.values.x=mark.summarizeX==="percent"?v.values.x/e.total:v.values.x||0;v.values.start=counter;counter+=+v.values.x}})});if(mark.arrange==="stacked"){if(this.config.x.type==="ordinal"||this.config.x.type==="linear"&&this.config.x.bin){dom_y=d3.extent(test.map(function(m){return m.total}))}if(this.config.y.type==="ordinal"||this.config.y.type==="linear"&&this.config.y.bin){dom_x=d3.extent(test.map(function(m){return m.total}))}}}else{var axis=this.config.x.type==="ordinal"||this.config.x.type==="linear"&&this.config.x.bin?"y":"x";test.forEach(function(e){return e.total=e.values[axis]})}if(this.config.x.sort==="total-ascending"&&this.config.x.type=="ordinal"||this.config.y.sort==="total-descending"&&this.config.y.type=="ordinal"){totalOrder=test.sort(function(a,b){return d3.ascending(a.total,b.total)}).map(function(m){return m.key})}else if(this.config.x.sort==="total-descending"&&this.config.x.type=="ordinal"||this.config.y.sort==="total-ascending"&&this.config.y.type=="ordinal"){totalOrder=test.sort(function(a,b){return d3.descending(+a.total,+b.total)}).map(function(m){return m.key})}return{nested:test,dom_x:dom_x,dom_y:dom_y,totalOrder:totalOrder}}function transformData(raw,mark){var _this=this;var config=this.config;var x_behavior=config.x.behavior||"raw";var y_behavior=config.y.behavior||"raw";var sublevel=mark.type==="line"?config.x.column:mark.type==="bar"&&mark.split?mark.split:null;var cleaned=cleanData.call(this,mark,raw);var raw_nest=void 0;if(mark.type==="bar"){raw_nest=mark.arrange!=="stacked"?makeNest.call(this,mark,cleaned,sublevel):makeNest.call(this,mark,cleaned)}else if(mark.summarizeX==="count"||mark.summarizeY==="count"){raw_nest=makeNest.call(this,mark,cleaned)}var raw_dom_x=mark.summarizeX==="cumulative"?[0,cleaned.length]:config.x.type==="ordinal"?d3.set(cleaned.map(function(m){return m[config.x.column]})).values().filter(function(f){return f}):mark.split&&mark.arrange!=="stacked"?d3.extent(d3.merge(raw_nest.nested.map(function(m){return m.values.map(function(p){return p.values.raw.length})}))):mark.summarizeX==="count"?d3.extent(raw_nest.nested.map(function(m){return m.values.raw.length})):d3.extent(cleaned.map(function(m){return+m[config.x.column]}).filter(function(f){return+f||+f===0}));var raw_dom_y=mark.summarizeY==="cumulative"?[0,cleaned.length]:config.y.type==="ordinal"?d3.set(cleaned.map(function(m){return m[config.y.column]})).values().filter(function(f){return f}):mark.split&&mark.arrange!=="stacked"?d3.extent(d3.merge(raw_nest.nested.map(function(m){return m.values.map(function(p){return p.values.raw.length})}))):mark.summarizeY==="count"?d3.extent(raw_nest.nested.map(function(m){return m.values.raw.length})):d3.extent(cleaned.map(function(m){return+m[config.y.column]}).filter(function(f){return+f||+f===0}));var filtered=cleaned;var filt1_xs=[];var filt1_ys=[];if(this.filters.length){this.filters.forEach(function(e){filtered=filtered.filter(function(d){return e.all===true&&e.index===0?d:e.val instanceof Array?e.val.indexOf(d[e.col])>-1:d[e.col]===e.val})});if(config.x.behavior==="firstfilter"||config.y.behavior==="firstfilter"){this.filters[0].choices.filter(function(f){return f!=="All"}).forEach(function(e){var perfilter=cleaned.filter(function(f){return f[_this.filters[0].col]===e});var filt_nested=makeNest.call(_this,mark,perfilter,sublevel);filt1_xs.push(filt_nested.dom_x);filt1_ys.push(filt_nested.dom_y)})}}if(mark.values){var _loop=function _loop(a){filtered=filtered.filter(function(f){return mark.values[a].indexOf(f[a])>-1})};for(var a in mark.values){_loop(a)}}var filt1_dom_x=d3.extent(d3.merge(filt1_xs));var filt1_dom_y=d3.extent(d3.merge(filt1_ys));var current_nested=makeNest.call(this,mark,filtered,sublevel);var flex_dom_x=current_nested.dom_x;var flex_dom_y=current_nested.dom_y;if(mark.type==="bar"){if(config.y.type==="ordinal"&&mark.summarizeX==="count"){config.x.domain=config.x.domain?[0,config.x.domain[1]]:[0,null]}else if(config.x.type==="ordinal"&&mark.summarizeY==="count"){config.y.domain=config.y.domain?[0,config.y.domain[1]]:[0,null]}}var nonall=Boolean(this.filters.length&&this.filters[0].val!=="All"&&this.filters.slice(1).filter(function(f){return f.val==="All"}).length===this.filters.length-1);var pre_x_dom=!this.filters.length?flex_dom_x:x_behavior==="raw"?raw_dom_x:nonall&&x_behavior==="firstfilter"?filt1_dom_x:flex_dom_x;var pre_y_dom=!this.filters.length?flex_dom_y:y_behavior==="raw"?raw_dom_y:nonall&&y_behavior==="firstfilter"?filt1_dom_y:flex_dom_y;var x_dom=config.x_dom?config.x_dom:config.x.type==="ordinal"&&config.x.behavior==="flex"?d3.set(filtered.map(function(m){return m[config.x.column]})).values():config.x.type==="ordinal"?d3.set(cleaned.map(function(m){return m[config.x.column]})).values():pre_x_dom;var y_dom=config.y_dom?config.y_dom:config.y.type==="ordinal"&&config.y.behavior==="flex"?d3.set(filtered.map(function(m){return m[config.y.column]})).values():config.y.type==="ordinal"?d3.set(cleaned.map(function(m){return m[config.y.column]})).values():pre_y_dom;if(mark.type==="bar"){if(config.x.behavior!=="flex"&&config.x.type==="linear"&&config.y.type==="ordinal"&&raw_dom_x[0]>=0)x_dom[0]=0;if(config.y.behavior!=="flex"&&config.x.type==="ordinal"&&config.y.type==="linear"&&raw_dom_y[0]>=0)y_dom[0]=0}if(config.x.domain&&(config.x.domain[0]||config.x.domain[0]===0)&&!isNaN(+config.x.domain[0])){x_dom[0]=config.x.domain[0]}if(config.x.domain&&(config.x.domain[1]||config.x.domain[1]===0)&&!isNaN(+config.x.domain[1])){x_dom[1]=config.x.domain[1]}if(config.y.domain&&(config.y.domain[0]||config.y.domain[0]===0)&&!isNaN(+config.y.domain[0])){y_dom[0]=config.y.domain[0]}if(config.y.domain&&(config.y.domain[1]||config.y.domain[1]===0)&&!isNaN(+config.y.domain[1])){y_dom[1]=config.y.domain[1]}if(config.x.type==="ordinal"&&!config.x.order){config.x.order=current_nested.totalOrder}if(config.y.type==="ordinal"&&!config.y.order){config.y.order=current_nested.totalOrder}this.current_data=current_nested.nested;this.events.onDatatransform.call(this);return{config:mark,data:current_nested.nested,x_dom:x_dom,y_dom:y_dom}}function setColorScale(){var config=this.config;var data=config.legend.behavior==="flex"?this.filtered_data:this.raw_data;var colordom=Array.isArray(config.color_dom)&&config.color_dom.length?config.color_dom.slice():d3.set(data.map(function(m){return m[config.color_by]})).values().filter(function(f){return f&&f!=="undefined"});if(config.legend.order)colordom.sort(function(a,b){return d3.ascending(config.legend.order.indexOf(a),config.legend.order.indexOf(b))});else colordom.sort(naturalSorter);this.colorScale=d3.scale.ordinal().domain(colordom).range(config.colors)}function xScaleAxis(max_range,domain,type){if(max_range===undefined){max_range=this.plot_width}if(domain===undefined){domain=this.x_dom}if(type===undefined){type=this.config.x.type}var config=this.config;var x=void 0;if(type==="log"){x=d3.scale.log()}else if(type==="ordinal"){x=d3.scale.ordinal()}else if(type==="time"){x=d3.time.scale()}else{x=d3.scale.linear()}x.domain(domain);if(type==="ordinal"){x.rangeBands([0,+max_range],config.padding,config.outer_pad)}else{x.range([0,+max_range]).clamp(Boolean(config.x.clamp))}var xFormat=config.x.format?config.x.format:config.marks.map(function(m){return m.summarizeX==="percent"}).indexOf(true)>-1?"0%":type==="time"?"%x":".0f";var tick_count=Math.max(2,Math.min(max_range/80,8));var xAxis=d3.svg.axis().scale(x).orient(config.x.location).ticks(tick_count).tickFormat(type==="ordinal"?null:type==="time"?d3.time.format(xFormat):d3.format(xFormat)).tickValues(config.x.ticks?config.x.ticks:null).innerTickSize(6).outerTickSize(3);this.svg.select("g.x.axis").attr("class","x axis "+type);this.x=x;this.xAxis=xAxis}function yScaleAxis(max_range,domain,type){if(max_range===undefined){max_range=this.plot_height}if(domain===undefined){domain=this.y_dom}if(type===undefined){type=this.config.y.type}var config=this.config;var y=void 0;if(type==="log"){y=d3.scale.log()}else if(type==="ordinal"){y=d3.scale.ordinal()}else if(type==="time"){y=d3.time.scale()}else{y=d3.scale.linear()}y.domain(domain);if(type==="ordinal"){y.rangeBands([+max_range,0],config.padding,config.outer_pad)}else{y.range([+max_range,0]).clamp(Boolean(config.y_clamp))}var yFormat=config.y.format?config.y.format:config.marks.map(function(m){return m.summarizeY==="percent"}).indexOf(true)>-1?"0%":".0f";var tick_count=Math.max(2,Math.min(max_range/80,8));var yAxis=d3.svg.axis().scale(y).orient("left").ticks(tick_count).tickFormat(type==="ordinal"?null:type==="time"?d3.time.format(yFormat):d3.format(yFormat)).tickValues(config.y.ticks?config.y.ticks:null).innerTickSize(6).outerTickSize(3);this.svg.select("g.y.axis").attr("class","y axis "+type);this.y=y;this.yAxis=yAxis}function resize(){var config=this.config;var aspect2=1/config.aspect;var div_width=parseInt(this.wrap.style("width"));var max_width=config.max_width?config.max_width:div_width;var preWidth=!config.resizable?config.width:!max_width||div_width=600){font_size="14px";point_size=4;stroke_width=2}else if(width>450&&width<600){font_size="12px";point_size=3;stroke_width=2}else if(width>300&&width<450){font_size="10px";point_size=2;stroke_width=2}else if(width<=300){font_size="10px";point_size=2;stroke_width=1}this.wrap.style("font-size",font_size);this.config.flex_point_size=point_size;this.config.flex_stroke_width=stroke_width}function setMargins(){var _this=this;var y_ticks=this.yAxis.tickFormat()?this.y.domain().map(function(m){return _this.yAxis.tickFormat()(m)}):this.y.domain();var max_y_text_length=d3.max(y_ticks.map(function(m){return String(m).length}));if(this.config.y_format&&this.config.y_format.indexOf("%")>-1){max_y_text_length+=1}max_y_text_length=Math.max(2,max_y_text_length);var x_label_on=this.config.x.label?1.5:0;var y_label_on=this.config.y.label?1.5:.25;var font_size=parseInt(this.wrap.style("font-size"));var x_second=this.config.x2_interval?1:0;var y_margin=max_y_text_length*font_size*.5+font_size*y_label_on*1.5||8;var x_margin=font_size+font_size/1.5+font_size*x_label_on+font_size*x_second||8;y_margin+=6;x_margin+=3;return{top:this.config.margin&&this.config.margin.top?this.config.margin.top:8,right:this.config.margin&&this.config.margin.right?this.config.margin.right:16,bottom:this.config.margin&&this.config.margin.bottom?this.config.margin.bottom:x_margin,left:this.config.margin&&this.config.margin.left?this.config.margin.left:y_margin}}function drawGridLines(){this.wrap.classed("gridlines",this.config.gridlines);if(this.config.gridlines){this.svg.select(".y.axis").selectAll(".tick line").attr("x1",0);this.svg.select(".x.axis").selectAll(".tick line").attr("y1",0);if(this.config.gridlines==="y"||this.config.gridlines==="xy")this.svg.select(".y.axis").selectAll(".tick line").attr("x1",this.plot_width);if(this.config.gridlines==="x"||this.config.gridlines==="xy")this.svg.select(".x.axis").selectAll(".tick line").attr("y1",-this.plot_height)}else{this.svg.select(".y.axis").selectAll(".tick line").attr("x1",0);this.svg.select(".x.axis").selectAll(".tick line").attr("y1",0)}}function makeLegend(){var scale=arguments.length>0&&arguments[0]!==undefined?arguments[0]:this.colorScale;var label=arguments.length>1&&arguments[1]!==undefined?arguments[1]:"";var custom_data=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;var config=this.config;config.legend.mark=config.legend.mark?config.legend.mark:config.marks.length&&config.marks[0].type==="bar"?"square":config.marks.length?config.marks[0].type:"square";var legend_label=label?label:typeof config.legend.label==="string"?config.legend.label:"";var legendOriginal=this.legend||this.wrap.select(".legend");var legend=legendOriginal;if(!this.parent){if(this.config.legend.location==="top"||this.config.legend.location==="left"){this.wrap.node().insertBefore(legendOriginal.node(),this.svg.node().parentNode)}else{this.wrap.node().appendChild(legendOriginal.node())}}else{if(this.config.legend.location==="top"||this.config.legend.location==="left"){this.parent.wrap.node().insertBefore(legendOriginal.node(),this.parent.wrap.select(".wc-chart").node())}else{this.parent.wrap.node().appendChild(legendOriginal.node())}}legend.style("padding",0);var legend_data=custom_data||scale.domain().slice(0).filter(function(f){return f!==undefined&&f!==null}).map(function(m){return{label:m,mark:config.legend.mark}});legend.select(".legend-title").text(legend_label).style("display",legend_label?"inline":"none").style("margin-right","1em");var leg_parts=legend.selectAll(".legend-item").data(legend_data,function(d){return d.label+d.mark});leg_parts.exit().remove();var legendPartDisplay=this.config.legend.location==="bottom"||this.config.legend.location==="top"?"inline-block":"block" +;var new_parts=leg_parts.enter().append("li").attr("class","legend-item").style({"list-style-type":"none","margin-right":"1em"});new_parts.append("span").attr("class","legend-mark-text").style("color",function(d){return scale(d.label)});new_parts.append("svg").attr("class","legend-color-block").attr("width","1.1em").attr("height","1.1em").style({position:"relative",top:"0.2em"});leg_parts.style("display",legendPartDisplay);if(config.legend.order){leg_parts.sort(function(a,b){return d3.ascending(config.legend.order.indexOf(a.label),config.legend.order.indexOf(b.label))})}leg_parts.selectAll(".legend-color-block").select(".legend-mark").remove();leg_parts.selectAll(".legend-color-block").each(function(e){var svg=d3.select(this);if(e.mark==="circle"){svg.append("circle").attr({cx:".5em",cy:".5em",r:".45em",class:"legend-mark"})}else if(e.mark==="line"){svg.append("line").attr({x1:0,y1:".5em",x2:"1em",y2:".5em","stroke-width":2,"shape-rendering":"crispEdges",class:"legend-mark"})}else if(e.mark==="square"){svg.append("rect").attr({height:"1em",width:"1em",class:"legend-mark","shape-rendering":"crispEdges"})}});leg_parts.selectAll(".legend-color-block").select(".legend-mark").attr("fill",function(d){return d.color||scale(d.label)}).attr("stroke",function(d){return d.color||scale(d.label)}).each(function(e){d3.select(this).attr(e.attributes)});new_parts.append("span").attr("class","legend-label").style("margin-left","0.25em").text(function(d){return d.label});if(scale.domain().length>0){var legendDisplay=(this.config.legend.location==="bottom"||this.config.legend.location==="top")&&!this.parent?"block":"inline-block";legend.style("display",legendDisplay)}else{legend.style("display","none")}this.legend=legend}function updateDataMarks(){this.drawBars(this.marks.filter(function(f){return f.type==="bar"}));this.drawLines(this.marks.filter(function(f){return f.type==="line"}));this.drawPoints(this.marks.filter(function(f){return f.type==="circle"}));this.drawText(this.marks.filter(function(f){return f.type==="text"}));this.marks.supergroups=this.svg.selectAll("g.supergroup")}function drawArea(area_drawer,area_data,datum_accessor){var class_match=arguments.length>3&&arguments[3]!==undefined?arguments[3]:"chart-area";var _this=this;var bind_accessor=arguments[4];var attr_accessor=arguments.length>5&&arguments[5]!==undefined?arguments[5]:function(d){return d};var area_grps=this.svg.selectAll("."+class_match).data(area_data,bind_accessor);area_grps.exit().remove();area_grps.enter().append("g").attr("class",function(d){return class_match+" "+d.key}).append("path");var areaPaths=area_grps.select("path").datum(datum_accessor).attr("fill",function(d){var d_attr=attr_accessor(d);return d_attr?_this.colorScale(d_attr[_this.config.color_by]):null}).attr("fill-opacity",this.config.fill_opacity||this.config.fill_opacity===0?this.config.fill_opacity:.3);var areaPathTransitions=this.config.transitions?areaPaths.transition():areaPaths;areaPathTransitions.attr("d",area_drawer);return area_grps}function drawBars(marks){var _this=this;var chart=this;var rawData=this.raw_data;var config=this.config;var bar_supergroups=this.svg.selectAll(".bar-supergroup").data(marks,function(d,i){return i+"-"+d.per.join("-")});bar_supergroups.enter().append("g").attr("class",function(d){return"supergroup bar-supergroup "+d.id});bar_supergroups.exit().remove();var bar_groups=bar_supergroups.selectAll(".bar-group").data(function(d){return d.data},function(d){return d.key});var old_bar_groups=bar_groups.exit();var nu_bar_groups=void 0;var bars=void 0;var oldBarsTrans=config.transitions?old_bar_groups.selectAll(".bar").transition():old_bar_groups.selectAll(".bar");var oldBarGroupsTrans=config.transitions?old_bar_groups.transition():old_bar_groups;if(config.x.type==="ordinal"){oldBarsTrans.attr("y",this.y(0)).attr("height",0);oldBarGroupsTrans.remove();nu_bar_groups=bar_groups.enter().append("g").attr("class",function(d){return"bar-group "+d.key});nu_bar_groups.append("title");bars=bar_groups.selectAll("rect").data(function(d){return d.values instanceof Array?d.values.sort(function(a,b){return _this.colorScale.domain().indexOf(b.key)-_this.colorScale.domain().indexOf(a.key)}):[d]},function(d){return d.key});var exitBars=config.transitions?bars.exit().transition():bars.exit();exitBars.attr("y",this.y(0)).attr("height",0).remove();bars.enter().append("rect").attr("class",function(d){return"wc-data-mark bar "+d.key}).style("clip-path","url(#"+chart.id+")").attr("y",this.y(0)).attr("height",0).append("title");bars.attr("shape-rendering","crispEdges").attr("stroke",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])});bars.each(function(d){var mark=d3.select(this.parentNode.parentNode).datum();d.tooltip=mark.tooltip;d.arrange=mark.split&&mark.arrange?mark.arrange:mark.split?"grouped":null;d.subcats=config.legend.order?config.legend.order.slice().reverse():mark.values&&mark.values[mark.split]?mark.values[mark.split]:d3.set(rawData.map(function(m){return m[mark.split]})).values();d3.select(this).attr(mark.attributes)});var xformat=config.marks.map(function(m){return m.summarizeX==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.x.format);var yformat=config.marks.map(function(m){return m.summarizeY==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.y.format);bars.select("title").text(function(d){var tt=d.tooltip||"";return tt.replace(/\$x/g,xformat(d.values.x)).replace(/\$y/g,yformat(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});var barsTrans=config.transitions?bars.transition():bars;barsTrans.attr("x",function(d){var position=void 0;if(!d.arrange||d.arrange==="stacked"){return _this.x(d.values.x)}else if(d.arrange==="nested"){var _position=d.subcats.indexOf(d.key);var offset=_position?_this.x.rangeBand()/(d.subcats.length*.75)/_position:_this.x.rangeBand();return _this.x(d.values.x)+(_this.x.rangeBand()-offset)/2}else{position=d.subcats.indexOf(d.key);return _this.x(d.values.x)+_this.x.rangeBand()/d.subcats.length*position}}).attr("y",function(d){if(d.arrange!=="stacked"){return _this.y(d.values.y)}else{return _this.y(d.values.start)}}).attr("width",function(d){if(!d.arrange||d.arrange==="stacked"){return _this.x.rangeBand()}else if(d.arrange==="nested"){var position=d.subcats.indexOf(d.key);return position?_this.x.rangeBand()/(d.subcats.length*.75)/position:_this.x.rangeBand()}else{return _this.x.rangeBand()/d.subcats.length}}).attr("height",function(d){return _this.y(0)-_this.y(d.values.y)})}else if(config.y.type==="ordinal"){oldBarsTrans.attr("x",this.x(0)).attr("width",0);oldBarGroupsTrans.remove();nu_bar_groups=bar_groups.enter().append("g").attr("class",function(d){return"bar-group "+d.key});nu_bar_groups.append("title");bars=bar_groups.selectAll("rect").data(function(d){return d.values instanceof Array?d.values.sort(function(a,b){return _this.colorScale.domain().indexOf(b.key)-_this.colorScale.domain().indexOf(a.key)}):[d]},function(d){return d.key});var _exitBars=config.transitions?bars.exit().transition():bars.exit();_exitBars.attr("x",this.x(0)).attr("width",0).remove();bars.enter().append("rect").attr("class",function(d){return"wc-data-mark bar "+d.key}).style("clip-path","url(#"+chart.id+")").attr("x",this.x(0)).attr("width",0).append("title");bars.attr("shape-rendering","crispEdges").attr("stroke",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])});bars.each(function(d){var mark=d3.select(this.parentNode.parentNode).datum();d.arrange=mark.split&&mark.arrange?mark.arrange:mark.split?"grouped":null;d.subcats=config.legend.order?config.legend.order.slice().reverse():mark.values&&mark.values[mark.split]?mark.values[mark.split]:d3.set(rawData.map(function(m){return m[mark.split]})).values();d.tooltip=mark.tooltip;d3.select(this).attr(mark.attributes)});var _xformat=config.marks.map(function(m){return m.summarizeX==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.x.format);var _yformat=config.marks.map(function(m){return m.summarizeY==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.y.format);bars.select("title").text(function(d){var tt=d.tooltip||"";return tt.replace(/\$x/g,_xformat(d.values.x)).replace(/\$y/g,_yformat(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});var _barsTrans=config.transitions?bars.transition():bars;_barsTrans.attr("x",function(d){if(d.arrange==="stacked"||!d.arrange){return d.values.start!==undefined?_this.x(d.values.start):_this.x(0)}else{return _this.x(0)}}).attr("y",function(d){if(d.arrange==="nested"){var position=d.subcats.indexOf(d.key);var offset=position?_this.y.rangeBand()/(d.subcats.length*.75)/position:_this.y.rangeBand();return _this.y(d.values.y)+(_this.y.rangeBand()-offset)/2}else if(d.arrange==="grouped"){var _position2=d.subcats.indexOf(d.key);return _this.y(d.values.y)+_this.y.rangeBand()/d.subcats.length*_position2}else{return _this.y(d.values.y)}}).attr("width",function(d){return _this.x(d.values.x)-_this.x(0)}).attr("height",function(d){if(config.y.type==="quantile"){return 20}else if(d.arrange==="nested"){var position=d.subcats.indexOf(d.key);return position?_this.y.rangeBand()/(d.subcats.length*.75)/position:_this.y.rangeBand()}else if(d.arrange==="grouped"){return _this.y.rangeBand()/d.subcats.length}else{return _this.y.rangeBand()}})}else if(["linear","log"].indexOf(config.x.type)>-1&&config.x.bin){oldBarsTrans.attr("y",this.y(0)).attr("height",0);oldBarGroupsTrans.remove();nu_bar_groups=bar_groups.enter().append("g").attr("class",function(d){return"bar-group "+d.key});nu_bar_groups.append("title");bars=bar_groups.selectAll("rect").data(function(d){return d.values instanceof Array?d.values:[d]},function(d){return d.key});var _exitBars2=config.transitions?bars.exit().transition():bars.exit();_exitBars2.attr("y",this.y(0)).attr("height",0).remove();bars.enter().append("rect").attr("class",function(d){return"wc-data-mark bar "+d.key}).style("clip-path","url(#"+chart.id+")").attr("y",this.y(0)).attr("height",0).append("title");bars.attr("shape-rendering","crispEdges").attr("stroke",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])});bars.each(function(d){var mark=d3.select(this.parentNode.parentNode).datum();d.arrange=mark.split?mark.arrange:null;d.subcats=config.legend.order?config.legend.order.slice().reverse():mark.values&&mark.values[mark.split]?mark.values[mark.split]:d3.set(rawData.map(function(m){return m[mark.split]})).values();d3.select(this).attr(mark.attributes);var parent=d3.select(this.parentNode).datum();var rangeSet=parent.key.split(",").map(function(m){return+m});d.rangeLow=d3.min(rangeSet);d.rangeHigh=d3.max(rangeSet);d.tooltip=mark.tooltip});var _xformat2=config.marks.map(function(m){return m.summarizeX==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.x.format);var _yformat2=config.marks.map(function(m){return m.summarizeY==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.y.format);bars.select("title").text(function(d){var tt=d.tooltip||"";return tt.replace(/\$x/g,_xformat2(d.values.x)).replace(/\$y/g,_yformat2(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});var _barsTrans2=config.transitions?bars.transition():bars;_barsTrans2.attr("x",function(d){return _this.x(d.rangeLow)}).attr("y",function(d){if(d.arrange!=="stacked"){return _this.y(d.values.y)}else{return _this.y(d.values.start)}}).attr("width",function(d){return _this.x(d.rangeHigh)-_this.x(d.rangeLow)}).attr("height",function(d){return _this.y(0)-_this.y(d.values.y)})}else if(["linear","log"].indexOf(config.y.type)>-1&&config.y.type==="linear"&&config.y.bin){oldBarsTrans.attr("x",this.x(0)).attr("width",0);oldBarGroupsTrans.remove();nu_bar_groups=bar_groups.enter().append("g").attr("class",function(d){return"bar-group "+d.key});nu_bar_groups.append("title");bars=bar_groups.selectAll("rect").data(function(d){return d.values instanceof Array?d.values:[d]},function(d){return d.key});var _exitBars3=config.transitions?bars.exit().transition():bars.exit();_exitBars3.attr("x",this.x(0)).attr("width",0).remove();bars.enter().append("rect").attr("class",function(d){return"wc-data-mark bar "+d.key}).style("clip-path","url(#"+chart.id+")").attr("x",this.x(0)).attr("width",0).append("title");bars.attr("shape-rendering","crispEdges").attr("stroke",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])});bars.each(function(d){var mark=d3.select(this.parentNode.parentNode).datum();d.arrange=mark.split?mark.arrange:null;d.subcats=config.legend.order?config.legend.order.slice().reverse():mark.values&&mark.values[mark.split]?mark.values[mark.split]:d3.set(rawData.map(function(m){return m[mark.split]})).values();var parent=d3.select(this.parentNode).datum();var rangeSet=parent.key.split(",").map(function(m){return+m});d.rangeLow=d3.min(rangeSet);d.rangeHigh=d3.max(rangeSet);d.tooltip=mark.tooltip});var _xformat3=config.marks.map(function(m){return m.summarizeX==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.x.format);var _yformat3=config.marks.map(function(m){return m.summarizeY==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.y.format);bars.select("title").text(function(d){var tt=d.tooltip||"";return tt.replace(/\$x/g,_xformat3(d.values.x)).replace(/\$y/g,_yformat3(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});var _barsTrans3=config.transitions?bars.transition():bars;_barsTrans3.attr("x",function(d){if(d.arrange==="stacked"){return _this.x(d.values.start)}else{return _this.x(0)}}).attr("y",function(d){return _this.y(d.rangeHigh)}).attr("width",function(d){return _this.x(d.values.x)}).attr("height",function(d){return _this.y(d.rangeLow)-_this.y(d.rangeHigh)})}else{oldBarsTrans.attr("y",this.y(0)).attr("height",0);oldBarGroupsTrans.remove();bar_supergroups.remove()}bar_supergroups.each(function(d){d.supergroup=d3.select(this);d.groups=d.supergroup.selectAll(".bar-group")})}function drawLines(marks){var _this=this;var chart=this;var config=this.config;var line=d3.svg.line().interpolate(config.interpolate).x(function(d){return config.x.type==="linear"||config.x.type=="log"?_this.x(+d.values.x):config.x.type==="time"?_this.x(new Date(d.values.x)):_this.x(d.values.x)+_this.x.rangeBand()/2}).y(function(d){return config.y.type==="linear"||config.y.type=="log"?_this.y(+d.values.y):config.y.type==="time"?_this.y(new Date(d.values.y)):_this.y(d.values.y)+_this.y.rangeBand()/2});var line_supergroups=this.svg.selectAll(".line-supergroup").data(marks,function(d,i){return i+"-"+d.per.join("-")});line_supergroups.enter().append("g").attr("class",function(d){return"supergroup line-supergroup "+d.id});line_supergroups.exit().remove();var line_grps=line_supergroups.selectAll(".line").data(function(d){return d.data},function(d){return d.key});line_grps.exit().remove();var nu_line_grps=line_grps.enter().append("g").attr("class",function(d){return d.key+" line"});nu_line_grps.append("path");nu_line_grps.append("title");var linePaths=line_grps.select("path").attr("class","wc-data-mark").style("clip-path","url(#"+chart.id+")").datum(function(d){return d.values}).attr("stroke",function(d){return _this.colorScale(d[0].values.raw[0][config.color_by])}).attr("stroke-width",config.stroke_width?config.stroke_width:config.flex_stroke_width).attr("stroke-linecap","round").attr("fill","none");var linePathsTrans=config.transitions?linePaths.transition():linePaths;linePathsTrans.attr("d",line);line_grps.each(function(d){var mark=d3.select(this.parentNode).datum();d.tooltip=mark.tooltip;d3.select(this).select("path").attr(mark.attributes)});line_grps.select("title").text(function(d){var tt=d.tooltip||"";var xformat=config.x.summary==="percent"?d3.format("0%"):d3.format(config.x.format);var yformat=config.y.summary==="percent"?d3.format("0%"):d3.format(config.y.format);return tt.replace(/\$x/g,xformat(d.values.x)).replace(/\$y/g,yformat(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values[0].values.raw[0][orig]})});line_supergroups.each(function(d){d.supergroup=d3.select(this);d.groups=d.supergroup.selectAll("g.line");d.paths=d.groups.select("path")});return line_grps}function drawPoints(marks){var _this=this;var chart=this;var config=this.config;var point_supergroups=this.svg.selectAll(".point-supergroup").data(marks,function(d,i){return i+"-"+d.per.join("-")});point_supergroups.enter().append("g").attr("class",function(d){return"supergroup point-supergroup "+d.id});point_supergroups.exit().remove();var points=point_supergroups.selectAll(".point").data(function(d){return d.data},function(d){return d.key});var oldPoints=points.exit();var oldPointsTrans=config.transitions?oldPoints.selectAll("circle").transition():oldPoints.selectAll("circle");oldPointsTrans.attr("r",0);var oldPointGroupTrans=config.transitions?oldPoints.transition():oldPoints;oldPointGroupTrans.remove();var nupoints=points.enter().append("g").attr("class",function(d){return d.key+" point"});nupoints.append("circle").attr("class","wc-data-mark").attr("r",0);nupoints.append("title");points.select("circle").style("clip-path","url(#"+chart.id+")").attr("fill-opacity",config.fill_opacity||config.fill_opacity===0?config.fill_opacity:.6).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).attr("stroke",function(d){return _this.colorScale(d.values.raw[0][config.color_by])});points.each(function(d){var mark=d3.select(this.parentNode).datum();d.mark=mark;d3.select(this).select("circle").attr(mark.attributes)});var pointsTrans=config.transitions?points.select("circle").transition():points.select("circle");pointsTrans.attr("r",function(d){return d.mark.radius||config.flex_point_size}).attr("cx",function(d){var x_pos=_this.x(d.values.x)||0;return config.x.type==="ordinal"?x_pos+_this.x.rangeBand()/2:x_pos}).attr("cy",function(d){var y_pos=_this.y(d.values.y)||0;return config.y.type==="ordinal"?y_pos+_this.y.rangeBand()/2:y_pos});points.select("title").text(function(d){var tt=d.mark.tooltip||"";var xformat=config.x.summary==="percent"?d3.format("0%"):config.x.type==="time"?d3.time.format(config.x.format):d3.format(config.x.format);var yformat=config.y.summary==="percent"?d3.format("0%"):config.y.type==="time"?d3.time.format(config.y.format):d3.format(config.y.format);return tt.replace(/\$x/g,config.x.type==="time"?xformat(new Date(d.values.x)):xformat(d.values.x)).replace(/\$y/g,config.y.type==="time"?yformat(new Date(d.values.y)):yformat(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});point_supergroups.each(function(d){d.supergroup=d3.select(this);d.groups=d.supergroup.selectAll("g.point");d.circles=d.groups.select("circle")});return points}function drawText(marks){var _this=this;var chart=this;var config=this.config;var textSupergroups=this.svg.selectAll(".text-supergroup").data(marks,function(d,i){return i+"-"+d.per.join("-")});textSupergroups.enter().append("g").attr("class",function(d){return"supergroup text-supergroup "+d.id});textSupergroups.exit().remove();var texts=textSupergroups.selectAll(".text").data(function(d){return d.data},function(d){return d.key});var oldTexts=texts.exit();var oldTextGroupTrans=config.transitions?oldTexts.transition():oldTexts;oldTextGroupTrans.remove();var nutexts=texts.enter().append("g").attr("class",function(d){return d.key+" text"});nutexts.append("text").attr("class","wc-data-mark");function attachMarks(d){d.mark=d3.select(this.parentNode).datum();d3.select(this).select("text").attr(d.mark.attributes)}texts.each(attachMarks);texts.select("text").style("clip-path","url(#"+chart.id+")").text(function(d){var tt=d.mark.text||"";var xformat=config.x.summary==="percent"?d3.format("0%"):config.x.type==="time"?d3.time.format(config.x.format):d3.format(config.x.format);var yformat=config.y.summary==="percent"?d3.format("0%"):config.y.type==="time"?d3.time.format(config.y.format):d3.format(config.y.format);return tt.replace(/\$x/g,config.x.type==="time"?xformat(new Date(d.values.x)):xformat(d.values.x)).replace(/\$y/g,config.y.type==="time"?yformat(new Date(d.values.y)):yformat(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});var textsTrans=config.transitions?texts.select("text").transition():texts.select("text");textsTrans.attr("x",function(d){var xPos=_this.x(d.values.x)||0;return config.x.type==="ordinal"?xPos+_this.x.rangeBand()/2:xPos}).attr("y",function(d){var yPos=_this.y(d.values.y)||0;return config.y.type==="ordinal"?yPos+_this.y.rangeBand()/2:yPos});textSupergroups.each(function(d){d.supergroup=d3.select(this);d.groups=d.supergroup.selectAll("g.text");d.texts=d.groups.select("text")});return texts}function destroy(){var destroyControls=arguments.length>0&&arguments[0]!==undefined?arguments[0]:true;this.events.onDestroy.call(this);var context=this;d3.select(window).on("resize."+context.element+context.id,null);if(destroyControls&&this.controls){this.controls.destroy()}this.wrap.remove()}var chartProto={raw_data:[],config:{}};var chart=Object.create(chartProto,{checkRequired:{value:checkRequired},consolidateData:{value:consolidateData},draw:{value:draw},destroy:{value:destroy},drawArea:{value:drawArea},drawBars:{value:drawBars},drawGridlines:{value:drawGridLines},drawLines:{value:drawLines},drawPoints:{value:drawPoints},drawText:{value:drawText},init:{value:init},layout:{value:layout},makeLegend:{value:makeLegend},resize:{value:resize},setColorScale:{value:setColorScale},setDefaults:{value:setDefaults},setMargins:{value:setMargins},textSize:{value:textSize},transformData:{value:transformData},updateDataMarks:{value:updateDataMarks},xScaleAxis:{value:xScaleAxis},yScaleAxis:{value:yScaleAxis}});var chartCount=0;function createChart(){var element=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"body";var config=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var controls=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;var thisChart=Object.create(chart);thisChart.div=element;thisChart.config=Object.create(config);thisChart.controls=controls;thisChart.raw_data=[];thisChart.filters=[];thisChart.marks=[];thisChart.wrap=d3.select(thisChart.div).append("div").datum(thisChart);thisChart.events={onInit:function onInit(){},onLayout:function onLayout(){},onPreprocess:function onPreprocess(){},onDatatransform:function onDatatransform(){},onDraw:function onDraw(){},onResize:function onResize(){},onDestroy:function onDestroy(){}};thisChart.on=function(event,callback){var possible_events=["init","layout","preprocess","datatransform","draw","resize","destroy"];if(possible_events.indexOf(event)<0){return}if(callback){thisChart.events["on"+event.charAt(0).toUpperCase()+event.slice(1)]=callback}};chartCount++;thisChart.id=chartCount;return thisChart}function changeOption(option,value,callback,draw){var _this=this;this.targets.forEach(function(target){if(option instanceof Array){option.forEach(function(o){return _this.stringAccessor(target.config,o,value)})}else{_this.stringAccessor(target.config,option,value)}if(callback){callback()}if(draw)target.draw()})}function checkRequired$1(dataset){if(!dataset[0]||!this.config.inputs)return;var colNames=d3.keys(dataset[0]);this.config.inputs.forEach(function(input,i){if(input.type==="subsetter"&&colNames.indexOf(input.value_col)===-1)throw new Error('Error in settings object: the value "'+input.value_col+'" does not match any column in the provided dataset.');input.draw=input.draw===undefined?true:input.draw})}function controlUpdate(){var _this=this;if(this.config.inputs&&this.config.inputs.length&&this.config.inputs[0])this.config.inputs.forEach(function(input){return _this.makeControlItem(input)})}function destroy$1(){this.wrap.remove()}function init$1(data){this.data=data;if(!this.config.builder)this.checkRequired(this.data);this.layout()}function layout$1(){this.wrap.selectAll("*").remove();this.ready=true;this.controlUpdate()}function makeControlItem(control){var control_wrap=this.wrap.append("div").attr("class","control-group").classed("inline",control.inline).datum(control);var ctrl_label=control_wrap.append("span").attr("class","wc-control-label").text(control.label);if(control.required)ctrl_label.append("span").attr("class","label label-required").text("Required");control_wrap.append("span").attr("class","span-description").text(control.description);if(control.type==="text"){this.makeTextControl(control,control_wrap)}else if(control.type==="number"){this.makeNumberControl(control,control_wrap)}else if(control.type==="list"){this.makeListControl(control,control_wrap)}else if(control.type==="dropdown"){this.makeDropdownControl(control,control_wrap)}else if(control.type==="btngroup"){this.makeBtnGroupControl(control,control_wrap)}else if(control.type==="checkbox"){this.makeCheckboxControl(control,control_wrap)}else if(control.type==="radio"){this.makeRadioControl(control,control_wrap)}else if(control.type==="subsetter"){this.makeSubsetterControl(control,control_wrap)}else{throw new Error('Each control must have a type! Choose from: "text", "number", "list", "dropdown", "btngroup", "checkbox", "radio", or "subsetter".')}}function makeBtnGroupControl(control,control_wrap){var _this=this;var option_data=control.values?control.values:d3.keys(this.data[0]);var btn_wrap=control_wrap.append("div").attr("class","btn-group");var changers=btn_wrap.selectAll("button").data(option_data).enter().append("button").attr("class","btn btn-default btn-sm").text(function(d){return d}).classed("btn-primary",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)===d});changers.on("click",function(d){changers.each(function(e){d3.select(this).classed("btn-primary",e===d)});_this.changeOption(control.option,d,control.callback,control.draw)})}function makeCheckboxControl(control,control_wrap){var _this=this;var changer=control_wrap.append("input").attr("type","checkbox").attr("class","changer").datum(control).property("checked",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)});changer.on("change",function(d){var value=changer.property("checked");_this.changeOption(d.option,value,control.callback,control.draw)})}function makeDropdownControl(control,control_wrap){var _this=this;var mainOption=control.option||control.options[0];var changer=control_wrap.append("select").attr("class","changer").attr("multiple",control.multiple?true:null).datum(control);var opt_values=control.values&&control.values instanceof Array?control.values:control.values?d3.set(this.data.map(function(m){return m[_this.targets[0].config[control.values]]})).values():d3.keys(this.data[0]);if(!control.require||control.none){opt_values.unshift("None")}var options=changer.selectAll("option").data(opt_values).enter().append("option").text(function(d){return d}).property("selected",function(d){return _this.stringAccessor(_this.targets[0].config,mainOption)===d});changer.on("change",function(d){var value=changer.property("value")==="None"?null:changer.property("value");if(control.multiple){value=options.filter(function(f){return d3.select(this).property("selected")})[0].map(function(m){return d3.select(m).property("value")}).filter(function(f){return f!=="None"})}if(control.options){_this.changeOption(control.options,value,control.callback,control.draw)}else{_this.changeOption(control.option,value,control.callback,control.draw)}});return changer}function makeListControl(control,control_wrap){var _this=this;var changer=control_wrap.append("input").attr("type","text").attr("class","changer").datum(control).property("value",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)});changer.on("change",function(d){var value=changer.property("value")?changer.property("value").split(",").map(function(m){return m.trim()}):null;_this.changeOption(control.option,value,control.callback,control.draw)})}function makeNumberControl(control,control_wrap){var _this=this;var changer=control_wrap.append("input").attr("type","number").attr("min",control.min!==undefined?control.min:0).attr("max",control.max).attr("step",control.step||1).attr("class","changer").datum(control).property("value",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)});changer.on("change",function(d){var value=+changer.property("value");_this.changeOption(control.option,value,control.callback,control.draw)})}function makeRadioControl(control,control_wrap){var _this=this;var changers=control_wrap.selectAll("label").data(control.values||d3.keys(this.data[0])).enter().append("label").attr("class","radio").text(function(d,i){return control.relabels?control.relabels[i]:d}).append("input").attr("type","radio").attr("class","changer").attr("name",control.option.replace(".","-")+"-"+this.targets[0].id).property("value",function(d){return d}).property("checked",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)===d});changers.on("change",function(d){var value=null;changers.each(function(c){if(d3.select(this).property("checked")){value=d3.select(this).property("value")==="none"?null:c}});_this.changeOption(control.option,value,control.callback,control.draw)})}function makeSubsetterControl(control,control_wrap){var targets=this.targets;var changer=control_wrap.append("select").classed("changer",true).attr("multiple",control.multiple?true:null).datum(control);var option_data=control.values?control.values:d3.set(this.data.map(function(m){return m[control.value_col]}).filter(function(f){return f})).values().sort(naturalSorter);control.start=control.start?control.start:control.loose?option_data[0]:null;if(!control.multiple&&!control.start){option_data.unshift("All");control.all=true}else{control.all=false}control.loose=!control.loose&&control.start?true:control.loose;var options=changer.selectAll("option").data(option_data).enter().append("option").text(function(d){return d}).property("selected",function(d){return d===control.start});targets.forEach(function(e){var match=e.filters.slice().map(function(m){return m.col===control.value_col}).indexOf(true);if(match>-1){e.filters[match]={col:control.value_col,val:control.start?control.start:!control.multiple?"All":option_data,index:0,choices:option_data,loose:control.loose,all:control.all}}else{e.filters.push({col:control.value_col,val:control.start?control.start:!control.multiple?"All":option_data,index:0,choices:option_data,loose:control.loose,all:control.all})}});function setSubsetter(target,obj){var match=-1;target.filters.forEach(function(e,i){if(e.col===obj.col){match=i}});if(match>-1){target.filters[match]=obj}}changer.on("change",function(d){if(control.multiple){var values=options.filter(function(f){return d3.select(this).property("selected")})[0].map(function(m){return d3.select(m).property("text")});var new_filter={col:control.value_col,val:values,index:null,choices:option_data,loose:control.loose,all:control.all};targets.forEach(function(e){setSubsetter(e,new_filter);if(control.callback){control.callback()}if(control.draw)e.draw()})}else{var value=d3.select(this).select("option:checked").property("text");var index=d3.select(this).select("option:checked").property("index");var _new_filter={col:control.value_col,val:value,index:index,choices:option_data,loose:control.loose,all:control.all};targets.forEach(function(e){setSubsetter(e,_new_filter);if(control.callback){control.callback()}e.draw()})}})}function makeTextControl(control,control_wrap){var _this=this +;var changer=control_wrap.append("input").attr("type","text").attr("class","changer").datum(control).property("value",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)});changer.on("change",function(d){var value=changer.property("value");_this.changeOption(control.option,value,control.callback,control.draw)})}function stringAccessor(o,s,v){s=s.replace(/\[(\w+)\]/g,".$1");s=s.replace(/^\./,"");var a=s.split(".");for(var i=0,n=a.length;i0&&arguments[0]!==undefined?arguments[0]:"body";var config=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var thisControls=Object.create(controls);thisControls.div=element;thisControls.config=Object.create(config);thisControls.config.inputs=thisControls.config.inputs||[];thisControls.targets=[];if(config.location==="bottom"){thisControls.wrap=d3.select(element).append("div").attr("class","wc-controls")}else{thisControls.wrap=d3.select(element).insert("div",":first-child").attr("class","wc-controls")}thisControls.wrap.datum(thisControls);return thisControls}function applyFilters(){var _this=this;if(this.filters&&this.filters.some(function(filter){return typeof filter.val==="string"&&!(filter.all===true&&filter.index===0)||Array.isArray(filter.val)&&filter.val.length-1:filter.val===d[filter.col]})})}else this.data.filtered=this.data.raw}function updateDataObject(){this.data.raw=this.data.passed;this.data.filtered=this.data.passed;this.config.activePage=0;this.config.startIndex=this.config.activePage*this.config.nRowsPerPage;this.config.endIndex=this.config.startIndex+this.config.nRowsPerPage}function applySearchTerm(data){var _this=this;if(this.searchable.searchTerm){this.data.searched=this.data.filtered.filter(function(d){var match=false;Object.keys(d).filter(function(key){return _this.config.cols.indexOf(key)>-1}).forEach(function(var_name){if(match===false){var cellText=""+d[var_name];match=cellText.toLowerCase().indexOf(_this.searchable.searchTerm)>-1}});return match});this.data.processing=this.data.searched}else{delete this.data.searched;this.data.processing=this.data.filtered}}if(Array.prototype.equals)console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code.");Array.prototype.equals=function(array){if(!array)return false;if(this.length!=array.length)return false;for(var i=0,l=this.length;i=Math.max(widths.top,widths.bottom)&&this.config.layout==="vertical"){this.config.layout="horizontal";this.wrap.style("display","table").selectAll(".table-top,.table-bottom").style("display","block").selectAll(".interactivity").style({display:"inline-block",float:function float(){return d3.select(this).classed("searchable-container")||d3.select(this).classed("pagination-container")?"right":null},clear:null})}}function draw$1(passed_data){var _this=this;var table=this;var config=this.config;this.data.passed=passed_data;this.events.onPreprocess.call(this);if(!passed_data)applyFilters.call(this);else updateDataObject.call(this);checkFilters.call(this);applySearchTerm.call(this);this.searchable.wrap.select(".nNrecords").text(this.data.processing.length===this.data.raw.length?this.data.raw.length+" records displayed":this.data.processing.length+"/"+this.data.raw.length+" records displayed");updateTableHeaders.call(this);this.tbody.selectAll("tr").remove();if(this.data.processing.length===0){this.tbody.append("tr").classed("no-data",true).append("td").attr("colspan",this.config.cols.length).text("No data selected.");this.data.current=this.data.processing;this.table.datum(this.table.current);if(this.config.exportable)this.config.exports.forEach(function(fmt){_this.exportable.exports[fmt].call(_this,_this.data.processing)});if(this.config.pagination)this.pagination.addPagination.call(this,this.data.processing)}else{if(this.config.sortable){this.thead.selectAll("th").on("click",function(header){table.sortable.onClick.call(table,this,header)});if(this.sortable.order.length)this.sortable.sortData.call(this,this.data.processing)}this.data.current=this.data.processing;this.table.datum(this.data.current);if(this.config.exportable)this.config.exports.forEach(function(fmt){_this.exportable.exports[fmt].call(_this,_this.data.processing)});if(this.config.pagination){this.pagination.addPagination.call(this,this.data.processing);this.data.processing=this.data.processing.filter(function(d,i){return _this.config.startIndex<=i&&i<_this.config.endIndex})}drawTableBody.call(this)}if(this.config.dynamicPositioning){dynamicLayout.call(this)}this.events.onDraw.call(this)}function layout$2(){var context=this;this.searchable.wrap=this.wrap.select(".table-top").append("div").classed("interactivity searchable-container",true).classed("hidden",!this.config.searchable);this.searchable.wrap.append("div").classed("search",true);this.searchable.wrap.select(".search").append("input").classed("search-box",true).attr("placeholder","Search").on("input",function(){context.searchable.searchTerm=this.value.toLowerCase()||null;context.config.activePage=0;context.config.startIndex=context.config.activePage*context.config.nRowsPerPage;context.config.endIndex=context.config.startIndex+context.config.nRowsPerPage;context.draw()});this.searchable.wrap.select(".search").append("span").classed("nNrecords",true)}function searchable(){return{layout:layout$2}}function layout$3(){var _this=this;this.exportable.wrap=this.wrap.select(".table-bottom").append("div").classed("interactivity exportable-container",true).classed("hidden",!this.config.exportable);this.exportable.wrap.append("span").text("Export:");if(this.config.exports&&this.config.exports.length)this.config.exports.forEach(function(fmt){_this.exportable.wrap.append("a").classed("wc-button export",true).attr({id:fmt}).style(!_this.test&&navigator.msSaveBlob?{cursor:"pointer","text-decoration":"underline",color:"blue"}:null).text(fmt.toUpperCase())})}function download(fileType,data){var blob=new Blob(data,{type:fileType==="csv"?"text/csv;charset=utf-8;":fileType==="xlsx"?"application/octet-stream":console.warn("File type not supported: "+fileType)});var fileName="webchartsTableExport_"+d3.time.format("%Y-%m-%dT%H-%M-%S")(new Date)+"."+fileType;var link=this.wrap.select(".export#"+fileType);if(navigator.msSaveBlob)navigator.msSaveBlob(blob,fileName);else if(link.node().download!==undefined){var url=URL.createObjectURL(blob);link.node().setAttribute("href",url);link.node().setAttribute("download",fileName)}}function csv(data){var _this=this;this.wrap.select(".export#csv").on("click",function(){var CSVarray=[];var headers=_this.config.headers.map(function(header){return'"'+header.replace(/"/g,'""')+'"'});CSVarray.push(headers);data.forEach(function(d,i){var row=_this.config.cols.map(function(col){var value=d[col];if(typeof value==="string")value=value.replace(/"/g,'""');return'"'+value+'"'});CSVarray.push(row)});download.call(_this,"csv",[CSVarray.join("\n")])})}function xlsx(data){var _this=this;this.wrap.select(".export#xlsx").on("click",function(){var sheetName="Selected Data";var options={bookType:"xlsx",bookSST:true,type:"binary"};var arrayOfArrays=data.map(function(d){return Object.keys(d).filter(function(key){return _this.config.cols.indexOf(key)>-1}).map(function(key){return d[key]})});var workbook={SheetNames:[sheetName],Sheets:{}};var cols=[];workbook.Sheets[sheetName]=XLSX.utils.aoa_to_sheet([_this.config.headers].concat(arrayOfArrays));workbook.Sheets[sheetName]["!autofilter"]={ref:"A1:"+String.fromCharCode(64+_this.config.cols.length)+(data.length+1)};_this.table.selectAll("thead tr th").each(function(){cols.push({wpx:this.offsetWidth})});workbook.Sheets[sheetName]["!cols"]=cols;var xlsx=XLSX.write(workbook,options);var s2ab=function s2ab(s){var buffer=new ArrayBuffer(s.length),view=new Uint8Array(buffer);for(var i=0;i!==s.length;++i){view[i]=s.charCodeAt(i)&255}return buffer};download.call(_this,"xlsx",[s2ab(xlsx)])})}var exports$1={csv:csv,xlsx:xlsx};function exportable(){return{layout:layout$3,exports:exports$1}}function layout$4(){this.sortable.wrap=this.wrap.select(".table-top").append("div").classed("interactivity sortable-container",true).classed("hidden",!this.config.sortable);this.sortable.wrap.append("div").classed("instruction",true).text("Click column headers to sort.")}function onClick(th,header){var context=this,selection=d3.select(th),col=this.config.cols[this.config.headers.indexOf(header)];var sortItem=this.sortable.order.filter(function(item){return item.col===col})[0];if(!sortItem){sortItem={col:col,direction:"ascending",wrap:this.sortable.wrap.append("div").datum({key:col}).classed("wc-button sort-box",true).text(header)};sortItem.wrap.append("span").classed("sort-direction",true).html("↓");sortItem.wrap.append("span").classed("remove-sort",true).html("❌");this.sortable.order.push(sortItem)}else{sortItem.direction=sortItem.direction==="ascending"?"descending":"ascending";sortItem.wrap.select("span.sort-direction").html(sortItem.direction==="ascending"?"↓":"↑")}this.sortable.wrap.select(".instruction").classed("hidden",true);this.sortable.order.forEach(function(item,i){item.wrap.on("click",function(d){d3.select(this).remove();context.sortable.order.splice(context.sortable.order.map(function(d){return d.col}).indexOf(d.key),1);context.sortable.wrap.select(".instruction").classed("hidden",context.sortable.order.length);context.draw()})});this.draw()}function sortData(data){var _this=this;data=data.sort(function(a,b){var order=0;_this.sortable.order.forEach(function(item){var aCell=a[item.col],bCell=b[item.col];if(order===0){if(item.direction==="ascending"&&aCellbCell)order=-1;else if(item.direction==="ascending"&&aCell>bCell||item.direction==="descending"&&aCell=_this.config.nPageLinksDisplayed:_this.config.activePage>=_this.config.nPages-_this.config.nPageLinksDisplayed?i<_this.config.nPages-_this.config.nPageLinksDisplayed:i<_this.config.activePage-(Math.ceil(_this.config.nPageLinksDisplayed/2)-1)||_this.config.activePage+_this.config.nPageLinksDisplayed/2=this.config.nPages)next=this.config.nPages-1;this.pagination.wrap.insert("span",":first-child").classed("dot-dot-dot",true).text("...").classed("hidden",this.config.activePage=Math.max(this.config.nPageLinksDisplayed,this.config.nPages-this.config.nPageLinksDisplayed)||this.config.nPages<=this.config.nPageLinksDisplayed);this.pagination.next=this.pagination.wrap.append("a").classed("wc-button arrow-link wc-right",true).classed("hidden",this.config.activePage==this.config.nPages-1||this.config.nPages==0).attr({rel:next}).text(">");this.pagination.doubleNext=this.pagination.wrap.append("a").classed("wc-button arrow-link wc-right double",true).classed("hidden",this.config.activePage==this.config.nPages-1||this.config.nPages==0).attr({rel:this.config.nPages-1}).text(">>");this.pagination.arrows=this.pagination.wrap.selectAll("a.arrow-link");this.pagination.doubleArrows=this.pagination.wrap.selectAll("a.double-arrow-link")}function addPagination(data){var context=this;this.config.nRows=data.length;this.config.nPages=Math.ceil(this.config.nRows/this.config.nRowsPerPage);this.config.paginationHidden=this.config.nPages===1;this.pagination.wrap.classed("hidden",this.config.paginationHidden);addLinks.call(this);this.pagination.links.on("click",function(){context.config.activePage=+d3.select(this).attr("rel");updatePagination.call(context)});addArrows.call(this);this.pagination.arrows.on("click",function(){if(context.config.activePage!==+d3.select(this).attr("rel")){context.config.activePage=+d3.select(this).attr("rel");context.pagination.prev.attr("rel",context.config.activePage>0?context.config.activePage-1:0);context.pagination.next.attr("rel",context.config.activePage1&&arguments[1]!==undefined?arguments[1]:false;this.test=test;if(d3.select(this.div).select(".loader").empty()){d3.select(this.div).insert("div",":first-child").attr("class","loader").selectAll(".blockG").data(d3.range(8)).enter().append("div").attr("class",function(d){return"blockG rotate"+(d+1)})}this.setDefaults.call(this,data[0]);this.wrap.classed("wc-chart",true).classed("wc-table",this.config.applyCSS);this.data={raw:data};this.searchable=searchable.call(this);this.sortable=sortable.call(this);this.pagination=pagination.call(this);this.exportable=exportable.call(this);var startup=function startup(data){if(_this.controls){_this.controls.targets.push(_this);if(!_this.controls.ready){_this.controls.init(_this.data.raw)}else{_this.controls.layout()}}var visible=d3.select(_this.div).property("offsetWidth")>0||test;if(!visible){console.warn("The table cannot be initialized inside an element with 0 width. The table will be initialized as soon as the container element is given a width > 0.");var onVisible=setInterval(function(i){var visible_now=d3.select(_this.div).property("offsetWidth")>0;if(visible_now){_this.layout();_this.wrap.datum(_this);_this.draw();clearInterval(onVisible)}},500)}else{_this.layout();_this.wrap.datum(_this);_this.draw()}};this.events.onInit.call(this);if(this.data.raw.length){this.checkRequired(this.data.raw)}startup(data);return this}function layout$6(){d3.select(this.div).select(".loader").remove();this.wrap.append("div").classed("table-top",true);this.searchable.layout.call(this);this.sortable.layout.call(this);this.table=this.wrap.append("table").classed("table",this.config.bootstrap);this.thead=this.table.append("thead");this.thead.append("tr");this.tbody=this.table.append("tbody");this.wrap.append("div").classed("table-bottom",true);this.pagination.layout.call(this);this.exportable.layout.call(this);this.events.onLayout.call(this)}function destroy$2(){var destroyControls=arguments.length>0&&arguments[0]!==undefined?arguments[0]:false;this.events.onDestroy.call(this);if(destroyControls&&this.controls){this.controls.destroy()}this.wrap.remove()}function setDefault(setting){var _default_=arguments.length>1&&arguments[1]!==undefined?arguments[1]:true;this.config[setting]=this.config[setting]!==undefined?this.config[setting]:_default_}function setDefaults$1(firstItem){if(this.config.cols instanceof Array&&this.config.headers instanceof Array){if(this.config.cols.length===0)delete this.config.cols;if(this.config.headers.length===0||this.config.headers.length!==this.config.cols.length)delete this.config.headers}this.config.cols=this.config.cols||d3.keys(firstItem);this.config.headers=this.config.headers||this.config.cols;this.config.layout="horizontal";setDefault.call(this,"searchable");setDefault.call(this,"exportable");setDefault.call(this,"exports",["csv"]);setDefault.call(this,"sortable");setDefault.call(this,"pagination");setDefault.call(this,"nRowsPerPage",10);setDefault.call(this,"nPageLinksDisplayed",5);setDefault.call(this,"applyCSS");setDefault.call(this,"dynamicPositioning")}function transformData$1(processed_data){var _this=this;this.data.processed=this.transformData(this.wrap.datum);if(!data){return}this.config.cols=this.config.cols||d3.keys(data[0]);this.config.headers=this.config.headers||this.config.cols;if(this.config.keep){this.config.keep.forEach(function(e){if(_this.config.cols.indexOf(e)===-1){_this.config.cols.unshift(e)}})}var filtered=data;if(this.filters.length){this.filters.forEach(function(e){var is_array=e.val instanceof Array;filtered=filtered.filter(function(d){if(is_array){return e.val.indexOf(d[e.col])!==-1}else{return e.val!=="All"?d[e.col]===e.val:d}})})}var slimmed=d3.nest().key(function(d){if(_this.config.row_per){return _this.config.row_per.map(function(m){return d[m]}).join(" ")}else{return d}}).rollup(function(r){if(_this.config.dataManipulate){r=_this.config.dataManipulate(r)}var nuarr=r.map(function(m){var arr=[];for(var x in m){arr.push({col:x,text:m[x]})}arr.sort(function(a,b){return _this.config.cols.indexOf(a.col)-_this.config.cols.indexOf(b.col)});return{cells:arr,raw:m}});return nuarr}).entries(filtered);this.data.current=slimmed.length?slimmed:[{key:null,values:[]}];this.pagination.wrap.selectAll("*").remove();this.events.onDatatransform.call(this);if(config.row_per){var rev_order=config.row_per.slice(0).reverse();rev_order.forEach(function(e){tbodies.sort(function(a,b){return a.values[0].raw[e]-b.values[0].raw[e]})})}if(config.row_per){rows.filter(function(f,i){return i>0}).selectAll("td").filter(function(f){return config.row_per.indexOf(f.col)>-1}).text("")}return this.data.current}var table=Object.create(chart,{draw:{value:draw$1},init:{value:init$2},layout:{value:layout$6},setDefaults:{value:setDefaults$1},transformData:{value:transformData$1},destroy:{value:destroy$2}});function createTable(){var element=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"body";var config=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var controls=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;var thisTable=Object.create(table);thisTable.div=element;thisTable.config=Object.create(config);thisTable.controls=controls;thisTable.filters=[];thisTable.required_cols=[];thisTable.wrap=d3.select(thisTable.div).append("div").datum(thisTable);thisTable.events={onInit:function onInit(){},onLayout:function onLayout(){},onPreprocess:function onPreprocess(){},onDraw:function onDraw(){},onDestroy:function onDestroy(){}};thisTable.on=function(event,callback){var possible_events=["init","layout","preprocess","draw","destroy"];if(possible_events.indexOf(event)<0){return}if(callback){thisTable.events["on"+event.charAt(0).toUpperCase()+event.slice(1)]=callback}};return thisTable}function multiply(chart,data,split_by,order){var test=arguments.length>4&&arguments[4]!==undefined?arguments[4]:false;chart.wrap.classed("wc-layout wc-small-multiples",true).classed("wc-chart",false);chart.master_legend=chart.wrap.append("ul").attr("class","legend");chart.master_legend.append("span").classed("legend-title",true);chart.multiples=[];function goAhead(data){var split_vals=d3.set(data.map(function(m){return m[split_by]})).values().filter(function(f){return f});if(order){split_vals=split_vals.sort(function(a,b){return d3.ascending(order.indexOf(a),order.indexOf(b))})}split_vals.forEach(function(e){var mchart=createChart(chart.wrap.node(),chart.config,chart.controls);chart.multiples.push(mchart);mchart.parent=chart;mchart.events=chart.events;mchart.legend=chart.master_legend;mchart.filters.unshift({col:split_by,val:e,choices:split_vals});mchart.wrap.insert("span","svg").attr("class","wc-chart-title").text(e);mchart.init(data,test)})}goAhead(data)}function getValType(data,variable){var var_vals=d3.set(data.map(function(m){return m[variable]})).values();var vals_numbers=var_vals.filter(function(f){return+f||+f===0});if(var_vals.length===vals_numbers.length&&var_vals.length>4){return"continuous"}else{return"categorical"}}function lengthenRaw(data,columns){var my_data=[];data.forEach(function(e){columns.forEach(function(g){var obj=Object.create(e);obj.wc_category=g;obj.wc_value=e[g];my_data.push(obj)})});return my_data}var dataOps={getValType:getValType,lengthenRaw:lengthenRaw,naturalSorter:naturalSorter,summarize:summarize};var index={version:version,createChart:createChart,createControls:createControls,createTable:createTable,multiply:multiply,dataOps:dataOps};return index}); diff --git a/package-lock.json b/package-lock.json index 87982ca..900b5c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1414,6 +1414,7 @@ }, "inherits": { "version": "2.0.3", + "resolved": false, "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "invariant": { @@ -2190,7 +2191,7 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, @@ -2754,6 +2755,7 @@ }, "safe-buffer": { "version": "5.1.0", + "resolved": false, "integrity": "sha1-/kyEYDl/nqqqWOc75GJzQIpF4iM=" }, "safer-buffer": { diff --git a/package.json b/package.json index 8b32738..030ce0b 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "build": "npm audit fix && npm run bundle && npm run format && npm run minify", "bundle": "rollup -c", "bunfor": "npm run bundle && npm run format", - "format": "npm run format-src && npm run format-bundle && npm run minify", + "format": "npm run format-src && npm run format-bundle && npm run format-test", "format-src": "prettier --print-width=100 --tab-width=4 --single-quote --write src/**/*.js", "format-bundle": "prettier --print-width=100 --tab-width=4 --single-quote --write build/webcharts.js", "format-test": "prettier --print-width=100 --tab-width=4 --single-quote --write test/**/*.js", diff --git a/src/chart/draw/consolidateData.js b/src/chart/draw/consolidateData.js index 2d8589d..17caef4 100644 --- a/src/chart/draw/consolidateData.js +++ b/src/chart/draw/consolidateData.js @@ -34,24 +34,7 @@ export default function consolidateData(raw) { y_dom: [] }; - this.marks[i] = { - id: mark.id, - type: mark.type, - per: mark.per, - data: mark_info.data, - x_dom: mark_info.x_dom, - y_dom: mark_info.y_dom, - split: mark.split, - text: mark.text, - arrange: mark.arrange, - order: mark.order, - summarizeX: mark.summarizeX, - summarizeY: mark.summarizeY, - tooltip: mark.tooltip, - radius: mark.radius, - attributes: mark.attributes, - values: mark.values - }; + this.marks[i] = Object.assign({}, mark, mark_info); }); //Set domains given extents of summarized mark data. diff --git a/src/chart/draw/consolidateData/transformData/makeNest.js b/src/chart/draw/consolidateData/transformData/makeNest.js index d12da32..faa2d74 100644 --- a/src/chart/draw/consolidateData/transformData/makeNest.js +++ b/src/chart/draw/consolidateData/transformData/makeNest.js @@ -12,19 +12,19 @@ export default function makeNest(mark, entries, sublevel) { (this.config.x.type === 'linear' && this.config.x.bin) || (this.config.y.type === 'linear' && this.config.y.bin) ) { - let xy = this.config.x.type === 'linear' && this.config.x.bin ? 'x' : 'y'; - let quant = scale + const xy = this.config.x.type === 'linear' && this.config.x.bin ? 'x' : 'y'; + mark.quant = scale .quantile() .domain( - this.config[xy].behavior !== 'flex' && this.config[xy].domain + this.config[xy].domain ? this.config[xy].domain : extent(entries.map(m => +m[this.config[xy].column])) ) .range(range(+this.config[xy].bin)); - entries.forEach(e => (e.wc_bin = quant(e[this.config[xy].column]))); + entries.forEach(e => (e.wc_bin = mark.quant(e[this.config[xy].column]))); - this_nest.key(d => quant.invertExtent(d.wc_bin)); + this_nest.key(d => mark.quant.invertExtent(d.wc_bin)); } else { this_nest.key(d => mark.per.map(m => d[m]).join(' ')); } diff --git a/test-page/histogram/index.js b/test-page/histogram/index.js index f51e70b..9d949da 100644 --- a/test-page/histogram/index.js +++ b/test-page/histogram/index.js @@ -5,7 +5,6 @@ const settings = { label: 'Sepal Length', bin: 15, format: '.1f', - domain: [3, 10], //behavior: 'flex' }, y: { @@ -20,10 +19,14 @@ const settings = { per: ['sepal length'], summarizeY: 'count', tooltip: '$y observations around $x', + attributes: { + 'fill-opacity': .75 + }, }, ], aspect: 3, gridlines: 'y', + x_domain: 'raw', }; const controls = new webCharts.createControls( @@ -35,18 +38,22 @@ const controls = new webCharts.createControls( value_col: 'species', label: 'Species', }, - //{ - // type: 'radio', - // option: 'x.domain.0', - // label: 'X-domain Lower Limit', - // values: ['minimum',0], - //}, - //{ - // type: 'radio', - // option: 'y.domain.0', - // label: 'Y-domain Lower Limit', - // values: ['minimum',0], - //}, + { + type: 'radio', + option: 'x_domain', + label: 'X-domain', + values: ['raw', 'filtered', 'custom'], + }, + { + type: 'number', + option: 'x.domain.0', + label: 'Lower Limit', + }, + { + type: 'number', + option: 'x.domain.1', + label: 'Upper Limit', + }, ], }, ); @@ -57,6 +64,96 @@ const chart = new webCharts.createChart( controls, ); +chart.on('layout', function() { + const context = this; + + this.controls.xDomain = this.controls.wrap.selectAll('.control-group') + .filter(function(d) { + return d.label === 'X-domain'; + }) + .selectAll('.changer') + .on('change', function(d) { + context.config.x_domain = d; + context.draw(); + }); + + this.controls.limits = this.controls.wrap.selectAll('.control-group') + .filter(function(d) { + return d.label.indexOf('Limit') > -1; + }) + .selectAll('.changer') + .on('change', function(d) { + context.config.x_domain = 'custom'; + context.controls.xDomain + .property('checked', function(di) { + return di === 'custom'; + }); + context.config.x.domain[+d.option.split('.').pop()] = +this.value; + context.draw(); + }); +}); + +chart.on('preprocess', function() { + const context = this; + + if (this.config.x_domain === 'filtered') { + this.filtered_data = this.raw_data; + this.filters.forEach(function(filter) { + if (filter.val !== 'All') + context.filtered_data = context.filtered_data + .filter(function(d) { + return filter.val === d[filter.col]; + }); + }); + } + + if (this.config.x_domain !== 'custom') { + this.config.x.domain = d3.extent( + this[this.config.x_domain + '_data'], + function(d) { + return d[context.config.x.column]; + } + ); + } + + this.controls.limits + .property('value', function(d) { + return context.config.x.domain[+d.option.split('.').pop()]; + }); +}); + +chart.on('resize', function() { + const context = this; + this.svg.selectAll('.bin-boundary, .x.axis .tick').remove(); + this.current_data + .sort(function(a,b) { + return a.rangeLow - b.rangeLow; + }) + .reduce( + function(acc,cur) { + if (acc.indexOf(cur.rangeLow) < 0) + acc.push(cur.rangeLow); + if (acc.indexOf(cur.rangeHigh) < 0) + acc.push(cur.rangeHigh); + return acc; + }, + [] + ) + .forEach(function(d,i) { + context.svg + .append('text') + .datum(d) + .classed('bin-boundary', true) + .attr({ + x: context.x(d), + y: context.plot_height, + dy: 16, + 'text-anchor': 'middle' + }) + .text(d3.format(context.config.x.format)(d)); + }); +}); + d3.csv( 'https://cdn.jsdelivr.net/gh/RhoInc/data-library/data/miscellaneous/iris.csv', function(d,i) { @@ -64,6 +161,7 @@ d3.csv( return d; }, function(data) { + chart.config.x.domain = d3.extent(data, function(d) { return +d['sepal length']; }); chart.init(data); } ); diff --git a/test-page/histograms/index.html b/test-page/histograms/index.html new file mode 100644 index 0000000..5e99b0b --- /dev/null +++ b/test-page/histograms/index.html @@ -0,0 +1,22 @@ + + + + Webcharts - Histogram + + + + + + + + + + + +
Webcharts
+
Histogram
+
+ + + + diff --git a/test-page/histograms/index.js b/test-page/histograms/index.js new file mode 100644 index 0000000..f9b167a --- /dev/null +++ b/test-page/histograms/index.js @@ -0,0 +1,111 @@ +const settings = { + x: { + type: 'linear', + column: 'sepal length', + label: 'Sepal Length', + bin: 15, + format: '.1f', + }, + y: { + type: 'linear', + label: '# of Observations', + behavior: 'flex', + domain: [0], + }, + marks: [ + { + type: 'bar', + per: ['sepal length'], + summarizeY: 'count', + tooltip: '$y observations around $x', + attributes: { + 'fill-opacity': .5, + fill: 'red', + }, + values: { + species: 'setosa', + }, + }, + { + type: 'bar', + per: ['sepal length'], + summarizeY: 'count', + tooltip: '$y observations around $x', + attributes: { + 'fill-opacity': .5, + fill: 'blue', + }, + values: { + species: 'versicolor', + }, + }, + { + type: 'bar', + per: ['sepal length'], + summarizeY: 'count', + tooltip: '$y observations around $x', + attributes: { + 'fill-opacity': .5, + fill: 'green', + }, + values: { + species: 'virginica', + }, + }, + ], + aspect: 3, + gridlines: 'y', +}; +console.log(JSON.stringify(settings, null, 4)); + +const controls = new webCharts.createControls( + '#container', + { + inputs: [ + { + type: 'dropdown', + options: [ + 'x.column', + 'marks.0.per.0', + ], + label: 'Dimension', + values: [ + 'sepal length', + 'sepal width', + 'petal length', + 'petal width', + ], + require: true, + }, + ], + }, +); + +const chart = new webCharts.createChart( + '#container', + settings, + controls, +); + +chart.on('layout', function() { + const context = this; +}); + +chart.on('preprocess', function() { + const context = this; +}); + +chart.on('resize', function() { + const context = this; +}); + +d3.csv( + 'https://cdn.jsdelivr.net/gh/RhoInc/data-library/data/miscellaneous/iris.csv', + function(d,i) { + d.seq = i; + return d; + }, + function(data) { + chart.init(data); + } +); diff --git a/test/chart/cleanData.js b/test/chart/cleanData.js index ba0cd07..ca41da7 100644 --- a/test/chart/cleanData.js +++ b/test/chart/cleanData.js @@ -22,47 +22,36 @@ export default function testCleanData(settings, data) { //transformData() validation describe('cleanData() is called for each item in settings.marks', () => { - const falseyValues = [ - '', - ' ', - 'asdf', - NaN, - null, - undefined, - false - ]; + const falseyValues = ['', ' ', 'asdf', NaN, null, undefined, false]; settings.marks.forEach(mark => { let copiedData, cleanedData; beforeEach(() => { copiedData = []; - data.forEach((d,i) => { + data.forEach((d, i) => { copiedData[i] = {}; - for (const variable in d) - copiedData[i][variable] = d[variable]; - - if (Math.random() < .1) - copiedData[i][settings.x.column] = falseyValues[i%(falseyValues.length - 1)]; - if (Math.random() > .9) - copiedData[i][settings.y.column] = falseyValues[i%(falseyValues.length - 1)]; + for (const variable in d) copiedData[i][variable] = d[variable]; + + if (Math.random() < 0.1) + copiedData[i][settings.x.column] = + falseyValues[i % (falseyValues.length - 1)]; + if (Math.random() > 0.9) + copiedData[i][settings.y.column] = + falseyValues[i % (falseyValues.length - 1)]; }); cleanedData = cleanData.call(chart, mark, copiedData); }); it('removes falsey values', () => { - const cleanedCopiedData = copiedData - .filter(d => ( + const cleanedCopiedData = copiedData.filter( + d => falseyValues.indexOf(d[settings.x.column]) < 0 && !isNaN(d[settings.x.column]) && falseyValues.indexOf(d[settings.y.column]) < 0 && !isNaN(d[settings.y.column]) - )); - expect( - cleanedData.length - ).toEqual( - cleanedCopiedData.length ); + expect(cleanedData.length).toEqual(cleanedCopiedData.length); }); }); }); diff --git a/test/chart/createChart.js b/test/chart/createChart.js index 56d980c..1580a79 100644 --- a/test/chart/createChart.js +++ b/test/chart/createChart.js @@ -54,9 +54,9 @@ export default function testCreateChart(settings, full = true) { }); it('chart object is bound to div.wc-chart', () => { - var datum = chart.wrap.datum() - let property; - expect(chart).toEqual(datum) + var datum = chart.wrap.datum(); + let property; + expect(chart).toEqual(datum); }); } }); diff --git a/test/chart/histogram.js b/test/chart/histogram.js new file mode 100644 index 0000000..5abd057 --- /dev/null +++ b/test/chart/histogram.js @@ -0,0 +1,32 @@ +import jsdom from 'jsdom'; +import createChart from '../../src/createChart'; +import expect from 'expect'; +import data from '../samples/irisData'; +import settings from '../samples/histogram'; +import clone from '../../src/util/clone'; +import { selectAll } from 'd3'; + +describe('histogram tests', () => { + const { JSDOM } = jsdom; + let dom, container, chart; + + before(() => { + dom = new JSDOM(''); + container = dom.window.document.createElement('div'); + chart = createChart(container, settings); + chart.init(data, true); + }); + + describe('settings specify a histogram by defining [x|y].bin', () => { + it('groups the data into as many bins as specified by [x|y].bin', () => { + const nodes = chart.wrap.node().querySelectorAll('.bar-group'); + expect(nodes.length).toEqual(chart.config.x.bin); + }); + it('when an axis domain is specified, that domain, rather than the extent of the data, is divided into bins', () => { + chart.config.x.domain = [2, 10]; + chart.draw(); + expect(chart.marks[0].quant.domain()).toEqual(chart.config.x.domain); + }); + //TODO: Have Webcharts calculate the bin width when [x|y].bin = 0 or 'fd' (Freedman-Diaconis rule). + }); +}); diff --git a/test/chart/rangeBand.js b/test/chart/rangeBand.js index b26f862..c453236 100644 --- a/test/chart/rangeBand.js +++ b/test/chart/rangeBand.js @@ -59,7 +59,7 @@ export default function testRangeBand(settings, data) { chart.draw(); expect( chart.config.range_band === chart.x.rangeBand() && - chart.config.range_band === chart.y.rangeBand() + chart.config.range_band === chart.y.rangeBand() ).toEqual(true); }); @@ -69,7 +69,7 @@ export default function testRangeBand(settings, data) { chart.draw(); expect( chart.config.x.range_band === chart.x.rangeBand() && - chart.config.y.range_band === chart.y.rangeBand() + chart.config.y.range_band === chart.y.rangeBand() ).toEqual(true); }); }); diff --git a/test/chart/rendering.js b/test/chart/rendering.js index 7f00f92..95db61f 100644 --- a/test/chart/rendering.js +++ b/test/chart/rendering.js @@ -15,8 +15,9 @@ export default function testRendering(settings, data) { /* supergroups = chart.svg.selectAll( '.point-supergroup, .bar-supergroup, .line-supergroup, .text-supergroup' );*/ - supergroups = chart.marks.supergroups, - groups = supergroups.selectAll('.point, .bar-group, .line, .text'); + (supergroups = chart.marks.supergroups), (groups = supergroups.selectAll( + '.point, .bar-group, .line, .text' + )); }); after(() => { @@ -30,77 +31,94 @@ export default function testRendering(settings, data) { it('g.supergroup elements are present for each specified mark type. ', () => { var supergroupsFound = 0; - chart.marks.forEach(function(mark){ - const markType = mark.type == 'circle' ? 'point-supergroup' : mark.type + '-supergroup' - if(mark.supergroup.classed(markType)) supergroupsFound = supergroupsFound+1; - }) + chart.marks.forEach(function(mark) { + const markType = mark.type == 'circle' + ? 'point-supergroup' + : mark.type + '-supergroup'; + if (mark.supergroup.classed(markType)) supergroupsFound = supergroupsFound + 1; + }); expect(supergroupsFound).toEqual(supergroups[0].length); }); it('Each mark group has an ID attached as a class ', () => { - chart.marks.forEach(function(mark,i){ - expect(mark.supergroup.classed(mark.id)).toEqual(true); - }) + chart.marks.forEach(function(mark, i) { + expect(mark.supergroup.classed(mark.id)).toEqual(true); + }); }); it('config marks is copied to chart.marks', () => { - chart.marks.forEach(function(mark,i){ - let property; - for (property in chart.config.marks[i]){ - expect(chart.config.marks[i][property]).toEqual(mark[property]); - } - }); + chart.marks.forEach(function(mark, i) { + let property; + for (property in chart.config.marks[i]) { + expect(chart.config.marks[i][property]).toEqual(mark[property]); + } + }); }); it('d3.selection for g.supergroup element bound to each item in chart.marks array', () => { - chart.marks.forEach(function(mark,i){ - let match = chart.svg.selectAll("g.supergroup").filter(function(f){return f.id == mark.id}) - expect(mark.supergroup).toEqual(match); - }); + chart.marks.forEach(function(mark, i) { + let match = chart.svg.selectAll('g.supergroup').filter(function(f) { + return f.id == mark.id; + }); + expect(mark.supergroup).toEqual(match); + }); }); it('d3.selection for g.groups elements bound to each item in chart.marks array', () => { - chart.marks.forEach(function(mark,i){ - let groupType = mark.type == "bar" ? "bar-group" : - mark.type =="circle" ? "point" : - mark.type =="text" ? "text" : - mark.type =="line" ? "line" : - "mark type not found" - let matches = chart.svg.selectAll("g.supergroup").filter(function(f){return f.id == mark.id}).selectAll("g."+groupType) - expect(mark.groups).toEqual(matches); - }); + chart.marks.forEach(function(mark, i) { + let groupType = mark.type == 'bar' + ? 'bar-group' + : mark.type == 'circle' + ? 'point' + : mark.type == 'text' + ? 'text' + : mark.type == 'line' ? 'line' : 'mark type not found'; + let matches = chart.svg + .selectAll('g.supergroup') + .filter(function(f) { + return f.id == mark.id; + }) + .selectAll('g.' + groupType); + expect(mark.groups).toEqual(matches); + }); }); it('d3.selection for specific d3 marks (circles, paths, etc) bound to each item in chart.marks array expect for when type=bar', () => { - chart.marks - .filter(f => f.type != "bar") - .forEach(function(mark,i){ - let groupType = mark.type =="circle" ? "point" : - mark.type =="text" ? "text" : - mark.type =="line" ? "line" : - "mark type not found" - - let markType = mark.type =="circle" ? "circle" : - mark.type =="text" ? "text" : - mark.type =="line" ? "path" : - "mark type not found" - - let markName = markType+"s" - - let matches = chart.svg.selectAll("g.supergroup") - .filter(function(f){return f.id == mark.id}) - .selectAll("g."+groupType) - .select(markType) - - expect(mark[markName]).toEqual(matches); - }); + chart.marks.filter(f => f.type != 'bar').forEach(function(mark, i) { + let groupType = mark.type == 'circle' + ? 'point' + : mark.type == 'text' + ? 'text' + : mark.type == 'line' ? 'line' : 'mark type not found'; + + let markType = mark.type == 'circle' + ? 'circle' + : mark.type == 'text' + ? 'text' + : mark.type == 'line' ? 'path' : 'mark type not found'; + + let markName = markType + 's'; + + let matches = chart.svg + .selectAll('g.supergroup') + .filter(function(f) { + return f.id == mark.id; + }) + .selectAll('g.' + groupType) + .select(markType); + + expect(mark[markName]).toEqual(matches); + }); }); it('d3.selection containing all mark supergroups bound as property to the chart.marks array object', () => { - expect(chart.marks.supergroups).toEqual(chart.svg.selectAll('.point-supergroup, .bar-supergroup, .line-supergroup, .text-supergroup')) + expect(chart.marks.supergroups).toEqual( + chart.svg.selectAll( + '.point-supergroup, .bar-supergroup, .line-supergroup, .text-supergroup' + ) + ); }); - it('1+ g elements are present in each g.supergroup. ', () => { const groupCounts = groups.map(m => m.length); expect(groupCounts).toExclude(0); @@ -122,11 +140,11 @@ export default function testRendering(settings, data) { }); it('all expected data sets are present, and have 1+ item', () => { - var dataSets = ["initial_data", "raw_data", "filtered_data", "current_data"]; - let setname; - dataSets.forEach(function(setname){ - expect(chart[setname].length).toBeGreaterThan(0); - }) + var dataSets = ['initial_data', 'raw_data', 'filtered_data', 'current_data']; + let setname; + dataSets.forEach(function(setname) { + expect(chart[setname].length).toBeGreaterThan(0); + }); }); }); } diff --git a/test/chart/runTests.js b/test/chart/runTests.js index 8a887fc..bfdee37 100644 --- a/test/chart/runTests.js +++ b/test/chart/runTests.js @@ -43,7 +43,7 @@ testTransformData(transformDataSettings, transformDataData); import testSetDomain from './setDomain'; import { linear_linear, linear_ordinal, ordinal_linear } from '../samples/irisSettings'; import setDomainData from '../samples/irisData'; -testSetDomain({linear_linear, linear_ordinal, ordinal_linear}, setDomainData); +testSetDomain({ linear_linear, linear_ordinal, ordinal_linear }, setDomainData); //remove falsey values from data import testCleanData from './cleanData'; @@ -55,7 +55,4 @@ testCleanData(cleanDataSettings, cleanDataData); import testRangeBand from './rangeBand'; import { ordinal_ordinal as ordinal_ordinal_rb } from '../samples/irisSettings'; import rangeBandData from '../samples/irisData'; -testRangeBand( - ordinal_ordinal_rb, - rangeBandData -); +testRangeBand(ordinal_ordinal_rb, rangeBandData); diff --git a/test/chart/setDomain.js b/test/chart/setDomain.js index 2726d92..25bd1b2 100644 --- a/test/chart/setDomain.js +++ b/test/chart/setDomain.js @@ -33,7 +33,7 @@ export default function testSetDomain(settings, data) { //linear x linear describe('setDomain() is called for a chart with two linear axes', () => { - ['x','y'].forEach(axis => { + ['x', 'y'].forEach(axis => { it('returns a non-zero-length array for the specified axis', () => { console.log(` - testing ${charts.linear_linear[axis].type} ${axis} axis:`); expect(charts.linear_linear[axis + '_dom'].length).toBeGreaterThan(0); @@ -43,17 +43,19 @@ export default function testSetDomain(settings, data) { const test_data = []; data.forEach(d => { const datum = {}; - for (const prop in d) - datum[prop] = d[prop]; + for (const prop in d) datum[prop] = d[prop]; datum[charts.linear_linear[axis].column] = 0; test_data.push(datum); }); charts.linear_linear.consolidateData(test_data); - expect(charts.linear_linear[axis + '_dom'][1] - charts.linear_linear[axis + '_dom'][0]).toBeGreaterThan(0); + expect( + charts.linear_linear[axis + '_dom'][1] - + charts.linear_linear[axis + '_dom'][0] + ).toBeGreaterThan(0); }); it('gives precedence to the domain defined in the config', () => { - const domain = [-100,100]; + const domain = [-100, 100]; charts.linear_linear.config[axis].domain = domain.slice(); charts.linear_linear.consolidateData(data); expect(charts.linear_linear[axis + '_dom'].join(',')).toEqual(domain.join(',')); diff --git a/test/chart/transformData.js b/test/chart/transformData.js index 198b7fe..2d3cb2b 100644 --- a/test/chart/transformData.js +++ b/test/chart/transformData.js @@ -45,15 +45,24 @@ export default function testTransformData(settings, data) { it('returns an object containing a config, a nested data array, an x-domain, and a y-domain', () => { console.log(`\n Testing ${mark.summarizeX}:\n`); - expect(Object.keys(transformedData)).toEqual(['config','data', 'x_dom', 'y_dom']); + expect(Object.keys(transformedData)).toEqual([ + 'config', + 'data', + 'x_dom', + 'y_dom' + ]); }); it('nests raw data by mark.per', () => { expect(nestedData.length).toEqual(transformedData.data.length); - expect(nestedData.map(d => d.key)).toEqual(transformedData.data.map(d => d.key)); + expect(nestedData.map(d => d.key)).toEqual( + transformedData.data.map(d => d.key) + ); nestedData.forEach(d => { - const transformedDatum = transformedData.data.filter(di => di.key === d.key)[0]; + const transformedDatum = transformedData.data.filter( + di => di.key === d.key + )[0]; expect(d.values.raw).toEqual(transformedDatum.values.raw); expect(d.values.x).toEqual(transformedDatum.values.x); diff --git a/test/controls/createControls.js b/test/controls/createControls.js index 9832945..e8bb92c 100644 --- a/test/controls/createControls.js +++ b/test/controls/createControls.js @@ -42,9 +42,9 @@ describe('controls object creation', () => { }); it('chart object is bound to div.wc-controls', () => { - var datum = controls.wrap.datum() - let property; - expect(controls).toEqual(datum) + var datum = controls.wrap.datum(); + let property; + expect(controls).toEqual(datum); }); }); }); diff --git a/test/multiply/multiply.js b/test/multiply/multiply.js index 8a1c3a7..a18aa07 100644 --- a/test/multiply/multiply.js +++ b/test/multiply/multiply.js @@ -34,11 +34,11 @@ describe('webCharts.multiply()', () => { it('a single legend should exist inside the parent node of the multiples', () => { expect(chart.wrap.selectAll('.legend').size()).toEqual(1); }); - it('appears after multiples by default', () => { + it('appears after multiples by default', () => { const nodes = chart.wrap.node().querySelectorAll('div,ul'); expect(nodes[nodes.length - 1]).toEqual(chart.master_legend.node()); }); - it('appears before multiples if legend location is set to top', () => { + it('appears before multiples if legend location is set to top', () => { const topLegendSettings = clone(irisSettings); topLegendSettings.legend.location = 'top'; chart = createChart(container, topLegendSettings); diff --git a/test/samples/chart-config/barchart_vertical.json b/test/samples/chart-config/barchart_vertical.json index 04bb72c..3a00325 100644 --- a/test/samples/chart-config/barchart_vertical.json +++ b/test/samples/chart-config/barchart_vertical.json @@ -3,7 +3,7 @@ "label": "Vertical Bar chart:linear Y-axis", "notes": "Note that 0 must be specified in the y-domain to avoid hiding the first bar. Circles are added for visual reference.", "tests": [ - "One bar per perior renders as expected", + "One bar per period renders as expected", "Bar heights are roughly at mean levels for circles" ], "settings": { diff --git a/test/samples/histogram.js b/test/samples/histogram.js new file mode 100644 index 0000000..3a6fbc9 --- /dev/null +++ b/test/samples/histogram.js @@ -0,0 +1,19 @@ +export default { + x: { + type: 'linear', + column: 'Sepal.Length', + bin: 15 + }, + y: { + type: 'linear', + behavior: 'flex', + domain: [0] + }, + marks: [ + { + type: 'bar', + per: ['Sepal.Length'], + summarizeY: 'count' + } + ] +}; diff --git a/test/samples/irisSettings.js b/test/samples/irisSettings.js index 95b05e0..44e5f67 100644 --- a/test/samples/irisSettings.js +++ b/test/samples/irisSettings.js @@ -14,7 +14,7 @@ export const linear_linear = { type: 'circle', per: ['Sepal.Length', 'Sepal.Width'], summarizeX: 'mean', - summarizeY: 'mean', + summarizeY: 'mean' }, { type: 'circle', @@ -54,7 +54,7 @@ export const ordinal_linear = { { type: 'bar', per: ['Species'], - summarizeY: 'mean', + summarizeY: 'mean' }, { type: 'circle', @@ -70,12 +70,12 @@ export const ordinal_linear = { type: 'circle', per: ['Species'], summarizeY: 'max' - }, + } ], color_by: 'Species', legend: {}, padding: 0, - outer_pad: 0, + outer_pad: 0 }; export const linear_ordinal = { @@ -93,7 +93,7 @@ export const linear_ordinal = { { type: 'bar', per: ['Species'], - summarizeX: 'mean', + summarizeX: 'mean' }, { type: 'circle', @@ -109,12 +109,12 @@ export const linear_ordinal = { type: 'circle', per: ['Species'], summarizeX: 'max' - }, + } ], color_by: 'Species', legend: {}, padding: 0, - outer_pad: 0, + outer_pad: 0 }; export const ordinal_ordinal = { @@ -131,20 +131,20 @@ export const ordinal_ordinal = { marks: [ { type: 'bar', - per: ['Species'], + per: ['Species'] }, { type: 'circle', - per: ['Species'], + per: ['Species'] }, { type: 'text', per: ['Species'], - text: '$x - $y', - }, + text: '$x - $y' + } ], color_by: 'Species', legend: {}, padding: 0, - outer_pad: 0, + outer_pad: 0 }; diff --git a/test/table/bindTableToDOM.js b/test/table/bindTableToDOM.js index 0b09339..b8aed73 100644 --- a/test/table/bindTableToDOM.js +++ b/test/table/bindTableToDOM.js @@ -16,8 +16,7 @@ export default function bindTableToDOM(settings, data) { table = createTable(container, settings).init(data, true); }); - afterEach(() => { - }); + afterEach(() => {}); describe('user calls table init() method', () => { it('binds table object to parent of table node', () => { diff --git a/test/table/runTests.js b/test/table/runTests.js index a0816c3..5488c7c 100644 --- a/test/table/runTests.js +++ b/test/table/runTests.js @@ -1,25 +1,13 @@ import data from '../samples/irisData'; import testInit from './init'; -testInit( - { exportable: false }, - data -); +testInit({ exportable: false }, data); import testSearchTable from './searchTable'; -testSearchTable( - { sortable: false, searchable: true, exportable: false, pagination: false }, - data -); +testSearchTable({ sortable: false, searchable: true, exportable: false, pagination: false }, data); import testSortTable from './sortTable'; -testSortTable( - { sortable: true, searchable: false, exportable: false, pagination: false }, - data -); +testSortTable({ sortable: true, searchable: false, exportable: false, pagination: false }, data); import testDestroyTable from './destroyTable'; -testDestroyTable( - { exportable: false }, - data -); +testDestroyTable({ exportable: false }, data); diff --git a/test/testNewUnitTests.js b/test/testNewUnitTests.js index 480fe08..9107366 100644 --- a/test/testNewUnitTests.js +++ b/test/testNewUnitTests.js @@ -1 +1 @@ -import './multiply/multiply'; +import './chart/histogram'; From b4982fe42c0bfcef5a15ec277fc7ae57d60c990e Mon Sep 17 00:00:00 2001 From: Spencer Childress Date: Fri, 10 May 2019 16:52:29 -0400 Subject: [PATCH 03/12] Webcharts v1.12.0 --- build/webcharts.js | 3208 ++++++++++++++------------------------------ package.json | 2 +- 2 files changed, 1006 insertions(+), 2204 deletions(-) diff --git a/build/webcharts.js b/build/webcharts.js index 24ad10e..9a38cb2 100644 --- a/build/webcharts.js +++ b/build/webcharts.js @@ -1,11 +1,9 @@ -(function(global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' - ? (module.exports = factory(require('d3'))) - : typeof define === 'function' && define.amd - ? define(['d3'], factory) - : (global.webCharts = factory(global.d3)); -})(typeof self !== 'undefined' ? self : this, function(d3) { - 'use strict'; +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('d3')) : + typeof define === 'function' && define.amd ? define(['d3'], factory) : + global.webCharts = factory(global.d3); +}(typeof self !== 'undefined' ? self : this, function (d3) { 'use strict'; + var version = '1.11.5'; function init(data) { @@ -14,17 +12,9 @@ var test = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; if (d3.select(this.div).select('.loader').empty()) { - d3 - .select(this.div) - .insert('div', ':first-child') - .attr('class', 'loader') - .selectAll('.blockG') - .data(d3.range(8)) - .enter() - .append('div') - .attr('class', function(d) { - return 'blockG rotate' + (d + 1); - }); + d3.select(this.div).insert('div', ':first-child').attr('class', 'loader').selectAll('.blockG').data(d3.range(8)).enter().append('div').attr('class', function (d) { + return 'blockG rotate' + (d + 1); + }); } this.wrap.attr('class', 'wc-chart'); @@ -48,10 +38,8 @@ //make sure container is visible (has height and width) before trying to initialize var visible = d3.select(_this.div).property('offsetWidth') > 0 || test; if (!visible) { - console.warn( - 'The chart cannot be initialized inside an element with 0 width. The chart will be initialized as soon as the container element is given a width > 0.' - ); - var onVisible = setInterval(function(i) { + console.warn('The chart cannot be initialized inside an element with 0 width. The chart will be initialized as soon as the container element is given a width > 0.'); + var onVisible = setInterval(function (i) { var visible_now = d3.select(_this.div).property('offsetWidth') > 0; if (visible_now) { _this.layout(); @@ -92,48 +80,32 @@ requiredVars.push('this.config.color_by'); requiredCols.push(this.config.color_by); } - if (this.config.marks) - this.config.marks.forEach(function(e, i) { - if (e.per && e.per.length) { - e.per.forEach(function(p, j) { - requiredVars.push('this.config.marks[' + i + '].per[' + j + ']'); - requiredCols.push(p); - }); - } - if (e.split) { - requiredVars.push('this.config.marks[' + i + '].split'); - requiredCols.push(e.split); - } - if (e.values) { - for (var value in e.values) { - requiredVars.push('this.config.marks[' + i + "].values['" + value + "']"); - requiredCols.push(value); - } + if (this.config.marks) this.config.marks.forEach(function (e, i) { + if (e.per && e.per.length) { + e.per.forEach(function (p, j) { + requiredVars.push('this.config.marks[' + i + '].per[' + j + ']'); + requiredCols.push(p); + }); + } + if (e.split) { + requiredVars.push('this.config.marks[' + i + '].split'); + requiredCols.push(e.split); + } + if (e.values) { + for (var value in e.values) { + requiredVars.push('this.config.marks[' + i + "].values['" + value + "']"); + requiredCols.push(value); } - }); + } + }); var missingDataField = false; - requiredCols.forEach(function(e, i) { + requiredCols.forEach(function (e, i) { if (colnames.indexOf(e) < 0) { missingDataField = true; d3.select(_this.div).select('.loader').remove(); - _this.wrap - .append('div') - .style('color', 'red') - .html( - 'The value "' + - e + - '" for the ' + - requiredVars[i] + - ' setting does not match any column in the provided dataset.' - ); - throw new Error( - 'Error in settings object: The value "' + - e + - '" for the ' + - requiredVars[i] + - ' setting does not match any column in the provided dataset.' - ); + _this.wrap.append('div').style('color', 'red').html('The value "' + e + '" for the ' + requiredVars[i] + ' setting does not match any column in the provided dataset.'); + throw new Error('Error in settings object: The value "' + e + '" for the ' + requiredVars[i] + ' setting does not match any column in the provided dataset.'); } }); @@ -145,94 +117,61 @@ } function addSVG() { - this.svg = this.wrap - .append('svg') - .datum(function() { - return null; - }) // prevent data inheritance - .attr({ - class: 'wc-svg', - xmlns: 'http://www.w3.org/2000/svg', - version: '1.1', - xlink: 'http://www.w3.org/1999/xlink' - }) - .append('g') - .style('display', 'inline-block'); + this.svg = this.wrap.append('svg').datum(function () { + return null; + }) // prevent data inheritance + .attr({ + class: 'wc-svg', + xmlns: 'http://www.w3.org/2000/svg', + version: '1.1', + xlink: 'http://www.w3.org/1999/xlink' + }).append('g').style('display', 'inline-block'); } function addDefs() { var defs = this.svg.append('defs'); //Add pattern. - defs - .append('pattern') - .attr({ - id: 'diagonal-stripes', - x: 0, - y: 0, - width: 3, - height: 8, - patternUnits: 'userSpaceOnUse', - patternTransform: 'rotate(30)' - }) - .append('rect') - .attr({ - x: '0', - y: '0', - width: '2', - height: '8' - }) - .style({ - stroke: 'none', - fill: 'black' - }); + defs.append('pattern').attr({ + id: 'diagonal-stripes', + x: 0, + y: 0, + width: 3, + height: 8, + patternUnits: 'userSpaceOnUse', + patternTransform: 'rotate(30)' + }).append('rect').attr({ + x: '0', + y: '0', + width: '2', + height: '8' + }).style({ + stroke: 'none', + fill: 'black' + }); //Add clipPath. defs.append('clipPath').attr('id', this.id).append('rect').attr('class', 'plotting-area'); } function addXAxis() { - this.svg - .append('g') - .attr('class', 'x axis') - .append('text') - .attr('class', 'axis-title') - .attr('dy', '-.35em') - .attr('text-anchor', 'middle'); + this.svg.append('g').attr('class', 'x axis').append('text').attr('class', 'axis-title').attr('dy', '-.35em').attr('text-anchor', 'middle'); } function addYAxis() { - this.svg - .append('g') - .attr('class', 'y axis') - .append('text') - .attr('class', 'axis-title') - .attr('transform', 'rotate(-90)') - .attr('dy', '.75em') - .attr('text-anchor', 'middle'); + this.svg.append('g').attr('class', 'y axis').append('text').attr('class', 'axis-title').attr('transform', 'rotate(-90)').attr('dy', '.75em').attr('text-anchor', 'middle'); } function addOverlay() { - this.overlay = this.svg - .append('rect') - .attr('class', 'overlay') - .attr('opacity', 0) - .attr('fill', 'none') - .style('pointer-events', 'all'); + this.overlay = this.svg.append('rect').attr('class', 'overlay').attr('opacity', 0).attr('fill', 'none').style('pointer-events', 'all'); } function addLegend() { //The legend is contained in the parent object of multiples so each multiple does not need its own legend. - if (!this.parent) - this.wrap - .append('ul') - .datum(function() { - return null; - }) // prevent data inheritance - .attr('class', 'legend') - .style('vertical-align', 'top') - .append('span') - .attr('class', 'legend-title'); + if (!this.parent) this.wrap.append('ul').datum(function () { + return null; + }) // prevent data inheritance + .attr('class', 'legend').style('vertical-align', 'top').append('span').attr('class', 'legend-title'); } function clearLoader() { @@ -268,9 +207,7 @@ // warn the user about the perils of "processed_data" if (processed_data) { - console.warn( - "Drawing the chart using user-defined 'processed_data', this is an experimental, untested feature." - ); + console.warn("Drawing the chart using user-defined 'processed_data', this is an experimental, untested feature."); } //Call consolidateData - this applies filters from controls and prepares data for each set of marks. @@ -285,38 +222,24 @@ this.setColorScale(); var max_width = config.max_width ? config.max_width : div_width; - this.raw_width = config.x.type === 'ordinal' && +config.x.range_band - ? (+config.x.range_band + config.x.range_band * config.padding) * this.x_dom.length - : config.resizable ? max_width : config.width ? config.width : div_width; - this.raw_height = config.y.type === 'ordinal' && +config.y.range_band - ? (+config.y.range_band + config.y.range_band * config.padding) * this.y_dom.length - : config.resizable - ? max_width * (1 / config.aspect) - : config.height ? config.height : div_width * (1 / config.aspect); - - var pseudo_width = this.svg.select('.overlay').attr('width') - ? this.svg.select('.overlay').attr('width') - : this.raw_width; - var pseudo_height = this.svg.select('.overlay').attr('height') - ? this.svg.select('.overlay').attr('height') - : this.raw_height; - - this.svg.select('.x.axis').select('.axis-title').text(function(d) { - return typeof config.x.label === 'string' - ? config.x.label - : typeof config.x.label === 'function' ? config.x.label.call(_this) : null; + this.raw_width = config.x.type === 'ordinal' && +config.x.range_band ? (+config.x.range_band + config.x.range_band * config.padding) * this.x_dom.length : config.resizable ? max_width : config.width ? config.width : div_width; + this.raw_height = config.y.type === 'ordinal' && +config.y.range_band ? (+config.y.range_band + config.y.range_band * config.padding) * this.y_dom.length : config.resizable ? max_width * (1 / config.aspect) : config.height ? config.height : div_width * (1 / config.aspect); + + var pseudo_width = this.svg.select('.overlay').attr('width') ? this.svg.select('.overlay').attr('width') : this.raw_width; + var pseudo_height = this.svg.select('.overlay').attr('height') ? this.svg.select('.overlay').attr('height') : this.raw_height; + + this.svg.select('.x.axis').select('.axis-title').text(function (d) { + return typeof config.x.label === 'string' ? config.x.label : typeof config.x.label === 'function' ? config.x.label.call(_this) : null; }); - this.svg.select('.y.axis').select('.axis-title').text(function(d) { - return typeof config.y.label === 'string' - ? config.y.label - : typeof config.y.label === 'function' ? config.y.label.call(_this) : null; + this.svg.select('.y.axis').select('.axis-title').text(function (d) { + return typeof config.y.label === 'string' ? config.y.label : typeof config.y.label === 'function' ? config.y.label.call(_this) : null; }); this.xScaleAxis(pseudo_width); this.yScaleAxis(pseudo_height); if (config.resizable && typeof window !== 'undefined') { - d3.select(window).on('resize.' + this.element + this.id, function() { + d3.select(window).on('resize.' + this.element + this.id, function () { chart.resize(); }); } else if (typeof window !== 'undefined') { @@ -341,8 +264,8 @@ i = void 0, j = void 0; - while ((i = (j = t.charAt(x++)).charCodeAt(0))) { - var m = i == 46 || (i >= 48 && i <= 57); + while (i = (j = t.charAt(x++)).charCodeAt(0)) { + var m = i == 46 || i >= 48 && i <= 57; if (m !== n) { tz[++y] = ''; n = m; @@ -382,101 +305,49 @@ this[axis + '_dom'] = this.config[axis].domain; } else if (this.config[axis].order) { //data-driven domain with user-defined domain order - this[axis + '_dom'] = d3 - .set( - d3.merge( - this.marks.map(function(mark) { - return mark[axis + '_dom']; - }) - ) - ) - .values() - .sort(function(a, b) { - return d3.ascending( - _this.config[axis].order.indexOf(a), - _this.config[axis].order.indexOf(b) - ); - }); - } else if ( - this.config[axis].sort && - this.config[axis].sort === 'alphabetical-ascending' - ) { + this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { + return mark[axis + '_dom']; + }))).values().sort(function (a, b) { + return d3.ascending(_this.config[axis].order.indexOf(a), _this.config[axis].order.indexOf(b)); + }); + } else if (this.config[axis].sort && this.config[axis].sort === 'alphabetical-ascending') { //data-driven domain with user-defined domain sort algorithm that sorts the axis //alphanumerically, first to last - this[axis + '_dom'] = d3 - .set( - d3.merge( - this.marks.map(function(mark) { - return mark[axis + '_dom']; - }) - ) - ) - .values() - .sort(naturalSorter); - } else if ( - ['time', 'linear'].indexOf(this.config[otherAxis].type) > -1 && - this.config[axis].sort === 'earliest' - ) { + this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { + return mark[axis + '_dom']; + }))).values().sort(naturalSorter); + } else if (['time', 'linear'].indexOf(this.config[otherAxis].type) > -1 && this.config[axis].sort === 'earliest') { //data-driven domain plotted against a time or linear axis that sorts the axis values //by earliest event/datum; generally used with timeline charts - this[axis + '_dom'] = d3 - .nest() - .key(function(d) { - return d[_this.config[axis].column]; - }) - .rollup(function(d) { - return d - .map(function(m) { - return m[_this.config[otherAxis].column]; - }) - .filter(function(f) { - return f instanceof Date; - }); - }) - .entries(this.filtered_data) - .sort(function(a, b) { - return d3.min(b.values) - d3.min(a.values); - }) - .map(function(m) { - return m.key; + this[axis + '_dom'] = d3.nest().key(function (d) { + return d[_this.config[axis].column]; + }).rollup(function (d) { + return d.map(function (m) { + return m[_this.config[otherAxis].column]; + }).filter(function (f) { + return f instanceof Date; }); - } else if ( - !this.config[axis].sort || - this.config[axis].sort === 'alphabetical-descending' - ) { + }).entries(this.filtered_data).sort(function (a, b) { + return d3.min(b.values) - d3.min(a.values); + }).map(function (m) { + return m.key; + }); + } else if (!this.config[axis].sort || this.config[axis].sort === 'alphabetical-descending') { //data-driven domain with default/user-defined domain sort algorithm that sorts the //axis alphanumerically, last to first - this[axis + '_dom'] = d3 - .set( - d3.merge( - this.marks.map(function(mark) { - return mark[axis + '_dom']; - }) - ) - ) - .values() - .sort(naturalSorter) - .reverse(); + this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { + return mark[axis + '_dom']; + }))).values().sort(naturalSorter).reverse(); } else { //data-driven domain with an invalid user-defined sort algorithm that captures a unique //set of values as they appear in the data - this[axis + '_dom'] = d3 - .set( - d3.merge( - this.marks.map(function(mark) { - return mark[axis + '_dom']; - }) - ) - ) - .values(); + this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { + return mark[axis + '_dom']; + }))).values(); } - } else if ( - this.config.marks - .map(function(m) { - return m['summarize' + axis.toUpperCase()] === 'percent'; - }) - .indexOf(true) > -1 - ) { + } else if (this.config.marks.map(function (m) { + return m['summarize' + axis.toUpperCase()] === 'percent'; + }).indexOf(true) > -1) { //rate domains run from 0 to 1 this[axis + '_dom'] = [0, 1]; } else { @@ -484,26 +355,13 @@ //TODO: they should really run from the minimum to the maximum summarized value, e.g. a //TODO: means over time chart should plot over the range of the means, not the range of the //TODO: raw data - this[axis + '_dom'] = d3.extent( - d3.merge( - this.marks.map(function(mark) { - return mark[axis + '_dom']; - }) - ) - ); + this[axis + '_dom'] = d3.extent(d3.merge(this.marks.map(function (mark) { + return mark[axis + '_dom']; + }))); } //Give the domain a range when the range of the variable is 0. - if ( - this.config[axis].type === 'linear' && - this[axis + '_dom'][0] === this[axis + '_dom'][1] - ) - this[axis + '_dom'] = this[axis + '_dom'][0] !== 0 - ? [ - this[axis + '_dom'][0] - this[axis + '_dom'][0] * 0.01, - this[axis + '_dom'][1] + this[axis + '_dom'][1] * 0.01 - ] - : [-1, 1]; + if (this.config[axis].type === 'linear' && this[axis + '_dom'][0] === this[axis + '_dom'][1]) this[axis + '_dom'] = this[axis + '_dom'][0] !== 0 ? [this[axis + '_dom'][0] - this[axis + '_dom'][0] * 0.01, this[axis + '_dom'][1] + this[axis + '_dom'][1] * 0.01] : [-1, 1]; return this[axis + '_dom']; } @@ -516,31 +374,25 @@ //Apply filters from associated controls objects to raw data. this.filtered_data = raw; if (this.filters.length) { - this.filters.forEach(function(filter) { - _this.filtered_data = _this.filtered_data.filter(function(d) { - return filter.all === true && filter.index === 0 - ? d - : filter.val instanceof Array - ? filter.val.indexOf(d[filter.col]) > -1 - : d[filter.col] === filter.val; + this.filters.forEach(function (filter) { + _this.filtered_data = _this.filtered_data.filter(function (d) { + return filter.all === true && filter.index === 0 ? d : filter.val instanceof Array ? filter.val.indexOf(d[filter.col]) > -1 : d[filter.col] === filter.val; }); }); } //Summarize data for each mark. - this.config.marks.forEach(function(mark, i) { + this.config.marks.forEach(function (mark, i) { if (mark.type !== 'bar') { mark.arrange = null; mark.split = null; } - var mark_info = mark.per - ? _this.transformData(raw, mark) - : { - data: [], - x_dom: [], - y_dom: [] - }; + var mark_info = mark.per ? _this.transformData(raw, mark) : { + data: [], + x_dom: [], + y_dom: [] + }; _this.marks[i] = { id: mark.id, @@ -571,12 +423,8 @@ this.config.x = this.config.x || {}; this.config.y = this.config.y || {}; - this.config.x.label = this.config.x.label !== undefined - ? this.config.x.label - : this.config.x.column; - this.config.y.label = this.config.y.label !== undefined - ? this.config.y.label - : this.config.y.column; + this.config.x.label = this.config.x.label !== undefined ? this.config.x.label : this.config.x.column; + this.config.y.label = this.config.y.label !== undefined ? this.config.y.label : this.config.y.column; this.config.x.sort = this.config.x.sort || 'alphabetical-ascending'; this.config.y.sort = this.config.y.sort || 'alphabetical-descending'; @@ -589,16 +437,10 @@ this.config.margin = this.config.margin || {}; this.config.legend = this.config.legend || {}; - this.config.legend.label = this.config.legend.label !== undefined - ? this.config.legend.label - : this.config.color_by; - this.config.legend.location = this.config.legend.location !== undefined - ? this.config.legend.location - : 'bottom'; - this.config.marks = this.config.marks && this.config.marks.length - ? this.config.marks - : [{}]; - this.config.marks.forEach(function(m, i) { + this.config.legend.label = this.config.legend.label !== undefined ? this.config.legend.label : this.config.color_by; + this.config.legend.location = this.config.legend.location !== undefined ? this.config.legend.location : 'bottom'; + this.config.marks = this.config.marks && this.config.marks.length ? this.config.marks : [{}]; + this.config.marks.forEach(function (m, i) { m.id = m.id ? m.id : 'mark' + (i + 1); }); @@ -611,23 +453,10 @@ this.config.aspect = this.config.aspect || 1.33; - this.config.colors = this.config.colors || [ - 'rgb(102,194,165)', - 'rgb(252,141,98)', - 'rgb(141,160,203)', - 'rgb(231,138,195)', - 'rgb(166,216,84)', - 'rgb(255,217,47)', - 'rgb(229,196,148)', - 'rgb(179,179,179)' - ]; - - this.config.scale_text = this.config.scale_text === undefined - ? true - : this.config.scale_text; - this.config.transitions = this.config.transitions === undefined - ? true - : this.config.transitions; + this.config.colors = this.config.colors || ['rgb(102,194,165)', 'rgb(252,141,98)', 'rgb(141,160,203)', 'rgb(231,138,195)', 'rgb(166,216,84)', 'rgb(255,217,47)', 'rgb(229,196,148)', 'rgb(179,179,179)']; + + this.config.scale_text = this.config.scale_text === undefined ? true : this.config.scale_text; + this.config.transitions = this.config.transitions === undefined ? true : this.config.transitions; } function cleanData(mark, raw) { @@ -636,68 +465,50 @@ var dateConvert = d3.time.format(this.config.date_format); var clean = raw; // only use data for the current mark - clean = mark.per && mark.per.length - ? clean.filter(function(f) { - return f[mark.per[0]] !== undefined; - }) - : clean; + clean = mark.per && mark.per.length ? clean.filter(function (f) { + return f[mark.per[0]] !== undefined; + }) : clean; // Make sure data has x and y values if (this.config.x.column) { - clean = clean.filter(function(f) { + clean = clean.filter(function (f) { return [undefined, null].indexOf(f[_this.config.x.column]) < 0; }); } if (this.config.y.column) { - clean = clean.filter(function(f) { + clean = clean.filter(function (f) { return [undefined, null].indexOf(f[_this.config.y.column]) < 0; }); } //check that x and y have the correct formats if (this.config.x.type === 'time') { - clean = clean.filter(function(f) { - return f[_this.config.x.column] instanceof Date - ? f[_this.config.x.column] - : dateConvert.parse(f[_this.config.x.column]); + clean = clean.filter(function (f) { + return f[_this.config.x.column] instanceof Date ? f[_this.config.x.column] : dateConvert.parse(f[_this.config.x.column]); }); - clean.forEach(function(e) { - return (e[_this.config.x.column] = e[_this.config.x.column] instanceof Date - ? e[_this.config.x.column] - : dateConvert.parse(e[_this.config.x.column])); + clean.forEach(function (e) { + return e[_this.config.x.column] = e[_this.config.x.column] instanceof Date ? e[_this.config.x.column] : dateConvert.parse(e[_this.config.x.column]); }); } if (this.config.y.type === 'time') { - clean = clean.filter(function(f) { - return f[_this.config.y.column] instanceof Date - ? f[_this.config.y.column] - : dateConvert.parse(f[_this.config.y.column]); + clean = clean.filter(function (f) { + return f[_this.config.y.column] instanceof Date ? f[_this.config.y.column] : dateConvert.parse(f[_this.config.y.column]); }); - clean.forEach(function(e) { - return (e[_this.config.y.column] = e[_this.config.y.column] instanceof Date - ? e[_this.config.y.column] - : dateConvert.parse(e[_this.config.y.column])); + clean.forEach(function (e) { + return e[_this.config.y.column] = e[_this.config.y.column] instanceof Date ? e[_this.config.y.column] : dateConvert.parse(e[_this.config.y.column]); }); } - if ( - (this.config.x.type === 'linear' || this.config.x.type === 'log') && - this.config.x.column - ) { - clean = clean.filter(function(f) { - return mark.summarizeX !== 'count' && mark.summarizeX !== 'percent' - ? !(isNaN(f[_this.config.x.column]) || /^\s*$/.test(f[_this.config.x.column])) // is or coerces to a number and is not a string that coerces to 0 - : f; + if ((this.config.x.type === 'linear' || this.config.x.type === 'log') && this.config.x.column) { + clean = clean.filter(function (f) { + return mark.summarizeX !== 'count' && mark.summarizeX !== 'percent' ? !(isNaN(f[_this.config.x.column]) || /^\s*$/.test(f[_this.config.x.column])) // is or coerces to a number and is not a string that coerces to 0 + : f; }); } - if ( - (this.config.y.type === 'linear' || this.config.y.type === 'log') && - this.config.y.column - ) { - clean = clean.filter(function(f) { - return mark.summarizeY !== 'count' && mark.summarizeY !== 'percent' - ? !(isNaN(f[_this.config.y.column]) || /^\s*$/.test(f[_this.config.y.column])) // is or coerces to a number and is not a string that coerces to 0 - : f; + if ((this.config.y.type === 'linear' || this.config.y.type === 'log') && this.config.y.column) { + clean = clean.filter(function (f) { + return mark.summarizeY !== 'count' && mark.summarizeY !== 'percent' ? !(isNaN(f[_this.config.y.column]) || /^\s*$/.test(f[_this.config.y.column])) // is or coerces to a number and is not a string that coerces to 0 + : f; }); } @@ -715,21 +526,17 @@ function summarize(vals) { var operation = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'mean'; - var nvals = vals - .filter(function(f) { - return +f || +f === 0; - }) - .map(function(m) { - return +m; - }); + var nvals = vals.filter(function (f) { + return +f || +f === 0; + }).map(function (m) { + return +m; + }); if (operation === 'cumulative') { return null; } - var mathed = operation === 'count' - ? vals.length - : operation === 'percent' ? vals.length : stats[operation](nvals); + var mathed = operation === 'count' ? vals.length : operation === 'percent' ? vals.length : stats[operation](nvals); return mathed; } @@ -742,125 +549,75 @@ var this_nest = d3.nest(); var totalOrder = void 0; - if ( - (this.config.x.type === 'linear' && this.config.x.bin) || - (this.config.y.type === 'linear' && this.config.y.bin) - ) { + if (this.config.x.type === 'linear' && this.config.x.bin || this.config.y.type === 'linear' && this.config.y.bin) { var xy = this.config.x.type === 'linear' && this.config.x.bin ? 'x' : 'y'; - var quant = d3.scale - .quantile() - .domain( - d3.extent( - entries.map(function(m) { - return +m[_this.config[xy].column]; - }) - ) - ) - .range(d3.range(+this.config[xy].bin)); - - entries.forEach(function(e) { - return (e.wc_bin = quant(e[_this.config[xy].column])); + var quant = d3.scale.quantile().domain(d3.extent(entries.map(function (m) { + return +m[_this.config[xy].column]; + }))).range(d3.range(+this.config[xy].bin)); + + entries.forEach(function (e) { + return e.wc_bin = quant(e[_this.config[xy].column]); }); - this_nest.key(function(d) { + this_nest.key(function (d) { return quant.invertExtent(d.wc_bin); }); } else { - this_nest.key(function(d) { - return mark.per - .map(function(m) { - return d[m]; - }) - .join(' '); + this_nest.key(function (d) { + return mark.per.map(function (m) { + return d[m]; + }).join(' '); }); } if (sublevel) { - this_nest.key(function(d) { + this_nest.key(function (d) { return d[sublevel]; }); - this_nest.sortKeys(function(a, b) { - return _this.config.x.type === 'time' - ? d3.ascending(new Date(a), new Date(b)) - : _this.config.x.order - ? d3.ascending( - _this.config.x.order.indexOf(a), - _this.config.x.order.indexOf(b) - ) - : sublevel === _this.config.color_by && _this.config.legend.order - ? d3.ascending( - _this.config.legend.order.indexOf(a), - _this.config.legend.order.indexOf(b) - ) - : _this.config.x.type === 'ordinal' || _this.config.y.type === 'ordinal' - ? naturalSorter(a, b) - : d3.ascending(+a, +b); + this_nest.sortKeys(function (a, b) { + return _this.config.x.type === 'time' ? d3.ascending(new Date(a), new Date(b)) : _this.config.x.order ? d3.ascending(_this.config.x.order.indexOf(a), _this.config.x.order.indexOf(b)) : sublevel === _this.config.color_by && _this.config.legend.order ? d3.ascending(_this.config.legend.order.indexOf(a), _this.config.legend.order.indexOf(b)) : _this.config.x.type === 'ordinal' || _this.config.y.type === 'ordinal' ? naturalSorter(a, b) : d3.ascending(+a, +b); }); } - this_nest.rollup(function(r) { + this_nest.rollup(function (r) { var obj = { raw: r }; - var y_vals = r - .map(function(m) { - return m[_this.config.y.column]; - }) - .sort(d3.ascending); - var x_vals = r - .map(function(m) { - return m[_this.config.x.column]; - }) - .sort(d3.ascending); - obj.x = _this.config.x.type === 'ordinal' - ? r[0][_this.config.x.column] - : summarize(x_vals, mark.summarizeX); - obj.y = _this.config.y.type === 'ordinal' - ? r[0][_this.config.y.column] - : summarize(y_vals, mark.summarizeY); - - obj.x_q25 = _this.config.error_bars && _this.config.y.type === 'ordinal' - ? d3.quantile(x_vals, 0.25) - : obj.x; - obj.x_q75 = _this.config.error_bars && _this.config.y.type === 'ordinal' - ? d3.quantile(x_vals, 0.75) - : obj.x; + var y_vals = r.map(function (m) { + return m[_this.config.y.column]; + }).sort(d3.ascending); + var x_vals = r.map(function (m) { + return m[_this.config.x.column]; + }).sort(d3.ascending); + obj.x = _this.config.x.type === 'ordinal' ? r[0][_this.config.x.column] : summarize(x_vals, mark.summarizeX); + obj.y = _this.config.y.type === 'ordinal' ? r[0][_this.config.y.column] : summarize(y_vals, mark.summarizeY); + + obj.x_q25 = _this.config.error_bars && _this.config.y.type === 'ordinal' ? d3.quantile(x_vals, 0.25) : obj.x; + obj.x_q75 = _this.config.error_bars && _this.config.y.type === 'ordinal' ? d3.quantile(x_vals, 0.75) : obj.x; obj.y_q25 = _this.config.error_bars ? d3.quantile(y_vals, 0.25) : obj.y; obj.y_q75 = _this.config.error_bars ? d3.quantile(y_vals, 0.75) : obj.y; dom_xs.push([obj.x_q25, obj.x_q75, obj.x]); dom_ys.push([obj.y_q25, obj.y_q75, obj.y]); if (mark.summarizeY === 'cumulative') { - var interm = entries.filter(function(f) { - return _this.config.x.type === 'time' - ? new Date(f[_this.config.x.column]) <= - new Date(r[0][_this.config.x.column]) - : +f[_this.config.x.column] <= +r[0][_this.config.x.column]; + var interm = entries.filter(function (f) { + return _this.config.x.type === 'time' ? new Date(f[_this.config.x.column]) <= new Date(r[0][_this.config.x.column]) : +f[_this.config.x.column] <= +r[0][_this.config.x.column]; }); if (mark.per.length) { - interm = interm.filter(function(f) { + interm = interm.filter(function (f) { return f[mark.per[0]] === r[0][mark.per[0]]; }); } - var cumul = _this.config.x.type === 'time' - ? interm.length - : d3.sum( - interm.map(function(m) { - return +m[_this.config.y.column] || +m[_this.config.y.column] === 0 - ? +m[_this.config.y.column] - : 1; - }) - ); + var cumul = _this.config.x.type === 'time' ? interm.length : d3.sum(interm.map(function (m) { + return +m[_this.config.y.column] || +m[_this.config.y.column] === 0 ? +m[_this.config.y.column] : 1; + })); dom_ys.push([cumul]); obj.y = cumul; } if (mark.summarizeX === 'cumulative') { - var _interm = entries.filter(function(f) { - return _this.config.y.type === 'time' - ? new Date(f[_this.config.y.column]) <= - new Date(r[0][_this.config.y.column]) - : +f[_this.config.y.column] <= +r[0][_this.config.y.column]; + var _interm = entries.filter(function (f) { + return _this.config.y.type === 'time' ? new Date(f[_this.config.y.column]) <= new Date(r[0][_this.config.y.column]) : +f[_this.config.y.column] <= +r[0][_this.config.y.column]; }); if (mark.per.length) { - _interm = _interm.filter(function(f) { + _interm = _interm.filter(function (f) { return f[mark.per[0]] === r[0][mark.per[0]]; }); } @@ -878,31 +635,19 @@ if (sublevel && mark.type === 'bar' && mark.split) { //calculate percentages in bars - test.forEach(function(e) { - var axis = _this.config.x.type === 'ordinal' || - (_this.config.x.type === 'linear' && _this.config.x.bin) - ? 'y' - : 'x'; - e.total = d3.sum( - e.values.map(function(m) { - return +m.values[axis]; - }) - ); + test.forEach(function (e) { + var axis = _this.config.x.type === 'ordinal' || _this.config.x.type === 'linear' && _this.config.x.bin ? 'y' : 'x'; + e.total = d3.sum(e.values.map(function (m) { + return +m.values[axis]; + })); var counter = 0; - e.values.forEach(function(v, i) { - if ( - _this.config.x.type === 'ordinal' || - (_this.config.x.type === 'linear' && _this.config.x.bin) - ) { - v.values.y = mark.summarizeY === 'percent' - ? v.values.y / e.total - : v.values.y || 0; + e.values.forEach(function (v, i) { + if (_this.config.x.type === 'ordinal' || _this.config.x.type === 'linear' && _this.config.x.bin) { + v.values.y = mark.summarizeY === 'percent' ? v.values.y / e.total : v.values.y || 0; counter += +v.values.y; v.values.start = e.values[i - 1] ? counter : v.values.y; } else { - v.values.x = mark.summarizeX === 'percent' - ? v.values.x / e.total - : v.values.x || 0; + v.values.x = mark.summarizeX === 'percent' ? v.values.x / e.total : v.values.x || 0; v.values.start = counter; counter += +v.values.x; } @@ -910,59 +655,36 @@ }); if (mark.arrange === 'stacked') { - if ( - this.config.x.type === 'ordinal' || - (this.config.x.type === 'linear' && this.config.x.bin) - ) { - dom_y = d3.extent( - test.map(function(m) { - return m.total; - }) - ); + if (this.config.x.type === 'ordinal' || this.config.x.type === 'linear' && this.config.x.bin) { + dom_y = d3.extent(test.map(function (m) { + return m.total; + })); } - if ( - this.config.y.type === 'ordinal' || - (this.config.y.type === 'linear' && this.config.y.bin) - ) { - dom_x = d3.extent( - test.map(function(m) { - return m.total; - }) - ); + if (this.config.y.type === 'ordinal' || this.config.y.type === 'linear' && this.config.y.bin) { + dom_x = d3.extent(test.map(function (m) { + return m.total; + })); } } } else { - var axis = this.config.x.type === 'ordinal' || - (this.config.x.type === 'linear' && this.config.x.bin) - ? 'y' - : 'x'; - test.forEach(function(e) { - return (e.total = e.values[axis]); + var axis = this.config.x.type === 'ordinal' || this.config.x.type === 'linear' && this.config.x.bin ? 'y' : 'x'; + test.forEach(function (e) { + return e.total = e.values[axis]; }); } - if ( - (this.config.x.sort === 'total-ascending' && this.config.x.type == 'ordinal') || - (this.config.y.sort === 'total-descending' && this.config.y.type == 'ordinal') - ) { - totalOrder = test - .sort(function(a, b) { - return d3.ascending(a.total, b.total); - }) - .map(function(m) { - return m.key; - }); - } else if ( - (this.config.x.sort === 'total-descending' && this.config.x.type == 'ordinal') || - (this.config.y.sort === 'total-ascending' && this.config.y.type == 'ordinal') - ) { - totalOrder = test - .sort(function(a, b) { - return d3.descending(+a.total, +b.total); - }) - .map(function(m) { - return m.key; - }); + if (this.config.x.sort === 'total-ascending' && this.config.x.type == 'ordinal' || this.config.y.sort === 'total-descending' && this.config.y.type == 'ordinal') { + totalOrder = test.sort(function (a, b) { + return d3.ascending(a.total, b.total); + }).map(function (m) { + return m.key; + }); + } else if (this.config.x.sort === 'total-descending' && this.config.x.type == 'ordinal' || this.config.y.sort === 'total-ascending' && this.config.y.type == 'ordinal') { + totalOrder = test.sort(function (a, b) { + return d3.descending(+a.total, +b.total); + }).map(function (m) { + return m.key; + }); } return { nested: test, dom_x: dom_x, dom_y: dom_y, totalOrder: totalOrder }; @@ -986,9 +708,7 @@ var config = this.config; var x_behavior = config.x.behavior || 'raw'; var y_behavior = config.y.behavior || 'raw'; - var sublevel = mark.type === 'line' - ? config.x.column - : mark.type === 'bar' && mark.split ? mark.split : null; + var sublevel = mark.type === 'line' ? config.x.column : mark.type === 'bar' && mark.split ? mark.split : null; ////////////////////////////////////////////////////////////////////////////////// // DATA PREP @@ -999,127 +719,73 @@ //prepare nested data required for bar charts var raw_nest = void 0; if (mark.type === 'bar') { - raw_nest = mark.arrange !== 'stacked' - ? makeNest.call(this, mark, cleaned, sublevel) - : makeNest.call(this, mark, cleaned); + raw_nest = mark.arrange !== 'stacked' ? makeNest.call(this, mark, cleaned, sublevel) : makeNest.call(this, mark, cleaned); } else if (mark.summarizeX === 'count' || mark.summarizeY === 'count') { raw_nest = makeNest.call(this, mark, cleaned); } // Get the domain for the mark based on the raw data - var raw_dom_x = mark.summarizeX === 'cumulative' - ? [0, cleaned.length] - : config.x.type === 'ordinal' - ? d3 - .set( - cleaned.map(function(m) { - return m[config.x.column]; - }) - ) - .values() - .filter(function(f) { - return f; - }) - : mark.split && mark.arrange !== 'stacked' - ? d3.extent( - d3.merge( - raw_nest.nested.map(function(m) { - return m.values.map(function(p) { - return p.values.raw.length; - }); - }) - ) - ) - : mark.summarizeX === 'count' - ? d3.extent( - raw_nest.nested.map(function(m) { - return m.values.raw.length; - }) - ) - : d3.extent( - cleaned - .map(function(m) { - return +m[config.x.column]; - }) - .filter(function(f) { - return +f || +f === 0; - }) - ); - - var raw_dom_y = mark.summarizeY === 'cumulative' - ? [0, cleaned.length] - : config.y.type === 'ordinal' - ? d3 - .set( - cleaned.map(function(m) { - return m[config.y.column]; - }) - ) - .values() - .filter(function(f) { - return f; - }) - : mark.split && mark.arrange !== 'stacked' - ? d3.extent( - d3.merge( - raw_nest.nested.map(function(m) { - return m.values.map(function(p) { - return p.values.raw.length; - }); - }) - ) - ) - : mark.summarizeY === 'count' - ? d3.extent( - raw_nest.nested.map(function(m) { - return m.values.raw.length; - }) - ) - : d3.extent( - cleaned - .map(function(m) { - return +m[config.y.column]; - }) - .filter(function(f) { - return +f || +f === 0; - }) - ); + var raw_dom_x = mark.summarizeX === 'cumulative' ? [0, cleaned.length] : config.x.type === 'ordinal' ? d3.set(cleaned.map(function (m) { + return m[config.x.column]; + })).values().filter(function (f) { + return f; + }) : mark.split && mark.arrange !== 'stacked' ? d3.extent(d3.merge(raw_nest.nested.map(function (m) { + return m.values.map(function (p) { + return p.values.raw.length; + }); + }))) : mark.summarizeX === 'count' ? d3.extent(raw_nest.nested.map(function (m) { + return m.values.raw.length; + })) : d3.extent(cleaned.map(function (m) { + return +m[config.x.column]; + }).filter(function (f) { + return +f || +f === 0; + })); + + var raw_dom_y = mark.summarizeY === 'cumulative' ? [0, cleaned.length] : config.y.type === 'ordinal' ? d3.set(cleaned.map(function (m) { + return m[config.y.column]; + })).values().filter(function (f) { + return f; + }) : mark.split && mark.arrange !== 'stacked' ? d3.extent(d3.merge(raw_nest.nested.map(function (m) { + return m.values.map(function (p) { + return p.values.raw.length; + }); + }))) : mark.summarizeY === 'count' ? d3.extent(raw_nest.nested.map(function (m) { + return m.values.raw.length; + })) : d3.extent(cleaned.map(function (m) { + return +m[config.y.column]; + }).filter(function (f) { + return +f || +f === 0; + })); var filtered = cleaned; var filt1_xs = []; var filt1_ys = []; if (this.filters.length) { - this.filters.forEach(function(e) { - filtered = filtered.filter(function(d) { - return e.all === true && e.index === 0 - ? d - : e.val instanceof Array - ? e.val.indexOf(d[e.col]) > -1 - : d[e.col] === e.val; + this.filters.forEach(function (e) { + filtered = filtered.filter(function (d) { + return e.all === true && e.index === 0 ? d : e.val instanceof Array ? e.val.indexOf(d[e.col]) > -1 : d[e.col] === e.val; }); }); //get domain for all non-All values of first filter if (config.x.behavior === 'firstfilter' || config.y.behavior === 'firstfilter') { - this.filters[0].choices - .filter(function(f) { - return f !== 'All'; - }) - .forEach(function(e) { - var perfilter = cleaned.filter(function(f) { - return f[_this.filters[0].col] === e; - }); - var filt_nested = makeNest.call(_this, mark, perfilter, sublevel); - filt1_xs.push(filt_nested.dom_x); - filt1_ys.push(filt_nested.dom_y); + this.filters[0].choices.filter(function (f) { + return f !== 'All'; + }).forEach(function (e) { + var perfilter = cleaned.filter(function (f) { + return f[_this.filters[0].col] === e; }); + var filt_nested = makeNest.call(_this, mark, perfilter, sublevel); + filt1_xs.push(filt_nested.dom_x); + filt1_ys.push(filt_nested.dom_y); + }); } } //filter on mark-specific instructions if (mark.values) { var _loop = function _loop(a) { - filtered = filtered.filter(function(f) { + filtered = filtered.filter(function (f) { return mark.values[a].indexOf(f[a]) > -1; }); }; @@ -1145,112 +811,43 @@ } //several criteria must be met in order to use the 'firstfilter' domain - var nonall = Boolean( - this.filters.length && - this.filters[0].val !== 'All' && - this.filters.slice(1).filter(function(f) { - return f.val === 'All'; - }).length === - this.filters.length - 1 - ); - - var pre_x_dom = !this.filters.length - ? flex_dom_x - : x_behavior === 'raw' - ? raw_dom_x - : nonall && x_behavior === 'firstfilter' ? filt1_dom_x : flex_dom_x; - var pre_y_dom = !this.filters.length - ? flex_dom_y - : y_behavior === 'raw' - ? raw_dom_y - : nonall && y_behavior === 'firstfilter' ? filt1_dom_y : flex_dom_y; - - var x_dom = config.x_dom - ? config.x_dom - : config.x.type === 'ordinal' && config.x.behavior === 'flex' - ? d3 - .set( - filtered.map(function(m) { - return m[config.x.column]; - }) - ) - .values() - : config.x.type === 'ordinal' - ? d3 - .set( - cleaned.map(function(m) { - return m[config.x.column]; - }) - ) - .values() - : pre_x_dom; - - var y_dom = config.y_dom - ? config.y_dom - : config.y.type === 'ordinal' && config.y.behavior === 'flex' - ? d3 - .set( - filtered.map(function(m) { - return m[config.y.column]; - }) - ) - .values() - : config.y.type === 'ordinal' - ? d3 - .set( - cleaned.map(function(m) { - return m[config.y.column]; - }) - ) - .values() - : pre_y_dom; + var nonall = Boolean(this.filters.length && this.filters[0].val !== 'All' && this.filters.slice(1).filter(function (f) { + return f.val === 'All'; + }).length === this.filters.length - 1); + + var pre_x_dom = !this.filters.length ? flex_dom_x : x_behavior === 'raw' ? raw_dom_x : nonall && x_behavior === 'firstfilter' ? filt1_dom_x : flex_dom_x; + var pre_y_dom = !this.filters.length ? flex_dom_y : y_behavior === 'raw' ? raw_dom_y : nonall && y_behavior === 'firstfilter' ? filt1_dom_y : flex_dom_y; + + var x_dom = config.x_dom ? config.x_dom : config.x.type === 'ordinal' && config.x.behavior === 'flex' ? d3.set(filtered.map(function (m) { + return m[config.x.column]; + })).values() : config.x.type === 'ordinal' ? d3.set(cleaned.map(function (m) { + return m[config.x.column]; + })).values() : pre_x_dom; + + var y_dom = config.y_dom ? config.y_dom : config.y.type === 'ordinal' && config.y.behavior === 'flex' ? d3.set(filtered.map(function (m) { + return m[config.y.column]; + })).values() : config.y.type === 'ordinal' ? d3.set(cleaned.map(function (m) { + return m[config.y.column]; + })).values() : pre_y_dom; //set lower limit of linear domain to 0 when other axis is ordinal and mark type is set to 'bar', provided no values are negative if (mark.type === 'bar') { - if ( - config.x.behavior !== 'flex' && - config.x.type === 'linear' && - config.y.type === 'ordinal' && - raw_dom_x[0] >= 0 - ) - x_dom[0] = 0; - - if ( - config.y.behavior !== 'flex' && - config.x.type === 'ordinal' && - config.y.type === 'linear' && - raw_dom_y[0] >= 0 - ) - y_dom[0] = 0; + if (config.x.behavior !== 'flex' && config.x.type === 'linear' && config.y.type === 'ordinal' && raw_dom_x[0] >= 0) x_dom[0] = 0; + + if (config.y.behavior !== 'flex' && config.x.type === 'ordinal' && config.y.type === 'linear' && raw_dom_y[0] >= 0) y_dom[0] = 0; } //update domains with those specified in the config - if ( - config.x.domain && - (config.x.domain[0] || config.x.domain[0] === 0) && - !isNaN(+config.x.domain[0]) - ) { + if (config.x.domain && (config.x.domain[0] || config.x.domain[0] === 0) && !isNaN(+config.x.domain[0])) { x_dom[0] = config.x.domain[0]; } - if ( - config.x.domain && - (config.x.domain[1] || config.x.domain[1] === 0) && - !isNaN(+config.x.domain[1]) - ) { + if (config.x.domain && (config.x.domain[1] || config.x.domain[1] === 0) && !isNaN(+config.x.domain[1])) { x_dom[1] = config.x.domain[1]; } - if ( - config.y.domain && - (config.y.domain[0] || config.y.domain[0] === 0) && - !isNaN(+config.y.domain[0]) - ) { + if (config.y.domain && (config.y.domain[0] || config.y.domain[0] === 0) && !isNaN(+config.y.domain[0])) { y_dom[0] = config.y.domain[0]; } - if ( - config.y.domain && - (config.y.domain[1] || config.y.domain[1] === 0) && - !isNaN(+config.y.domain[1]) - ) { + if (config.y.domain && (config.y.domain[1] || config.y.domain[1] === 0) && !isNaN(+config.y.domain[1])) { y_dom[1] = config.y.domain[1]; } @@ -1271,24 +868,15 @@ function setColorScale() { var config = this.config; var data = config.legend.behavior === 'flex' ? this.filtered_data : this.raw_data; - var colordom = Array.isArray(config.color_dom) && config.color_dom.length - ? config.color_dom.slice() - : d3 - .set( - data.map(function(m) { - return m[config.color_by]; - }) - ) - .values() - .filter(function(f) { - return f && f !== 'undefined'; - }); - - if (config.legend.order) - colordom.sort(function(a, b) { - return d3.ascending(config.legend.order.indexOf(a), config.legend.order.indexOf(b)); - }); - else colordom.sort(naturalSorter); + var colordom = Array.isArray(config.color_dom) && config.color_dom.length ? config.color_dom.slice() : d3.set(data.map(function (m) { + return m[config.color_by]; + })).values().filter(function (f) { + return f && f !== 'undefined'; + }); + + if (config.legend.order) colordom.sort(function (a, b) { + return d3.ascending(config.legend.order.indexOf(a), config.legend.order.indexOf(b)); + });else colordom.sort(naturalSorter); this.colorScale = d3.scale.ordinal().domain(colordom).range(config.colors); } @@ -1324,29 +912,11 @@ x.range([0, +max_range]).clamp(Boolean(config.x.clamp)); } - var xFormat = config.x.format - ? config.x.format - : config.marks - .map(function(m) { - return m.summarizeX === 'percent'; - }) - .indexOf(true) > -1 - ? '0%' - : type === 'time' ? '%x' : '.0f'; + var xFormat = config.x.format ? config.x.format : config.marks.map(function (m) { + return m.summarizeX === 'percent'; + }).indexOf(true) > -1 ? '0%' : type === 'time' ? '%x' : '.0f'; var tick_count = Math.max(2, Math.min(max_range / 80, 8)); - var xAxis = d3.svg - .axis() - .scale(x) - .orient(config.x.location) - .ticks(tick_count) - .tickFormat( - type === 'ordinal' - ? null - : type === 'time' ? d3.time.format(xFormat) : d3.format(xFormat) - ) - .tickValues(config.x.ticks ? config.x.ticks : null) - .innerTickSize(6) - .outerTickSize(3); + var xAxis = d3.svg.axis().scale(x).orient(config.x.location).ticks(tick_count).tickFormat(type === 'ordinal' ? null : type === 'time' ? d3.time.format(xFormat) : d3.format(xFormat)).tickValues(config.x.ticks ? config.x.ticks : null).innerTickSize(6).outerTickSize(3); this.svg.select('g.x.axis').attr('class', 'x axis ' + type); this.x = x; @@ -1383,29 +953,11 @@ y.range([+max_range, 0]).clamp(Boolean(config.y_clamp)); } - var yFormat = config.y.format - ? config.y.format - : config.marks - .map(function(m) { - return m.summarizeY === 'percent'; - }) - .indexOf(true) > -1 - ? '0%' - : '.0f'; + var yFormat = config.y.format ? config.y.format : config.marks.map(function (m) { + return m.summarizeY === 'percent'; + }).indexOf(true) > -1 ? '0%' : '.0f'; var tick_count = Math.max(2, Math.min(max_range / 80, 8)); - var yAxis = d3.svg - .axis() - .scale(y) - .orient('left') - .ticks(tick_count) - .tickFormat( - type === 'ordinal' - ? null - : type === 'time' ? d3.time.format(yFormat) : d3.format(yFormat) - ) - .tickValues(config.y.ticks ? config.y.ticks : null) - .innerTickSize(6) - .outerTickSize(3); + var yAxis = d3.svg.axis().scale(y).orient('left').ticks(tick_count).tickFormat(type === 'ordinal' ? null : type === 'time' ? d3.time.format(yFormat) : d3.format(yFormat)).tickValues(config.y.ticks ? config.y.ticks : null).innerTickSize(6).outerTickSize(3); this.svg.select('g.y.axis').attr('class', 'y axis ' + type); @@ -1419,45 +971,22 @@ var aspect2 = 1 / config.aspect; var div_width = parseInt(this.wrap.style('width')); var max_width = config.max_width ? config.max_width : div_width; - var preWidth = !config.resizable - ? config.width - : !max_width || div_width < max_width ? div_width : this.raw_width; + var preWidth = !config.resizable ? config.width : !max_width || div_width < max_width ? div_width : this.raw_width; this.textSize(preWidth); this.margin = this.setMargins(); - var svg_width = config.x.type === 'ordinal' && +config.x.range_band - ? this.raw_width + this.margin.left + this.margin.right - : !config.resizable - ? this.raw_width - : !config.max_width || div_width < config.max_width ? div_width : this.raw_width; + var svg_width = config.x.type === 'ordinal' && +config.x.range_band ? this.raw_width + this.margin.left + this.margin.right : !config.resizable ? this.raw_width : !config.max_width || div_width < config.max_width ? div_width : this.raw_width; this.plot_width = svg_width - this.margin.left - this.margin.right; - var svg_height = config.y.type === 'ordinal' && +config.y.range_band - ? this.raw_height + this.margin.top + this.margin.bottom - : !config.resizable && config.height - ? config.height - : !config.resizable ? svg_width * aspect2 : this.plot_width * aspect2; + var svg_height = config.y.type === 'ordinal' && +config.y.range_band ? this.raw_height + this.margin.top + this.margin.bottom : !config.resizable && config.height ? config.height : !config.resizable ? svg_width * aspect2 : this.plot_width * aspect2; this.plot_height = svg_height - this.margin.top - this.margin.bottom; - d3 - .select(this.svg.node().parentNode) - .attr('width', svg_width) - .attr('height', svg_height) - .select('g') - .attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')'); - - this.svg - .select('.overlay') - .attr('width', this.plot_width) - .attr('height', this.plot_height) - .classed('zoomable', config.zoomable); - - this.svg - .select('.plotting-area') - .attr('width', this.plot_width) - .attr('height', this.plot_height + 1) - .attr('transform', 'translate(0, -1)'); + d3.select(this.svg.node().parentNode).attr('width', svg_width).attr('height', svg_height).select('g').attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')'); + + this.svg.select('.overlay').attr('width', this.plot_width).attr('height', this.plot_height).classed('zoomable', config.zoomable); + + this.svg.select('.plotting-area').attr('width', this.plot_width).attr('height', this.plot_height + 1).attr('transform', 'translate(0, -1)'); this.xScaleAxis(); this.yScaleAxis(); @@ -1475,23 +1004,11 @@ var gYAxisTrans = config.transitions ? g_y_axis.transition() : g_y_axis; gYAxisTrans.call(this.yAxis); - x_axis_label.attr( - 'transform', - 'translate(' + this.plot_width / 2 + ',' + (this.margin.bottom - 2) + ')' - ); + x_axis_label.attr('transform', 'translate(' + this.plot_width / 2 + ',' + (this.margin.bottom - 2) + ')'); y_axis_label.attr('x', -1 * this.plot_height / 2).attr('y', -1 * this.margin.left); - this.svg - .selectAll('.axis .domain') - .attr({ - fill: 'none', - stroke: '#ccc', - 'stroke-width': 1, - 'shape-rendering': 'crispEdges' - }); - this.svg - .selectAll('.axis .tick line') - .attr({ stroke: '#eee', 'stroke-width': 1, 'shape-rendering': 'crispEdges' }); + this.svg.selectAll('.axis .domain').attr({ fill: 'none', stroke: '#ccc', 'stroke-width': 1, 'shape-rendering': 'crispEdges' }); + this.svg.selectAll('.axis .tick line').attr({ stroke: '#eee', 'stroke-width': 1, 'shape-rendering': 'crispEdges' }); this.drawGridlines(); @@ -1540,17 +1057,13 @@ function setMargins() { var _this = this; - var y_ticks = this.yAxis.tickFormat() - ? this.y.domain().map(function(m) { - return _this.yAxis.tickFormat()(m); - }) - : this.y.domain(); - - var max_y_text_length = d3.max( - y_ticks.map(function(m) { - return String(m).length; - }) - ); + var y_ticks = this.yAxis.tickFormat() ? this.y.domain().map(function (m) { + return _this.yAxis.tickFormat()(m); + }) : this.y.domain(); + + var max_y_text_length = d3.max(y_ticks.map(function (m) { + return String(m).length; + })); if (this.config.y_format && this.config.y_format.indexOf('%') > -1) { max_y_text_length += 1; } @@ -1560,8 +1073,7 @@ var font_size = parseInt(this.wrap.style('font-size')); var x_second = this.config.x2_interval ? 1 : 0; var y_margin = max_y_text_length * font_size * 0.5 + font_size * y_label_on * 1.5 || 8; - var x_margin = - font_size + font_size / 1.5 + font_size * x_label_on + font_size * x_second || 8; + var x_margin = font_size + font_size / 1.5 + font_size * x_label_on + font_size * x_second || 8; y_margin += 6; x_margin += 3; @@ -1569,9 +1081,7 @@ return { top: this.config.margin && this.config.margin.top ? this.config.margin.top : 8, right: this.config.margin && this.config.margin.right ? this.config.margin.right : 16, - bottom: this.config.margin && this.config.margin.bottom - ? this.config.margin.bottom - : x_margin, + bottom: this.config.margin && this.config.margin.bottom ? this.config.margin.bottom : x_margin, left: this.config.margin && this.config.margin.left ? this.config.margin.left : y_margin }; } @@ -1581,10 +1091,8 @@ if (this.config.gridlines) { this.svg.select('.y.axis').selectAll('.tick line').attr('x1', 0); this.svg.select('.x.axis').selectAll('.tick line').attr('y1', 0); - if (this.config.gridlines === 'y' || this.config.gridlines === 'xy') - this.svg.select('.y.axis').selectAll('.tick line').attr('x1', this.plot_width); - if (this.config.gridlines === 'x' || this.config.gridlines === 'xy') - this.svg.select('.x.axis').selectAll('.tick line').attr('y1', -this.plot_height); + if (this.config.gridlines === 'y' || this.config.gridlines === 'xy') this.svg.select('.y.axis').selectAll('.tick line').attr('x1', this.plot_width); + if (this.config.gridlines === 'x' || this.config.gridlines === 'xy') this.svg.select('.x.axis').selectAll('.tick line').attr('y1', -this.plot_height); } else { this.svg.select('.y.axis').selectAll('.tick line').attr('x1', 0); this.svg.select('.x.axis').selectAll('.tick line').attr('y1', 0); @@ -1592,23 +1100,15 @@ } function makeLegend() { - var scale = arguments.length > 0 && arguments[0] !== undefined - ? arguments[0] - : this.colorScale; + var scale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.colorScale; var label = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; var custom_data = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; var config = this.config; - config.legend.mark = config.legend.mark - ? config.legend.mark - : config.marks.length && config.marks[0].type === 'bar' - ? 'square' - : config.marks.length ? config.marks[0].type : 'square'; + config.legend.mark = config.legend.mark ? config.legend.mark : config.marks.length && config.marks[0].type === 'bar' ? 'square' : config.marks.length ? config.marks[0].type : 'square'; - var legend_label = label - ? label - : typeof config.legend.label === 'string' ? config.legend.label : ''; + var legend_label = label ? label : typeof config.legend.label === 'string' ? config.legend.label : ''; var legendOriginal = this.legend || this.wrap.select('.legend'); var legend = legendOriginal; @@ -1623,12 +1123,7 @@ } else { //multiples - keep legend outside of individual charts' wraps if (this.config.legend.location === 'top' || this.config.legend.location === 'left') { - this.parent.wrap - .node() - .insertBefore( - legendOriginal.node(), - this.parent.wrap.select('.wc-chart').node() - ); + this.parent.wrap.node().insertBefore(legendOriginal.node(), this.parent.wrap.select('.wc-chart').node()); } else { this.parent.wrap.node().appendChild(legendOriginal.node()); } @@ -1636,65 +1131,40 @@ legend.style('padding', 0); - var legend_data = - custom_data || - scale - .domain() - .slice(0) - .filter(function(f) { - return f !== undefined && f !== null; - }) - .map(function(m) { - return { label: m, mark: config.legend.mark }; - }); + var legend_data = custom_data || scale.domain().slice(0).filter(function (f) { + return f !== undefined && f !== null; + }).map(function (m) { + return { label: m, mark: config.legend.mark }; + }); - legend - .select('.legend-title') - .text(legend_label) - .style('display', legend_label ? 'inline' : 'none') - .style('margin-right', '1em'); + legend.select('.legend-title').text(legend_label).style('display', legend_label ? 'inline' : 'none').style('margin-right', '1em'); - var leg_parts = legend.selectAll('.legend-item').data(legend_data, function(d) { + var leg_parts = legend.selectAll('.legend-item').data(legend_data, function (d) { return d.label + d.mark; }); leg_parts.exit().remove(); - var legendPartDisplay = this.config.legend.location === 'bottom' || - this.config.legend.location === 'top' - ? 'inline-block' - : 'block'; - var new_parts = leg_parts - .enter() - .append('li') - .attr('class', 'legend-item') - .style({ 'list-style-type': 'none', 'margin-right': '1em' }); - new_parts.append('span').attr('class', 'legend-mark-text').style('color', function(d) { + var legendPartDisplay = this.config.legend.location === 'bottom' || this.config.legend.location === 'top' ? 'inline-block' : 'block'; + var new_parts = leg_parts.enter().append('li').attr('class', 'legend-item').style({ 'list-style-type': 'none', 'margin-right': '1em' }); + new_parts.append('span').attr('class', 'legend-mark-text').style('color', function (d) { return scale(d.label); }); - new_parts - .append('svg') - .attr('class', 'legend-color-block') - .attr('width', '1.1em') - .attr('height', '1.1em') - .style({ - position: 'relative', - top: '0.2em' - }); + new_parts.append('svg').attr('class', 'legend-color-block').attr('width', '1.1em').attr('height', '1.1em').style({ + position: 'relative', + top: '0.2em' + }); leg_parts.style('display', legendPartDisplay); if (config.legend.order) { - leg_parts.sort(function(a, b) { - return d3.ascending( - config.legend.order.indexOf(a.label), - config.legend.order.indexOf(b.label) - ); + leg_parts.sort(function (a, b) { + return d3.ascending(config.legend.order.indexOf(a.label), config.legend.order.indexOf(b.label)); }); } leg_parts.selectAll('.legend-color-block').select('.legend-mark').remove(); - leg_parts.selectAll('.legend-color-block').each(function(e) { + leg_parts.selectAll('.legend-color-block').each(function (e) { var svg = d3.select(this); if (e.mark === 'circle') { svg.append('circle').attr({ @@ -1722,33 +1192,20 @@ }); } }); - leg_parts - .selectAll('.legend-color-block') - .select('.legend-mark') - .attr('fill', function(d) { - return d.color || scale(d.label); - }) - .attr('stroke', function(d) { - return d.color || scale(d.label); - }) - .each(function(e) { - d3.select(this).attr(e.attributes); - }); + leg_parts.selectAll('.legend-color-block').select('.legend-mark').attr('fill', function (d) { + return d.color || scale(d.label); + }).attr('stroke', function (d) { + return d.color || scale(d.label); + }).each(function (e) { + d3.select(this).attr(e.attributes); + }); - new_parts - .append('span') - .attr('class', 'legend-label') - .style('margin-left', '0.25em') - .text(function(d) { - return d.label; - }); + new_parts.append('span').attr('class', 'legend-label').style('margin-left', '0.25em').text(function (d) { + return d.label; + }); if (scale.domain().length > 0) { - var legendDisplay = (this.config.legend.location === 'bottom' || - this.config.legend.location === 'top') && - !this.parent - ? 'block' - : 'inline-block'; + var legendDisplay = (this.config.legend.location === 'bottom' || this.config.legend.location === 'top') && !this.parent ? 'block' : 'inline-block'; legend.style('display', legendDisplay); } else { legend.style('display', 'none'); @@ -1758,67 +1215,42 @@ } function updateDataMarks() { - this.drawBars( - this.marks.filter(function(f) { - return f.type === 'bar'; - }) - ); - this.drawLines( - this.marks.filter(function(f) { - return f.type === 'line'; - }) - ); - this.drawPoints( - this.marks.filter(function(f) { - return f.type === 'circle'; - }) - ); - this.drawText( - this.marks.filter(function(f) { - return f.type === 'text'; - }) - ); + this.drawBars(this.marks.filter(function (f) { + return f.type === 'bar'; + })); + this.drawLines(this.marks.filter(function (f) { + return f.type === 'line'; + })); + this.drawPoints(this.marks.filter(function (f) { + return f.type === 'circle'; + })); + this.drawText(this.marks.filter(function (f) { + return f.type === 'text'; + })); this.marks.supergroups = this.svg.selectAll('g.supergroup'); } function drawArea(area_drawer, area_data, datum_accessor) { - var class_match = arguments.length > 3 && arguments[3] !== undefined - ? arguments[3] - : 'chart-area'; + var class_match = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'chart-area'; var _this = this; var bind_accessor = arguments[4]; - var attr_accessor = arguments.length > 5 && arguments[5] !== undefined - ? arguments[5] - : function(d) { - return d; - }; + var attr_accessor = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : function (d) { + return d; + }; var area_grps = this.svg.selectAll('.' + class_match).data(area_data, bind_accessor); area_grps.exit().remove(); - area_grps - .enter() - .append('g') - .attr('class', function(d) { - return class_match + ' ' + d.key; - }) - .append('path'); - - var areaPaths = area_grps - .select('path') - .datum(datum_accessor) - .attr('fill', function(d) { - var d_attr = attr_accessor(d); - return d_attr ? _this.colorScale(d_attr[_this.config.color_by]) : null; - }) - .attr( - 'fill-opacity', - this.config.fill_opacity || this.config.fill_opacity === 0 - ? this.config.fill_opacity - : 0.3 - ); + area_grps.enter().append('g').attr('class', function (d) { + return class_match + ' ' + d.key; + }).append('path'); + + var areaPaths = area_grps.select('path').datum(datum_accessor).attr('fill', function (d) { + var d_attr = attr_accessor(d); + return d_attr ? _this.colorScale(d_attr[_this.config.color_by]) : null; + }).attr('fill-opacity', this.config.fill_opacity || this.config.fill_opacity === 0 ? this.config.fill_opacity : 0.3); //don't transition if config says not to var areaPathTransitions = this.config.transitions ? areaPaths.transition() : areaPaths; @@ -1835,32 +1267,27 @@ var rawData = this.raw_data; var config = this.config; - var bar_supergroups = this.svg.selectAll('.bar-supergroup').data(marks, function(d, i) { + var bar_supergroups = this.svg.selectAll('.bar-supergroup').data(marks, function (d, i) { return i + '-' + d.per.join('-'); }); - bar_supergroups.enter().append('g').attr('class', function(d) { + bar_supergroups.enter().append('g').attr('class', function (d) { return 'supergroup bar-supergroup ' + d.id; }); bar_supergroups.exit().remove(); - var bar_groups = bar_supergroups.selectAll('.bar-group').data( - function(d) { - return d.data; - }, - function(d) { - return d.key; - } - ); + var bar_groups = bar_supergroups.selectAll('.bar-group').data(function (d) { + return d.data; + }, function (d) { + return d.key; + }); var old_bar_groups = bar_groups.exit(); var nu_bar_groups = void 0; var bars = void 0; - var oldBarsTrans = config.transitions - ? old_bar_groups.selectAll('.bar').transition() - : old_bar_groups.selectAll('.bar'); + var oldBarsTrans = config.transitions ? old_bar_groups.selectAll('.bar').transition() : old_bar_groups.selectAll('.bar'); var oldBarGroupsTrans = config.transitions ? old_bar_groups.transition() : old_bar_groups; if (config.x.type === 'ordinal') { @@ -1868,327 +1295,207 @@ oldBarGroupsTrans.remove(); - nu_bar_groups = bar_groups.enter().append('g').attr('class', function(d) { + nu_bar_groups = bar_groups.enter().append('g').attr('class', function (d) { return 'bar-group ' + d.key; }); nu_bar_groups.append('title'); - bars = bar_groups.selectAll('rect').data( - function(d) { - return d.values instanceof Array - ? d.values.sort(function(a, b) { - return ( - _this.colorScale.domain().indexOf(b.key) - - _this.colorScale.domain().indexOf(a.key) - ); - }) - : [d]; - }, - function(d) { - return d.key; - } - ); + bars = bar_groups.selectAll('rect').data(function (d) { + return d.values instanceof Array ? d.values.sort(function (a, b) { + return _this.colorScale.domain().indexOf(b.key) - _this.colorScale.domain().indexOf(a.key); + }) : [d]; + }, function (d) { + return d.key; + }); var exitBars = config.transitions ? bars.exit().transition() : bars.exit(); exitBars.attr('y', this.y(0)).attr('height', 0).remove(); - bars - .enter() - .append('rect') - .attr('class', function(d) { - return 'wc-data-mark bar ' + d.key; - }) - .style('clip-path', 'url(#' + chart.id + ')') - .attr('y', this.y(0)) - .attr('height', 0) - .append('title'); - - bars - .attr('shape-rendering', 'crispEdges') - .attr('stroke', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }) - .attr('fill', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); + bars.enter().append('rect').attr('class', function (d) { + return 'wc-data-mark bar ' + d.key; + }).style('clip-path', 'url(#' + chart.id + ')').attr('y', this.y(0)).attr('height', 0).append('title'); + + bars.attr('shape-rendering', 'crispEdges').attr('stroke', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }).attr('fill', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); - bars.each(function(d) { + bars.each(function (d) { var mark = d3.select(this.parentNode.parentNode).datum(); d.tooltip = mark.tooltip; - d.arrange = mark.split && mark.arrange - ? mark.arrange - : mark.split ? 'grouped' : null; - d.subcats = config.legend.order - ? config.legend.order.slice().reverse() - : mark.values && mark.values[mark.split] - ? mark.values[mark.split] - : d3 - .set( - rawData.map(function(m) { - return m[mark.split]; - }) - ) - .values(); + d.arrange = mark.split && mark.arrange ? mark.arrange : mark.split ? 'grouped' : null; + d.subcats = config.legend.order ? config.legend.order.slice().reverse() : mark.values && mark.values[mark.split] ? mark.values[mark.split] : d3.set(rawData.map(function (m) { + return m[mark.split]; + })).values(); d3.select(this).attr(mark.attributes); }); - var xformat = config.marks - .map(function(m) { - return m.summarizeX === 'percent'; - }) - .indexOf(true) > -1 - ? d3.format('0%') - : d3.format(config.x.format); - var yformat = config.marks - .map(function(m) { - return m.summarizeY === 'percent'; - }) - .indexOf(true) > -1 - ? d3.format('0%') - : d3.format(config.y.format); - bars.select('title').text(function(d) { + var xformat = config.marks.map(function (m) { + return m.summarizeX === 'percent'; + }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.x.format); + var yformat = config.marks.map(function (m) { + return m.summarizeY === 'percent'; + }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.y.format); + bars.select('title').text(function (d) { var tt = d.tooltip || ''; - return tt - .replace(/\$x/g, xformat(d.values.x)) - .replace(/\$y/g, yformat(d.values.y)) - .replace(/\[(.+?)\]/g, function(str, orig) { - return d.values.raw[0][orig]; - }); + return tt.replace(/\$x/g, xformat(d.values.x)).replace(/\$y/g, yformat(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { + return d.values.raw[0][orig]; + }); }); var barsTrans = config.transitions ? bars.transition() : bars; - barsTrans - .attr('x', function(d) { - var position = void 0; - if (!d.arrange || d.arrange === 'stacked') { - return _this.x(d.values.x); - } else if (d.arrange === 'nested') { - var _position = d.subcats.indexOf(d.key); - var offset = _position - ? _this.x.rangeBand() / (d.subcats.length * 0.75) / _position - : _this.x.rangeBand(); - return _this.x(d.values.x) + (_this.x.rangeBand() - offset) / 2; - } else { - position = d.subcats.indexOf(d.key); - return ( - _this.x(d.values.x) + _this.x.rangeBand() / d.subcats.length * position - ); - } - }) - .attr('y', function(d) { - if (d.arrange !== 'stacked') { - return _this.y(d.values.y); - } else { - return _this.y(d.values.start); - } - }) - .attr('width', function(d) { - if (!d.arrange || d.arrange === 'stacked') { - return _this.x.rangeBand(); - } else if (d.arrange === 'nested') { - var position = d.subcats.indexOf(d.key); - return position - ? _this.x.rangeBand() / (d.subcats.length * 0.75) / position - : _this.x.rangeBand(); - } else { - return _this.x.rangeBand() / d.subcats.length; - } - }) - .attr('height', function(d) { - return _this.y(0) - _this.y(d.values.y); - }); + barsTrans.attr('x', function (d) { + var position = void 0; + if (!d.arrange || d.arrange === 'stacked') { + return _this.x(d.values.x); + } else if (d.arrange === 'nested') { + var _position = d.subcats.indexOf(d.key); + var offset = _position ? _this.x.rangeBand() / (d.subcats.length * 0.75) / _position : _this.x.rangeBand(); + return _this.x(d.values.x) + (_this.x.rangeBand() - offset) / 2; + } else { + position = d.subcats.indexOf(d.key); + return _this.x(d.values.x) + _this.x.rangeBand() / d.subcats.length * position; + } + }).attr('y', function (d) { + if (d.arrange !== 'stacked') { + return _this.y(d.values.y); + } else { + return _this.y(d.values.start); + } + }).attr('width', function (d) { + if (!d.arrange || d.arrange === 'stacked') { + return _this.x.rangeBand(); + } else if (d.arrange === 'nested') { + var position = d.subcats.indexOf(d.key); + return position ? _this.x.rangeBand() / (d.subcats.length * 0.75) / position : _this.x.rangeBand(); + } else { + return _this.x.rangeBand() / d.subcats.length; + } + }).attr('height', function (d) { + return _this.y(0) - _this.y(d.values.y); + }); } else if (config.y.type === 'ordinal') { oldBarsTrans.attr('x', this.x(0)).attr('width', 0); oldBarGroupsTrans.remove(); - nu_bar_groups = bar_groups.enter().append('g').attr('class', function(d) { + nu_bar_groups = bar_groups.enter().append('g').attr('class', function (d) { return 'bar-group ' + d.key; }); nu_bar_groups.append('title'); - bars = bar_groups.selectAll('rect').data( - function(d) { - return d.values instanceof Array - ? d.values.sort(function(a, b) { - return ( - _this.colorScale.domain().indexOf(b.key) - - _this.colorScale.domain().indexOf(a.key) - ); - }) - : [d]; - }, - function(d) { - return d.key; - } - ); + bars = bar_groups.selectAll('rect').data(function (d) { + return d.values instanceof Array ? d.values.sort(function (a, b) { + return _this.colorScale.domain().indexOf(b.key) - _this.colorScale.domain().indexOf(a.key); + }) : [d]; + }, function (d) { + return d.key; + }); var _exitBars = config.transitions ? bars.exit().transition() : bars.exit(); _exitBars.attr('x', this.x(0)).attr('width', 0).remove(); - bars - .enter() - .append('rect') - .attr('class', function(d) { - return 'wc-data-mark bar ' + d.key; - }) - .style('clip-path', 'url(#' + chart.id + ')') - .attr('x', this.x(0)) - .attr('width', 0) - .append('title'); - - bars - .attr('shape-rendering', 'crispEdges') - .attr('stroke', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }) - .attr('fill', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); + bars.enter().append('rect').attr('class', function (d) { + return 'wc-data-mark bar ' + d.key; + }).style('clip-path', 'url(#' + chart.id + ')').attr('x', this.x(0)).attr('width', 0).append('title'); + + bars.attr('shape-rendering', 'crispEdges').attr('stroke', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }).attr('fill', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); - bars.each(function(d) { + bars.each(function (d) { var mark = d3.select(this.parentNode.parentNode).datum(); - d.arrange = mark.split && mark.arrange - ? mark.arrange - : mark.split ? 'grouped' : null; - d.subcats = config.legend.order - ? config.legend.order.slice().reverse() - : mark.values && mark.values[mark.split] - ? mark.values[mark.split] - : d3 - .set( - rawData.map(function(m) { - return m[mark.split]; - }) - ) - .values(); + d.arrange = mark.split && mark.arrange ? mark.arrange : mark.split ? 'grouped' : null; + d.subcats = config.legend.order ? config.legend.order.slice().reverse() : mark.values && mark.values[mark.split] ? mark.values[mark.split] : d3.set(rawData.map(function (m) { + return m[mark.split]; + })).values(); d.tooltip = mark.tooltip; d3.select(this).attr(mark.attributes); }); - var _xformat = config.marks - .map(function(m) { - return m.summarizeX === 'percent'; - }) - .indexOf(true) > -1 - ? d3.format('0%') - : d3.format(config.x.format); - var _yformat = config.marks - .map(function(m) { - return m.summarizeY === 'percent'; - }) - .indexOf(true) > -1 - ? d3.format('0%') - : d3.format(config.y.format); - bars.select('title').text(function(d) { + var _xformat = config.marks.map(function (m) { + return m.summarizeX === 'percent'; + }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.x.format); + var _yformat = config.marks.map(function (m) { + return m.summarizeY === 'percent'; + }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.y.format); + bars.select('title').text(function (d) { var tt = d.tooltip || ''; - return tt - .replace(/\$x/g, _xformat(d.values.x)) - .replace(/\$y/g, _yformat(d.values.y)) - .replace(/\[(.+?)\]/g, function(str, orig) { - return d.values.raw[0][orig]; - }); + return tt.replace(/\$x/g, _xformat(d.values.x)).replace(/\$y/g, _yformat(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { + return d.values.raw[0][orig]; + }); }); var _barsTrans = config.transitions ? bars.transition() : bars; - _barsTrans - .attr('x', function(d) { - if (d.arrange === 'stacked' || !d.arrange) { - return d.values.start !== undefined ? _this.x(d.values.start) : _this.x(0); - } else { - return _this.x(0); - } - }) - .attr('y', function(d) { - if (d.arrange === 'nested') { - var position = d.subcats.indexOf(d.key); - var offset = position - ? _this.y.rangeBand() / (d.subcats.length * 0.75) / position - : _this.y.rangeBand(); - return _this.y(d.values.y) + (_this.y.rangeBand() - offset) / 2; - } else if (d.arrange === 'grouped') { - var _position2 = d.subcats.indexOf(d.key); - return ( - _this.y(d.values.y) + - _this.y.rangeBand() / d.subcats.length * _position2 - ); - } else { - return _this.y(d.values.y); - } - }) - .attr('width', function(d) { - return _this.x(d.values.x) - _this.x(0); - }) - .attr('height', function(d) { - if (config.y.type === 'quantile') { - return 20; - } else if (d.arrange === 'nested') { - var position = d.subcats.indexOf(d.key); - return position - ? _this.y.rangeBand() / (d.subcats.length * 0.75) / position - : _this.y.rangeBand(); - } else if (d.arrange === 'grouped') { - return _this.y.rangeBand() / d.subcats.length; - } else { - return _this.y.rangeBand(); - } - }); + _barsTrans.attr('x', function (d) { + if (d.arrange === 'stacked' || !d.arrange) { + return d.values.start !== undefined ? _this.x(d.values.start) : _this.x(0); + } else { + return _this.x(0); + } + }).attr('y', function (d) { + if (d.arrange === 'nested') { + var position = d.subcats.indexOf(d.key); + var offset = position ? _this.y.rangeBand() / (d.subcats.length * 0.75) / position : _this.y.rangeBand(); + return _this.y(d.values.y) + (_this.y.rangeBand() - offset) / 2; + } else if (d.arrange === 'grouped') { + var _position2 = d.subcats.indexOf(d.key); + return _this.y(d.values.y) + _this.y.rangeBand() / d.subcats.length * _position2; + } else { + return _this.y(d.values.y); + } + }).attr('width', function (d) { + return _this.x(d.values.x) - _this.x(0); + }).attr('height', function (d) { + if (config.y.type === 'quantile') { + return 20; + } else if (d.arrange === 'nested') { + var position = d.subcats.indexOf(d.key); + return position ? _this.y.rangeBand() / (d.subcats.length * 0.75) / position : _this.y.rangeBand(); + } else if (d.arrange === 'grouped') { + return _this.y.rangeBand() / d.subcats.length; + } else { + return _this.y.rangeBand(); + } + }); } else if (['linear', 'log'].indexOf(config.x.type) > -1 && config.x.bin) { oldBarsTrans.attr('y', this.y(0)).attr('height', 0); oldBarGroupsTrans.remove(); - nu_bar_groups = bar_groups.enter().append('g').attr('class', function(d) { + nu_bar_groups = bar_groups.enter().append('g').attr('class', function (d) { return 'bar-group ' + d.key; }); nu_bar_groups.append('title'); - bars = bar_groups.selectAll('rect').data( - function(d) { - return d.values instanceof Array ? d.values : [d]; - }, - function(d) { - return d.key; - } - ); + bars = bar_groups.selectAll('rect').data(function (d) { + return d.values instanceof Array ? d.values : [d]; + }, function (d) { + return d.key; + }); var _exitBars2 = config.transitions ? bars.exit().transition() : bars.exit(); _exitBars2.attr('y', this.y(0)).attr('height', 0).remove(); - bars - .enter() - .append('rect') - .attr('class', function(d) { - return 'wc-data-mark bar ' + d.key; - }) - .style('clip-path', 'url(#' + chart.id + ')') - .attr('y', this.y(0)) - .attr('height', 0) - .append('title'); - - bars - .attr('shape-rendering', 'crispEdges') - .attr('stroke', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }) - .attr('fill', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); + bars.enter().append('rect').attr('class', function (d) { + return 'wc-data-mark bar ' + d.key; + }).style('clip-path', 'url(#' + chart.id + ')').attr('y', this.y(0)).attr('height', 0).append('title'); + + bars.attr('shape-rendering', 'crispEdges').attr('stroke', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }).attr('fill', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); - bars.each(function(d) { + bars.each(function (d) { var mark = d3.select(this.parentNode.parentNode).datum(); d.arrange = mark.split ? mark.arrange : null; - d.subcats = config.legend.order - ? config.legend.order.slice().reverse() - : mark.values && mark.values[mark.split] - ? mark.values[mark.split] - : d3 - .set( - rawData.map(function(m) { - return m[mark.split]; - }) - ) - .values(); + d.subcats = config.legend.order ? config.legend.order.slice().reverse() : mark.values && mark.values[mark.split] ? mark.values[mark.split] : d3.set(rawData.map(function (m) { + return m[mark.split]; + })).values(); d3.select(this).attr(mark.attributes); var parent = d3.select(this.parentNode).datum(); - var rangeSet = parent.key.split(',').map(function(m) { + var rangeSet = parent.key.split(',').map(function (m) { return +m; }); d.rangeLow = d3.min(rangeSet); @@ -2196,108 +1503,68 @@ d.tooltip = mark.tooltip; }); - var _xformat2 = config.marks - .map(function(m) { - return m.summarizeX === 'percent'; - }) - .indexOf(true) > -1 - ? d3.format('0%') - : d3.format(config.x.format); - var _yformat2 = config.marks - .map(function(m) { - return m.summarizeY === 'percent'; - }) - .indexOf(true) > -1 - ? d3.format('0%') - : d3.format(config.y.format); - bars.select('title').text(function(d) { + var _xformat2 = config.marks.map(function (m) { + return m.summarizeX === 'percent'; + }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.x.format); + var _yformat2 = config.marks.map(function (m) { + return m.summarizeY === 'percent'; + }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.y.format); + bars.select('title').text(function (d) { var tt = d.tooltip || ''; - return tt - .replace(/\$x/g, _xformat2(d.values.x)) - .replace(/\$y/g, _yformat2(d.values.y)) - .replace(/\[(.+?)\]/g, function(str, orig) { - return d.values.raw[0][orig]; - }); + return tt.replace(/\$x/g, _xformat2(d.values.x)).replace(/\$y/g, _yformat2(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { + return d.values.raw[0][orig]; + }); }); var _barsTrans2 = config.transitions ? bars.transition() : bars; - _barsTrans2 - .attr('x', function(d) { - return _this.x(d.rangeLow); - }) - .attr('y', function(d) { - if (d.arrange !== 'stacked') { - return _this.y(d.values.y); - } else { - return _this.y(d.values.start); - } - }) - .attr('width', function(d) { - return _this.x(d.rangeHigh) - _this.x(d.rangeLow); - }) - .attr('height', function(d) { - return _this.y(0) - _this.y(d.values.y); - }); - } else if ( - ['linear', 'log'].indexOf(config.y.type) > -1 && - config.y.type === 'linear' && - config.y.bin - ) { + _barsTrans2.attr('x', function (d) { + return _this.x(d.rangeLow); + }).attr('y', function (d) { + if (d.arrange !== 'stacked') { + return _this.y(d.values.y); + } else { + return _this.y(d.values.start); + } + }).attr('width', function (d) { + return _this.x(d.rangeHigh) - _this.x(d.rangeLow); + }).attr('height', function (d) { + return _this.y(0) - _this.y(d.values.y); + }); + } else if (['linear', 'log'].indexOf(config.y.type) > -1 && config.y.type === 'linear' && config.y.bin) { oldBarsTrans.attr('x', this.x(0)).attr('width', 0); oldBarGroupsTrans.remove(); - nu_bar_groups = bar_groups.enter().append('g').attr('class', function(d) { + nu_bar_groups = bar_groups.enter().append('g').attr('class', function (d) { return 'bar-group ' + d.key; }); nu_bar_groups.append('title'); - bars = bar_groups.selectAll('rect').data( - function(d) { - return d.values instanceof Array ? d.values : [d]; - }, - function(d) { - return d.key; - } - ); + bars = bar_groups.selectAll('rect').data(function (d) { + return d.values instanceof Array ? d.values : [d]; + }, function (d) { + return d.key; + }); var _exitBars3 = config.transitions ? bars.exit().transition() : bars.exit(); _exitBars3.attr('x', this.x(0)).attr('width', 0).remove(); - bars - .enter() - .append('rect') - .attr('class', function(d) { - return 'wc-data-mark bar ' + d.key; - }) - .style('clip-path', 'url(#' + chart.id + ')') - .attr('x', this.x(0)) - .attr('width', 0) - .append('title'); - - bars - .attr('shape-rendering', 'crispEdges') - .attr('stroke', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }) - .attr('fill', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); + bars.enter().append('rect').attr('class', function (d) { + return 'wc-data-mark bar ' + d.key; + }).style('clip-path', 'url(#' + chart.id + ')').attr('x', this.x(0)).attr('width', 0).append('title'); - bars.each(function(d) { + bars.attr('shape-rendering', 'crispEdges').attr('stroke', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }).attr('fill', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); + + bars.each(function (d) { var mark = d3.select(this.parentNode.parentNode).datum(); d.arrange = mark.split ? mark.arrange : null; - d.subcats = config.legend.order - ? config.legend.order.slice().reverse() - : mark.values && mark.values[mark.split] - ? mark.values[mark.split] - : d3 - .set( - rawData.map(function(m) { - return m[mark.split]; - }) - ) - .values(); + d.subcats = config.legend.order ? config.legend.order.slice().reverse() : mark.values && mark.values[mark.split] ? mark.values[mark.split] : d3.set(rawData.map(function (m) { + return m[mark.split]; + })).values(); var parent = d3.select(this.parentNode).datum(); - var rangeSet = parent.key.split(',').map(function(m) { + var rangeSet = parent.key.split(',').map(function (m) { return +m; }); d.rangeLow = d3.min(rangeSet); @@ -2305,48 +1572,33 @@ d.tooltip = mark.tooltip; }); - var _xformat3 = config.marks - .map(function(m) { - return m.summarizeX === 'percent'; - }) - .indexOf(true) > -1 - ? d3.format('0%') - : d3.format(config.x.format); - var _yformat3 = config.marks - .map(function(m) { - return m.summarizeY === 'percent'; - }) - .indexOf(true) > -1 - ? d3.format('0%') - : d3.format(config.y.format); - bars.select('title').text(function(d) { + var _xformat3 = config.marks.map(function (m) { + return m.summarizeX === 'percent'; + }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.x.format); + var _yformat3 = config.marks.map(function (m) { + return m.summarizeY === 'percent'; + }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.y.format); + bars.select('title').text(function (d) { var tt = d.tooltip || ''; - return tt - .replace(/\$x/g, _xformat3(d.values.x)) - .replace(/\$y/g, _yformat3(d.values.y)) - .replace(/\[(.+?)\]/g, function(str, orig) { - return d.values.raw[0][orig]; - }); + return tt.replace(/\$x/g, _xformat3(d.values.x)).replace(/\$y/g, _yformat3(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { + return d.values.raw[0][orig]; + }); }); var _barsTrans3 = config.transitions ? bars.transition() : bars; - _barsTrans3 - .attr('x', function(d) { - if (d.arrange === 'stacked') { - return _this.x(d.values.start); - } else { - return _this.x(0); - } - }) - .attr('y', function(d) { - return _this.y(d.rangeHigh); - }) - .attr('width', function(d) { - return _this.x(d.values.x); - }) - .attr('height', function(d) { - return _this.y(d.rangeLow) - _this.y(d.rangeHigh); - }); + _barsTrans3.attr('x', function (d) { + if (d.arrange === 'stacked') { + return _this.x(d.values.start); + } else { + return _this.x(0); + } + }).attr('y', function (d) { + return _this.y(d.rangeHigh); + }).attr('width', function (d) { + return _this.x(d.values.x); + }).attr('height', function (d) { + return _this.y(d.rangeLow) - _this.y(d.rangeHigh); + }); } else { oldBarsTrans.attr('y', this.y(0)).attr('height', 0); oldBarGroupsTrans.remove(); @@ -2354,7 +1606,7 @@ } //Link to the d3.selection from the data - bar_supergroups.each(function(d) { + bar_supergroups.each(function (d) { d.supergroup = d3.select(this); d.groups = d.supergroup.selectAll('.bar-group'); }); @@ -2365,92 +1617,59 @@ var chart = this; var config = this.config; - var line = d3.svg - .line() - .interpolate(config.interpolate) - .x(function(d) { - return config.x.type === 'linear' || config.x.type == 'log' - ? _this.x(+d.values.x) - : config.x.type === 'time' - ? _this.x(new Date(d.values.x)) - : _this.x(d.values.x) + _this.x.rangeBand() / 2; - }) - .y(function(d) { - return config.y.type === 'linear' || config.y.type == 'log' - ? _this.y(+d.values.y) - : config.y.type === 'time' - ? _this.y(new Date(d.values.y)) - : _this.y(d.values.y) + _this.y.rangeBand() / 2; - }); + var line = d3.svg.line().interpolate(config.interpolate).x(function (d) { + return config.x.type === 'linear' || config.x.type == 'log' ? _this.x(+d.values.x) : config.x.type === 'time' ? _this.x(new Date(d.values.x)) : _this.x(d.values.x) + _this.x.rangeBand() / 2; + }).y(function (d) { + return config.y.type === 'linear' || config.y.type == 'log' ? _this.y(+d.values.y) : config.y.type === 'time' ? _this.y(new Date(d.values.y)) : _this.y(d.values.y) + _this.y.rangeBand() / 2; + }); - var line_supergroups = this.svg.selectAll('.line-supergroup').data(marks, function(d, i) { + var line_supergroups = this.svg.selectAll('.line-supergroup').data(marks, function (d, i) { return i + '-' + d.per.join('-'); }); - line_supergroups.enter().append('g').attr('class', function(d) { + line_supergroups.enter().append('g').attr('class', function (d) { return 'supergroup line-supergroup ' + d.id; }); line_supergroups.exit().remove(); - var line_grps = line_supergroups.selectAll('.line').data( - function(d) { - return d.data; - }, - function(d) { - return d.key; - } - ); + var line_grps = line_supergroups.selectAll('.line').data(function (d) { + return d.data; + }, function (d) { + return d.key; + }); line_grps.exit().remove(); - var nu_line_grps = line_grps.enter().append('g').attr('class', function(d) { + var nu_line_grps = line_grps.enter().append('g').attr('class', function (d) { return d.key + ' line'; }); nu_line_grps.append('path'); nu_line_grps.append('title'); - var linePaths = line_grps - .select('path') - .attr('class', 'wc-data-mark') - .style('clip-path', 'url(#' + chart.id + ')') - .datum(function(d) { - return d.values; - }) - .attr('stroke', function(d) { - return _this.colorScale(d[0].values.raw[0][config.color_by]); - }) - .attr( - 'stroke-width', - config.stroke_width ? config.stroke_width : config.flex_stroke_width - ) - .attr('stroke-linecap', 'round') - .attr('fill', 'none'); + var linePaths = line_grps.select('path').attr('class', 'wc-data-mark').style('clip-path', 'url(#' + chart.id + ')').datum(function (d) { + return d.values; + }).attr('stroke', function (d) { + return _this.colorScale(d[0].values.raw[0][config.color_by]); + }).attr('stroke-width', config.stroke_width ? config.stroke_width : config.flex_stroke_width).attr('stroke-linecap', 'round').attr('fill', 'none'); var linePathsTrans = config.transitions ? linePaths.transition() : linePaths; linePathsTrans.attr('d', line); - line_grps.each(function(d) { + line_grps.each(function (d) { var mark = d3.select(this.parentNode).datum(); d.tooltip = mark.tooltip; d3.select(this).select('path').attr(mark.attributes); }); - line_grps.select('title').text(function(d) { + line_grps.select('title').text(function (d) { var tt = d.tooltip || ''; - var xformat = config.x.summary === 'percent' - ? d3.format('0%') - : d3.format(config.x.format); - var yformat = config.y.summary === 'percent' - ? d3.format('0%') - : d3.format(config.y.format); - return tt - .replace(/\$x/g, xformat(d.values.x)) - .replace(/\$y/g, yformat(d.values.y)) - .replace(/\[(.+?)\]/g, function(str, orig) { - return d.values[0].values.raw[0][orig]; - }); + var xformat = config.x.summary === 'percent' ? d3.format('0%') : d3.format(config.x.format); + var yformat = config.y.summary === 'percent' ? d3.format('0%') : d3.format(config.y.format); + return tt.replace(/\$x/g, xformat(d.values.x)).replace(/\$y/g, yformat(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { + return d.values[0].values.raw[0][orig]; + }); }); //Link to the d3.selection from the data - line_supergroups.each(function(d) { + line_supergroups.each(function (d) { d.supergroup = d3.select(this); d.groups = d.supergroup.selectAll('g.line'); d.paths = d.groups.select('path'); @@ -2464,104 +1683,69 @@ var chart = this; var config = this.config; - var point_supergroups = this.svg.selectAll('.point-supergroup').data(marks, function(d, i) { + var point_supergroups = this.svg.selectAll('.point-supergroup').data(marks, function (d, i) { return i + '-' + d.per.join('-'); }); - point_supergroups.enter().append('g').attr('class', function(d) { + point_supergroups.enter().append('g').attr('class', function (d) { return 'supergroup point-supergroup ' + d.id; }); point_supergroups.exit().remove(); - var points = point_supergroups.selectAll('.point').data( - function(d) { - return d.data; - }, - function(d) { - return d.key; - } - ); + var points = point_supergroups.selectAll('.point').data(function (d) { + return d.data; + }, function (d) { + return d.key; + }); var oldPoints = points.exit(); - var oldPointsTrans = config.transitions - ? oldPoints.selectAll('circle').transition() - : oldPoints.selectAll('circle'); + var oldPointsTrans = config.transitions ? oldPoints.selectAll('circle').transition() : oldPoints.selectAll('circle'); oldPointsTrans.attr('r', 0); var oldPointGroupTrans = config.transitions ? oldPoints.transition() : oldPoints; oldPointGroupTrans.remove(); - var nupoints = points.enter().append('g').attr('class', function(d) { + var nupoints = points.enter().append('g').attr('class', function (d) { return d.key + ' point'; }); nupoints.append('circle').attr('class', 'wc-data-mark').attr('r', 0); nupoints.append('title'); //static attributes - points - .select('circle') - .style('clip-path', 'url(#' + chart.id + ')') - .attr( - 'fill-opacity', - config.fill_opacity || config.fill_opacity === 0 ? config.fill_opacity : 0.6 - ) - .attr('fill', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }) - .attr('stroke', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); + points.select('circle').style('clip-path', 'url(#' + chart.id + ')').attr('fill-opacity', config.fill_opacity || config.fill_opacity === 0 ? config.fill_opacity : 0.6).attr('fill', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }).attr('stroke', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); //attach mark info - points.each(function(d) { + points.each(function (d) { var mark = d3.select(this.parentNode).datum(); d.mark = mark; d3.select(this).select('circle').attr(mark.attributes); }); //animated attributes - var pointsTrans = config.transitions - ? points.select('circle').transition() - : points.select('circle'); - pointsTrans - .attr('r', function(d) { - return d.mark.radius || config.flex_point_size; - }) - .attr('cx', function(d) { - var x_pos = _this.x(d.values.x) || 0; - return config.x.type === 'ordinal' ? x_pos + _this.x.rangeBand() / 2 : x_pos; - }) - .attr('cy', function(d) { - var y_pos = _this.y(d.values.y) || 0; - return config.y.type === 'ordinal' ? y_pos + _this.y.rangeBand() / 2 : y_pos; - }); + var pointsTrans = config.transitions ? points.select('circle').transition() : points.select('circle'); + pointsTrans.attr('r', function (d) { + return d.mark.radius || config.flex_point_size; + }).attr('cx', function (d) { + var x_pos = _this.x(d.values.x) || 0; + return config.x.type === 'ordinal' ? x_pos + _this.x.rangeBand() / 2 : x_pos; + }).attr('cy', function (d) { + var y_pos = _this.y(d.values.y) || 0; + return config.y.type === 'ordinal' ? y_pos + _this.y.rangeBand() / 2 : y_pos; + }); - points.select('title').text(function(d) { + points.select('title').text(function (d) { var tt = d.mark.tooltip || ''; - var xformat = config.x.summary === 'percent' - ? d3.format('0%') - : config.x.type === 'time' - ? d3.time.format(config.x.format) - : d3.format(config.x.format); - var yformat = config.y.summary === 'percent' - ? d3.format('0%') - : config.y.type === 'time' - ? d3.time.format(config.y.format) - : d3.format(config.y.format); - return tt - .replace( - /\$x/g, - config.x.type === 'time' ? xformat(new Date(d.values.x)) : xformat(d.values.x) - ) - .replace( - /\$y/g, - config.y.type === 'time' ? yformat(new Date(d.values.y)) : yformat(d.values.y) - ) - .replace(/\[(.+?)\]/g, function(str, orig) { - return d.values.raw[0][orig]; - }); + var xformat = config.x.summary === 'percent' ? d3.format('0%') : config.x.type === 'time' ? d3.time.format(config.x.format) : d3.format(config.x.format); + var yformat = config.y.summary === 'percent' ? d3.format('0%') : config.y.type === 'time' ? d3.time.format(config.y.format) : d3.format(config.y.format); + return tt.replace(/\$x/g, config.x.type === 'time' ? xformat(new Date(d.values.x)) : xformat(d.values.x)).replace(/\$y/g, config.y.type === 'time' ? yformat(new Date(d.values.y)) : yformat(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { + return d.values.raw[0][orig]; + }); }); //Link to the d3.selection from the data - point_supergroups.each(function(d) { + point_supergroups.each(function (d) { d.supergroup = d3.select(this); d.groups = d.supergroup.selectAll('g.point'); d.circles = d.groups.select('circle'); @@ -2576,24 +1760,21 @@ var chart = this; var config = this.config; - var textSupergroups = this.svg.selectAll('.text-supergroup').data(marks, function(d, i) { + var textSupergroups = this.svg.selectAll('.text-supergroup').data(marks, function (d, i) { return i + '-' + d.per.join('-'); }); - textSupergroups.enter().append('g').attr('class', function(d) { + textSupergroups.enter().append('g').attr('class', function (d) { return 'supergroup text-supergroup ' + d.id; }); textSupergroups.exit().remove(); - var texts = textSupergroups.selectAll('.text').data( - function(d) { - return d.data; - }, - function(d) { - return d.key; - } - ); + var texts = textSupergroups.selectAll('.text').data(function (d) { + return d.data; + }, function (d) { + return d.key; + }); var oldTexts = texts.exit(); // don't need to transition position of outgoing text @@ -2602,7 +1783,7 @@ var oldTextGroupTrans = config.transitions ? oldTexts.transition() : oldTexts; oldTextGroupTrans.remove(); - var nutexts = texts.enter().append('g').attr('class', function(d) { + var nutexts = texts.enter().append('g').attr('class', function (d) { return d.key + ' text'; }); nutexts.append('text').attr('class', 'wc-data-mark'); @@ -2616,46 +1797,25 @@ texts.each(attachMarks); // parse text like tooltips - texts.select('text').style('clip-path', 'url(#' + chart.id + ')').text(function(d) { + texts.select('text').style('clip-path', 'url(#' + chart.id + ')').text(function (d) { var tt = d.mark.text || ''; - var xformat = config.x.summary === 'percent' - ? d3.format('0%') - : config.x.type === 'time' - ? d3.time.format(config.x.format) - : d3.format(config.x.format); - var yformat = config.y.summary === 'percent' - ? d3.format('0%') - : config.y.type === 'time' - ? d3.time.format(config.y.format) - : d3.format(config.y.format); - return tt - .replace( - /\$x/g, - config.x.type === 'time' ? xformat(new Date(d.values.x)) : xformat(d.values.x) - ) - .replace( - /\$y/g, - config.y.type === 'time' ? yformat(new Date(d.values.y)) : yformat(d.values.y) - ) - .replace(/\[(.+?)\]/g, function(str, orig) { - return d.values.raw[0][orig]; - }); + var xformat = config.x.summary === 'percent' ? d3.format('0%') : config.x.type === 'time' ? d3.time.format(config.x.format) : d3.format(config.x.format); + var yformat = config.y.summary === 'percent' ? d3.format('0%') : config.y.type === 'time' ? d3.time.format(config.y.format) : d3.format(config.y.format); + return tt.replace(/\$x/g, config.x.type === 'time' ? xformat(new Date(d.values.x)) : xformat(d.values.x)).replace(/\$y/g, config.y.type === 'time' ? yformat(new Date(d.values.y)) : yformat(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { + return d.values.raw[0][orig]; + }); }); // animated attributes - var textsTrans = config.transitions - ? texts.select('text').transition() - : texts.select('text'); - textsTrans - .attr('x', function(d) { - var xPos = _this.x(d.values.x) || 0; - return config.x.type === 'ordinal' ? xPos + _this.x.rangeBand() / 2 : xPos; - }) - .attr('y', function(d) { - var yPos = _this.y(d.values.y) || 0; - return config.y.type === 'ordinal' ? yPos + _this.y.rangeBand() / 2 : yPos; - }); + var textsTrans = config.transitions ? texts.select('text').transition() : texts.select('text'); + textsTrans.attr('x', function (d) { + var xPos = _this.x(d.values.x) || 0; + return config.x.type === 'ordinal' ? xPos + _this.x.rangeBand() / 2 : xPos; + }).attr('y', function (d) { + var yPos = _this.y(d.values.y) || 0; + return config.y.type === 'ordinal' ? yPos + _this.y.rangeBand() / 2 : yPos; + }); //add a reference to the selection from it's data - textSupergroups.each(function(d) { + textSupergroups.each(function (d) { d.supergroup = d3.select(this); d.groups = d.supergroup.selectAll('g.text'); d.texts = d.groups.select('text'); @@ -2664,9 +1824,7 @@ } function destroy() { - var destroyControls = arguments.length > 0 && arguments[0] !== undefined - ? arguments[0] - : true; + var destroyControls = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; //run onDestroy callback this.events.onDestroy.call(this); @@ -2747,16 +1905,8 @@ onDestroy: function onDestroy() {} }; - thisChart.on = function(event, callback) { - var possible_events = [ - 'init', - 'layout', - 'preprocess', - 'datatransform', - 'draw', - 'resize', - 'destroy' - ]; + thisChart.on = function (event, callback) { + var possible_events = ['init', 'layout', 'preprocess', 'datatransform', 'draw', 'resize', 'destroy']; if (possible_events.indexOf(event) < 0) { return; } @@ -2776,9 +1926,9 @@ function changeOption(option, value, callback, draw) { var _this = this; - this.targets.forEach(function(target) { + this.targets.forEach(function (target) { if (option instanceof Array) { - option.forEach(function(o) { + option.forEach(function (o) { return _this.stringAccessor(target.config, o, value); }); } else { @@ -2797,13 +1947,8 @@ var colNames = d3.keys(dataset[0]); - this.config.inputs.forEach(function(input, i) { - if (input.type === 'subsetter' && colNames.indexOf(input.value_col) === -1) - throw new Error( - 'Error in settings object: the value "' + - input.value_col + - '" does not match any column in the provided dataset.' - ); + this.config.inputs.forEach(function (input, i) { + if (input.type === 'subsetter' && colNames.indexOf(input.value_col) === -1) throw new Error('Error in settings object: the value "' + input.value_col + '" does not match any column in the provided dataset.'); //Draw the chart when a control changes unless the user specifies otherwise. input.draw = input.draw === undefined ? true : input.draw; @@ -2813,10 +1958,9 @@ function controlUpdate() { var _this = this; - if (this.config.inputs && this.config.inputs.length && this.config.inputs[0]) - this.config.inputs.forEach(function(input) { - return _this.makeControlItem(input); - }); + if (this.config.inputs && this.config.inputs.length && this.config.inputs[0]) this.config.inputs.forEach(function (input) { + return _this.makeControlItem(input); + }); } function destroy$1() { @@ -2837,21 +1981,13 @@ } function makeControlItem(control) { - var control_wrap = this.wrap - .append('div') - .attr('class', 'control-group') - .classed('inline', control.inline) - .datum(control); + var control_wrap = this.wrap.append('div').attr('class', 'control-group').classed('inline', control.inline).datum(control); //Add control label span. - var ctrl_label = control_wrap - .append('span') - .attr('class', 'wc-control-label') - .text(control.label); + var ctrl_label = control_wrap.append('span').attr('class', 'wc-control-label').text(control.label); //Add control _Required_ text to control label span. - if (control.required) - ctrl_label.append('span').attr('class', 'label label-required').text('Required'); + if (control.required) ctrl_label.append('span').attr('class', 'label label-required').text('Required'); //Add control description span. control_wrap.append('span').attr('class', 'span-description').text(control.description); @@ -2873,9 +2009,7 @@ } else if (control.type === 'subsetter') { this.makeSubsetterControl(control, control_wrap); } else { - throw new Error( - 'Each control must have a type! Choose from: "text", "number", "list", "dropdown", "btngroup", "checkbox", "radio", or "subsetter".' - ); + throw new Error('Each control must have a type! Choose from: "text", "number", "list", "dropdown", "btngroup", "checkbox", "radio", or "subsetter".'); } } @@ -2886,21 +2020,14 @@ var btn_wrap = control_wrap.append('div').attr('class', 'btn-group'); - var changers = btn_wrap - .selectAll('button') - .data(option_data) - .enter() - .append('button') - .attr('class', 'btn btn-default btn-sm') - .text(function(d) { - return d; - }) - .classed('btn-primary', function(d) { - return _this.stringAccessor(_this.targets[0].config, control.option) === d; - }); + var changers = btn_wrap.selectAll('button').data(option_data).enter().append('button').attr('class', 'btn btn-default btn-sm').text(function (d) { + return d; + }).classed('btn-primary', function (d) { + return _this.stringAccessor(_this.targets[0].config, control.option) === d; + }); - changers.on('click', function(d) { - changers.each(function(e) { + changers.on('click', function (d) { + changers.each(function (e) { d3.select(this).classed('btn-primary', e === d); }); _this.changeOption(control.option, d, control.callback, control.draw); @@ -2910,16 +2037,11 @@ function makeCheckboxControl(control, control_wrap) { var _this = this; - var changer = control_wrap - .append('input') - .attr('type', 'checkbox') - .attr('class', 'changer') - .datum(control) - .property('checked', function(d) { - return _this.stringAccessor(_this.targets[0].config, control.option); - }); + var changer = control_wrap.append('input').attr('type', 'checkbox').attr('class', 'changer').datum(control).property('checked', function (d) { + return _this.stringAccessor(_this.targets[0].config, control.option); + }); - changer.on('change', function(d) { + changer.on('change', function (d) { var value = changer.property('checked'); _this.changeOption(d.option, value, control.callback, control.draw); }); @@ -2929,54 +2051,33 @@ var _this = this; var mainOption = control.option || control.options[0]; - var changer = control_wrap - .append('select') - .attr('class', 'changer') - .attr('multiple', control.multiple ? true : null) - .datum(control); - - var opt_values = control.values && control.values instanceof Array - ? control.values - : control.values - ? d3 - .set( - this.data.map(function(m) { - return m[_this.targets[0].config[control.values]]; - }) - ) - .values() - : d3.keys(this.data[0]); + var changer = control_wrap.append('select').attr('class', 'changer').attr('multiple', control.multiple ? true : null).datum(control); + + var opt_values = control.values && control.values instanceof Array ? control.values : control.values ? d3.set(this.data.map(function (m) { + return m[_this.targets[0].config[control.values]]; + })).values() : d3.keys(this.data[0]); if (!control.require || control.none) { opt_values.unshift('None'); } - var options = changer - .selectAll('option') - .data(opt_values) - .enter() - .append('option') - .text(function(d) { - return d; - }) - .property('selected', function(d) { - return _this.stringAccessor(_this.targets[0].config, mainOption) === d; - }); + var options = changer.selectAll('option').data(opt_values).enter().append('option').text(function (d) { + return d; + }).property('selected', function (d) { + return _this.stringAccessor(_this.targets[0].config, mainOption) === d; + }); - changer.on('change', function(d) { + changer.on('change', function (d) { var value = changer.property('value') === 'None' ? null : changer.property('value'); if (control.multiple) { - value = options - .filter(function(f) { - return d3.select(this).property('selected'); - })[0] - .map(function(m) { - return d3.select(m).property('value'); - }) - .filter(function(f) { - return f !== 'None'; - }); + value = options.filter(function (f) { + return d3.select(this).property('selected'); + })[0].map(function (m) { + return d3.select(m).property('value'); + }).filter(function (f) { + return f !== 'None'; + }); } if (control.options) { @@ -2992,21 +2093,14 @@ function makeListControl(control, control_wrap) { var _this = this; - var changer = control_wrap - .append('input') - .attr('type', 'text') - .attr('class', 'changer') - .datum(control) - .property('value', function(d) { - return _this.stringAccessor(_this.targets[0].config, control.option); - }); + var changer = control_wrap.append('input').attr('type', 'text').attr('class', 'changer').datum(control).property('value', function (d) { + return _this.stringAccessor(_this.targets[0].config, control.option); + }); - changer.on('change', function(d) { - var value = changer.property('value') - ? changer.property('value').split(',').map(function(m) { - return m.trim(); - }) - : null; + changer.on('change', function (d) { + var value = changer.property('value') ? changer.property('value').split(',').map(function (m) { + return m.trim(); + }) : null; _this.changeOption(control.option, value, control.callback, control.draw); }); } @@ -3014,19 +2108,11 @@ function makeNumberControl(control, control_wrap) { var _this = this; - var changer = control_wrap - .append('input') - .attr('type', 'number') - .attr('min', control.min !== undefined ? control.min : 0) - .attr('max', control.max) - .attr('step', control.step || 1) - .attr('class', 'changer') - .datum(control) - .property('value', function(d) { - return _this.stringAccessor(_this.targets[0].config, control.option); - }); + var changer = control_wrap.append('input').attr('type', 'number').attr('min', control.min !== undefined ? control.min : 0).attr('max', control.max).attr('step', control.step || 1).attr('class', 'changer').datum(control).property('value', function (d) { + return _this.stringAccessor(_this.targets[0].config, control.option); + }); - changer.on('change', function(d) { + changer.on('change', function (d) { var value = +changer.property('value'); _this.changeOption(control.option, value, control.callback, control.draw); }); @@ -3035,29 +2121,17 @@ function makeRadioControl(control, control_wrap) { var _this = this; - var changers = control_wrap - .selectAll('label') - .data(control.values || d3.keys(this.data[0])) - .enter() - .append('label') - .attr('class', 'radio') - .text(function(d, i) { - return control.relabels ? control.relabels[i] : d; - }) - .append('input') - .attr('type', 'radio') - .attr('class', 'changer') - .attr('name', control.option.replace('.', '-') + '-' + this.targets[0].id) - .property('value', function(d) { - return d; - }) - .property('checked', function(d) { - return _this.stringAccessor(_this.targets[0].config, control.option) === d; - }); + var changers = control_wrap.selectAll('label').data(control.values || d3.keys(this.data[0])).enter().append('label').attr('class', 'radio').text(function (d, i) { + return control.relabels ? control.relabels[i] : d; + }).append('input').attr('type', 'radio').attr('class', 'changer').attr('name', control.option.replace('.', '-') + '-' + this.targets[0].id).property('value', function (d) { + return d; + }).property('checked', function (d) { + return _this.stringAccessor(_this.targets[0].config, control.option) === d; + }); - changers.on('change', function(d) { + changers.on('change', function (d) { var value = null; - changers.each(function(c) { + changers.each(function (c) { if (d3.select(this).property('checked')) { value = d3.select(this).property('value') === 'none' ? null : c; } @@ -3070,27 +2144,14 @@ var targets = this.targets; // associated charts and tables. //dropdown selection - var changer = control_wrap - .append('select') - .classed('changer', true) - .attr('multiple', control.multiple ? true : null) - .datum(control); + var changer = control_wrap.append('select').classed('changer', true).attr('multiple', control.multiple ? true : null).datum(control); //dropdown option data - var option_data = control.values - ? control.values - : d3 - .set( - this.data - .map(function(m) { - return m[control.value_col]; - }) - .filter(function(f) { - return f; - }) - ) - .values() - .sort(naturalSorter); // only sort when values are derived + var option_data = control.values ? control.values : d3.set(this.data.map(function (m) { + return m[control.value_col]; + }).filter(function (f) { + return f; + })).values().sort(naturalSorter); // only sort when values are derived //initial dropdown option control.start = control.start ? control.start : control.loose ? option_data[0] : null; @@ -3107,26 +2168,17 @@ control.loose = !control.loose && control.start ? true : control.loose; //dropdown options selection - var options = changer - .selectAll('option') - .data(option_data) - .enter() - .append('option') - .text(function(d) { - return d; - }) - .property('selected', function(d) { - return d === control.start; - }); + var options = changer.selectAll('option').data(option_data).enter().append('option').text(function (d) { + return d; + }).property('selected', function (d) { + return d === control.start; + }); //define filter object for each associated target - targets.forEach(function(e) { - var match = e.filters - .slice() - .map(function(m) { - return m.col === control.value_col; - }) - .indexOf(true); + targets.forEach(function (e) { + var match = e.filters.slice().map(function (m) { + return m.col === control.value_col; + }).indexOf(true); if (match > -1) { e.filters[match] = { col: control.value_col, @@ -3150,7 +2202,7 @@ function setSubsetter(target, obj) { var match = -1; - target.filters.forEach(function(e, i) { + target.filters.forEach(function (e, i) { if (e.col === obj.col) { match = i; } @@ -3161,15 +2213,13 @@ } //add event listener to control - changer.on('change', function(d) { + changer.on('change', function (d) { if (control.multiple) { - var values = options - .filter(function(f) { - return d3.select(this).property('selected'); - })[0] - .map(function(m) { - return d3.select(m).property('text'); - }); + var values = options.filter(function (f) { + return d3.select(this).property('selected'); + })[0].map(function (m) { + return d3.select(m).property('text'); + }); var new_filter = { col: control.value_col, @@ -3179,7 +2229,7 @@ loose: control.loose, all: control.all }; - targets.forEach(function(e) { + targets.forEach(function (e) { setSubsetter(e, new_filter); //call callback function if provided if (control.callback) { @@ -3198,7 +2248,7 @@ loose: control.loose, all: control.all }; - targets.forEach(function(e) { + targets.forEach(function (e) { setSubsetter(e, _new_filter); //call callback function if provided if (control.callback) { @@ -3213,16 +2263,11 @@ function makeTextControl(control, control_wrap) { var _this = this; - var changer = control_wrap - .append('input') - .attr('type', 'text') - .attr('class', 'changer') - .datum(control) - .property('value', function(d) { - return _this.stringAccessor(_this.targets[0].config, control.option); - }); + var changer = control_wrap.append('input').attr('type', 'text').attr('class', 'changer').datum(control).property('value', function (d) { + return _this.stringAccessor(_this.targets[0].config, control.option); + }); - changer.on('change', function(d) { + changer.on('change', function (d) { var value = changer.property('value'); _this.changeOption(control.option, value, control.callback, control.draw); }); @@ -3280,10 +2325,7 @@ if (config.location === 'bottom') { thisControls.wrap = d3.select(element).append('div').attr('class', 'wc-controls'); } else { - thisControls.wrap = d3 - .select(element) - .insert('div', ':first-child') - .attr('class', 'wc-controls'); + thisControls.wrap = d3.select(element).insert('div', ':first-child').attr('class', 'wc-controls'); } thisControls.wrap.datum(thisControls); @@ -3296,32 +2338,17 @@ //If there are filters, return a filtered data array of the raw data. //Otherwise return the raw data. - if ( - this.filters && - this.filters.some(function(filter) { - return ( - (typeof filter.val === 'string' && - !(filter.all === true && filter.index === 0)) || - (Array.isArray(filter.val) && filter.val.length < filter.choices.length) - ); - }) - ) { + if (this.filters && this.filters.some(function (filter) { + return typeof filter.val === 'string' && !(filter.all === true && filter.index === 0) || Array.isArray(filter.val) && filter.val.length < filter.choices.length; + })) { this.data.filtered = this.data.raw; - this.filters - .filter(function(filter) { - return ( - (typeof filter.val === 'string' && - !(filter.all === true && filter.index === 0)) || - (Array.isArray(filter.val) && filter.val.length < filter.choices.length) - ); - }) - .forEach(function(filter) { - _this.data.filtered = _this.data.filtered.filter(function(d) { - return Array.isArray(filter.val) - ? filter.val.indexOf(d[filter.col]) > -1 - : filter.val === d[filter.col]; - }); + this.filters.filter(function (filter) { + return typeof filter.val === 'string' && !(filter.all === true && filter.index === 0) || Array.isArray(filter.val) && filter.val.length < filter.choices.length; + }).forEach(function (filter) { + _this.data.filtered = _this.data.filtered.filter(function (d) { + return Array.isArray(filter.val) ? filter.val.indexOf(d[filter.col]) > -1 : filter.val === d[filter.col]; }); + }); } else this.data.filtered = this.data.raw; } @@ -3338,20 +2365,17 @@ if (this.searchable.searchTerm) { //Determine which rows contain input text. - this.data.searched = this.data.filtered.filter(function(d) { + this.data.searched = this.data.filtered.filter(function (d) { var match = false; - Object.keys(d) - .filter(function(key) { - return _this.config.cols.indexOf(key) > -1; - }) - .forEach(function(var_name) { - if (match === false) { - var cellText = '' + d[var_name]; - match = - cellText.toLowerCase().indexOf(_this.searchable.searchTerm) > -1; - } - }); + Object.keys(d).filter(function (key) { + return _this.config.cols.indexOf(key) > -1; + }).forEach(function (var_name) { + if (match === false) { + var cellText = '' + d[var_name]; + match = cellText.toLowerCase().indexOf(_this.searchable.searchTerm) > -1; + } + }); return match; }); @@ -3368,12 +2392,9 @@ \------------------------------------------------------------------------------------------------*/ // Warn if overriding existing method - if (Array.prototype.equals) - console.warn( - "Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code." - ); + if (Array.prototype.equals) console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code."); // attach the .equals method to Array's prototype to call it on any array - Array.prototype.equals = function(array) { + Array.prototype.equals = function (array) { // if the other array is a falsy value, return if (!array) return false; @@ -3397,7 +2418,7 @@ function checkFilters() { if (this.filters) { - this.currentFilters = this.filters.map(function(filter) { + this.currentFilters = this.filters.map(function (filter) { return filter.val; }); @@ -3415,24 +2436,19 @@ function updateTableHeaders() { var _this = this; - this.thead_cells = this.thead - .select('tr') - .selectAll('th') - .data(this.config.headers, function(d) { - return d; - }); + this.thead_cells = this.thead.select('tr').selectAll('th').data(this.config.headers, function (d) { + return d; + }); this.thead_cells.exit().remove(); this.thead_cells.enter().append('th'); - this.thead_cells - .sort(function(a, b) { - return _this.config.headers.indexOf(a) - _this.config.headers.indexOf(b); - }) - .attr('class', function(d) { - return _this.config.cols[_this.config.headers.indexOf(d)]; - }) // associate column header with column name - .text(function(d) { - return d; - }); + this.thead_cells.sort(function (a, b) { + return _this.config.headers.indexOf(a) - _this.config.headers.indexOf(b); + }).attr('class', function (d) { + return _this.config.cols[_this.config.headers.indexOf(d)]; + }) // associate column header with column name + .text(function (d) { + return d; + }); } function drawTableBody() { @@ -3444,77 +2460,51 @@ var rows = this.tbody.selectAll('tr').data(this.data.processing).enter().append('tr'); //Define table body cells. - var cells = rows.selectAll('td').data(function(d) { - return _this.config.cols.map(function(key) { + var cells = rows.selectAll('td').data(function (d) { + return _this.config.cols.map(function (key) { return { col: key, text: d[key] }; }); }); cells.exit().remove(); cells.enter().append('td'); - cells - .sort(function(a, b) { - return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); - }) - .attr('class', function(d) { - return d.col; - }) - .each(function(d) { - var cell = d3.select(this); - - //Apply text in data as html or as plain text. - if (table.config.as_html) { - cell.html(d.text); - } else { - cell.text(d.text); - } - }); + cells.sort(function (a, b) { + return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); + }).attr('class', function (d) { + return d.col; + }).each(function (d) { + var cell = d3.select(this); + + //Apply text in data as html or as plain text. + if (table.config.as_html) { + cell.html(d.text); + } else { + cell.text(d.text); + } + }); } function dynamicLayout() { var widths = { table: this.table.select('thead').node().offsetWidth, - top: - this.wrap.select('.table-top .searchable-container').node().offsetWidth + - this.wrap.select('.table-top .sortable-container').node().offsetWidth, - bottom: - this.wrap.select('.table-bottom .pagination-container').node().offsetWidth + - this.wrap.select('.table-bottom .exportable-container').node().offsetWidth + top: this.wrap.select('.table-top .searchable-container').node().offsetWidth + this.wrap.select('.table-top .sortable-container').node().offsetWidth, + bottom: this.wrap.select('.table-bottom .pagination-container').node().offsetWidth + this.wrap.select('.table-bottom .exportable-container').node().offsetWidth }; - if ( - widths.table < Math.max(widths.top, widths.bottom) && - this.config.layout === 'horizontal' - ) { + if (widths.table < Math.max(widths.top, widths.bottom) && this.config.layout === 'horizontal') { this.config.layout = 'vertical'; - this.wrap - .style('display', 'inline-block') - .selectAll('.table-top,.table-bottom') - .style('display', 'inline-block') - .selectAll('.interactivity') - .style({ - display: 'block', - clear: 'both' - }); - } else if ( - widths.table >= Math.max(widths.top, widths.bottom) && - this.config.layout === 'vertical' - ) { + this.wrap.style('display', 'inline-block').selectAll('.table-top,.table-bottom').style('display', 'inline-block').selectAll('.interactivity').style({ + display: 'block', + clear: 'both' + }); + } else if (widths.table >= Math.max(widths.top, widths.bottom) && this.config.layout === 'vertical') { this.config.layout = 'horizontal'; - this.wrap - .style('display', 'table') - .selectAll('.table-top,.table-bottom') - .style('display', 'block') - .selectAll('.interactivity') - .style({ - display: 'inline-block', - float: function float() { - return d3.select(this).classed('searchable-container') || - d3.select(this).classed('pagination-container') - ? 'right' - : null; - }, - clear: null - }); + this.wrap.style('display', 'table').selectAll('.table-top,.table-bottom').style('display', 'block').selectAll('.interactivity').style({ + display: 'inline-block', + float: function float() { + return d3.select(this).classed('searchable-container') || d3.select(this).classed('pagination-container') ? 'right' : null; + }, + clear: null + }); } } @@ -3529,8 +2519,7 @@ if (!passed_data) //Apply filters if data is not passed to table.draw(). - applyFilters.call(this); - else + applyFilters.call(this);else //Otherwise update data object. updateDataObject.call(this); @@ -3540,16 +2529,7 @@ //Filter data on search term if it exists and set data to searched data. applySearchTerm.call(this); - this.searchable.wrap - .select('.nNrecords') - .text( - this.data.processing.length === this.data.raw.length - ? this.data.raw.length + ' records displayed' - : this.data.processing.length + - '/' + - this.data.raw.length + - ' records displayed' - ); + this.searchable.wrap.select('.nNrecords').text(this.data.processing.length === this.data.raw.length ? this.data.raw.length + ' records displayed' : this.data.processing.length + '/' + this.data.raw.length + ' records displayed'); //Update table headers. updateTableHeaders.call(this); @@ -3559,35 +2539,27 @@ //Print a note that no data was selected for empty tables. if (this.data.processing.length === 0) { - this.tbody - .append('tr') - .classed('no-data', true) - .append('td') - .attr('colspan', this.config.cols.length) - .text('No data selected.'); + this.tbody.append('tr').classed('no-data', true).append('td').attr('colspan', this.config.cols.length).text('No data selected.'); //Bind table filtered/searched data to table container. this.data.current = this.data.processing; this.table.datum(this.table.current); //Add export. - if (this.config.exportable) - this.config.exports.forEach(function(fmt) { - _this.exportable.exports[fmt].call(_this, _this.data.processing); - }); + if (this.config.exportable) this.config.exports.forEach(function (fmt) { + _this.exportable.exports[fmt].call(_this, _this.data.processing); + }); //Add pagination. - if (this.config.pagination) - this.pagination.addPagination.call(this, this.data.processing); + if (this.config.pagination) this.pagination.addPagination.call(this, this.data.processing); } else { //Sort data. if (this.config.sortable) { - this.thead.selectAll('th').on('click', function(header) { + this.thead.selectAll('th').on('click', function (header) { table.sortable.onClick.call(table, this, header); }); - if (this.sortable.order.length) - this.sortable.sortData.call(this, this.data.processing); + if (this.sortable.order.length) this.sortable.sortData.call(this, this.data.processing); } //Bind table filtered/searched data to table container. @@ -3595,17 +2567,16 @@ this.table.datum(this.data.current); //Add export. - if (this.config.exportable) - this.config.exports.forEach(function(fmt) { - _this.exportable.exports[fmt].call(_this, _this.data.processing); - }); + if (this.config.exportable) this.config.exports.forEach(function (fmt) { + _this.exportable.exports[fmt].call(_this, _this.data.processing); + }); //Add pagination. if (this.config.pagination) { this.pagination.addPagination.call(this, this.data.processing); //Apply pagination. - this.data.processing = this.data.processing.filter(function(d, i) { + this.data.processing = this.data.processing.filter(function (d, i) { return _this.config.startIndex <= i && i < _this.config.endIndex; }); } @@ -3625,24 +2596,15 @@ function layout$2() { var context = this; - this.searchable.wrap = this.wrap - .select('.table-top') - .append('div') - .classed('interactivity searchable-container', true) - .classed('hidden', !this.config.searchable); + this.searchable.wrap = this.wrap.select('.table-top').append('div').classed('interactivity searchable-container', true).classed('hidden', !this.config.searchable); this.searchable.wrap.append('div').classed('search', true); - this.searchable.wrap - .select('.search') - .append('input') - .classed('search-box', true) - .attr('placeholder', 'Search') - .on('input', function() { - context.searchable.searchTerm = this.value.toLowerCase() || null; - context.config.activePage = 0; - context.config.startIndex = context.config.activePage * context.config.nRowsPerPage; // first row shown - context.config.endIndex = context.config.startIndex + context.config.nRowsPerPage; // last row shown - context.draw(); - }); + this.searchable.wrap.select('.search').append('input').classed('search-box', true).attr('placeholder', 'Search').on('input', function () { + context.searchable.searchTerm = this.value.toLowerCase() || null; + context.config.activePage = 0; + context.config.startIndex = context.config.activePage * context.config.nRowsPerPage; // first row shown + context.config.endIndex = context.config.startIndex + context.config.nRowsPerPage; // last row shown + context.draw(); + }); this.searchable.wrap.select('.search').append('span').classed('nNrecords', true); } @@ -3655,55 +2617,32 @@ function layout$3() { var _this = this; - this.exportable.wrap = this.wrap - .select('.table-bottom') - .append('div') - .classed('interactivity exportable-container', true) - .classed('hidden', !this.config.exportable); + this.exportable.wrap = this.wrap.select('.table-bottom').append('div').classed('interactivity exportable-container', true).classed('hidden', !this.config.exportable); this.exportable.wrap.append('span').text('Export:'); - if (this.config.exports && this.config.exports.length) - this.config.exports.forEach(function(fmt) { - _this.exportable.wrap - .append('a') - .classed('wc-button export', true) - .attr({ - id: fmt - }) - .style( - !_this.test && navigator.msSaveBlob - ? { - cursor: 'pointer', - 'text-decoration': 'underline', - color: 'blue' - } - : null - ) - .text(fmt.toUpperCase()); - }); + if (this.config.exports && this.config.exports.length) this.config.exports.forEach(function (fmt) { + _this.exportable.wrap.append('a').classed('wc-button export', true).attr({ + id: fmt + }).style(!_this.test && navigator.msSaveBlob ? { + cursor: 'pointer', + 'text-decoration': 'underline', + color: 'blue' + } : null).text(fmt.toUpperCase()); + }); } function download(fileType, data) { //transform blob array into a blob of characters var blob = new Blob(data, { - type: fileType === 'csv' - ? 'text/csv;charset=utf-8;' - : fileType === 'xlsx' - ? 'application/octet-stream' - : console.warn('File type not supported: ' + fileType) + type: fileType === 'csv' ? 'text/csv;charset=utf-8;' : fileType === 'xlsx' ? 'application/octet-stream' : console.warn('File type not supported: ' + fileType) }); - var fileName = - 'webchartsTableExport_' + - d3.time.format('%Y-%m-%dT%H-%M-%S')(new Date()) + - '.' + - fileType; + var fileName = 'webchartsTableExport_' + d3.time.format('%Y-%m-%dT%H-%M-%S')(new Date()) + '.' + fileType; var link = this.wrap.select('.export#' + fileType); if (navigator.msSaveBlob) //IE - navigator.msSaveBlob(blob, fileName); - else if (link.node().download !== undefined) { + navigator.msSaveBlob(blob, fileName);else if (link.node().download !== undefined) { //21st century browsers var url = URL.createObjectURL(blob); link.node().setAttribute('href', url); @@ -3714,18 +2653,18 @@ function csv(data) { var _this = this; - this.wrap.select('.export#csv').on('click', function() { + this.wrap.select('.export#csv').on('click', function () { var CSVarray = []; //add headers to CSV array - var headers = _this.config.headers.map(function(header) { + var headers = _this.config.headers.map(function (header) { return '"' + header.replace(/"/g, '""') + '"'; }); CSVarray.push(headers); //add rows to CSV array - data.forEach(function(d, i) { - var row = _this.config.cols.map(function(col) { + data.forEach(function (d, i) { + var row = _this.config.cols.map(function (col) { var value = d[col]; if (typeof value === 'string') value = value.replace(/"/g, '""'); @@ -3744,21 +2683,19 @@ function xlsx(data) { var _this = this; - this.wrap.select('.export#xlsx').on('click', function() { + this.wrap.select('.export#xlsx').on('click', function () { var sheetName = 'Selected Data'; var options = { bookType: 'xlsx', bookSST: true, type: 'binary' }; - var arrayOfArrays = data.map(function(d) { - return Object.keys(d) - .filter(function(key) { - return _this.config.cols.indexOf(key) > -1; - }) - .map(function(key) { - return d[key]; - }); + var arrayOfArrays = data.map(function (d) { + return Object.keys(d).filter(function (key) { + return _this.config.cols.indexOf(key) > -1; + }).map(function (key) { + return d[key]; + }); }); // convert data from array of objects to array of arrays. var workbook = { SheetNames: [sheetName], @@ -3767,9 +2704,7 @@ var cols = []; //Convert headers and data from array of arrays to sheet. - workbook.Sheets[sheetName] = XLSX.utils.aoa_to_sheet( - [_this.config.headers].concat(arrayOfArrays) - ); + workbook.Sheets[sheetName] = XLSX.utils.aoa_to_sheet([_this.config.headers].concat(arrayOfArrays)); //Add filters to spreadsheet. workbook.Sheets[sheetName]['!autofilter'] = { @@ -3777,7 +2712,7 @@ }; //Define column widths in spreadsheet. - _this.table.selectAll('thead tr th').each(function() { + _this.table.selectAll('thead tr th').each(function () { cols.push({ wpx: this.offsetWidth }); }); workbook.Sheets[sheetName]['!cols'] = cols; @@ -3789,8 +2724,7 @@ for (var i = 0; i !== s.length; ++i) { view[i] = s.charCodeAt(i) & 0xff; - } - return buffer; + }return buffer; }; // convert spreadsheet to binary or something, i don't know //Download .xlsx file. @@ -3811,16 +2745,10 @@ } function layout$4() { + //Add sort container. - this.sortable.wrap = this.wrap - .select('.table-top') - .append('div') - .classed('interactivity sortable-container', true) - .classed('hidden', !this.config.sortable); - this.sortable.wrap - .append('div') - .classed('instruction', true) - .text('Click column headers to sort.'); + this.sortable.wrap = this.wrap.select('.table-top').append('div').classed('interactivity sortable-container', true).classed('hidden', !this.config.sortable); + this.sortable.wrap.append('div').classed('instruction', true).text('Click column headers to sort.'); } function onClick(th, header) { @@ -3829,7 +2757,7 @@ col = this.config.cols[this.config.headers.indexOf(header)]; //Check if column is already a part of current sort order. - var sortItem = this.sortable.order.filter(function(item) { + var sortItem = this.sortable.order.filter(function (item) { return item.col === col; })[0]; @@ -3838,11 +2766,7 @@ sortItem = { col: col, direction: 'ascending', - wrap: this.sortable.wrap - .append('div') - .datum({ key: col }) - .classed('wc-button sort-box', true) - .text(header) + wrap: this.sortable.wrap.append('div').datum({ key: col }).classed('wc-button sort-box', true).text(header) }; sortItem.wrap.append('span').classed('sort-direction', true).html('↓'); sortItem.wrap.append('span').classed('remove-sort', true).html('❌'); @@ -3850,34 +2774,25 @@ } else { //Otherwise reverse its sort direction. sortItem.direction = sortItem.direction === 'ascending' ? 'descending' : 'ascending'; - sortItem.wrap - .select('span.sort-direction') - .html(sortItem.direction === 'ascending' ? '↓' : '↑'); + sortItem.wrap.select('span.sort-direction').html(sortItem.direction === 'ascending' ? '↓' : '↑'); } //Hide sort instructions. this.sortable.wrap.select('.instruction').classed('hidden', true); //Add sort container deletion functionality. - this.sortable.order.forEach(function(item, i) { - item.wrap.on('click', function(d) { + this.sortable.order.forEach(function (item, i) { + item.wrap.on('click', function (d) { //Remove column's sort container. d3.select(this).remove(); //Remove column from sort. - context.sortable.order.splice( - context.sortable.order - .map(function(d) { - return d.col; - }) - .indexOf(d.key), - 1 - ); + context.sortable.order.splice(context.sortable.order.map(function (d) { + return d.col; + }).indexOf(d.key), 1); //Display sorting instruction. - context.sortable.wrap - .select('.instruction') - .classed('hidden', context.sortable.order.length); + context.sortable.wrap.select('.instruction').classed('hidden', context.sortable.order.length); //Redraw chart. context.draw(); @@ -3891,24 +2806,15 @@ function sortData(data) { var _this = this; - data = data.sort(function(a, b) { + data = data.sort(function (a, b) { var order = 0; - _this.sortable.order.forEach(function(item) { + _this.sortable.order.forEach(function (item) { var aCell = a[item.col], bCell = b[item.col]; if (order === 0) { - if ( - (item.direction === 'ascending' && aCell < bCell) || - (item.direction === 'descending' && aCell > bCell) - ) - order = -1; - else if ( - (item.direction === 'ascending' && aCell > bCell) || - (item.direction === 'descending' && aCell < bCell) - ) - order = 1; + if (item.direction === 'ascending' && aCell < bCell || item.direction === 'descending' && aCell > bCell) order = -1;else if (item.direction === 'ascending' && aCell > bCell || item.direction === 'descending' && aCell < bCell) order = 1; } }); @@ -3926,11 +2832,7 @@ } function layout$5() { - this.pagination.wrap = this.wrap - .select('.table-bottom') - .append('div') - .classed('interactivity pagination-container', true) - .classed('hidden', !this.config.pagination); + this.pagination.wrap = this.wrap.select('.table-bottom').append('div').classed('interactivity pagination-container', true).classed('hidden', !this.config.pagination); } function updatePagination() { @@ -3940,11 +2842,9 @@ this.pagination.links.classed('active', false); //Set to active the selected page link. - var activePage = this.pagination.links - .filter(function(link) { - return +link.rel === +_this.config.activePage; - }) - .classed('active', true); + var activePage = this.pagination.links.filter(function (link) { + return +link.rel === +_this.config.activePage; + }).classed('active', true); //Define and draw selected page. this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; @@ -3962,28 +2862,15 @@ this.pagination.wrap.selectAll('a,span').remove(); var _loop = function _loop(i) { - _this.pagination.wrap - .append('a') - .datum({ rel: i }) - .attr({ - rel: i - }) - .text(i + 1) - .classed('wc-button page-link', true) - .classed('active', function(d) { - return d.rel == _this.config.activePage; - }) - .classed('hidden', function() { - return _this.config.activePage < _this.config.nPageLinksDisplayed - ? i >= _this.config.nPageLinksDisplayed // first nPageLinksDisplayed pages - : _this.config.activePage >= - _this.config.nPages - _this.config.nPageLinksDisplayed - ? i < _this.config.nPages - _this.config.nPageLinksDisplayed // last nPageLinksDisplayed pages - : i < - _this.config.activePage - - (Math.ceil(_this.config.nPageLinksDisplayed / 2) - 1) || - _this.config.activePage + _this.config.nPageLinksDisplayed / 2 < i; // nPageLinksDisplayed < activePage or activePage < (nPages - nPageLinksDisplayed) - }); + _this.pagination.wrap.append('a').datum({ rel: i }).attr({ + rel: i + }).text(i + 1).classed('wc-button page-link', true).classed('active', function (d) { + return d.rel == _this.config.activePage; + }).classed('hidden', function () { + return _this.config.activePage < _this.config.nPageLinksDisplayed ? i >= _this.config.nPageLinksDisplayed // first nPageLinksDisplayed pages + : _this.config.activePage >= _this.config.nPages - _this.config.nPageLinksDisplayed ? i < _this.config.nPages - _this.config.nPageLinksDisplayed // last nPageLinksDisplayed pages + : i < _this.config.activePage - (Math.ceil(_this.config.nPageLinksDisplayed / 2) - 1) || _this.config.activePage + _this.config.nPageLinksDisplayed / 2 < i; // nPageLinksDisplayed < activePage or activePage < (nPages - nPageLinksDisplayed) + }); }; for (var i = 0; i < this.config.nPages; i++) { @@ -4003,69 +2890,28 @@ Left side \-------------------------------------------------------------------------------------------**/ - this.pagination.wrap - .insert('span', ':first-child') - .classed('dot-dot-dot', true) - .text('...') - .classed('hidden', this.config.activePage < this.config.nPageLinksDisplayed); - - this.pagination.prev = this.pagination.wrap - .insert('a', ':first-child') - .classed('wc-button arrow-link wc-left', true) - .classed('hidden', this.config.activePage == 0) - .attr({ - rel: prev - }) - .text('<'); - - this.pagination.doublePrev = this.pagination.wrap - .insert('a', ':first-child') - .classed('wc-button arrow-link wc-left double', true) - .classed('hidden', this.config.activePage == 0) - .attr({ - rel: 0 - }) - .text('<<'); + this.pagination.wrap.insert('span', ':first-child').classed('dot-dot-dot', true).text('...').classed('hidden', this.config.activePage < this.config.nPageLinksDisplayed); + + this.pagination.prev = this.pagination.wrap.insert('a', ':first-child').classed('wc-button arrow-link wc-left', true).classed('hidden', this.config.activePage == 0).attr({ + rel: prev + }).text('<'); + + this.pagination.doublePrev = this.pagination.wrap.insert('a', ':first-child').classed('wc-button arrow-link wc-left double', true).classed('hidden', this.config.activePage == 0).attr({ + rel: 0 + }).text('<<'); /**-------------------------------------------------------------------------------------------\ Right side \-------------------------------------------------------------------------------------------**/ - this.pagination.wrap - .append('span') - .classed('dot-dot-dot', true) - .text('...') - .classed( - 'hidden', - this.config.activePage >= - Math.max( - this.config.nPageLinksDisplayed, - this.config.nPages - this.config.nPageLinksDisplayed - ) || this.config.nPages <= this.config.nPageLinksDisplayed - ); - this.pagination.next = this.pagination.wrap - .append('a') - .classed('wc-button arrow-link wc-right', true) - .classed( - 'hidden', - this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0 - ) - .attr({ - rel: next - }) - .text('>'); - - this.pagination.doubleNext = this.pagination.wrap - .append('a') - .classed('wc-button arrow-link wc-right double', true) - .classed( - 'hidden', - this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0 - ) - .attr({ - rel: this.config.nPages - 1 - }) - .text('>>'); + this.pagination.wrap.append('span').classed('dot-dot-dot', true).text('...').classed('hidden', this.config.activePage >= Math.max(this.config.nPageLinksDisplayed, this.config.nPages - this.config.nPageLinksDisplayed) || this.config.nPages <= this.config.nPageLinksDisplayed); + this.pagination.next = this.pagination.wrap.append('a').classed('wc-button arrow-link wc-right', true).classed('hidden', this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0).attr({ + rel: next + }).text('>'); + + this.pagination.doubleNext = this.pagination.wrap.append('a').classed('wc-button arrow-link wc-right double', true).classed('hidden', this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0).attr({ + rel: this.config.nPages - 1 + }).text('>>'); this.pagination.arrows = this.pagination.wrap.selectAll('a.arrow-link'); this.pagination.doubleArrows = this.pagination.wrap.selectAll('a.double-arrow-link'); @@ -4086,7 +2932,7 @@ addLinks.call(this); //Render a different page on click. - this.pagination.links.on('click', function() { + this.pagination.links.on('click', function () { context.config.activePage = +d3.select(this).attr('rel'); updatePagination.call(context); }); @@ -4095,25 +2941,17 @@ addArrows.call(this); //Render a different page on click. - this.pagination.arrows.on('click', function() { + this.pagination.arrows.on('click', function () { if (context.config.activePage !== +d3.select(this).attr('rel')) { context.config.activePage = +d3.select(this).attr('rel'); - context.pagination.prev.attr( - 'rel', - context.config.activePage > 0 ? context.config.activePage - 1 : 0 - ); - context.pagination.next.attr( - 'rel', - context.config.activePage < context.config.nPages - ? context.config.activePage + 1 - : context.config.nPages - 1 - ); + context.pagination.prev.attr('rel', context.config.activePage > 0 ? context.config.activePage - 1 : 0); + context.pagination.next.attr('rel', context.config.activePage < context.config.nPages ? context.config.activePage + 1 : context.config.nPages - 1); updatePagination.call(context); } }); //Render a different page on click. - this.pagination.doubleArrows.on('click', function() { + this.pagination.doubleArrows.on('click', function () { context.config.activePage = +d3.select(this).attr('rel'); updatePagination.call(context); }); @@ -4146,17 +2984,9 @@ this.test = test; if (d3.select(this.div).select('.loader').empty()) { - d3 - .select(this.div) - .insert('div', ':first-child') - .attr('class', 'loader') - .selectAll('.blockG') - .data(d3.range(8)) - .enter() - .append('div') - .attr('class', function(d) { - return 'blockG rotate' + (d + 1); - }); + d3.select(this.div).insert('div', ':first-child').attr('class', 'loader').selectAll('.blockG').data(d3.range(8)).enter().append('div').attr('class', function (d) { + return 'blockG rotate' + (d + 1); + }); } //Define default settings. @@ -4196,10 +3026,8 @@ //make sure container is visible (has height and width) before trying to initialize var visible = d3.select(_this.div).property('offsetWidth') > 0 || test; if (!visible) { - console.warn( - 'The table cannot be initialized inside an element with 0 width. The table will be initialized as soon as the container element is given a width > 0.' - ); - var onVisible = setInterval(function(i) { + console.warn('The table cannot be initialized inside an element with 0 width. The table will be initialized as soon as the container element is given a width > 0.'); + var onVisible = setInterval(function (i) { var visible_now = d3.select(_this.div).property('offsetWidth') > 0; if (visible_now) { _this.layout(); @@ -4257,9 +3085,7 @@ } function destroy$2() { - var destroyControls = arguments.length > 0 && arguments[0] !== undefined - ? arguments[0] - : false; + var destroyControls = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; //run onDestroy callback this.events.onDestroy.call(this); @@ -4276,20 +3102,14 @@ function setDefault(setting) { var _default_ = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - this.config[setting] = this.config[setting] !== undefined - ? this.config[setting] - : _default_; + this.config[setting] = this.config[setting] !== undefined ? this.config[setting] : _default_; } function setDefaults$1(firstItem) { //Set data-driven defaults. if (this.config.cols instanceof Array && this.config.headers instanceof Array) { if (this.config.cols.length === 0) delete this.config.cols; - if ( - this.config.headers.length === 0 || - this.config.headers.length !== this.config.cols.length - ) - delete this.config.headers; + if (this.config.headers.length === 0 || this.config.headers.length !== this.config.cols.length) delete this.config.headers; } this.config.cols = this.config.cols || d3.keys(firstItem); @@ -4322,7 +3142,7 @@ this.config.headers = this.config.headers || this.config.cols; if (this.config.keep) { - this.config.keep.forEach(function(e) { + this.config.keep.forEach(function (e) { if (_this.config.cols.indexOf(e) === -1) { _this.config.cols.unshift(e); } @@ -4332,9 +3152,9 @@ var filtered = data; if (this.filters.length) { - this.filters.forEach(function(e) { + this.filters.forEach(function (e) { var is_array = e.val instanceof Array; - filtered = filtered.filter(function(d) { + filtered = filtered.filter(function (d) { if (is_array) { return e.val.indexOf(d[e.col]) !== -1; } else { @@ -4344,36 +3164,30 @@ }); } - var slimmed = d3 - .nest() - .key(function(d) { - if (_this.config.row_per) { - return _this.config.row_per - .map(function(m) { - return d[m]; - }) - .join(' '); - } else { - return d; - } - }) - .rollup(function(r) { - if (_this.config.dataManipulate) { - r = _this.config.dataManipulate(r); + var slimmed = d3.nest().key(function (d) { + if (_this.config.row_per) { + return _this.config.row_per.map(function (m) { + return d[m]; + }).join(' '); + } else { + return d; + } + }).rollup(function (r) { + if (_this.config.dataManipulate) { + r = _this.config.dataManipulate(r); + } + var nuarr = r.map(function (m) { + var arr = []; + for (var x in m) { + arr.push({ col: x, text: m[x] }); } - var nuarr = r.map(function(m) { - var arr = []; - for (var x in m) { - arr.push({ col: x, text: m[x] }); - } - arr.sort(function(a, b) { - return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); - }); - return { cells: arr, raw: m }; + arr.sort(function (a, b) { + return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); }); - return nuarr; - }) - .entries(filtered); + return { cells: arr, raw: m }; + }); + return nuarr; + }).entries(filtered); this.data.current = slimmed.length ? slimmed : [{ key: null, values: [] }]; // dummy nested data array @@ -4388,8 +3202,8 @@ if (config.row_per) { var rev_order = config.row_per.slice(0).reverse(); - rev_order.forEach(function(e) { - tbodies.sort(function(a, b) { + rev_order.forEach(function (e) { + tbodies.sort(function (a, b) { return a.values[0].raw[e] - b.values[0].raw[e]; }); }); @@ -4397,15 +3211,11 @@ //Delete text from columns with repeated values? if (config.row_per) { - rows - .filter(function(f, i) { - return i > 0; - }) - .selectAll('td') - .filter(function(f) { - return config.row_per.indexOf(f.col) > -1; - }) - .text(''); + rows.filter(function (f, i) { + return i > 0; + }).selectAll('td').filter(function (f) { + return config.row_per.indexOf(f.col) > -1; + }).text(''); } return this.data.current; @@ -4447,7 +3257,7 @@ onDestroy: function onDestroy() {} }; - thisTable.on = function(event, callback) { + thisTable.on = function (event, callback) { var possible_events = ['init', 'layout', 'preprocess', 'draw', 'destroy']; if (possible_events.indexOf(event) < 0) { return; @@ -4473,22 +3283,17 @@ chart.multiples = []; function goAhead(data) { - var split_vals = d3 - .set( - data.map(function(m) { - return m[split_by]; - }) - ) - .values() - .filter(function(f) { - return f; - }); + var split_vals = d3.set(data.map(function (m) { + return m[split_by]; + })).values().filter(function (f) { + return f; + }); if (order) { - split_vals = split_vals.sort(function(a, b) { + split_vals = split_vals.sort(function (a, b) { return d3.ascending(order.indexOf(a), order.indexOf(b)); }); } - split_vals.forEach(function(e) { + split_vals.forEach(function (e) { var mchart = createChart(chart.wrap.node(), chart.config, chart.controls); chart.multiples.push(mchart); mchart.parent = chart; @@ -4504,14 +3309,10 @@ } function getValType(data, variable) { - var var_vals = d3 - .set( - data.map(function(m) { - return m[variable]; - }) - ) - .values(); - var vals_numbers = var_vals.filter(function(f) { + var var_vals = d3.set(data.map(function (m) { + return m[variable]; + })).values(); + var vals_numbers = var_vals.filter(function (f) { return +f || +f === 0; }); @@ -4525,8 +3326,8 @@ function lengthenRaw(data, columns) { var my_data = []; - data.forEach(function(e) { - columns.forEach(function(g) { + data.forEach(function (e) { + columns.forEach(function (g) { var obj = Object.create(e); obj.wc_category = g; obj.wc_value = e[g]; @@ -4554,4 +3355,5 @@ }; return index; -}); + +})); diff --git a/package.json b/package.json index 8b32738..699d357 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "webcharts", "description": "A library for creating flexible, interactive charts", - "version": "1.11.5", + "version": "1.12.0", "keywords": [ "charts", "javascript", From 2d5e542655c84de76754cf0ced144d6d7e5a9e57 Mon Sep 17 00:00:00 2001 From: Spencer Childress Date: Fri, 10 May 2019 16:54:22 -0400 Subject: [PATCH 04/12] rebuild --- package-lock.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package-lock.json b/package-lock.json index 900b5c7..6eecb9b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "webcharts", - "version": "1.11.5", + "version": "1.12.0", "lockfileVersion": 1, "requires": true, "dependencies": { From d6aff4458348c064b60b5c46bc4e9cae5c804129 Mon Sep 17 00:00:00 2001 From: Spencer Childress Date: Fri, 10 May 2019 17:06:32 -0400 Subject: [PATCH 05/12] update versin --- build/webcharts.js | 3210 ++++++++++++++++++++++++++++++-------------- src/version.js | 2 +- 2 files changed, 2205 insertions(+), 1007 deletions(-) diff --git a/build/webcharts.js b/build/webcharts.js index 9a38cb2..cad58a8 100644 --- a/build/webcharts.js +++ b/build/webcharts.js @@ -1,10 +1,12 @@ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('d3')) : - typeof define === 'function' && define.amd ? define(['d3'], factory) : - global.webCharts = factory(global.d3); -}(typeof self !== 'undefined' ? self : this, function (d3) { 'use strict'; - - var version = '1.11.5'; +(function(global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' + ? (module.exports = factory(require('d3'))) + : typeof define === 'function' && define.amd + ? define(['d3'], factory) + : (global.webCharts = factory(global.d3)); +})(typeof self !== 'undefined' ? self : this, function(d3) { + 'use strict'; + var version = '1.12.0'; function init(data) { var _this = this; @@ -12,9 +14,17 @@ var test = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; if (d3.select(this.div).select('.loader').empty()) { - d3.select(this.div).insert('div', ':first-child').attr('class', 'loader').selectAll('.blockG').data(d3.range(8)).enter().append('div').attr('class', function (d) { - return 'blockG rotate' + (d + 1); - }); + d3 + .select(this.div) + .insert('div', ':first-child') + .attr('class', 'loader') + .selectAll('.blockG') + .data(d3.range(8)) + .enter() + .append('div') + .attr('class', function(d) { + return 'blockG rotate' + (d + 1); + }); } this.wrap.attr('class', 'wc-chart'); @@ -38,8 +48,10 @@ //make sure container is visible (has height and width) before trying to initialize var visible = d3.select(_this.div).property('offsetWidth') > 0 || test; if (!visible) { - console.warn('The chart cannot be initialized inside an element with 0 width. The chart will be initialized as soon as the container element is given a width > 0.'); - var onVisible = setInterval(function (i) { + console.warn( + 'The chart cannot be initialized inside an element with 0 width. The chart will be initialized as soon as the container element is given a width > 0.' + ); + var onVisible = setInterval(function(i) { var visible_now = d3.select(_this.div).property('offsetWidth') > 0; if (visible_now) { _this.layout(); @@ -80,32 +92,48 @@ requiredVars.push('this.config.color_by'); requiredCols.push(this.config.color_by); } - if (this.config.marks) this.config.marks.forEach(function (e, i) { - if (e.per && e.per.length) { - e.per.forEach(function (p, j) { - requiredVars.push('this.config.marks[' + i + '].per[' + j + ']'); - requiredCols.push(p); - }); - } - if (e.split) { - requiredVars.push('this.config.marks[' + i + '].split'); - requiredCols.push(e.split); - } - if (e.values) { - for (var value in e.values) { - requiredVars.push('this.config.marks[' + i + "].values['" + value + "']"); - requiredCols.push(value); + if (this.config.marks) + this.config.marks.forEach(function(e, i) { + if (e.per && e.per.length) { + e.per.forEach(function(p, j) { + requiredVars.push('this.config.marks[' + i + '].per[' + j + ']'); + requiredCols.push(p); + }); } - } - }); + if (e.split) { + requiredVars.push('this.config.marks[' + i + '].split'); + requiredCols.push(e.split); + } + if (e.values) { + for (var value in e.values) { + requiredVars.push('this.config.marks[' + i + "].values['" + value + "']"); + requiredCols.push(value); + } + } + }); var missingDataField = false; - requiredCols.forEach(function (e, i) { + requiredCols.forEach(function(e, i) { if (colnames.indexOf(e) < 0) { missingDataField = true; d3.select(_this.div).select('.loader').remove(); - _this.wrap.append('div').style('color', 'red').html('The value "' + e + '" for the ' + requiredVars[i] + ' setting does not match any column in the provided dataset.'); - throw new Error('Error in settings object: The value "' + e + '" for the ' + requiredVars[i] + ' setting does not match any column in the provided dataset.'); + _this.wrap + .append('div') + .style('color', 'red') + .html( + 'The value "' + + e + + '" for the ' + + requiredVars[i] + + ' setting does not match any column in the provided dataset.' + ); + throw new Error( + 'Error in settings object: The value "' + + e + + '" for the ' + + requiredVars[i] + + ' setting does not match any column in the provided dataset.' + ); } }); @@ -117,61 +145,94 @@ } function addSVG() { - this.svg = this.wrap.append('svg').datum(function () { - return null; - }) // prevent data inheritance - .attr({ - class: 'wc-svg', - xmlns: 'http://www.w3.org/2000/svg', - version: '1.1', - xlink: 'http://www.w3.org/1999/xlink' - }).append('g').style('display', 'inline-block'); + this.svg = this.wrap + .append('svg') + .datum(function() { + return null; + }) // prevent data inheritance + .attr({ + class: 'wc-svg', + xmlns: 'http://www.w3.org/2000/svg', + version: '1.1', + xlink: 'http://www.w3.org/1999/xlink' + }) + .append('g') + .style('display', 'inline-block'); } function addDefs() { var defs = this.svg.append('defs'); //Add pattern. - defs.append('pattern').attr({ - id: 'diagonal-stripes', - x: 0, - y: 0, - width: 3, - height: 8, - patternUnits: 'userSpaceOnUse', - patternTransform: 'rotate(30)' - }).append('rect').attr({ - x: '0', - y: '0', - width: '2', - height: '8' - }).style({ - stroke: 'none', - fill: 'black' - }); + defs + .append('pattern') + .attr({ + id: 'diagonal-stripes', + x: 0, + y: 0, + width: 3, + height: 8, + patternUnits: 'userSpaceOnUse', + patternTransform: 'rotate(30)' + }) + .append('rect') + .attr({ + x: '0', + y: '0', + width: '2', + height: '8' + }) + .style({ + stroke: 'none', + fill: 'black' + }); //Add clipPath. defs.append('clipPath').attr('id', this.id).append('rect').attr('class', 'plotting-area'); } function addXAxis() { - this.svg.append('g').attr('class', 'x axis').append('text').attr('class', 'axis-title').attr('dy', '-.35em').attr('text-anchor', 'middle'); + this.svg + .append('g') + .attr('class', 'x axis') + .append('text') + .attr('class', 'axis-title') + .attr('dy', '-.35em') + .attr('text-anchor', 'middle'); } function addYAxis() { - this.svg.append('g').attr('class', 'y axis').append('text').attr('class', 'axis-title').attr('transform', 'rotate(-90)').attr('dy', '.75em').attr('text-anchor', 'middle'); + this.svg + .append('g') + .attr('class', 'y axis') + .append('text') + .attr('class', 'axis-title') + .attr('transform', 'rotate(-90)') + .attr('dy', '.75em') + .attr('text-anchor', 'middle'); } function addOverlay() { - this.overlay = this.svg.append('rect').attr('class', 'overlay').attr('opacity', 0).attr('fill', 'none').style('pointer-events', 'all'); + this.overlay = this.svg + .append('rect') + .attr('class', 'overlay') + .attr('opacity', 0) + .attr('fill', 'none') + .style('pointer-events', 'all'); } function addLegend() { //The legend is contained in the parent object of multiples so each multiple does not need its own legend. - if (!this.parent) this.wrap.append('ul').datum(function () { - return null; - }) // prevent data inheritance - .attr('class', 'legend').style('vertical-align', 'top').append('span').attr('class', 'legend-title'); + if (!this.parent) + this.wrap + .append('ul') + .datum(function() { + return null; + }) // prevent data inheritance + .attr('class', 'legend') + .style('vertical-align', 'top') + .append('span') + .attr('class', 'legend-title'); } function clearLoader() { @@ -207,7 +268,9 @@ // warn the user about the perils of "processed_data" if (processed_data) { - console.warn("Drawing the chart using user-defined 'processed_data', this is an experimental, untested feature."); + console.warn( + "Drawing the chart using user-defined 'processed_data', this is an experimental, untested feature." + ); } //Call consolidateData - this applies filters from controls and prepares data for each set of marks. @@ -222,24 +285,38 @@ this.setColorScale(); var max_width = config.max_width ? config.max_width : div_width; - this.raw_width = config.x.type === 'ordinal' && +config.x.range_band ? (+config.x.range_band + config.x.range_band * config.padding) * this.x_dom.length : config.resizable ? max_width : config.width ? config.width : div_width; - this.raw_height = config.y.type === 'ordinal' && +config.y.range_band ? (+config.y.range_band + config.y.range_band * config.padding) * this.y_dom.length : config.resizable ? max_width * (1 / config.aspect) : config.height ? config.height : div_width * (1 / config.aspect); - - var pseudo_width = this.svg.select('.overlay').attr('width') ? this.svg.select('.overlay').attr('width') : this.raw_width; - var pseudo_height = this.svg.select('.overlay').attr('height') ? this.svg.select('.overlay').attr('height') : this.raw_height; - - this.svg.select('.x.axis').select('.axis-title').text(function (d) { - return typeof config.x.label === 'string' ? config.x.label : typeof config.x.label === 'function' ? config.x.label.call(_this) : null; + this.raw_width = config.x.type === 'ordinal' && +config.x.range_band + ? (+config.x.range_band + config.x.range_band * config.padding) * this.x_dom.length + : config.resizable ? max_width : config.width ? config.width : div_width; + this.raw_height = config.y.type === 'ordinal' && +config.y.range_band + ? (+config.y.range_band + config.y.range_band * config.padding) * this.y_dom.length + : config.resizable + ? max_width * (1 / config.aspect) + : config.height ? config.height : div_width * (1 / config.aspect); + + var pseudo_width = this.svg.select('.overlay').attr('width') + ? this.svg.select('.overlay').attr('width') + : this.raw_width; + var pseudo_height = this.svg.select('.overlay').attr('height') + ? this.svg.select('.overlay').attr('height') + : this.raw_height; + + this.svg.select('.x.axis').select('.axis-title').text(function(d) { + return typeof config.x.label === 'string' + ? config.x.label + : typeof config.x.label === 'function' ? config.x.label.call(_this) : null; }); - this.svg.select('.y.axis').select('.axis-title').text(function (d) { - return typeof config.y.label === 'string' ? config.y.label : typeof config.y.label === 'function' ? config.y.label.call(_this) : null; + this.svg.select('.y.axis').select('.axis-title').text(function(d) { + return typeof config.y.label === 'string' + ? config.y.label + : typeof config.y.label === 'function' ? config.y.label.call(_this) : null; }); this.xScaleAxis(pseudo_width); this.yScaleAxis(pseudo_height); if (config.resizable && typeof window !== 'undefined') { - d3.select(window).on('resize.' + this.element + this.id, function () { + d3.select(window).on('resize.' + this.element + this.id, function() { chart.resize(); }); } else if (typeof window !== 'undefined') { @@ -264,8 +341,8 @@ i = void 0, j = void 0; - while (i = (j = t.charAt(x++)).charCodeAt(0)) { - var m = i == 46 || i >= 48 && i <= 57; + while ((i = (j = t.charAt(x++)).charCodeAt(0))) { + var m = i == 46 || (i >= 48 && i <= 57); if (m !== n) { tz[++y] = ''; n = m; @@ -305,49 +382,101 @@ this[axis + '_dom'] = this.config[axis].domain; } else if (this.config[axis].order) { //data-driven domain with user-defined domain order - this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { - return mark[axis + '_dom']; - }))).values().sort(function (a, b) { - return d3.ascending(_this.config[axis].order.indexOf(a), _this.config[axis].order.indexOf(b)); - }); - } else if (this.config[axis].sort && this.config[axis].sort === 'alphabetical-ascending') { + this[axis + '_dom'] = d3 + .set( + d3.merge( + this.marks.map(function(mark) { + return mark[axis + '_dom']; + }) + ) + ) + .values() + .sort(function(a, b) { + return d3.ascending( + _this.config[axis].order.indexOf(a), + _this.config[axis].order.indexOf(b) + ); + }); + } else if ( + this.config[axis].sort && + this.config[axis].sort === 'alphabetical-ascending' + ) { //data-driven domain with user-defined domain sort algorithm that sorts the axis //alphanumerically, first to last - this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { - return mark[axis + '_dom']; - }))).values().sort(naturalSorter); - } else if (['time', 'linear'].indexOf(this.config[otherAxis].type) > -1 && this.config[axis].sort === 'earliest') { + this[axis + '_dom'] = d3 + .set( + d3.merge( + this.marks.map(function(mark) { + return mark[axis + '_dom']; + }) + ) + ) + .values() + .sort(naturalSorter); + } else if ( + ['time', 'linear'].indexOf(this.config[otherAxis].type) > -1 && + this.config[axis].sort === 'earliest' + ) { //data-driven domain plotted against a time or linear axis that sorts the axis values //by earliest event/datum; generally used with timeline charts - this[axis + '_dom'] = d3.nest().key(function (d) { - return d[_this.config[axis].column]; - }).rollup(function (d) { - return d.map(function (m) { - return m[_this.config[otherAxis].column]; - }).filter(function (f) { - return f instanceof Date; + this[axis + '_dom'] = d3 + .nest() + .key(function(d) { + return d[_this.config[axis].column]; + }) + .rollup(function(d) { + return d + .map(function(m) { + return m[_this.config[otherAxis].column]; + }) + .filter(function(f) { + return f instanceof Date; + }); + }) + .entries(this.filtered_data) + .sort(function(a, b) { + return d3.min(b.values) - d3.min(a.values); + }) + .map(function(m) { + return m.key; }); - }).entries(this.filtered_data).sort(function (a, b) { - return d3.min(b.values) - d3.min(a.values); - }).map(function (m) { - return m.key; - }); - } else if (!this.config[axis].sort || this.config[axis].sort === 'alphabetical-descending') { + } else if ( + !this.config[axis].sort || + this.config[axis].sort === 'alphabetical-descending' + ) { //data-driven domain with default/user-defined domain sort algorithm that sorts the //axis alphanumerically, last to first - this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { - return mark[axis + '_dom']; - }))).values().sort(naturalSorter).reverse(); + this[axis + '_dom'] = d3 + .set( + d3.merge( + this.marks.map(function(mark) { + return mark[axis + '_dom']; + }) + ) + ) + .values() + .sort(naturalSorter) + .reverse(); } else { //data-driven domain with an invalid user-defined sort algorithm that captures a unique //set of values as they appear in the data - this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { - return mark[axis + '_dom']; - }))).values(); + this[axis + '_dom'] = d3 + .set( + d3.merge( + this.marks.map(function(mark) { + return mark[axis + '_dom']; + }) + ) + ) + .values(); } - } else if (this.config.marks.map(function (m) { - return m['summarize' + axis.toUpperCase()] === 'percent'; - }).indexOf(true) > -1) { + } else if ( + this.config.marks + .map(function(m) { + return m['summarize' + axis.toUpperCase()] === 'percent'; + }) + .indexOf(true) > -1 + ) { //rate domains run from 0 to 1 this[axis + '_dom'] = [0, 1]; } else { @@ -355,13 +484,26 @@ //TODO: they should really run from the minimum to the maximum summarized value, e.g. a //TODO: means over time chart should plot over the range of the means, not the range of the //TODO: raw data - this[axis + '_dom'] = d3.extent(d3.merge(this.marks.map(function (mark) { - return mark[axis + '_dom']; - }))); + this[axis + '_dom'] = d3.extent( + d3.merge( + this.marks.map(function(mark) { + return mark[axis + '_dom']; + }) + ) + ); } //Give the domain a range when the range of the variable is 0. - if (this.config[axis].type === 'linear' && this[axis + '_dom'][0] === this[axis + '_dom'][1]) this[axis + '_dom'] = this[axis + '_dom'][0] !== 0 ? [this[axis + '_dom'][0] - this[axis + '_dom'][0] * 0.01, this[axis + '_dom'][1] + this[axis + '_dom'][1] * 0.01] : [-1, 1]; + if ( + this.config[axis].type === 'linear' && + this[axis + '_dom'][0] === this[axis + '_dom'][1] + ) + this[axis + '_dom'] = this[axis + '_dom'][0] !== 0 + ? [ + this[axis + '_dom'][0] - this[axis + '_dom'][0] * 0.01, + this[axis + '_dom'][1] + this[axis + '_dom'][1] * 0.01 + ] + : [-1, 1]; return this[axis + '_dom']; } @@ -374,25 +516,31 @@ //Apply filters from associated controls objects to raw data. this.filtered_data = raw; if (this.filters.length) { - this.filters.forEach(function (filter) { - _this.filtered_data = _this.filtered_data.filter(function (d) { - return filter.all === true && filter.index === 0 ? d : filter.val instanceof Array ? filter.val.indexOf(d[filter.col]) > -1 : d[filter.col] === filter.val; + this.filters.forEach(function(filter) { + _this.filtered_data = _this.filtered_data.filter(function(d) { + return filter.all === true && filter.index === 0 + ? d + : filter.val instanceof Array + ? filter.val.indexOf(d[filter.col]) > -1 + : d[filter.col] === filter.val; }); }); } //Summarize data for each mark. - this.config.marks.forEach(function (mark, i) { + this.config.marks.forEach(function(mark, i) { if (mark.type !== 'bar') { mark.arrange = null; mark.split = null; } - var mark_info = mark.per ? _this.transformData(raw, mark) : { - data: [], - x_dom: [], - y_dom: [] - }; + var mark_info = mark.per + ? _this.transformData(raw, mark) + : { + data: [], + x_dom: [], + y_dom: [] + }; _this.marks[i] = { id: mark.id, @@ -423,8 +571,12 @@ this.config.x = this.config.x || {}; this.config.y = this.config.y || {}; - this.config.x.label = this.config.x.label !== undefined ? this.config.x.label : this.config.x.column; - this.config.y.label = this.config.y.label !== undefined ? this.config.y.label : this.config.y.column; + this.config.x.label = this.config.x.label !== undefined + ? this.config.x.label + : this.config.x.column; + this.config.y.label = this.config.y.label !== undefined + ? this.config.y.label + : this.config.y.column; this.config.x.sort = this.config.x.sort || 'alphabetical-ascending'; this.config.y.sort = this.config.y.sort || 'alphabetical-descending'; @@ -437,10 +589,16 @@ this.config.margin = this.config.margin || {}; this.config.legend = this.config.legend || {}; - this.config.legend.label = this.config.legend.label !== undefined ? this.config.legend.label : this.config.color_by; - this.config.legend.location = this.config.legend.location !== undefined ? this.config.legend.location : 'bottom'; - this.config.marks = this.config.marks && this.config.marks.length ? this.config.marks : [{}]; - this.config.marks.forEach(function (m, i) { + this.config.legend.label = this.config.legend.label !== undefined + ? this.config.legend.label + : this.config.color_by; + this.config.legend.location = this.config.legend.location !== undefined + ? this.config.legend.location + : 'bottom'; + this.config.marks = this.config.marks && this.config.marks.length + ? this.config.marks + : [{}]; + this.config.marks.forEach(function(m, i) { m.id = m.id ? m.id : 'mark' + (i + 1); }); @@ -453,10 +611,23 @@ this.config.aspect = this.config.aspect || 1.33; - this.config.colors = this.config.colors || ['rgb(102,194,165)', 'rgb(252,141,98)', 'rgb(141,160,203)', 'rgb(231,138,195)', 'rgb(166,216,84)', 'rgb(255,217,47)', 'rgb(229,196,148)', 'rgb(179,179,179)']; - - this.config.scale_text = this.config.scale_text === undefined ? true : this.config.scale_text; - this.config.transitions = this.config.transitions === undefined ? true : this.config.transitions; + this.config.colors = this.config.colors || [ + 'rgb(102,194,165)', + 'rgb(252,141,98)', + 'rgb(141,160,203)', + 'rgb(231,138,195)', + 'rgb(166,216,84)', + 'rgb(255,217,47)', + 'rgb(229,196,148)', + 'rgb(179,179,179)' + ]; + + this.config.scale_text = this.config.scale_text === undefined + ? true + : this.config.scale_text; + this.config.transitions = this.config.transitions === undefined + ? true + : this.config.transitions; } function cleanData(mark, raw) { @@ -465,50 +636,68 @@ var dateConvert = d3.time.format(this.config.date_format); var clean = raw; // only use data for the current mark - clean = mark.per && mark.per.length ? clean.filter(function (f) { - return f[mark.per[0]] !== undefined; - }) : clean; + clean = mark.per && mark.per.length + ? clean.filter(function(f) { + return f[mark.per[0]] !== undefined; + }) + : clean; // Make sure data has x and y values if (this.config.x.column) { - clean = clean.filter(function (f) { + clean = clean.filter(function(f) { return [undefined, null].indexOf(f[_this.config.x.column]) < 0; }); } if (this.config.y.column) { - clean = clean.filter(function (f) { + clean = clean.filter(function(f) { return [undefined, null].indexOf(f[_this.config.y.column]) < 0; }); } //check that x and y have the correct formats if (this.config.x.type === 'time') { - clean = clean.filter(function (f) { - return f[_this.config.x.column] instanceof Date ? f[_this.config.x.column] : dateConvert.parse(f[_this.config.x.column]); + clean = clean.filter(function(f) { + return f[_this.config.x.column] instanceof Date + ? f[_this.config.x.column] + : dateConvert.parse(f[_this.config.x.column]); }); - clean.forEach(function (e) { - return e[_this.config.x.column] = e[_this.config.x.column] instanceof Date ? e[_this.config.x.column] : dateConvert.parse(e[_this.config.x.column]); + clean.forEach(function(e) { + return (e[_this.config.x.column] = e[_this.config.x.column] instanceof Date + ? e[_this.config.x.column] + : dateConvert.parse(e[_this.config.x.column])); }); } if (this.config.y.type === 'time') { - clean = clean.filter(function (f) { - return f[_this.config.y.column] instanceof Date ? f[_this.config.y.column] : dateConvert.parse(f[_this.config.y.column]); + clean = clean.filter(function(f) { + return f[_this.config.y.column] instanceof Date + ? f[_this.config.y.column] + : dateConvert.parse(f[_this.config.y.column]); }); - clean.forEach(function (e) { - return e[_this.config.y.column] = e[_this.config.y.column] instanceof Date ? e[_this.config.y.column] : dateConvert.parse(e[_this.config.y.column]); + clean.forEach(function(e) { + return (e[_this.config.y.column] = e[_this.config.y.column] instanceof Date + ? e[_this.config.y.column] + : dateConvert.parse(e[_this.config.y.column])); }); } - if ((this.config.x.type === 'linear' || this.config.x.type === 'log') && this.config.x.column) { - clean = clean.filter(function (f) { - return mark.summarizeX !== 'count' && mark.summarizeX !== 'percent' ? !(isNaN(f[_this.config.x.column]) || /^\s*$/.test(f[_this.config.x.column])) // is or coerces to a number and is not a string that coerces to 0 - : f; + if ( + (this.config.x.type === 'linear' || this.config.x.type === 'log') && + this.config.x.column + ) { + clean = clean.filter(function(f) { + return mark.summarizeX !== 'count' && mark.summarizeX !== 'percent' + ? !(isNaN(f[_this.config.x.column]) || /^\s*$/.test(f[_this.config.x.column])) // is or coerces to a number and is not a string that coerces to 0 + : f; }); } - if ((this.config.y.type === 'linear' || this.config.y.type === 'log') && this.config.y.column) { - clean = clean.filter(function (f) { - return mark.summarizeY !== 'count' && mark.summarizeY !== 'percent' ? !(isNaN(f[_this.config.y.column]) || /^\s*$/.test(f[_this.config.y.column])) // is or coerces to a number and is not a string that coerces to 0 - : f; + if ( + (this.config.y.type === 'linear' || this.config.y.type === 'log') && + this.config.y.column + ) { + clean = clean.filter(function(f) { + return mark.summarizeY !== 'count' && mark.summarizeY !== 'percent' + ? !(isNaN(f[_this.config.y.column]) || /^\s*$/.test(f[_this.config.y.column])) // is or coerces to a number and is not a string that coerces to 0 + : f; }); } @@ -526,17 +715,21 @@ function summarize(vals) { var operation = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'mean'; - var nvals = vals.filter(function (f) { - return +f || +f === 0; - }).map(function (m) { - return +m; - }); + var nvals = vals + .filter(function(f) { + return +f || +f === 0; + }) + .map(function(m) { + return +m; + }); if (operation === 'cumulative') { return null; } - var mathed = operation === 'count' ? vals.length : operation === 'percent' ? vals.length : stats[operation](nvals); + var mathed = operation === 'count' + ? vals.length + : operation === 'percent' ? vals.length : stats[operation](nvals); return mathed; } @@ -549,75 +742,125 @@ var this_nest = d3.nest(); var totalOrder = void 0; - if (this.config.x.type === 'linear' && this.config.x.bin || this.config.y.type === 'linear' && this.config.y.bin) { + if ( + (this.config.x.type === 'linear' && this.config.x.bin) || + (this.config.y.type === 'linear' && this.config.y.bin) + ) { var xy = this.config.x.type === 'linear' && this.config.x.bin ? 'x' : 'y'; - var quant = d3.scale.quantile().domain(d3.extent(entries.map(function (m) { - return +m[_this.config[xy].column]; - }))).range(d3.range(+this.config[xy].bin)); - - entries.forEach(function (e) { - return e.wc_bin = quant(e[_this.config[xy].column]); + var quant = d3.scale + .quantile() + .domain( + d3.extent( + entries.map(function(m) { + return +m[_this.config[xy].column]; + }) + ) + ) + .range(d3.range(+this.config[xy].bin)); + + entries.forEach(function(e) { + return (e.wc_bin = quant(e[_this.config[xy].column])); }); - this_nest.key(function (d) { + this_nest.key(function(d) { return quant.invertExtent(d.wc_bin); }); } else { - this_nest.key(function (d) { - return mark.per.map(function (m) { - return d[m]; - }).join(' '); + this_nest.key(function(d) { + return mark.per + .map(function(m) { + return d[m]; + }) + .join(' '); }); } if (sublevel) { - this_nest.key(function (d) { + this_nest.key(function(d) { return d[sublevel]; }); - this_nest.sortKeys(function (a, b) { - return _this.config.x.type === 'time' ? d3.ascending(new Date(a), new Date(b)) : _this.config.x.order ? d3.ascending(_this.config.x.order.indexOf(a), _this.config.x.order.indexOf(b)) : sublevel === _this.config.color_by && _this.config.legend.order ? d3.ascending(_this.config.legend.order.indexOf(a), _this.config.legend.order.indexOf(b)) : _this.config.x.type === 'ordinal' || _this.config.y.type === 'ordinal' ? naturalSorter(a, b) : d3.ascending(+a, +b); + this_nest.sortKeys(function(a, b) { + return _this.config.x.type === 'time' + ? d3.ascending(new Date(a), new Date(b)) + : _this.config.x.order + ? d3.ascending( + _this.config.x.order.indexOf(a), + _this.config.x.order.indexOf(b) + ) + : sublevel === _this.config.color_by && _this.config.legend.order + ? d3.ascending( + _this.config.legend.order.indexOf(a), + _this.config.legend.order.indexOf(b) + ) + : _this.config.x.type === 'ordinal' || _this.config.y.type === 'ordinal' + ? naturalSorter(a, b) + : d3.ascending(+a, +b); }); } - this_nest.rollup(function (r) { + this_nest.rollup(function(r) { var obj = { raw: r }; - var y_vals = r.map(function (m) { - return m[_this.config.y.column]; - }).sort(d3.ascending); - var x_vals = r.map(function (m) { - return m[_this.config.x.column]; - }).sort(d3.ascending); - obj.x = _this.config.x.type === 'ordinal' ? r[0][_this.config.x.column] : summarize(x_vals, mark.summarizeX); - obj.y = _this.config.y.type === 'ordinal' ? r[0][_this.config.y.column] : summarize(y_vals, mark.summarizeY); - - obj.x_q25 = _this.config.error_bars && _this.config.y.type === 'ordinal' ? d3.quantile(x_vals, 0.25) : obj.x; - obj.x_q75 = _this.config.error_bars && _this.config.y.type === 'ordinal' ? d3.quantile(x_vals, 0.75) : obj.x; + var y_vals = r + .map(function(m) { + return m[_this.config.y.column]; + }) + .sort(d3.ascending); + var x_vals = r + .map(function(m) { + return m[_this.config.x.column]; + }) + .sort(d3.ascending); + obj.x = _this.config.x.type === 'ordinal' + ? r[0][_this.config.x.column] + : summarize(x_vals, mark.summarizeX); + obj.y = _this.config.y.type === 'ordinal' + ? r[0][_this.config.y.column] + : summarize(y_vals, mark.summarizeY); + + obj.x_q25 = _this.config.error_bars && _this.config.y.type === 'ordinal' + ? d3.quantile(x_vals, 0.25) + : obj.x; + obj.x_q75 = _this.config.error_bars && _this.config.y.type === 'ordinal' + ? d3.quantile(x_vals, 0.75) + : obj.x; obj.y_q25 = _this.config.error_bars ? d3.quantile(y_vals, 0.25) : obj.y; obj.y_q75 = _this.config.error_bars ? d3.quantile(y_vals, 0.75) : obj.y; dom_xs.push([obj.x_q25, obj.x_q75, obj.x]); dom_ys.push([obj.y_q25, obj.y_q75, obj.y]); if (mark.summarizeY === 'cumulative') { - var interm = entries.filter(function (f) { - return _this.config.x.type === 'time' ? new Date(f[_this.config.x.column]) <= new Date(r[0][_this.config.x.column]) : +f[_this.config.x.column] <= +r[0][_this.config.x.column]; + var interm = entries.filter(function(f) { + return _this.config.x.type === 'time' + ? new Date(f[_this.config.x.column]) <= + new Date(r[0][_this.config.x.column]) + : +f[_this.config.x.column] <= +r[0][_this.config.x.column]; }); if (mark.per.length) { - interm = interm.filter(function (f) { + interm = interm.filter(function(f) { return f[mark.per[0]] === r[0][mark.per[0]]; }); } - var cumul = _this.config.x.type === 'time' ? interm.length : d3.sum(interm.map(function (m) { - return +m[_this.config.y.column] || +m[_this.config.y.column] === 0 ? +m[_this.config.y.column] : 1; - })); + var cumul = _this.config.x.type === 'time' + ? interm.length + : d3.sum( + interm.map(function(m) { + return +m[_this.config.y.column] || +m[_this.config.y.column] === 0 + ? +m[_this.config.y.column] + : 1; + }) + ); dom_ys.push([cumul]); obj.y = cumul; } if (mark.summarizeX === 'cumulative') { - var _interm = entries.filter(function (f) { - return _this.config.y.type === 'time' ? new Date(f[_this.config.y.column]) <= new Date(r[0][_this.config.y.column]) : +f[_this.config.y.column] <= +r[0][_this.config.y.column]; + var _interm = entries.filter(function(f) { + return _this.config.y.type === 'time' + ? new Date(f[_this.config.y.column]) <= + new Date(r[0][_this.config.y.column]) + : +f[_this.config.y.column] <= +r[0][_this.config.y.column]; }); if (mark.per.length) { - _interm = _interm.filter(function (f) { + _interm = _interm.filter(function(f) { return f[mark.per[0]] === r[0][mark.per[0]]; }); } @@ -635,19 +878,31 @@ if (sublevel && mark.type === 'bar' && mark.split) { //calculate percentages in bars - test.forEach(function (e) { - var axis = _this.config.x.type === 'ordinal' || _this.config.x.type === 'linear' && _this.config.x.bin ? 'y' : 'x'; - e.total = d3.sum(e.values.map(function (m) { - return +m.values[axis]; - })); + test.forEach(function(e) { + var axis = _this.config.x.type === 'ordinal' || + (_this.config.x.type === 'linear' && _this.config.x.bin) + ? 'y' + : 'x'; + e.total = d3.sum( + e.values.map(function(m) { + return +m.values[axis]; + }) + ); var counter = 0; - e.values.forEach(function (v, i) { - if (_this.config.x.type === 'ordinal' || _this.config.x.type === 'linear' && _this.config.x.bin) { - v.values.y = mark.summarizeY === 'percent' ? v.values.y / e.total : v.values.y || 0; + e.values.forEach(function(v, i) { + if ( + _this.config.x.type === 'ordinal' || + (_this.config.x.type === 'linear' && _this.config.x.bin) + ) { + v.values.y = mark.summarizeY === 'percent' + ? v.values.y / e.total + : v.values.y || 0; counter += +v.values.y; v.values.start = e.values[i - 1] ? counter : v.values.y; } else { - v.values.x = mark.summarizeX === 'percent' ? v.values.x / e.total : v.values.x || 0; + v.values.x = mark.summarizeX === 'percent' + ? v.values.x / e.total + : v.values.x || 0; v.values.start = counter; counter += +v.values.x; } @@ -655,36 +910,59 @@ }); if (mark.arrange === 'stacked') { - if (this.config.x.type === 'ordinal' || this.config.x.type === 'linear' && this.config.x.bin) { - dom_y = d3.extent(test.map(function (m) { - return m.total; - })); + if ( + this.config.x.type === 'ordinal' || + (this.config.x.type === 'linear' && this.config.x.bin) + ) { + dom_y = d3.extent( + test.map(function(m) { + return m.total; + }) + ); } - if (this.config.y.type === 'ordinal' || this.config.y.type === 'linear' && this.config.y.bin) { - dom_x = d3.extent(test.map(function (m) { - return m.total; - })); + if ( + this.config.y.type === 'ordinal' || + (this.config.y.type === 'linear' && this.config.y.bin) + ) { + dom_x = d3.extent( + test.map(function(m) { + return m.total; + }) + ); } } } else { - var axis = this.config.x.type === 'ordinal' || this.config.x.type === 'linear' && this.config.x.bin ? 'y' : 'x'; - test.forEach(function (e) { - return e.total = e.values[axis]; + var axis = this.config.x.type === 'ordinal' || + (this.config.x.type === 'linear' && this.config.x.bin) + ? 'y' + : 'x'; + test.forEach(function(e) { + return (e.total = e.values[axis]); }); } - if (this.config.x.sort === 'total-ascending' && this.config.x.type == 'ordinal' || this.config.y.sort === 'total-descending' && this.config.y.type == 'ordinal') { - totalOrder = test.sort(function (a, b) { - return d3.ascending(a.total, b.total); - }).map(function (m) { - return m.key; - }); - } else if (this.config.x.sort === 'total-descending' && this.config.x.type == 'ordinal' || this.config.y.sort === 'total-ascending' && this.config.y.type == 'ordinal') { - totalOrder = test.sort(function (a, b) { - return d3.descending(+a.total, +b.total); - }).map(function (m) { - return m.key; - }); + if ( + (this.config.x.sort === 'total-ascending' && this.config.x.type == 'ordinal') || + (this.config.y.sort === 'total-descending' && this.config.y.type == 'ordinal') + ) { + totalOrder = test + .sort(function(a, b) { + return d3.ascending(a.total, b.total); + }) + .map(function(m) { + return m.key; + }); + } else if ( + (this.config.x.sort === 'total-descending' && this.config.x.type == 'ordinal') || + (this.config.y.sort === 'total-ascending' && this.config.y.type == 'ordinal') + ) { + totalOrder = test + .sort(function(a, b) { + return d3.descending(+a.total, +b.total); + }) + .map(function(m) { + return m.key; + }); } return { nested: test, dom_x: dom_x, dom_y: dom_y, totalOrder: totalOrder }; @@ -708,7 +986,9 @@ var config = this.config; var x_behavior = config.x.behavior || 'raw'; var y_behavior = config.y.behavior || 'raw'; - var sublevel = mark.type === 'line' ? config.x.column : mark.type === 'bar' && mark.split ? mark.split : null; + var sublevel = mark.type === 'line' + ? config.x.column + : mark.type === 'bar' && mark.split ? mark.split : null; ////////////////////////////////////////////////////////////////////////////////// // DATA PREP @@ -719,73 +999,127 @@ //prepare nested data required for bar charts var raw_nest = void 0; if (mark.type === 'bar') { - raw_nest = mark.arrange !== 'stacked' ? makeNest.call(this, mark, cleaned, sublevel) : makeNest.call(this, mark, cleaned); + raw_nest = mark.arrange !== 'stacked' + ? makeNest.call(this, mark, cleaned, sublevel) + : makeNest.call(this, mark, cleaned); } else if (mark.summarizeX === 'count' || mark.summarizeY === 'count') { raw_nest = makeNest.call(this, mark, cleaned); } // Get the domain for the mark based on the raw data - var raw_dom_x = mark.summarizeX === 'cumulative' ? [0, cleaned.length] : config.x.type === 'ordinal' ? d3.set(cleaned.map(function (m) { - return m[config.x.column]; - })).values().filter(function (f) { - return f; - }) : mark.split && mark.arrange !== 'stacked' ? d3.extent(d3.merge(raw_nest.nested.map(function (m) { - return m.values.map(function (p) { - return p.values.raw.length; - }); - }))) : mark.summarizeX === 'count' ? d3.extent(raw_nest.nested.map(function (m) { - return m.values.raw.length; - })) : d3.extent(cleaned.map(function (m) { - return +m[config.x.column]; - }).filter(function (f) { - return +f || +f === 0; - })); - - var raw_dom_y = mark.summarizeY === 'cumulative' ? [0, cleaned.length] : config.y.type === 'ordinal' ? d3.set(cleaned.map(function (m) { - return m[config.y.column]; - })).values().filter(function (f) { - return f; - }) : mark.split && mark.arrange !== 'stacked' ? d3.extent(d3.merge(raw_nest.nested.map(function (m) { - return m.values.map(function (p) { - return p.values.raw.length; - }); - }))) : mark.summarizeY === 'count' ? d3.extent(raw_nest.nested.map(function (m) { - return m.values.raw.length; - })) : d3.extent(cleaned.map(function (m) { - return +m[config.y.column]; - }).filter(function (f) { - return +f || +f === 0; - })); + var raw_dom_x = mark.summarizeX === 'cumulative' + ? [0, cleaned.length] + : config.x.type === 'ordinal' + ? d3 + .set( + cleaned.map(function(m) { + return m[config.x.column]; + }) + ) + .values() + .filter(function(f) { + return f; + }) + : mark.split && mark.arrange !== 'stacked' + ? d3.extent( + d3.merge( + raw_nest.nested.map(function(m) { + return m.values.map(function(p) { + return p.values.raw.length; + }); + }) + ) + ) + : mark.summarizeX === 'count' + ? d3.extent( + raw_nest.nested.map(function(m) { + return m.values.raw.length; + }) + ) + : d3.extent( + cleaned + .map(function(m) { + return +m[config.x.column]; + }) + .filter(function(f) { + return +f || +f === 0; + }) + ); + + var raw_dom_y = mark.summarizeY === 'cumulative' + ? [0, cleaned.length] + : config.y.type === 'ordinal' + ? d3 + .set( + cleaned.map(function(m) { + return m[config.y.column]; + }) + ) + .values() + .filter(function(f) { + return f; + }) + : mark.split && mark.arrange !== 'stacked' + ? d3.extent( + d3.merge( + raw_nest.nested.map(function(m) { + return m.values.map(function(p) { + return p.values.raw.length; + }); + }) + ) + ) + : mark.summarizeY === 'count' + ? d3.extent( + raw_nest.nested.map(function(m) { + return m.values.raw.length; + }) + ) + : d3.extent( + cleaned + .map(function(m) { + return +m[config.y.column]; + }) + .filter(function(f) { + return +f || +f === 0; + }) + ); var filtered = cleaned; var filt1_xs = []; var filt1_ys = []; if (this.filters.length) { - this.filters.forEach(function (e) { - filtered = filtered.filter(function (d) { - return e.all === true && e.index === 0 ? d : e.val instanceof Array ? e.val.indexOf(d[e.col]) > -1 : d[e.col] === e.val; + this.filters.forEach(function(e) { + filtered = filtered.filter(function(d) { + return e.all === true && e.index === 0 + ? d + : e.val instanceof Array + ? e.val.indexOf(d[e.col]) > -1 + : d[e.col] === e.val; }); }); //get domain for all non-All values of first filter if (config.x.behavior === 'firstfilter' || config.y.behavior === 'firstfilter') { - this.filters[0].choices.filter(function (f) { - return f !== 'All'; - }).forEach(function (e) { - var perfilter = cleaned.filter(function (f) { - return f[_this.filters[0].col] === e; + this.filters[0].choices + .filter(function(f) { + return f !== 'All'; + }) + .forEach(function(e) { + var perfilter = cleaned.filter(function(f) { + return f[_this.filters[0].col] === e; + }); + var filt_nested = makeNest.call(_this, mark, perfilter, sublevel); + filt1_xs.push(filt_nested.dom_x); + filt1_ys.push(filt_nested.dom_y); }); - var filt_nested = makeNest.call(_this, mark, perfilter, sublevel); - filt1_xs.push(filt_nested.dom_x); - filt1_ys.push(filt_nested.dom_y); - }); } } //filter on mark-specific instructions if (mark.values) { var _loop = function _loop(a) { - filtered = filtered.filter(function (f) { + filtered = filtered.filter(function(f) { return mark.values[a].indexOf(f[a]) > -1; }); }; @@ -811,43 +1145,112 @@ } //several criteria must be met in order to use the 'firstfilter' domain - var nonall = Boolean(this.filters.length && this.filters[0].val !== 'All' && this.filters.slice(1).filter(function (f) { - return f.val === 'All'; - }).length === this.filters.length - 1); - - var pre_x_dom = !this.filters.length ? flex_dom_x : x_behavior === 'raw' ? raw_dom_x : nonall && x_behavior === 'firstfilter' ? filt1_dom_x : flex_dom_x; - var pre_y_dom = !this.filters.length ? flex_dom_y : y_behavior === 'raw' ? raw_dom_y : nonall && y_behavior === 'firstfilter' ? filt1_dom_y : flex_dom_y; - - var x_dom = config.x_dom ? config.x_dom : config.x.type === 'ordinal' && config.x.behavior === 'flex' ? d3.set(filtered.map(function (m) { - return m[config.x.column]; - })).values() : config.x.type === 'ordinal' ? d3.set(cleaned.map(function (m) { - return m[config.x.column]; - })).values() : pre_x_dom; - - var y_dom = config.y_dom ? config.y_dom : config.y.type === 'ordinal' && config.y.behavior === 'flex' ? d3.set(filtered.map(function (m) { - return m[config.y.column]; - })).values() : config.y.type === 'ordinal' ? d3.set(cleaned.map(function (m) { - return m[config.y.column]; - })).values() : pre_y_dom; + var nonall = Boolean( + this.filters.length && + this.filters[0].val !== 'All' && + this.filters.slice(1).filter(function(f) { + return f.val === 'All'; + }).length === + this.filters.length - 1 + ); + + var pre_x_dom = !this.filters.length + ? flex_dom_x + : x_behavior === 'raw' + ? raw_dom_x + : nonall && x_behavior === 'firstfilter' ? filt1_dom_x : flex_dom_x; + var pre_y_dom = !this.filters.length + ? flex_dom_y + : y_behavior === 'raw' + ? raw_dom_y + : nonall && y_behavior === 'firstfilter' ? filt1_dom_y : flex_dom_y; + + var x_dom = config.x_dom + ? config.x_dom + : config.x.type === 'ordinal' && config.x.behavior === 'flex' + ? d3 + .set( + filtered.map(function(m) { + return m[config.x.column]; + }) + ) + .values() + : config.x.type === 'ordinal' + ? d3 + .set( + cleaned.map(function(m) { + return m[config.x.column]; + }) + ) + .values() + : pre_x_dom; + + var y_dom = config.y_dom + ? config.y_dom + : config.y.type === 'ordinal' && config.y.behavior === 'flex' + ? d3 + .set( + filtered.map(function(m) { + return m[config.y.column]; + }) + ) + .values() + : config.y.type === 'ordinal' + ? d3 + .set( + cleaned.map(function(m) { + return m[config.y.column]; + }) + ) + .values() + : pre_y_dom; //set lower limit of linear domain to 0 when other axis is ordinal and mark type is set to 'bar', provided no values are negative if (mark.type === 'bar') { - if (config.x.behavior !== 'flex' && config.x.type === 'linear' && config.y.type === 'ordinal' && raw_dom_x[0] >= 0) x_dom[0] = 0; - - if (config.y.behavior !== 'flex' && config.x.type === 'ordinal' && config.y.type === 'linear' && raw_dom_y[0] >= 0) y_dom[0] = 0; + if ( + config.x.behavior !== 'flex' && + config.x.type === 'linear' && + config.y.type === 'ordinal' && + raw_dom_x[0] >= 0 + ) + x_dom[0] = 0; + + if ( + config.y.behavior !== 'flex' && + config.x.type === 'ordinal' && + config.y.type === 'linear' && + raw_dom_y[0] >= 0 + ) + y_dom[0] = 0; } //update domains with those specified in the config - if (config.x.domain && (config.x.domain[0] || config.x.domain[0] === 0) && !isNaN(+config.x.domain[0])) { + if ( + config.x.domain && + (config.x.domain[0] || config.x.domain[0] === 0) && + !isNaN(+config.x.domain[0]) + ) { x_dom[0] = config.x.domain[0]; } - if (config.x.domain && (config.x.domain[1] || config.x.domain[1] === 0) && !isNaN(+config.x.domain[1])) { + if ( + config.x.domain && + (config.x.domain[1] || config.x.domain[1] === 0) && + !isNaN(+config.x.domain[1]) + ) { x_dom[1] = config.x.domain[1]; } - if (config.y.domain && (config.y.domain[0] || config.y.domain[0] === 0) && !isNaN(+config.y.domain[0])) { + if ( + config.y.domain && + (config.y.domain[0] || config.y.domain[0] === 0) && + !isNaN(+config.y.domain[0]) + ) { y_dom[0] = config.y.domain[0]; } - if (config.y.domain && (config.y.domain[1] || config.y.domain[1] === 0) && !isNaN(+config.y.domain[1])) { + if ( + config.y.domain && + (config.y.domain[1] || config.y.domain[1] === 0) && + !isNaN(+config.y.domain[1]) + ) { y_dom[1] = config.y.domain[1]; } @@ -868,15 +1271,24 @@ function setColorScale() { var config = this.config; var data = config.legend.behavior === 'flex' ? this.filtered_data : this.raw_data; - var colordom = Array.isArray(config.color_dom) && config.color_dom.length ? config.color_dom.slice() : d3.set(data.map(function (m) { - return m[config.color_by]; - })).values().filter(function (f) { - return f && f !== 'undefined'; - }); - - if (config.legend.order) colordom.sort(function (a, b) { - return d3.ascending(config.legend.order.indexOf(a), config.legend.order.indexOf(b)); - });else colordom.sort(naturalSorter); + var colordom = Array.isArray(config.color_dom) && config.color_dom.length + ? config.color_dom.slice() + : d3 + .set( + data.map(function(m) { + return m[config.color_by]; + }) + ) + .values() + .filter(function(f) { + return f && f !== 'undefined'; + }); + + if (config.legend.order) + colordom.sort(function(a, b) { + return d3.ascending(config.legend.order.indexOf(a), config.legend.order.indexOf(b)); + }); + else colordom.sort(naturalSorter); this.colorScale = d3.scale.ordinal().domain(colordom).range(config.colors); } @@ -912,11 +1324,29 @@ x.range([0, +max_range]).clamp(Boolean(config.x.clamp)); } - var xFormat = config.x.format ? config.x.format : config.marks.map(function (m) { - return m.summarizeX === 'percent'; - }).indexOf(true) > -1 ? '0%' : type === 'time' ? '%x' : '.0f'; + var xFormat = config.x.format + ? config.x.format + : config.marks + .map(function(m) { + return m.summarizeX === 'percent'; + }) + .indexOf(true) > -1 + ? '0%' + : type === 'time' ? '%x' : '.0f'; var tick_count = Math.max(2, Math.min(max_range / 80, 8)); - var xAxis = d3.svg.axis().scale(x).orient(config.x.location).ticks(tick_count).tickFormat(type === 'ordinal' ? null : type === 'time' ? d3.time.format(xFormat) : d3.format(xFormat)).tickValues(config.x.ticks ? config.x.ticks : null).innerTickSize(6).outerTickSize(3); + var xAxis = d3.svg + .axis() + .scale(x) + .orient(config.x.location) + .ticks(tick_count) + .tickFormat( + type === 'ordinal' + ? null + : type === 'time' ? d3.time.format(xFormat) : d3.format(xFormat) + ) + .tickValues(config.x.ticks ? config.x.ticks : null) + .innerTickSize(6) + .outerTickSize(3); this.svg.select('g.x.axis').attr('class', 'x axis ' + type); this.x = x; @@ -953,11 +1383,29 @@ y.range([+max_range, 0]).clamp(Boolean(config.y_clamp)); } - var yFormat = config.y.format ? config.y.format : config.marks.map(function (m) { - return m.summarizeY === 'percent'; - }).indexOf(true) > -1 ? '0%' : '.0f'; + var yFormat = config.y.format + ? config.y.format + : config.marks + .map(function(m) { + return m.summarizeY === 'percent'; + }) + .indexOf(true) > -1 + ? '0%' + : '.0f'; var tick_count = Math.max(2, Math.min(max_range / 80, 8)); - var yAxis = d3.svg.axis().scale(y).orient('left').ticks(tick_count).tickFormat(type === 'ordinal' ? null : type === 'time' ? d3.time.format(yFormat) : d3.format(yFormat)).tickValues(config.y.ticks ? config.y.ticks : null).innerTickSize(6).outerTickSize(3); + var yAxis = d3.svg + .axis() + .scale(y) + .orient('left') + .ticks(tick_count) + .tickFormat( + type === 'ordinal' + ? null + : type === 'time' ? d3.time.format(yFormat) : d3.format(yFormat) + ) + .tickValues(config.y.ticks ? config.y.ticks : null) + .innerTickSize(6) + .outerTickSize(3); this.svg.select('g.y.axis').attr('class', 'y axis ' + type); @@ -971,22 +1419,45 @@ var aspect2 = 1 / config.aspect; var div_width = parseInt(this.wrap.style('width')); var max_width = config.max_width ? config.max_width : div_width; - var preWidth = !config.resizable ? config.width : !max_width || div_width < max_width ? div_width : this.raw_width; + var preWidth = !config.resizable + ? config.width + : !max_width || div_width < max_width ? div_width : this.raw_width; this.textSize(preWidth); this.margin = this.setMargins(); - var svg_width = config.x.type === 'ordinal' && +config.x.range_band ? this.raw_width + this.margin.left + this.margin.right : !config.resizable ? this.raw_width : !config.max_width || div_width < config.max_width ? div_width : this.raw_width; + var svg_width = config.x.type === 'ordinal' && +config.x.range_band + ? this.raw_width + this.margin.left + this.margin.right + : !config.resizable + ? this.raw_width + : !config.max_width || div_width < config.max_width ? div_width : this.raw_width; this.plot_width = svg_width - this.margin.left - this.margin.right; - var svg_height = config.y.type === 'ordinal' && +config.y.range_band ? this.raw_height + this.margin.top + this.margin.bottom : !config.resizable && config.height ? config.height : !config.resizable ? svg_width * aspect2 : this.plot_width * aspect2; + var svg_height = config.y.type === 'ordinal' && +config.y.range_band + ? this.raw_height + this.margin.top + this.margin.bottom + : !config.resizable && config.height + ? config.height + : !config.resizable ? svg_width * aspect2 : this.plot_width * aspect2; this.plot_height = svg_height - this.margin.top - this.margin.bottom; - d3.select(this.svg.node().parentNode).attr('width', svg_width).attr('height', svg_height).select('g').attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')'); - - this.svg.select('.overlay').attr('width', this.plot_width).attr('height', this.plot_height).classed('zoomable', config.zoomable); - - this.svg.select('.plotting-area').attr('width', this.plot_width).attr('height', this.plot_height + 1).attr('transform', 'translate(0, -1)'); + d3 + .select(this.svg.node().parentNode) + .attr('width', svg_width) + .attr('height', svg_height) + .select('g') + .attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')'); + + this.svg + .select('.overlay') + .attr('width', this.plot_width) + .attr('height', this.plot_height) + .classed('zoomable', config.zoomable); + + this.svg + .select('.plotting-area') + .attr('width', this.plot_width) + .attr('height', this.plot_height + 1) + .attr('transform', 'translate(0, -1)'); this.xScaleAxis(); this.yScaleAxis(); @@ -1004,11 +1475,23 @@ var gYAxisTrans = config.transitions ? g_y_axis.transition() : g_y_axis; gYAxisTrans.call(this.yAxis); - x_axis_label.attr('transform', 'translate(' + this.plot_width / 2 + ',' + (this.margin.bottom - 2) + ')'); + x_axis_label.attr( + 'transform', + 'translate(' + this.plot_width / 2 + ',' + (this.margin.bottom - 2) + ')' + ); y_axis_label.attr('x', -1 * this.plot_height / 2).attr('y', -1 * this.margin.left); - this.svg.selectAll('.axis .domain').attr({ fill: 'none', stroke: '#ccc', 'stroke-width': 1, 'shape-rendering': 'crispEdges' }); - this.svg.selectAll('.axis .tick line').attr({ stroke: '#eee', 'stroke-width': 1, 'shape-rendering': 'crispEdges' }); + this.svg + .selectAll('.axis .domain') + .attr({ + fill: 'none', + stroke: '#ccc', + 'stroke-width': 1, + 'shape-rendering': 'crispEdges' + }); + this.svg + .selectAll('.axis .tick line') + .attr({ stroke: '#eee', 'stroke-width': 1, 'shape-rendering': 'crispEdges' }); this.drawGridlines(); @@ -1057,13 +1540,17 @@ function setMargins() { var _this = this; - var y_ticks = this.yAxis.tickFormat() ? this.y.domain().map(function (m) { - return _this.yAxis.tickFormat()(m); - }) : this.y.domain(); - - var max_y_text_length = d3.max(y_ticks.map(function (m) { - return String(m).length; - })); + var y_ticks = this.yAxis.tickFormat() + ? this.y.domain().map(function(m) { + return _this.yAxis.tickFormat()(m); + }) + : this.y.domain(); + + var max_y_text_length = d3.max( + y_ticks.map(function(m) { + return String(m).length; + }) + ); if (this.config.y_format && this.config.y_format.indexOf('%') > -1) { max_y_text_length += 1; } @@ -1073,7 +1560,8 @@ var font_size = parseInt(this.wrap.style('font-size')); var x_second = this.config.x2_interval ? 1 : 0; var y_margin = max_y_text_length * font_size * 0.5 + font_size * y_label_on * 1.5 || 8; - var x_margin = font_size + font_size / 1.5 + font_size * x_label_on + font_size * x_second || 8; + var x_margin = + font_size + font_size / 1.5 + font_size * x_label_on + font_size * x_second || 8; y_margin += 6; x_margin += 3; @@ -1081,7 +1569,9 @@ return { top: this.config.margin && this.config.margin.top ? this.config.margin.top : 8, right: this.config.margin && this.config.margin.right ? this.config.margin.right : 16, - bottom: this.config.margin && this.config.margin.bottom ? this.config.margin.bottom : x_margin, + bottom: this.config.margin && this.config.margin.bottom + ? this.config.margin.bottom + : x_margin, left: this.config.margin && this.config.margin.left ? this.config.margin.left : y_margin }; } @@ -1091,8 +1581,10 @@ if (this.config.gridlines) { this.svg.select('.y.axis').selectAll('.tick line').attr('x1', 0); this.svg.select('.x.axis').selectAll('.tick line').attr('y1', 0); - if (this.config.gridlines === 'y' || this.config.gridlines === 'xy') this.svg.select('.y.axis').selectAll('.tick line').attr('x1', this.plot_width); - if (this.config.gridlines === 'x' || this.config.gridlines === 'xy') this.svg.select('.x.axis').selectAll('.tick line').attr('y1', -this.plot_height); + if (this.config.gridlines === 'y' || this.config.gridlines === 'xy') + this.svg.select('.y.axis').selectAll('.tick line').attr('x1', this.plot_width); + if (this.config.gridlines === 'x' || this.config.gridlines === 'xy') + this.svg.select('.x.axis').selectAll('.tick line').attr('y1', -this.plot_height); } else { this.svg.select('.y.axis').selectAll('.tick line').attr('x1', 0); this.svg.select('.x.axis').selectAll('.tick line').attr('y1', 0); @@ -1100,15 +1592,23 @@ } function makeLegend() { - var scale = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.colorScale; + var scale = arguments.length > 0 && arguments[0] !== undefined + ? arguments[0] + : this.colorScale; var label = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; var custom_data = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; var config = this.config; - config.legend.mark = config.legend.mark ? config.legend.mark : config.marks.length && config.marks[0].type === 'bar' ? 'square' : config.marks.length ? config.marks[0].type : 'square'; + config.legend.mark = config.legend.mark + ? config.legend.mark + : config.marks.length && config.marks[0].type === 'bar' + ? 'square' + : config.marks.length ? config.marks[0].type : 'square'; - var legend_label = label ? label : typeof config.legend.label === 'string' ? config.legend.label : ''; + var legend_label = label + ? label + : typeof config.legend.label === 'string' ? config.legend.label : ''; var legendOriginal = this.legend || this.wrap.select('.legend'); var legend = legendOriginal; @@ -1123,7 +1623,12 @@ } else { //multiples - keep legend outside of individual charts' wraps if (this.config.legend.location === 'top' || this.config.legend.location === 'left') { - this.parent.wrap.node().insertBefore(legendOriginal.node(), this.parent.wrap.select('.wc-chart').node()); + this.parent.wrap + .node() + .insertBefore( + legendOriginal.node(), + this.parent.wrap.select('.wc-chart').node() + ); } else { this.parent.wrap.node().appendChild(legendOriginal.node()); } @@ -1131,40 +1636,65 @@ legend.style('padding', 0); - var legend_data = custom_data || scale.domain().slice(0).filter(function (f) { - return f !== undefined && f !== null; - }).map(function (m) { - return { label: m, mark: config.legend.mark }; - }); + var legend_data = + custom_data || + scale + .domain() + .slice(0) + .filter(function(f) { + return f !== undefined && f !== null; + }) + .map(function(m) { + return { label: m, mark: config.legend.mark }; + }); - legend.select('.legend-title').text(legend_label).style('display', legend_label ? 'inline' : 'none').style('margin-right', '1em'); + legend + .select('.legend-title') + .text(legend_label) + .style('display', legend_label ? 'inline' : 'none') + .style('margin-right', '1em'); - var leg_parts = legend.selectAll('.legend-item').data(legend_data, function (d) { + var leg_parts = legend.selectAll('.legend-item').data(legend_data, function(d) { return d.label + d.mark; }); leg_parts.exit().remove(); - var legendPartDisplay = this.config.legend.location === 'bottom' || this.config.legend.location === 'top' ? 'inline-block' : 'block'; - var new_parts = leg_parts.enter().append('li').attr('class', 'legend-item').style({ 'list-style-type': 'none', 'margin-right': '1em' }); - new_parts.append('span').attr('class', 'legend-mark-text').style('color', function (d) { + var legendPartDisplay = this.config.legend.location === 'bottom' || + this.config.legend.location === 'top' + ? 'inline-block' + : 'block'; + var new_parts = leg_parts + .enter() + .append('li') + .attr('class', 'legend-item') + .style({ 'list-style-type': 'none', 'margin-right': '1em' }); + new_parts.append('span').attr('class', 'legend-mark-text').style('color', function(d) { return scale(d.label); }); - new_parts.append('svg').attr('class', 'legend-color-block').attr('width', '1.1em').attr('height', '1.1em').style({ - position: 'relative', - top: '0.2em' - }); + new_parts + .append('svg') + .attr('class', 'legend-color-block') + .attr('width', '1.1em') + .attr('height', '1.1em') + .style({ + position: 'relative', + top: '0.2em' + }); leg_parts.style('display', legendPartDisplay); if (config.legend.order) { - leg_parts.sort(function (a, b) { - return d3.ascending(config.legend.order.indexOf(a.label), config.legend.order.indexOf(b.label)); + leg_parts.sort(function(a, b) { + return d3.ascending( + config.legend.order.indexOf(a.label), + config.legend.order.indexOf(b.label) + ); }); } leg_parts.selectAll('.legend-color-block').select('.legend-mark').remove(); - leg_parts.selectAll('.legend-color-block').each(function (e) { + leg_parts.selectAll('.legend-color-block').each(function(e) { var svg = d3.select(this); if (e.mark === 'circle') { svg.append('circle').attr({ @@ -1192,20 +1722,33 @@ }); } }); - leg_parts.selectAll('.legend-color-block').select('.legend-mark').attr('fill', function (d) { - return d.color || scale(d.label); - }).attr('stroke', function (d) { - return d.color || scale(d.label); - }).each(function (e) { - d3.select(this).attr(e.attributes); - }); + leg_parts + .selectAll('.legend-color-block') + .select('.legend-mark') + .attr('fill', function(d) { + return d.color || scale(d.label); + }) + .attr('stroke', function(d) { + return d.color || scale(d.label); + }) + .each(function(e) { + d3.select(this).attr(e.attributes); + }); - new_parts.append('span').attr('class', 'legend-label').style('margin-left', '0.25em').text(function (d) { - return d.label; - }); + new_parts + .append('span') + .attr('class', 'legend-label') + .style('margin-left', '0.25em') + .text(function(d) { + return d.label; + }); if (scale.domain().length > 0) { - var legendDisplay = (this.config.legend.location === 'bottom' || this.config.legend.location === 'top') && !this.parent ? 'block' : 'inline-block'; + var legendDisplay = (this.config.legend.location === 'bottom' || + this.config.legend.location === 'top') && + !this.parent + ? 'block' + : 'inline-block'; legend.style('display', legendDisplay); } else { legend.style('display', 'none'); @@ -1215,42 +1758,67 @@ } function updateDataMarks() { - this.drawBars(this.marks.filter(function (f) { - return f.type === 'bar'; - })); - this.drawLines(this.marks.filter(function (f) { - return f.type === 'line'; - })); - this.drawPoints(this.marks.filter(function (f) { - return f.type === 'circle'; - })); - this.drawText(this.marks.filter(function (f) { - return f.type === 'text'; - })); + this.drawBars( + this.marks.filter(function(f) { + return f.type === 'bar'; + }) + ); + this.drawLines( + this.marks.filter(function(f) { + return f.type === 'line'; + }) + ); + this.drawPoints( + this.marks.filter(function(f) { + return f.type === 'circle'; + }) + ); + this.drawText( + this.marks.filter(function(f) { + return f.type === 'text'; + }) + ); this.marks.supergroups = this.svg.selectAll('g.supergroup'); } function drawArea(area_drawer, area_data, datum_accessor) { - var class_match = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'chart-area'; + var class_match = arguments.length > 3 && arguments[3] !== undefined + ? arguments[3] + : 'chart-area'; var _this = this; var bind_accessor = arguments[4]; - var attr_accessor = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : function (d) { - return d; - }; + var attr_accessor = arguments.length > 5 && arguments[5] !== undefined + ? arguments[5] + : function(d) { + return d; + }; var area_grps = this.svg.selectAll('.' + class_match).data(area_data, bind_accessor); area_grps.exit().remove(); - area_grps.enter().append('g').attr('class', function (d) { - return class_match + ' ' + d.key; - }).append('path'); - - var areaPaths = area_grps.select('path').datum(datum_accessor).attr('fill', function (d) { - var d_attr = attr_accessor(d); - return d_attr ? _this.colorScale(d_attr[_this.config.color_by]) : null; - }).attr('fill-opacity', this.config.fill_opacity || this.config.fill_opacity === 0 ? this.config.fill_opacity : 0.3); + area_grps + .enter() + .append('g') + .attr('class', function(d) { + return class_match + ' ' + d.key; + }) + .append('path'); + + var areaPaths = area_grps + .select('path') + .datum(datum_accessor) + .attr('fill', function(d) { + var d_attr = attr_accessor(d); + return d_attr ? _this.colorScale(d_attr[_this.config.color_by]) : null; + }) + .attr( + 'fill-opacity', + this.config.fill_opacity || this.config.fill_opacity === 0 + ? this.config.fill_opacity + : 0.3 + ); //don't transition if config says not to var areaPathTransitions = this.config.transitions ? areaPaths.transition() : areaPaths; @@ -1267,27 +1835,32 @@ var rawData = this.raw_data; var config = this.config; - var bar_supergroups = this.svg.selectAll('.bar-supergroup').data(marks, function (d, i) { + var bar_supergroups = this.svg.selectAll('.bar-supergroup').data(marks, function(d, i) { return i + '-' + d.per.join('-'); }); - bar_supergroups.enter().append('g').attr('class', function (d) { + bar_supergroups.enter().append('g').attr('class', function(d) { return 'supergroup bar-supergroup ' + d.id; }); bar_supergroups.exit().remove(); - var bar_groups = bar_supergroups.selectAll('.bar-group').data(function (d) { - return d.data; - }, function (d) { - return d.key; - }); + var bar_groups = bar_supergroups.selectAll('.bar-group').data( + function(d) { + return d.data; + }, + function(d) { + return d.key; + } + ); var old_bar_groups = bar_groups.exit(); var nu_bar_groups = void 0; var bars = void 0; - var oldBarsTrans = config.transitions ? old_bar_groups.selectAll('.bar').transition() : old_bar_groups.selectAll('.bar'); + var oldBarsTrans = config.transitions + ? old_bar_groups.selectAll('.bar').transition() + : old_bar_groups.selectAll('.bar'); var oldBarGroupsTrans = config.transitions ? old_bar_groups.transition() : old_bar_groups; if (config.x.type === 'ordinal') { @@ -1295,207 +1868,327 @@ oldBarGroupsTrans.remove(); - nu_bar_groups = bar_groups.enter().append('g').attr('class', function (d) { + nu_bar_groups = bar_groups.enter().append('g').attr('class', function(d) { return 'bar-group ' + d.key; }); nu_bar_groups.append('title'); - bars = bar_groups.selectAll('rect').data(function (d) { - return d.values instanceof Array ? d.values.sort(function (a, b) { - return _this.colorScale.domain().indexOf(b.key) - _this.colorScale.domain().indexOf(a.key); - }) : [d]; - }, function (d) { - return d.key; - }); + bars = bar_groups.selectAll('rect').data( + function(d) { + return d.values instanceof Array + ? d.values.sort(function(a, b) { + return ( + _this.colorScale.domain().indexOf(b.key) - + _this.colorScale.domain().indexOf(a.key) + ); + }) + : [d]; + }, + function(d) { + return d.key; + } + ); var exitBars = config.transitions ? bars.exit().transition() : bars.exit(); exitBars.attr('y', this.y(0)).attr('height', 0).remove(); - bars.enter().append('rect').attr('class', function (d) { - return 'wc-data-mark bar ' + d.key; - }).style('clip-path', 'url(#' + chart.id + ')').attr('y', this.y(0)).attr('height', 0).append('title'); - - bars.attr('shape-rendering', 'crispEdges').attr('stroke', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }).attr('fill', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); + bars + .enter() + .append('rect') + .attr('class', function(d) { + return 'wc-data-mark bar ' + d.key; + }) + .style('clip-path', 'url(#' + chart.id + ')') + .attr('y', this.y(0)) + .attr('height', 0) + .append('title'); + + bars + .attr('shape-rendering', 'crispEdges') + .attr('stroke', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }) + .attr('fill', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); - bars.each(function (d) { + bars.each(function(d) { var mark = d3.select(this.parentNode.parentNode).datum(); d.tooltip = mark.tooltip; - d.arrange = mark.split && mark.arrange ? mark.arrange : mark.split ? 'grouped' : null; - d.subcats = config.legend.order ? config.legend.order.slice().reverse() : mark.values && mark.values[mark.split] ? mark.values[mark.split] : d3.set(rawData.map(function (m) { - return m[mark.split]; - })).values(); + d.arrange = mark.split && mark.arrange + ? mark.arrange + : mark.split ? 'grouped' : null; + d.subcats = config.legend.order + ? config.legend.order.slice().reverse() + : mark.values && mark.values[mark.split] + ? mark.values[mark.split] + : d3 + .set( + rawData.map(function(m) { + return m[mark.split]; + }) + ) + .values(); d3.select(this).attr(mark.attributes); }); - var xformat = config.marks.map(function (m) { - return m.summarizeX === 'percent'; - }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.x.format); - var yformat = config.marks.map(function (m) { - return m.summarizeY === 'percent'; - }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.y.format); - bars.select('title').text(function (d) { + var xformat = config.marks + .map(function(m) { + return m.summarizeX === 'percent'; + }) + .indexOf(true) > -1 + ? d3.format('0%') + : d3.format(config.x.format); + var yformat = config.marks + .map(function(m) { + return m.summarizeY === 'percent'; + }) + .indexOf(true) > -1 + ? d3.format('0%') + : d3.format(config.y.format); + bars.select('title').text(function(d) { var tt = d.tooltip || ''; - return tt.replace(/\$x/g, xformat(d.values.x)).replace(/\$y/g, yformat(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { - return d.values.raw[0][orig]; - }); + return tt + .replace(/\$x/g, xformat(d.values.x)) + .replace(/\$y/g, yformat(d.values.y)) + .replace(/\[(.+?)\]/g, function(str, orig) { + return d.values.raw[0][orig]; + }); }); var barsTrans = config.transitions ? bars.transition() : bars; - barsTrans.attr('x', function (d) { - var position = void 0; - if (!d.arrange || d.arrange === 'stacked') { - return _this.x(d.values.x); - } else if (d.arrange === 'nested') { - var _position = d.subcats.indexOf(d.key); - var offset = _position ? _this.x.rangeBand() / (d.subcats.length * 0.75) / _position : _this.x.rangeBand(); - return _this.x(d.values.x) + (_this.x.rangeBand() - offset) / 2; - } else { - position = d.subcats.indexOf(d.key); - return _this.x(d.values.x) + _this.x.rangeBand() / d.subcats.length * position; - } - }).attr('y', function (d) { - if (d.arrange !== 'stacked') { - return _this.y(d.values.y); - } else { - return _this.y(d.values.start); - } - }).attr('width', function (d) { - if (!d.arrange || d.arrange === 'stacked') { - return _this.x.rangeBand(); - } else if (d.arrange === 'nested') { - var position = d.subcats.indexOf(d.key); - return position ? _this.x.rangeBand() / (d.subcats.length * 0.75) / position : _this.x.rangeBand(); - } else { - return _this.x.rangeBand() / d.subcats.length; - } - }).attr('height', function (d) { - return _this.y(0) - _this.y(d.values.y); - }); + barsTrans + .attr('x', function(d) { + var position = void 0; + if (!d.arrange || d.arrange === 'stacked') { + return _this.x(d.values.x); + } else if (d.arrange === 'nested') { + var _position = d.subcats.indexOf(d.key); + var offset = _position + ? _this.x.rangeBand() / (d.subcats.length * 0.75) / _position + : _this.x.rangeBand(); + return _this.x(d.values.x) + (_this.x.rangeBand() - offset) / 2; + } else { + position = d.subcats.indexOf(d.key); + return ( + _this.x(d.values.x) + _this.x.rangeBand() / d.subcats.length * position + ); + } + }) + .attr('y', function(d) { + if (d.arrange !== 'stacked') { + return _this.y(d.values.y); + } else { + return _this.y(d.values.start); + } + }) + .attr('width', function(d) { + if (!d.arrange || d.arrange === 'stacked') { + return _this.x.rangeBand(); + } else if (d.arrange === 'nested') { + var position = d.subcats.indexOf(d.key); + return position + ? _this.x.rangeBand() / (d.subcats.length * 0.75) / position + : _this.x.rangeBand(); + } else { + return _this.x.rangeBand() / d.subcats.length; + } + }) + .attr('height', function(d) { + return _this.y(0) - _this.y(d.values.y); + }); } else if (config.y.type === 'ordinal') { oldBarsTrans.attr('x', this.x(0)).attr('width', 0); oldBarGroupsTrans.remove(); - nu_bar_groups = bar_groups.enter().append('g').attr('class', function (d) { + nu_bar_groups = bar_groups.enter().append('g').attr('class', function(d) { return 'bar-group ' + d.key; }); nu_bar_groups.append('title'); - bars = bar_groups.selectAll('rect').data(function (d) { - return d.values instanceof Array ? d.values.sort(function (a, b) { - return _this.colorScale.domain().indexOf(b.key) - _this.colorScale.domain().indexOf(a.key); - }) : [d]; - }, function (d) { - return d.key; - }); + bars = bar_groups.selectAll('rect').data( + function(d) { + return d.values instanceof Array + ? d.values.sort(function(a, b) { + return ( + _this.colorScale.domain().indexOf(b.key) - + _this.colorScale.domain().indexOf(a.key) + ); + }) + : [d]; + }, + function(d) { + return d.key; + } + ); var _exitBars = config.transitions ? bars.exit().transition() : bars.exit(); _exitBars.attr('x', this.x(0)).attr('width', 0).remove(); - bars.enter().append('rect').attr('class', function (d) { - return 'wc-data-mark bar ' + d.key; - }).style('clip-path', 'url(#' + chart.id + ')').attr('x', this.x(0)).attr('width', 0).append('title'); - - bars.attr('shape-rendering', 'crispEdges').attr('stroke', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }).attr('fill', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); + bars + .enter() + .append('rect') + .attr('class', function(d) { + return 'wc-data-mark bar ' + d.key; + }) + .style('clip-path', 'url(#' + chart.id + ')') + .attr('x', this.x(0)) + .attr('width', 0) + .append('title'); + + bars + .attr('shape-rendering', 'crispEdges') + .attr('stroke', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }) + .attr('fill', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); - bars.each(function (d) { + bars.each(function(d) { var mark = d3.select(this.parentNode.parentNode).datum(); - d.arrange = mark.split && mark.arrange ? mark.arrange : mark.split ? 'grouped' : null; - d.subcats = config.legend.order ? config.legend.order.slice().reverse() : mark.values && mark.values[mark.split] ? mark.values[mark.split] : d3.set(rawData.map(function (m) { - return m[mark.split]; - })).values(); + d.arrange = mark.split && mark.arrange + ? mark.arrange + : mark.split ? 'grouped' : null; + d.subcats = config.legend.order + ? config.legend.order.slice().reverse() + : mark.values && mark.values[mark.split] + ? mark.values[mark.split] + : d3 + .set( + rawData.map(function(m) { + return m[mark.split]; + }) + ) + .values(); d.tooltip = mark.tooltip; d3.select(this).attr(mark.attributes); }); - var _xformat = config.marks.map(function (m) { - return m.summarizeX === 'percent'; - }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.x.format); - var _yformat = config.marks.map(function (m) { - return m.summarizeY === 'percent'; - }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.y.format); - bars.select('title').text(function (d) { + var _xformat = config.marks + .map(function(m) { + return m.summarizeX === 'percent'; + }) + .indexOf(true) > -1 + ? d3.format('0%') + : d3.format(config.x.format); + var _yformat = config.marks + .map(function(m) { + return m.summarizeY === 'percent'; + }) + .indexOf(true) > -1 + ? d3.format('0%') + : d3.format(config.y.format); + bars.select('title').text(function(d) { var tt = d.tooltip || ''; - return tt.replace(/\$x/g, _xformat(d.values.x)).replace(/\$y/g, _yformat(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { - return d.values.raw[0][orig]; - }); + return tt + .replace(/\$x/g, _xformat(d.values.x)) + .replace(/\$y/g, _yformat(d.values.y)) + .replace(/\[(.+?)\]/g, function(str, orig) { + return d.values.raw[0][orig]; + }); }); var _barsTrans = config.transitions ? bars.transition() : bars; - _barsTrans.attr('x', function (d) { - if (d.arrange === 'stacked' || !d.arrange) { - return d.values.start !== undefined ? _this.x(d.values.start) : _this.x(0); - } else { - return _this.x(0); - } - }).attr('y', function (d) { - if (d.arrange === 'nested') { - var position = d.subcats.indexOf(d.key); - var offset = position ? _this.y.rangeBand() / (d.subcats.length * 0.75) / position : _this.y.rangeBand(); - return _this.y(d.values.y) + (_this.y.rangeBand() - offset) / 2; - } else if (d.arrange === 'grouped') { - var _position2 = d.subcats.indexOf(d.key); - return _this.y(d.values.y) + _this.y.rangeBand() / d.subcats.length * _position2; - } else { - return _this.y(d.values.y); - } - }).attr('width', function (d) { - return _this.x(d.values.x) - _this.x(0); - }).attr('height', function (d) { - if (config.y.type === 'quantile') { - return 20; - } else if (d.arrange === 'nested') { - var position = d.subcats.indexOf(d.key); - return position ? _this.y.rangeBand() / (d.subcats.length * 0.75) / position : _this.y.rangeBand(); - } else if (d.arrange === 'grouped') { - return _this.y.rangeBand() / d.subcats.length; - } else { - return _this.y.rangeBand(); - } - }); + _barsTrans + .attr('x', function(d) { + if (d.arrange === 'stacked' || !d.arrange) { + return d.values.start !== undefined ? _this.x(d.values.start) : _this.x(0); + } else { + return _this.x(0); + } + }) + .attr('y', function(d) { + if (d.arrange === 'nested') { + var position = d.subcats.indexOf(d.key); + var offset = position + ? _this.y.rangeBand() / (d.subcats.length * 0.75) / position + : _this.y.rangeBand(); + return _this.y(d.values.y) + (_this.y.rangeBand() - offset) / 2; + } else if (d.arrange === 'grouped') { + var _position2 = d.subcats.indexOf(d.key); + return ( + _this.y(d.values.y) + + _this.y.rangeBand() / d.subcats.length * _position2 + ); + } else { + return _this.y(d.values.y); + } + }) + .attr('width', function(d) { + return _this.x(d.values.x) - _this.x(0); + }) + .attr('height', function(d) { + if (config.y.type === 'quantile') { + return 20; + } else if (d.arrange === 'nested') { + var position = d.subcats.indexOf(d.key); + return position + ? _this.y.rangeBand() / (d.subcats.length * 0.75) / position + : _this.y.rangeBand(); + } else if (d.arrange === 'grouped') { + return _this.y.rangeBand() / d.subcats.length; + } else { + return _this.y.rangeBand(); + } + }); } else if (['linear', 'log'].indexOf(config.x.type) > -1 && config.x.bin) { oldBarsTrans.attr('y', this.y(0)).attr('height', 0); oldBarGroupsTrans.remove(); - nu_bar_groups = bar_groups.enter().append('g').attr('class', function (d) { + nu_bar_groups = bar_groups.enter().append('g').attr('class', function(d) { return 'bar-group ' + d.key; }); nu_bar_groups.append('title'); - bars = bar_groups.selectAll('rect').data(function (d) { - return d.values instanceof Array ? d.values : [d]; - }, function (d) { - return d.key; - }); + bars = bar_groups.selectAll('rect').data( + function(d) { + return d.values instanceof Array ? d.values : [d]; + }, + function(d) { + return d.key; + } + ); var _exitBars2 = config.transitions ? bars.exit().transition() : bars.exit(); _exitBars2.attr('y', this.y(0)).attr('height', 0).remove(); - bars.enter().append('rect').attr('class', function (d) { - return 'wc-data-mark bar ' + d.key; - }).style('clip-path', 'url(#' + chart.id + ')').attr('y', this.y(0)).attr('height', 0).append('title'); - - bars.attr('shape-rendering', 'crispEdges').attr('stroke', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }).attr('fill', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); + bars + .enter() + .append('rect') + .attr('class', function(d) { + return 'wc-data-mark bar ' + d.key; + }) + .style('clip-path', 'url(#' + chart.id + ')') + .attr('y', this.y(0)) + .attr('height', 0) + .append('title'); + + bars + .attr('shape-rendering', 'crispEdges') + .attr('stroke', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }) + .attr('fill', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); - bars.each(function (d) { + bars.each(function(d) { var mark = d3.select(this.parentNode.parentNode).datum(); d.arrange = mark.split ? mark.arrange : null; - d.subcats = config.legend.order ? config.legend.order.slice().reverse() : mark.values && mark.values[mark.split] ? mark.values[mark.split] : d3.set(rawData.map(function (m) { - return m[mark.split]; - })).values(); + d.subcats = config.legend.order + ? config.legend.order.slice().reverse() + : mark.values && mark.values[mark.split] + ? mark.values[mark.split] + : d3 + .set( + rawData.map(function(m) { + return m[mark.split]; + }) + ) + .values(); d3.select(this).attr(mark.attributes); var parent = d3.select(this.parentNode).datum(); - var rangeSet = parent.key.split(',').map(function (m) { + var rangeSet = parent.key.split(',').map(function(m) { return +m; }); d.rangeLow = d3.min(rangeSet); @@ -1503,68 +2196,108 @@ d.tooltip = mark.tooltip; }); - var _xformat2 = config.marks.map(function (m) { - return m.summarizeX === 'percent'; - }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.x.format); - var _yformat2 = config.marks.map(function (m) { - return m.summarizeY === 'percent'; - }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.y.format); - bars.select('title').text(function (d) { + var _xformat2 = config.marks + .map(function(m) { + return m.summarizeX === 'percent'; + }) + .indexOf(true) > -1 + ? d3.format('0%') + : d3.format(config.x.format); + var _yformat2 = config.marks + .map(function(m) { + return m.summarizeY === 'percent'; + }) + .indexOf(true) > -1 + ? d3.format('0%') + : d3.format(config.y.format); + bars.select('title').text(function(d) { var tt = d.tooltip || ''; - return tt.replace(/\$x/g, _xformat2(d.values.x)).replace(/\$y/g, _yformat2(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { - return d.values.raw[0][orig]; - }); + return tt + .replace(/\$x/g, _xformat2(d.values.x)) + .replace(/\$y/g, _yformat2(d.values.y)) + .replace(/\[(.+?)\]/g, function(str, orig) { + return d.values.raw[0][orig]; + }); }); var _barsTrans2 = config.transitions ? bars.transition() : bars; - _barsTrans2.attr('x', function (d) { - return _this.x(d.rangeLow); - }).attr('y', function (d) { - if (d.arrange !== 'stacked') { - return _this.y(d.values.y); - } else { - return _this.y(d.values.start); - } - }).attr('width', function (d) { - return _this.x(d.rangeHigh) - _this.x(d.rangeLow); - }).attr('height', function (d) { - return _this.y(0) - _this.y(d.values.y); - }); - } else if (['linear', 'log'].indexOf(config.y.type) > -1 && config.y.type === 'linear' && config.y.bin) { + _barsTrans2 + .attr('x', function(d) { + return _this.x(d.rangeLow); + }) + .attr('y', function(d) { + if (d.arrange !== 'stacked') { + return _this.y(d.values.y); + } else { + return _this.y(d.values.start); + } + }) + .attr('width', function(d) { + return _this.x(d.rangeHigh) - _this.x(d.rangeLow); + }) + .attr('height', function(d) { + return _this.y(0) - _this.y(d.values.y); + }); + } else if ( + ['linear', 'log'].indexOf(config.y.type) > -1 && + config.y.type === 'linear' && + config.y.bin + ) { oldBarsTrans.attr('x', this.x(0)).attr('width', 0); oldBarGroupsTrans.remove(); - nu_bar_groups = bar_groups.enter().append('g').attr('class', function (d) { + nu_bar_groups = bar_groups.enter().append('g').attr('class', function(d) { return 'bar-group ' + d.key; }); nu_bar_groups.append('title'); - bars = bar_groups.selectAll('rect').data(function (d) { - return d.values instanceof Array ? d.values : [d]; - }, function (d) { - return d.key; - }); + bars = bar_groups.selectAll('rect').data( + function(d) { + return d.values instanceof Array ? d.values : [d]; + }, + function(d) { + return d.key; + } + ); var _exitBars3 = config.transitions ? bars.exit().transition() : bars.exit(); _exitBars3.attr('x', this.x(0)).attr('width', 0).remove(); - bars.enter().append('rect').attr('class', function (d) { - return 'wc-data-mark bar ' + d.key; - }).style('clip-path', 'url(#' + chart.id + ')').attr('x', this.x(0)).attr('width', 0).append('title'); - - bars.attr('shape-rendering', 'crispEdges').attr('stroke', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }).attr('fill', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); + bars + .enter() + .append('rect') + .attr('class', function(d) { + return 'wc-data-mark bar ' + d.key; + }) + .style('clip-path', 'url(#' + chart.id + ')') + .attr('x', this.x(0)) + .attr('width', 0) + .append('title'); + + bars + .attr('shape-rendering', 'crispEdges') + .attr('stroke', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }) + .attr('fill', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); - bars.each(function (d) { + bars.each(function(d) { var mark = d3.select(this.parentNode.parentNode).datum(); d.arrange = mark.split ? mark.arrange : null; - d.subcats = config.legend.order ? config.legend.order.slice().reverse() : mark.values && mark.values[mark.split] ? mark.values[mark.split] : d3.set(rawData.map(function (m) { - return m[mark.split]; - })).values(); + d.subcats = config.legend.order + ? config.legend.order.slice().reverse() + : mark.values && mark.values[mark.split] + ? mark.values[mark.split] + : d3 + .set( + rawData.map(function(m) { + return m[mark.split]; + }) + ) + .values(); var parent = d3.select(this.parentNode).datum(); - var rangeSet = parent.key.split(',').map(function (m) { + var rangeSet = parent.key.split(',').map(function(m) { return +m; }); d.rangeLow = d3.min(rangeSet); @@ -1572,33 +2305,48 @@ d.tooltip = mark.tooltip; }); - var _xformat3 = config.marks.map(function (m) { - return m.summarizeX === 'percent'; - }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.x.format); - var _yformat3 = config.marks.map(function (m) { - return m.summarizeY === 'percent'; - }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.y.format); - bars.select('title').text(function (d) { + var _xformat3 = config.marks + .map(function(m) { + return m.summarizeX === 'percent'; + }) + .indexOf(true) > -1 + ? d3.format('0%') + : d3.format(config.x.format); + var _yformat3 = config.marks + .map(function(m) { + return m.summarizeY === 'percent'; + }) + .indexOf(true) > -1 + ? d3.format('0%') + : d3.format(config.y.format); + bars.select('title').text(function(d) { var tt = d.tooltip || ''; - return tt.replace(/\$x/g, _xformat3(d.values.x)).replace(/\$y/g, _yformat3(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { - return d.values.raw[0][orig]; - }); + return tt + .replace(/\$x/g, _xformat3(d.values.x)) + .replace(/\$y/g, _yformat3(d.values.y)) + .replace(/\[(.+?)\]/g, function(str, orig) { + return d.values.raw[0][orig]; + }); }); var _barsTrans3 = config.transitions ? bars.transition() : bars; - _barsTrans3.attr('x', function (d) { - if (d.arrange === 'stacked') { - return _this.x(d.values.start); - } else { - return _this.x(0); - } - }).attr('y', function (d) { - return _this.y(d.rangeHigh); - }).attr('width', function (d) { - return _this.x(d.values.x); - }).attr('height', function (d) { - return _this.y(d.rangeLow) - _this.y(d.rangeHigh); - }); + _barsTrans3 + .attr('x', function(d) { + if (d.arrange === 'stacked') { + return _this.x(d.values.start); + } else { + return _this.x(0); + } + }) + .attr('y', function(d) { + return _this.y(d.rangeHigh); + }) + .attr('width', function(d) { + return _this.x(d.values.x); + }) + .attr('height', function(d) { + return _this.y(d.rangeLow) - _this.y(d.rangeHigh); + }); } else { oldBarsTrans.attr('y', this.y(0)).attr('height', 0); oldBarGroupsTrans.remove(); @@ -1606,7 +2354,7 @@ } //Link to the d3.selection from the data - bar_supergroups.each(function (d) { + bar_supergroups.each(function(d) { d.supergroup = d3.select(this); d.groups = d.supergroup.selectAll('.bar-group'); }); @@ -1617,59 +2365,92 @@ var chart = this; var config = this.config; - var line = d3.svg.line().interpolate(config.interpolate).x(function (d) { - return config.x.type === 'linear' || config.x.type == 'log' ? _this.x(+d.values.x) : config.x.type === 'time' ? _this.x(new Date(d.values.x)) : _this.x(d.values.x) + _this.x.rangeBand() / 2; - }).y(function (d) { - return config.y.type === 'linear' || config.y.type == 'log' ? _this.y(+d.values.y) : config.y.type === 'time' ? _this.y(new Date(d.values.y)) : _this.y(d.values.y) + _this.y.rangeBand() / 2; - }); + var line = d3.svg + .line() + .interpolate(config.interpolate) + .x(function(d) { + return config.x.type === 'linear' || config.x.type == 'log' + ? _this.x(+d.values.x) + : config.x.type === 'time' + ? _this.x(new Date(d.values.x)) + : _this.x(d.values.x) + _this.x.rangeBand() / 2; + }) + .y(function(d) { + return config.y.type === 'linear' || config.y.type == 'log' + ? _this.y(+d.values.y) + : config.y.type === 'time' + ? _this.y(new Date(d.values.y)) + : _this.y(d.values.y) + _this.y.rangeBand() / 2; + }); - var line_supergroups = this.svg.selectAll('.line-supergroup').data(marks, function (d, i) { + var line_supergroups = this.svg.selectAll('.line-supergroup').data(marks, function(d, i) { return i + '-' + d.per.join('-'); }); - line_supergroups.enter().append('g').attr('class', function (d) { + line_supergroups.enter().append('g').attr('class', function(d) { return 'supergroup line-supergroup ' + d.id; }); line_supergroups.exit().remove(); - var line_grps = line_supergroups.selectAll('.line').data(function (d) { - return d.data; - }, function (d) { - return d.key; - }); + var line_grps = line_supergroups.selectAll('.line').data( + function(d) { + return d.data; + }, + function(d) { + return d.key; + } + ); line_grps.exit().remove(); - var nu_line_grps = line_grps.enter().append('g').attr('class', function (d) { + var nu_line_grps = line_grps.enter().append('g').attr('class', function(d) { return d.key + ' line'; }); nu_line_grps.append('path'); nu_line_grps.append('title'); - var linePaths = line_grps.select('path').attr('class', 'wc-data-mark').style('clip-path', 'url(#' + chart.id + ')').datum(function (d) { - return d.values; - }).attr('stroke', function (d) { - return _this.colorScale(d[0].values.raw[0][config.color_by]); - }).attr('stroke-width', config.stroke_width ? config.stroke_width : config.flex_stroke_width).attr('stroke-linecap', 'round').attr('fill', 'none'); + var linePaths = line_grps + .select('path') + .attr('class', 'wc-data-mark') + .style('clip-path', 'url(#' + chart.id + ')') + .datum(function(d) { + return d.values; + }) + .attr('stroke', function(d) { + return _this.colorScale(d[0].values.raw[0][config.color_by]); + }) + .attr( + 'stroke-width', + config.stroke_width ? config.stroke_width : config.flex_stroke_width + ) + .attr('stroke-linecap', 'round') + .attr('fill', 'none'); var linePathsTrans = config.transitions ? linePaths.transition() : linePaths; linePathsTrans.attr('d', line); - line_grps.each(function (d) { + line_grps.each(function(d) { var mark = d3.select(this.parentNode).datum(); d.tooltip = mark.tooltip; d3.select(this).select('path').attr(mark.attributes); }); - line_grps.select('title').text(function (d) { + line_grps.select('title').text(function(d) { var tt = d.tooltip || ''; - var xformat = config.x.summary === 'percent' ? d3.format('0%') : d3.format(config.x.format); - var yformat = config.y.summary === 'percent' ? d3.format('0%') : d3.format(config.y.format); - return tt.replace(/\$x/g, xformat(d.values.x)).replace(/\$y/g, yformat(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { - return d.values[0].values.raw[0][orig]; - }); + var xformat = config.x.summary === 'percent' + ? d3.format('0%') + : d3.format(config.x.format); + var yformat = config.y.summary === 'percent' + ? d3.format('0%') + : d3.format(config.y.format); + return tt + .replace(/\$x/g, xformat(d.values.x)) + .replace(/\$y/g, yformat(d.values.y)) + .replace(/\[(.+?)\]/g, function(str, orig) { + return d.values[0].values.raw[0][orig]; + }); }); //Link to the d3.selection from the data - line_supergroups.each(function (d) { + line_supergroups.each(function(d) { d.supergroup = d3.select(this); d.groups = d.supergroup.selectAll('g.line'); d.paths = d.groups.select('path'); @@ -1683,69 +2464,104 @@ var chart = this; var config = this.config; - var point_supergroups = this.svg.selectAll('.point-supergroup').data(marks, function (d, i) { + var point_supergroups = this.svg.selectAll('.point-supergroup').data(marks, function(d, i) { return i + '-' + d.per.join('-'); }); - point_supergroups.enter().append('g').attr('class', function (d) { + point_supergroups.enter().append('g').attr('class', function(d) { return 'supergroup point-supergroup ' + d.id; }); point_supergroups.exit().remove(); - var points = point_supergroups.selectAll('.point').data(function (d) { - return d.data; - }, function (d) { - return d.key; - }); + var points = point_supergroups.selectAll('.point').data( + function(d) { + return d.data; + }, + function(d) { + return d.key; + } + ); var oldPoints = points.exit(); - var oldPointsTrans = config.transitions ? oldPoints.selectAll('circle').transition() : oldPoints.selectAll('circle'); + var oldPointsTrans = config.transitions + ? oldPoints.selectAll('circle').transition() + : oldPoints.selectAll('circle'); oldPointsTrans.attr('r', 0); var oldPointGroupTrans = config.transitions ? oldPoints.transition() : oldPoints; oldPointGroupTrans.remove(); - var nupoints = points.enter().append('g').attr('class', function (d) { + var nupoints = points.enter().append('g').attr('class', function(d) { return d.key + ' point'; }); nupoints.append('circle').attr('class', 'wc-data-mark').attr('r', 0); nupoints.append('title'); //static attributes - points.select('circle').style('clip-path', 'url(#' + chart.id + ')').attr('fill-opacity', config.fill_opacity || config.fill_opacity === 0 ? config.fill_opacity : 0.6).attr('fill', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }).attr('stroke', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); + points + .select('circle') + .style('clip-path', 'url(#' + chart.id + ')') + .attr( + 'fill-opacity', + config.fill_opacity || config.fill_opacity === 0 ? config.fill_opacity : 0.6 + ) + .attr('fill', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }) + .attr('stroke', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); //attach mark info - points.each(function (d) { + points.each(function(d) { var mark = d3.select(this.parentNode).datum(); d.mark = mark; d3.select(this).select('circle').attr(mark.attributes); }); //animated attributes - var pointsTrans = config.transitions ? points.select('circle').transition() : points.select('circle'); - pointsTrans.attr('r', function (d) { - return d.mark.radius || config.flex_point_size; - }).attr('cx', function (d) { - var x_pos = _this.x(d.values.x) || 0; - return config.x.type === 'ordinal' ? x_pos + _this.x.rangeBand() / 2 : x_pos; - }).attr('cy', function (d) { - var y_pos = _this.y(d.values.y) || 0; - return config.y.type === 'ordinal' ? y_pos + _this.y.rangeBand() / 2 : y_pos; - }); + var pointsTrans = config.transitions + ? points.select('circle').transition() + : points.select('circle'); + pointsTrans + .attr('r', function(d) { + return d.mark.radius || config.flex_point_size; + }) + .attr('cx', function(d) { + var x_pos = _this.x(d.values.x) || 0; + return config.x.type === 'ordinal' ? x_pos + _this.x.rangeBand() / 2 : x_pos; + }) + .attr('cy', function(d) { + var y_pos = _this.y(d.values.y) || 0; + return config.y.type === 'ordinal' ? y_pos + _this.y.rangeBand() / 2 : y_pos; + }); - points.select('title').text(function (d) { + points.select('title').text(function(d) { var tt = d.mark.tooltip || ''; - var xformat = config.x.summary === 'percent' ? d3.format('0%') : config.x.type === 'time' ? d3.time.format(config.x.format) : d3.format(config.x.format); - var yformat = config.y.summary === 'percent' ? d3.format('0%') : config.y.type === 'time' ? d3.time.format(config.y.format) : d3.format(config.y.format); - return tt.replace(/\$x/g, config.x.type === 'time' ? xformat(new Date(d.values.x)) : xformat(d.values.x)).replace(/\$y/g, config.y.type === 'time' ? yformat(new Date(d.values.y)) : yformat(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { - return d.values.raw[0][orig]; - }); + var xformat = config.x.summary === 'percent' + ? d3.format('0%') + : config.x.type === 'time' + ? d3.time.format(config.x.format) + : d3.format(config.x.format); + var yformat = config.y.summary === 'percent' + ? d3.format('0%') + : config.y.type === 'time' + ? d3.time.format(config.y.format) + : d3.format(config.y.format); + return tt + .replace( + /\$x/g, + config.x.type === 'time' ? xformat(new Date(d.values.x)) : xformat(d.values.x) + ) + .replace( + /\$y/g, + config.y.type === 'time' ? yformat(new Date(d.values.y)) : yformat(d.values.y) + ) + .replace(/\[(.+?)\]/g, function(str, orig) { + return d.values.raw[0][orig]; + }); }); //Link to the d3.selection from the data - point_supergroups.each(function (d) { + point_supergroups.each(function(d) { d.supergroup = d3.select(this); d.groups = d.supergroup.selectAll('g.point'); d.circles = d.groups.select('circle'); @@ -1760,21 +2576,24 @@ var chart = this; var config = this.config; - var textSupergroups = this.svg.selectAll('.text-supergroup').data(marks, function (d, i) { + var textSupergroups = this.svg.selectAll('.text-supergroup').data(marks, function(d, i) { return i + '-' + d.per.join('-'); }); - textSupergroups.enter().append('g').attr('class', function (d) { + textSupergroups.enter().append('g').attr('class', function(d) { return 'supergroup text-supergroup ' + d.id; }); textSupergroups.exit().remove(); - var texts = textSupergroups.selectAll('.text').data(function (d) { - return d.data; - }, function (d) { - return d.key; - }); + var texts = textSupergroups.selectAll('.text').data( + function(d) { + return d.data; + }, + function(d) { + return d.key; + } + ); var oldTexts = texts.exit(); // don't need to transition position of outgoing text @@ -1783,7 +2602,7 @@ var oldTextGroupTrans = config.transitions ? oldTexts.transition() : oldTexts; oldTextGroupTrans.remove(); - var nutexts = texts.enter().append('g').attr('class', function (d) { + var nutexts = texts.enter().append('g').attr('class', function(d) { return d.key + ' text'; }); nutexts.append('text').attr('class', 'wc-data-mark'); @@ -1797,25 +2616,46 @@ texts.each(attachMarks); // parse text like tooltips - texts.select('text').style('clip-path', 'url(#' + chart.id + ')').text(function (d) { + texts.select('text').style('clip-path', 'url(#' + chart.id + ')').text(function(d) { var tt = d.mark.text || ''; - var xformat = config.x.summary === 'percent' ? d3.format('0%') : config.x.type === 'time' ? d3.time.format(config.x.format) : d3.format(config.x.format); - var yformat = config.y.summary === 'percent' ? d3.format('0%') : config.y.type === 'time' ? d3.time.format(config.y.format) : d3.format(config.y.format); - return tt.replace(/\$x/g, config.x.type === 'time' ? xformat(new Date(d.values.x)) : xformat(d.values.x)).replace(/\$y/g, config.y.type === 'time' ? yformat(new Date(d.values.y)) : yformat(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { - return d.values.raw[0][orig]; - }); + var xformat = config.x.summary === 'percent' + ? d3.format('0%') + : config.x.type === 'time' + ? d3.time.format(config.x.format) + : d3.format(config.x.format); + var yformat = config.y.summary === 'percent' + ? d3.format('0%') + : config.y.type === 'time' + ? d3.time.format(config.y.format) + : d3.format(config.y.format); + return tt + .replace( + /\$x/g, + config.x.type === 'time' ? xformat(new Date(d.values.x)) : xformat(d.values.x) + ) + .replace( + /\$y/g, + config.y.type === 'time' ? yformat(new Date(d.values.y)) : yformat(d.values.y) + ) + .replace(/\[(.+?)\]/g, function(str, orig) { + return d.values.raw[0][orig]; + }); }); // animated attributes - var textsTrans = config.transitions ? texts.select('text').transition() : texts.select('text'); - textsTrans.attr('x', function (d) { - var xPos = _this.x(d.values.x) || 0; - return config.x.type === 'ordinal' ? xPos + _this.x.rangeBand() / 2 : xPos; - }).attr('y', function (d) { - var yPos = _this.y(d.values.y) || 0; - return config.y.type === 'ordinal' ? yPos + _this.y.rangeBand() / 2 : yPos; - }); + var textsTrans = config.transitions + ? texts.select('text').transition() + : texts.select('text'); + textsTrans + .attr('x', function(d) { + var xPos = _this.x(d.values.x) || 0; + return config.x.type === 'ordinal' ? xPos + _this.x.rangeBand() / 2 : xPos; + }) + .attr('y', function(d) { + var yPos = _this.y(d.values.y) || 0; + return config.y.type === 'ordinal' ? yPos + _this.y.rangeBand() / 2 : yPos; + }); //add a reference to the selection from it's data - textSupergroups.each(function (d) { + textSupergroups.each(function(d) { d.supergroup = d3.select(this); d.groups = d.supergroup.selectAll('g.text'); d.texts = d.groups.select('text'); @@ -1824,7 +2664,9 @@ } function destroy() { - var destroyControls = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + var destroyControls = arguments.length > 0 && arguments[0] !== undefined + ? arguments[0] + : true; //run onDestroy callback this.events.onDestroy.call(this); @@ -1905,8 +2747,16 @@ onDestroy: function onDestroy() {} }; - thisChart.on = function (event, callback) { - var possible_events = ['init', 'layout', 'preprocess', 'datatransform', 'draw', 'resize', 'destroy']; + thisChart.on = function(event, callback) { + var possible_events = [ + 'init', + 'layout', + 'preprocess', + 'datatransform', + 'draw', + 'resize', + 'destroy' + ]; if (possible_events.indexOf(event) < 0) { return; } @@ -1926,9 +2776,9 @@ function changeOption(option, value, callback, draw) { var _this = this; - this.targets.forEach(function (target) { + this.targets.forEach(function(target) { if (option instanceof Array) { - option.forEach(function (o) { + option.forEach(function(o) { return _this.stringAccessor(target.config, o, value); }); } else { @@ -1947,8 +2797,13 @@ var colNames = d3.keys(dataset[0]); - this.config.inputs.forEach(function (input, i) { - if (input.type === 'subsetter' && colNames.indexOf(input.value_col) === -1) throw new Error('Error in settings object: the value "' + input.value_col + '" does not match any column in the provided dataset.'); + this.config.inputs.forEach(function(input, i) { + if (input.type === 'subsetter' && colNames.indexOf(input.value_col) === -1) + throw new Error( + 'Error in settings object: the value "' + + input.value_col + + '" does not match any column in the provided dataset.' + ); //Draw the chart when a control changes unless the user specifies otherwise. input.draw = input.draw === undefined ? true : input.draw; @@ -1958,9 +2813,10 @@ function controlUpdate() { var _this = this; - if (this.config.inputs && this.config.inputs.length && this.config.inputs[0]) this.config.inputs.forEach(function (input) { - return _this.makeControlItem(input); - }); + if (this.config.inputs && this.config.inputs.length && this.config.inputs[0]) + this.config.inputs.forEach(function(input) { + return _this.makeControlItem(input); + }); } function destroy$1() { @@ -1981,13 +2837,21 @@ } function makeControlItem(control) { - var control_wrap = this.wrap.append('div').attr('class', 'control-group').classed('inline', control.inline).datum(control); + var control_wrap = this.wrap + .append('div') + .attr('class', 'control-group') + .classed('inline', control.inline) + .datum(control); //Add control label span. - var ctrl_label = control_wrap.append('span').attr('class', 'wc-control-label').text(control.label); + var ctrl_label = control_wrap + .append('span') + .attr('class', 'wc-control-label') + .text(control.label); //Add control _Required_ text to control label span. - if (control.required) ctrl_label.append('span').attr('class', 'label label-required').text('Required'); + if (control.required) + ctrl_label.append('span').attr('class', 'label label-required').text('Required'); //Add control description span. control_wrap.append('span').attr('class', 'span-description').text(control.description); @@ -2009,7 +2873,9 @@ } else if (control.type === 'subsetter') { this.makeSubsetterControl(control, control_wrap); } else { - throw new Error('Each control must have a type! Choose from: "text", "number", "list", "dropdown", "btngroup", "checkbox", "radio", or "subsetter".'); + throw new Error( + 'Each control must have a type! Choose from: "text", "number", "list", "dropdown", "btngroup", "checkbox", "radio", or "subsetter".' + ); } } @@ -2020,14 +2886,21 @@ var btn_wrap = control_wrap.append('div').attr('class', 'btn-group'); - var changers = btn_wrap.selectAll('button').data(option_data).enter().append('button').attr('class', 'btn btn-default btn-sm').text(function (d) { - return d; - }).classed('btn-primary', function (d) { - return _this.stringAccessor(_this.targets[0].config, control.option) === d; - }); + var changers = btn_wrap + .selectAll('button') + .data(option_data) + .enter() + .append('button') + .attr('class', 'btn btn-default btn-sm') + .text(function(d) { + return d; + }) + .classed('btn-primary', function(d) { + return _this.stringAccessor(_this.targets[0].config, control.option) === d; + }); - changers.on('click', function (d) { - changers.each(function (e) { + changers.on('click', function(d) { + changers.each(function(e) { d3.select(this).classed('btn-primary', e === d); }); _this.changeOption(control.option, d, control.callback, control.draw); @@ -2037,11 +2910,16 @@ function makeCheckboxControl(control, control_wrap) { var _this = this; - var changer = control_wrap.append('input').attr('type', 'checkbox').attr('class', 'changer').datum(control).property('checked', function (d) { - return _this.stringAccessor(_this.targets[0].config, control.option); - }); + var changer = control_wrap + .append('input') + .attr('type', 'checkbox') + .attr('class', 'changer') + .datum(control) + .property('checked', function(d) { + return _this.stringAccessor(_this.targets[0].config, control.option); + }); - changer.on('change', function (d) { + changer.on('change', function(d) { var value = changer.property('checked'); _this.changeOption(d.option, value, control.callback, control.draw); }); @@ -2051,33 +2929,54 @@ var _this = this; var mainOption = control.option || control.options[0]; - var changer = control_wrap.append('select').attr('class', 'changer').attr('multiple', control.multiple ? true : null).datum(control); - - var opt_values = control.values && control.values instanceof Array ? control.values : control.values ? d3.set(this.data.map(function (m) { - return m[_this.targets[0].config[control.values]]; - })).values() : d3.keys(this.data[0]); + var changer = control_wrap + .append('select') + .attr('class', 'changer') + .attr('multiple', control.multiple ? true : null) + .datum(control); + + var opt_values = control.values && control.values instanceof Array + ? control.values + : control.values + ? d3 + .set( + this.data.map(function(m) { + return m[_this.targets[0].config[control.values]]; + }) + ) + .values() + : d3.keys(this.data[0]); if (!control.require || control.none) { opt_values.unshift('None'); } - var options = changer.selectAll('option').data(opt_values).enter().append('option').text(function (d) { - return d; - }).property('selected', function (d) { - return _this.stringAccessor(_this.targets[0].config, mainOption) === d; - }); + var options = changer + .selectAll('option') + .data(opt_values) + .enter() + .append('option') + .text(function(d) { + return d; + }) + .property('selected', function(d) { + return _this.stringAccessor(_this.targets[0].config, mainOption) === d; + }); - changer.on('change', function (d) { + changer.on('change', function(d) { var value = changer.property('value') === 'None' ? null : changer.property('value'); if (control.multiple) { - value = options.filter(function (f) { - return d3.select(this).property('selected'); - })[0].map(function (m) { - return d3.select(m).property('value'); - }).filter(function (f) { - return f !== 'None'; - }); + value = options + .filter(function(f) { + return d3.select(this).property('selected'); + })[0] + .map(function(m) { + return d3.select(m).property('value'); + }) + .filter(function(f) { + return f !== 'None'; + }); } if (control.options) { @@ -2093,14 +2992,21 @@ function makeListControl(control, control_wrap) { var _this = this; - var changer = control_wrap.append('input').attr('type', 'text').attr('class', 'changer').datum(control).property('value', function (d) { - return _this.stringAccessor(_this.targets[0].config, control.option); - }); + var changer = control_wrap + .append('input') + .attr('type', 'text') + .attr('class', 'changer') + .datum(control) + .property('value', function(d) { + return _this.stringAccessor(_this.targets[0].config, control.option); + }); - changer.on('change', function (d) { - var value = changer.property('value') ? changer.property('value').split(',').map(function (m) { - return m.trim(); - }) : null; + changer.on('change', function(d) { + var value = changer.property('value') + ? changer.property('value').split(',').map(function(m) { + return m.trim(); + }) + : null; _this.changeOption(control.option, value, control.callback, control.draw); }); } @@ -2108,11 +3014,19 @@ function makeNumberControl(control, control_wrap) { var _this = this; - var changer = control_wrap.append('input').attr('type', 'number').attr('min', control.min !== undefined ? control.min : 0).attr('max', control.max).attr('step', control.step || 1).attr('class', 'changer').datum(control).property('value', function (d) { - return _this.stringAccessor(_this.targets[0].config, control.option); - }); + var changer = control_wrap + .append('input') + .attr('type', 'number') + .attr('min', control.min !== undefined ? control.min : 0) + .attr('max', control.max) + .attr('step', control.step || 1) + .attr('class', 'changer') + .datum(control) + .property('value', function(d) { + return _this.stringAccessor(_this.targets[0].config, control.option); + }); - changer.on('change', function (d) { + changer.on('change', function(d) { var value = +changer.property('value'); _this.changeOption(control.option, value, control.callback, control.draw); }); @@ -2121,17 +3035,29 @@ function makeRadioControl(control, control_wrap) { var _this = this; - var changers = control_wrap.selectAll('label').data(control.values || d3.keys(this.data[0])).enter().append('label').attr('class', 'radio').text(function (d, i) { - return control.relabels ? control.relabels[i] : d; - }).append('input').attr('type', 'radio').attr('class', 'changer').attr('name', control.option.replace('.', '-') + '-' + this.targets[0].id).property('value', function (d) { - return d; - }).property('checked', function (d) { - return _this.stringAccessor(_this.targets[0].config, control.option) === d; - }); + var changers = control_wrap + .selectAll('label') + .data(control.values || d3.keys(this.data[0])) + .enter() + .append('label') + .attr('class', 'radio') + .text(function(d, i) { + return control.relabels ? control.relabels[i] : d; + }) + .append('input') + .attr('type', 'radio') + .attr('class', 'changer') + .attr('name', control.option.replace('.', '-') + '-' + this.targets[0].id) + .property('value', function(d) { + return d; + }) + .property('checked', function(d) { + return _this.stringAccessor(_this.targets[0].config, control.option) === d; + }); - changers.on('change', function (d) { + changers.on('change', function(d) { var value = null; - changers.each(function (c) { + changers.each(function(c) { if (d3.select(this).property('checked')) { value = d3.select(this).property('value') === 'none' ? null : c; } @@ -2144,14 +3070,27 @@ var targets = this.targets; // associated charts and tables. //dropdown selection - var changer = control_wrap.append('select').classed('changer', true).attr('multiple', control.multiple ? true : null).datum(control); + var changer = control_wrap + .append('select') + .classed('changer', true) + .attr('multiple', control.multiple ? true : null) + .datum(control); //dropdown option data - var option_data = control.values ? control.values : d3.set(this.data.map(function (m) { - return m[control.value_col]; - }).filter(function (f) { - return f; - })).values().sort(naturalSorter); // only sort when values are derived + var option_data = control.values + ? control.values + : d3 + .set( + this.data + .map(function(m) { + return m[control.value_col]; + }) + .filter(function(f) { + return f; + }) + ) + .values() + .sort(naturalSorter); // only sort when values are derived //initial dropdown option control.start = control.start ? control.start : control.loose ? option_data[0] : null; @@ -2168,17 +3107,26 @@ control.loose = !control.loose && control.start ? true : control.loose; //dropdown options selection - var options = changer.selectAll('option').data(option_data).enter().append('option').text(function (d) { - return d; - }).property('selected', function (d) { - return d === control.start; - }); + var options = changer + .selectAll('option') + .data(option_data) + .enter() + .append('option') + .text(function(d) { + return d; + }) + .property('selected', function(d) { + return d === control.start; + }); //define filter object for each associated target - targets.forEach(function (e) { - var match = e.filters.slice().map(function (m) { - return m.col === control.value_col; - }).indexOf(true); + targets.forEach(function(e) { + var match = e.filters + .slice() + .map(function(m) { + return m.col === control.value_col; + }) + .indexOf(true); if (match > -1) { e.filters[match] = { col: control.value_col, @@ -2202,7 +3150,7 @@ function setSubsetter(target, obj) { var match = -1; - target.filters.forEach(function (e, i) { + target.filters.forEach(function(e, i) { if (e.col === obj.col) { match = i; } @@ -2213,13 +3161,15 @@ } //add event listener to control - changer.on('change', function (d) { + changer.on('change', function(d) { if (control.multiple) { - var values = options.filter(function (f) { - return d3.select(this).property('selected'); - })[0].map(function (m) { - return d3.select(m).property('text'); - }); + var values = options + .filter(function(f) { + return d3.select(this).property('selected'); + })[0] + .map(function(m) { + return d3.select(m).property('text'); + }); var new_filter = { col: control.value_col, @@ -2229,7 +3179,7 @@ loose: control.loose, all: control.all }; - targets.forEach(function (e) { + targets.forEach(function(e) { setSubsetter(e, new_filter); //call callback function if provided if (control.callback) { @@ -2248,7 +3198,7 @@ loose: control.loose, all: control.all }; - targets.forEach(function (e) { + targets.forEach(function(e) { setSubsetter(e, _new_filter); //call callback function if provided if (control.callback) { @@ -2263,11 +3213,16 @@ function makeTextControl(control, control_wrap) { var _this = this; - var changer = control_wrap.append('input').attr('type', 'text').attr('class', 'changer').datum(control).property('value', function (d) { - return _this.stringAccessor(_this.targets[0].config, control.option); - }); + var changer = control_wrap + .append('input') + .attr('type', 'text') + .attr('class', 'changer') + .datum(control) + .property('value', function(d) { + return _this.stringAccessor(_this.targets[0].config, control.option); + }); - changer.on('change', function (d) { + changer.on('change', function(d) { var value = changer.property('value'); _this.changeOption(control.option, value, control.callback, control.draw); }); @@ -2325,7 +3280,10 @@ if (config.location === 'bottom') { thisControls.wrap = d3.select(element).append('div').attr('class', 'wc-controls'); } else { - thisControls.wrap = d3.select(element).insert('div', ':first-child').attr('class', 'wc-controls'); + thisControls.wrap = d3 + .select(element) + .insert('div', ':first-child') + .attr('class', 'wc-controls'); } thisControls.wrap.datum(thisControls); @@ -2338,17 +3296,32 @@ //If there are filters, return a filtered data array of the raw data. //Otherwise return the raw data. - if (this.filters && this.filters.some(function (filter) { - return typeof filter.val === 'string' && !(filter.all === true && filter.index === 0) || Array.isArray(filter.val) && filter.val.length < filter.choices.length; - })) { + if ( + this.filters && + this.filters.some(function(filter) { + return ( + (typeof filter.val === 'string' && + !(filter.all === true && filter.index === 0)) || + (Array.isArray(filter.val) && filter.val.length < filter.choices.length) + ); + }) + ) { this.data.filtered = this.data.raw; - this.filters.filter(function (filter) { - return typeof filter.val === 'string' && !(filter.all === true && filter.index === 0) || Array.isArray(filter.val) && filter.val.length < filter.choices.length; - }).forEach(function (filter) { - _this.data.filtered = _this.data.filtered.filter(function (d) { - return Array.isArray(filter.val) ? filter.val.indexOf(d[filter.col]) > -1 : filter.val === d[filter.col]; + this.filters + .filter(function(filter) { + return ( + (typeof filter.val === 'string' && + !(filter.all === true && filter.index === 0)) || + (Array.isArray(filter.val) && filter.val.length < filter.choices.length) + ); + }) + .forEach(function(filter) { + _this.data.filtered = _this.data.filtered.filter(function(d) { + return Array.isArray(filter.val) + ? filter.val.indexOf(d[filter.col]) > -1 + : filter.val === d[filter.col]; + }); }); - }); } else this.data.filtered = this.data.raw; } @@ -2365,17 +3338,20 @@ if (this.searchable.searchTerm) { //Determine which rows contain input text. - this.data.searched = this.data.filtered.filter(function (d) { + this.data.searched = this.data.filtered.filter(function(d) { var match = false; - Object.keys(d).filter(function (key) { - return _this.config.cols.indexOf(key) > -1; - }).forEach(function (var_name) { - if (match === false) { - var cellText = '' + d[var_name]; - match = cellText.toLowerCase().indexOf(_this.searchable.searchTerm) > -1; - } - }); + Object.keys(d) + .filter(function(key) { + return _this.config.cols.indexOf(key) > -1; + }) + .forEach(function(var_name) { + if (match === false) { + var cellText = '' + d[var_name]; + match = + cellText.toLowerCase().indexOf(_this.searchable.searchTerm) > -1; + } + }); return match; }); @@ -2392,9 +3368,12 @@ \------------------------------------------------------------------------------------------------*/ // Warn if overriding existing method - if (Array.prototype.equals) console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code."); + if (Array.prototype.equals) + console.warn( + "Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code." + ); // attach the .equals method to Array's prototype to call it on any array - Array.prototype.equals = function (array) { + Array.prototype.equals = function(array) { // if the other array is a falsy value, return if (!array) return false; @@ -2418,7 +3397,7 @@ function checkFilters() { if (this.filters) { - this.currentFilters = this.filters.map(function (filter) { + this.currentFilters = this.filters.map(function(filter) { return filter.val; }); @@ -2436,19 +3415,24 @@ function updateTableHeaders() { var _this = this; - this.thead_cells = this.thead.select('tr').selectAll('th').data(this.config.headers, function (d) { - return d; - }); + this.thead_cells = this.thead + .select('tr') + .selectAll('th') + .data(this.config.headers, function(d) { + return d; + }); this.thead_cells.exit().remove(); this.thead_cells.enter().append('th'); - this.thead_cells.sort(function (a, b) { - return _this.config.headers.indexOf(a) - _this.config.headers.indexOf(b); - }).attr('class', function (d) { - return _this.config.cols[_this.config.headers.indexOf(d)]; - }) // associate column header with column name - .text(function (d) { - return d; - }); + this.thead_cells + .sort(function(a, b) { + return _this.config.headers.indexOf(a) - _this.config.headers.indexOf(b); + }) + .attr('class', function(d) { + return _this.config.cols[_this.config.headers.indexOf(d)]; + }) // associate column header with column name + .text(function(d) { + return d; + }); } function drawTableBody() { @@ -2460,51 +3444,77 @@ var rows = this.tbody.selectAll('tr').data(this.data.processing).enter().append('tr'); //Define table body cells. - var cells = rows.selectAll('td').data(function (d) { - return _this.config.cols.map(function (key) { + var cells = rows.selectAll('td').data(function(d) { + return _this.config.cols.map(function(key) { return { col: key, text: d[key] }; }); }); cells.exit().remove(); cells.enter().append('td'); - cells.sort(function (a, b) { - return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); - }).attr('class', function (d) { - return d.col; - }).each(function (d) { - var cell = d3.select(this); - - //Apply text in data as html or as plain text. - if (table.config.as_html) { - cell.html(d.text); - } else { - cell.text(d.text); - } - }); + cells + .sort(function(a, b) { + return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); + }) + .attr('class', function(d) { + return d.col; + }) + .each(function(d) { + var cell = d3.select(this); + + //Apply text in data as html or as plain text. + if (table.config.as_html) { + cell.html(d.text); + } else { + cell.text(d.text); + } + }); } function dynamicLayout() { var widths = { table: this.table.select('thead').node().offsetWidth, - top: this.wrap.select('.table-top .searchable-container').node().offsetWidth + this.wrap.select('.table-top .sortable-container').node().offsetWidth, - bottom: this.wrap.select('.table-bottom .pagination-container').node().offsetWidth + this.wrap.select('.table-bottom .exportable-container').node().offsetWidth + top: + this.wrap.select('.table-top .searchable-container').node().offsetWidth + + this.wrap.select('.table-top .sortable-container').node().offsetWidth, + bottom: + this.wrap.select('.table-bottom .pagination-container').node().offsetWidth + + this.wrap.select('.table-bottom .exportable-container').node().offsetWidth }; - if (widths.table < Math.max(widths.top, widths.bottom) && this.config.layout === 'horizontal') { + if ( + widths.table < Math.max(widths.top, widths.bottom) && + this.config.layout === 'horizontal' + ) { this.config.layout = 'vertical'; - this.wrap.style('display', 'inline-block').selectAll('.table-top,.table-bottom').style('display', 'inline-block').selectAll('.interactivity').style({ - display: 'block', - clear: 'both' - }); - } else if (widths.table >= Math.max(widths.top, widths.bottom) && this.config.layout === 'vertical') { + this.wrap + .style('display', 'inline-block') + .selectAll('.table-top,.table-bottom') + .style('display', 'inline-block') + .selectAll('.interactivity') + .style({ + display: 'block', + clear: 'both' + }); + } else if ( + widths.table >= Math.max(widths.top, widths.bottom) && + this.config.layout === 'vertical' + ) { this.config.layout = 'horizontal'; - this.wrap.style('display', 'table').selectAll('.table-top,.table-bottom').style('display', 'block').selectAll('.interactivity').style({ - display: 'inline-block', - float: function float() { - return d3.select(this).classed('searchable-container') || d3.select(this).classed('pagination-container') ? 'right' : null; - }, - clear: null - }); + this.wrap + .style('display', 'table') + .selectAll('.table-top,.table-bottom') + .style('display', 'block') + .selectAll('.interactivity') + .style({ + display: 'inline-block', + float: function float() { + return d3.select(this).classed('searchable-container') || + d3.select(this).classed('pagination-container') + ? 'right' + : null; + }, + clear: null + }); } } @@ -2519,7 +3529,8 @@ if (!passed_data) //Apply filters if data is not passed to table.draw(). - applyFilters.call(this);else + applyFilters.call(this); + else //Otherwise update data object. updateDataObject.call(this); @@ -2529,7 +3540,16 @@ //Filter data on search term if it exists and set data to searched data. applySearchTerm.call(this); - this.searchable.wrap.select('.nNrecords').text(this.data.processing.length === this.data.raw.length ? this.data.raw.length + ' records displayed' : this.data.processing.length + '/' + this.data.raw.length + ' records displayed'); + this.searchable.wrap + .select('.nNrecords') + .text( + this.data.processing.length === this.data.raw.length + ? this.data.raw.length + ' records displayed' + : this.data.processing.length + + '/' + + this.data.raw.length + + ' records displayed' + ); //Update table headers. updateTableHeaders.call(this); @@ -2539,27 +3559,35 @@ //Print a note that no data was selected for empty tables. if (this.data.processing.length === 0) { - this.tbody.append('tr').classed('no-data', true).append('td').attr('colspan', this.config.cols.length).text('No data selected.'); + this.tbody + .append('tr') + .classed('no-data', true) + .append('td') + .attr('colspan', this.config.cols.length) + .text('No data selected.'); //Bind table filtered/searched data to table container. this.data.current = this.data.processing; this.table.datum(this.table.current); //Add export. - if (this.config.exportable) this.config.exports.forEach(function (fmt) { - _this.exportable.exports[fmt].call(_this, _this.data.processing); - }); + if (this.config.exportable) + this.config.exports.forEach(function(fmt) { + _this.exportable.exports[fmt].call(_this, _this.data.processing); + }); //Add pagination. - if (this.config.pagination) this.pagination.addPagination.call(this, this.data.processing); + if (this.config.pagination) + this.pagination.addPagination.call(this, this.data.processing); } else { //Sort data. if (this.config.sortable) { - this.thead.selectAll('th').on('click', function (header) { + this.thead.selectAll('th').on('click', function(header) { table.sortable.onClick.call(table, this, header); }); - if (this.sortable.order.length) this.sortable.sortData.call(this, this.data.processing); + if (this.sortable.order.length) + this.sortable.sortData.call(this, this.data.processing); } //Bind table filtered/searched data to table container. @@ -2567,16 +3595,17 @@ this.table.datum(this.data.current); //Add export. - if (this.config.exportable) this.config.exports.forEach(function (fmt) { - _this.exportable.exports[fmt].call(_this, _this.data.processing); - }); + if (this.config.exportable) + this.config.exports.forEach(function(fmt) { + _this.exportable.exports[fmt].call(_this, _this.data.processing); + }); //Add pagination. if (this.config.pagination) { this.pagination.addPagination.call(this, this.data.processing); //Apply pagination. - this.data.processing = this.data.processing.filter(function (d, i) { + this.data.processing = this.data.processing.filter(function(d, i) { return _this.config.startIndex <= i && i < _this.config.endIndex; }); } @@ -2596,15 +3625,24 @@ function layout$2() { var context = this; - this.searchable.wrap = this.wrap.select('.table-top').append('div').classed('interactivity searchable-container', true).classed('hidden', !this.config.searchable); + this.searchable.wrap = this.wrap + .select('.table-top') + .append('div') + .classed('interactivity searchable-container', true) + .classed('hidden', !this.config.searchable); this.searchable.wrap.append('div').classed('search', true); - this.searchable.wrap.select('.search').append('input').classed('search-box', true).attr('placeholder', 'Search').on('input', function () { - context.searchable.searchTerm = this.value.toLowerCase() || null; - context.config.activePage = 0; - context.config.startIndex = context.config.activePage * context.config.nRowsPerPage; // first row shown - context.config.endIndex = context.config.startIndex + context.config.nRowsPerPage; // last row shown - context.draw(); - }); + this.searchable.wrap + .select('.search') + .append('input') + .classed('search-box', true) + .attr('placeholder', 'Search') + .on('input', function() { + context.searchable.searchTerm = this.value.toLowerCase() || null; + context.config.activePage = 0; + context.config.startIndex = context.config.activePage * context.config.nRowsPerPage; // first row shown + context.config.endIndex = context.config.startIndex + context.config.nRowsPerPage; // last row shown + context.draw(); + }); this.searchable.wrap.select('.search').append('span').classed('nNrecords', true); } @@ -2617,32 +3655,55 @@ function layout$3() { var _this = this; - this.exportable.wrap = this.wrap.select('.table-bottom').append('div').classed('interactivity exportable-container', true).classed('hidden', !this.config.exportable); + this.exportable.wrap = this.wrap + .select('.table-bottom') + .append('div') + .classed('interactivity exportable-container', true) + .classed('hidden', !this.config.exportable); this.exportable.wrap.append('span').text('Export:'); - if (this.config.exports && this.config.exports.length) this.config.exports.forEach(function (fmt) { - _this.exportable.wrap.append('a').classed('wc-button export', true).attr({ - id: fmt - }).style(!_this.test && navigator.msSaveBlob ? { - cursor: 'pointer', - 'text-decoration': 'underline', - color: 'blue' - } : null).text(fmt.toUpperCase()); - }); + if (this.config.exports && this.config.exports.length) + this.config.exports.forEach(function(fmt) { + _this.exportable.wrap + .append('a') + .classed('wc-button export', true) + .attr({ + id: fmt + }) + .style( + !_this.test && navigator.msSaveBlob + ? { + cursor: 'pointer', + 'text-decoration': 'underline', + color: 'blue' + } + : null + ) + .text(fmt.toUpperCase()); + }); } function download(fileType, data) { //transform blob array into a blob of characters var blob = new Blob(data, { - type: fileType === 'csv' ? 'text/csv;charset=utf-8;' : fileType === 'xlsx' ? 'application/octet-stream' : console.warn('File type not supported: ' + fileType) + type: fileType === 'csv' + ? 'text/csv;charset=utf-8;' + : fileType === 'xlsx' + ? 'application/octet-stream' + : console.warn('File type not supported: ' + fileType) }); - var fileName = 'webchartsTableExport_' + d3.time.format('%Y-%m-%dT%H-%M-%S')(new Date()) + '.' + fileType; + var fileName = + 'webchartsTableExport_' + + d3.time.format('%Y-%m-%dT%H-%M-%S')(new Date()) + + '.' + + fileType; var link = this.wrap.select('.export#' + fileType); if (navigator.msSaveBlob) //IE - navigator.msSaveBlob(blob, fileName);else if (link.node().download !== undefined) { + navigator.msSaveBlob(blob, fileName); + else if (link.node().download !== undefined) { //21st century browsers var url = URL.createObjectURL(blob); link.node().setAttribute('href', url); @@ -2653,18 +3714,18 @@ function csv(data) { var _this = this; - this.wrap.select('.export#csv').on('click', function () { + this.wrap.select('.export#csv').on('click', function() { var CSVarray = []; //add headers to CSV array - var headers = _this.config.headers.map(function (header) { + var headers = _this.config.headers.map(function(header) { return '"' + header.replace(/"/g, '""') + '"'; }); CSVarray.push(headers); //add rows to CSV array - data.forEach(function (d, i) { - var row = _this.config.cols.map(function (col) { + data.forEach(function(d, i) { + var row = _this.config.cols.map(function(col) { var value = d[col]; if (typeof value === 'string') value = value.replace(/"/g, '""'); @@ -2683,19 +3744,21 @@ function xlsx(data) { var _this = this; - this.wrap.select('.export#xlsx').on('click', function () { + this.wrap.select('.export#xlsx').on('click', function() { var sheetName = 'Selected Data'; var options = { bookType: 'xlsx', bookSST: true, type: 'binary' }; - var arrayOfArrays = data.map(function (d) { - return Object.keys(d).filter(function (key) { - return _this.config.cols.indexOf(key) > -1; - }).map(function (key) { - return d[key]; - }); + var arrayOfArrays = data.map(function(d) { + return Object.keys(d) + .filter(function(key) { + return _this.config.cols.indexOf(key) > -1; + }) + .map(function(key) { + return d[key]; + }); }); // convert data from array of objects to array of arrays. var workbook = { SheetNames: [sheetName], @@ -2704,7 +3767,9 @@ var cols = []; //Convert headers and data from array of arrays to sheet. - workbook.Sheets[sheetName] = XLSX.utils.aoa_to_sheet([_this.config.headers].concat(arrayOfArrays)); + workbook.Sheets[sheetName] = XLSX.utils.aoa_to_sheet( + [_this.config.headers].concat(arrayOfArrays) + ); //Add filters to spreadsheet. workbook.Sheets[sheetName]['!autofilter'] = { @@ -2712,7 +3777,7 @@ }; //Define column widths in spreadsheet. - _this.table.selectAll('thead tr th').each(function () { + _this.table.selectAll('thead tr th').each(function() { cols.push({ wpx: this.offsetWidth }); }); workbook.Sheets[sheetName]['!cols'] = cols; @@ -2724,7 +3789,8 @@ for (var i = 0; i !== s.length; ++i) { view[i] = s.charCodeAt(i) & 0xff; - }return buffer; + } + return buffer; }; // convert spreadsheet to binary or something, i don't know //Download .xlsx file. @@ -2745,10 +3811,16 @@ } function layout$4() { - //Add sort container. - this.sortable.wrap = this.wrap.select('.table-top').append('div').classed('interactivity sortable-container', true).classed('hidden', !this.config.sortable); - this.sortable.wrap.append('div').classed('instruction', true).text('Click column headers to sort.'); + this.sortable.wrap = this.wrap + .select('.table-top') + .append('div') + .classed('interactivity sortable-container', true) + .classed('hidden', !this.config.sortable); + this.sortable.wrap + .append('div') + .classed('instruction', true) + .text('Click column headers to sort.'); } function onClick(th, header) { @@ -2757,7 +3829,7 @@ col = this.config.cols[this.config.headers.indexOf(header)]; //Check if column is already a part of current sort order. - var sortItem = this.sortable.order.filter(function (item) { + var sortItem = this.sortable.order.filter(function(item) { return item.col === col; })[0]; @@ -2766,7 +3838,11 @@ sortItem = { col: col, direction: 'ascending', - wrap: this.sortable.wrap.append('div').datum({ key: col }).classed('wc-button sort-box', true).text(header) + wrap: this.sortable.wrap + .append('div') + .datum({ key: col }) + .classed('wc-button sort-box', true) + .text(header) }; sortItem.wrap.append('span').classed('sort-direction', true).html('↓'); sortItem.wrap.append('span').classed('remove-sort', true).html('❌'); @@ -2774,25 +3850,34 @@ } else { //Otherwise reverse its sort direction. sortItem.direction = sortItem.direction === 'ascending' ? 'descending' : 'ascending'; - sortItem.wrap.select('span.sort-direction').html(sortItem.direction === 'ascending' ? '↓' : '↑'); + sortItem.wrap + .select('span.sort-direction') + .html(sortItem.direction === 'ascending' ? '↓' : '↑'); } //Hide sort instructions. this.sortable.wrap.select('.instruction').classed('hidden', true); //Add sort container deletion functionality. - this.sortable.order.forEach(function (item, i) { - item.wrap.on('click', function (d) { + this.sortable.order.forEach(function(item, i) { + item.wrap.on('click', function(d) { //Remove column's sort container. d3.select(this).remove(); //Remove column from sort. - context.sortable.order.splice(context.sortable.order.map(function (d) { - return d.col; - }).indexOf(d.key), 1); + context.sortable.order.splice( + context.sortable.order + .map(function(d) { + return d.col; + }) + .indexOf(d.key), + 1 + ); //Display sorting instruction. - context.sortable.wrap.select('.instruction').classed('hidden', context.sortable.order.length); + context.sortable.wrap + .select('.instruction') + .classed('hidden', context.sortable.order.length); //Redraw chart. context.draw(); @@ -2806,15 +3891,24 @@ function sortData(data) { var _this = this; - data = data.sort(function (a, b) { + data = data.sort(function(a, b) { var order = 0; - _this.sortable.order.forEach(function (item) { + _this.sortable.order.forEach(function(item) { var aCell = a[item.col], bCell = b[item.col]; if (order === 0) { - if (item.direction === 'ascending' && aCell < bCell || item.direction === 'descending' && aCell > bCell) order = -1;else if (item.direction === 'ascending' && aCell > bCell || item.direction === 'descending' && aCell < bCell) order = 1; + if ( + (item.direction === 'ascending' && aCell < bCell) || + (item.direction === 'descending' && aCell > bCell) + ) + order = -1; + else if ( + (item.direction === 'ascending' && aCell > bCell) || + (item.direction === 'descending' && aCell < bCell) + ) + order = 1; } }); @@ -2832,7 +3926,11 @@ } function layout$5() { - this.pagination.wrap = this.wrap.select('.table-bottom').append('div').classed('interactivity pagination-container', true).classed('hidden', !this.config.pagination); + this.pagination.wrap = this.wrap + .select('.table-bottom') + .append('div') + .classed('interactivity pagination-container', true) + .classed('hidden', !this.config.pagination); } function updatePagination() { @@ -2842,9 +3940,11 @@ this.pagination.links.classed('active', false); //Set to active the selected page link. - var activePage = this.pagination.links.filter(function (link) { - return +link.rel === +_this.config.activePage; - }).classed('active', true); + var activePage = this.pagination.links + .filter(function(link) { + return +link.rel === +_this.config.activePage; + }) + .classed('active', true); //Define and draw selected page. this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; @@ -2862,15 +3962,28 @@ this.pagination.wrap.selectAll('a,span').remove(); var _loop = function _loop(i) { - _this.pagination.wrap.append('a').datum({ rel: i }).attr({ - rel: i - }).text(i + 1).classed('wc-button page-link', true).classed('active', function (d) { - return d.rel == _this.config.activePage; - }).classed('hidden', function () { - return _this.config.activePage < _this.config.nPageLinksDisplayed ? i >= _this.config.nPageLinksDisplayed // first nPageLinksDisplayed pages - : _this.config.activePage >= _this.config.nPages - _this.config.nPageLinksDisplayed ? i < _this.config.nPages - _this.config.nPageLinksDisplayed // last nPageLinksDisplayed pages - : i < _this.config.activePage - (Math.ceil(_this.config.nPageLinksDisplayed / 2) - 1) || _this.config.activePage + _this.config.nPageLinksDisplayed / 2 < i; // nPageLinksDisplayed < activePage or activePage < (nPages - nPageLinksDisplayed) - }); + _this.pagination.wrap + .append('a') + .datum({ rel: i }) + .attr({ + rel: i + }) + .text(i + 1) + .classed('wc-button page-link', true) + .classed('active', function(d) { + return d.rel == _this.config.activePage; + }) + .classed('hidden', function() { + return _this.config.activePage < _this.config.nPageLinksDisplayed + ? i >= _this.config.nPageLinksDisplayed // first nPageLinksDisplayed pages + : _this.config.activePage >= + _this.config.nPages - _this.config.nPageLinksDisplayed + ? i < _this.config.nPages - _this.config.nPageLinksDisplayed // last nPageLinksDisplayed pages + : i < + _this.config.activePage - + (Math.ceil(_this.config.nPageLinksDisplayed / 2) - 1) || + _this.config.activePage + _this.config.nPageLinksDisplayed / 2 < i; // nPageLinksDisplayed < activePage or activePage < (nPages - nPageLinksDisplayed) + }); }; for (var i = 0; i < this.config.nPages; i++) { @@ -2890,28 +4003,69 @@ Left side \-------------------------------------------------------------------------------------------**/ - this.pagination.wrap.insert('span', ':first-child').classed('dot-dot-dot', true).text('...').classed('hidden', this.config.activePage < this.config.nPageLinksDisplayed); - - this.pagination.prev = this.pagination.wrap.insert('a', ':first-child').classed('wc-button arrow-link wc-left', true).classed('hidden', this.config.activePage == 0).attr({ - rel: prev - }).text('<'); - - this.pagination.doublePrev = this.pagination.wrap.insert('a', ':first-child').classed('wc-button arrow-link wc-left double', true).classed('hidden', this.config.activePage == 0).attr({ - rel: 0 - }).text('<<'); + this.pagination.wrap + .insert('span', ':first-child') + .classed('dot-dot-dot', true) + .text('...') + .classed('hidden', this.config.activePage < this.config.nPageLinksDisplayed); + + this.pagination.prev = this.pagination.wrap + .insert('a', ':first-child') + .classed('wc-button arrow-link wc-left', true) + .classed('hidden', this.config.activePage == 0) + .attr({ + rel: prev + }) + .text('<'); + + this.pagination.doublePrev = this.pagination.wrap + .insert('a', ':first-child') + .classed('wc-button arrow-link wc-left double', true) + .classed('hidden', this.config.activePage == 0) + .attr({ + rel: 0 + }) + .text('<<'); /**-------------------------------------------------------------------------------------------\ Right side \-------------------------------------------------------------------------------------------**/ - this.pagination.wrap.append('span').classed('dot-dot-dot', true).text('...').classed('hidden', this.config.activePage >= Math.max(this.config.nPageLinksDisplayed, this.config.nPages - this.config.nPageLinksDisplayed) || this.config.nPages <= this.config.nPageLinksDisplayed); - this.pagination.next = this.pagination.wrap.append('a').classed('wc-button arrow-link wc-right', true).classed('hidden', this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0).attr({ - rel: next - }).text('>'); - - this.pagination.doubleNext = this.pagination.wrap.append('a').classed('wc-button arrow-link wc-right double', true).classed('hidden', this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0).attr({ - rel: this.config.nPages - 1 - }).text('>>'); + this.pagination.wrap + .append('span') + .classed('dot-dot-dot', true) + .text('...') + .classed( + 'hidden', + this.config.activePage >= + Math.max( + this.config.nPageLinksDisplayed, + this.config.nPages - this.config.nPageLinksDisplayed + ) || this.config.nPages <= this.config.nPageLinksDisplayed + ); + this.pagination.next = this.pagination.wrap + .append('a') + .classed('wc-button arrow-link wc-right', true) + .classed( + 'hidden', + this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0 + ) + .attr({ + rel: next + }) + .text('>'); + + this.pagination.doubleNext = this.pagination.wrap + .append('a') + .classed('wc-button arrow-link wc-right double', true) + .classed( + 'hidden', + this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0 + ) + .attr({ + rel: this.config.nPages - 1 + }) + .text('>>'); this.pagination.arrows = this.pagination.wrap.selectAll('a.arrow-link'); this.pagination.doubleArrows = this.pagination.wrap.selectAll('a.double-arrow-link'); @@ -2932,7 +4086,7 @@ addLinks.call(this); //Render a different page on click. - this.pagination.links.on('click', function () { + this.pagination.links.on('click', function() { context.config.activePage = +d3.select(this).attr('rel'); updatePagination.call(context); }); @@ -2941,17 +4095,25 @@ addArrows.call(this); //Render a different page on click. - this.pagination.arrows.on('click', function () { + this.pagination.arrows.on('click', function() { if (context.config.activePage !== +d3.select(this).attr('rel')) { context.config.activePage = +d3.select(this).attr('rel'); - context.pagination.prev.attr('rel', context.config.activePage > 0 ? context.config.activePage - 1 : 0); - context.pagination.next.attr('rel', context.config.activePage < context.config.nPages ? context.config.activePage + 1 : context.config.nPages - 1); + context.pagination.prev.attr( + 'rel', + context.config.activePage > 0 ? context.config.activePage - 1 : 0 + ); + context.pagination.next.attr( + 'rel', + context.config.activePage < context.config.nPages + ? context.config.activePage + 1 + : context.config.nPages - 1 + ); updatePagination.call(context); } }); //Render a different page on click. - this.pagination.doubleArrows.on('click', function () { + this.pagination.doubleArrows.on('click', function() { context.config.activePage = +d3.select(this).attr('rel'); updatePagination.call(context); }); @@ -2984,9 +4146,17 @@ this.test = test; if (d3.select(this.div).select('.loader').empty()) { - d3.select(this.div).insert('div', ':first-child').attr('class', 'loader').selectAll('.blockG').data(d3.range(8)).enter().append('div').attr('class', function (d) { - return 'blockG rotate' + (d + 1); - }); + d3 + .select(this.div) + .insert('div', ':first-child') + .attr('class', 'loader') + .selectAll('.blockG') + .data(d3.range(8)) + .enter() + .append('div') + .attr('class', function(d) { + return 'blockG rotate' + (d + 1); + }); } //Define default settings. @@ -3026,8 +4196,10 @@ //make sure container is visible (has height and width) before trying to initialize var visible = d3.select(_this.div).property('offsetWidth') > 0 || test; if (!visible) { - console.warn('The table cannot be initialized inside an element with 0 width. The table will be initialized as soon as the container element is given a width > 0.'); - var onVisible = setInterval(function (i) { + console.warn( + 'The table cannot be initialized inside an element with 0 width. The table will be initialized as soon as the container element is given a width > 0.' + ); + var onVisible = setInterval(function(i) { var visible_now = d3.select(_this.div).property('offsetWidth') > 0; if (visible_now) { _this.layout(); @@ -3085,7 +4257,9 @@ } function destroy$2() { - var destroyControls = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + var destroyControls = arguments.length > 0 && arguments[0] !== undefined + ? arguments[0] + : false; //run onDestroy callback this.events.onDestroy.call(this); @@ -3102,14 +4276,20 @@ function setDefault(setting) { var _default_ = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - this.config[setting] = this.config[setting] !== undefined ? this.config[setting] : _default_; + this.config[setting] = this.config[setting] !== undefined + ? this.config[setting] + : _default_; } function setDefaults$1(firstItem) { //Set data-driven defaults. if (this.config.cols instanceof Array && this.config.headers instanceof Array) { if (this.config.cols.length === 0) delete this.config.cols; - if (this.config.headers.length === 0 || this.config.headers.length !== this.config.cols.length) delete this.config.headers; + if ( + this.config.headers.length === 0 || + this.config.headers.length !== this.config.cols.length + ) + delete this.config.headers; } this.config.cols = this.config.cols || d3.keys(firstItem); @@ -3142,7 +4322,7 @@ this.config.headers = this.config.headers || this.config.cols; if (this.config.keep) { - this.config.keep.forEach(function (e) { + this.config.keep.forEach(function(e) { if (_this.config.cols.indexOf(e) === -1) { _this.config.cols.unshift(e); } @@ -3152,9 +4332,9 @@ var filtered = data; if (this.filters.length) { - this.filters.forEach(function (e) { + this.filters.forEach(function(e) { var is_array = e.val instanceof Array; - filtered = filtered.filter(function (d) { + filtered = filtered.filter(function(d) { if (is_array) { return e.val.indexOf(d[e.col]) !== -1; } else { @@ -3164,30 +4344,36 @@ }); } - var slimmed = d3.nest().key(function (d) { - if (_this.config.row_per) { - return _this.config.row_per.map(function (m) { - return d[m]; - }).join(' '); - } else { - return d; - } - }).rollup(function (r) { - if (_this.config.dataManipulate) { - r = _this.config.dataManipulate(r); - } - var nuarr = r.map(function (m) { - var arr = []; - for (var x in m) { - arr.push({ col: x, text: m[x] }); + var slimmed = d3 + .nest() + .key(function(d) { + if (_this.config.row_per) { + return _this.config.row_per + .map(function(m) { + return d[m]; + }) + .join(' '); + } else { + return d; + } + }) + .rollup(function(r) { + if (_this.config.dataManipulate) { + r = _this.config.dataManipulate(r); } - arr.sort(function (a, b) { - return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); + var nuarr = r.map(function(m) { + var arr = []; + for (var x in m) { + arr.push({ col: x, text: m[x] }); + } + arr.sort(function(a, b) { + return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); + }); + return { cells: arr, raw: m }; }); - return { cells: arr, raw: m }; - }); - return nuarr; - }).entries(filtered); + return nuarr; + }) + .entries(filtered); this.data.current = slimmed.length ? slimmed : [{ key: null, values: [] }]; // dummy nested data array @@ -3202,8 +4388,8 @@ if (config.row_per) { var rev_order = config.row_per.slice(0).reverse(); - rev_order.forEach(function (e) { - tbodies.sort(function (a, b) { + rev_order.forEach(function(e) { + tbodies.sort(function(a, b) { return a.values[0].raw[e] - b.values[0].raw[e]; }); }); @@ -3211,11 +4397,15 @@ //Delete text from columns with repeated values? if (config.row_per) { - rows.filter(function (f, i) { - return i > 0; - }).selectAll('td').filter(function (f) { - return config.row_per.indexOf(f.col) > -1; - }).text(''); + rows + .filter(function(f, i) { + return i > 0; + }) + .selectAll('td') + .filter(function(f) { + return config.row_per.indexOf(f.col) > -1; + }) + .text(''); } return this.data.current; @@ -3257,7 +4447,7 @@ onDestroy: function onDestroy() {} }; - thisTable.on = function (event, callback) { + thisTable.on = function(event, callback) { var possible_events = ['init', 'layout', 'preprocess', 'draw', 'destroy']; if (possible_events.indexOf(event) < 0) { return; @@ -3283,17 +4473,22 @@ chart.multiples = []; function goAhead(data) { - var split_vals = d3.set(data.map(function (m) { - return m[split_by]; - })).values().filter(function (f) { - return f; - }); + var split_vals = d3 + .set( + data.map(function(m) { + return m[split_by]; + }) + ) + .values() + .filter(function(f) { + return f; + }); if (order) { - split_vals = split_vals.sort(function (a, b) { + split_vals = split_vals.sort(function(a, b) { return d3.ascending(order.indexOf(a), order.indexOf(b)); }); } - split_vals.forEach(function (e) { + split_vals.forEach(function(e) { var mchart = createChart(chart.wrap.node(), chart.config, chart.controls); chart.multiples.push(mchart); mchart.parent = chart; @@ -3309,10 +4504,14 @@ } function getValType(data, variable) { - var var_vals = d3.set(data.map(function (m) { - return m[variable]; - })).values(); - var vals_numbers = var_vals.filter(function (f) { + var var_vals = d3 + .set( + data.map(function(m) { + return m[variable]; + }) + ) + .values(); + var vals_numbers = var_vals.filter(function(f) { return +f || +f === 0; }); @@ -3326,8 +4525,8 @@ function lengthenRaw(data, columns) { var my_data = []; - data.forEach(function (e) { - columns.forEach(function (g) { + data.forEach(function(e) { + columns.forEach(function(g) { var obj = Object.create(e); obj.wc_category = g; obj.wc_value = e[g]; @@ -3355,5 +4554,4 @@ }; return index; - -})); +}); diff --git a/src/version.js b/src/version.js index e8fcfd9..80b28e7 100644 --- a/src/version.js +++ b/src/version.js @@ -1 +1 @@ -export default '1.11.5'; +export default '1.12.0'; From 1641fb9c35c89bc9d62ad39f031d58ea6788f38b Mon Sep 17 00:00:00 2001 From: samussiah Date: Mon, 13 May 2019 15:09:59 -0400 Subject: [PATCH 06/12] update version to patch release --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 271cea1..537bbfc 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "webcharts", "description": "A library for creating flexible, interactive charts", - "version": "1.12.0", + "version": "1.11.6", "keywords": [ "charts", "javascript", From f1f0bc40e5013b9d161c76731f7e1928253e6b7a Mon Sep 17 00:00:00 2001 From: samussiah Date: Mon, 13 May 2019 15:14:01 -0400 Subject: [PATCH 07/12] update version... again --- build/webcharts.js | 2 +- build/webcharts.min.js | 2 +- package-lock.json | 6 +++--- src/version.js | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/build/webcharts.js b/build/webcharts.js index 648ad26..b624c11 100644 --- a/build/webcharts.js +++ b/build/webcharts.js @@ -6,7 +6,7 @@ : (global.webCharts = factory(global.d3)); })(typeof self !== 'undefined' ? self : this, function(d3) { 'use strict'; - var version = '1.12.0'; + var version = '1.11.6'; function init(data) { var _this = this; diff --git a/build/webcharts.min.js b/build/webcharts.min.js index 20abde6..f58cbe0 100644 --- a/build/webcharts.min.js +++ b/build/webcharts.min.js @@ -1,3 +1,3 @@ -(function(global,factory){typeof exports==="object"&&typeof module!=="undefined"?module.exports=factory(require("d3")):typeof define==="function"&&define.amd?define(["d3"],factory):global.webCharts=factory(global.d3)})(typeof self!=="undefined"?self:this,function(d3){"use strict";var version="1.12.0";function init(data){var _this=this;var test=arguments.length>1&&arguments[1]!==undefined?arguments[1]:false;if(d3.select(this.div).select(".loader").empty()){d3.select(this.div).insert("div",":first-child").attr("class","loader").selectAll(".blockG").data(d3.range(8)).enter().append("div").attr("class",function(d){return"blockG rotate"+(d+1)})}this.wrap.attr("class","wc-chart");this.setDefaults();this.raw_data=data;this.initial_data=data;var startup=function startup(data){if(_this.controls){_this.controls.targets.push(_this);if(!_this.controls.ready){_this.controls.init(_this.raw_data)}else{_this.controls.layout()}}var visible=d3.select(_this.div).property("offsetWidth")>0||test;if(!visible){console.warn("The chart cannot be initialized inside an element with 0 width. The chart will be initialized as soon as the container element is given a width > 0.");var onVisible=setInterval(function(i){var visible_now=d3.select(_this.div).property("offsetWidth")>0;if(visible_now){_this.layout();_this.draw();clearInterval(onVisible)}},500)}else{_this.layout();_this.draw()}};this.events.onInit.call(this);if(this.raw_data.length){this.checkRequired(this.raw_data)}startup(data);return this}function checkRequired(data){var _this=this;var colnames=Object.keys(data[0]);var requiredVars=[];var requiredCols=[];if(this.config.x&&this.config.x.column){requiredVars.push("this.config.x.column");requiredCols.push(this.config.x.column)}if(this.config.y&&this.config.y.column){requiredVars.push("this.config.y.column");requiredCols.push(this.config.y.column)}if(this.config.color_by){requiredVars.push("this.config.color_by");requiredCols.push(this.config.color_by)}if(this.config.marks)this.config.marks.forEach(function(e,i){if(e.per&&e.per.length){e.per.forEach(function(p,j){requiredVars.push("this.config.marks["+i+"].per["+j+"]");requiredCols.push(p)})}if(e.split){requiredVars.push("this.config.marks["+i+"].split");requiredCols.push(e.split)}if(e.values){for(var value in e.values){requiredVars.push("this.config.marks["+i+"].values['"+value+"']");requiredCols.push(value)}}});var missingDataField=false;requiredCols.forEach(function(e,i){if(colnames.indexOf(e)<0){missingDataField=true;d3.select(_this.div).select(".loader").remove();_this.wrap.append("div").style("color","red").html('The value "'+e+'" for the '+requiredVars[i]+" setting does not match any column in the provided dataset.");throw new Error('Error in settings object: The value "'+e+'" for the '+requiredVars[i]+" setting does not match any column in the provided dataset.")}});return{missingDataField:missingDataField,dataFieldArguments:requiredVars,requiredDataFields:requiredCols}}function addSVG(){this.svg=this.wrap.append("svg").datum(function(){return null}).attr({class:"wc-svg",xmlns:"http://www.w3.org/2000/svg",version:"1.1",xlink:"http://www.w3.org/1999/xlink"}).append("g").style("display","inline-block")}function addDefs(){var defs=this.svg.append("defs");defs.append("pattern").attr({id:"diagonal-stripes",x:0,y:0,width:3,height:8,patternUnits:"userSpaceOnUse",patternTransform:"rotate(30)"}).append("rect").attr({x:"0",y:"0",width:"2",height:"8"}).style({stroke:"none",fill:"black"});defs.append("clipPath").attr("id",this.id).append("rect").attr("class","plotting-area")}function addXAxis(){this.svg.append("g").attr("class","x axis").append("text").attr("class","axis-title").attr("dy","-.35em").attr("text-anchor","middle")}function addYAxis(){this.svg.append("g").attr("class","y axis").append("text").attr("class","axis-title").attr("transform","rotate(-90)").attr("dy",".75em").attr("text-anchor","middle")}function addOverlay(){this.overlay=this.svg.append("rect").attr("class","overlay").attr("opacity",0).attr("fill","none").style("pointer-events","all")}function addLegend(){if(!this.parent)this.wrap.append("ul").datum(function(){return null}).attr("class","legend").style("vertical-align","top").append("span").attr("class","legend-title")}function clearLoader(){d3.select(this.div).select(".loader").remove()}function layout(){addSVG.call(this);addDefs.call(this);addXAxis.call(this);addYAxis.call(this);addOverlay.call(this);addLegend.call(this);clearLoader.call(this);this.events.onLayout.call(this)}function draw(raw_data,processed_data){var _this=this;var chart=this;var config=this.config;this.events.onPreprocess.call(this);var raw=raw_data?raw_data:this.raw_data?this.raw_data:[];if(processed_data){console.warn("Drawing the chart using user-defined 'processed_data', this is an experimental, untested feature.")}this.consolidateData(raw);var div_width=parseInt(this.wrap.style("width"));this.setColorScale();var max_width=config.max_width?config.max_width:div_width;this.raw_width=config.x.type==="ordinal"&&+config.x.range_band?(+config.x.range_band+config.x.range_band*config.padding)*this.x_dom.length:config.resizable?max_width:config.width?config.width:div_width;this.raw_height=config.y.type==="ordinal"&&+config.y.range_band?(+config.y.range_band+config.y.range_band*config.padding)*this.y_dom.length:config.resizable?max_width*(1/config.aspect):config.height?config.height:div_width*(1/config.aspect);var pseudo_width=this.svg.select(".overlay").attr("width")?this.svg.select(".overlay").attr("width"):this.raw_width;var pseudo_height=this.svg.select(".overlay").attr("height")?this.svg.select(".overlay").attr("height"):this.raw_height;this.svg.select(".x.axis").select(".axis-title").text(function(d){return typeof config.x.label==="string"?config.x.label:typeof config.x.label==="function"?config.x.label.call(_this):null});this.svg.select(".y.axis").select(".axis-title").text(function(d){return typeof config.y.label==="string"?config.y.label:typeof config.y.label==="function"?config.y.label.call(_this):null});this.xScaleAxis(pseudo_width);this.yScaleAxis(pseudo_height);if(config.resizable&&typeof window!=="undefined"){d3.select(window).on("resize."+this.element+this.id,function(){chart.resize()})}else if(typeof window!=="undefined"){d3.select(window).on("resize."+this.element+this.id,null)}this.events.onDraw.call(this);this.resize()}function naturalSorter(a,b){function chunkify(t){var tz=[];var x=0,y=-1,n=0,i=void 0,j=void 0;while(i=(j=t.charAt(x++)).charCodeAt(0)){var m=i==46||i>=48&&i<=57;if(m!==n){tz[++y]="";n=m}tz[y]+=j}return tz}var aa=chunkify(a.toLowerCase());var bb=chunkify(b.toLowerCase());for(var x=0;aa[x]&&bb[x];x++){if(aa[x]!==bb[x]){var c=Number(aa[x]),d=Number(bb[x]);if(c==aa[x]&&d==bb[x]){return c-d}else{return aa[x]>bb[x]?1:-1}}}return aa.length-bb.length}function setDomain(axis){var _this=this;var otherAxis=axis==="x"?"y":"x";if(this.config[axis].type==="ordinal"){if(this.config[axis].domain){this[axis+"_dom"]=this.config[axis].domain}else if(this.config[axis].order){this[axis+"_dom"]=d3.set(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]}))).values().sort(function(a,b){return d3.ascending(_this.config[axis].order.indexOf(a),_this.config[axis].order.indexOf(b))})}else if(this.config[axis].sort&&this.config[axis].sort==="alphabetical-ascending"){this[axis+"_dom"]=d3.set(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]}))).values().sort(naturalSorter)}else if(["time","linear"].indexOf(this.config[otherAxis].type)>-1&&this.config[axis].sort==="earliest"){this[axis+"_dom"]=d3.nest().key(function(d){return d[_this.config[axis].column]}).rollup(function(d){return d.map(function(m){return m[_this.config[otherAxis].column]}).filter(function(f){return f instanceof Date})}).entries(this.filtered_data).sort(function(a,b){return d3.min(b.values)-d3.min(a.values)}).map(function(m){return m.key})}else if(!this.config[axis].sort||this.config[axis].sort==="alphabetical-descending"){this[axis+"_dom"]=d3.set(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]}))).values().sort(naturalSorter).reverse()}else{this[axis+"_dom"]=d3.set(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]}))).values()}}else if(this.config.marks.map(function(m){return m["summarize"+axis.toUpperCase()]==="percent"}).indexOf(true)>-1){this[axis+"_dom"]=[0,1]}else{this[axis+"_dom"]=d3.extent(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]})))}if(this.config[axis].type==="linear"&&this[axis+"_dom"][0]===this[axis+"_dom"][1])this[axis+"_dom"]=this[axis+"_dom"][0]!==0?[this[axis+"_dom"][0]-this[axis+"_dom"][0]*.01,this[axis+"_dom"][1]+this[axis+"_dom"][1]*.01]:[-1,1];return this[axis+"_dom"]}function consolidateData(raw){var _this=this;this.setDefaults();this.filtered_data=raw;if(this.filters.length){this.filters.forEach(function(filter){_this.filtered_data=_this.filtered_data.filter(function(d){return filter.all===true&&filter.index===0?d:filter.val instanceof Array?filter.val.indexOf(d[filter.col])>-1:d[filter.col]===filter.val})})}this.config.marks.forEach(function(mark,i){if(mark.type!=="bar"){mark.arrange=null;mark.split=null}var mark_info=mark.per?_this.transformData(raw,mark):{data:[],x_dom:[],y_dom:[]};_this.marks[i]=Object.assign({},mark,mark_info)});setDomain.call(this,"x");setDomain.call(this,"y")}function setDefaults(){this.config.x=this.config.x||{};this.config.y=this.config.y||{};this.config.x.label=this.config.x.label!==undefined?this.config.x.label:this.config.x.column;this.config.y.label=this.config.y.label!==undefined?this.config.y.label:this.config.y.column;this.config.x.sort=this.config.x.sort||"alphabetical-ascending";this.config.y.sort=this.config.y.sort||"alphabetical-descending";this.config.x.type=this.config.x.type||"linear";this.config.y.type=this.config.y.type||"linear";this.config.x.range_band=this.config.x.range_band||this.config.range_band;this.config.y.range_band=this.config.y.range_band||this.config.range_band;this.config.margin=this.config.margin||{};this.config.legend=this.config.legend||{};this.config.legend.label=this.config.legend.label!==undefined?this.config.legend.label:this.config.color_by;this.config.legend.location=this.config.legend.location!==undefined?this.config.legend.location:"bottom";this.config.marks=this.config.marks&&this.config.marks.length?this.config.marks:[{}];this.config.marks.forEach(function(m,i){m.id=m.id?m.id:"mark"+(i+1)});this.config.date_format=this.config.date_format||"%x";this.config.padding=this.config.padding!==undefined?this.config.padding:.3;this.config.outer_pad=this.config.outer_pad!==undefined?this.config.outer_pad:.1;this.config.resizable=this.config.resizable!==undefined?this.config.resizable:true;this.config.aspect=this.config.aspect||1.33;this.config.colors=this.config.colors||["rgb(102,194,165)","rgb(252,141,98)","rgb(141,160,203)","rgb(231,138,195)","rgb(166,216,84)","rgb(255,217,47)","rgb(229,196,148)","rgb(179,179,179)"];this.config.scale_text=this.config.scale_text===undefined?true:this.config.scale_text;this.config.transitions=this.config.transitions===undefined?true:this.config.transitions}function cleanData(mark,raw){var _this=this;var dateConvert=d3.time.format(this.config.date_format);var clean=raw;clean=mark.per&&mark.per.length?clean.filter(function(f){return f[mark.per[0]]!==undefined}):clean;if(this.config.x.column){clean=clean.filter(function(f){return[undefined,null].indexOf(f[_this.config.x.column])<0})}if(this.config.y.column){clean=clean.filter(function(f){return[undefined,null].indexOf(f[_this.config.y.column])<0})}if(this.config.x.type==="time"){clean=clean.filter(function(f){return f[_this.config.x.column]instanceof Date?f[_this.config.x.column]:dateConvert.parse(f[_this.config.x.column])});clean.forEach(function(e){return e[_this.config.x.column]=e[_this.config.x.column]instanceof Date?e[_this.config.x.column]:dateConvert.parse(e[_this.config.x.column])})}if(this.config.y.type==="time"){clean=clean.filter(function(f){return f[_this.config.y.column]instanceof Date?f[_this.config.y.column]:dateConvert.parse(f[_this.config.y.column])});clean.forEach(function(e){return e[_this.config.y.column]=e[_this.config.y.column]instanceof Date?e[_this.config.y.column]:dateConvert.parse(e[_this.config.y.column])})}if((this.config.x.type==="linear"||this.config.x.type==="log")&&this.config.x.column){clean=clean.filter(function(f){return mark.summarizeX!=="count"&&mark.summarizeX!=="percent"?!(isNaN(f[_this.config.x.column])||/^\s*$/.test(f[_this.config.x.column])):f})}if((this.config.y.type==="linear"||this.config.y.type==="log")&&this.config.y.column){clean=clean.filter(function(f){return mark.summarizeY!=="count"&&mark.summarizeY!=="percent"?!(isNaN(f[_this.config.y.column])||/^\s*$/.test(f[_this.config.y.column])):f})}return clean}var stats={mean:d3.mean,min:d3.min,max:d3.max,median:d3.median,sum:d3.sum};function summarize(vals){var operation=arguments.length>1&&arguments[1]!==undefined?arguments[1]:"mean";var nvals=vals.filter(function(f){return+f||+f===0}).map(function(m){return+m});if(operation==="cumulative"){return null}var mathed=operation==="count"?vals.length:operation==="percent"?vals.length:stats[operation](nvals);return mathed}function makeNest(mark,entries,sublevel){var _this=this;var dom_xs=[];var dom_ys=[];var this_nest=d3.nest();var totalOrder=void 0;if(this.config.x.type==="linear"&&this.config.x.bin||this.config.y.type==="linear"&&this.config.y.bin){var xy=this.config.x.type==="linear"&&this.config.x.bin?"x":"y";mark.quant=d3.scale.quantile().domain(this.config[xy].domain?this.config[xy].domain:d3.extent(entries.map(function(m){return+m[_this.config[xy].column]}))).range(d3.range(+this.config[xy].bin));entries.forEach(function(e){return e.wc_bin=mark.quant(e[_this.config[xy].column])});this_nest.key(function(d){return mark.quant.invertExtent(d.wc_bin)})}else{this_nest.key(function(d){return mark.per.map(function(m){return d[m]}).join(" ")})}if(sublevel){this_nest.key(function(d){return d[sublevel]});this_nest.sortKeys(function(a,b){return _this.config.x.type==="time"?d3.ascending(new Date(a),new Date(b)):_this.config.x.order?d3.ascending(_this.config.x.order.indexOf(a),_this.config.x.order.indexOf(b)):sublevel===_this.config.color_by&&_this.config.legend.order?d3.ascending(_this.config.legend.order.indexOf(a),_this.config.legend.order.indexOf(b)):_this.config.x.type==="ordinal"||_this.config.y.type==="ordinal"?naturalSorter(a,b):d3.ascending(+a,+b)})}this_nest.rollup(function(r){var obj={raw:r};var y_vals=r.map(function(m){return m[_this.config.y.column]}).sort(d3.ascending);var x_vals=r.map(function(m){return m[_this.config.x.column]}).sort(d3.ascending);obj.x=_this.config.x.type==="ordinal"?r[0][_this.config.x.column]:summarize(x_vals,mark.summarizeX);obj.y=_this.config.y.type==="ordinal"?r[0][_this.config.y.column]:summarize(y_vals,mark.summarizeY);obj.x_q25=_this.config.error_bars&&_this.config.y.type==="ordinal"?d3.quantile(x_vals,.25):obj.x;obj.x_q75=_this.config.error_bars&&_this.config.y.type==="ordinal"?d3.quantile(x_vals,.75):obj.x;obj.y_q25=_this.config.error_bars?d3.quantile(y_vals,.25):obj.y;obj.y_q75=_this.config.error_bars?d3.quantile(y_vals,.75):obj.y;dom_xs.push([obj.x_q25,obj.x_q75,obj.x]);dom_ys.push([obj.y_q25,obj.y_q75,obj.y]);if(mark.summarizeY==="cumulative"){var interm=entries.filter(function(f){return _this.config.x.type==="time"?new Date(f[_this.config.x.column])<=new Date(r[0][_this.config.x.column]):+f[_this.config.x.column]<=+r[0][_this.config.x.column]});if(mark.per.length){interm=interm.filter(function(f){return f[mark.per[0]]===r[0][mark.per[0]]})}var cumul=_this.config.x.type==="time"?interm.length:d3.sum(interm.map(function(m){return+m[_this.config.y.column]||+m[_this.config.y.column]===0?+m[_this.config.y.column]:1}));dom_ys.push([cumul]);obj.y=cumul}if(mark.summarizeX==="cumulative"){var _interm=entries.filter(function(f){return _this.config.y.type==="time"?new Date(f[_this.config.y.column])<=new Date(r[0][_this.config.y.column]):+f[_this.config.y.column]<=+r[0][_this.config.y.column]});if(mark.per.length){_interm=_interm.filter(function(f){return f[mark.per[0]]===r[0][mark.per[0]]})}dom_xs.push([_interm.length]);obj.x=_interm.length}return obj});var test=this_nest.entries(entries);var dom_x=d3.extent(d3.merge(dom_xs));var dom_y=d3.extent(d3.merge(dom_ys));if(sublevel&&mark.type==="bar"&&mark.split){test.forEach(function(e){var axis=_this.config.x.type==="ordinal"||_this.config.x.type==="linear"&&_this.config.x.bin?"y":"x";e.total=d3.sum(e.values.map(function(m){return+m.values[axis]}));var counter=0;e.values.forEach(function(v,i){if(_this.config.x.type==="ordinal"||_this.config.x.type==="linear"&&_this.config.x.bin){v.values.y=mark.summarizeY==="percent"?v.values.y/e.total:v.values.y||0;counter+=+v.values.y;v.values.start=e.values[i-1]?counter:v.values.y}else{v.values.x=mark.summarizeX==="percent"?v.values.x/e.total:v.values.x||0;v.values.start=counter;counter+=+v.values.x}})});if(mark.arrange==="stacked"){if(this.config.x.type==="ordinal"||this.config.x.type==="linear"&&this.config.x.bin){dom_y=d3.extent(test.map(function(m){return m.total}))}if(this.config.y.type==="ordinal"||this.config.y.type==="linear"&&this.config.y.bin){dom_x=d3.extent(test.map(function(m){return m.total}))}}}else{var axis=this.config.x.type==="ordinal"||this.config.x.type==="linear"&&this.config.x.bin?"y":"x";test.forEach(function(e){return e.total=e.values[axis]})}if(this.config.x.sort==="total-ascending"&&this.config.x.type=="ordinal"||this.config.y.sort==="total-descending"&&this.config.y.type=="ordinal"){totalOrder=test.sort(function(a,b){return d3.ascending(a.total,b.total)}).map(function(m){return m.key})}else if(this.config.x.sort==="total-descending"&&this.config.x.type=="ordinal"||this.config.y.sort==="total-ascending"&&this.config.y.type=="ordinal"){totalOrder=test.sort(function(a,b){return d3.descending(+a.total,+b.total)}).map(function(m){return m.key})}return{nested:test,dom_x:dom_x,dom_y:dom_y,totalOrder:totalOrder}}function transformData(raw,mark){var _this=this;var config=this.config;var x_behavior=config.x.behavior||"raw";var y_behavior=config.y.behavior||"raw";var sublevel=mark.type==="line"?config.x.column:mark.type==="bar"&&mark.split?mark.split:null;var cleaned=cleanData.call(this,mark,raw);var raw_nest=void 0;if(mark.type==="bar"){raw_nest=mark.arrange!=="stacked"?makeNest.call(this,mark,cleaned,sublevel):makeNest.call(this,mark,cleaned)}else if(mark.summarizeX==="count"||mark.summarizeY==="count"){raw_nest=makeNest.call(this,mark,cleaned)}var raw_dom_x=mark.summarizeX==="cumulative"?[0,cleaned.length]:config.x.type==="ordinal"?d3.set(cleaned.map(function(m){return m[config.x.column]})).values().filter(function(f){return f}):mark.split&&mark.arrange!=="stacked"?d3.extent(d3.merge(raw_nest.nested.map(function(m){return m.values.map(function(p){return p.values.raw.length})}))):mark.summarizeX==="count"?d3.extent(raw_nest.nested.map(function(m){return m.values.raw.length})):d3.extent(cleaned.map(function(m){return+m[config.x.column]}).filter(function(f){return+f||+f===0}));var raw_dom_y=mark.summarizeY==="cumulative"?[0,cleaned.length]:config.y.type==="ordinal"?d3.set(cleaned.map(function(m){return m[config.y.column]})).values().filter(function(f){return f}):mark.split&&mark.arrange!=="stacked"?d3.extent(d3.merge(raw_nest.nested.map(function(m){return m.values.map(function(p){return p.values.raw.length})}))):mark.summarizeY==="count"?d3.extent(raw_nest.nested.map(function(m){return m.values.raw.length})):d3.extent(cleaned.map(function(m){return+m[config.y.column]}).filter(function(f){return+f||+f===0}));var filtered=cleaned;var filt1_xs=[];var filt1_ys=[];if(this.filters.length){this.filters.forEach(function(e){filtered=filtered.filter(function(d){return e.all===true&&e.index===0?d:e.val instanceof Array?e.val.indexOf(d[e.col])>-1:d[e.col]===e.val})});if(config.x.behavior==="firstfilter"||config.y.behavior==="firstfilter"){this.filters[0].choices.filter(function(f){return f!=="All"}).forEach(function(e){var perfilter=cleaned.filter(function(f){return f[_this.filters[0].col]===e});var filt_nested=makeNest.call(_this,mark,perfilter,sublevel);filt1_xs.push(filt_nested.dom_x);filt1_ys.push(filt_nested.dom_y)})}}if(mark.values){var _loop=function _loop(a){filtered=filtered.filter(function(f){return mark.values[a].indexOf(f[a])>-1})};for(var a in mark.values){_loop(a)}}var filt1_dom_x=d3.extent(d3.merge(filt1_xs));var filt1_dom_y=d3.extent(d3.merge(filt1_ys));var current_nested=makeNest.call(this,mark,filtered,sublevel);var flex_dom_x=current_nested.dom_x;var flex_dom_y=current_nested.dom_y;if(mark.type==="bar"){if(config.y.type==="ordinal"&&mark.summarizeX==="count"){config.x.domain=config.x.domain?[0,config.x.domain[1]]:[0,null]}else if(config.x.type==="ordinal"&&mark.summarizeY==="count"){config.y.domain=config.y.domain?[0,config.y.domain[1]]:[0,null]}}var nonall=Boolean(this.filters.length&&this.filters[0].val!=="All"&&this.filters.slice(1).filter(function(f){return f.val==="All"}).length===this.filters.length-1);var pre_x_dom=!this.filters.length?flex_dom_x:x_behavior==="raw"?raw_dom_x:nonall&&x_behavior==="firstfilter"?filt1_dom_x:flex_dom_x;var pre_y_dom=!this.filters.length?flex_dom_y:y_behavior==="raw"?raw_dom_y:nonall&&y_behavior==="firstfilter"?filt1_dom_y:flex_dom_y;var x_dom=config.x_dom?config.x_dom:config.x.type==="ordinal"&&config.x.behavior==="flex"?d3.set(filtered.map(function(m){return m[config.x.column]})).values():config.x.type==="ordinal"?d3.set(cleaned.map(function(m){return m[config.x.column]})).values():pre_x_dom;var y_dom=config.y_dom?config.y_dom:config.y.type==="ordinal"&&config.y.behavior==="flex"?d3.set(filtered.map(function(m){return m[config.y.column]})).values():config.y.type==="ordinal"?d3.set(cleaned.map(function(m){return m[config.y.column]})).values():pre_y_dom;if(mark.type==="bar"){if(config.x.behavior!=="flex"&&config.x.type==="linear"&&config.y.type==="ordinal"&&raw_dom_x[0]>=0)x_dom[0]=0;if(config.y.behavior!=="flex"&&config.x.type==="ordinal"&&config.y.type==="linear"&&raw_dom_y[0]>=0)y_dom[0]=0}if(config.x.domain&&(config.x.domain[0]||config.x.domain[0]===0)&&!isNaN(+config.x.domain[0])){x_dom[0]=config.x.domain[0]}if(config.x.domain&&(config.x.domain[1]||config.x.domain[1]===0)&&!isNaN(+config.x.domain[1])){x_dom[1]=config.x.domain[1]}if(config.y.domain&&(config.y.domain[0]||config.y.domain[0]===0)&&!isNaN(+config.y.domain[0])){y_dom[0]=config.y.domain[0]}if(config.y.domain&&(config.y.domain[1]||config.y.domain[1]===0)&&!isNaN(+config.y.domain[1])){y_dom[1]=config.y.domain[1]}if(config.x.type==="ordinal"&&!config.x.order){config.x.order=current_nested.totalOrder}if(config.y.type==="ordinal"&&!config.y.order){config.y.order=current_nested.totalOrder}this.current_data=current_nested.nested;this.events.onDatatransform.call(this);return{config:mark,data:current_nested.nested,x_dom:x_dom,y_dom:y_dom}}function setColorScale(){var config=this.config;var data=config.legend.behavior==="flex"?this.filtered_data:this.raw_data;var colordom=Array.isArray(config.color_dom)&&config.color_dom.length?config.color_dom.slice():d3.set(data.map(function(m){return m[config.color_by]})).values().filter(function(f){return f&&f!=="undefined"});if(config.legend.order)colordom.sort(function(a,b){return d3.ascending(config.legend.order.indexOf(a),config.legend.order.indexOf(b))});else colordom.sort(naturalSorter);this.colorScale=d3.scale.ordinal().domain(colordom).range(config.colors)}function xScaleAxis(max_range,domain,type){if(max_range===undefined){max_range=this.plot_width}if(domain===undefined){domain=this.x_dom}if(type===undefined){type=this.config.x.type}var config=this.config;var x=void 0;if(type==="log"){x=d3.scale.log()}else if(type==="ordinal"){x=d3.scale.ordinal()}else if(type==="time"){x=d3.time.scale()}else{x=d3.scale.linear()}x.domain(domain);if(type==="ordinal"){x.rangeBands([0,+max_range],config.padding,config.outer_pad)}else{x.range([0,+max_range]).clamp(Boolean(config.x.clamp))}var xFormat=config.x.format?config.x.format:config.marks.map(function(m){return m.summarizeX==="percent"}).indexOf(true)>-1?"0%":type==="time"?"%x":".0f";var tick_count=Math.max(2,Math.min(max_range/80,8));var xAxis=d3.svg.axis().scale(x).orient(config.x.location).ticks(tick_count).tickFormat(type==="ordinal"?null:type==="time"?d3.time.format(xFormat):d3.format(xFormat)).tickValues(config.x.ticks?config.x.ticks:null).innerTickSize(6).outerTickSize(3);this.svg.select("g.x.axis").attr("class","x axis "+type);this.x=x;this.xAxis=xAxis}function yScaleAxis(max_range,domain,type){if(max_range===undefined){max_range=this.plot_height}if(domain===undefined){domain=this.y_dom}if(type===undefined){type=this.config.y.type}var config=this.config;var y=void 0;if(type==="log"){y=d3.scale.log()}else if(type==="ordinal"){y=d3.scale.ordinal()}else if(type==="time"){y=d3.time.scale()}else{y=d3.scale.linear()}y.domain(domain);if(type==="ordinal"){y.rangeBands([+max_range,0],config.padding,config.outer_pad)}else{y.range([+max_range,0]).clamp(Boolean(config.y_clamp))}var yFormat=config.y.format?config.y.format:config.marks.map(function(m){return m.summarizeY==="percent"}).indexOf(true)>-1?"0%":".0f";var tick_count=Math.max(2,Math.min(max_range/80,8));var yAxis=d3.svg.axis().scale(y).orient("left").ticks(tick_count).tickFormat(type==="ordinal"?null:type==="time"?d3.time.format(yFormat):d3.format(yFormat)).tickValues(config.y.ticks?config.y.ticks:null).innerTickSize(6).outerTickSize(3);this.svg.select("g.y.axis").attr("class","y axis "+type);this.y=y;this.yAxis=yAxis}function resize(){var config=this.config;var aspect2=1/config.aspect;var div_width=parseInt(this.wrap.style("width"));var max_width=config.max_width?config.max_width:div_width;var preWidth=!config.resizable?config.width:!max_width||div_width=600){font_size="14px";point_size=4;stroke_width=2}else if(width>450&&width<600){font_size="12px";point_size=3;stroke_width=2}else if(width>300&&width<450){font_size="10px";point_size=2;stroke_width=2}else if(width<=300){font_size="10px";point_size=2;stroke_width=1}this.wrap.style("font-size",font_size);this.config.flex_point_size=point_size;this.config.flex_stroke_width=stroke_width}function setMargins(){var _this=this;var y_ticks=this.yAxis.tickFormat()?this.y.domain().map(function(m){return _this.yAxis.tickFormat()(m)}):this.y.domain();var max_y_text_length=d3.max(y_ticks.map(function(m){return String(m).length}));if(this.config.y_format&&this.config.y_format.indexOf("%")>-1){max_y_text_length+=1}max_y_text_length=Math.max(2,max_y_text_length);var x_label_on=this.config.x.label?1.5:0;var y_label_on=this.config.y.label?1.5:.25;var font_size=parseInt(this.wrap.style("font-size"));var x_second=this.config.x2_interval?1:0;var y_margin=max_y_text_length*font_size*.5+font_size*y_label_on*1.5||8;var x_margin=font_size+font_size/1.5+font_size*x_label_on+font_size*x_second||8;y_margin+=6;x_margin+=3;return{top:this.config.margin&&this.config.margin.top?this.config.margin.top:8,right:this.config.margin&&this.config.margin.right?this.config.margin.right:16,bottom:this.config.margin&&this.config.margin.bottom?this.config.margin.bottom:x_margin,left:this.config.margin&&this.config.margin.left?this.config.margin.left:y_margin}}function drawGridLines(){this.wrap.classed("gridlines",this.config.gridlines);if(this.config.gridlines){this.svg.select(".y.axis").selectAll(".tick line").attr("x1",0);this.svg.select(".x.axis").selectAll(".tick line").attr("y1",0);if(this.config.gridlines==="y"||this.config.gridlines==="xy")this.svg.select(".y.axis").selectAll(".tick line").attr("x1",this.plot_width);if(this.config.gridlines==="x"||this.config.gridlines==="xy")this.svg.select(".x.axis").selectAll(".tick line").attr("y1",-this.plot_height)}else{this.svg.select(".y.axis").selectAll(".tick line").attr("x1",0);this.svg.select(".x.axis").selectAll(".tick line").attr("y1",0)}}function makeLegend(){var scale=arguments.length>0&&arguments[0]!==undefined?arguments[0]:this.colorScale;var label=arguments.length>1&&arguments[1]!==undefined?arguments[1]:"";var custom_data=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;var config=this.config;config.legend.mark=config.legend.mark?config.legend.mark:config.marks.length&&config.marks[0].type==="bar"?"square":config.marks.length?config.marks[0].type:"square";var legend_label=label?label:typeof config.legend.label==="string"?config.legend.label:"";var legendOriginal=this.legend||this.wrap.select(".legend");var legend=legendOriginal;if(!this.parent){if(this.config.legend.location==="top"||this.config.legend.location==="left"){this.wrap.node().insertBefore(legendOriginal.node(),this.svg.node().parentNode)}else{this.wrap.node().appendChild(legendOriginal.node())}}else{if(this.config.legend.location==="top"||this.config.legend.location==="left"){this.parent.wrap.node().insertBefore(legendOriginal.node(),this.parent.wrap.select(".wc-chart").node())}else{this.parent.wrap.node().appendChild(legendOriginal.node())}}legend.style("padding",0);var legend_data=custom_data||scale.domain().slice(0).filter(function(f){return f!==undefined&&f!==null}).map(function(m){return{label:m,mark:config.legend.mark}});legend.select(".legend-title").text(legend_label).style("display",legend_label?"inline":"none").style("margin-right","1em");var leg_parts=legend.selectAll(".legend-item").data(legend_data,function(d){return d.label+d.mark});leg_parts.exit().remove();var legendPartDisplay=this.config.legend.location==="bottom"||this.config.legend.location==="top"?"inline-block":"block" +(function(global,factory){typeof exports==="object"&&typeof module!=="undefined"?module.exports=factory(require("d3")):typeof define==="function"&&define.amd?define(["d3"],factory):global.webCharts=factory(global.d3)})(typeof self!=="undefined"?self:this,function(d3){"use strict";var version="1.11.6";function init(data){var _this=this;var test=arguments.length>1&&arguments[1]!==undefined?arguments[1]:false;if(d3.select(this.div).select(".loader").empty()){d3.select(this.div).insert("div",":first-child").attr("class","loader").selectAll(".blockG").data(d3.range(8)).enter().append("div").attr("class",function(d){return"blockG rotate"+(d+1)})}this.wrap.attr("class","wc-chart");this.setDefaults();this.raw_data=data;this.initial_data=data;var startup=function startup(data){if(_this.controls){_this.controls.targets.push(_this);if(!_this.controls.ready){_this.controls.init(_this.raw_data)}else{_this.controls.layout()}}var visible=d3.select(_this.div).property("offsetWidth")>0||test;if(!visible){console.warn("The chart cannot be initialized inside an element with 0 width. The chart will be initialized as soon as the container element is given a width > 0.");var onVisible=setInterval(function(i){var visible_now=d3.select(_this.div).property("offsetWidth")>0;if(visible_now){_this.layout();_this.draw();clearInterval(onVisible)}},500)}else{_this.layout();_this.draw()}};this.events.onInit.call(this);if(this.raw_data.length){this.checkRequired(this.raw_data)}startup(data);return this}function checkRequired(data){var _this=this;var colnames=Object.keys(data[0]);var requiredVars=[];var requiredCols=[];if(this.config.x&&this.config.x.column){requiredVars.push("this.config.x.column");requiredCols.push(this.config.x.column)}if(this.config.y&&this.config.y.column){requiredVars.push("this.config.y.column");requiredCols.push(this.config.y.column)}if(this.config.color_by){requiredVars.push("this.config.color_by");requiredCols.push(this.config.color_by)}if(this.config.marks)this.config.marks.forEach(function(e,i){if(e.per&&e.per.length){e.per.forEach(function(p,j){requiredVars.push("this.config.marks["+i+"].per["+j+"]");requiredCols.push(p)})}if(e.split){requiredVars.push("this.config.marks["+i+"].split");requiredCols.push(e.split)}if(e.values){for(var value in e.values){requiredVars.push("this.config.marks["+i+"].values['"+value+"']");requiredCols.push(value)}}});var missingDataField=false;requiredCols.forEach(function(e,i){if(colnames.indexOf(e)<0){missingDataField=true;d3.select(_this.div).select(".loader").remove();_this.wrap.append("div").style("color","red").html('The value "'+e+'" for the '+requiredVars[i]+" setting does not match any column in the provided dataset.");throw new Error('Error in settings object: The value "'+e+'" for the '+requiredVars[i]+" setting does not match any column in the provided dataset.")}});return{missingDataField:missingDataField,dataFieldArguments:requiredVars,requiredDataFields:requiredCols}}function addSVG(){this.svg=this.wrap.append("svg").datum(function(){return null}).attr({class:"wc-svg",xmlns:"http://www.w3.org/2000/svg",version:"1.1",xlink:"http://www.w3.org/1999/xlink"}).append("g").style("display","inline-block")}function addDefs(){var defs=this.svg.append("defs");defs.append("pattern").attr({id:"diagonal-stripes",x:0,y:0,width:3,height:8,patternUnits:"userSpaceOnUse",patternTransform:"rotate(30)"}).append("rect").attr({x:"0",y:"0",width:"2",height:"8"}).style({stroke:"none",fill:"black"});defs.append("clipPath").attr("id",this.id).append("rect").attr("class","plotting-area")}function addXAxis(){this.svg.append("g").attr("class","x axis").append("text").attr("class","axis-title").attr("dy","-.35em").attr("text-anchor","middle")}function addYAxis(){this.svg.append("g").attr("class","y axis").append("text").attr("class","axis-title").attr("transform","rotate(-90)").attr("dy",".75em").attr("text-anchor","middle")}function addOverlay(){this.overlay=this.svg.append("rect").attr("class","overlay").attr("opacity",0).attr("fill","none").style("pointer-events","all")}function addLegend(){if(!this.parent)this.wrap.append("ul").datum(function(){return null}).attr("class","legend").style("vertical-align","top").append("span").attr("class","legend-title")}function clearLoader(){d3.select(this.div).select(".loader").remove()}function layout(){addSVG.call(this);addDefs.call(this);addXAxis.call(this);addYAxis.call(this);addOverlay.call(this);addLegend.call(this);clearLoader.call(this);this.events.onLayout.call(this)}function draw(raw_data,processed_data){var _this=this;var chart=this;var config=this.config;this.events.onPreprocess.call(this);var raw=raw_data?raw_data:this.raw_data?this.raw_data:[];if(processed_data){console.warn("Drawing the chart using user-defined 'processed_data', this is an experimental, untested feature.")}this.consolidateData(raw);var div_width=parseInt(this.wrap.style("width"));this.setColorScale();var max_width=config.max_width?config.max_width:div_width;this.raw_width=config.x.type==="ordinal"&&+config.x.range_band?(+config.x.range_band+config.x.range_band*config.padding)*this.x_dom.length:config.resizable?max_width:config.width?config.width:div_width;this.raw_height=config.y.type==="ordinal"&&+config.y.range_band?(+config.y.range_band+config.y.range_band*config.padding)*this.y_dom.length:config.resizable?max_width*(1/config.aspect):config.height?config.height:div_width*(1/config.aspect);var pseudo_width=this.svg.select(".overlay").attr("width")?this.svg.select(".overlay").attr("width"):this.raw_width;var pseudo_height=this.svg.select(".overlay").attr("height")?this.svg.select(".overlay").attr("height"):this.raw_height;this.svg.select(".x.axis").select(".axis-title").text(function(d){return typeof config.x.label==="string"?config.x.label:typeof config.x.label==="function"?config.x.label.call(_this):null});this.svg.select(".y.axis").select(".axis-title").text(function(d){return typeof config.y.label==="string"?config.y.label:typeof config.y.label==="function"?config.y.label.call(_this):null});this.xScaleAxis(pseudo_width);this.yScaleAxis(pseudo_height);if(config.resizable&&typeof window!=="undefined"){d3.select(window).on("resize."+this.element+this.id,function(){chart.resize()})}else if(typeof window!=="undefined"){d3.select(window).on("resize."+this.element+this.id,null)}this.events.onDraw.call(this);this.resize()}function naturalSorter(a,b){function chunkify(t){var tz=[];var x=0,y=-1,n=0,i=void 0,j=void 0;while(i=(j=t.charAt(x++)).charCodeAt(0)){var m=i==46||i>=48&&i<=57;if(m!==n){tz[++y]="";n=m}tz[y]+=j}return tz}var aa=chunkify(a.toLowerCase());var bb=chunkify(b.toLowerCase());for(var x=0;aa[x]&&bb[x];x++){if(aa[x]!==bb[x]){var c=Number(aa[x]),d=Number(bb[x]);if(c==aa[x]&&d==bb[x]){return c-d}else{return aa[x]>bb[x]?1:-1}}}return aa.length-bb.length}function setDomain(axis){var _this=this;var otherAxis=axis==="x"?"y":"x";if(this.config[axis].type==="ordinal"){if(this.config[axis].domain){this[axis+"_dom"]=this.config[axis].domain}else if(this.config[axis].order){this[axis+"_dom"]=d3.set(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]}))).values().sort(function(a,b){return d3.ascending(_this.config[axis].order.indexOf(a),_this.config[axis].order.indexOf(b))})}else if(this.config[axis].sort&&this.config[axis].sort==="alphabetical-ascending"){this[axis+"_dom"]=d3.set(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]}))).values().sort(naturalSorter)}else if(["time","linear"].indexOf(this.config[otherAxis].type)>-1&&this.config[axis].sort==="earliest"){this[axis+"_dom"]=d3.nest().key(function(d){return d[_this.config[axis].column]}).rollup(function(d){return d.map(function(m){return m[_this.config[otherAxis].column]}).filter(function(f){return f instanceof Date})}).entries(this.filtered_data).sort(function(a,b){return d3.min(b.values)-d3.min(a.values)}).map(function(m){return m.key})}else if(!this.config[axis].sort||this.config[axis].sort==="alphabetical-descending"){this[axis+"_dom"]=d3.set(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]}))).values().sort(naturalSorter).reverse()}else{this[axis+"_dom"]=d3.set(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]}))).values()}}else if(this.config.marks.map(function(m){return m["summarize"+axis.toUpperCase()]==="percent"}).indexOf(true)>-1){this[axis+"_dom"]=[0,1]}else{this[axis+"_dom"]=d3.extent(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]})))}if(this.config[axis].type==="linear"&&this[axis+"_dom"][0]===this[axis+"_dom"][1])this[axis+"_dom"]=this[axis+"_dom"][0]!==0?[this[axis+"_dom"][0]-this[axis+"_dom"][0]*.01,this[axis+"_dom"][1]+this[axis+"_dom"][1]*.01]:[-1,1];return this[axis+"_dom"]}function consolidateData(raw){var _this=this;this.setDefaults();this.filtered_data=raw;if(this.filters.length){this.filters.forEach(function(filter){_this.filtered_data=_this.filtered_data.filter(function(d){return filter.all===true&&filter.index===0?d:filter.val instanceof Array?filter.val.indexOf(d[filter.col])>-1:d[filter.col]===filter.val})})}this.config.marks.forEach(function(mark,i){if(mark.type!=="bar"){mark.arrange=null;mark.split=null}var mark_info=mark.per?_this.transformData(raw,mark):{data:[],x_dom:[],y_dom:[]};_this.marks[i]=Object.assign({},mark,mark_info)});setDomain.call(this,"x");setDomain.call(this,"y")}function setDefaults(){this.config.x=this.config.x||{};this.config.y=this.config.y||{};this.config.x.label=this.config.x.label!==undefined?this.config.x.label:this.config.x.column;this.config.y.label=this.config.y.label!==undefined?this.config.y.label:this.config.y.column;this.config.x.sort=this.config.x.sort||"alphabetical-ascending";this.config.y.sort=this.config.y.sort||"alphabetical-descending";this.config.x.type=this.config.x.type||"linear";this.config.y.type=this.config.y.type||"linear";this.config.x.range_band=this.config.x.range_band||this.config.range_band;this.config.y.range_band=this.config.y.range_band||this.config.range_band;this.config.margin=this.config.margin||{};this.config.legend=this.config.legend||{};this.config.legend.label=this.config.legend.label!==undefined?this.config.legend.label:this.config.color_by;this.config.legend.location=this.config.legend.location!==undefined?this.config.legend.location:"bottom";this.config.marks=this.config.marks&&this.config.marks.length?this.config.marks:[{}];this.config.marks.forEach(function(m,i){m.id=m.id?m.id:"mark"+(i+1)});this.config.date_format=this.config.date_format||"%x";this.config.padding=this.config.padding!==undefined?this.config.padding:.3;this.config.outer_pad=this.config.outer_pad!==undefined?this.config.outer_pad:.1;this.config.resizable=this.config.resizable!==undefined?this.config.resizable:true;this.config.aspect=this.config.aspect||1.33;this.config.colors=this.config.colors||["rgb(102,194,165)","rgb(252,141,98)","rgb(141,160,203)","rgb(231,138,195)","rgb(166,216,84)","rgb(255,217,47)","rgb(229,196,148)","rgb(179,179,179)"];this.config.scale_text=this.config.scale_text===undefined?true:this.config.scale_text;this.config.transitions=this.config.transitions===undefined?true:this.config.transitions}function cleanData(mark,raw){var _this=this;var dateConvert=d3.time.format(this.config.date_format);var clean=raw;clean=mark.per&&mark.per.length?clean.filter(function(f){return f[mark.per[0]]!==undefined}):clean;if(this.config.x.column){clean=clean.filter(function(f){return[undefined,null].indexOf(f[_this.config.x.column])<0})}if(this.config.y.column){clean=clean.filter(function(f){return[undefined,null].indexOf(f[_this.config.y.column])<0})}if(this.config.x.type==="time"){clean=clean.filter(function(f){return f[_this.config.x.column]instanceof Date?f[_this.config.x.column]:dateConvert.parse(f[_this.config.x.column])});clean.forEach(function(e){return e[_this.config.x.column]=e[_this.config.x.column]instanceof Date?e[_this.config.x.column]:dateConvert.parse(e[_this.config.x.column])})}if(this.config.y.type==="time"){clean=clean.filter(function(f){return f[_this.config.y.column]instanceof Date?f[_this.config.y.column]:dateConvert.parse(f[_this.config.y.column])});clean.forEach(function(e){return e[_this.config.y.column]=e[_this.config.y.column]instanceof Date?e[_this.config.y.column]:dateConvert.parse(e[_this.config.y.column])})}if((this.config.x.type==="linear"||this.config.x.type==="log")&&this.config.x.column){clean=clean.filter(function(f){return mark.summarizeX!=="count"&&mark.summarizeX!=="percent"?!(isNaN(f[_this.config.x.column])||/^\s*$/.test(f[_this.config.x.column])):f})}if((this.config.y.type==="linear"||this.config.y.type==="log")&&this.config.y.column){clean=clean.filter(function(f){return mark.summarizeY!=="count"&&mark.summarizeY!=="percent"?!(isNaN(f[_this.config.y.column])||/^\s*$/.test(f[_this.config.y.column])):f})}return clean}var stats={mean:d3.mean,min:d3.min,max:d3.max,median:d3.median,sum:d3.sum};function summarize(vals){var operation=arguments.length>1&&arguments[1]!==undefined?arguments[1]:"mean";var nvals=vals.filter(function(f){return+f||+f===0}).map(function(m){return+m});if(operation==="cumulative"){return null}var mathed=operation==="count"?vals.length:operation==="percent"?vals.length:stats[operation](nvals);return mathed}function makeNest(mark,entries,sublevel){var _this=this;var dom_xs=[];var dom_ys=[];var this_nest=d3.nest();var totalOrder=void 0;if(this.config.x.type==="linear"&&this.config.x.bin||this.config.y.type==="linear"&&this.config.y.bin){var xy=this.config.x.type==="linear"&&this.config.x.bin?"x":"y";mark.quant=d3.scale.quantile().domain(this.config[xy].domain?this.config[xy].domain:d3.extent(entries.map(function(m){return+m[_this.config[xy].column]}))).range(d3.range(+this.config[xy].bin));entries.forEach(function(e){return e.wc_bin=mark.quant(e[_this.config[xy].column])});this_nest.key(function(d){return mark.quant.invertExtent(d.wc_bin)})}else{this_nest.key(function(d){return mark.per.map(function(m){return d[m]}).join(" ")})}if(sublevel){this_nest.key(function(d){return d[sublevel]});this_nest.sortKeys(function(a,b){return _this.config.x.type==="time"?d3.ascending(new Date(a),new Date(b)):_this.config.x.order?d3.ascending(_this.config.x.order.indexOf(a),_this.config.x.order.indexOf(b)):sublevel===_this.config.color_by&&_this.config.legend.order?d3.ascending(_this.config.legend.order.indexOf(a),_this.config.legend.order.indexOf(b)):_this.config.x.type==="ordinal"||_this.config.y.type==="ordinal"?naturalSorter(a,b):d3.ascending(+a,+b)})}this_nest.rollup(function(r){var obj={raw:r};var y_vals=r.map(function(m){return m[_this.config.y.column]}).sort(d3.ascending);var x_vals=r.map(function(m){return m[_this.config.x.column]}).sort(d3.ascending);obj.x=_this.config.x.type==="ordinal"?r[0][_this.config.x.column]:summarize(x_vals,mark.summarizeX);obj.y=_this.config.y.type==="ordinal"?r[0][_this.config.y.column]:summarize(y_vals,mark.summarizeY);obj.x_q25=_this.config.error_bars&&_this.config.y.type==="ordinal"?d3.quantile(x_vals,.25):obj.x;obj.x_q75=_this.config.error_bars&&_this.config.y.type==="ordinal"?d3.quantile(x_vals,.75):obj.x;obj.y_q25=_this.config.error_bars?d3.quantile(y_vals,.25):obj.y;obj.y_q75=_this.config.error_bars?d3.quantile(y_vals,.75):obj.y;dom_xs.push([obj.x_q25,obj.x_q75,obj.x]);dom_ys.push([obj.y_q25,obj.y_q75,obj.y]);if(mark.summarizeY==="cumulative"){var interm=entries.filter(function(f){return _this.config.x.type==="time"?new Date(f[_this.config.x.column])<=new Date(r[0][_this.config.x.column]):+f[_this.config.x.column]<=+r[0][_this.config.x.column]});if(mark.per.length){interm=interm.filter(function(f){return f[mark.per[0]]===r[0][mark.per[0]]})}var cumul=_this.config.x.type==="time"?interm.length:d3.sum(interm.map(function(m){return+m[_this.config.y.column]||+m[_this.config.y.column]===0?+m[_this.config.y.column]:1}));dom_ys.push([cumul]);obj.y=cumul}if(mark.summarizeX==="cumulative"){var _interm=entries.filter(function(f){return _this.config.y.type==="time"?new Date(f[_this.config.y.column])<=new Date(r[0][_this.config.y.column]):+f[_this.config.y.column]<=+r[0][_this.config.y.column]});if(mark.per.length){_interm=_interm.filter(function(f){return f[mark.per[0]]===r[0][mark.per[0]]})}dom_xs.push([_interm.length]);obj.x=_interm.length}return obj});var test=this_nest.entries(entries);var dom_x=d3.extent(d3.merge(dom_xs));var dom_y=d3.extent(d3.merge(dom_ys));if(sublevel&&mark.type==="bar"&&mark.split){test.forEach(function(e){var axis=_this.config.x.type==="ordinal"||_this.config.x.type==="linear"&&_this.config.x.bin?"y":"x";e.total=d3.sum(e.values.map(function(m){return+m.values[axis]}));var counter=0;e.values.forEach(function(v,i){if(_this.config.x.type==="ordinal"||_this.config.x.type==="linear"&&_this.config.x.bin){v.values.y=mark.summarizeY==="percent"?v.values.y/e.total:v.values.y||0;counter+=+v.values.y;v.values.start=e.values[i-1]?counter:v.values.y}else{v.values.x=mark.summarizeX==="percent"?v.values.x/e.total:v.values.x||0;v.values.start=counter;counter+=+v.values.x}})});if(mark.arrange==="stacked"){if(this.config.x.type==="ordinal"||this.config.x.type==="linear"&&this.config.x.bin){dom_y=d3.extent(test.map(function(m){return m.total}))}if(this.config.y.type==="ordinal"||this.config.y.type==="linear"&&this.config.y.bin){dom_x=d3.extent(test.map(function(m){return m.total}))}}}else{var axis=this.config.x.type==="ordinal"||this.config.x.type==="linear"&&this.config.x.bin?"y":"x";test.forEach(function(e){return e.total=e.values[axis]})}if(this.config.x.sort==="total-ascending"&&this.config.x.type=="ordinal"||this.config.y.sort==="total-descending"&&this.config.y.type=="ordinal"){totalOrder=test.sort(function(a,b){return d3.ascending(a.total,b.total)}).map(function(m){return m.key})}else if(this.config.x.sort==="total-descending"&&this.config.x.type=="ordinal"||this.config.y.sort==="total-ascending"&&this.config.y.type=="ordinal"){totalOrder=test.sort(function(a,b){return d3.descending(+a.total,+b.total)}).map(function(m){return m.key})}return{nested:test,dom_x:dom_x,dom_y:dom_y,totalOrder:totalOrder}}function transformData(raw,mark){var _this=this;var config=this.config;var x_behavior=config.x.behavior||"raw";var y_behavior=config.y.behavior||"raw";var sublevel=mark.type==="line"?config.x.column:mark.type==="bar"&&mark.split?mark.split:null;var cleaned=cleanData.call(this,mark,raw);var raw_nest=void 0;if(mark.type==="bar"){raw_nest=mark.arrange!=="stacked"?makeNest.call(this,mark,cleaned,sublevel):makeNest.call(this,mark,cleaned)}else if(mark.summarizeX==="count"||mark.summarizeY==="count"){raw_nest=makeNest.call(this,mark,cleaned)}var raw_dom_x=mark.summarizeX==="cumulative"?[0,cleaned.length]:config.x.type==="ordinal"?d3.set(cleaned.map(function(m){return m[config.x.column]})).values().filter(function(f){return f}):mark.split&&mark.arrange!=="stacked"?d3.extent(d3.merge(raw_nest.nested.map(function(m){return m.values.map(function(p){return p.values.raw.length})}))):mark.summarizeX==="count"?d3.extent(raw_nest.nested.map(function(m){return m.values.raw.length})):d3.extent(cleaned.map(function(m){return+m[config.x.column]}).filter(function(f){return+f||+f===0}));var raw_dom_y=mark.summarizeY==="cumulative"?[0,cleaned.length]:config.y.type==="ordinal"?d3.set(cleaned.map(function(m){return m[config.y.column]})).values().filter(function(f){return f}):mark.split&&mark.arrange!=="stacked"?d3.extent(d3.merge(raw_nest.nested.map(function(m){return m.values.map(function(p){return p.values.raw.length})}))):mark.summarizeY==="count"?d3.extent(raw_nest.nested.map(function(m){return m.values.raw.length})):d3.extent(cleaned.map(function(m){return+m[config.y.column]}).filter(function(f){return+f||+f===0}));var filtered=cleaned;var filt1_xs=[];var filt1_ys=[];if(this.filters.length){this.filters.forEach(function(e){filtered=filtered.filter(function(d){return e.all===true&&e.index===0?d:e.val instanceof Array?e.val.indexOf(d[e.col])>-1:d[e.col]===e.val})});if(config.x.behavior==="firstfilter"||config.y.behavior==="firstfilter"){this.filters[0].choices.filter(function(f){return f!=="All"}).forEach(function(e){var perfilter=cleaned.filter(function(f){return f[_this.filters[0].col]===e});var filt_nested=makeNest.call(_this,mark,perfilter,sublevel);filt1_xs.push(filt_nested.dom_x);filt1_ys.push(filt_nested.dom_y)})}}if(mark.values){var _loop=function _loop(a){filtered=filtered.filter(function(f){return mark.values[a].indexOf(f[a])>-1})};for(var a in mark.values){_loop(a)}}var filt1_dom_x=d3.extent(d3.merge(filt1_xs));var filt1_dom_y=d3.extent(d3.merge(filt1_ys));var current_nested=makeNest.call(this,mark,filtered,sublevel);var flex_dom_x=current_nested.dom_x;var flex_dom_y=current_nested.dom_y;if(mark.type==="bar"){if(config.y.type==="ordinal"&&mark.summarizeX==="count"){config.x.domain=config.x.domain?[0,config.x.domain[1]]:[0,null]}else if(config.x.type==="ordinal"&&mark.summarizeY==="count"){config.y.domain=config.y.domain?[0,config.y.domain[1]]:[0,null]}}var nonall=Boolean(this.filters.length&&this.filters[0].val!=="All"&&this.filters.slice(1).filter(function(f){return f.val==="All"}).length===this.filters.length-1);var pre_x_dom=!this.filters.length?flex_dom_x:x_behavior==="raw"?raw_dom_x:nonall&&x_behavior==="firstfilter"?filt1_dom_x:flex_dom_x;var pre_y_dom=!this.filters.length?flex_dom_y:y_behavior==="raw"?raw_dom_y:nonall&&y_behavior==="firstfilter"?filt1_dom_y:flex_dom_y;var x_dom=config.x_dom?config.x_dom:config.x.type==="ordinal"&&config.x.behavior==="flex"?d3.set(filtered.map(function(m){return m[config.x.column]})).values():config.x.type==="ordinal"?d3.set(cleaned.map(function(m){return m[config.x.column]})).values():pre_x_dom;var y_dom=config.y_dom?config.y_dom:config.y.type==="ordinal"&&config.y.behavior==="flex"?d3.set(filtered.map(function(m){return m[config.y.column]})).values():config.y.type==="ordinal"?d3.set(cleaned.map(function(m){return m[config.y.column]})).values():pre_y_dom;if(mark.type==="bar"){if(config.x.behavior!=="flex"&&config.x.type==="linear"&&config.y.type==="ordinal"&&raw_dom_x[0]>=0)x_dom[0]=0;if(config.y.behavior!=="flex"&&config.x.type==="ordinal"&&config.y.type==="linear"&&raw_dom_y[0]>=0)y_dom[0]=0}if(config.x.domain&&(config.x.domain[0]||config.x.domain[0]===0)&&!isNaN(+config.x.domain[0])){x_dom[0]=config.x.domain[0]}if(config.x.domain&&(config.x.domain[1]||config.x.domain[1]===0)&&!isNaN(+config.x.domain[1])){x_dom[1]=config.x.domain[1]}if(config.y.domain&&(config.y.domain[0]||config.y.domain[0]===0)&&!isNaN(+config.y.domain[0])){y_dom[0]=config.y.domain[0]}if(config.y.domain&&(config.y.domain[1]||config.y.domain[1]===0)&&!isNaN(+config.y.domain[1])){y_dom[1]=config.y.domain[1]}if(config.x.type==="ordinal"&&!config.x.order){config.x.order=current_nested.totalOrder}if(config.y.type==="ordinal"&&!config.y.order){config.y.order=current_nested.totalOrder}this.current_data=current_nested.nested;this.events.onDatatransform.call(this);return{config:mark,data:current_nested.nested,x_dom:x_dom,y_dom:y_dom}}function setColorScale(){var config=this.config;var data=config.legend.behavior==="flex"?this.filtered_data:this.raw_data;var colordom=Array.isArray(config.color_dom)&&config.color_dom.length?config.color_dom.slice():d3.set(data.map(function(m){return m[config.color_by]})).values().filter(function(f){return f&&f!=="undefined"});if(config.legend.order)colordom.sort(function(a,b){return d3.ascending(config.legend.order.indexOf(a),config.legend.order.indexOf(b))});else colordom.sort(naturalSorter);this.colorScale=d3.scale.ordinal().domain(colordom).range(config.colors)}function xScaleAxis(max_range,domain,type){if(max_range===undefined){max_range=this.plot_width}if(domain===undefined){domain=this.x_dom}if(type===undefined){type=this.config.x.type}var config=this.config;var x=void 0;if(type==="log"){x=d3.scale.log()}else if(type==="ordinal"){x=d3.scale.ordinal()}else if(type==="time"){x=d3.time.scale()}else{x=d3.scale.linear()}x.domain(domain);if(type==="ordinal"){x.rangeBands([0,+max_range],config.padding,config.outer_pad)}else{x.range([0,+max_range]).clamp(Boolean(config.x.clamp))}var xFormat=config.x.format?config.x.format:config.marks.map(function(m){return m.summarizeX==="percent"}).indexOf(true)>-1?"0%":type==="time"?"%x":".0f";var tick_count=Math.max(2,Math.min(max_range/80,8));var xAxis=d3.svg.axis().scale(x).orient(config.x.location).ticks(tick_count).tickFormat(type==="ordinal"?null:type==="time"?d3.time.format(xFormat):d3.format(xFormat)).tickValues(config.x.ticks?config.x.ticks:null).innerTickSize(6).outerTickSize(3);this.svg.select("g.x.axis").attr("class","x axis "+type);this.x=x;this.xAxis=xAxis}function yScaleAxis(max_range,domain,type){if(max_range===undefined){max_range=this.plot_height}if(domain===undefined){domain=this.y_dom}if(type===undefined){type=this.config.y.type}var config=this.config;var y=void 0;if(type==="log"){y=d3.scale.log()}else if(type==="ordinal"){y=d3.scale.ordinal()}else if(type==="time"){y=d3.time.scale()}else{y=d3.scale.linear()}y.domain(domain);if(type==="ordinal"){y.rangeBands([+max_range,0],config.padding,config.outer_pad)}else{y.range([+max_range,0]).clamp(Boolean(config.y_clamp))}var yFormat=config.y.format?config.y.format:config.marks.map(function(m){return m.summarizeY==="percent"}).indexOf(true)>-1?"0%":".0f";var tick_count=Math.max(2,Math.min(max_range/80,8));var yAxis=d3.svg.axis().scale(y).orient("left").ticks(tick_count).tickFormat(type==="ordinal"?null:type==="time"?d3.time.format(yFormat):d3.format(yFormat)).tickValues(config.y.ticks?config.y.ticks:null).innerTickSize(6).outerTickSize(3);this.svg.select("g.y.axis").attr("class","y axis "+type);this.y=y;this.yAxis=yAxis}function resize(){var config=this.config;var aspect2=1/config.aspect;var div_width=parseInt(this.wrap.style("width"));var max_width=config.max_width?config.max_width:div_width;var preWidth=!config.resizable?config.width:!max_width||div_width=600){font_size="14px";point_size=4;stroke_width=2}else if(width>450&&width<600){font_size="12px";point_size=3;stroke_width=2}else if(width>300&&width<450){font_size="10px";point_size=2;stroke_width=2}else if(width<=300){font_size="10px";point_size=2;stroke_width=1}this.wrap.style("font-size",font_size);this.config.flex_point_size=point_size;this.config.flex_stroke_width=stroke_width}function setMargins(){var _this=this;var y_ticks=this.yAxis.tickFormat()?this.y.domain().map(function(m){return _this.yAxis.tickFormat()(m)}):this.y.domain();var max_y_text_length=d3.max(y_ticks.map(function(m){return String(m).length}));if(this.config.y_format&&this.config.y_format.indexOf("%")>-1){max_y_text_length+=1}max_y_text_length=Math.max(2,max_y_text_length);var x_label_on=this.config.x.label?1.5:0;var y_label_on=this.config.y.label?1.5:.25;var font_size=parseInt(this.wrap.style("font-size"));var x_second=this.config.x2_interval?1:0;var y_margin=max_y_text_length*font_size*.5+font_size*y_label_on*1.5||8;var x_margin=font_size+font_size/1.5+font_size*x_label_on+font_size*x_second||8;y_margin+=6;x_margin+=3;return{top:this.config.margin&&this.config.margin.top?this.config.margin.top:8,right:this.config.margin&&this.config.margin.right?this.config.margin.right:16,bottom:this.config.margin&&this.config.margin.bottom?this.config.margin.bottom:x_margin,left:this.config.margin&&this.config.margin.left?this.config.margin.left:y_margin}}function drawGridLines(){this.wrap.classed("gridlines",this.config.gridlines);if(this.config.gridlines){this.svg.select(".y.axis").selectAll(".tick line").attr("x1",0);this.svg.select(".x.axis").selectAll(".tick line").attr("y1",0);if(this.config.gridlines==="y"||this.config.gridlines==="xy")this.svg.select(".y.axis").selectAll(".tick line").attr("x1",this.plot_width);if(this.config.gridlines==="x"||this.config.gridlines==="xy")this.svg.select(".x.axis").selectAll(".tick line").attr("y1",-this.plot_height)}else{this.svg.select(".y.axis").selectAll(".tick line").attr("x1",0);this.svg.select(".x.axis").selectAll(".tick line").attr("y1",0)}}function makeLegend(){var scale=arguments.length>0&&arguments[0]!==undefined?arguments[0]:this.colorScale;var label=arguments.length>1&&arguments[1]!==undefined?arguments[1]:"";var custom_data=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;var config=this.config;config.legend.mark=config.legend.mark?config.legend.mark:config.marks.length&&config.marks[0].type==="bar"?"square":config.marks.length?config.marks[0].type:"square";var legend_label=label?label:typeof config.legend.label==="string"?config.legend.label:"";var legendOriginal=this.legend||this.wrap.select(".legend");var legend=legendOriginal;if(!this.parent){if(this.config.legend.location==="top"||this.config.legend.location==="left"){this.wrap.node().insertBefore(legendOriginal.node(),this.svg.node().parentNode)}else{this.wrap.node().appendChild(legendOriginal.node())}}else{if(this.config.legend.location==="top"||this.config.legend.location==="left"){this.parent.wrap.node().insertBefore(legendOriginal.node(),this.parent.wrap.select(".wc-chart").node())}else{this.parent.wrap.node().appendChild(legendOriginal.node())}}legend.style("padding",0);var legend_data=custom_data||scale.domain().slice(0).filter(function(f){return f!==undefined&&f!==null}).map(function(m){return{label:m,mark:config.legend.mark}});legend.select(".legend-title").text(legend_label).style("display",legend_label?"inline":"none").style("margin-right","1em");var leg_parts=legend.selectAll(".legend-item").data(legend_data,function(d){return d.label+d.mark});leg_parts.exit().remove();var legendPartDisplay=this.config.legend.location==="bottom"||this.config.legend.location==="top"?"inline-block":"block" ;var new_parts=leg_parts.enter().append("li").attr("class","legend-item").style({"list-style-type":"none","margin-right":"1em"});new_parts.append("span").attr("class","legend-mark-text").style("color",function(d){return scale(d.label)});new_parts.append("svg").attr("class","legend-color-block").attr("width","1.1em").attr("height","1.1em").style({position:"relative",top:"0.2em"});leg_parts.style("display",legendPartDisplay);if(config.legend.order){leg_parts.sort(function(a,b){return d3.ascending(config.legend.order.indexOf(a.label),config.legend.order.indexOf(b.label))})}leg_parts.selectAll(".legend-color-block").select(".legend-mark").remove();leg_parts.selectAll(".legend-color-block").each(function(e){var svg=d3.select(this);if(e.mark==="circle"){svg.append("circle").attr({cx:".5em",cy:".5em",r:".45em",class:"legend-mark"})}else if(e.mark==="line"){svg.append("line").attr({x1:0,y1:".5em",x2:"1em",y2:".5em","stroke-width":2,"shape-rendering":"crispEdges",class:"legend-mark"})}else if(e.mark==="square"){svg.append("rect").attr({height:"1em",width:"1em",class:"legend-mark","shape-rendering":"crispEdges"})}});leg_parts.selectAll(".legend-color-block").select(".legend-mark").attr("fill",function(d){return d.color||scale(d.label)}).attr("stroke",function(d){return d.color||scale(d.label)}).each(function(e){d3.select(this).attr(e.attributes)});new_parts.append("span").attr("class","legend-label").style("margin-left","0.25em").text(function(d){return d.label});if(scale.domain().length>0){var legendDisplay=(this.config.legend.location==="bottom"||this.config.legend.location==="top")&&!this.parent?"block":"inline-block";legend.style("display",legendDisplay)}else{legend.style("display","none")}this.legend=legend}function updateDataMarks(){this.drawBars(this.marks.filter(function(f){return f.type==="bar"}));this.drawLines(this.marks.filter(function(f){return f.type==="line"}));this.drawPoints(this.marks.filter(function(f){return f.type==="circle"}));this.drawText(this.marks.filter(function(f){return f.type==="text"}));this.marks.supergroups=this.svg.selectAll("g.supergroup")}function drawArea(area_drawer,area_data,datum_accessor){var class_match=arguments.length>3&&arguments[3]!==undefined?arguments[3]:"chart-area";var _this=this;var bind_accessor=arguments[4];var attr_accessor=arguments.length>5&&arguments[5]!==undefined?arguments[5]:function(d){return d};var area_grps=this.svg.selectAll("."+class_match).data(area_data,bind_accessor);area_grps.exit().remove();area_grps.enter().append("g").attr("class",function(d){return class_match+" "+d.key}).append("path");var areaPaths=area_grps.select("path").datum(datum_accessor).attr("fill",function(d){var d_attr=attr_accessor(d);return d_attr?_this.colorScale(d_attr[_this.config.color_by]):null}).attr("fill-opacity",this.config.fill_opacity||this.config.fill_opacity===0?this.config.fill_opacity:.3);var areaPathTransitions=this.config.transitions?areaPaths.transition():areaPaths;areaPathTransitions.attr("d",area_drawer);return area_grps}function drawBars(marks){var _this=this;var chart=this;var rawData=this.raw_data;var config=this.config;var bar_supergroups=this.svg.selectAll(".bar-supergroup").data(marks,function(d,i){return i+"-"+d.per.join("-")});bar_supergroups.enter().append("g").attr("class",function(d){return"supergroup bar-supergroup "+d.id});bar_supergroups.exit().remove();var bar_groups=bar_supergroups.selectAll(".bar-group").data(function(d){return d.data},function(d){return d.key});var old_bar_groups=bar_groups.exit();var nu_bar_groups=void 0;var bars=void 0;var oldBarsTrans=config.transitions?old_bar_groups.selectAll(".bar").transition():old_bar_groups.selectAll(".bar");var oldBarGroupsTrans=config.transitions?old_bar_groups.transition():old_bar_groups;if(config.x.type==="ordinal"){oldBarsTrans.attr("y",this.y(0)).attr("height",0);oldBarGroupsTrans.remove();nu_bar_groups=bar_groups.enter().append("g").attr("class",function(d){return"bar-group "+d.key});nu_bar_groups.append("title");bars=bar_groups.selectAll("rect").data(function(d){return d.values instanceof Array?d.values.sort(function(a,b){return _this.colorScale.domain().indexOf(b.key)-_this.colorScale.domain().indexOf(a.key)}):[d]},function(d){return d.key});var exitBars=config.transitions?bars.exit().transition():bars.exit();exitBars.attr("y",this.y(0)).attr("height",0).remove();bars.enter().append("rect").attr("class",function(d){return"wc-data-mark bar "+d.key}).style("clip-path","url(#"+chart.id+")").attr("y",this.y(0)).attr("height",0).append("title");bars.attr("shape-rendering","crispEdges").attr("stroke",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])});bars.each(function(d){var mark=d3.select(this.parentNode.parentNode).datum();d.tooltip=mark.tooltip;d.arrange=mark.split&&mark.arrange?mark.arrange:mark.split?"grouped":null;d.subcats=config.legend.order?config.legend.order.slice().reverse():mark.values&&mark.values[mark.split]?mark.values[mark.split]:d3.set(rawData.map(function(m){return m[mark.split]})).values();d3.select(this).attr(mark.attributes)});var xformat=config.marks.map(function(m){return m.summarizeX==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.x.format);var yformat=config.marks.map(function(m){return m.summarizeY==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.y.format);bars.select("title").text(function(d){var tt=d.tooltip||"";return tt.replace(/\$x/g,xformat(d.values.x)).replace(/\$y/g,yformat(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});var barsTrans=config.transitions?bars.transition():bars;barsTrans.attr("x",function(d){var position=void 0;if(!d.arrange||d.arrange==="stacked"){return _this.x(d.values.x)}else if(d.arrange==="nested"){var _position=d.subcats.indexOf(d.key);var offset=_position?_this.x.rangeBand()/(d.subcats.length*.75)/_position:_this.x.rangeBand();return _this.x(d.values.x)+(_this.x.rangeBand()-offset)/2}else{position=d.subcats.indexOf(d.key);return _this.x(d.values.x)+_this.x.rangeBand()/d.subcats.length*position}}).attr("y",function(d){if(d.arrange!=="stacked"){return _this.y(d.values.y)}else{return _this.y(d.values.start)}}).attr("width",function(d){if(!d.arrange||d.arrange==="stacked"){return _this.x.rangeBand()}else if(d.arrange==="nested"){var position=d.subcats.indexOf(d.key);return position?_this.x.rangeBand()/(d.subcats.length*.75)/position:_this.x.rangeBand()}else{return _this.x.rangeBand()/d.subcats.length}}).attr("height",function(d){return _this.y(0)-_this.y(d.values.y)})}else if(config.y.type==="ordinal"){oldBarsTrans.attr("x",this.x(0)).attr("width",0);oldBarGroupsTrans.remove();nu_bar_groups=bar_groups.enter().append("g").attr("class",function(d){return"bar-group "+d.key});nu_bar_groups.append("title");bars=bar_groups.selectAll("rect").data(function(d){return d.values instanceof Array?d.values.sort(function(a,b){return _this.colorScale.domain().indexOf(b.key)-_this.colorScale.domain().indexOf(a.key)}):[d]},function(d){return d.key});var _exitBars=config.transitions?bars.exit().transition():bars.exit();_exitBars.attr("x",this.x(0)).attr("width",0).remove();bars.enter().append("rect").attr("class",function(d){return"wc-data-mark bar "+d.key}).style("clip-path","url(#"+chart.id+")").attr("x",this.x(0)).attr("width",0).append("title");bars.attr("shape-rendering","crispEdges").attr("stroke",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])});bars.each(function(d){var mark=d3.select(this.parentNode.parentNode).datum();d.arrange=mark.split&&mark.arrange?mark.arrange:mark.split?"grouped":null;d.subcats=config.legend.order?config.legend.order.slice().reverse():mark.values&&mark.values[mark.split]?mark.values[mark.split]:d3.set(rawData.map(function(m){return m[mark.split]})).values();d.tooltip=mark.tooltip;d3.select(this).attr(mark.attributes)});var _xformat=config.marks.map(function(m){return m.summarizeX==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.x.format);var _yformat=config.marks.map(function(m){return m.summarizeY==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.y.format);bars.select("title").text(function(d){var tt=d.tooltip||"";return tt.replace(/\$x/g,_xformat(d.values.x)).replace(/\$y/g,_yformat(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});var _barsTrans=config.transitions?bars.transition():bars;_barsTrans.attr("x",function(d){if(d.arrange==="stacked"||!d.arrange){return d.values.start!==undefined?_this.x(d.values.start):_this.x(0)}else{return _this.x(0)}}).attr("y",function(d){if(d.arrange==="nested"){var position=d.subcats.indexOf(d.key);var offset=position?_this.y.rangeBand()/(d.subcats.length*.75)/position:_this.y.rangeBand();return _this.y(d.values.y)+(_this.y.rangeBand()-offset)/2}else if(d.arrange==="grouped"){var _position2=d.subcats.indexOf(d.key);return _this.y(d.values.y)+_this.y.rangeBand()/d.subcats.length*_position2}else{return _this.y(d.values.y)}}).attr("width",function(d){return _this.x(d.values.x)-_this.x(0)}).attr("height",function(d){if(config.y.type==="quantile"){return 20}else if(d.arrange==="nested"){var position=d.subcats.indexOf(d.key);return position?_this.y.rangeBand()/(d.subcats.length*.75)/position:_this.y.rangeBand()}else if(d.arrange==="grouped"){return _this.y.rangeBand()/d.subcats.length}else{return _this.y.rangeBand()}})}else if(["linear","log"].indexOf(config.x.type)>-1&&config.x.bin){oldBarsTrans.attr("y",this.y(0)).attr("height",0);oldBarGroupsTrans.remove();nu_bar_groups=bar_groups.enter().append("g").attr("class",function(d){return"bar-group "+d.key});nu_bar_groups.append("title");bars=bar_groups.selectAll("rect").data(function(d){return d.values instanceof Array?d.values:[d]},function(d){return d.key});var _exitBars2=config.transitions?bars.exit().transition():bars.exit();_exitBars2.attr("y",this.y(0)).attr("height",0).remove();bars.enter().append("rect").attr("class",function(d){return"wc-data-mark bar "+d.key}).style("clip-path","url(#"+chart.id+")").attr("y",this.y(0)).attr("height",0).append("title");bars.attr("shape-rendering","crispEdges").attr("stroke",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])});bars.each(function(d){var mark=d3.select(this.parentNode.parentNode).datum();d.arrange=mark.split?mark.arrange:null;d.subcats=config.legend.order?config.legend.order.slice().reverse():mark.values&&mark.values[mark.split]?mark.values[mark.split]:d3.set(rawData.map(function(m){return m[mark.split]})).values();d3.select(this).attr(mark.attributes);var parent=d3.select(this.parentNode).datum();var rangeSet=parent.key.split(",").map(function(m){return+m});d.rangeLow=d3.min(rangeSet);d.rangeHigh=d3.max(rangeSet);d.tooltip=mark.tooltip});var _xformat2=config.marks.map(function(m){return m.summarizeX==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.x.format);var _yformat2=config.marks.map(function(m){return m.summarizeY==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.y.format);bars.select("title").text(function(d){var tt=d.tooltip||"";return tt.replace(/\$x/g,_xformat2(d.values.x)).replace(/\$y/g,_yformat2(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});var _barsTrans2=config.transitions?bars.transition():bars;_barsTrans2.attr("x",function(d){return _this.x(d.rangeLow)}).attr("y",function(d){if(d.arrange!=="stacked"){return _this.y(d.values.y)}else{return _this.y(d.values.start)}}).attr("width",function(d){return _this.x(d.rangeHigh)-_this.x(d.rangeLow)}).attr("height",function(d){return _this.y(0)-_this.y(d.values.y)})}else if(["linear","log"].indexOf(config.y.type)>-1&&config.y.type==="linear"&&config.y.bin){oldBarsTrans.attr("x",this.x(0)).attr("width",0);oldBarGroupsTrans.remove();nu_bar_groups=bar_groups.enter().append("g").attr("class",function(d){return"bar-group "+d.key});nu_bar_groups.append("title");bars=bar_groups.selectAll("rect").data(function(d){return d.values instanceof Array?d.values:[d]},function(d){return d.key});var _exitBars3=config.transitions?bars.exit().transition():bars.exit();_exitBars3.attr("x",this.x(0)).attr("width",0).remove();bars.enter().append("rect").attr("class",function(d){return"wc-data-mark bar "+d.key}).style("clip-path","url(#"+chart.id+")").attr("x",this.x(0)).attr("width",0).append("title");bars.attr("shape-rendering","crispEdges").attr("stroke",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])});bars.each(function(d){var mark=d3.select(this.parentNode.parentNode).datum();d.arrange=mark.split?mark.arrange:null;d.subcats=config.legend.order?config.legend.order.slice().reverse():mark.values&&mark.values[mark.split]?mark.values[mark.split]:d3.set(rawData.map(function(m){return m[mark.split]})).values();var parent=d3.select(this.parentNode).datum();var rangeSet=parent.key.split(",").map(function(m){return+m});d.rangeLow=d3.min(rangeSet);d.rangeHigh=d3.max(rangeSet);d.tooltip=mark.tooltip});var _xformat3=config.marks.map(function(m){return m.summarizeX==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.x.format);var _yformat3=config.marks.map(function(m){return m.summarizeY==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.y.format);bars.select("title").text(function(d){var tt=d.tooltip||"";return tt.replace(/\$x/g,_xformat3(d.values.x)).replace(/\$y/g,_yformat3(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});var _barsTrans3=config.transitions?bars.transition():bars;_barsTrans3.attr("x",function(d){if(d.arrange==="stacked"){return _this.x(d.values.start)}else{return _this.x(0)}}).attr("y",function(d){return _this.y(d.rangeHigh)}).attr("width",function(d){return _this.x(d.values.x)}).attr("height",function(d){return _this.y(d.rangeLow)-_this.y(d.rangeHigh)})}else{oldBarsTrans.attr("y",this.y(0)).attr("height",0);oldBarGroupsTrans.remove();bar_supergroups.remove()}bar_supergroups.each(function(d){d.supergroup=d3.select(this);d.groups=d.supergroup.selectAll(".bar-group")})}function drawLines(marks){var _this=this;var chart=this;var config=this.config;var line=d3.svg.line().interpolate(config.interpolate).x(function(d){return config.x.type==="linear"||config.x.type=="log"?_this.x(+d.values.x):config.x.type==="time"?_this.x(new Date(d.values.x)):_this.x(d.values.x)+_this.x.rangeBand()/2}).y(function(d){return config.y.type==="linear"||config.y.type=="log"?_this.y(+d.values.y):config.y.type==="time"?_this.y(new Date(d.values.y)):_this.y(d.values.y)+_this.y.rangeBand()/2});var line_supergroups=this.svg.selectAll(".line-supergroup").data(marks,function(d,i){return i+"-"+d.per.join("-")});line_supergroups.enter().append("g").attr("class",function(d){return"supergroup line-supergroup "+d.id});line_supergroups.exit().remove();var line_grps=line_supergroups.selectAll(".line").data(function(d){return d.data},function(d){return d.key});line_grps.exit().remove();var nu_line_grps=line_grps.enter().append("g").attr("class",function(d){return d.key+" line"});nu_line_grps.append("path");nu_line_grps.append("title");var linePaths=line_grps.select("path").attr("class","wc-data-mark").style("clip-path","url(#"+chart.id+")").datum(function(d){return d.values}).attr("stroke",function(d){return _this.colorScale(d[0].values.raw[0][config.color_by])}).attr("stroke-width",config.stroke_width?config.stroke_width:config.flex_stroke_width).attr("stroke-linecap","round").attr("fill","none");var linePathsTrans=config.transitions?linePaths.transition():linePaths;linePathsTrans.attr("d",line);line_grps.each(function(d){var mark=d3.select(this.parentNode).datum();d.tooltip=mark.tooltip;d3.select(this).select("path").attr(mark.attributes)});line_grps.select("title").text(function(d){var tt=d.tooltip||"";var xformat=config.x.summary==="percent"?d3.format("0%"):d3.format(config.x.format);var yformat=config.y.summary==="percent"?d3.format("0%"):d3.format(config.y.format);return tt.replace(/\$x/g,xformat(d.values.x)).replace(/\$y/g,yformat(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values[0].values.raw[0][orig]})});line_supergroups.each(function(d){d.supergroup=d3.select(this);d.groups=d.supergroup.selectAll("g.line");d.paths=d.groups.select("path")});return line_grps}function drawPoints(marks){var _this=this;var chart=this;var config=this.config;var point_supergroups=this.svg.selectAll(".point-supergroup").data(marks,function(d,i){return i+"-"+d.per.join("-")});point_supergroups.enter().append("g").attr("class",function(d){return"supergroup point-supergroup "+d.id});point_supergroups.exit().remove();var points=point_supergroups.selectAll(".point").data(function(d){return d.data},function(d){return d.key});var oldPoints=points.exit();var oldPointsTrans=config.transitions?oldPoints.selectAll("circle").transition():oldPoints.selectAll("circle");oldPointsTrans.attr("r",0);var oldPointGroupTrans=config.transitions?oldPoints.transition():oldPoints;oldPointGroupTrans.remove();var nupoints=points.enter().append("g").attr("class",function(d){return d.key+" point"});nupoints.append("circle").attr("class","wc-data-mark").attr("r",0);nupoints.append("title");points.select("circle").style("clip-path","url(#"+chart.id+")").attr("fill-opacity",config.fill_opacity||config.fill_opacity===0?config.fill_opacity:.6).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).attr("stroke",function(d){return _this.colorScale(d.values.raw[0][config.color_by])});points.each(function(d){var mark=d3.select(this.parentNode).datum();d.mark=mark;d3.select(this).select("circle").attr(mark.attributes)});var pointsTrans=config.transitions?points.select("circle").transition():points.select("circle");pointsTrans.attr("r",function(d){return d.mark.radius||config.flex_point_size}).attr("cx",function(d){var x_pos=_this.x(d.values.x)||0;return config.x.type==="ordinal"?x_pos+_this.x.rangeBand()/2:x_pos}).attr("cy",function(d){var y_pos=_this.y(d.values.y)||0;return config.y.type==="ordinal"?y_pos+_this.y.rangeBand()/2:y_pos});points.select("title").text(function(d){var tt=d.mark.tooltip||"";var xformat=config.x.summary==="percent"?d3.format("0%"):config.x.type==="time"?d3.time.format(config.x.format):d3.format(config.x.format);var yformat=config.y.summary==="percent"?d3.format("0%"):config.y.type==="time"?d3.time.format(config.y.format):d3.format(config.y.format);return tt.replace(/\$x/g,config.x.type==="time"?xformat(new Date(d.values.x)):xformat(d.values.x)).replace(/\$y/g,config.y.type==="time"?yformat(new Date(d.values.y)):yformat(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});point_supergroups.each(function(d){d.supergroup=d3.select(this);d.groups=d.supergroup.selectAll("g.point");d.circles=d.groups.select("circle")});return points}function drawText(marks){var _this=this;var chart=this;var config=this.config;var textSupergroups=this.svg.selectAll(".text-supergroup").data(marks,function(d,i){return i+"-"+d.per.join("-")});textSupergroups.enter().append("g").attr("class",function(d){return"supergroup text-supergroup "+d.id});textSupergroups.exit().remove();var texts=textSupergroups.selectAll(".text").data(function(d){return d.data},function(d){return d.key});var oldTexts=texts.exit();var oldTextGroupTrans=config.transitions?oldTexts.transition():oldTexts;oldTextGroupTrans.remove();var nutexts=texts.enter().append("g").attr("class",function(d){return d.key+" text"});nutexts.append("text").attr("class","wc-data-mark");function attachMarks(d){d.mark=d3.select(this.parentNode).datum();d3.select(this).select("text").attr(d.mark.attributes)}texts.each(attachMarks);texts.select("text").style("clip-path","url(#"+chart.id+")").text(function(d){var tt=d.mark.text||"";var xformat=config.x.summary==="percent"?d3.format("0%"):config.x.type==="time"?d3.time.format(config.x.format):d3.format(config.x.format);var yformat=config.y.summary==="percent"?d3.format("0%"):config.y.type==="time"?d3.time.format(config.y.format):d3.format(config.y.format);return tt.replace(/\$x/g,config.x.type==="time"?xformat(new Date(d.values.x)):xformat(d.values.x)).replace(/\$y/g,config.y.type==="time"?yformat(new Date(d.values.y)):yformat(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});var textsTrans=config.transitions?texts.select("text").transition():texts.select("text");textsTrans.attr("x",function(d){var xPos=_this.x(d.values.x)||0;return config.x.type==="ordinal"?xPos+_this.x.rangeBand()/2:xPos}).attr("y",function(d){var yPos=_this.y(d.values.y)||0;return config.y.type==="ordinal"?yPos+_this.y.rangeBand()/2:yPos});textSupergroups.each(function(d){d.supergroup=d3.select(this);d.groups=d.supergroup.selectAll("g.text");d.texts=d.groups.select("text")});return texts}function destroy(){var destroyControls=arguments.length>0&&arguments[0]!==undefined?arguments[0]:true;this.events.onDestroy.call(this);var context=this;d3.select(window).on("resize."+context.element+context.id,null);if(destroyControls&&this.controls){this.controls.destroy()}this.wrap.remove()}var chartProto={raw_data:[],config:{}};var chart=Object.create(chartProto,{checkRequired:{value:checkRequired},consolidateData:{value:consolidateData},draw:{value:draw},destroy:{value:destroy},drawArea:{value:drawArea},drawBars:{value:drawBars},drawGridlines:{value:drawGridLines},drawLines:{value:drawLines},drawPoints:{value:drawPoints},drawText:{value:drawText},init:{value:init},layout:{value:layout},makeLegend:{value:makeLegend},resize:{value:resize},setColorScale:{value:setColorScale},setDefaults:{value:setDefaults},setMargins:{value:setMargins},textSize:{value:textSize},transformData:{value:transformData},updateDataMarks:{value:updateDataMarks},xScaleAxis:{value:xScaleAxis},yScaleAxis:{value:yScaleAxis}});var chartCount=0;function createChart(){var element=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"body";var config=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var controls=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;var thisChart=Object.create(chart);thisChart.div=element;thisChart.config=Object.create(config);thisChart.controls=controls;thisChart.raw_data=[];thisChart.filters=[];thisChart.marks=[];thisChart.wrap=d3.select(thisChart.div).append("div").datum(thisChart);thisChart.events={onInit:function onInit(){},onLayout:function onLayout(){},onPreprocess:function onPreprocess(){},onDatatransform:function onDatatransform(){},onDraw:function onDraw(){},onResize:function onResize(){},onDestroy:function onDestroy(){}};thisChart.on=function(event,callback){var possible_events=["init","layout","preprocess","datatransform","draw","resize","destroy"];if(possible_events.indexOf(event)<0){return}if(callback){thisChart.events["on"+event.charAt(0).toUpperCase()+event.slice(1)]=callback}};chartCount++;thisChart.id=chartCount;return thisChart}function changeOption(option,value,callback,draw){var _this=this;this.targets.forEach(function(target){if(option instanceof Array){option.forEach(function(o){return _this.stringAccessor(target.config,o,value)})}else{_this.stringAccessor(target.config,option,value)}if(callback){callback()}if(draw)target.draw()})}function checkRequired$1(dataset){if(!dataset[0]||!this.config.inputs)return;var colNames=d3.keys(dataset[0]);this.config.inputs.forEach(function(input,i){if(input.type==="subsetter"&&colNames.indexOf(input.value_col)===-1)throw new Error('Error in settings object: the value "'+input.value_col+'" does not match any column in the provided dataset.');input.draw=input.draw===undefined?true:input.draw})}function controlUpdate(){var _this=this;if(this.config.inputs&&this.config.inputs.length&&this.config.inputs[0])this.config.inputs.forEach(function(input){return _this.makeControlItem(input)})}function destroy$1(){this.wrap.remove()}function init$1(data){this.data=data;if(!this.config.builder)this.checkRequired(this.data);this.layout()}function layout$1(){this.wrap.selectAll("*").remove();this.ready=true;this.controlUpdate()}function makeControlItem(control){var control_wrap=this.wrap.append("div").attr("class","control-group").classed("inline",control.inline).datum(control);var ctrl_label=control_wrap.append("span").attr("class","wc-control-label").text(control.label);if(control.required)ctrl_label.append("span").attr("class","label label-required").text("Required");control_wrap.append("span").attr("class","span-description").text(control.description);if(control.type==="text"){this.makeTextControl(control,control_wrap)}else if(control.type==="number"){this.makeNumberControl(control,control_wrap)}else if(control.type==="list"){this.makeListControl(control,control_wrap)}else if(control.type==="dropdown"){this.makeDropdownControl(control,control_wrap)}else if(control.type==="btngroup"){this.makeBtnGroupControl(control,control_wrap)}else if(control.type==="checkbox"){this.makeCheckboxControl(control,control_wrap)}else if(control.type==="radio"){this.makeRadioControl(control,control_wrap)}else if(control.type==="subsetter"){this.makeSubsetterControl(control,control_wrap)}else{throw new Error('Each control must have a type! Choose from: "text", "number", "list", "dropdown", "btngroup", "checkbox", "radio", or "subsetter".')}}function makeBtnGroupControl(control,control_wrap){var _this=this;var option_data=control.values?control.values:d3.keys(this.data[0]);var btn_wrap=control_wrap.append("div").attr("class","btn-group");var changers=btn_wrap.selectAll("button").data(option_data).enter().append("button").attr("class","btn btn-default btn-sm").text(function(d){return d}).classed("btn-primary",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)===d});changers.on("click",function(d){changers.each(function(e){d3.select(this).classed("btn-primary",e===d)});_this.changeOption(control.option,d,control.callback,control.draw)})}function makeCheckboxControl(control,control_wrap){var _this=this;var changer=control_wrap.append("input").attr("type","checkbox").attr("class","changer").datum(control).property("checked",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)});changer.on("change",function(d){var value=changer.property("checked");_this.changeOption(d.option,value,control.callback,control.draw)})}function makeDropdownControl(control,control_wrap){var _this=this;var mainOption=control.option||control.options[0];var changer=control_wrap.append("select").attr("class","changer").attr("multiple",control.multiple?true:null).datum(control);var opt_values=control.values&&control.values instanceof Array?control.values:control.values?d3.set(this.data.map(function(m){return m[_this.targets[0].config[control.values]]})).values():d3.keys(this.data[0]);if(!control.require||control.none){opt_values.unshift("None")}var options=changer.selectAll("option").data(opt_values).enter().append("option").text(function(d){return d}).property("selected",function(d){return _this.stringAccessor(_this.targets[0].config,mainOption)===d});changer.on("change",function(d){var value=changer.property("value")==="None"?null:changer.property("value");if(control.multiple){value=options.filter(function(f){return d3.select(this).property("selected")})[0].map(function(m){return d3.select(m).property("value")}).filter(function(f){return f!=="None"})}if(control.options){_this.changeOption(control.options,value,control.callback,control.draw)}else{_this.changeOption(control.option,value,control.callback,control.draw)}});return changer}function makeListControl(control,control_wrap){var _this=this;var changer=control_wrap.append("input").attr("type","text").attr("class","changer").datum(control).property("value",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)});changer.on("change",function(d){var value=changer.property("value")?changer.property("value").split(",").map(function(m){return m.trim()}):null;_this.changeOption(control.option,value,control.callback,control.draw)})}function makeNumberControl(control,control_wrap){var _this=this;var changer=control_wrap.append("input").attr("type","number").attr("min",control.min!==undefined?control.min:0).attr("max",control.max).attr("step",control.step||1).attr("class","changer").datum(control).property("value",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)});changer.on("change",function(d){var value=+changer.property("value");_this.changeOption(control.option,value,control.callback,control.draw)})}function makeRadioControl(control,control_wrap){var _this=this;var changers=control_wrap.selectAll("label").data(control.values||d3.keys(this.data[0])).enter().append("label").attr("class","radio").text(function(d,i){return control.relabels?control.relabels[i]:d}).append("input").attr("type","radio").attr("class","changer").attr("name",control.option.replace(".","-")+"-"+this.targets[0].id).property("value",function(d){return d}).property("checked",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)===d});changers.on("change",function(d){var value=null;changers.each(function(c){if(d3.select(this).property("checked")){value=d3.select(this).property("value")==="none"?null:c}});_this.changeOption(control.option,value,control.callback,control.draw)})}function makeSubsetterControl(control,control_wrap){var targets=this.targets;var changer=control_wrap.append("select").classed("changer",true).attr("multiple",control.multiple?true:null).datum(control);var option_data=control.values?control.values:d3.set(this.data.map(function(m){return m[control.value_col]}).filter(function(f){return f})).values().sort(naturalSorter);control.start=control.start?control.start:control.loose?option_data[0]:null;if(!control.multiple&&!control.start){option_data.unshift("All");control.all=true}else{control.all=false}control.loose=!control.loose&&control.start?true:control.loose;var options=changer.selectAll("option").data(option_data).enter().append("option").text(function(d){return d}).property("selected",function(d){return d===control.start});targets.forEach(function(e){var match=e.filters.slice().map(function(m){return m.col===control.value_col}).indexOf(true);if(match>-1){e.filters[match]={col:control.value_col,val:control.start?control.start:!control.multiple?"All":option_data,index:0,choices:option_data,loose:control.loose,all:control.all}}else{e.filters.push({col:control.value_col,val:control.start?control.start:!control.multiple?"All":option_data,index:0,choices:option_data,loose:control.loose,all:control.all})}});function setSubsetter(target,obj){var match=-1;target.filters.forEach(function(e,i){if(e.col===obj.col){match=i}});if(match>-1){target.filters[match]=obj}}changer.on("change",function(d){if(control.multiple){var values=options.filter(function(f){return d3.select(this).property("selected")})[0].map(function(m){return d3.select(m).property("text")});var new_filter={col:control.value_col,val:values,index:null,choices:option_data,loose:control.loose,all:control.all};targets.forEach(function(e){setSubsetter(e,new_filter);if(control.callback){control.callback()}if(control.draw)e.draw()})}else{var value=d3.select(this).select("option:checked").property("text");var index=d3.select(this).select("option:checked").property("index");var _new_filter={col:control.value_col,val:value,index:index,choices:option_data,loose:control.loose,all:control.all};targets.forEach(function(e){setSubsetter(e,_new_filter);if(control.callback){control.callback()}e.draw()})}})}function makeTextControl(control,control_wrap){var _this=this ;var changer=control_wrap.append("input").attr("type","text").attr("class","changer").datum(control).property("value",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)});changer.on("change",function(d){var value=changer.property("value");_this.changeOption(control.option,value,control.callback,control.draw)})}function stringAccessor(o,s,v){s=s.replace(/\[(\w+)\]/g,".$1");s=s.replace(/^\./,"");var a=s.split(".");for(var i=0,n=a.length;i0&&arguments[0]!==undefined?arguments[0]:"body";var config=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var thisControls=Object.create(controls);thisControls.div=element;thisControls.config=Object.create(config);thisControls.config.inputs=thisControls.config.inputs||[];thisControls.targets=[];if(config.location==="bottom"){thisControls.wrap=d3.select(element).append("div").attr("class","wc-controls")}else{thisControls.wrap=d3.select(element).insert("div",":first-child").attr("class","wc-controls")}thisControls.wrap.datum(thisControls);return thisControls}function applyFilters(){var _this=this;if(this.filters&&this.filters.some(function(filter){return typeof filter.val==="string"&&!(filter.all===true&&filter.index===0)||Array.isArray(filter.val)&&filter.val.length-1:filter.val===d[filter.col]})})}else this.data.filtered=this.data.raw}function updateDataObject(){this.data.raw=this.data.passed;this.data.filtered=this.data.passed;this.config.activePage=0;this.config.startIndex=this.config.activePage*this.config.nRowsPerPage;this.config.endIndex=this.config.startIndex+this.config.nRowsPerPage}function applySearchTerm(data){var _this=this;if(this.searchable.searchTerm){this.data.searched=this.data.filtered.filter(function(d){var match=false;Object.keys(d).filter(function(key){return _this.config.cols.indexOf(key)>-1}).forEach(function(var_name){if(match===false){var cellText=""+d[var_name];match=cellText.toLowerCase().indexOf(_this.searchable.searchTerm)>-1}});return match});this.data.processing=this.data.searched}else{delete this.data.searched;this.data.processing=this.data.filtered}}if(Array.prototype.equals)console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code.");Array.prototype.equals=function(array){if(!array)return false;if(this.length!=array.length)return false;for(var i=0,l=this.length;i=Math.max(widths.top,widths.bottom)&&this.config.layout==="vertical"){this.config.layout="horizontal";this.wrap.style("display","table").selectAll(".table-top,.table-bottom").style("display","block").selectAll(".interactivity").style({display:"inline-block",float:function float(){return d3.select(this).classed("searchable-container")||d3.select(this).classed("pagination-container")?"right":null},clear:null})}}function draw$1(passed_data){var _this=this;var table=this;var config=this.config;this.data.passed=passed_data;this.events.onPreprocess.call(this);if(!passed_data)applyFilters.call(this);else updateDataObject.call(this);checkFilters.call(this);applySearchTerm.call(this);this.searchable.wrap.select(".nNrecords").text(this.data.processing.length===this.data.raw.length?this.data.raw.length+" records displayed":this.data.processing.length+"/"+this.data.raw.length+" records displayed");updateTableHeaders.call(this);this.tbody.selectAll("tr").remove();if(this.data.processing.length===0){this.tbody.append("tr").classed("no-data",true).append("td").attr("colspan",this.config.cols.length).text("No data selected.");this.data.current=this.data.processing;this.table.datum(this.table.current);if(this.config.exportable)this.config.exports.forEach(function(fmt){_this.exportable.exports[fmt].call(_this,_this.data.processing)});if(this.config.pagination)this.pagination.addPagination.call(this,this.data.processing)}else{if(this.config.sortable){this.thead.selectAll("th").on("click",function(header){table.sortable.onClick.call(table,this,header)});if(this.sortable.order.length)this.sortable.sortData.call(this,this.data.processing)}this.data.current=this.data.processing;this.table.datum(this.data.current);if(this.config.exportable)this.config.exports.forEach(function(fmt){_this.exportable.exports[fmt].call(_this,_this.data.processing)});if(this.config.pagination){this.pagination.addPagination.call(this,this.data.processing);this.data.processing=this.data.processing.filter(function(d,i){return _this.config.startIndex<=i&&i<_this.config.endIndex})}drawTableBody.call(this)}if(this.config.dynamicPositioning){dynamicLayout.call(this)}this.events.onDraw.call(this)}function layout$2(){var context=this;this.searchable.wrap=this.wrap.select(".table-top").append("div").classed("interactivity searchable-container",true).classed("hidden",!this.config.searchable);this.searchable.wrap.append("div").classed("search",true);this.searchable.wrap.select(".search").append("input").classed("search-box",true).attr("placeholder","Search").on("input",function(){context.searchable.searchTerm=this.value.toLowerCase()||null;context.config.activePage=0;context.config.startIndex=context.config.activePage*context.config.nRowsPerPage;context.config.endIndex=context.config.startIndex+context.config.nRowsPerPage;context.draw()});this.searchable.wrap.select(".search").append("span").classed("nNrecords",true)}function searchable(){return{layout:layout$2}}function layout$3(){var _this=this;this.exportable.wrap=this.wrap.select(".table-bottom").append("div").classed("interactivity exportable-container",true).classed("hidden",!this.config.exportable);this.exportable.wrap.append("span").text("Export:");if(this.config.exports&&this.config.exports.length)this.config.exports.forEach(function(fmt){_this.exportable.wrap.append("a").classed("wc-button export",true).attr({id:fmt}).style(!_this.test&&navigator.msSaveBlob?{cursor:"pointer","text-decoration":"underline",color:"blue"}:null).text(fmt.toUpperCase())})}function download(fileType,data){var blob=new Blob(data,{type:fileType==="csv"?"text/csv;charset=utf-8;":fileType==="xlsx"?"application/octet-stream":console.warn("File type not supported: "+fileType)});var fileName="webchartsTableExport_"+d3.time.format("%Y-%m-%dT%H-%M-%S")(new Date)+"."+fileType;var link=this.wrap.select(".export#"+fileType);if(navigator.msSaveBlob)navigator.msSaveBlob(blob,fileName);else if(link.node().download!==undefined){var url=URL.createObjectURL(blob);link.node().setAttribute("href",url);link.node().setAttribute("download",fileName)}}function csv(data){var _this=this;this.wrap.select(".export#csv").on("click",function(){var CSVarray=[];var headers=_this.config.headers.map(function(header){return'"'+header.replace(/"/g,'""')+'"'});CSVarray.push(headers);data.forEach(function(d,i){var row=_this.config.cols.map(function(col){var value=d[col];if(typeof value==="string")value=value.replace(/"/g,'""');return'"'+value+'"'});CSVarray.push(row)});download.call(_this,"csv",[CSVarray.join("\n")])})}function xlsx(data){var _this=this;this.wrap.select(".export#xlsx").on("click",function(){var sheetName="Selected Data";var options={bookType:"xlsx",bookSST:true,type:"binary"};var arrayOfArrays=data.map(function(d){return Object.keys(d).filter(function(key){return _this.config.cols.indexOf(key)>-1}).map(function(key){return d[key]})});var workbook={SheetNames:[sheetName],Sheets:{}};var cols=[];workbook.Sheets[sheetName]=XLSX.utils.aoa_to_sheet([_this.config.headers].concat(arrayOfArrays));workbook.Sheets[sheetName]["!autofilter"]={ref:"A1:"+String.fromCharCode(64+_this.config.cols.length)+(data.length+1)};_this.table.selectAll("thead tr th").each(function(){cols.push({wpx:this.offsetWidth})});workbook.Sheets[sheetName]["!cols"]=cols;var xlsx=XLSX.write(workbook,options);var s2ab=function s2ab(s){var buffer=new ArrayBuffer(s.length),view=new Uint8Array(buffer);for(var i=0;i!==s.length;++i){view[i]=s.charCodeAt(i)&255}return buffer};download.call(_this,"xlsx",[s2ab(xlsx)])})}var exports$1={csv:csv,xlsx:xlsx};function exportable(){return{layout:layout$3,exports:exports$1}}function layout$4(){this.sortable.wrap=this.wrap.select(".table-top").append("div").classed("interactivity sortable-container",true).classed("hidden",!this.config.sortable);this.sortable.wrap.append("div").classed("instruction",true).text("Click column headers to sort.")}function onClick(th,header){var context=this,selection=d3.select(th),col=this.config.cols[this.config.headers.indexOf(header)];var sortItem=this.sortable.order.filter(function(item){return item.col===col})[0];if(!sortItem){sortItem={col:col,direction:"ascending",wrap:this.sortable.wrap.append("div").datum({key:col}).classed("wc-button sort-box",true).text(header)};sortItem.wrap.append("span").classed("sort-direction",true).html("↓");sortItem.wrap.append("span").classed("remove-sort",true).html("❌");this.sortable.order.push(sortItem)}else{sortItem.direction=sortItem.direction==="ascending"?"descending":"ascending";sortItem.wrap.select("span.sort-direction").html(sortItem.direction==="ascending"?"↓":"↑")}this.sortable.wrap.select(".instruction").classed("hidden",true);this.sortable.order.forEach(function(item,i){item.wrap.on("click",function(d){d3.select(this).remove();context.sortable.order.splice(context.sortable.order.map(function(d){return d.col}).indexOf(d.key),1);context.sortable.wrap.select(".instruction").classed("hidden",context.sortable.order.length);context.draw()})});this.draw()}function sortData(data){var _this=this;data=data.sort(function(a,b){var order=0;_this.sortable.order.forEach(function(item){var aCell=a[item.col],bCell=b[item.col];if(order===0){if(item.direction==="ascending"&&aCellbCell)order=-1;else if(item.direction==="ascending"&&aCell>bCell||item.direction==="descending"&&aCell=_this.config.nPageLinksDisplayed:_this.config.activePage>=_this.config.nPages-_this.config.nPageLinksDisplayed?i<_this.config.nPages-_this.config.nPageLinksDisplayed:i<_this.config.activePage-(Math.ceil(_this.config.nPageLinksDisplayed/2)-1)||_this.config.activePage+_this.config.nPageLinksDisplayed/2=this.config.nPages)next=this.config.nPages-1;this.pagination.wrap.insert("span",":first-child").classed("dot-dot-dot",true).text("...").classed("hidden",this.config.activePage=Math.max(this.config.nPageLinksDisplayed,this.config.nPages-this.config.nPageLinksDisplayed)||this.config.nPages<=this.config.nPageLinksDisplayed);this.pagination.next=this.pagination.wrap.append("a").classed("wc-button arrow-link wc-right",true).classed("hidden",this.config.activePage==this.config.nPages-1||this.config.nPages==0).attr({rel:next}).text(">");this.pagination.doubleNext=this.pagination.wrap.append("a").classed("wc-button arrow-link wc-right double",true).classed("hidden",this.config.activePage==this.config.nPages-1||this.config.nPages==0).attr({rel:this.config.nPages-1}).text(">>");this.pagination.arrows=this.pagination.wrap.selectAll("a.arrow-link");this.pagination.doubleArrows=this.pagination.wrap.selectAll("a.double-arrow-link")}function addPagination(data){var context=this;this.config.nRows=data.length;this.config.nPages=Math.ceil(this.config.nRows/this.config.nRowsPerPage);this.config.paginationHidden=this.config.nPages===1;this.pagination.wrap.classed("hidden",this.config.paginationHidden);addLinks.call(this);this.pagination.links.on("click",function(){context.config.activePage=+d3.select(this).attr("rel");updatePagination.call(context)});addArrows.call(this);this.pagination.arrows.on("click",function(){if(context.config.activePage!==+d3.select(this).attr("rel")){context.config.activePage=+d3.select(this).attr("rel");context.pagination.prev.attr("rel",context.config.activePage>0?context.config.activePage-1:0);context.pagination.next.attr("rel",context.config.activePage1&&arguments[1]!==undefined?arguments[1]:false;this.test=test;if(d3.select(this.div).select(".loader").empty()){d3.select(this.div).insert("div",":first-child").attr("class","loader").selectAll(".blockG").data(d3.range(8)).enter().append("div").attr("class",function(d){return"blockG rotate"+(d+1)})}this.setDefaults.call(this,data[0]);this.wrap.classed("wc-chart",true).classed("wc-table",this.config.applyCSS);this.data={raw:data};this.searchable=searchable.call(this);this.sortable=sortable.call(this);this.pagination=pagination.call(this);this.exportable=exportable.call(this);var startup=function startup(data){if(_this.controls){_this.controls.targets.push(_this);if(!_this.controls.ready){_this.controls.init(_this.data.raw)}else{_this.controls.layout()}}var visible=d3.select(_this.div).property("offsetWidth")>0||test;if(!visible){console.warn("The table cannot be initialized inside an element with 0 width. The table will be initialized as soon as the container element is given a width > 0.");var onVisible=setInterval(function(i){var visible_now=d3.select(_this.div).property("offsetWidth")>0;if(visible_now){_this.layout();_this.wrap.datum(_this);_this.draw();clearInterval(onVisible)}},500)}else{_this.layout();_this.wrap.datum(_this);_this.draw()}};this.events.onInit.call(this);if(this.data.raw.length){this.checkRequired(this.data.raw)}startup(data);return this}function layout$6(){d3.select(this.div).select(".loader").remove();this.wrap.append("div").classed("table-top",true);this.searchable.layout.call(this);this.sortable.layout.call(this);this.table=this.wrap.append("table").classed("table",this.config.bootstrap);this.thead=this.table.append("thead");this.thead.append("tr");this.tbody=this.table.append("tbody");this.wrap.append("div").classed("table-bottom",true);this.pagination.layout.call(this);this.exportable.layout.call(this);this.events.onLayout.call(this)}function destroy$2(){var destroyControls=arguments.length>0&&arguments[0]!==undefined?arguments[0]:false;this.events.onDestroy.call(this);if(destroyControls&&this.controls){this.controls.destroy()}this.wrap.remove()}function setDefault(setting){var _default_=arguments.length>1&&arguments[1]!==undefined?arguments[1]:true;this.config[setting]=this.config[setting]!==undefined?this.config[setting]:_default_}function setDefaults$1(firstItem){if(this.config.cols instanceof Array&&this.config.headers instanceof Array){if(this.config.cols.length===0)delete this.config.cols;if(this.config.headers.length===0||this.config.headers.length!==this.config.cols.length)delete this.config.headers}this.config.cols=this.config.cols||d3.keys(firstItem);this.config.headers=this.config.headers||this.config.cols;this.config.layout="horizontal";setDefault.call(this,"searchable");setDefault.call(this,"exportable");setDefault.call(this,"exports",["csv"]);setDefault.call(this,"sortable");setDefault.call(this,"pagination");setDefault.call(this,"nRowsPerPage",10);setDefault.call(this,"nPageLinksDisplayed",5);setDefault.call(this,"applyCSS");setDefault.call(this,"dynamicPositioning")}function transformData$1(processed_data){var _this=this;this.data.processed=this.transformData(this.wrap.datum);if(!data){return}this.config.cols=this.config.cols||d3.keys(data[0]);this.config.headers=this.config.headers||this.config.cols;if(this.config.keep){this.config.keep.forEach(function(e){if(_this.config.cols.indexOf(e)===-1){_this.config.cols.unshift(e)}})}var filtered=data;if(this.filters.length){this.filters.forEach(function(e){var is_array=e.val instanceof Array;filtered=filtered.filter(function(d){if(is_array){return e.val.indexOf(d[e.col])!==-1}else{return e.val!=="All"?d[e.col]===e.val:d}})})}var slimmed=d3.nest().key(function(d){if(_this.config.row_per){return _this.config.row_per.map(function(m){return d[m]}).join(" ")}else{return d}}).rollup(function(r){if(_this.config.dataManipulate){r=_this.config.dataManipulate(r)}var nuarr=r.map(function(m){var arr=[];for(var x in m){arr.push({col:x,text:m[x]})}arr.sort(function(a,b){return _this.config.cols.indexOf(a.col)-_this.config.cols.indexOf(b.col)});return{cells:arr,raw:m}});return nuarr}).entries(filtered);this.data.current=slimmed.length?slimmed:[{key:null,values:[]}];this.pagination.wrap.selectAll("*").remove();this.events.onDatatransform.call(this);if(config.row_per){var rev_order=config.row_per.slice(0).reverse();rev_order.forEach(function(e){tbodies.sort(function(a,b){return a.values[0].raw[e]-b.values[0].raw[e]})})}if(config.row_per){rows.filter(function(f,i){return i>0}).selectAll("td").filter(function(f){return config.row_per.indexOf(f.col)>-1}).text("")}return this.data.current}var table=Object.create(chart,{draw:{value:draw$1},init:{value:init$2},layout:{value:layout$6},setDefaults:{value:setDefaults$1},transformData:{value:transformData$1},destroy:{value:destroy$2}});function createTable(){var element=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"body";var config=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var controls=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;var thisTable=Object.create(table);thisTable.div=element;thisTable.config=Object.create(config);thisTable.controls=controls;thisTable.filters=[];thisTable.required_cols=[];thisTable.wrap=d3.select(thisTable.div).append("div").datum(thisTable);thisTable.events={onInit:function onInit(){},onLayout:function onLayout(){},onPreprocess:function onPreprocess(){},onDraw:function onDraw(){},onDestroy:function onDestroy(){}};thisTable.on=function(event,callback){var possible_events=["init","layout","preprocess","draw","destroy"];if(possible_events.indexOf(event)<0){return}if(callback){thisTable.events["on"+event.charAt(0).toUpperCase()+event.slice(1)]=callback}};return thisTable}function multiply(chart,data,split_by,order){var test=arguments.length>4&&arguments[4]!==undefined?arguments[4]:false;chart.wrap.classed("wc-layout wc-small-multiples",true).classed("wc-chart",false);chart.master_legend=chart.wrap.append("ul").attr("class","legend");chart.master_legend.append("span").classed("legend-title",true);chart.multiples=[];function goAhead(data){var split_vals=d3.set(data.map(function(m){return m[split_by]})).values().filter(function(f){return f});if(order){split_vals=split_vals.sort(function(a,b){return d3.ascending(order.indexOf(a),order.indexOf(b))})}split_vals.forEach(function(e){var mchart=createChart(chart.wrap.node(),chart.config,chart.controls);chart.multiples.push(mchart);mchart.parent=chart;mchart.events=chart.events;mchart.legend=chart.master_legend;mchart.filters.unshift({col:split_by,val:e,choices:split_vals});mchart.wrap.insert("span","svg").attr("class","wc-chart-title").text(e);mchart.init(data,test)})}goAhead(data)}function getValType(data,variable){var var_vals=d3.set(data.map(function(m){return m[variable]})).values();var vals_numbers=var_vals.filter(function(f){return+f||+f===0});if(var_vals.length===vals_numbers.length&&var_vals.length>4){return"continuous"}else{return"categorical"}}function lengthenRaw(data,columns){var my_data=[];data.forEach(function(e){columns.forEach(function(g){var obj=Object.create(e);obj.wc_category=g;obj.wc_value=e[g];my_data.push(obj)})});return my_data}var dataOps={getValType:getValType,lengthenRaw:lengthenRaw,naturalSorter:naturalSorter,summarize:summarize};var index={version:version,createChart:createChart,createControls:createControls,createTable:createTable,multiply:multiply,dataOps:dataOps};return index}); diff --git a/package-lock.json b/package-lock.json index 6eecb9b..d86cefb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "webcharts", - "version": "1.12.0", + "version": "1.11.6", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -1414,7 +1414,7 @@ }, "inherits": { "version": "2.0.3", - "resolved": false, + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "invariant": { @@ -2755,7 +2755,7 @@ }, "safe-buffer": { "version": "5.1.0", - "resolved": false, + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.0.tgz", "integrity": "sha1-/kyEYDl/nqqqWOc75GJzQIpF4iM=" }, "safer-buffer": { diff --git a/src/version.js b/src/version.js index 80b28e7..a952de7 100644 --- a/src/version.js +++ b/src/version.js @@ -1 +1 @@ -export default '1.12.0'; +export default '1.11.6'; From 8a8ce35eadbee0beb82b5206f2012b8736a6c45d Mon Sep 17 00:00:00 2001 From: samussiah Date: Tue, 14 May 2019 16:03:53 -0400 Subject: [PATCH 08/12] fix potential security vulnerabilities --- package-lock.json | 1112 +++++++++++++++++++++++++++++--------- package.json | 30 +- test/chart/histogram.js | 45 +- test/chart/rangeBand.js | 8 +- test/chart/runTests.js | 6 + test/testNewUnitTests.js | 2 +- 6 files changed, 908 insertions(+), 295 deletions(-) diff --git a/package-lock.json b/package-lock.json index d86cefb..7779073 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,9 +11,9 @@ "dev": true }, "@types/node": { - "version": "10.12.15", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.15.tgz", - "integrity": "sha512-9kROxduaN98QghwwHmxXO2Xz3MaWf+I1sLVAA6KJDF5xix+IyXVhds0MAfdNwtcpSrzhaTsNB0/jnL86fgUhqA==", + "version": "12.0.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.1.tgz", + "integrity": "sha512-7sy7DKVJrCTbaAERJZq/CU12bzdmpjRr321/Ne9QmzhB3iZ//L16Cizcni5hHNbANxDbxwMb9EFoWkM8KPkp0A==", "dev": true }, "adler-32": { @@ -38,6 +38,12 @@ "uri-js": "^4.2.2" } }, + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "dev": true + }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", @@ -50,6 +56,15 @@ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -858,6 +873,12 @@ "concat-map": "0.0.1" } }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, "browserslist": { "version": "3.2.8", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", @@ -868,6 +889,12 @@ "electron-to-chromium": "^1.3.47" } }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, "caniuse-lite": { "version": "1.0.30000921", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000921.tgz", @@ -921,9 +948,9 @@ } }, "clean-css-cli": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/clean-css-cli/-/clean-css-cli-4.2.1.tgz", - "integrity": "sha512-ST2yi9F2kAmLRs9phSpGRUm44SbRy29QGm1OuAKfTU0KCLilFMTcz+/Fxhbdi5GrsjIMhTBdFUQhc55CjM3Isw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/clean-css-cli/-/clean-css-cli-4.3.0.tgz", + "integrity": "sha512-8GHZfr+mG3zB/Lgqrr27qHBFsPSn0fyEI3f2rIZpxPxUbn2J6A8xyyeBRVTW8duDuXigN0s80vsXiXJOEFIO5Q==", "dev": true, "requires": { "clean-css": "^4.2.1", @@ -931,6 +958,40 @@ "glob": "7.x" } }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, "codepage": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.3.8.tgz", @@ -950,6 +1011,21 @@ } } }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, "colors": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", @@ -966,9 +1042,9 @@ } }, "commander": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", "dev": true }, "concat-map": { @@ -1026,6 +1102,19 @@ "printj": "~1.1.0" } }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, "d3": { "version": "3.5.17", "resolved": "https://registry.npmjs.org/d3/-/d3-3.5.17.tgz", @@ -1049,6 +1138,21 @@ "ms": "2.0.0" } }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1064,6 +1168,12 @@ "repeating": "^2.0.0" } }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -1080,18 +1190,79 @@ "integrity": "sha512-H+tt+fedI+C5zl4yGtzdk17e6mOYAyawolXuAojWBULIbqOz9VR7h0cG5YcivQ1yCXrpw+Rjk6cBw47HlYtnKg==", "dev": true }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "es-abstract": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", + "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, "esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", "dev": true }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, "exit-on-epipe": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", @@ -1302,6 +1473,24 @@ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", "dev": true }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "flat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", + "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "dev": true, + "requires": { + "is-buffer": "~2.0.3" + } + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -1331,6 +1520,27 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -1341,9 +1551,9 @@ } }, "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -1360,6 +1570,12 @@ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", "dev": true }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -1376,6 +1592,15 @@ "har-schema": "^2.0.0" } }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -1385,10 +1610,22 @@ "ansi-regex": "^2.0.0" } }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, "http-signature": { @@ -1426,6 +1663,30 @@ "loose-envify": "^1.0.0" } }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "is-buffer": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", + "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==", + "dev": true + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, "is-finite": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", @@ -1435,6 +1696,36 @@ "number-is-nan": "^1.0.0" } }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -1447,6 +1738,12 @@ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "optional": true }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -1482,6 +1779,16 @@ } } }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", @@ -1849,12 +2156,71 @@ "pako": "~0.2.5" } }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, "lodash": { "version": "4.17.11", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", "dev": true }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -1864,6 +2230,26 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, "mime-db": { "version": "1.37.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", @@ -1879,6 +2265,12 @@ "mime-db": "~1.37.0" } }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -1888,271 +2280,89 @@ "brace-expansion": "^1.1.7" } }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, "mocha": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.3.tgz", - "integrity": "sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg==", + "version": "6.1.4", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.1.4.tgz", + "integrity": "sha512-PN8CIy4RXsIoxoFJzS4QNnCH4psUCPWc4/rPrst/ecSJJbLBkubMiyGCP2Kj/9YnWbotFqAoeXyXMucj7gwCFg==", "dev": true, "requires": { - "browser-stdout": "1.3.0", - "commander": "2.9.0", - "debug": "2.6.8", - "diff": "3.2.0", + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "debug": "3.2.6", + "diff": "3.5.0", "escape-string-regexp": "1.0.5", - "glob": "7.1.1", - "growl": "1.9.2", - "he": "1.1.1", - "json3": "3.3.2", - "lodash.create": "3.1.1", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "2.2.0", + "minimatch": "3.0.4", "mkdirp": "0.5.1", - "supports-color": "3.1.2" + "ms": "2.1.1", + "node-environment-flags": "1.0.5", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.2.2", + "yargs-parser": "13.0.0", + "yargs-unparser": "1.5.0" }, "dependencies": { - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", - "dev": true - }, - "commander": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", - "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", - "dev": true, - "requires": { - "graceful-readlink": ">= 1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "^2.1.1" } }, - "diff": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", - "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, "glob": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", - "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.2", + "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", - "dev": true - }, - "growl": { - "version": "1.9.2", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", - "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", - "dev": true - }, - "has-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "json3": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", - "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", - "dev": true - }, - "lodash._baseassign": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", - "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", - "dev": true, - "requires": { - "lodash._basecopy": "^3.0.0", - "lodash.keys": "^3.0.0" - } - }, - "lodash._basecopy": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", - "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", - "dev": true - }, - "lodash._basecreate": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", - "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", - "dev": true - }, - "lodash._getnative": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", - "dev": true - }, - "lodash._isiterateecall": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", - "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", - "dev": true - }, - "lodash.create": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", - "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", - "dev": true, - "requires": { - "lodash._baseassign": "^3.0.0", - "lodash._basecreate": "^3.0.0", - "lodash._isiterateecall": "^3.0.0" - } - }, - "lodash.isarguments": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", - "dev": true - }, - "lodash.isarray": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", - "dev": true - }, - "lodash.keys": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", - "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", - "dev": true, - "requires": { - "lodash._getnative": "^3.0.0", - "lodash.isarguments": "^3.0.0", - "lodash.isarray": "^3.0.0" - } - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true }, "supports-color": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", - "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", "dev": true, "requires": { - "has-flag": "^1.0.0" + "has-flag": "^3.0.0" } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true } } }, @@ -2162,6 +2372,39 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-environment-flags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", + "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + }, + "dependencies": { + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + } + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", @@ -2174,6 +2417,34 @@ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.getownpropertydescriptors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", + "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2183,18 +2454,83 @@ "wrappy": "1" } }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", + "dev": true + }, + "p-limit": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", + "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, "pako": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", "optional": true }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, "path-is-absolute": { "version": "1.0.1", "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", @@ -2230,6 +2566,16 @@ "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", "dev": true }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -2359,10 +2705,22 @@ } } }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, "rollup": { - "version": "0.68.0", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.68.0.tgz", - "integrity": "sha512-UbmntCf8QBlOqJnwsNWQCI0oonHOgs9y1OLoO8BHf2r8gCyRLp3JzLHXARJpsNDAS08Qm3LDjzyWma5sqnCxDQ==", + "version": "0.68.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.68.2.tgz", + "integrity": "sha512-WgjNCXYv7ZbtStIap1+tz4pd2zwz0XYN//OILwEY6dINIFLVizK1iWdu+ZtUURL/OKnp8Lv2w8FBds8YihzX7Q==", "dev": true, "requires": { "@types/estree": "0.0.39", @@ -2770,6 +3128,33 @@ "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", "dev": true }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, "slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", @@ -2782,6 +3167,12 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, "ssf": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.8.2.tgz", @@ -2810,6 +3201,33 @@ "tweetnacl": "~0.14.0" } }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, "string_decoder": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", @@ -2828,6 +3246,18 @@ "ansi-regex": "^2.0.0" } }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", @@ -3058,11 +3488,185 @@ "resolved": "https://registry.npmjs.org/voc/-/voc-1.0.0.tgz", "integrity": "sha512-mQwxWlK+zosxxDTqiFb9ZQBNgd794scgkhVwca7h9sEhvA52f3VzbOK+TOWeS8eSrFXnfuKrxElSPc5oLAetfw==" }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "13.2.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.2.tgz", + "integrity": "sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "yargs-parser": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.0.0.tgz", + "integrity": "sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yargs-unparser": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.5.0.tgz", + "integrity": "sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw==", + "dev": true, + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.11", + "yargs": "^12.0.5" + }, + "dependencies": { + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } } } } diff --git a/package.json b/package.json index 537bbfc..f3ff6c5 100644 --- a/package.json +++ b/package.json @@ -2,21 +2,16 @@ "name": "webcharts", "description": "A library for creating flexible, interactive charts", "version": "1.11.6", + "author": "Rho, Inc.", + "homepage": "https://github.com/RhoInc/Webcharts", "keywords": [ "charts", "javascript", "interactive", "data visualization" ], - "homepage": "https://github.com/RhoInc/Webcharts", "main": "./build/webcharts.js", "module": "./src/index.js", - "dependencies": { - "d3": "^3" - }, - "optionalDependencies": { - "js-xlsx": "^0.8.22" - }, "scripts": { "build": "npm audit fix && npm run bundle && npm run format && npm run minify", "bundle": "rollup -c", @@ -38,14 +33,11 @@ "test-table": "mocha --timeout 5000 --require babel-register --recursive ./test/table/*.js", "watch": "rollup -c -w" }, - "repository": { - "type": "git", - "url": "https://github.com/rhoinc/webcharts.git" + "dependencies": { + "d3": "^3" }, - "author": "Rho, Inc.", - "license": "MIT", - "bugs": { - "url": "https://github.com/rhoinc/webcharts/issues" + "optionalDependencies": { + "js-xlsx": "^0.8.22" }, "devDependencies": { "babel-plugin-external-helpers": "^6.22.0", @@ -54,10 +46,18 @@ "clean-css-cli": "^4.2.1", "expect": "1", "jsdom": "10", - "mocha": "3", + "mocha": "^6.1.4", "prettier": "1.4.4", "rollup": "^0.68.0", "rollup-plugin-babel": "^2.7.1", "uglify-js": "^2.5.0" + }, + "repository": { + "type": "git", + "url": "https://github.com/rhoinc/webcharts.git" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/rhoinc/webcharts/issues" } } diff --git a/test/chart/histogram.js b/test/chart/histogram.js index 5abd057..b7f453d 100644 --- a/test/chart/histogram.js +++ b/test/chart/histogram.js @@ -1,32 +1,33 @@ import jsdom from 'jsdom'; import createChart from '../../src/createChart'; import expect from 'expect'; +import d3 from 'd3'; import data from '../samples/irisData'; import settings from '../samples/histogram'; -import clone from '../../src/util/clone'; -import { selectAll } from 'd3'; -describe('histogram tests', () => { - const { JSDOM } = jsdom; - let dom, container, chart; +export default function testHistogram(settings, data) { + describe('histogram tests', () => { + const { JSDOM } = jsdom; + let dom, container, chart; - before(() => { - dom = new JSDOM(''); - container = dom.window.document.createElement('div'); - chart = createChart(container, settings); - chart.init(data, true); - }); - - describe('settings specify a histogram by defining [x|y].bin', () => { - it('groups the data into as many bins as specified by [x|y].bin', () => { - const nodes = chart.wrap.node().querySelectorAll('.bar-group'); - expect(nodes.length).toEqual(chart.config.x.bin); + before(() => { + dom = new JSDOM(''); + container = dom.window.document.createElement('div'); + chart = createChart(container, settings); + chart.init(data, true); }); - it('when an axis domain is specified, that domain, rather than the extent of the data, is divided into bins', () => { - chart.config.x.domain = [2, 10]; - chart.draw(); - expect(chart.marks[0].quant.domain()).toEqual(chart.config.x.domain); + + describe('settings specify a histogram by defining [x|y].bin', () => { + it('groups the data into as many bins as specified by [x|y].bin', () => { + const nodes = chart.wrap.node().querySelectorAll('.bar-group'); + expect(nodes.length).toEqual(chart.config.x.bin); + }); + it('when an axis domain is specified, that domain, rather than the extent of the data, is divided into bins', () => { + chart.config.x.domain = [2, 10]; + chart.draw(); + expect(chart.marks[0].quant.domain()).toEqual(chart.config.x.domain); + }); + //TODO: Have Webcharts calculate the bin width when [x|y].bin = 0 or 'fd' (Freedman-Diaconis rule). }); - //TODO: Have Webcharts calculate the bin width when [x|y].bin = 0 or 'fd' (Freedman-Diaconis rule). }); -}); +} diff --git a/test/chart/rangeBand.js b/test/chart/rangeBand.js index c453236..54ec707 100644 --- a/test/chart/rangeBand.js +++ b/test/chart/rangeBand.js @@ -2,8 +2,10 @@ import jsdom from 'jsdom'; import createChart from '../../src/createChart'; import expect from 'expect'; import d3 from 'd3'; +import { ordinal_ordinal as settings } from '../samples/irisSettings'; +import data from '../samples/irisData'; -export default function testRangeBand(settings, data) { +//export default function testRangeBand(settings, data) { describe('range band definitions for ordinal axes', () => { const { JSDOM } = jsdom; let dom, container, chart; @@ -11,11 +13,11 @@ export default function testRangeBand(settings, data) { //DOM setup before(() => { dom = new JSDOM(''); - container = dom.window.document.createElement('div'); }); //Chart initialization beforeEach(() => { + container = dom.window.document.createElement('div'); chart = createChart(container, settings).init(data, true); }); @@ -74,4 +76,4 @@ export default function testRangeBand(settings, data) { }); }); }); -} +//} diff --git a/test/chart/runTests.js b/test/chart/runTests.js index bfdee37..6ee7b28 100644 --- a/test/chart/runTests.js +++ b/test/chart/runTests.js @@ -56,3 +56,9 @@ import testRangeBand from './rangeBand'; import { ordinal_ordinal as ordinal_ordinal_rb } from '../samples/irisSettings'; import rangeBandData from '../samples/irisData'; testRangeBand(ordinal_ordinal_rb, rangeBandData); + +//test histogram settings +import testHistogram from './testHistogram'; +import histogramSettings from '../samples/histogram'; +import histogramData from '../samples/irisData'; +testHistogram(histogramSettings, histogramData); diff --git a/test/testNewUnitTests.js b/test/testNewUnitTests.js index 9107366..9b6bf79 100644 --- a/test/testNewUnitTests.js +++ b/test/testNewUnitTests.js @@ -1 +1 @@ -import './chart/histogram'; +import './chart/rangeBand'; From c0570cd9aba79a32a65e4765644495ac328633fd Mon Sep 17 00:00:00 2001 From: samussiah Date: Tue, 14 May 2019 16:30:12 -0400 Subject: [PATCH 09/12] modularize histogram unit test --- test/chart/configTester.js | 96 +++++++++++++++++++------------------- test/chart/histogram.js | 2 - test/chart/rangeBand.js | 11 ++--- test/chart/runTests.js | 2 +- test/testNewUnitTests.js | 4 ++ 5 files changed, 58 insertions(+), 57 deletions(-) diff --git a/test/chart/configTester.js b/test/chart/configTester.js index f70951c..4178388 100644 --- a/test/chart/configTester.js +++ b/test/chart/configTester.js @@ -1,48 +1,48 @@ -import testSettingList from '../samples/chart-config/testSettingList'; - -import { readFile, readFileSync } from 'fs'; -import d3 from 'd3'; -import { merge } from 'd3'; -import jsdom from 'jsdom'; -import webcharts from '../../build/webcharts'; -import expect from 'expect'; - -import testCreateChart from '../chart/createChart'; -import testRendering from '../chart/rendering'; - -var settingsList = []; -var numLoaded = 0; - -var testSettingList_charts = testSettingList.filter(function(d) { - return d.type == 'charts'; -}); - -testSettingList_charts.forEach(function(d) { - var path = require('path'); - var jsonPath = path.join(__dirname, '..', 'samples', 'chart-config', d.filename); - var jsonRaw = readFileSync(jsonPath, 'utf8'); - var jsonData = JSON.parse(jsonRaw); - settingsList = merge([settingsList, jsonData]); - numLoaded = numLoaded + 1; - if (numLoaded == testSettingList_charts.length) runTests(settingsList); - //if (numLoaded == 1) runTests(settingsList); -}); - -function runTests(settingsList) { - it('run tests once for each settings object', done => { - settingsList.forEach((settings, i) => { - const dataFile = `./test/samples/data/${settings.filename}`, - raw = readFileSync(dataFile, 'utf8'), - data = d3.csv.parse(raw); - describe(`Chart Test ${i + 1} of ${settingsList.length}: ${settings.label}. `, () => { - describe('Create Chart. ', () => { - testCreateChart(settings.settings, false); - }); - describe('Render Chart. ', () => { - testRendering(settings.settings, data, false); - }); - }); - }); - done(); - }); -} +//import testSettingList from '../samples/chart-config/testSettingList'; +// +//import { readFile, readFileSync } from 'fs'; +//import d3 from 'd3'; +//import { merge } from 'd3'; +//import jsdom from 'jsdom'; +//import webcharts from '../../build/webcharts'; +//import expect from 'expect'; +// +//import testCreateChart from '../chart/createChart'; +//import testRendering from '../chart/rendering'; +// +//var settingsList = []; +//var numLoaded = 0; +// +//var testSettingList_charts = testSettingList.filter(function(d) { +// return d.type == 'charts'; +//}); +// +//testSettingList_charts.forEach(function(d) { +// var path = require('path'); +// var jsonPath = path.join(__dirname, '..', 'samples', 'chart-config', d.filename); +// var jsonRaw = readFileSync(jsonPath, 'utf8'); +// var jsonData = JSON.parse(jsonRaw); +// settingsList = merge([settingsList, jsonData]); +// numLoaded = numLoaded + 1; +// if (numLoaded == testSettingList_charts.length) runTests(settingsList); +// //if (numLoaded == 1) runTests(settingsList); +//}); +// +//function runTests(settingsList) { +// it('run tests once for each settings object', done => { +// settingsList.forEach((settings, i) => { +// const dataFile = `./test/samples/data/${settings.filename}`, +// raw = readFileSync(dataFile, 'utf8'), +// data = d3.csv.parse(raw); +// describe(`Chart Test ${i + 1} of ${settingsList.length}: ${settings.label}. `, () => { +// describe('Create Chart. ', () => { +// testCreateChart(settings.settings, false); +// }); +// describe('Render Chart. ', () => { +// testRendering(settings.settings, data, false); +// }); +// }); +// }); +// done(); +// }); +//} diff --git a/test/chart/histogram.js b/test/chart/histogram.js index b7f453d..287137f 100644 --- a/test/chart/histogram.js +++ b/test/chart/histogram.js @@ -2,8 +2,6 @@ import jsdom from 'jsdom'; import createChart from '../../src/createChart'; import expect from 'expect'; import d3 from 'd3'; -import data from '../samples/irisData'; -import settings from '../samples/histogram'; export default function testHistogram(settings, data) { describe('histogram tests', () => { diff --git a/test/chart/rangeBand.js b/test/chart/rangeBand.js index 54ec707..d86f518 100644 --- a/test/chart/rangeBand.js +++ b/test/chart/rangeBand.js @@ -2,10 +2,8 @@ import jsdom from 'jsdom'; import createChart from '../../src/createChart'; import expect from 'expect'; import d3 from 'd3'; -import { ordinal_ordinal as settings } from '../samples/irisSettings'; -import data from '../samples/irisData'; -//export default function testRangeBand(settings, data) { +export default function testRangeBand(settings, data) { describe('range band definitions for ordinal axes', () => { const { JSDOM } = jsdom; let dom, container, chart; @@ -13,12 +11,13 @@ import data from '../samples/irisData'; //DOM setup before(() => { dom = new JSDOM(''); + container = dom.window.document.createElement('div'); + chart = createChart(container, settings).init(data, true); }); //Chart initialization beforeEach(() => { - container = dom.window.document.createElement('div'); - chart = createChart(container, settings).init(data, true); + chart.draw(); }); afterEach(() => { @@ -76,4 +75,4 @@ import data from '../samples/irisData'; }); }); }); -//} +} diff --git a/test/chart/runTests.js b/test/chart/runTests.js index 6ee7b28..6d557e8 100644 --- a/test/chart/runTests.js +++ b/test/chart/runTests.js @@ -58,7 +58,7 @@ import rangeBandData from '../samples/irisData'; testRangeBand(ordinal_ordinal_rb, rangeBandData); //test histogram settings -import testHistogram from './testHistogram'; +import testHistogram from './histogram'; import histogramSettings from '../samples/histogram'; import histogramData from '../samples/irisData'; testHistogram(histogramSettings, histogramData); diff --git a/test/testNewUnitTests.js b/test/testNewUnitTests.js index 9b6bf79..7d0870e 100644 --- a/test/testNewUnitTests.js +++ b/test/testNewUnitTests.js @@ -1 +1,5 @@ import './chart/rangeBand'; +import testRangeBand from './chart/rangeBand'; +import { ordinal_ordinal as ordinal_ordinal_rb } from './samples/irisSettings'; +import rangeBandData from './samples/irisData'; +testRangeBand(ordinal_ordinal_rb, rangeBandData); From a0d44bdf7357b934ac2a71b012c0dd1a5251bd09 Mon Sep 17 00:00:00 2001 From: Spencer Childress Date: Thu, 16 May 2019 18:44:54 -0400 Subject: [PATCH 10/12] roll back mocha; v6 fixes security vulnerabilities but breaks test/chart/rangeBand --- package-lock.json | 1583 +++++++++++----------------------- package.json | 6 +- src/chart/destroy.js | 3 +- src/chart/init.js | 2 + test/chart/rangeBand.js | 7 +- test/samples/irisSettings.js | 8 +- 6 files changed, 495 insertions(+), 1114 deletions(-) diff --git a/package-lock.json b/package-lock.json index 7779073..b145075 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,6 +16,42 @@ "integrity": "sha512-7sy7DKVJrCTbaAERJZq/CU12bzdmpjRr321/Ne9QmzhB3iZ//L16Cizcni5hHNbANxDbxwMb9EFoWkM8KPkp0A==", "dev": true }, + "abab": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.0.tgz", + "integrity": "sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w==", + "dev": true + }, + "acorn": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", + "dev": true + }, + "acorn-globals": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.2.tgz", + "integrity": "sha512-BbzvZhVtZP+Bs1J1HcwrQe8ycfO0wStkSGxuul3He3GkHOIZ6eTqOkPuw9IP1X3+IkOo4wiJmwkobzXYz4wewQ==", + "dev": true, + "requires": { + "acorn": "^6.0.1", + "acorn-walk": "^6.0.1" + }, + "dependencies": { + "acorn": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "dev": true + } + } + }, + "acorn-walk": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", + "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", + "dev": true + }, "adler-32": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/adler-32/-/adler-32-1.1.0.tgz", @@ -27,9 +63,9 @@ } }, "ajv": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.6.2.tgz", - "integrity": "sha512-FBHEW6Jf5TB9MGBgUUA9XHkTbjXYfAUjY43ACMfmdMRHniyoMHjHjzD50OK8LGDWQwp4rWEsIq5kEqq7rvIM1g==", + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", @@ -38,12 +74,6 @@ "uri-js": "^4.2.2" } }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", @@ -56,14 +86,11 @@ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", "dev": true }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } + "array-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true }, "asn1": { "version": "0.2.4", @@ -80,6 +107,12 @@ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "dev": true + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -873,10 +906,16 @@ "concat-map": "0.0.1" } }, + "browser-process-hrtime": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", + "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==", + "dev": true + }, "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", + "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", "dev": true }, "browserslist": { @@ -889,12 +928,6 @@ "electron-to-chromium": "^1.3.47" } }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, "caniuse-lite": { "version": "1.0.30000921", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000921.tgz", @@ -958,40 +991,6 @@ "glob": "7.x" } }, - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, "codepage": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/codepage/-/codepage-1.3.8.tgz", @@ -1011,21 +1010,6 @@ } } }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, "colors": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/colors/-/colors-0.6.2.tgz", @@ -1033,9 +1017,9 @@ "optional": true }, "combined-stream": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", - "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "dev": true, "requires": { "delayed-stream": "~1.0.0" @@ -1102,17 +1086,19 @@ "printj": "~1.1.0" } }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "cssom": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.6.tgz", + "integrity": "sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A==", + "dev": true + }, + "cssstyle": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.2.2.tgz", + "integrity": "sha512-43wY3kl1CVQSvL7wUY1qXkxVGkStjpkDmVjiIKX8R97uhajy8Bybay78uOtqvh7Q5GK75dNPfW0geWjE6qQQow==", "dev": true, "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" + "cssom": "0.3.x" } }, "d3": { @@ -1129,6 +1115,30 @@ "assert-plus": "^1.0.0" } }, + "data-urls": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", + "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "whatwg-mimetype": "^2.2.0", + "whatwg-url": "^7.0.0" + }, + "dependencies": { + "whatwg-url": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", + "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + } + } + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -1138,21 +1148,12 @@ "ms": "2.0.0" } }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -1169,11 +1170,20 @@ } }, "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.2.0.tgz", + "integrity": "sha1-yc45Okt8vQsFinJck98pkCeGj/k=", "dev": true }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, + "requires": { + "webidl-conversions": "^4.0.2" + } + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -1190,56 +1200,37 @@ "integrity": "sha512-H+tt+fedI+C5zl4yGtzdk17e6mOYAyawolXuAojWBULIbqOz9VR7h0cG5YcivQ1yCXrpw+Rjk6cBw47HlYtnKg==", "dev": true }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "es-abstract": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", - "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.0", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", - "object-keys": "^1.0.12" - } - }, - "es-to-primitive": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", - "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "escodegen": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.1.tgz", + "integrity": "sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw==", + "dev": true, + "requires": { + "esprima": "^3.1.3", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true + } + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", "dev": true }, "esutils": { @@ -1248,21 +1239,6 @@ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", "dev": true }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, "exit-on-epipe": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", @@ -1473,23 +1449,11 @@ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", "dev": true }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - } + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true }, "forever-agent": { "version": "0.6.1", @@ -1520,27 +1484,6 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -1570,10 +1513,16 @@ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", "dev": true }, + "graceful-readlink": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", + "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", + "dev": true + }, "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.9.2.tgz", + "integrity": "sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=", "dev": true }, "har-schema": { @@ -1592,15 +1541,6 @@ "har-schema": "^2.0.0" } }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -1611,23 +1551,26 @@ } }, "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", "dev": true }, "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", "dev": true }, + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.1" + } + }, "http-signature": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", @@ -1639,6 +1582,15 @@ "sshpk": "^1.7.0" } }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -1651,7 +1603,7 @@ }, "inherits": { "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "resolved": false, "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "invariant": { @@ -1663,30 +1615,6 @@ "loose-envify": "^1.0.0" } }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true - }, - "is-buffer": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", - "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==", - "dev": true - }, - "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", - "dev": true - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true - }, "is-finite": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", @@ -1696,36 +1624,6 @@ "number-is-nan": "^1.0.0" } }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, - "requires": { - "has": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-symbol": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", - "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.0" - } - }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -1738,12 +1636,6 @@ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "optional": true }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", @@ -1779,16 +1671,6 @@ } } }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", @@ -1796,313 +1678,37 @@ "dev": true }, "jsdom": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-10.1.0.tgz", - "integrity": "sha1-d2XgD9XDVn80mFochv9GamHazGo=", + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", + "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", "dev": true, "requires": { - "abab": "^1.0.3", - "acorn": "^4.0.4", - "acorn-globals": "^3.1.0", + "abab": "^2.0.0", + "acorn": "^5.5.3", + "acorn-globals": "^4.1.0", "array-equal": "^1.0.0", - "content-type-parser": "^1.0.1", "cssom": ">= 0.3.2 < 0.4.0", - "cssstyle": ">= 0.2.37 < 0.3.0", - "escodegen": "^1.6.1", - "html-encoding-sniffer": "^1.0.1", - "nwmatcher": ">= 1.3.9 < 2.0.0", - "parse5": "^1.5.1", - "pn": "^1.0.0", - "request": "^2.79.0", - "request-promise-native": "^1.0.3", - "sax": "^1.2.1", - "symbol-tree": "^3.2.1", - "tough-cookie": "^2.3.2", - "webidl-conversions": "^4.0.0", - "whatwg-encoding": "^1.0.1", - "whatwg-url": "^4.3.0", - "xml-name-validator": "^2.0.1" - }, - "dependencies": { - "abab": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", - "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=", - "dev": true - }, - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", - "dev": true - }, - "acorn-globals": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz", - "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=", - "dev": true, - "requires": { - "acorn": "^4.0.4" - } - }, - "array-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", - "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", - "dev": true - }, - "content-type-parser": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.2.tgz", - "integrity": "sha512-lM4l4CnMEwOLHAHr/P6MEZwZFPJFtAAKgL6pogbXmVZggIqXhdB6RbBtPOTsw2FcXwYhehRGERJmRrjOiIB8pQ==", - "dev": true - }, - "cssom": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz", - "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=", - "dev": true - }, - "cssstyle": { - "version": "0.2.37", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz", - "integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=", - "dev": true, - "requires": { - "cssom": "0.3.x" - } - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "escodegen": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.0.tgz", - "integrity": "sha512-v0MYvNQ32bzwoG2OSFzWAkuahDQHK92JBN0pTAALJ4RIxEZe766QJPDR8Hqy7XNUy5K3fnVL76OqYAdc4TZEIw==", - "dev": true, - "requires": { - "esprima": "^3.1.3", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.5.6" - } - }, - "esprima": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", - "dev": true - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "html-encoding-sniffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", - "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", - "dev": true, - "requires": { - "whatwg-encoding": "^1.0.1" - } - }, - "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", - "dev": true - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "lodash": { - "version": "4.17.5", - "resolved": "", - "dev": true - }, - "nwmatcher": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.3.tgz", - "integrity": "sha512-IKdSTiDWCarf2JTS5e9e2+5tPZGdkRJ79XjYV0pzK8Q9BpsFyBq1RGKxzs7Q8UBushGw7m6TzVKz6fcY99iSWw==", - "dev": true - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.4", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "wordwrap": "~1.0.0" - } - }, - "parse5": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz", - "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=", - "dev": true - }, - "pn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", - "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "request-promise-core": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz", - "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=", - "dev": true, - "requires": { - "lodash": "^4.13.1" - } - }, - "request-promise-native": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.5.tgz", - "integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=", - "dev": true, - "requires": { - "request-promise-core": "1.1.1", - "stealthy-require": "^1.1.0", - "tough-cookie": ">=2.3.3" - } - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "optional": true - }, - "stealthy-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", - "dev": true - }, - "symbol-tree": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", - "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", - "dev": true - }, - "tough-cookie": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", - "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", - "dev": true, - "requires": { - "punycode": "^1.4.1" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - }, - "webidl-conversions": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", - "dev": true - }, - "whatwg-encoding": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz", - "integrity": "sha512-jLBwwKUhi8WtBfsMQlL4bUUcT8sMkAtQinscJAe/M4KHCkHuUJAF6vuB0tueNIw4c8ziO6AkRmgY+jL3a0iiPw==", - "dev": true, - "requires": { - "iconv-lite": "0.4.19" - } - }, - "whatwg-url": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-4.8.0.tgz", - "integrity": "sha1-0pgaqRSMHgCkHFphMRZqtGg7vMA=", - "dev": true, - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=", - "dev": true - } - } - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "xml-name-validator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", - "integrity": "sha1-TYuPHszTQZqjYgYb7O9RXh5VljU=", - "dev": true - } + "cssstyle": "^1.0.0", + "data-urls": "^1.0.0", + "domexception": "^1.0.1", + "escodegen": "^1.9.1", + "html-encoding-sniffer": "^1.0.2", + "left-pad": "^1.3.0", + "nwsapi": "^2.0.7", + "parse5": "4.0.0", + "pn": "^1.1.0", + "request": "^2.87.0", + "request-promise-native": "^1.0.5", + "sax": "^1.2.4", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.3.4", + "w3c-hr-time": "^1.0.1", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.3", + "whatwg-mimetype": "^2.1.0", + "whatwg-url": "^6.4.1", + "ws": "^5.2.0", + "xml-name-validator": "^3.0.0" } }, "jsesc": { @@ -2129,6 +1735,12 @@ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", "dev": true }, + "json3": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", + "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", + "dev": true + }, "json5": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", @@ -2156,23 +1768,20 @@ "pako": "~0.2.5" } }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } + "left-pad": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", + "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==", + "dev": true }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", "dev": true, "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" } }, "lodash": { @@ -2181,96 +1790,104 @@ "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", "dev": true }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "lodash._baseassign": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz", + "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=", "dev": true, "requires": { - "chalk": "^2.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } + "lodash._basecopy": "^3.0.0", + "lodash.keys": "^3.0.0" } }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "lodash._basecopy": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true + }, + "lodash._basecreate": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz", + "integrity": "sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=", + "dev": true + }, + "lodash._getnative": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true + }, + "lodash._isiterateecall": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true + }, + "lodash.create": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lodash.create/-/lodash.create-3.1.1.tgz", + "integrity": "sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=", "dev": true, "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" + "lodash._baseassign": "^3.0.0", + "lodash._basecreate": "^3.0.0", + "lodash._isiterateecall": "^3.0.0" } }, - "map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "lodash.isarguments": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true + }, + "lodash.isarray": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true + }, + "lodash.keys": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", + "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", "dev": true, "requires": { - "p-defer": "^1.0.0" + "lodash._getnative": "^3.0.0", + "lodash.isarguments": "^3.0.0", + "lodash.isarray": "^3.0.0" } }, - "mem": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dev": true, "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" + "js-tokens": "^3.0.0 || ^4.0.0" } }, "mime-db": { - "version": "1.37.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", - "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "version": "1.40.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", "dev": true }, "mime-types": { - "version": "2.1.21", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", - "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "version": "2.1.24", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", + "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", "dev": true, "requires": { - "mime-db": "~1.37.0" + "mime-db": "1.40.0" } }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -2296,72 +1913,64 @@ } }, "mocha": { - "version": "6.1.4", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.1.4.tgz", - "integrity": "sha512-PN8CIy4RXsIoxoFJzS4QNnCH4psUCPWc4/rPrst/ecSJJbLBkubMiyGCP2Kj/9YnWbotFqAoeXyXMucj7gwCFg==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-3.5.3.tgz", + "integrity": "sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg==", "dev": true, "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "debug": "3.2.6", - "diff": "3.5.0", + "browser-stdout": "1.3.0", + "commander": "2.9.0", + "debug": "2.6.8", + "diff": "3.2.0", "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "2.2.0", - "minimatch": "3.0.4", + "glob": "7.1.1", + "growl": "1.9.2", + "he": "1.1.1", + "json3": "3.3.2", + "lodash.create": "3.1.1", "mkdirp": "0.5.1", - "ms": "2.1.1", - "node-environment-flags": "1.0.5", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.2.2", - "yargs-parser": "13.0.0", - "yargs-unparser": "1.5.0" + "supports-color": "3.1.2" }, "dependencies": { + "commander": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", + "dev": true, + "requires": { + "graceful-readlink": ">= 1.0.0" + } + }, "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "2.6.8", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", + "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.0.0" } }, "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.1.tgz", + "integrity": "sha1-gFIR3wT6rxxjo2ADBs31reULLsg=", "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.4", + "minimatch": "^3.0.2", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.1.2.tgz", + "integrity": "sha1-cqJiiU2dQIuVbKBf83su2KbiotU=", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "^1.0.0" } } } @@ -2372,79 +1981,24 @@ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node-environment-flags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", - "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - }, - "dependencies": { - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", - "dev": true - } - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, + "nwsapi": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.4.tgz", + "integrity": "sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw==", + "dev": true + }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", "dev": true }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", - "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.1" - } - }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -2454,69 +2008,30 @@ "wrappy": "1" } }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "dev": true - }, - "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", "dev": true, "requires": { - "p-limit": "^2.0.0" + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" } }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, "pako": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", "optional": true }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", "dev": true }, "path-is-absolute": { @@ -2525,18 +2040,24 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, + "pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, "prettier": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.4.4.tgz", @@ -2566,16 +2087,6 @@ "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", "dev": true }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", @@ -2697,25 +2208,49 @@ "uuid": "^3.3.2" }, "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "dev": true + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } } } }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true + "request-promise-core": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz", + "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==", + "dev": true, + "requires": { + "lodash": "^4.17.11" + } }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true + "request-promise-native": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz", + "integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==", + "dev": true, + "requires": { + "request-promise-core": "1.1.2", + "stealthy-require": "^1.1.1", + "tough-cookie": "^2.3.3" + } }, "rollup": { "version": "0.68.2", @@ -3113,7 +2648,7 @@ }, "safe-buffer": { "version": "5.1.0", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.0.tgz", + "resolved": false, "integrity": "sha1-/kyEYDl/nqqqWOc75GJzQIpF4iM=" }, "safer-buffer": { @@ -3122,39 +2657,18 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, "semver": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", "dev": true }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, "slash": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", @@ -3167,12 +2681,6 @@ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", "dev": true }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, "ssf": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/ssf/-/ssf-0.8.2.tgz", @@ -3185,9 +2693,9 @@ } }, "sshpk": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz", - "integrity": "sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==", + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", "dev": true, "requires": { "asn1": "~0.2.3", @@ -3201,32 +2709,11 @@ "tweetnacl": "~0.14.0" } }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } + "stealthy-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true }, "string_decoder": { "version": "1.0.3", @@ -3246,24 +2733,18 @@ "ansi-regex": "^2.0.0" } }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", "dev": true }, + "symbol-tree": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", + "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", + "dev": true + }, "to-fast-properties": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", @@ -3271,21 +2752,22 @@ "dev": true }, "tough-cookie": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", - "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", "dev": true, "requires": { - "psl": "^1.1.24", - "punycode": "^1.4.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, + "requires": { + "punycode": "^2.1.0" } }, "trim-right": { @@ -3309,6 +2791,15 @@ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "dev": true }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -3488,185 +2979,73 @@ "resolved": "https://registry.npmjs.org/voc/-/voc-1.0.0.tgz", "integrity": "sha512-mQwxWlK+zosxxDTqiFb9ZQBNgd794scgkhVwca7h9sEhvA52f3VzbOK+TOWeS8eSrFXnfuKrxElSPc5oLAetfw==" }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "w3c-hr-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", + "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", "dev": true, "requires": { - "isexe": "^2.0.0" + "browser-process-hrtime": "^0.1.2" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", "dev": true }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", "dev": true, "requires": { - "string-width": "^1.0.2 || 2" + "iconv-lite": "0.4.24" } }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "whatwg-url": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", + "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", "dev": true, "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" } }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yargs": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.2.tgz", - "integrity": "sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "os-locale": "^3.1.0", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "yargs-parser": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.0.0.tgz", - "integrity": "sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw==", + "ws": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", "dev": true, "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" + "async-limiter": "~1.0.0" } }, - "yargs-unparser": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.5.0.tgz", - "integrity": "sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.11", - "yargs": "^12.0.5" - }, - "dependencies": { - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" - } - }, - "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true } } } diff --git a/package.json b/package.json index f3ff6c5..dcc684e 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "test-controls": "mocha --timeout 5000 --require babel-register --recursive ./test/controls/*.js", "test-miscellaneous": "mocha --timeout 5000 --require babel-register --recursive ./test/miscellaneous/*.js", "test-multiply": "mocha --timeout 5000 --require babel-register --recursive ./test/multiply/*.js", - "test-new": "mocha --timeout 5000 --require babel-register --recursive ./test/testNewUnitTests.js", + "test-new": "mocha --require babel-register ./test/setup.js ./test/testNewUnitTests.js", "test-page": "start chrome ./test-page/createChart/index.html && start chrome ./test-page/createTable/index.html && start chrome ./test-page/multiply/index.html", "test-table": "mocha --timeout 5000 --require babel-register --recursive ./test/table/*.js", "watch": "rollup -c -w" @@ -45,8 +45,8 @@ "babel-register": "6", "clean-css-cli": "^4.2.1", "expect": "1", - "jsdom": "10", - "mocha": "^6.1.4", + "jsdom": "^11.12.0", + "mocha": "^3.5.3", "prettier": "1.4.4", "rollup": "^0.68.0", "rollup-plugin-babel": "^2.7.1", diff --git a/src/chart/destroy.js b/src/chart/destroy.js index 1451a12..72b766b 100644 --- a/src/chart/destroy.js +++ b/src/chart/destroy.js @@ -6,7 +6,8 @@ export default function destroy(destroyControls = true) { //remove resize event listener var context = this; - select(window).on('resize.' + context.element + context.id, null); + if (!this.test) + select(window).on('resize.' + context.element + context.id, null); //destroy controls if (destroyControls && this.controls) { diff --git a/src/chart/init.js b/src/chart/init.js index 2c32ac6..972b27f 100644 --- a/src/chart/init.js +++ b/src/chart/init.js @@ -1,6 +1,8 @@ import { select, range } from 'd3'; export default function init(data, test = false) { + this.test = test; + if (select(this.div).select('.loader').empty()) { select(this.div) .insert('div', ':first-child') diff --git a/test/chart/rangeBand.js b/test/chart/rangeBand.js index d86f518..b3b65de 100644 --- a/test/chart/rangeBand.js +++ b/test/chart/rangeBand.js @@ -6,18 +6,17 @@ import d3 from 'd3'; export default function testRangeBand(settings, data) { describe('range band definitions for ordinal axes', () => { const { JSDOM } = jsdom; - let dom, container, chart; + let dom, window, container, chart; //DOM setup before(() => { - dom = new JSDOM(''); - container = dom.window.document.createElement('div'); + container = window.document.createElement('div'); chart = createChart(container, settings).init(data, true); }); //Chart initialization beforeEach(() => { - chart.draw(); + chart = createChart(container, settings).init(data, true); }); afterEach(() => { diff --git a/test/samples/irisSettings.js b/test/samples/irisSettings.js index 44e5f67..de9879a 100644 --- a/test/samples/irisSettings.js +++ b/test/samples/irisSettings.js @@ -129,10 +129,10 @@ export const ordinal_ordinal = { label: 'Species' }, marks: [ - { - type: 'bar', - per: ['Species'] - }, + //{ + // type: 'bar', + // per: ['Species'] + //}, { type: 'circle', per: ['Species'] From 8ef75dc5114ee4254eee2eb20f33203f3dac3a2e Mon Sep 17 00:00:00 2001 From: Spencer Childress Date: Thu, 16 May 2019 18:46:04 -0400 Subject: [PATCH 11/12] revert unit test files --- package.json | 2 +- test/chart/configTester.js | 96 +++++++++++++++++++------------------- test/chart/rangeBand.js | 1 - 3 files changed, 49 insertions(+), 50 deletions(-) diff --git a/package.json b/package.json index dcc684e..6121e1e 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "test-controls": "mocha --timeout 5000 --require babel-register --recursive ./test/controls/*.js", "test-miscellaneous": "mocha --timeout 5000 --require babel-register --recursive ./test/miscellaneous/*.js", "test-multiply": "mocha --timeout 5000 --require babel-register --recursive ./test/multiply/*.js", - "test-new": "mocha --require babel-register ./test/setup.js ./test/testNewUnitTests.js", + "test-new": "mocha --require babel-register ./test/testNewUnitTests.js", "test-page": "start chrome ./test-page/createChart/index.html && start chrome ./test-page/createTable/index.html && start chrome ./test-page/multiply/index.html", "test-table": "mocha --timeout 5000 --require babel-register --recursive ./test/table/*.js", "watch": "rollup -c -w" diff --git a/test/chart/configTester.js b/test/chart/configTester.js index 4178388..f70951c 100644 --- a/test/chart/configTester.js +++ b/test/chart/configTester.js @@ -1,48 +1,48 @@ -//import testSettingList from '../samples/chart-config/testSettingList'; -// -//import { readFile, readFileSync } from 'fs'; -//import d3 from 'd3'; -//import { merge } from 'd3'; -//import jsdom from 'jsdom'; -//import webcharts from '../../build/webcharts'; -//import expect from 'expect'; -// -//import testCreateChart from '../chart/createChart'; -//import testRendering from '../chart/rendering'; -// -//var settingsList = []; -//var numLoaded = 0; -// -//var testSettingList_charts = testSettingList.filter(function(d) { -// return d.type == 'charts'; -//}); -// -//testSettingList_charts.forEach(function(d) { -// var path = require('path'); -// var jsonPath = path.join(__dirname, '..', 'samples', 'chart-config', d.filename); -// var jsonRaw = readFileSync(jsonPath, 'utf8'); -// var jsonData = JSON.parse(jsonRaw); -// settingsList = merge([settingsList, jsonData]); -// numLoaded = numLoaded + 1; -// if (numLoaded == testSettingList_charts.length) runTests(settingsList); -// //if (numLoaded == 1) runTests(settingsList); -//}); -// -//function runTests(settingsList) { -// it('run tests once for each settings object', done => { -// settingsList.forEach((settings, i) => { -// const dataFile = `./test/samples/data/${settings.filename}`, -// raw = readFileSync(dataFile, 'utf8'), -// data = d3.csv.parse(raw); -// describe(`Chart Test ${i + 1} of ${settingsList.length}: ${settings.label}. `, () => { -// describe('Create Chart. ', () => { -// testCreateChart(settings.settings, false); -// }); -// describe('Render Chart. ', () => { -// testRendering(settings.settings, data, false); -// }); -// }); -// }); -// done(); -// }); -//} +import testSettingList from '../samples/chart-config/testSettingList'; + +import { readFile, readFileSync } from 'fs'; +import d3 from 'd3'; +import { merge } from 'd3'; +import jsdom from 'jsdom'; +import webcharts from '../../build/webcharts'; +import expect from 'expect'; + +import testCreateChart from '../chart/createChart'; +import testRendering from '../chart/rendering'; + +var settingsList = []; +var numLoaded = 0; + +var testSettingList_charts = testSettingList.filter(function(d) { + return d.type == 'charts'; +}); + +testSettingList_charts.forEach(function(d) { + var path = require('path'); + var jsonPath = path.join(__dirname, '..', 'samples', 'chart-config', d.filename); + var jsonRaw = readFileSync(jsonPath, 'utf8'); + var jsonData = JSON.parse(jsonRaw); + settingsList = merge([settingsList, jsonData]); + numLoaded = numLoaded + 1; + if (numLoaded == testSettingList_charts.length) runTests(settingsList); + //if (numLoaded == 1) runTests(settingsList); +}); + +function runTests(settingsList) { + it('run tests once for each settings object', done => { + settingsList.forEach((settings, i) => { + const dataFile = `./test/samples/data/${settings.filename}`, + raw = readFileSync(dataFile, 'utf8'), + data = d3.csv.parse(raw); + describe(`Chart Test ${i + 1} of ${settingsList.length}: ${settings.label}. `, () => { + describe('Create Chart. ', () => { + testCreateChart(settings.settings, false); + }); + describe('Render Chart. ', () => { + testRendering(settings.settings, data, false); + }); + }); + }); + done(); + }); +} diff --git a/test/chart/rangeBand.js b/test/chart/rangeBand.js index b3b65de..2bae037 100644 --- a/test/chart/rangeBand.js +++ b/test/chart/rangeBand.js @@ -11,7 +11,6 @@ export default function testRangeBand(settings, data) { //DOM setup before(() => { container = window.document.createElement('div'); - chart = createChart(container, settings).init(data, true); }); //Chart initialization From 147b20857a9452f70cfa4f5be0cbb4345672bdf0 Mon Sep 17 00:00:00 2001 From: samussiah Date: Fri, 17 May 2019 11:24:45 -0400 Subject: [PATCH 12/12] revert mocha to v3 because v6 breaks chart/rangeBand unit test --- package-lock.json | 2 +- test/chart/layout.js | 8 ++++---- test/chart/rangeBand.js | 5 ++++- test/testNewUnitTests.js | 6 +----- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index b145075..072ea92 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2036,7 +2036,7 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, diff --git a/test/chart/layout.js b/test/chart/layout.js index d9ab1b3..c3f1fb5 100644 --- a/test/chart/layout.js +++ b/test/chart/layout.js @@ -36,7 +36,7 @@ export default function testLayout(settings, data) { it('creates an x-axis g child element of svg', () => { const xAxis = svgChildren.filter( child => - child.nodeName.toLowerCase() === 'g' && child.className.indexOf('x axis') > -1 + child.nodeName.toLowerCase() === 'g' && [...child.classList].join(' ').indexOf('x axis') > -1 ); expect(xAxis.length).toEqual(1); }); @@ -44,7 +44,7 @@ export default function testLayout(settings, data) { it('creates a y-axis g child element of svg', () => { const yAxis = svgChildren.filter( child => - child.nodeName.toLowerCase() === 'g' && child.className.indexOf('y axis') > -1 + child.nodeName.toLowerCase() === 'g' && [...child.classList].join(' ').indexOf('y axis') > -1 ); expect(yAxis.length).toEqual(1); }); @@ -53,7 +53,7 @@ export default function testLayout(settings, data) { const overlay = svgChildren.filter( child => child.nodeName.toLowerCase() === 'rect' && - child.className.indexOf('overlay') > -1 + [...child.classList].join(' ').indexOf('overlay') > -1 ); expect(overlay.length).toEqual(1); }); @@ -64,7 +64,7 @@ export default function testLayout(settings, data) { .filter( child => child.nodeName.toLowerCase() === 'ul' && - child.className.indexOf('legend') > -1 + [...child.classList].join(' ').indexOf('legend') > -1 ); expect(legend.length).toEqual(1); }); diff --git a/test/chart/rangeBand.js b/test/chart/rangeBand.js index 2bae037..9ce1b08 100644 --- a/test/chart/rangeBand.js +++ b/test/chart/rangeBand.js @@ -10,7 +10,10 @@ export default function testRangeBand(settings, data) { //DOM setup before(() => { - container = window.document.createElement('div'); + dom = new JSDOM(''); + container = dom.window.document.createElement('div'); + chart = createChart(container, settings); + chart.init(data, true); }); //Chart initialization diff --git a/test/testNewUnitTests.js b/test/testNewUnitTests.js index 7d0870e..11ce233 100644 --- a/test/testNewUnitTests.js +++ b/test/testNewUnitTests.js @@ -1,5 +1 @@ -import './chart/rangeBand'; -import testRangeBand from './chart/rangeBand'; -import { ordinal_ordinal as ordinal_ordinal_rb } from './samples/irisSettings'; -import rangeBandData from './samples/irisData'; -testRangeBand(ordinal_ordinal_rb, rangeBandData); +//import './folder/unit-test';