diff --git a/build/webcharts.js b/build/webcharts.js index a0f4a51..c24d660 100644 --- a/build/webcharts.js +++ b/build/webcharts.js @@ -39,7 +39,7 @@ this.initial_data = data; var startup = function startup(data) { - //connect this chart and its controls, if any + // connect this chart and its controls, if any if (_this.controls) { _this.controls.targets.push(_this); @@ -48,7 +48,7 @@ } else { _this.controls.layout(); } - } //make sure container is visible (has height and width) before trying to initialize + } // make sure container is visible (has height and width) before trying to initialize var visible = d3.select(_this.div).property('offsetWidth') > 0 || test; @@ -120,7 +120,7 @@ requiredCols.push(e.split); } - if (e.values) { + if (e.values && e.checkColumns) { for (var value in e.values) { requiredVars.push('this.config.marks[' + i + "].values['" + value + "']"); requiredCols.push(value); @@ -550,7 +550,7 @@ ? d : filter.val instanceof Array ? filter.val.indexOf(d[filter.col]) > -1 - : d[filter.col] === filter.val; + : d[filter.col] + '' === filter.val + ''; }); }); } //Summarize data for each mark. @@ -600,6 +600,7 @@ 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); + m.checkColumns = m.checkColumns !== false ? true : false; }); this.config.date_format = this.config.date_format || '%x'; this.config.padding = this.config.padding !== undefined ? this.config.padding : 0.3; @@ -776,18 +777,27 @@ 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); + var sort; + + if (_this.config.x.type === 'time') { + sort = d3.ascending(new Date(a), new Date(b)); + } else if (_this.config.x.order) { + sort = d3.ascending( + _this.config.x.order.indexOf(a), + _this.config.x.order.indexOf(b) + ); + } else if (sublevel === _this.config.color_by && _this.config.legend.order) { + sort = d3.ascending( + _this.config.legend.order.indexOf(a), + _this.config.legend.order.indexOf(b) + ); + } else if (_this.config.x.type === 'ordinal' || _this.config.y.type === 'ordinal') { + sort = naturalSorter(a, b); + } else { + sort = d3.ascending(+a, +b); + } + + return sort; }); } @@ -1106,7 +1116,7 @@ ? d : e.val instanceof Array ? e.val.indexOf(d[e.col]) > -1 - : d[e.col] === e.val; + : d[e.col] + '' === e.val.toString() + ''; }); }); //get domain for all non-All values of first filter @@ -1292,10 +1302,8 @@ return m[config.color_by]; }) ) - .values() - .filter(function(f) { - return f && f !== 'undefined'; - }); + .values(); //.filter(f => 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)); @@ -1863,541 +1871,565 @@ return area_grps; } - function drawBars(marks) { + function xOrdinal(oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars) { 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 + oldBarsTrans.attr('y', this.y(0)).attr('height', 0); + oldBarGroupsTrans.remove(); + nu_bar_groups = bar_groups .enter() .append('g') .attr('class', function(d) { - return 'supergroup bar-supergroup ' + d.id; + return 'bar-group ' + d.key; }); - bar_supergroups.exit().remove(); - var bar_groups = bar_supergroups.selectAll('.bar-group').data( + nu_bar_groups.append('title'); + bars = bar_groups.selectAll('rect').data( function(d) { - return d.data; + return d.values instanceof Array + ? d.values.sort(function(a, b) { + return ( + _this.colorScale.domain().indexOf(a.key) - + _this.colorScale.domain().indexOf(b.key) + ); + }) // controls the order of the bars in the DOM + : [d]; }, function(d) { return d.key; } ); - var old_bar_groups = bar_groups.exit(); - var nu_bar_groups; - var bars; - 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; + 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(#'.concat(chart.id, ')')) + .attr('y', this.y(0)) + .attr('height', 0) + .append('title'); // sort bars in DOM to display widest bar behind every other bar and narrowest bar in front of every other bar - that's poorly worded but you get the gist - 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; - } + bars.sort(function(a, b) { + return ( + _this.colorScale.domain().indexOf(a.key) - _this.colorScale.domain().indexOf(b.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(#'.concat(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]; - }); + }); + 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]); }); - var barsTrans = config.transitions ? bars.transition() : bars; - barsTrans - .attr('x', function(d) { - var position; - - 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) { - 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) - ); + 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() + : mark.values && mark.values[mark.split] + ? mark.values[mark.split] + : d3 + .set( + rawData.map(function(m) { + return m[mark.split]; }) - : [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(); + ) + .values() + .sort(); // controls the order of the bars in the chart - bars.enter() - .append('rect') - .attr('class', function(d) { - return 'wc-data-mark bar ' + d.key; + d3.select(this).attr(mark.attributes); + }); + var xformat = + config.marks + .map(function(m) { + return m.summarizeX === 'percent'; }) - .style('clip-path', 'url(#'.concat(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]); + .indexOf(true) > -1 + ? d3.format('0%') + : d3.format(config.x.format); + var yformat = + config.marks + .map(function(m) { + return m.summarizeY === 'percent'; }) - .attr('fill', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); + .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]; }); - 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 barsTrans = config.transitions ? bars.transition() : bars; + barsTrans + .attr('x', function(d) { + var position; - var _xformat = - config.marks - .map(function(m) { - return m.summarizeX === 'percent'; - }) - .indexOf(true) > -1 - ? d3.format('0%') - : d3.format(config.x.format); + 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 _yformat = - config.marks - .map(function(m) { - return m.summarizeY === 'percent'; - }) - .indexOf(true) > -1 - ? d3.format('0%') - : d3.format(config.y.format); + 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); + }); + } - 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]; - }); + function yOrdinal(oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars) { + var _this = this; + + var chart = this; + var rawData = this.raw_data; + var config = this.config; + 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(a.key) - + _this.colorScale.domain().indexOf(b.key) + ); + }) // controls the order of the bars in the DOM + : [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(#'.concat(chart.id, ')')) + .attr('x', this.x(0)) + .attr('width', 0) + .append('title'); // sort bars in DOM to display widest bar behind every other bar and narrowest bar in front of every other bar - that's poorly worded but you get the gist - var _barsTrans = config.transitions ? bars.transition() : bars; + bars.sort(function(a, b) { + return ( + _this.colorScale.domain().indexOf(a.key) - _this.colorScale.domain().indexOf(b.key) + ); + }); + 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() + : mark.values && mark.values[mark.split] + ? mark.values[mark.split] + : d3 + .set( + rawData.map(function(m) { + return m[mark.split]; + }) + ) + .values() + .sort(); // controls the order of the bars in the chart - _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); - } + d3.select(this).attr(mark.attributes); + }); + var xformat = + config.marks + .map(function(m) { + return m.summarizeX === 'percent'; }) - .attr('width', function(d) { - return _this.x(d.values.x) - _this.x(0); + .indexOf(true) > -1 + ? d3.format('0%') + : d3.format(config.x.format); + var yformat = + config.marks + .map(function(m) { + return m.summarizeY === 'percent'; }) - .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) { - return 'bar-group ' + d.key; + .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]; }); - 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 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); } - ); - - var _exitBars2 = config.transitions ? bars.exit().transition() : bars.exit(); - - _exitBars2 - .attr('y', this.y(0)) - .attr('height', 0) - .remove(); + }) + .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 _position = d.subcats.indexOf(d.key); - bars.enter() - .append('rect') - .attr('class', function(d) { - return 'wc-data-mark bar ' + d.key; - }) - .style('clip-path', 'url(#'.concat(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; + return ( + _this.y(d.values.y) + (_this.y.rangeBand() / d.subcats.length) * _position + ); + } 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(); + } }); + } - 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); + function xBin(oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars) { + var _this = this; - 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 chart = this; + var rawData = this.raw_data; + var config = this.config; + 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; }); - - 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); - } + 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 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(#'.concat(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 xformat = + config.marks + .map(function(m) { + return m.summarizeX === 'percent'; }) - .attr('width', function(d) { - return _this.x(d.rangeHigh) - _this.x(d.rangeLow); + .indexOf(true) > -1 + ? d3.format('0%') + : d3.format(config.x.format); + var yformat = + config.marks + .map(function(m) { + return m.summarizeY === 'percent'; }) - .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; + .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]; }); - 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 barsTrans = config.transitions ? bars.transition() : bars; + barsTrans + .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); } - ); - - var _exitBars3 = config.transitions ? bars.exit().transition() : bars.exit(); + }) + .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); + }); + } - _exitBars3 - .attr('x', this.x(0)) - .attr('width', 0) - .remove(); + function yBin(oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars) { + var _this = this; - bars.enter() - .append('rect') - .attr('class', function(d) { - return 'wc-data-mark bar ' + d.key; + var chart = this; + var rawData = this.raw_data; + var config = this.config; + 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 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(#'.concat(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 xformat = + config.marks + .map(function(m) { + return m.summarizeX === 'percent'; }) - .style('clip-path', 'url(#'.concat(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]); + .indexOf(true) > -1 + ? d3.format('0%') + : d3.format(config.x.format); + var yformat = + config.marks + .map(function(m) { + return m.summarizeY === 'percent'; }) - .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; + .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]; }); - d.rangeLow = d3.min(rangeSet); - d.rangeHigh = d3.max(rangeSet); - d.tooltip = mark.tooltip; + }); + var barsTrans = config.transitions ? bars.transition() : bars; + barsTrans + .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); }); + } - 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); + function drawBars(marks) { + var rawData = this.raw_data; + var config = this.config; // bar super-groups - 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 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(); // bar groups - var _barsTrans3 = config.transitions ? bars.transition() : bars; + 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; + var bars; // bar transitions - _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); - }); + 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') { + xOrdinal.call(this, oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars); + } else if (config.y.type === 'ordinal') { + yOrdinal.call(this, oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars); + } else if (['linear', 'log'].indexOf(config.x.type) > -1 && config.x.bin) { + xBin.call(this, oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars); + } else if ( + ['linear', 'log'].indexOf(config.y.type) > -1 && + config.y.type === 'linear' && + config.y.bin + ) { + yBin.call(this, oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars); } else { oldBarsTrans.attr('y', this.y(0)).attr('height', 0); oldBarGroupsTrans.remove(); @@ -2546,7 +2578,7 @@ .append('circle') .attr('class', 'wc-data-mark') .attr('r', 0); - nupoints.append('title'); //static attributes + nupoints.append('title'); // static attributes points .select('circle') @@ -2560,7 +2592,7 @@ }) .attr('stroke', function(d) { return _this.colorScale(d.values.raw[0][config.color_by]); - }); //attach mark info + }); // attach mark info points.each(function(d) { var mark = d3.select(this.parentNode).datum(); @@ -2568,7 +2600,7 @@ d3.select(this) .select('circle') .attr(mark.attributes); - }); //animated attributes + }); // animated attributes var pointsTrans = config.transitions ? points.select('circle').transition() @@ -2611,13 +2643,29 @@ .replace(/\[(.+?)\]/g, function(str, orig) { return d.values.raw[0][orig]; }); - }); //Link to the d3.selection from the data + }); // Link to the d3.selection from the data point_supergroups.each(function(d) { d.supergroup = d3.select(this); d.groups = d.supergroup.selectAll('g.point'); d.circles = d.groups.select('circle'); + }); // expand the plotting area slightly to prevent mark cutoff + + var radius = d3.max(marks, function(mark) { + return mark.radius || _this.config.flex_point_size; }); + this.svg + .select('.plotting-area') + .attr('width', this.plot_width + radius * 2 + 2) // plot width + circle radius * 2 + circle stroke width * 2 + .attr('height', this.plot_height + radius * 2 + 2) // plot height + circle radius * 2 + circle stroke width * 2 + .attr( + 'transform', + 'translate(-' + + (radius + 1) + // translate left circle radius + circle stroke width + ',-' + + (radius + 1) + // translate up circle radius + circle stroke width + ')' + ); return points; } @@ -2626,17 +2674,17 @@ var chart = this; var config = this.config; - var textSupergroups = this.svg.selectAll('.text-supergroup').data(marks, function(d, i) { + var text_supergroups = this.svg.selectAll('.text-supergroup').data(marks, function(d, i) { return ''.concat(i, '-').concat(d.per.join('-')); }); - textSupergroups + text_supergroups .enter() .append('g') .attr('class', function(d) { return 'supergroup text-supergroup ' + d.id; }); - textSupergroups.exit().remove(); - var texts = textSupergroups.selectAll('.text').data( + text_supergroups.exit().remove(); + var texts = text_supergroups.selectAll('.text').data( function(d) { return d.data; }, @@ -2713,9 +2761,9 @@ .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 + }); // add a reference to the selection from it's data - textSupergroups.each(function(d) { + text_supergroups.each(function(d) { d.supergroup = d3.select(this); d.groups = d.supergroup.selectAll('g.text'); d.texts = d.groups.select('text'); @@ -3171,14 +3219,10 @@ ? control.values : d3 .set( - this.data - .map(function(m) { - return m[control.value_col]; - }) - .filter(function(f) { - return f; - }) - ) + this.data.map(function(m) { + return m[control.value_col]; + }) + ) //.filter(f => f)) .values() .sort(naturalSorter); // only sort when values are derived //initial dropdown option @@ -3402,7 +3446,7 @@ ); }) ) { - this.data.filtered = this.data.raw; + this.data.filtered = this.data.raw.slice(); this.filters .filter(function(filter) { return ( @@ -3418,7 +3462,7 @@ : filter.val === d[filter.col]; }); }); - } else this.data.filtered = this.data.raw; + } else this.data.filtered = this.data.raw.slice(); } function updateDataObject() { @@ -3922,7 +3966,8 @@ key: col }) .classed('wc-button sort-box', true) - .text(header) + .text(header), + type: this.config.types[col] }; sortItem.wrap .append('span') @@ -3968,6 +4013,25 @@ this.draw(); } + function _typeof(obj) { + if (typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol') { + _typeof = function(obj) { + return typeof obj; + }; + } else { + _typeof = function(obj) { + return obj && + typeof Symbol === 'function' && + obj.constructor === Symbol && + obj !== Symbol.prototype + ? 'symbol' + : typeof obj; + }; + } + + return _typeof(obj); + } + function sortData(data) { var _this = this; @@ -3975,20 +4039,24 @@ var order = 0; _this.sortable.order.forEach(function(item) { - var aCell = a[item.col], - bCell = b[item.col]; + var aCell = a[item.col]; + var 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.type === 'number') { + order = item.direction === 'ascending' ? +aCell - +bCell : +bCell - +aCell; + } else { + 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; + } } }); @@ -4347,30 +4415,39 @@ } 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; - } + var _this = this; - this.config.cols = this.config.cols || d3.keys(firstItem); - this.config.headers = this.config.headers || this.config.cols; - this.config.layout = 'horizontal'; // placeholder setting to align table components vertically or horizontally - //Set all other defaults. + // cols + if ( + !Array.isArray(this.config.cols) || + (Array.isArray(this.config.cols) && this.config.cols.length === 0) + ) + this.config.cols = d3.keys(firstItem); // headers + + if ( + !Array.isArray(this.config.headers) || + (Array.isArray(this.config.headers) && this.config.headers.length === 0) || + (Array.isArray(this.config.headers) && + this.config.headers.length !== this.config.cols.length) + ) + this.config.headers = this.config.cols.slice(); // types + + if (_typeof(this.config.types) !== 'object') this.config.types = {}; + this.config.cols.forEach(function(col) { + if (!['string', 'number'].includes(_this.config.types[col])) + _this.config.types[col] = 'string'; + }); // Set all other defaults. setDefault.call(this, 'searchable'); - setDefault.call(this, 'exportable'); - setDefault.call(this, 'exports', ['csv']); setDefault.call(this, 'sortable'); setDefault.call(this, 'pagination'); + setDefault.call(this, 'exportable'); + setDefault.call(this, 'exports', ['csv']); setDefault.call(this, 'nRowsPerPage', 10); setDefault.call(this, 'nPageLinksDisplayed', 5); setDefault.call(this, 'applyCSS'); setDefault.call(this, 'dynamicPositioning'); + setDefault.call(this, 'layout', 'horizontal'); } function transformData$1(processed_data) { @@ -4508,6 +4585,7 @@ } }); + var tableCount = 0; function createTable() { var element = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'body'; var config = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; @@ -4540,8 +4618,10 @@ if (callback) { thisTable.events['on' + event.charAt(0).toUpperCase() + event.slice(1)] = callback; } - }; + }; //increment thisChart count to get unique thisChart id + tableCount++; + thisTable.id = tableCount; return thisTable; } diff --git a/build/webcharts.min.js b/build/webcharts.min.js index 517e760..4c3c426 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=global||self,global.webCharts=factory(global.d3))})(this,function(d3){"use strict";var version="1.11.7";function init(data){var _this=this;var test=arguments.length>1&&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.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();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,j;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;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;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;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;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 _this=this;var class_match=arguments.length>3&&arguments[3]!==undefined?arguments[3]:"chart-area";var bind_accessor=arguments.length>4?arguments[4]:undefined;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;var bars;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(#".concat(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;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(#".concat(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(#".concat(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(#".concat(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(#".concat(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(#".concat(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"".concat(i,"-").concat(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"".concat(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(#".concat(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;if(!this.test)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 "'.concat(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?"".concat(this.data.raw.length," records displayed"):"".concat(this.data.processing.length,"/").concat(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: ".concat(fileType))});var fileName="webchartsTableExport_".concat(d3.time.format("%Y-%m-%dT%H-%M-%S")(new Date),".").concat(fileType);var link=this.wrap.select(".export#".concat(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'"'.concat(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'"'.concat(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:".concat(String.fromCharCode(64+_this.config.cols.length)).concat(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();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=global||self,global.webCharts=factory(global.d3))})(this,function(d3){"use strict";var version="1.11.7";function init(data){var _this=this;var test=arguments.length>1&&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.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();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&&e.checkColumns){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,j;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);m.checkColumns=m.checkColumns!==false?true:false});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;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){var sort;if(_this.config.x.type==="time"){sort=d3.ascending(new Date(a),new Date(b))}else if(_this.config.x.order){sort=d3.ascending(_this.config.x.order.indexOf(a),_this.config.x.order.indexOf(b))}else if(sublevel===_this.config.color_by&&_this.config.legend.order){sort=d3.ascending(_this.config.legend.order.indexOf(a),_this.config.legend.order.indexOf(b))}else if(_this.config.x.type==="ordinal"||_this.config.y.type==="ordinal"){sort=naturalSorter(a,b)}else{sort=d3.ascending(+a,+b)}return sort})}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;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.toString()+""})});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();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;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;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 _this=this;var class_match=arguments.length>3&&arguments[3]!==undefined?arguments[3]:"chart-area";var bind_accessor=arguments.length>4?arguments[4]:undefined;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 xOrdinal(oldBarsTrans,oldBarGroupsTrans,nu_bar_groups,bar_groups,bars){var _this=this;var chart=this;var rawData=this.raw_data;var config=this.config;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(a.key)-_this.colorScale.domain().indexOf(b.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(#".concat(chart.id,")")).attr("y",this.y(0)).attr("height",0).append("title");bars.sort(function(a,b){return _this.colorScale.domain().indexOf(a.key)-_this.colorScale.domain().indexOf(b.key)});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():mark.values&&mark.values[mark.split]?mark.values[mark.split]:d3.set(rawData.map(function(m){return m[mark.split]})).values().sort();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;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)})}function yOrdinal(oldBarsTrans,oldBarGroupsTrans,nu_bar_groups,bar_groups,bars){var _this=this;var chart=this;var rawData=this.raw_data;var config=this.config;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(a.key)-_this.colorScale.domain().indexOf(b.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(#".concat(chart.id,")")).attr("x",this.x(0)).attr("width",0).append("title");bars.sort(function(a,b){return _this.colorScale.domain().indexOf(a.key)-_this.colorScale.domain().indexOf(b.key)});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():mark.values&&mark.values[mark.split]?mark.values[mark.split]:d3.set(rawData.map(function(m){return m[mark.split]})).values().sort();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 _position=d.subcats.indexOf(d.key);return _this.y(d.values.y)+_this.y.rangeBand()/d.subcats.length*_position}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()}})}function xBin(oldBarsTrans,oldBarGroupsTrans,nu_bar_groups,bar_groups,bars){var _this=this;var chart=this;var rawData=this.raw_data;var config=this.config;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 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(#".concat(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 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){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)})}function yBin(oldBarsTrans,oldBarGroupsTrans,nu_bar_groups,bar_groups,bars){var _this=this;var chart=this;var rawData=this.raw_data;var config=this.config;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 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(#".concat(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 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"){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)})}function drawBars(marks){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;var bars;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"){xOrdinal.call(this,oldBarsTrans,oldBarGroupsTrans,nu_bar_groups,bar_groups,bars)}else if(config.y.type==="ordinal"){yOrdinal.call(this,oldBarsTrans,oldBarGroupsTrans,nu_bar_groups,bar_groups,bars)}else if(["linear","log"].indexOf(config.x.type)>-1&&config.x.bin){xBin.call(this,oldBarsTrans,oldBarGroupsTrans,nu_bar_groups,bar_groups,bars)}else if(["linear","log"].indexOf(config.y.type)>-1&&config.y.type==="linear"&&config.y.bin){yBin.call(this,oldBarsTrans,oldBarGroupsTrans,nu_bar_groups,bar_groups,bars)}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(#".concat(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(#".concat(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")});var radius=d3.max(marks,function(mark){return mark.radius||_this.config.flex_point_size});this.svg.select(".plotting-area").attr("width",this.plot_width+radius*2+2).attr("height",this.plot_height+radius*2+2).attr("transform","translate(-"+(radius+1)+",-"+(radius+1)+")");return points}function drawText(marks){var _this=this;var chart=this;var config=this.config;var text_supergroups=this.svg.selectAll(".text-supergroup").data(marks,function(d,i){return"".concat(i,"-").concat(d.per.join("-"))});text_supergroups.enter().append("g").attr("class",function(d){return"supergroup text-supergroup "+d.id});text_supergroups.exit().remove();var texts=text_supergroups.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"".concat(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(#".concat(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});text_supergroups.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;if(!this.test)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 "'.concat(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]})).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.slice()}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?"".concat(this.data.raw.length," records displayed"):"".concat(this.data.processing.length,"/").concat(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: ".concat(fileType))});var fileName="webchartsTableExport_".concat(d3.time.format("%Y-%m-%dT%H-%M-%S")(new Date),".").concat(fileType);var link=this.wrap.select(".export#".concat(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'"'.concat(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'"'.concat(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:".concat(String.fromCharCode(64+_this.config.cols.length)).concat(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),type:this.config.types[col]};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 _typeof(obj){if(typeof Symbol==="function"&&typeof Symbol.iterator==="symbol"){_typeof=function(obj){return typeof obj}}else{_typeof=function(obj){return obj&&typeof Symbol==="function"&&obj.constructor===Symbol&&obj!==Symbol.prototype?"symbol":typeof obj}}return _typeof(obj)}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];var bCell=b[item.col];if(item.type==="number"){order=item.direction==="ascending"?+aCell-+bCell:+bCell-+aCell}else{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();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){var _this=this;if(!Array.isArray(this.config.cols)||Array.isArray(this.config.cols)&&this.config.cols.length===0)this.config.cols=d3.keys(firstItem);if(!Array.isArray(this.config.headers)||Array.isArray(this.config.headers)&&this.config.headers.length===0||Array.isArray(this.config.headers)&&this.config.headers.length!==this.config.cols.length)this.config.headers=this.config.cols.slice();if(_typeof(this.config.types)!=="object")this.config.types={};this.config.cols.forEach(function(col){if(!["string","number"].includes(_this.config.types[col]))_this.config.types[col]="string"});setDefault.call(this,"searchable");setDefault.call(this,"sortable");setDefault.call(this,"pagination");setDefault.call(this,"exportable");setDefault.call(this,"exports",["csv"]);setDefault.call(this,"nRowsPerPage",10);setDefault.call(this,"nPageLinksDisplayed",5);setDefault.call(this,"applyCSS");setDefault.call(this,"dynamicPositioning");setDefault.call(this,"layout","horizontal")}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}});var tableCount=0;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}};tableCount++;thisTable.id=tableCount;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/src/chart/draw/consolidateData.js b/src/chart/draw/consolidateData.js index e9200c3..3f18049 100644 --- a/src/chart/draw/consolidateData.js +++ b/src/chart/draw/consolidateData.js @@ -14,7 +14,7 @@ export default function consolidateData(raw) { ? d : filter.val instanceof Array ? filter.val.indexOf(d[filter.col]) > -1 - : d[filter.col] === filter.val; + : d[filter.col] + '' === filter.val + ''; }); }); } diff --git a/src/chart/draw/consolidateData/setDefaults.js b/src/chart/draw/consolidateData/setDefaults.js index d212d61..def69ab 100644 --- a/src/chart/draw/consolidateData/setDefaults.js +++ b/src/chart/draw/consolidateData/setDefaults.js @@ -25,6 +25,7 @@ export default function setDefaults() { 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); + m.checkColumns = m.checkColumns !== false ? true : false; }); this.config.date_format = this.config.date_format || '%x'; diff --git a/src/chart/draw/consolidateData/transformData.js b/src/chart/draw/consolidateData/transformData.js index 5eab8a3..5f85e24 100644 --- a/src/chart/draw/consolidateData/transformData.js +++ b/src/chart/draw/consolidateData/transformData.js @@ -80,7 +80,7 @@ export default function transformData(raw, mark) { ? d : e.val instanceof Array ? e.val.indexOf(d[e.col]) > -1 - : d[e.col] === e.val; + : d[e.col] + '' === e.val.toString() + ''; }); }); //get domain for all non-All values of first filter diff --git a/src/chart/draw/consolidateData/transformData/makeNest.js b/src/chart/draw/consolidateData/transformData/makeNest.js index 65f343e..4078ab5 100644 --- a/src/chart/draw/consolidateData/transformData/makeNest.js +++ b/src/chart/draw/consolidateData/transformData/makeNest.js @@ -32,18 +32,24 @@ export default function makeNest(mark, entries, sublevel) { if (sublevel) { this_nest.key(d => d[sublevel]); this_nest.sortKeys((a, b) => { - return this.config.x.type === 'time' - ? ascending(new Date(a), new Date(b)) - : this.config.x.order - ? ascending(this.config.x.order.indexOf(a), this.config.x.order.indexOf(b)) - : sublevel === this.config.color_by && this.config.legend.order - ? 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) - : ascending(+a, +b); + let sort; + + if (this.config.x.type === 'time') { + sort = ascending(new Date(a), new Date(b)); + } else if (this.config.x.order) { + sort = ascending(this.config.x.order.indexOf(a), this.config.x.order.indexOf(b)); + } else if (sublevel === this.config.color_by && this.config.legend.order) { + sort = ascending( + this.config.legend.order.indexOf(a), + this.config.legend.order.indexOf(b) + ); + } else if (this.config.x.type === 'ordinal' || this.config.y.type === 'ordinal') { + sort = naturalSorter(a, b); + } else { + sort = ascending(+a, +b); + } + + return sort; }); } this_nest.rollup(r => { diff --git a/src/chart/draw/setColorScale.js b/src/chart/draw/setColorScale.js index 7bb76f3..8efeb35 100644 --- a/src/chart/draw/setColorScale.js +++ b/src/chart/draw/setColorScale.js @@ -7,9 +7,8 @@ export default function setColorScale() { const colordom = Array.isArray(config.color_dom) && config.color_dom.length ? config.color_dom.slice() - : set(data.map(m => m[config.color_by])) - .values() - .filter(f => f && f !== 'undefined'); + : set(data.map(m => m[config.color_by])).values(); + //.filter(f => f && f !== 'undefined'); if (config.legend.order) colordom.sort((a, b) => diff --git a/src/chart/init.js b/src/chart/init.js index 1208974..1396e14 100644 --- a/src/chart/init.js +++ b/src/chart/init.js @@ -26,7 +26,7 @@ export default function init(data, test = false) { this.initial_data = data; let startup = data => { - //connect this chart and its controls, if any + // connect this chart and its controls, if any if (this.controls) { this.controls.targets.push(this); if (!this.controls.ready) { @@ -36,7 +36,7 @@ export default function init(data, test = false) { } } - //make sure container is visible (has height and width) before trying to initialize + // make sure container is visible (has height and width) before trying to initialize var visible = select(this.div).property('offsetWidth') > 0 || test; if (!visible) { console.warn( diff --git a/src/chart/init/checkRequired.js b/src/chart/init/checkRequired.js index a879e38..ca2a1e0 100644 --- a/src/chart/init/checkRequired.js +++ b/src/chart/init/checkRequired.js @@ -28,7 +28,7 @@ export default function checkRequired(data) { requiredVars.push('this.config.marks[' + i + '].split'); requiredCols.push(e.split); } - if (e.values) { + if (e.values && e.checkColumns) { for (const value in e.values) { requiredVars.push('this.config.marks[' + i + "].values['" + value + "']"); requiredCols.push(value); diff --git a/src/chart/resize/updateDataMarks/drawBars.js b/src/chart/resize/updateDataMarks/drawBars.js index cf6fa73..67c0261 100644 --- a/src/chart/resize/updateDataMarks/drawBars.js +++ b/src/chart/resize/updateDataMarks/drawBars.js @@ -1,404 +1,52 @@ import { select, set, format, min, max } from 'd3'; +import xOrdinal from './drawBars/xOrdinal'; +import yOrdinal from './drawBars/yOrdinal'; +import xBin from './drawBars/xBin'; +import yBin from './drawBars/yBin'; export default function drawBars(marks) { - let chart = this; - let rawData = this.raw_data; - let config = this.config; + const chart = this; + const rawData = this.raw_data; + const config = this.config; - let bar_supergroups = this.svg + // bar super-groups + const bar_supergroups = this.svg .selectAll('.bar-supergroup') .data(marks, (d, i) => i + '-' + d.per.join('-')); - bar_supergroups .enter() .append('g') .attr('class', d => 'supergroup bar-supergroup ' + d.id); - bar_supergroups.exit().remove(); - let bar_groups = bar_supergroups.selectAll('.bar-group').data( + // bar groups + const bar_groups = bar_supergroups.selectAll('.bar-group').data( d => d.data, d => d.key ); - let old_bar_groups = bar_groups.exit(); + const old_bar_groups = bar_groups.exit(); let nu_bar_groups; let bars; - let oldBarsTrans = config.transitions + // bar transitions + const oldBarsTrans = config.transitions ? old_bar_groups.selectAll('.bar').transition() : old_bar_groups.selectAll('.bar'); - let oldBarGroupsTrans = config.transitions ? old_bar_groups.transition() : old_bar_groups; + const 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', d => 'bar-group ' + d.key); - nu_bar_groups.append('title'); - - bars = bar_groups.selectAll('rect').data( - d => { - return d.values instanceof Array - ? d.values.sort( - (a, b) => - this.colorScale.domain().indexOf(b.key) - - this.colorScale.domain().indexOf(a.key) - ) - : [d]; - }, - d => d.key - ); - - let exitBars = config.transitions ? bars.exit().transition() : bars.exit(); - exitBars - .attr('y', this.y(0)) - .attr('height', 0) - .remove(); - bars.enter() - .append('rect') - .attr('class', d => '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', d => this.colorScale(d.values.raw[0][config.color_by])) - .attr('fill', d => this.colorScale(d.values.raw[0][config.color_by])); - - bars.each(function(d) { - let mark = 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] - : set(rawData.map(m => m[mark.split])).values(); - select(this).attr(mark.attributes); - }); - - let xformat = - config.marks.map(m => m.summarizeX === 'percent').indexOf(true) > -1 - ? format('0%') - : format(config.x.format); - let yformat = - config.marks.map(m => m.summarizeY === 'percent').indexOf(true) > -1 - ? format('0%') - : format(config.y.format); - bars.select('title').text(d => { - let tt = d.tooltip || ''; - return tt - .replace(/\$x/g, xformat(d.values.x)) - .replace(/\$y/g, yformat(d.values.y)) - .replace(/\[(.+?)\]/g, (str, orig) => d.values.raw[0][orig]); - }); - - let barsTrans = config.transitions ? bars.transition() : bars; - barsTrans - .attr('x', d => { - let position; - if (!d.arrange || d.arrange === 'stacked') { - return this.x(d.values.x); - } else if (d.arrange === 'nested') { - let position = d.subcats.indexOf(d.key); - let 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', d => { - if (d.arrange !== 'stacked') { - return this.y(d.values.y); - } else { - return this.y(d.values.start); - } - }) - .attr('width', d => { - if (!d.arrange || d.arrange === 'stacked') { - return this.x.rangeBand(); - } else if (d.arrange === 'nested') { - let 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', d => this.y(0) - this.y(d.values.y)); + xOrdinal.call(this, oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars); } 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', d => 'bar-group ' + d.key); - nu_bar_groups.append('title'); - - bars = bar_groups.selectAll('rect').data( - d => { - return d.values instanceof Array - ? d.values.sort( - (a, b) => - this.colorScale.domain().indexOf(b.key) - - this.colorScale.domain().indexOf(a.key) - ) - : [d]; - }, - d => d.key - ); - - let exitBars = config.transitions ? bars.exit().transition() : bars.exit(); - exitBars - .attr('x', this.x(0)) - .attr('width', 0) - .remove(); - bars.enter() - .append('rect') - .attr('class', d => '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', d => this.colorScale(d.values.raw[0][config.color_by])) - .attr('fill', d => this.colorScale(d.values.raw[0][config.color_by])); - - bars.each(function(d) { - let mark = 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] - : set(rawData.map(m => m[mark.split])).values(); - d.tooltip = mark.tooltip; - select(this).attr(mark.attributes); - }); - - let xformat = - config.marks.map(m => m.summarizeX === 'percent').indexOf(true) > -1 - ? format('0%') - : format(config.x.format); - let yformat = - config.marks.map(m => m.summarizeY === 'percent').indexOf(true) > -1 - ? format('0%') - : format(config.y.format); - bars.select('title').text(d => { - let tt = d.tooltip || ''; - return tt - .replace(/\$x/g, xformat(d.values.x)) - .replace(/\$y/g, yformat(d.values.y)) - .replace(/\[(.+?)\]/g, (str, orig) => d.values.raw[0][orig]); - }); - - let barsTrans = config.transitions ? bars.transition() : bars; - barsTrans - .attr('x', 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', d => { - if (d.arrange === 'nested') { - let position = d.subcats.indexOf(d.key); - let 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') { - let position = d.subcats.indexOf(d.key); - return this.y(d.values.y) + (this.y.rangeBand() / d.subcats.length) * position; - } else { - return this.y(d.values.y); - } - }) - .attr('width', d => this.x(d.values.x) - this.x(0)) - .attr('height', d => { - if (config.y.type === 'quantile') { - return 20; - } else if (d.arrange === 'nested') { - let 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(); - } - }); + yOrdinal.call(this, oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars); } 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', d => 'bar-group ' + d.key); - nu_bar_groups.append('title'); - - bars = bar_groups.selectAll('rect').data( - d => (d.values instanceof Array ? d.values : [d]), - d => d.key - ); - - let exitBars = config.transitions ? bars.exit().transition() : bars.exit(); - exitBars - .attr('y', this.y(0)) - .attr('height', 0) - .remove(); - bars.enter() - .append('rect') - .attr('class', d => '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', d => this.colorScale(d.values.raw[0][config.color_by])) - .attr('fill', d => this.colorScale(d.values.raw[0][config.color_by])); - - bars.each(function(d) { - let mark = 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] - : set(rawData.map(m => m[mark.split])).values(); - select(this).attr(mark.attributes); - let parent = select(this.parentNode).datum(); - let rangeSet = parent.key.split(',').map(m => +m); - d.rangeLow = min(rangeSet); - d.rangeHigh = max(rangeSet); - d.tooltip = mark.tooltip; - }); - - let xformat = - config.marks.map(m => m.summarizeX === 'percent').indexOf(true) > -1 - ? format('0%') - : format(config.x.format); - let yformat = - config.marks.map(m => m.summarizeY === 'percent').indexOf(true) > -1 - ? format('0%') - : format(config.y.format); - bars.select('title').text(d => { - let tt = d.tooltip || ''; - return tt - .replace(/\$x/g, xformat(d.values.x)) - .replace(/\$y/g, yformat(d.values.y)) - .replace(/\[(.+?)\]/g, (str, orig) => d.values.raw[0][orig]); - }); - - let barsTrans = config.transitions ? bars.transition() : bars; - barsTrans - .attr('x', d => this.x(d.rangeLow)) - .attr('y', d => { - if (d.arrange !== 'stacked') { - return this.y(d.values.y); - } else { - return this.y(d.values.start); - } - }) - .attr('width', d => this.x(d.rangeHigh) - this.x(d.rangeLow)) - .attr('height', d => this.y(0) - this.y(d.values.y)); + xBin.call(this, oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars); } 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', d => 'bar-group ' + d.key); - nu_bar_groups.append('title'); - - bars = bar_groups.selectAll('rect').data( - d => (d.values instanceof Array ? d.values : [d]), - d => d.key - ); - - let exitBars = config.transitions ? bars.exit().transition() : bars.exit(); - exitBars - .attr('x', this.x(0)) - .attr('width', 0) - .remove(); - bars.enter() - .append('rect') - .attr('class', d => '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', d => this.colorScale(d.values.raw[0][config.color_by])) - .attr('fill', d => this.colorScale(d.values.raw[0][config.color_by])); - - bars.each(function(d) { - let mark = 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] - : set(rawData.map(m => m[mark.split])).values(); - let parent = select(this.parentNode).datum(); - let rangeSet = parent.key.split(',').map(m => +m); - d.rangeLow = min(rangeSet); - d.rangeHigh = max(rangeSet); - d.tooltip = mark.tooltip; - }); - - let xformat = - config.marks.map(m => m.summarizeX === 'percent').indexOf(true) > -1 - ? format('0%') - : format(config.x.format); - let yformat = - config.marks.map(m => m.summarizeY === 'percent').indexOf(true) > -1 - ? format('0%') - : format(config.y.format); - bars.select('title').text(d => { - let tt = d.tooltip || ''; - return tt - .replace(/\$x/g, xformat(d.values.x)) - .replace(/\$y/g, yformat(d.values.y)) - .replace(/\[(.+?)\]/g, (str, orig) => d.values.raw[0][orig]); - }); - - let barsTrans = config.transitions ? bars.transition() : bars; - barsTrans - .attr('x', d => { - if (d.arrange === 'stacked') { - return this.x(d.values.start); - } else { - return this.x(0); - } - }) - .attr('y', d => this.y(d.rangeHigh)) - .attr('width', d => this.x(d.values.x)) - .attr('height', d => this.y(d.rangeLow) - this.y(d.rangeHigh)); + yBin.call(this, oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars); } else { oldBarsTrans.attr('y', this.y(0)).attr('height', 0); oldBarGroupsTrans.remove(); diff --git a/src/chart/resize/updateDataMarks/drawBars/xBin.js b/src/chart/resize/updateDataMarks/drawBars/xBin.js new file mode 100644 index 0000000..f03c30e --- /dev/null +++ b/src/chart/resize/updateDataMarks/drawBars/xBin.js @@ -0,0 +1,84 @@ +import { select, set, format, min, max } from 'd3'; + +export default function xBin(oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars) { + const chart = this; + const rawData = this.raw_data; + const config = this.config; + + oldBarsTrans.attr('y', this.y(0)).attr('height', 0); + + oldBarGroupsTrans.remove(); + + nu_bar_groups = bar_groups + .enter() + .append('g') + .attr('class', d => 'bar-group ' + d.key); + nu_bar_groups.append('title'); + + bars = bar_groups.selectAll('rect').data( + d => (d.values instanceof Array ? d.values : [d]), + d => d.key + ); + + let exitBars = config.transitions ? bars.exit().transition() : bars.exit(); + exitBars + .attr('y', this.y(0)) + .attr('height', 0) + .remove(); + bars.enter() + .append('rect') + .attr('class', d => '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', d => this.colorScale(d.values.raw[0][config.color_by])) + .attr('fill', d => this.colorScale(d.values.raw[0][config.color_by])); + + bars.each(function(d) { + let mark = 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] + : set(rawData.map(m => m[mark.split])).values(); + select(this).attr(mark.attributes); + let parent = select(this.parentNode).datum(); + let rangeSet = parent.key.split(',').map(m => +m); + d.rangeLow = min(rangeSet); + d.rangeHigh = max(rangeSet); + d.tooltip = mark.tooltip; + }); + + let xformat = + config.marks.map(m => m.summarizeX === 'percent').indexOf(true) > -1 + ? format('0%') + : format(config.x.format); + let yformat = + config.marks.map(m => m.summarizeY === 'percent').indexOf(true) > -1 + ? format('0%') + : format(config.y.format); + bars.select('title').text(d => { + let tt = d.tooltip || ''; + return tt + .replace(/\$x/g, xformat(d.values.x)) + .replace(/\$y/g, yformat(d.values.y)) + .replace(/\[(.+?)\]/g, (str, orig) => d.values.raw[0][orig]); + }); + + let barsTrans = config.transitions ? bars.transition() : bars; + barsTrans + .attr('x', d => this.x(d.rangeLow)) + .attr('y', d => { + if (d.arrange !== 'stacked') { + return this.y(d.values.y); + } else { + return this.y(d.values.start); + } + }) + .attr('width', d => this.x(d.rangeHigh) - this.x(d.rangeLow)) + .attr('height', d => this.y(0) - this.y(d.values.y)); +} diff --git a/src/chart/resize/updateDataMarks/drawBars/xOrdinal.js b/src/chart/resize/updateDataMarks/drawBars/xOrdinal.js new file mode 100644 index 0000000..a1796a1 --- /dev/null +++ b/src/chart/resize/updateDataMarks/drawBars/xOrdinal.js @@ -0,0 +1,121 @@ +import { select, set, format } from 'd3'; + +// TODO: merge xOrdinal and yOrdinal into a single function +export default function xOrdinal(oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars) { + const chart = this; + const rawData = this.raw_data; + const config = this.config; + + oldBarsTrans.attr('y', this.y(0)).attr('height', 0); + + oldBarGroupsTrans.remove(); + + nu_bar_groups = bar_groups + .enter() + .append('g') + .attr('class', d => 'bar-group ' + d.key); + nu_bar_groups.append('title'); + + bars = bar_groups.selectAll('rect').data( + d => { + return d.values instanceof Array + ? d.values.sort( + (a, b) => + this.colorScale.domain().indexOf(a.key) - + this.colorScale.domain().indexOf(b.key) + ) // controls the order of the bars in the DOM + : [d]; + }, + d => d.key + ); + + let exitBars = config.transitions ? bars.exit().transition() : bars.exit(); + exitBars + .attr('y', this.y(0)) + .attr('height', 0) + .remove(); + bars.enter() + .append('rect') + .attr('class', d => 'wc-data-mark bar ' + d.key) + .style('clip-path', `url(#${chart.id})`) + .attr('y', this.y(0)) + .attr('height', 0) + .append('title'); + + // sort bars in DOM to display widest bar behind every other bar and narrowest bar in front of every other bar - that's poorly worded but you get the gist + bars.sort( + (a, b) => this.colorScale.domain().indexOf(a.key) - this.colorScale.domain().indexOf(b.key) + ); + + bars.attr('shape-rendering', 'crispEdges') + .attr('stroke', d => this.colorScale(d.values.raw[0][config.color_by])) + .attr('fill', d => this.colorScale(d.values.raw[0][config.color_by])); + + bars.each(function(d) { + let mark = 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() + : mark.values && mark.values[mark.split] + ? mark.values[mark.split] + : set(rawData.map(m => m[mark.split])) + .values() + .sort(); // controls the order of the bars in the chart + select(this).attr(mark.attributes); + }); + + let xformat = + config.marks.map(m => m.summarizeX === 'percent').indexOf(true) > -1 + ? format('0%') + : format(config.x.format); + let yformat = + config.marks.map(m => m.summarizeY === 'percent').indexOf(true) > -1 + ? format('0%') + : format(config.y.format); + bars.select('title').text(d => { + let tt = d.tooltip || ''; + return tt + .replace(/\$x/g, xformat(d.values.x)) + .replace(/\$y/g, yformat(d.values.y)) + .replace(/\[(.+?)\]/g, (str, orig) => d.values.raw[0][orig]); + }); + + let barsTrans = config.transitions ? bars.transition() : bars; + barsTrans + .attr('x', d => { + let position; + if (!d.arrange || d.arrange === 'stacked') { + return this.x(d.values.x); + } else if (d.arrange === 'nested') { + let position = d.subcats.indexOf(d.key); + let 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', d => { + if (d.arrange !== 'stacked') { + return this.y(d.values.y); + } else { + return this.y(d.values.start); + } + }) + .attr('width', d => { + if (!d.arrange || d.arrange === 'stacked') { + return this.x.rangeBand(); + } else if (d.arrange === 'nested') { + let 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', d => this.y(0) - this.y(d.values.y)); +} diff --git a/src/chart/resize/updateDataMarks/drawBars/yBin.js b/src/chart/resize/updateDataMarks/drawBars/yBin.js new file mode 100644 index 0000000..f79394b --- /dev/null +++ b/src/chart/resize/updateDataMarks/drawBars/yBin.js @@ -0,0 +1,82 @@ +import { select, set, format, min, max } from 'd3'; + +export default function yBin(oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars) { + const chart = this; + const rawData = this.raw_data; + const config = this.config; + + oldBarsTrans.attr('x', this.x(0)).attr('width', 0); + oldBarGroupsTrans.remove(); + + nu_bar_groups = bar_groups + .enter() + .append('g') + .attr('class', d => 'bar-group ' + d.key); + nu_bar_groups.append('title'); + + bars = bar_groups.selectAll('rect').data( + d => (d.values instanceof Array ? d.values : [d]), + d => d.key + ); + + let exitBars = config.transitions ? bars.exit().transition() : bars.exit(); + exitBars + .attr('x', this.x(0)) + .attr('width', 0) + .remove(); + bars.enter() + .append('rect') + .attr('class', d => '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', d => this.colorScale(d.values.raw[0][config.color_by])) + .attr('fill', d => this.colorScale(d.values.raw[0][config.color_by])); + + bars.each(function(d) { + let mark = 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] + : set(rawData.map(m => m[mark.split])).values(); + let parent = select(this.parentNode).datum(); + let rangeSet = parent.key.split(',').map(m => +m); + d.rangeLow = min(rangeSet); + d.rangeHigh = max(rangeSet); + d.tooltip = mark.tooltip; + }); + + let xformat = + config.marks.map(m => m.summarizeX === 'percent').indexOf(true) > -1 + ? format('0%') + : format(config.x.format); + let yformat = + config.marks.map(m => m.summarizeY === 'percent').indexOf(true) > -1 + ? format('0%') + : format(config.y.format); + bars.select('title').text(d => { + let tt = d.tooltip || ''; + return tt + .replace(/\$x/g, xformat(d.values.x)) + .replace(/\$y/g, yformat(d.values.y)) + .replace(/\[(.+?)\]/g, (str, orig) => d.values.raw[0][orig]); + }); + + let barsTrans = config.transitions ? bars.transition() : bars; + barsTrans + .attr('x', d => { + if (d.arrange === 'stacked') { + return this.x(d.values.start); + } else { + return this.x(0); + } + }) + .attr('y', d => this.y(d.rangeHigh)) + .attr('width', d => this.x(d.values.x)) + .attr('height', d => this.y(d.rangeLow) - this.y(d.rangeHigh)); +} diff --git a/src/chart/resize/updateDataMarks/drawBars/yOrdinal.js b/src/chart/resize/updateDataMarks/drawBars/yOrdinal.js new file mode 100644 index 0000000..c9c543c --- /dev/null +++ b/src/chart/resize/updateDataMarks/drawBars/yOrdinal.js @@ -0,0 +1,122 @@ +import { select, set, format } from 'd3'; + +// TODO: merge yOrdinal and xOrdinal into a single function +export default function yOrdinal(oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars) { + const chart = this; + const rawData = this.raw_data; + const config = this.config; + + oldBarsTrans.attr('x', this.x(0)).attr('width', 0); + + oldBarGroupsTrans.remove(); + + nu_bar_groups = bar_groups + .enter() + .append('g') + .attr('class', d => 'bar-group ' + d.key); + nu_bar_groups.append('title'); + + bars = bar_groups.selectAll('rect').data( + d => { + return d.values instanceof Array + ? d.values.sort( + (a, b) => + this.colorScale.domain().indexOf(a.key) - + this.colorScale.domain().indexOf(b.key) + ) // controls the order of the bars in the DOM + : [d]; + }, + d => d.key + ); + + let exitBars = config.transitions ? bars.exit().transition() : bars.exit(); + exitBars + .attr('x', this.x(0)) + .attr('width', 0) + .remove(); + bars.enter() + .append('rect') + .attr('class', d => 'wc-data-mark bar ' + d.key) + .style('clip-path', `url(#${chart.id})`) + .attr('x', this.x(0)) + .attr('width', 0) + .append('title'); + + // sort bars in DOM to display widest bar behind every other bar and narrowest bar in front of every other bar - that's poorly worded but you get the gist + bars.sort( + (a, b) => this.colorScale.domain().indexOf(a.key) - this.colorScale.domain().indexOf(b.key) + ); + + bars.attr('shape-rendering', 'crispEdges') + .attr('stroke', d => this.colorScale(d.values.raw[0][config.color_by])) + .attr('fill', d => this.colorScale(d.values.raw[0][config.color_by])); + + bars.each(function(d) { + let mark = 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() + : mark.values && mark.values[mark.split] + ? mark.values[mark.split] + : set(rawData.map(m => m[mark.split])) + .values() + .sort(); // controls the order of the bars in the chart + select(this).attr(mark.attributes); + }); + + let xformat = + config.marks.map(m => m.summarizeX === 'percent').indexOf(true) > -1 + ? format('0%') + : format(config.x.format); + let yformat = + config.marks.map(m => m.summarizeY === 'percent').indexOf(true) > -1 + ? format('0%') + : format(config.y.format); + bars.select('title').text(d => { + let tt = d.tooltip || ''; + return tt + .replace(/\$x/g, xformat(d.values.x)) + .replace(/\$y/g, yformat(d.values.y)) + .replace(/\[(.+?)\]/g, (str, orig) => d.values.raw[0][orig]); + }); + + let barsTrans = config.transitions ? bars.transition() : bars; + barsTrans + .attr('x', 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', d => { + if (d.arrange === 'nested') { + let position = d.subcats.indexOf(d.key); + let 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') { + let position = d.subcats.indexOf(d.key); + return this.y(d.values.y) + (this.y.rangeBand() / d.subcats.length) * position; + } else { + return this.y(d.values.y); + } + }) + .attr('width', d => this.x(d.values.x) - this.x(0)) + .attr('height', d => { + if (config.y.type === 'quantile') { + return 20; + } else if (d.arrange === 'nested') { + let 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(); + } + }); +} diff --git a/src/chart/resize/updateDataMarks/drawPoints.js b/src/chart/resize/updateDataMarks/drawPoints.js index 8a16650..5fb75a5 100644 --- a/src/chart/resize/updateDataMarks/drawPoints.js +++ b/src/chart/resize/updateDataMarks/drawPoints.js @@ -1,4 +1,4 @@ -import { select, format, time } from 'd3'; +import { select, format, time, max } from 'd3'; export default function drawPoints(marks) { let chart = this; @@ -38,7 +38,8 @@ export default function drawPoints(marks) { .attr('class', 'wc-data-mark') .attr('r', 0); nupoints.append('title'); - //static attributes + + // static attributes points .select('circle') .style('clip-path', `url(#${chart.id})`) @@ -48,7 +49,7 @@ export default function drawPoints(marks) { ) .attr('fill', d => this.colorScale(d.values.raw[0][config.color_by])) .attr('stroke', d => this.colorScale(d.values.raw[0][config.color_by])); - //attach mark info + // attach mark info points.each(function(d) { let mark = select(this.parentNode).datum(); d.mark = mark; @@ -56,7 +57,7 @@ export default function drawPoints(marks) { .select('circle') .attr(mark.attributes); }); - //animated attributes + // animated attributes let pointsTrans = config.transitions ? points.select('circle').transition() : points.select('circle'); @@ -97,12 +98,27 @@ export default function drawPoints(marks) { .replace(/\[(.+?)\]/g, (str, orig) => d.values.raw[0][orig]); }); - //Link to the d3.selection from the data + // Link to the d3.selection from the data point_supergroups.each(function(d) { d.supergroup = select(this); d.groups = d.supergroup.selectAll('g.point'); d.circles = d.groups.select('circle'); }); + // expand the plotting area slightly to prevent mark cutoff + const radius = max(marks, mark => mark.radius || this.config.flex_point_size); + this.svg + .select('.plotting-area') + .attr('width', this.plot_width + radius * 2 + 2) // plot width + circle radius * 2 + circle stroke width * 2 + .attr('height', this.plot_height + radius * 2 + 2) // plot height + circle radius * 2 + circle stroke width * 2 + .attr( + 'transform', + 'translate(-' + + (radius + 1) + // translate left circle radius + circle stroke width + ',-' + + (radius + 1) + // translate up circle radius + circle stroke width + ')' + ); + return points; } diff --git a/src/chart/resize/updateDataMarks/drawText.js b/src/chart/resize/updateDataMarks/drawText.js index 5fbe89f..3060ed0 100644 --- a/src/chart/resize/updateDataMarks/drawText.js +++ b/src/chart/resize/updateDataMarks/drawText.js @@ -4,18 +4,18 @@ export default function drawText(marks) { const chart = this; const config = this.config; - const textSupergroups = this.svg + const text_supergroups = this.svg .selectAll('.text-supergroup') .data(marks, (d, i) => `${i}-${d.per.join('-')}`); - textSupergroups + text_supergroups .enter() .append('g') .attr('class', d => 'supergroup text-supergroup ' + d.id); - textSupergroups.exit().remove(); + text_supergroups.exit().remove(); - const texts = textSupergroups.selectAll('.text').data( + const texts = text_supergroups.selectAll('.text').data( d => d.data, d => d.key ); @@ -85,11 +85,13 @@ export default function drawText(marks) { const 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) { + + // add a reference to the selection from it's data + text_supergroups.each(function(d) { d.supergroup = select(this); d.groups = d.supergroup.selectAll('g.text'); d.texts = d.groups.select('text'); }); + return texts; } diff --git a/src/controls/index.js b/src/controls/index.js index 51b2872..35d2034 100644 --- a/src/controls/index.js +++ b/src/controls/index.js @@ -5,14 +5,14 @@ import destroy from './destroy'; import init from './init'; import layout from './layout'; import makeControlItem from './makeControlItem'; -import makeBtnGroupControl from './makeBtnGroupControl'; -import makeCheckboxControl from './makeCheckboxControl'; -import makeDropdownControl from './makeDropdownControl'; -import makeListControl from './makeListControl'; -import makeNumberControl from './makeNumberControl'; -import makeRadioControl from './makeRadioControl'; -import makeSubsetterControl from './makeSubsetterControl'; -import makeTextControl from './makeTextControl'; +import makeBtnGroupControl from './makeControlItem/makeBtnGroupControl'; +import makeCheckboxControl from './makeControlItem/makeCheckboxControl'; +import makeDropdownControl from './makeControlItem/makeDropdownControl'; +import makeListControl from './makeControlItem/makeListControl'; +import makeNumberControl from './makeControlItem/makeNumberControl'; +import makeRadioControl from './makeControlItem/makeRadioControl'; +import makeSubsetterControl from './makeControlItem/makeSubsetterControl'; +import makeTextControl from './makeControlItem/makeTextControl'; import stringAccessor from './stringAccessor'; export default { diff --git a/src/controls/makeBtnGroupControl.js b/src/controls/makeControlItem/makeBtnGroupControl.js similarity index 100% rename from src/controls/makeBtnGroupControl.js rename to src/controls/makeControlItem/makeBtnGroupControl.js diff --git a/src/controls/makeCheckboxControl.js b/src/controls/makeControlItem/makeCheckboxControl.js similarity index 100% rename from src/controls/makeCheckboxControl.js rename to src/controls/makeControlItem/makeCheckboxControl.js diff --git a/src/controls/makeDropdownControl.js b/src/controls/makeControlItem/makeDropdownControl.js similarity index 100% rename from src/controls/makeDropdownControl.js rename to src/controls/makeControlItem/makeDropdownControl.js diff --git a/src/controls/makeListControl.js b/src/controls/makeControlItem/makeListControl.js similarity index 100% rename from src/controls/makeListControl.js rename to src/controls/makeControlItem/makeListControl.js diff --git a/src/controls/makeNumberControl.js b/src/controls/makeControlItem/makeNumberControl.js similarity index 100% rename from src/controls/makeNumberControl.js rename to src/controls/makeControlItem/makeNumberControl.js diff --git a/src/controls/makeRadioControl.js b/src/controls/makeControlItem/makeRadioControl.js similarity index 100% rename from src/controls/makeRadioControl.js rename to src/controls/makeControlItem/makeRadioControl.js diff --git a/src/controls/makeSubsetterControl.js b/src/controls/makeControlItem/makeSubsetterControl.js similarity index 96% rename from src/controls/makeSubsetterControl.js rename to src/controls/makeControlItem/makeSubsetterControl.js index 1bcc046..70ab52b 100644 --- a/src/controls/makeSubsetterControl.js +++ b/src/controls/makeControlItem/makeSubsetterControl.js @@ -1,4 +1,4 @@ -import naturalSorter from '../dataOps/naturalSorter'; +import naturalSorter from '../../dataOps/naturalSorter'; import { set, select } from 'd3'; export default function makeSubsetterControl(control, control_wrap) { @@ -14,7 +14,7 @@ export default function makeSubsetterControl(control, control_wrap) { //dropdown option data const option_data = control.values ? control.values - : set(this.data.map(m => m[control.value_col]).filter(f => f)) + : set(this.data.map(m => m[control.value_col])) //.filter(f => f)) .values() .sort(naturalSorter); // only sort when values are derived diff --git a/src/controls/makeTextControl.js b/src/controls/makeControlItem/makeTextControl.js similarity index 100% rename from src/controls/makeTextControl.js rename to src/controls/makeControlItem/makeTextControl.js diff --git a/src/createTable.js b/src/createTable.js index fe2bf5a..a63474a 100644 --- a/src/createTable.js +++ b/src/createTable.js @@ -1,6 +1,8 @@ import table from './table/index'; import { select } from 'd3'; +export var tableCount = 0; + export default function createTable(element = 'body', config = {}, controls = null) { let thisTable = Object.create(table); @@ -36,5 +38,10 @@ export default function createTable(element = 'body', config = {}, controls = nu } }; + //increment thisChart count to get unique thisChart id + tableCount++; + + thisTable.id = tableCount; + return thisTable; } diff --git a/src/table/draw/applyFilters.js b/src/table/draw/applyFilters.js index 7104fd5..2c20776 100644 --- a/src/table/draw/applyFilters.js +++ b/src/table/draw/applyFilters.js @@ -9,7 +9,7 @@ export default function applyFilters() { (Array.isArray(filter.val) && filter.val.length < filter.choices.length) ) ) { - this.data.filtered = this.data.raw; + this.data.filtered = this.data.raw.slice(); this.filters .filter( filter => @@ -24,5 +24,5 @@ export default function applyFilters() { : filter.val === d[filter.col] ); }); - } else this.data.filtered = this.data.raw; + } else this.data.filtered = this.data.raw.slice(); } diff --git a/src/table/setDefaults.js b/src/table/setDefaults.js index e23be0c..2e13165 100644 --- a/src/table/setDefaults.js +++ b/src/table/setDefaults.js @@ -2,28 +2,39 @@ import { keys } from 'd3'; import setDefault from '../util/setDefault'; export default function setDefaults(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; - } + // cols + if ( + !Array.isArray(this.config.cols) || + (Array.isArray(this.config.cols) && this.config.cols.length === 0) + ) + this.config.cols = keys(firstItem); - this.config.cols = this.config.cols || keys(firstItem); - this.config.headers = this.config.headers || this.config.cols; - this.config.layout = 'horizontal'; // placeholder setting to align table components vertically or horizontally + // headers + if ( + !Array.isArray(this.config.headers) || + (Array.isArray(this.config.headers) && this.config.headers.length === 0) || + (Array.isArray(this.config.headers) && + this.config.headers.length !== this.config.cols.length) + ) + this.config.headers = this.config.cols.slice(); - //Set all other defaults. + // types + if (typeof this.config.types !== 'object') this.config.types = {}; + + this.config.cols.forEach(col => { + if (!['string', 'number'].includes(this.config.types[col])) + this.config.types[col] = 'string'; + }); + + // Set all other defaults. setDefault.call(this, 'searchable'); - setDefault.call(this, 'exportable'); - setDefault.call(this, 'exports', ['csv']); setDefault.call(this, 'sortable'); setDefault.call(this, 'pagination'); + setDefault.call(this, 'exportable'); + setDefault.call(this, 'exports', ['csv']); setDefault.call(this, 'nRowsPerPage', 10); setDefault.call(this, 'nPageLinksDisplayed', 5); setDefault.call(this, 'applyCSS'); setDefault.call(this, 'dynamicPositioning'); + setDefault.call(this, 'layout', 'horizontal'); } diff --git a/src/table/sortable/onClick.js b/src/table/sortable/onClick.js index 740bd7d..e1a0c81 100644 --- a/src/table/sortable/onClick.js +++ b/src/table/sortable/onClick.js @@ -17,7 +17,8 @@ export default function onClick(th, header) { .append('div') .datum({ key: col }) .classed('wc-button sort-box', true) - .text(header) + .text(header), + type: this.config.types[col] }; sortItem.wrap .append('span') diff --git a/src/table/sortable/sortData.js b/src/table/sortable/sortData.js index 84f4912..fcfc189 100644 --- a/src/table/sortable/sortData.js +++ b/src/table/sortable/sortData.js @@ -5,20 +5,24 @@ export default function sortData(data) { let order = 0; this.sortable.order.forEach(item => { - const aCell = a[item.col], - bCell = b[item.col]; + const aCell = a[item.col]; + const 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.type === 'number') { + order = item.direction === 'ascending' ? +aCell - +bCell : +bCell - +aCell; + } else { + 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; + } } }); diff --git a/test-page/arranged-bar-chart.css b/test-page/arranged-bar-chart.css new file mode 100644 index 0000000..8bad0b7 --- /dev/null +++ b/test-page/arranged-bar-chart.css @@ -0,0 +1,10 @@ +#container { + display: flex; + justify-content: space-between; +} +.bar-chart { + width: 49%; +} +.randomize-bar-order { + float: right; +} diff --git a/test-page/arranged-bar-chart.js b/test-page/arranged-bar-chart.js new file mode 100644 index 0000000..6368013 --- /dev/null +++ b/test-page/arranged-bar-chart.js @@ -0,0 +1,47 @@ +const settings = function(arrange) { + return { + ordinal: { + type: 'ordinal', + column: 'AEREL', + label: 'Relationship', + }, + linear: { + type: 'linear', + column: null, + label: '# of Adverse Events', + }, + marks: [ + { + type: 'bar', + per: ['AEREL'], + summarizeX: 'count', + summarizeY: 'count', + tooltip: null, + split: 'AESEV', + arrange: arrange, + }, + ], + color_by: 'AESEV', + legend: { + label: 'Severity', + order: ['MILD', 'MODERATE', 'SEVERE'], + }, + resizable: false, + aspect: 2, + }; +}; + +const onLayout = function() { + this.wrap.select('.legend') + .append('button') + .classed('randomize-bar-order', true) + .text('Randomize Bar Order') + .on('click', () => { + let randomOrder = this.colorScale.domain().sort(() => Math.random() < .5 ? -1 : 1); + while (this.config.legend.order.join('|') === randomOrder.join('|')) { + randomOrder = this.colorScale.domain().sort(() => Math.random() < .5 ? -1 : 1) + } + this.config.legend.order = randomOrder; + this.draw(); + }); +}; diff --git a/test-page/createChart/index.js b/test-page/createChart/index.js index 1eeb793..04f42f1 100644 --- a/test-page/createChart/index.js +++ b/test-page/createChart/index.js @@ -3,13 +3,15 @@ const settings = { type: 'linear', column: 'sepal length', label: 'Sepal length', - domain: ['minimum',null], + domain: null, + format: '.1f', }, y: { type: 'linear', column: 'sepal width', label: 'Sepal Width', - domain: ['minimum',null], + domain: null, + format: '.1f', }, marks: [ { @@ -37,16 +39,24 @@ const controls = new webCharts.createControls( label: 'Species', }, { - type: 'radio', + type: 'number', option: 'x.domain.0', label: 'X-domain Lower Limit', - values: ['minimum',0], }, { - type: 'radio', + type: 'number', + option: 'x.domain.1', + label: 'X-domain Upper Limit', + }, + { + type: 'number', option: 'y.domain.0', label: 'Y-domain Lower Limit', - values: ['minimum',0], + }, + { + type: 'number', + option: 'y.domain.1', + label: 'Y-domain Upper Limit', }, ], }, @@ -65,6 +75,14 @@ d3.csv( return d; }, function(data) { + chart.config.x.domain = d3.extent(data, d => +d[chart.config.x.column]); + chart.config.y.domain = d3.extent(data, d => +d[chart.config.y.column]); + chart.on('layout', function() { + this.controls.wrap + .selectAll('.control-group input') + .filter(d => d.type === 'number') + .attr('step', .1); + }); chart.init(data); } ); diff --git a/test-page/createTable/index.js b/test-page/createTable/index.js index 2ccf69e..ff95fff 100644 --- a/test-page/createTable/index.js +++ b/test-page/createTable/index.js @@ -1,10 +1,10 @@ function createTable(element, settings) { - var controls = webCharts.createControls( + const controls = webCharts.createControls( element, { inputs: [ {type: 'subsetter', value_col: 'Period', label: 'Filter by Period'}, - {type: 'subsetter', value_col: 'Group', label: 'Filter by Group'} + {type: 'subsetter', value_col: 'Group', label: 'Filter by Group'}, ] } ); @@ -12,7 +12,7 @@ function createTable(element, settings) { return webCharts.createTable(element, settings, controls); } -var table = createTable( +const table = createTable( '.table', { 'sortable': true, @@ -27,17 +27,36 @@ var table = createTable( ); d3.csv( - 'https://cdn.jsdelivr.net/gh/RhoInc/data-library/data/miscellaneous/elements.csv', + 'https://raw.githubusercontent.com/RhoInc/data-library/master/data/miscellaneous/elements.csv', function(d) { return d; }, function(data) { + table.config.types = Object.keys(data[0]) + .map(col => { + let type = 'string'; + + const vector = data + .map(d => d[col]).filter(d => d !== ''); + + if (vector.length > 0 && vector.every(d => !isNaN(parseFloat(d)))) + type = 'number'; + + return [col, type]; + }) + .reduce( + (acc,cur) => { + acc[cur[0]] = cur[1]; + return acc; + }, + {} + ); table.init(data); //Update settings. d3.selectAll('.controls input') .on('change',function(){ - var settings = { + const settings = { sortable: d3.select('input.sortable').property('checked'), searchable: d3.select('input.searchable').property('checked'), nRowsPerPage: +d3.select('input.items').node().value, @@ -50,7 +69,7 @@ d3.csv( console.log(settings); d3.select('.table').selectAll('*').remove() - var table = createTable( + const table = createTable( '.table', settings ); @@ -62,7 +81,7 @@ d3.csv( //Randomize columns. d3.select('button.randomize-columns') .on('click', function() { - var table = d3.select('.wc-table').datum(); + const table = d3.select('.wc-table').datum(); table.config.cols = Object.keys(table.data.raw[0]) .reverse() .filter(function(d) { @@ -76,7 +95,7 @@ d3.select('button.randomize-columns') //Randomize headers. d3.select('button.randomize-headers') .on('click', function() { - var table = d3.select('.wc-table').datum(); + const table = d3.select('.wc-table').datum(); table.config.headers = table.config.cols .map(function(key) { const strArr = []; diff --git a/test-page/groupedBarChart/index.html b/test-page/groupedBarChart/index.html new file mode 100644 index 0000000..13aeddf --- /dev/null +++ b/test-page/groupedBarChart/index.html @@ -0,0 +1,27 @@ + + + + Webcharts - Grouped Bar Chart + + + + + + + + + + + + + +
Webcharts
+
Grouped Bar Chart
+
+
+
+
+ + + + diff --git a/test-page/groupedBarChart/index.js b/test-page/groupedBarChart/index.js new file mode 100644 index 0000000..3651961 --- /dev/null +++ b/test-page/groupedBarChart/index.js @@ -0,0 +1,33 @@ +hSettings = JSON.parse(JSON.stringify(settings('grouped'))); +hSettings.x = hSettings.ordinal; +hSettings.y = hSettings.linear; +hSettings.marks[0].tooltip = '$x: $y'; + +const hChart = new webCharts.createChart( + '.bar-chart--horizontal', + hSettings, +); + +vSettings = JSON.parse(JSON.stringify(settings('grouped'))); +vSettings.x = vSettings.linear; +vSettings.y = vSettings.ordinal; +hSettings.marks[0].tooltip = '$y: $x'; + +const vChart = new webCharts.createChart( + '.bar-chart--vertical', + vSettings, +); + +d3.csv( + 'https://raw.githubusercontent.com/RhoInc/data-library/master/data/clinical-trials/sdtm/ae.csv', + function(d,i) { + d.seq = i; + return d; + }, + function(data) { + hChart.on('layout', onLayout); + hChart.init(data); + vChart.on('layout', onLayout); + vChart.init(data); + } +); diff --git a/test-page/nestedBarChart/index.html b/test-page/nestedBarChart/index.html new file mode 100644 index 0000000..bbf4f5e --- /dev/null +++ b/test-page/nestedBarChart/index.html @@ -0,0 +1,27 @@ + + + + Webcharts - Nested Bar Chart + + + + + + + + + + + + + +
Webcharts
+
Nested Bar Chart
+
+
+
+
+ + + + diff --git a/test-page/nestedBarChart/index.js b/test-page/nestedBarChart/index.js new file mode 100644 index 0000000..29ac872 --- /dev/null +++ b/test-page/nestedBarChart/index.js @@ -0,0 +1,33 @@ +hSettings = JSON.parse(JSON.stringify(settings('nested'))); +hSettings.x = hSettings.ordinal; +hSettings.y = hSettings.linear; +hSettings.marks[0].tooltip = '$x: $y'; + +const hChart = new webCharts.createChart( + '.bar-chart--horizontal', + hSettings, +); + +vSettings = JSON.parse(JSON.stringify(settings('nested'))); +vSettings.x = vSettings.linear; +vSettings.y = vSettings.ordinal; +hSettings.marks[0].tooltip = '$y: $x'; + +const vChart = new webCharts.createChart( + '.bar-chart--vertical', + vSettings, +); + +d3.csv( + 'https://raw.githubusercontent.com/RhoInc/data-library/master/data/clinical-trials/sdtm/ae.csv', + function(d,i) { + d.seq = i; + return d; + }, + function(data) { + hChart.on('layout', onLayout); + hChart.init(data); + vChart.on('layout', onLayout); + vChart.init(data); + } +); diff --git a/test-page/stackedBarChart/index.html b/test-page/stackedBarChart/index.html new file mode 100644 index 0000000..4eea172 --- /dev/null +++ b/test-page/stackedBarChart/index.html @@ -0,0 +1,27 @@ + + + + Webcharts - Stacked Bar Chart + + + + + + + + + + + + + +
Webcharts
+
Stacked Bar Chart
+
+
+
+
+ + + + diff --git a/test-page/stackedBarChart/index.js b/test-page/stackedBarChart/index.js new file mode 100644 index 0000000..c4df51f --- /dev/null +++ b/test-page/stackedBarChart/index.js @@ -0,0 +1,33 @@ +hSettings = JSON.parse(JSON.stringify(settings('stacked'))); +hSettings.x = hSettings.ordinal; +hSettings.y = hSettings.linear; +hSettings.marks[0].tooltip = '$x: $y'; + +const hChart = new webCharts.createChart( + '.bar-chart--horizontal', + hSettings, +); + +vSettings = JSON.parse(JSON.stringify(settings('stacked'))); +vSettings.x = vSettings.linear; +vSettings.y = vSettings.ordinal; +hSettings.marks[0].tooltip = '$y: $x'; + +const vChart = new webCharts.createChart( + '.bar-chart--vertical', + vSettings, +); + +d3.csv( + 'https://raw.githubusercontent.com/RhoInc/data-library/master/data/clinical-trials/sdtm/ae.csv', + function(d,i) { + d.seq = i; + return d; + }, + function(data) { + hChart.on('layout', onLayout); + hChart.init(data); + vChart.on('layout', onLayout); + vChart.init(data); + } +);