From 351f306c5b4542cccdfcbe322e25ec116f151dce Mon Sep 17 00:00:00 2001 From: Spencer Date: Thu, 12 Dec 2019 11:52:31 -0500 Subject: [PATCH 01/14] fix #259 --- build/webcharts.js | 5 ++++- build/webcharts.min.js | 2 +- src/createTable.js | 7 +++++++ test-page/createTable/index.js | 16 ++++++++-------- 4 files changed, 20 insertions(+), 10 deletions(-) diff --git a/build/webcharts.js b/build/webcharts.js index a0f4a51..aa1e745 100644 --- a/build/webcharts.js +++ b/build/webcharts.js @@ -4508,6 +4508,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 +4541,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..df3964f 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}); +;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}});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/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/test-page/createTable/index.js b/test-page/createTable/index.js index 2ccf69e..422c74f 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,7 +27,7 @@ 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; }, @@ -37,7 +37,7 @@ d3.csv( //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 +50,7 @@ d3.csv( console.log(settings); d3.select('.table').selectAll('*').remove() - var table = createTable( + const table = createTable( '.table', settings ); @@ -62,7 +62,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 +76,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 = []; From 20f71d4ef618f1a09450c2fd9f1c1c286ef1a61e Mon Sep 17 00:00:00 2001 From: Spencer Date: Thu, 12 Dec 2019 15:50:37 -0500 Subject: [PATCH 02/14] fix #123; fix #256 --- build/webcharts.js | 95 +++++++++++++++++++++++----------- build/webcharts.min.js | 2 +- src/table/draw/applyFilters.js | 4 +- src/table/setDefaults.js | 41 +++++++++------ src/table/sortable/onClick.js | 3 +- src/table/sortable/sortData.js | 30 ++++++----- test-page/createTable/index.js | 19 +++++++ 7 files changed, 131 insertions(+), 63 deletions(-) diff --git a/build/webcharts.js b/build/webcharts.js index aa1e745..fb3d568 100644 --- a/build/webcharts.js +++ b/build/webcharts.js @@ -3402,7 +3402,7 @@ ); }) ) { - this.data.filtered = this.data.raw; + this.data.filtered = this.data.raw.slice(); this.filters .filter(function(filter) { return ( @@ -3418,7 +3418,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 +3922,8 @@ key: col }) .classed('wc-button sort-box', true) - .text(header) + .text(header), + type: this.config.types[col] }; sortItem.wrap .append('span') @@ -3968,6 +3969,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 +3995,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 +4371,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) { diff --git a/build/webcharts.min.js b/build/webcharts.min.js index df3964f..4f79562 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}});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}); +;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/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/createTable/index.js b/test-page/createTable/index.js index 422c74f..ff95fff 100644 --- a/test-page/createTable/index.js +++ b/test-page/createTable/index.js @@ -32,6 +32,25 @@ d3.csv( 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. From e6d3004f6c59a8beedbd0ecf3831cd213448e398 Mon Sep 17 00:00:00 2001 From: Spencer Date: Thu, 12 Dec 2019 16:28:30 -0500 Subject: [PATCH 03/14] add split bar chart examples --- build/webcharts.js | 6964 +++++++++++--------------- test-page/groupedBarChart/index.css | 7 + test-page/groupedBarChart/index.html | 26 + test-page/groupedBarChart/index.js | 62 + test-page/nestedBarChart/index.css | 7 + test-page/nestedBarChart/index.html | 26 + test-page/nestedBarChart/index.js | 62 + test-page/stackedBarChart/index.css | 7 + test-page/stackedBarChart/index.html | 26 + test-page/stackedBarChart/index.js | 62 + 10 files changed, 3078 insertions(+), 4171 deletions(-) create mode 100644 test-page/groupedBarChart/index.css create mode 100644 test-page/groupedBarChart/index.html create mode 100644 test-page/groupedBarChart/index.js create mode 100644 test-page/nestedBarChart/index.css create mode 100644 test-page/nestedBarChart/index.html create mode 100644 test-page/nestedBarChart/index.js create mode 100644 test-page/stackedBarChart/index.css create mode 100644 test-page/stackedBarChart/index.html create mode 100644 test-page/stackedBarChart/index.js diff --git a/build/webcharts.js b/build/webcharts.js index fb3d568..c80fe8c 100644 --- a/build/webcharts.js +++ b/build/webcharts.js @@ -1,980 +1,671 @@ -(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'; +(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); - }); - } + var _this = this; - this.wrap.attr('class', 'wc-chart'); - this.setDefaults(); - this.raw_data = data; - this.initial_data = data; + var test = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + this.test = test; - var startup = function startup(data) { - //connect this chart and its controls, if any - if (_this.controls) { - _this.controls.targets.push(_this); + 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); + }); + } - if (!_this.controls.ready) { - _this.controls.init(_this.raw_data); - } else { - _this.controls.layout(); - } - } //make sure container is visible (has height and width) before trying to initialize + this.wrap.attr('class', 'wc-chart'); + this.setDefaults(); + this.raw_data = data; + this.initial_data = data; - var visible = d3.select(_this.div).property('offsetWidth') > 0 || test; + var startup = function startup(data) { + //connect this chart and its controls, if any + if (_this.controls) { + _this.controls.targets.push(_this); - 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 (!_this.controls.ready) { + _this.controls.init(_this.raw_data); + } else { + _this.controls.layout(); + } + } //make sure container is visible (has height and width) before trying to initialize - if (visible_now) { - _this.layout(); - _this.draw(); + var visible = d3.select(_this.div).property('offsetWidth') > 0 || test; - clearInterval(onVisible); - } - }, 500); - } else { - _this.layout(); + 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; - _this.draw(); - } - }; + if (visible_now) { + _this.layout(); + + _this.draw(); - this.events.onInit.call(this); + clearInterval(onVisible); + } + }, 500); + } else { + _this.layout(); - if (this.raw_data.length) { - this.checkRequired(this.raw_data); + _this.draw(); } + }; - startup(); - return this; + 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 _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); + } - var colnames = Object.keys(data[0]); - var requiredVars = []; - var requiredCols = []; + if (this.config.y && this.config.y.column) { + requiredVars.push('this.config.y.column'); + requiredCols.push(this.config.y.column); + } - if (this.config.x && this.config.x.column) { - requiredVars.push('this.config.x.column'); - requiredCols.push(this.config.x.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 (this.config.y && this.config.y.column) { - requiredVars.push('this.config.y.column'); - requiredCols.push(this.config.y.column); + if (e.split) { + requiredVars.push('this.config.marks[' + i + '].split'); + requiredCols.push(e.split); } - if (this.config.color_by) { - requiredVars.push('this.config.color_by'); - requiredCols.push(this.config.color_by); + 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(); - 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 - }; + _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; - }) // prevent data inheritance - .attr({ - class: 'wc-svg', - xmlns: 'http://www.w3.org/2000/svg', - version: '1.1', - xlink: 'http://www.w3.org/1999/xlink' - }) - .append('g') - .style('display', 'inline-block'); + this.svg = this.wrap.append('svg').datum(function () { + return null; + }) // prevent data inheritance + .attr({ + "class": 'wc-svg', + xmlns: 'http://www.w3.org/2000/svg', + version: '1.1', + xlink: 'http://www.w3.org/1999/xlink' + }).append('g').style('display', 'inline-block'); } function addDefs() { - var defs = this.svg.append('defs'); //Add pattern. - - defs.append('pattern') - .attr({ - id: 'diagonal-stripes', - x: 0, - y: 0, - width: 3, - height: 8, - patternUnits: 'userSpaceOnUse', - patternTransform: 'rotate(30)' - }) - .append('rect') - .attr({ - x: '0', - y: '0', - width: '2', - height: '8' - }) - .style({ - stroke: 'none', - fill: 'black' - }); //Add clipPath. - - defs.append('clipPath') - .attr('id', this.id) - .append('rect') - .attr('class', 'plotting-area'); + var defs = this.svg.append('defs'); //Add pattern. + + defs.append('pattern').attr({ + id: 'diagonal-stripes', + x: 0, + y: 0, + width: 3, + height: 8, + patternUnits: 'userSpaceOnUse', + patternTransform: 'rotate(30)' + }).append('rect').attr({ + x: '0', + y: '0', + width: '2', + height: '8' + }).style({ + stroke: 'none', + fill: 'black' + }); //Add clipPath. + + defs.append('clipPath').attr('id', this.id).append('rect').attr('class', 'plotting-area'); } function addXAxis() { - this.svg - .append('g') - .attr('class', 'x axis') - .append('text') - .attr('class', 'axis-title') - .attr('dy', '-.35em') - .attr('text-anchor', 'middle'); + this.svg.append('g').attr('class', 'x axis').append('text').attr('class', 'axis-title').attr('dy', '-.35em').attr('text-anchor', 'middle'); } function addYAxis() { - this.svg - .append('g') - .attr('class', 'y axis') - .append('text') - .attr('class', 'axis-title') - .attr('transform', 'rotate(-90)') - .attr('dy', '.75em') - .attr('text-anchor', 'middle'); + this.svg.append('g').attr('class', 'y axis').append('text').attr('class', 'axis-title').attr('transform', 'rotate(-90)').attr('dy', '.75em').attr('text-anchor', 'middle'); } function addOverlay() { - this.overlay = this.svg - .append('rect') - .attr('class', 'overlay') - .attr('opacity', 0) - .attr('fill', 'none') - .style('pointer-events', 'all'); + this.overlay = this.svg.append('rect').attr('class', 'overlay').attr('opacity', 0).attr('fill', 'none').style('pointer-events', 'all'); } function addLegend() { - //The legend is contained in the parent object of multiples so each multiple does not need its own legend. - if (!this.parent) - this.wrap - .append('ul') - .datum(function() { - return null; - }) // prevent data inheritance - .attr('class', 'legend') - .style('vertical-align', 'top') - .append('span') - .attr('class', 'legend-title'); + //The legend is contained in the parent object of multiples so each multiple does not need its own legend. + if (!this.parent) this.wrap.append('ul').datum(function () { + return null; + }) // prevent data inheritance + .attr('class', 'legend').style('vertical-align', 'top').append('span').attr('class', 'legend-title'); } function clearLoader() { - d3.select(this.div) - .select('.loader') - .remove(); + 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); + 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; //if pre-processing callback, run it now - - this.events.onPreprocess.call(this); ///////////////////////// - // Data prep pipeline // - ///////////////////////// - // if user passed raw_data to chart.draw(), use that, otherwise use chart.raw_data - - var raw = raw_data ? raw_data : this.raw_data ? this.raw_data : []; // warn the user about the perils of "processed_data" - - if (processed_data) { - console.warn( - "Drawing the chart using user-defined 'processed_data', this is an experimental, untested feature." - ); - } //Call consolidateData - this applies filters from controls and prepares data for each set of marks. - - this.consolidateData(raw); ///////////////////////////// - // Prepare scales and axes // - ///////////////////////////// - - 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); - } + var _this = this; + + var chart = this; + var config = this.config; //if pre-processing callback, run it now + + this.events.onPreprocess.call(this); ///////////////////////// + // Data prep pipeline // + ///////////////////////// + // if user passed raw_data to chart.draw(), use that, otherwise use chart.raw_data + + var raw = raw_data ? raw_data : this.raw_data ? this.raw_data : []; // warn the user about the perils of "processed_data" + + if (processed_data) { + console.warn("Drawing the chart using user-defined 'processed_data', this is an experimental, untested feature."); + } //Call consolidateData - this applies filters from controls and prepares data for each set of marks. + + + this.consolidateData(raw); ///////////////////////////// + // Prepare scales and axes // + ///////////////////////////// + + 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); ////////////////////////////////////////////////////////////////////// - // Call resize - updates marks on the chart (amongst other things) // - ///////////////////////////////////////////////////////////////////// + this.events.onDraw.call(this); ////////////////////////////////////////////////////////////////////// + // Call resize - updates marks on the chart (amongst other things) // + ///////////////////////////////////////////////////////////////////// - this.resize(); + this.resize(); } function naturalSorter(a, b) { - //adapted from http://www.davekoelle.com/files/alphanum.js - 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; - } + //adapted from http://www.davekoelle.com/files/alphanum.js + function chunkify(t) { + var tz = []; + var x = 0, + y = -1, + n = 0, + i, + j; - return tz; + 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; } - var aa = chunkify(a.toLowerCase()); - var bb = chunkify(b.toLowerCase()); + return tz; + } - for (var x = 0; aa[x] && bb[x]; x++) { - if (aa[x] !== bb[x]) { - var c = Number(aa[x]), - d = Number(bb[x]); + var aa = chunkify(a.toLowerCase()); + var bb = chunkify(b.toLowerCase()); - if (c == aa[x] && d == bb[x]) { - return c - d; - } else { - return aa[x] > bb[x] ? 1 : -1; - } - } + 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; + return aa.length - bb.length; } function setDomain(axis) { - var _this = this; - - var otherAxis = axis === 'x' ? 'y' : 'x'; - - if (this.config[axis].type === 'ordinal') { - //ordinal domains - if (this.config[axis].domain) { - //user-defined domain - this[axis + '_dom'] = this.config[axis].domain; - } else if (this.config[axis].order) { - //data-driven domain with user-defined domain order - this[axis + '_dom'] = d3 - .set( - d3.merge( - this.marks.map(function(mark) { - return mark[axis + '_dom']; - }) - ) - ) - .values() - .sort(function(a, b) { - return d3.ascending( - _this.config[axis].order.indexOf(a), - _this.config[axis].order.indexOf(b) - ); - }); - } else if ( - this.config[axis].sort && - this.config[axis].sort === 'alphabetical-ascending' - ) { - //data-driven domain with user-defined domain sort algorithm that sorts the axis - //alphanumerically, first to last - this[axis + '_dom'] = d3 - .set( - d3.merge( - this.marks.map(function(mark) { - return mark[axis + '_dom']; - }) - ) - ) - .values() - .sort(naturalSorter); - } else if ( - ['time', 'linear'].indexOf(this.config[otherAxis].type) > -1 && - this.config[axis].sort === 'earliest' - ) { - //data-driven domain plotted against a time or linear axis that sorts the axis values - //by earliest event/datum; generally used with timeline charts - this[axis + '_dom'] = d3 - .nest() - .key(function(d) { - return d[_this.config[axis].column]; - }) - .rollup(function(d) { - return d - .map(function(m) { - return m[_this.config[otherAxis].column]; - }) - .filter(function(f) { - return f instanceof Date; - }); - }) - .entries(this.filtered_data) - .sort(function(a, b) { - return d3.min(b.values) - d3.min(a.values); - }) - .map(function(m) { - return m.key; - }); - } else if ( - !this.config[axis].sort || - this.config[axis].sort === 'alphabetical-descending' - ) { - //data-driven domain with default/user-defined domain sort algorithm that sorts the - //axis alphanumerically, last to first - this[axis + '_dom'] = d3 - .set( - d3.merge( - this.marks.map(function(mark) { - return mark[axis + '_dom']; - }) - ) - ) - .values() - .sort(naturalSorter) - .reverse(); - } else { - //data-driven domain with an invalid user-defined sort algorithm that captures a unique - //set of values as they appear in the data - this[axis + '_dom'] = d3 - .set( - d3.merge( - this.marks.map(function(mark) { - return mark[axis + '_dom']; - }) - ) - ) - .values(); - } - } else if ( - this.config.marks - .map(function(m) { - return m['summarize' + axis.toUpperCase()] === 'percent'; - }) - .indexOf(true) > -1 - ) { - //rate domains run from 0 to 1 - this[axis + '_dom'] = [0, 1]; + var _this = this; + + var otherAxis = axis === 'x' ? 'y' : 'x'; + + if (this.config[axis].type === 'ordinal') { + //ordinal domains + if (this.config[axis].domain) { + //user-defined domain + this[axis + '_dom'] = this.config[axis].domain; + } else if (this.config[axis].order) { + //data-driven domain with user-defined domain order + this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { + return mark[axis + '_dom']; + }))).values().sort(function (a, b) { + return d3.ascending(_this.config[axis].order.indexOf(a), _this.config[axis].order.indexOf(b)); + }); + } else if (this.config[axis].sort && this.config[axis].sort === 'alphabetical-ascending') { + //data-driven domain with user-defined domain sort algorithm that sorts the axis + //alphanumerically, first to last + this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { + return mark[axis + '_dom']; + }))).values().sort(naturalSorter); + } else if (['time', 'linear'].indexOf(this.config[otherAxis].type) > -1 && this.config[axis].sort === 'earliest') { + //data-driven domain plotted against a time or linear axis that sorts the axis values + //by earliest event/datum; generally used with timeline charts + this[axis + '_dom'] = d3.nest().key(function (d) { + return d[_this.config[axis].column]; + }).rollup(function (d) { + return d.map(function (m) { + return m[_this.config[otherAxis].column]; + }).filter(function (f) { + return f instanceof Date; + }); + }).entries(this.filtered_data).sort(function (a, b) { + return d3.min(b.values) - d3.min(a.values); + }).map(function (m) { + return m.key; + }); + } else if (!this.config[axis].sort || this.config[axis].sort === 'alphabetical-descending') { + //data-driven domain with default/user-defined domain sort algorithm that sorts the + //axis alphanumerically, last to first + this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { + return mark[axis + '_dom']; + }))).values().sort(naturalSorter).reverse(); } else { - //continuous domains run from the minimum to the maximum raw (or is it summarized...?) value - //TODO: they should really run from the minimum to the maximum summarized value, e.g. a - //TODO: means over time chart should plot over the range of the means, not the range of the - //TODO: raw data - this[axis + '_dom'] = d3.extent( - d3.merge( - this.marks.map(function(mark) { - return mark[axis + '_dom']; - }) - ) - ); - } //Give the domain a range when the range of the variable is 0. - - if ( - this.config[axis].type === 'linear' && - this[axis + '_dom'][0] === this[axis + '_dom'][1] - ) - this[axis + '_dom'] = - this[axis + '_dom'][0] !== 0 - ? [ - this[axis + '_dom'][0] - this[axis + '_dom'][0] * 0.01, - this[axis + '_dom'][1] + this[axis + '_dom'][1] * 0.01 - ] - : [-1, 1]; - return this[axis + '_dom']; + //data-driven domain with an invalid user-defined sort algorithm that captures a unique + //set of values as they appear in the data + this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { + return mark[axis + '_dom']; + }))).values(); + } + } else if (this.config.marks.map(function (m) { + return m['summarize' + axis.toUpperCase()] === 'percent'; + }).indexOf(true) > -1) { + //rate domains run from 0 to 1 + this[axis + '_dom'] = [0, 1]; + } else { + //continuous domains run from the minimum to the maximum raw (or is it summarized...?) value + //TODO: they should really run from the minimum to the maximum summarized value, e.g. a + //TODO: means over time chart should plot over the range of the means, not the range of the + //TODO: raw data + this[axis + '_dom'] = d3.extent(d3.merge(this.marks.map(function (mark) { + return mark[axis + '_dom']; + }))); + } //Give the domain a range when the range of the variable is 0. + + + if (this.config[axis].type === 'linear' && this[axis + '_dom'][0] === this[axis + '_dom'][1]) this[axis + '_dom'] = this[axis + '_dom'][0] !== 0 ? [this[axis + '_dom'][0] - this[axis + '_dom'][0] * 0.01, this[axis + '_dom'][1] + this[axis + '_dom'][1] * 0.01] : [-1, 1]; + return this[axis + '_dom']; } function consolidateData(raw) { - var _this = this; + var _this = this; - this.setDefaults(); //Apply filters from associated controls objects to raw data. + this.setDefaults(); //Apply filters from associated controls objects to raw data. - this.filtered_data = raw; + 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; - }); - }); - } //Summarize data for each mark. + 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; + }); + }); + } //Summarize data for each mark. - 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); - }); //Set domains given extents of summarized mark data. - - setDomain.call(this, 'x'); - setDomain.call(this, 'y'); + 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); + }); //Set domains given extents of summarized mark data. + + 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 : 0.3; - this.config.outer_pad = this.config.outer_pad !== undefined ? this.config.outer_pad : 0.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; + 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 : 0.3; + this.config.outer_pad = this.config.outer_pad !== undefined ? this.config.outer_pad : 0.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 _this = this; - var dateConvert = d3.time.format(this.config.date_format); - var clean = raw; // only use data for the current mark + var dateConvert = d3.time.format(this.config.date_format); + var clean = raw; // only use data for the current mark - clean = - mark.per && mark.per.length - ? clean.filter(function(f) { - return f[mark.per[0]] !== undefined; - }) - : clean; // Make sure data has x and y values + clean = mark.per && mark.per.length ? clean.filter(function (f) { + return f[mark.per[0]] !== undefined; + }) : clean; // Make sure data has x and y values - if (this.config.x.column) { - clean = clean.filter(function(f) { - return [undefined, null].indexOf(f[_this.config.x.column]) < 0; - }); - } + 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; - }); - } //check that x and y have the correct formats + if (this.config.y.column) { + clean = clean.filter(function (f) { + return [undefined, null].indexOf(f[_this.config.y.column]) < 0; + }); + } //check that x and y have the correct formats - if (this.config.x.type === 'time') { - clean = clean.filter(function(f) { - return f[_this.config.x.column] instanceof Date - ? f[_this.config.x.column] - : dateConvert.parse(f[_this.config.x.column]); - }); - clean.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 === '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.x.type === 'linear' || this.config.x.type === 'log') && - this.config.x.column - ) { - clean = clean.filter(function(f) { - return mark.summarizeX !== 'count' && mark.summarizeX !== 'percent' - ? !(isNaN(f[_this.config.x.column]) || /^\s*$/.test(f[_this.config.x.column])) // is or coerces to a number and is not a string that coerces to 0 - : f; - }); - } + if (this.config.y.type === '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.y.type === 'linear' || this.config.y.type === 'log') && - this.config.y.column - ) { - clean = clean.filter(function(f) { - return mark.summarizeY !== 'count' && mark.summarizeY !== 'percent' - ? !(isNaN(f[_this.config.y.column]) || /^\s*$/.test(f[_this.config.y.column])) // is or coerces to a number and is not a string that coerces to 0 - : f; - }); - } + if ((this.config.x.type === 'linear' || this.config.x.type === 'log') && this.config.x.column) { + clean = clean.filter(function (f) { + return mark.summarizeX !== 'count' && mark.summarizeX !== 'percent' ? !(isNaN(f[_this.config.x.column]) || /^\s*$/.test(f[_this.config.x.column])) // is or coerces to a number and is not a string that coerces to 0 + : f; + }); + } + + if ((this.config.y.type === 'linear' || this.config.y.type === 'log') && this.config.y.column) { + clean = clean.filter(function (f) { + return mark.summarizeY !== 'count' && mark.summarizeY !== 'percent' ? !(isNaN(f[_this.config.y.column]) || /^\s*$/.test(f[_this.config.y.column])) // is or coerces to a number and is not a string that coerces to 0 + : f; + }); + } - return clean; + return clean; } var stats = { - mean: d3.mean, - min: d3.min, - max: d3.max, - median: d3.median, - sum: d3.sum + 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; - }); + 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; - } + if (operation === 'cumulative') { + return null; + } - var mathed = - operation === 'count' - ? vals.length - : operation === 'percent' - ? vals.length - : stats[operation](nvals); - return mathed; + 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); - }); - } + 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(' '); + }); + } - this_nest.rollup(function(r) { - var obj = { - raw: r - }; - var y_vals = r - .map(function(m) { - return m[_this.config.y.column]; - }) - .sort(d3.ascending); - var x_vals = r - .map(function(m) { - return m[_this.config.x.column]; - }) - .sort(d3.ascending); - obj.x = - _this.config.x.type === 'ordinal' - ? r[0][_this.config.x.column] - : summarize(x_vals, mark.summarizeX); - obj.y = - _this.config.y.type === 'ordinal' - ? r[0][_this.config.y.column] - : summarize(y_vals, mark.summarizeY); - obj.x_q25 = - _this.config.error_bars && _this.config.y.type === 'ordinal' - ? d3.quantile(x_vals, 0.25) - : obj.x; - obj.x_q75 = - _this.config.error_bars && _this.config.y.type === 'ordinal' - ? d3.quantile(x_vals, 0.75) - : obj.x; - obj.y_q25 = _this.config.error_bars ? d3.quantile(y_vals, 0.25) : obj.y; - obj.y_q75 = _this.config.error_bars ? d3.quantile(y_vals, 0.75) : obj.y; - dom_xs.push([obj.x_q25, obj.x_q75, obj.x]); - dom_ys.push([obj.y_q25, obj.y_q75, obj.y]); - - if (mark.summarizeY === 'cumulative') { - var interm = entries.filter(function(f) { - return _this.config.x.type === 'time' - ? new Date(f[_this.config.x.column]) <= - new Date(r[0][_this.config.x.column]) - : +f[_this.config.x.column] <= +r[0][_this.config.x.column]; - }); - - 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 (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); + }); + } - 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; + this_nest.rollup(function (r) { + var obj = { + raw: r + }; + var y_vals = r.map(function (m) { + return m[_this.config.y.column]; + }).sort(d3.ascending); + var x_vals = r.map(function (m) { + return m[_this.config.x.column]; + }).sort(d3.ascending); + obj.x = _this.config.x.type === 'ordinal' ? r[0][_this.config.x.column] : summarize(x_vals, mark.summarizeX); + obj.y = _this.config.y.type === 'ordinal' ? r[0][_this.config.y.column] : summarize(y_vals, mark.summarizeY); + obj.x_q25 = _this.config.error_bars && _this.config.y.type === 'ordinal' ? d3.quantile(x_vals, 0.25) : obj.x; + obj.x_q75 = _this.config.error_bars && _this.config.y.type === 'ordinal' ? d3.quantile(x_vals, 0.75) : obj.x; + obj.y_q25 = _this.config.error_bars ? d3.quantile(y_vals, 0.25) : obj.y; + obj.y_q75 = _this.config.error_bars ? d3.quantile(y_vals, 0.75) : obj.y; + dom_xs.push([obj.x_q25, obj.x_q75, obj.x]); + dom_ys.push([obj.y_q25, obj.y_q75, obj.y]); + + if (mark.summarizeY === 'cumulative') { + var interm = entries.filter(function (f) { + return _this.config.x.type === 'time' ? new Date(f[_this.config.x.column]) <= new Date(r[0][_this.config.x.column]) : +f[_this.config.x.column] <= +r[0][_this.config.x.column]; + }); + + 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) { + //calculate percentages in bars + test.forEach(function (e) { + var axis = _this.config.x.type === 'ordinal' || _this.config.x.type === 'linear' && _this.config.x.bin ? 'y' : 'x'; + e.total = d3.sum(e.values.map(function (m) { + return +m.values[axis]; + })); + 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; } - - 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) { - //calculate percentages in bars - test.forEach(function(e) { - var axis = - _this.config.x.type === 'ordinal' || - (_this.config.x.type === 'linear' && _this.config.x.bin) - ? 'y' - : 'x'; - e.total = d3.sum( - e.values.map(function(m) { - return +m.values[axis]; - }) - ); - 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 (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; - }); - } + 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 - }; + return { + nested: test, + dom_x: dom_x, + dom_y: dom_y, + totalOrder: totalOrder + }; } // transformData(raw, mark) provides specifications and data for @@ -988,3695 +679,2626 @@ //////////////////////////////////////////////////////// function transformData(raw, mark) { - var _this = this; - - //convenience mappings - 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; ////////////////////////////////////////////////////////////////////////////////// - // DATA PREP - // prepare data based on the properties of the mark - drop missing records, etc - ////////////////////////////////////////////////////////////////////////////////// - - var cleaned = cleanData.call(this, mark, raw); //prepare nested data required for bar charts - - 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); - } // Get the domain for the mark based on the raw data - - var raw_dom_x = - mark.summarizeX === 'cumulative' - ? [0, cleaned.length] - : config.x.type === 'ordinal' - ? d3 - .set( - cleaned.map(function(m) { - return m[config.x.column]; - }) - ) - .values() - .filter(function(f) { - return f; - }) - : mark.split && mark.arrange !== 'stacked' - ? d3.extent( - d3.merge( - raw_nest.nested.map(function(m) { - return m.values.map(function(p) { - return p.values.raw.length; - }); - }) - ) - ) - : mark.summarizeX === 'count' - ? d3.extent( - raw_nest.nested.map(function(m) { - return m.values.raw.length; - }) - ) - : d3.extent( - cleaned - .map(function(m) { - return +m[config.x.column]; - }) - .filter(function(f) { - return +f || +f === 0; - }) - ); - var raw_dom_y = - mark.summarizeY === 'cumulative' - ? [0, cleaned.length] - : config.y.type === 'ordinal' - ? d3 - .set( - cleaned.map(function(m) { - return m[config.y.column]; - }) - ) - .values() - .filter(function(f) { - return f; - }) - : mark.split && mark.arrange !== 'stacked' - ? d3.extent( - d3.merge( - raw_nest.nested.map(function(m) { - return m.values.map(function(p) { - return p.values.raw.length; - }); - }) - ) - ) - : mark.summarizeY === 'count' - ? d3.extent( - raw_nest.nested.map(function(m) { - return m.values.raw.length; - }) - ) - : d3.extent( - cleaned - .map(function(m) { - return +m[config.y.column]; - }) - .filter(function(f) { - return +f || +f === 0; - }) - ); - var 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; - }); - }); //get domain for all non-All values of first filter - - if (config.x.behavior === 'firstfilter' || config.y.behavior === 'firstfilter') { - this.filters[0].choices - .filter(function(f) { - return f !== 'All'; - }) - .forEach(function(e) { - var perfilter = cleaned.filter(function(f) { - return f[_this.filters[0].col] === e; - }); - var filt_nested = makeNest.call(_this, mark, perfilter, sublevel); - filt1_xs.push(filt_nested.dom_x); - filt1_ys.push(filt_nested.dom_y); - }); - } - } //filter on mark-specific instructions - - 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]; - } - } //several criteria must be met in order to use the 'firstfilter' domain - - var nonall = Boolean( - this.filters.length && - this.filters[0].val !== 'All' && - this.filters.slice(1).filter(function(f) { - return f.val === 'All'; - }).length === - this.filters.length - 1 - ); - var pre_x_dom = !this.filters.length - ? flex_dom_x - : x_behavior === 'raw' - ? raw_dom_x - : nonall && x_behavior === 'firstfilter' - ? filt1_dom_x - : flex_dom_x; - var pre_y_dom = !this.filters.length - ? flex_dom_y - : y_behavior === 'raw' - ? raw_dom_y - : nonall && y_behavior === 'firstfilter' - ? filt1_dom_y - : flex_dom_y; - var x_dom = config.x_dom - ? config.x_dom - : config.x.type === 'ordinal' && config.x.behavior === 'flex' - ? d3 - .set( - filtered.map(function(m) { - return m[config.x.column]; - }) - ) - .values() - : config.x.type === 'ordinal' - ? d3 - .set( - cleaned.map(function(m) { - return m[config.x.column]; - }) - ) - .values() - : pre_x_dom; - var y_dom = config.y_dom - ? config.y_dom - : config.y.type === 'ordinal' && config.y.behavior === 'flex' - ? d3 - .set( - filtered.map(function(m) { - return m[config.y.column]; - }) - ) - .values() - : config.y.type === 'ordinal' - ? d3 - .set( - cleaned.map(function(m) { - return m[config.y.column]; - }) - ) - .values() - : pre_y_dom; //set lower limit of linear domain to 0 when other axis is ordinal and mark type is set to 'bar', provided no values are negative - - if (mark.type === 'bar') { - if ( - config.x.behavior !== 'flex' && - config.x.type === 'linear' && - config.y.type === 'ordinal' && - raw_dom_x[0] >= 0 - ) - x_dom[0] = 0; - if ( - config.y.behavior !== 'flex' && - config.x.type === 'ordinal' && - config.y.type === 'linear' && - raw_dom_y[0] >= 0 - ) - y_dom[0] = 0; - } //update domains with those specified in the config - - if ( - config.x.domain && - (config.x.domain[0] || config.x.domain[0] === 0) && - !isNaN(+config.x.domain[0]) - ) { - 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 + var _this = this; + + //convenience mappings + 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; ////////////////////////////////////////////////////////////////////////////////// + // DATA PREP + // prepare data based on the properties of the mark - drop missing records, etc + ////////////////////////////////////////////////////////////////////////////////// + + var cleaned = cleanData.call(this, mark, raw); //prepare nested data required for bar charts + + 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); + } // Get the domain for the mark based on the raw data + + + var raw_dom_x = mark.summarizeX === 'cumulative' ? [0, cleaned.length] : config.x.type === 'ordinal' ? d3.set(cleaned.map(function (m) { + return m[config.x.column]; + })).values().filter(function (f) { + return f; + }) : mark.split && mark.arrange !== 'stacked' ? d3.extent(d3.merge(raw_nest.nested.map(function (m) { + return m.values.map(function (p) { + return p.values.raw.length; + }); + }))) : mark.summarizeX === 'count' ? d3.extent(raw_nest.nested.map(function (m) { + return m.values.raw.length; + })) : d3.extent(cleaned.map(function (m) { + return +m[config.x.column]; + }).filter(function (f) { + return +f || +f === 0; + })); + var raw_dom_y = mark.summarizeY === 'cumulative' ? [0, cleaned.length] : config.y.type === 'ordinal' ? d3.set(cleaned.map(function (m) { + return m[config.y.column]; + })).values().filter(function (f) { + return f; + }) : mark.split && mark.arrange !== 'stacked' ? d3.extent(d3.merge(raw_nest.nested.map(function (m) { + return m.values.map(function (p) { + return p.values.raw.length; + }); + }))) : mark.summarizeY === 'count' ? d3.extent(raw_nest.nested.map(function (m) { + return m.values.raw.length; + })) : d3.extent(cleaned.map(function (m) { + return +m[config.y.column]; + }).filter(function (f) { + return +f || +f === 0; + })); + var 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; + }); + }); //get domain for all non-All values of first filter + + if (config.x.behavior === 'firstfilter' || config.y.behavior === 'firstfilter') { + this.filters[0].choices.filter(function (f) { + return f !== 'All'; + }).forEach(function (e) { + var perfilter = cleaned.filter(function (f) { + return f[_this.filters[0].col] === e; + }); + var filt_nested = makeNest.call(_this, mark, perfilter, sublevel); + filt1_xs.push(filt_nested.dom_x); + filt1_ys.push(filt_nested.dom_y); + }); + } + } //filter on mark-specific instructions + + + 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]; + } + } //several criteria must be met in order to use the 'firstfilter' domain + + + var nonall = Boolean(this.filters.length && this.filters[0].val !== 'All' && this.filters.slice(1).filter(function (f) { + return f.val === 'All'; + }).length === this.filters.length - 1); + var pre_x_dom = !this.filters.length ? flex_dom_x : x_behavior === 'raw' ? raw_dom_x : nonall && x_behavior === 'firstfilter' ? filt1_dom_x : flex_dom_x; + var pre_y_dom = !this.filters.length ? flex_dom_y : y_behavior === 'raw' ? raw_dom_y : nonall && y_behavior === 'firstfilter' ? filt1_dom_y : flex_dom_y; + var x_dom = config.x_dom ? config.x_dom : config.x.type === 'ordinal' && config.x.behavior === 'flex' ? d3.set(filtered.map(function (m) { + return m[config.x.column]; + })).values() : config.x.type === 'ordinal' ? d3.set(cleaned.map(function (m) { + return m[config.x.column]; + })).values() : pre_x_dom; + var y_dom = config.y_dom ? config.y_dom : config.y.type === 'ordinal' && config.y.behavior === 'flex' ? d3.set(filtered.map(function (m) { + return m[config.y.column]; + })).values() : config.y.type === 'ordinal' ? d3.set(cleaned.map(function (m) { + return m[config.y.column]; + })).values() : pre_y_dom; //set lower limit of linear domain to 0 when other axis is ordinal and mark type is set to 'bar', provided no values are negative + + if (mark.type === 'bar') { + if (config.x.behavior !== 'flex' && config.x.type === 'linear' && config.y.type === 'ordinal' && raw_dom_x[0] >= 0) x_dom[0] = 0; + if (config.y.behavior !== 'flex' && config.x.type === 'ordinal' && config.y.type === 'linear' && raw_dom_y[0] >= 0) y_dom[0] = 0; + } //update domains with those specified in the config + + + if (config.x.domain && (config.x.domain[0] || config.x.domain[0] === 0) && !isNaN(+config.x.domain[0])) { + 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); + 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 (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; + } - if (type === 'ordinal') { - x.rangeBands([0, +max_range], config.padding, config.outer_pad); - } else { - x.range([0, +max_range]).clamp(Boolean(config.x.clamp)); - } + 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; + } - 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 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 < max_width ? div_width : this.raw_width; + this.textSize(preWidth); + this.margin = this.setMargins(); + var svg_width = config.x.type === 'ordinal' && +config.x.range_band ? this.raw_width + this.margin.left + this.margin.right : !config.resizable ? this.raw_width : !config.max_width || div_width < config.max_width ? div_width : this.raw_width; + this.plot_width = svg_width - this.margin.left - this.margin.right; + var svg_height = config.y.type === 'ordinal' && +config.y.range_band ? this.raw_height + this.margin.top + this.margin.bottom : !config.resizable && config.height ? config.height : !config.resizable ? svg_width * aspect2 : this.plot_width * aspect2; + this.plot_height = svg_height - this.margin.top - this.margin.bottom; + d3.select(this.svg.node().parentNode).attr('width', svg_width).attr('height', svg_height).select('g').attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')'); + this.svg.select('.overlay').attr('width', this.plot_width).attr('height', this.plot_height).classed('zoomable', config.zoomable); + this.svg.select('.plotting-area').attr('width', this.plot_width).attr('height', this.plot_height + 1).attr('transform', 'translate(0, -1)'); + this.xScaleAxis(); + this.yScaleAxis(); + var g_x_axis = this.svg.select('.x.axis'); + var g_y_axis = this.svg.select('.y.axis'); + var x_axis_label = g_x_axis.select('.axis-title'); + var y_axis_label = g_y_axis.select('.axis-title'); + + if (config.x_location !== 'top') { + g_x_axis.attr('transform', 'translate(0,' + this.plot_height + ')'); + } + + var gXAxisTrans = config.transitions ? g_x_axis.transition() : g_x_axis; + gXAxisTrans.call(this.xAxis); + var gYAxisTrans = config.transitions ? g_y_axis.transition() : g_y_axis; + gYAxisTrans.call(this.yAxis); + x_axis_label.attr('transform', 'translate(' + this.plot_width / 2 + ',' + (this.margin.bottom - 2) + ')'); + y_axis_label.attr('x', -1 * this.plot_height / 2).attr('y', -1 * this.margin.left); + this.svg.selectAll('.axis .domain').attr({ + fill: 'none', + stroke: '#ccc', + 'stroke-width': 1, + 'shape-rendering': 'crispEdges' + }); + this.svg.selectAll('.axis .tick line').attr({ + stroke: '#eee', + 'stroke-width': 1, + 'shape-rendering': 'crispEdges' + }); + this.drawGridlines(); //update legend - margins need to be set first + + this.makeLegend(); //update the chart's specific marks + + this.updateDataMarks(); //call .on("resize") function, if any + + this.events.onResize.call(this); } - function yScaleAxis(max_range, domain, type) { - if (max_range === undefined) { - max_range = this.plot_height; - } + function textSize(width) { + var font_size = '14px'; + var point_size = 4; + var stroke_width = 2; + + if (!this.config.scale_text) { + font_size = this.config.font_size; + point_size = this.config.point_size || 4; + stroke_width = this.config.stroke_width || 2; + } else if (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; + } - if (domain === undefined) { - domain = this.y_dom; - } + 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 : 0.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 * 0.5 + font_size * y_label_on * 1.5 || 8; + var x_margin = font_size + font_size / 1.5 + font_size * x_label_on + font_size * x_second || 8; + 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 + }; + } - if (type === undefined) { - type = this.config.y.type; - } + function drawGridLines() { + this.wrap.classed('gridlines', this.config.gridlines); - var config = this.config; - var y; + 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); + } + } - if (type === 'log') { - y = d3.scale.log(); - } else if (type === 'ordinal') { - y = d3.scale.ordinal(); - } else if (type === 'time') { - y = d3.time.scale(); + 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) { + //singular chart + if (this.config.legend.location === 'top' || this.config.legend.location === 'left') { + this.wrap.node().insertBefore(legendOriginal.node(), this.svg.node().parentNode); } else { - y = d3.scale.linear(); + this.wrap.node().appendChild(legendOriginal.node()); } - - y.domain(domain); - - if (type === 'ordinal') { - y.rangeBands([+max_range, 0], config.padding, config.outer_pad); + } else { + //multiples - keep legend outside of individual charts' wraps + if (this.config.legend.location === 'top' || this.config.legend.location === 'left') { + this.parent.wrap.node().insertBefore(legendOriginal.node(), this.parent.wrap.select('.wc-chart').node()); } else { - y.range([+max_range, 0]).clamp(Boolean(config.y_clamp)); + 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; + } - 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 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 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 < max_width - ? div_width - : this.raw_width; - this.textSize(preWidth); - this.margin = this.setMargins(); - var svg_width = - config.x.type === 'ordinal' && +config.x.range_band - ? this.raw_width + this.margin.left + this.margin.right - : !config.resizable - ? this.raw_width - : !config.max_width || div_width < config.max_width - ? div_width - : this.raw_width; - this.plot_width = svg_width - this.margin.left - this.margin.right; - var svg_height = - config.y.type === 'ordinal' && +config.y.range_band - ? this.raw_height + this.margin.top + this.margin.bottom - : !config.resizable && config.height - ? config.height - : !config.resizable - ? svg_width * aspect2 - : this.plot_width * aspect2; - this.plot_height = svg_height - this.margin.top - this.margin.bottom; - d3.select(this.svg.node().parentNode) - .attr('width', svg_width) - .attr('height', svg_height) - .select('g') - .attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')'); - this.svg - .select('.overlay') - .attr('width', this.plot_width) - .attr('height', this.plot_height) - .classed('zoomable', config.zoomable); - this.svg - .select('.plotting-area') - .attr('width', this.plot_width) - .attr('height', this.plot_height + 1) - .attr('transform', 'translate(0, -1)'); - this.xScaleAxis(); - this.yScaleAxis(); - var g_x_axis = this.svg.select('.x.axis'); - var g_y_axis = this.svg.select('.y.axis'); - var x_axis_label = g_x_axis.select('.axis-title'); - var y_axis_label = g_y_axis.select('.axis-title'); - - if (config.x_location !== 'top') { - g_x_axis.attr('transform', 'translate(0,' + this.plot_height + ')'); - } + 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 : 0.3); //don't transition if config says not to + + var areaPathTransitions = this.config.transitions ? areaPaths.transition() : areaPaths; + areaPathTransitions.attr('d', area_drawer); + return area_grps; + } - var gXAxisTrans = config.transitions ? g_x_axis.transition() : g_x_axis; - gXAxisTrans.call(this.xAxis); - var gYAxisTrans = config.transitions ? g_y_axis.transition() : g_y_axis; - gYAxisTrans.call(this.yAxis); - x_axis_label.attr( - 'transform', - 'translate(' + this.plot_width / 2 + ',' + (this.margin.bottom - 2) + ')' - ); - y_axis_label.attr('x', (-1 * this.plot_height) / 2).attr('y', -1 * this.margin.left); - this.svg.selectAll('.axis .domain').attr({ - fill: 'none', - stroke: '#ccc', - 'stroke-width': 1, - 'shape-rendering': 'crispEdges' + 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; }); - this.svg.selectAll('.axis .tick line').attr({ - stroke: '#eee', - 'stroke-width': 1, - 'shape-rendering': 'crispEdges' + 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 * 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); + }) : [d]; + }, function (d) { + return d.key; }); - this.drawGridlines(); //update legend - margins need to be set first - this.makeLegend(); //update the chart's specific marks + var _exitBars = config.transitions ? bars.exit().transition() : bars.exit(); - this.updateDataMarks(); //call .on("resize") function, if any + _exitBars.attr('x', this.x(0)).attr('width', 0).remove(); - this.events.onResize.call(this); - } + 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); + }); - function textSize(width) { - var font_size = '14px'; - var point_size = 4; - var stroke_width = 2; - - if (!this.config.scale_text) { - font_size = this.config.font_size; - point_size = this.config.point_size || 4; - stroke_width = this.config.stroke_width || 2; - } else if (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; - } + var _xformat = config.marks.map(function (m) { + return m.summarizeX === 'percent'; + }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.x.format); - this.wrap.style('font-size', font_size); - this.config.flex_point_size = point_size; - this.config.flex_stroke_width = stroke_width; - } + var _yformat = config.marks.map(function (m) { + return m.summarizeY === 'percent'; + }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.y.format); - 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; - } + 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]; + }); + }); - 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 : 0.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 * 0.5 + font_size * y_label_on * 1.5 || 8; - var x_margin = - font_size + font_size / 1.5 + font_size * x_label_on + font_size * x_second || 8; - 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 - }; - } + var _barsTrans = config.transitions ? bars.transition() : bars; + + _barsTrans.attr('x', function (d) { + if (d.arrange === 'stacked' || !d.arrange) { + return d.values.start !== undefined ? _this.x(d.values.start) : _this.x(0); + } else { + return _this.x(0); + } + }).attr('y', function (d) { + if (d.arrange === 'nested') { + var position = d.subcats.indexOf(d.key); + var offset = position ? _this.y.rangeBand() / (d.subcats.length * 0.75) / position : _this.y.rangeBand(); + return _this.y(d.values.y) + (_this.y.rangeBand() - offset) / 2; + } else if (d.arrange === 'grouped') { + var _position2 = d.subcats.indexOf(d.key); + + return _this.y(d.values.y) + _this.y.rangeBand() / d.subcats.length * _position2; + } else { + return _this.y(d.values.y); + } + }).attr('width', function (d) { + return _this.x(d.values.x) - _this.x(0); + }).attr('height', function (d) { + if (config.y.type === 'quantile') { + return 20; + } else if (d.arrange === 'nested') { + var position = d.subcats.indexOf(d.key); + return position ? _this.y.rangeBand() / (d.subcats.length * 0.75) / position : _this.y.rangeBand(); + } else if (d.arrange === 'grouped') { + return _this.y.rangeBand() / d.subcats.length; + } else { + return _this.y.rangeBand(); + } + }); + } 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; + }); - 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); - } - } + var _exitBars2 = config.transitions ? bars.exit().transition() : bars.exit(); - 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) { - //singular chart - 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 { - //multiples - keep legend outside of individual charts' wraps - if (this.config.legend.location === 'top' || this.config.legend.location === 'left') { - this.parent.wrap - .node() - .insertBefore( - legendOriginal.node(), - this.parent.wrap.select('.wc-chart').node() - ); - } else { - this.parent.wrap.node().appendChild(legendOriginal.node()); - } - } + _exitBars2.attr('y', this.y(0)).attr('height', 0).remove(); - 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; + 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]); }); - 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' - }); - } + 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; }); - 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'); - } + var _xformat2 = config.marks.map(function (m) { + return m.summarizeX === 'percent'; + }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.x.format); - this.legend = legend; - } + var _yformat2 = config.marks.map(function (m) { + return m.summarizeY === 'percent'; + }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.y.format); - 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'); - } + 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]; + }); + }); - 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 - : 0.3 - ); //don't transition if config says not to - - var areaPathTransitions = this.config.transitions ? areaPaths.transition() : areaPaths; - areaPathTransitions.attr('d', area_drawer); - return area_grps; - } + 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; + }); - function drawBars(marks) { - var _this = this; + var _exitBars3 = config.transitions ? bars.exit().transition() : bars.exit(); - 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('-'); + _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; }); - 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 * 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) - ); - }) - : [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 _xformat3 = config.marks.map(function (m) { + return m.summarizeX === 'percent'; + }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.x.format); - var _barsTrans = config.transitions ? bars.transition() : bars; - - _barsTrans - .attr('x', function(d) { - if (d.arrange === 'stacked' || !d.arrange) { - return d.values.start !== undefined ? _this.x(d.values.start) : _this.x(0); - } else { - return _this.x(0); - } - }) - .attr('y', function(d) { - if (d.arrange === 'nested') { - var position = d.subcats.indexOf(d.key); - var offset = position - ? _this.y.rangeBand() / (d.subcats.length * 0.75) / position - : _this.y.rangeBand(); - return _this.y(d.values.y) + (_this.y.rangeBand() - offset) / 2; - } else if (d.arrange === 'grouped') { - var _position2 = d.subcats.indexOf(d.key); - - return ( - _this.y(d.values.y) + - (_this.y.rangeBand() / d.subcats.length) * _position2 - ); - } else { - return _this.y(d.values.y); - } - }) - .attr('width', function(d) { - return _this.x(d.values.x) - _this.x(0); - }) - .attr('height', function(d) { - if (config.y.type === 'quantile') { - return 20; - } else if (d.arrange === 'nested') { - var position = d.subcats.indexOf(d.key); - return position - ? _this.y.rangeBand() / (d.subcats.length * 0.75) / position - : _this.y.rangeBand(); - } else if (d.arrange === 'grouped') { - return _this.y.rangeBand() / d.subcats.length; - } else { - return _this.y.rangeBand(); - } - }); - } 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 _yformat3 = config.marks.map(function (m) { + return m.summarizeY === 'percent'; + }).indexOf(true) > -1 ? d3.format('0%') : d3.format(config.y.format); - 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]; - }); - }); + 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 _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 _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(); + } //Link to the d3.selection from the data - 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(); - } //Link to the d3.selection from the data - - bar_supergroups.each(function(d) { - d.supergroup = d3.select(this); - d.groups = d.supergroup.selectAll('.bar-group'); - }); + 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]; - }); - }); //Link to the d3.selection from the data - - line_supergroups.each(function(d) { - d.supergroup = d3.select(this); - d.groups = d.supergroup.selectAll('g.line'); - d.paths = d.groups.select('path'); + 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]; }); - return line_grps; + }); //Link to the d3.selection from the data + + 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('-'); + 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'); //static attributes + + points.select('circle').style('clip-path', "url(#".concat(chart.id, ")")).attr('fill-opacity', config.fill_opacity || config.fill_opacity === 0 ? config.fill_opacity : 0.6).attr('fill', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }).attr('stroke', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); //attach mark info + + points.each(function (d) { + var mark = d3.select(this.parentNode).datum(); + d.mark = mark; + d3.select(this).select('circle').attr(mark.attributes); + }); //animated attributes + + var pointsTrans = config.transitions ? points.select('circle').transition() : points.select('circle'); + pointsTrans.attr('r', function (d) { + return d.mark.radius || config.flex_point_size; + }).attr('cx', function (d) { + var x_pos = _this.x(d.values.x) || 0; + return config.x.type === 'ordinal' ? x_pos + _this.x.rangeBand() / 2 : x_pos; + }).attr('cy', function (d) { + var y_pos = _this.y(d.values.y) || 0; + return config.y.type === 'ordinal' ? y_pos + _this.y.rangeBand() / 2 : y_pos; + }); + 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 - .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'); //static attributes - - points - .select('circle') - .style('clip-path', 'url(#'.concat(chart.id, ')')) - .attr( - 'fill-opacity', - config.fill_opacity || config.fill_opacity === 0 ? config.fill_opacity : 0.6 - ) - .attr('fill', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }) - .attr('stroke', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); //attach mark info - - points.each(function(d) { - var mark = d3.select(this.parentNode).datum(); - d.mark = mark; - d3.select(this) - .select('circle') - .attr(mark.attributes); - }); //animated attributes - - var pointsTrans = config.transitions - ? points.select('circle').transition() - : points.select('circle'); - pointsTrans - .attr('r', function(d) { - return d.mark.radius || config.flex_point_size; - }) - .attr('cx', function(d) { - var x_pos = _this.x(d.values.x) || 0; - return config.x.type === 'ordinal' ? x_pos + _this.x.rangeBand() / 2 : x_pos; - }) - .attr('cy', function(d) { - var y_pos = _this.y(d.values.y) || 0; - return config.y.type === 'ordinal' ? y_pos + _this.y.rangeBand() / 2 : y_pos; - }); - 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]; - }); - }); //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'); - }); - return points; + }); //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'); + }); + 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('-')); + 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(); // don't need to transition position of outgoing text + // const oldTextsTrans = config.transitions ? oldTexts.selectAll('text').transition() : oldTexts.selectAll('text'); + + 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'); // don't need to set initial location for incoming text + // attach mark info + + function attachMarks(d) { + d.mark = d3.select(this.parentNode).datum(); + d3.select(this).select('text').attr(d.mark.attributes); + } + + texts.each(attachMarks); // parse text like tooltips + + 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]; }); - 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(); // don't need to transition position of outgoing text - // const oldTextsTrans = config.transitions ? oldTexts.selectAll('text').transition() : oldTexts.selectAll('text'); - - 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'); // don't need to set initial location for incoming text - // attach mark info - - function attachMarks(d) { - d.mark = d3.select(this.parentNode).datum(); - d3.select(this) - .select('text') - .attr(d.mark.attributes); - } + }); // animated attributes - texts.each(attachMarks); // parse text like tooltips - - 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]; - }); - }); // animated attributes - - var textsTrans = config.transitions - ? texts.select('text').transition() - : texts.select('text'); - textsTrans - .attr('x', function(d) { - var xPos = _this.x(d.values.x) || 0; - return config.x.type === 'ordinal' ? xPos + _this.x.rangeBand() / 2 : xPos; - }) - .attr('y', function(d) { - var yPos = _this.y(d.values.y) || 0; - return config.y.type === 'ordinal' ? yPos + _this.y.rangeBand() / 2 : yPos; - }); //add a reference to the selection from it's data - - textSupergroups.each(function(d) { - d.supergroup = d3.select(this); - d.groups = d.supergroup.selectAll('g.text'); - d.texts = d.groups.select('text'); - }); - return texts; + var textsTrans = config.transitions ? texts.select('text').transition() : texts.select('text'); + textsTrans.attr('x', function (d) { + var xPos = _this.x(d.values.x) || 0; + return config.x.type === 'ordinal' ? xPos + _this.x.rangeBand() / 2 : xPos; + }).attr('y', function (d) { + var yPos = _this.y(d.values.y) || 0; + return config.y.type === 'ordinal' ? yPos + _this.y.rangeBand() / 2 : yPos; + }); //add a reference to the selection from it's data + + textSupergroups.each(function (d) { + 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; - //run onDestroy callback - this.events.onDestroy.call(this); //remove resize event listener + var destroyControls = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + //run onDestroy callback + this.events.onDestroy.call(this); //remove resize event listener - var context = this; - if (!this.test) d3.select(window).on('resize.' + context.element + context.id, null); //destroy controls + var context = this; + if (!this.test) d3.select(window).on('resize.' + context.element + context.id, null); //destroy controls - if (destroyControls && this.controls) { - this.controls.destroy(); - } //unmount chart wrapper + if (destroyControls && this.controls) { + this.controls.destroy(); + } //unmount chart wrapper - this.wrap.remove(); + + this.wrap.remove(); } var chartProto = { - raw_data: [], - config: {} + 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 - } + 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() {} - }; + 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; - } + 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; + } + }; //increment thisChart count to get unique thisChart id - if (callback) { - thisChart.events['on' + event.charAt(0).toUpperCase() + event.slice(1)] = callback; - } - }; //increment thisChart count to get unique thisChart id - chartCount++; - thisChart.id = chartCount; - return thisChart; + chartCount++; + thisChart.id = chartCount; + return thisChart; } function changeOption(option, value, callback, draw) { - var _this = this; + 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); - } //call callback function if provided + 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); + } //call callback function if provided - if (callback) { - callback(); - } - if (draw) target.draw(); - }); + 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.' - ) - ); //Draw the chart when a control changes unless the user specifies otherwise. - - input.draw = input.draw === undefined ? true : input.draw; - }); + 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.")); //Draw the chart when a control changes unless the user specifies otherwise. + + input.draw = input.draw === undefined ? true : input.draw; + }); } function controlUpdate() { - var _this = this; + var _this = this; - if (this.config.inputs && this.config.inputs.length && this.config.inputs[0]) - this.config.inputs.forEach(function(input) { - return _this.makeControlItem(input); - }); + if (this.config.inputs && this.config.inputs.length && this.config.inputs[0]) this.config.inputs.forEach(function (input) { + return _this.makeControlItem(input); + }); } function destroy$1() { - //unmount controls wrapper - this.wrap.remove(); + //unmount controls wrapper + this.wrap.remove(); } function init$1(data) { - this.data = data; - if (!this.config.builder) this.checkRequired(this.data); - this.layout(); + 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(); + 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); //Add control label span. - - var ctrl_label = control_wrap - .append('span') - .attr('class', 'wc-control-label') - .text(control.label); //Add control _Required_ text to control label span. - - if (control.required) - ctrl_label - .append('span') - .attr('class', 'label label-required') - .text('Required'); //Add control description span. - - 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".' - ); - } + var control_wrap = this.wrap.append('div').attr('class', 'control-group').classed('inline', control.inline).datum(control); //Add control label span. + + var ctrl_label = control_wrap.append('span').attr('class', 'wc-control-label').text(control.label); //Add control _Required_ text to control label span. + + if (control.required) ctrl_label.append('span').attr('class', 'label label-required').text('Required'); //Add control description span. + + control_wrap.append('span').attr('class', 'span-description').text(control.description); + + 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); + 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'); + var _this = this; - _this.changeOption(d.option, value, control.callback, control.draw); - }); + 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 _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); } - - 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; + }); + 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); - }); + 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'); + var _this = this; - _this.changeOption(control.option, value, control.callback, control.draw); - }); + 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); + 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; // associated charts and tables. - //dropdown selection - - var changer = control_wrap - .append('select') - .classed('changer', true) - .attr('multiple', control.multiple ? true : null) - .datum(control); //dropdown option data - - var option_data = control.values - ? control.values - : d3 - .set( - this.data - .map(function(m) { - return m[control.value_col]; - }) - .filter(function(f) { - return f; - }) - ) - .values() - .sort(naturalSorter); // only sort when values are derived - //initial dropdown option - - control.start = control.start ? control.start : control.loose ? option_data[0] : null; //conditionally add All option - - if (!control.multiple && !control.start) { - option_data.unshift('All'); - control.all = true; + var targets = this.targets; // associated charts and tables. + //dropdown selection + + var changer = control_wrap.append('select').classed('changer', true).attr('multiple', control.multiple ? true : null).datum(control); //dropdown option data + + var option_data = control.values ? control.values : d3.set(this.data.map(function (m) { + return m[control.value_col]; + }).filter(function (f) { + return f; + })).values().sort(naturalSorter); // only sort when values are derived + //initial dropdown option + + control.start = control.start ? control.start : control.loose ? option_data[0] : null; //conditionally add All option + + if (!control.multiple && !control.start) { + option_data.unshift('All'); + control.all = true; + } else { + control.all = false; + } //what does loose mean? + + + control.loose = !control.loose && control.start ? true : control.loose; //dropdown options selection + + var options = changer.selectAll('option').data(option_data).enter().append('option').text(function (d) { + return d; + }).property('selected', function (d) { + return d === control.start; + }); //define filter object for each associated target + + targets.forEach(function (e) { + var match = e.filters.slice().map(function (m) { + return m.col === control.value_col; + }).indexOf(true); + + 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 { - control.all = false; - } //what does loose mean? - - control.loose = !control.loose && control.start ? true : control.loose; //dropdown options selection - - var options = changer - .selectAll('option') - .data(option_data) - .enter() - .append('option') - .text(function(d) { - return d; - }) - .property('selected', function(d) { - return d === control.start; - }); //define filter object for each associated target - - targets.forEach(function(e) { - var match = e.filters - .slice() - .map(function(m) { - return m.col === control.value_col; - }) - .indexOf(true); - - 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 - }); - } + 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; + } }); - 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; + if (match > -1) { + target.filters[match] = obj; + } + } //add event listener to control + + + 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, + // could specify an array of indices but seems like a waste of resources give it doesn't inform anything without an overall 'All' + choices: option_data, + loose: control.loose, + all: control.all + }; + targets.forEach(function (e) { + setSubsetter(e, new_filter); //call callback function if provided + + if (control.callback) { + control.callback(); } - } //add event listener to control - - 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, - // could specify an array of indices but seems like a waste of resources give it doesn't inform anything without an overall 'All' - choices: option_data, - loose: control.loose, - all: control.all - }; - targets.forEach(function(e) { - setSubsetter(e, new_filter); //call callback function if provided - - 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); //call callback function if provided - - if (control.callback) { - control.callback(); - } - - e.draw(); - }); + + 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); //call callback function if provided + + 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'); + var _this = this; - _this.changeOption(control.option, value, control.callback, control.draw); - }); + 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) { - //adapted from http://jsfiddle.net/alnitak/hEsys/ - s = s.replace(/\[(\w+)\]/g, '.$1'); - s = s.replace(/^\./, ''); - var a = s.split('.'); + //adapted from http://jsfiddle.net/alnitak/hEsys/ + s = s.replace(/\[(\w+)\]/g, '.$1'); + s = s.replace(/^\./, ''); + var a = s.split('.'); - for (var i = 0, n = a.length; i < n; ++i) { - var k = a[i]; + for (var i = 0, n = a.length; i < n; ++i) { + var k = a[i]; - if (k in o) { - if (i == n - 1 && v !== undefined) o[k] = v; - o = o[k]; - } else { - return; - } + if (k in o) { + if (i == n - 1 && v !== undefined) o[k] = v; + o = o[k]; + } else { + return; } + } - return o; + return o; } var controls = { - changeOption: changeOption, - checkRequired: checkRequired$1, - controlUpdate: controlUpdate, - destroy: destroy$1, - init: init$1, - layout: layout$1, - makeControlItem: makeControlItem, - makeBtnGroupControl: makeBtnGroupControl, - makeCheckboxControl: makeCheckboxControl, - makeDropdownControl: makeDropdownControl, - makeListControl: makeListControl, - makeNumberControl: makeNumberControl, - makeRadioControl: makeRadioControl, - makeSubsetterControl: makeSubsetterControl, - makeTextControl: makeTextControl, - stringAccessor: stringAccessor + changeOption: changeOption, + checkRequired: checkRequired$1, + controlUpdate: controlUpdate, + destroy: destroy$1, + init: init$1, + layout: layout$1, + makeControlItem: makeControlItem, + makeBtnGroupControl: makeBtnGroupControl, + makeCheckboxControl: makeCheckboxControl, + makeDropdownControl: makeDropdownControl, + makeListControl: makeListControl, + makeNumberControl: makeNumberControl, + makeRadioControl: makeRadioControl, + makeSubsetterControl: makeSubsetterControl, + makeTextControl: makeTextControl, + stringAccessor: stringAccessor }; function createControls() { - var element = arguments.length > 0 && 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'); - } + var element = arguments.length > 0 && 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; + thisControls.wrap.datum(thisControls); + return thisControls; } function applyFilters() { - var _this = this; - - //If there are filters, return a filtered data array of the raw data. - //Otherwise return the raw data. - if ( - this.filters && - this.filters.some(function(filter) { - return ( - (typeof filter.val === 'string' && - !(filter.all === true && filter.index === 0)) || - (Array.isArray(filter.val) && filter.val.length < filter.choices.length) - ); - }) - ) { - this.data.filtered = this.data.raw.slice(); - this.filters - .filter(function(filter) { - return ( - (typeof filter.val === 'string' && - !(filter.all === true && filter.index === 0)) || - (Array.isArray(filter.val) && filter.val.length < filter.choices.length) - ); - }) - .forEach(function(filter) { - _this.data.filtered = _this.data.filtered.filter(function(d) { - return Array.isArray(filter.val) - ? filter.val.indexOf(d[filter.col]) > -1 - : filter.val === d[filter.col]; - }); - }); - } else this.data.filtered = this.data.raw.slice(); + var _this = this; + + //If there are filters, return a filtered data array of the raw data. + //Otherwise return the raw data. + if (this.filters && this.filters.some(function (filter) { + return typeof filter.val === 'string' && !(filter.all === true && filter.index === 0) || Array.isArray(filter.val) && filter.val.length < filter.choices.length; + })) { + this.data.filtered = this.data.raw.slice(); + this.filters.filter(function (filter) { + return typeof filter.val === 'string' && !(filter.all === true && filter.index === 0) || Array.isArray(filter.val) && filter.val.length < filter.choices.length; + }).forEach(function (filter) { + _this.data.filtered = _this.data.filtered.filter(function (d) { + return Array.isArray(filter.val) ? filter.val.indexOf(d[filter.col]) > -1 : filter.val === d[filter.col]; + }); + }); + } else this.data.filtered = this.data.raw.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; // first row shown + 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; // first row shown - this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown + this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown } function applySearchTerm(data) { - var _this = this; - - if (this.searchable.searchTerm) { - //Determine which rows contain input text. - 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 { - //Otherwise delete previously searched data and set data to filtered data. - delete this.data.searched; - this.data.processing = this.data.filtered; - } + var _this = this; + + if (this.searchable.searchTerm) { + //Determine which rows contain input text. + 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 { + //Otherwise delete previously searched data and set data to filtered data. + delete this.data.searched; + this.data.processing = this.data.filtered; + } } /*------------------------------------------------------------------------------------------------\ Check equality of two arrays (https://stackoverflow.com/questions/7837456/how-to-compare-arrays-in-javascript) \------------------------------------------------------------------------------------------------*/ // Warn if overriding existing method - if (Array.prototype.equals) - console.warn( - "Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code." - ); // attach the .equals method to Array's prototype to call it on any array - - Array.prototype.equals = function(array) { - // if the other array is a falsy value, return - if (!array) return false; // compare lengths - can save a lot of time - - if (this.length != array.length) return false; - - for (var i = 0, l = this.length; i < l; i++) { - // Check if we have nested arrays - if (this[i] instanceof Array && array[i] instanceof Array) { - // recurse into the nested arrays - if (!this[i].equals(array[i])) return false; - } else if (this[i] != array[i]) { - // Warning - two different object instances will never be equal: {x:20} != {x:20} - return false; - } + if (Array.prototype.equals) console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code."); // attach the .equals method to Array's prototype to call it on any array + + Array.prototype.equals = function (array) { + // if the other array is a falsy value, return + if (!array) return false; // compare lengths - can save a lot of time + + if (this.length != array.length) return false; + + for (var i = 0, l = this.length; i < l; i++) { + // Check if we have nested arrays + if (this[i] instanceof Array && array[i] instanceof Array) { + // recurse into the nested arrays + if (!this[i].equals(array[i])) return false; + } else if (this[i] != array[i]) { + // Warning - two different object instances will never be equal: {x:20} != {x:20} + return false; } + } - return true; + return true; }; // Hide method from for-in loops + Object.defineProperty(Array.prototype, 'equals', { - enumerable: false + enumerable: false }); function checkFilters() { - if (this.filters) { - this.currentFilters = this.filters.map(function(filter) { - return filter.val; - }); //Reset pagination if filters have changed. - - if (!this.currentFilters.equals(this.previousFilters)) { - this.config.activePage = 0; - this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; // first row shown + if (this.filters) { + this.currentFilters = this.filters.map(function (filter) { + return filter.val; + }); //Reset pagination if filters have changed. - this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown - } + if (!this.currentFilters.equals(this.previousFilters)) { + this.config.activePage = 0; + this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; // first row shown - this.previousFilters = this.currentFilters; + this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown } + + this.previousFilters = this.currentFilters; + } } function updateTableHeaders() { - var _this = this; - - this.thead_cells = this.thead - .select('tr') - .selectAll('th') - .data(this.config.headers, function(d) { - return d; - }); - this.thead_cells.exit().remove(); - this.thead_cells.enter().append('th'); - this.thead_cells - .sort(function(a, b) { - return _this.config.headers.indexOf(a) - _this.config.headers.indexOf(b); - }) - .attr('class', function(d) { - return _this.config.cols[_this.config.headers.indexOf(d)]; - }) // associate column header with column name - .text(function(d) { - return d; - }); + var _this = this; + + this.thead_cells = this.thead.select('tr').selectAll('th').data(this.config.headers, function (d) { + return d; + }); + this.thead_cells.exit().remove(); + this.thead_cells.enter().append('th'); + this.thead_cells.sort(function (a, b) { + return _this.config.headers.indexOf(a) - _this.config.headers.indexOf(b); + }).attr('class', function (d) { + return _this.config.cols[_this.config.headers.indexOf(d)]; + }) // associate column header with column name + .text(function (d) { + return d; + }); } function drawTableBody() { - var _this = this; - - var table = this; //Define table body rows. - - var rows = this.tbody - .selectAll('tr') - .data(this.data.processing) - .enter() - .append('tr'); //Define table body cells. - - var cells = rows.selectAll('td').data(function(d) { - return _this.config.cols.map(function(key) { - return { - col: key, - text: d[key] - }; - }); + var _this = this; + + var table = this; //Define table body rows. + + var rows = this.tbody.selectAll('tr').data(this.data.processing).enter().append('tr'); //Define table body cells. + + var cells = rows.selectAll('td').data(function (d) { + return _this.config.cols.map(function (key) { + return { + col: key, + text: d[key] + }; }); - cells.exit().remove(); - cells.enter().append('td'); - cells - .sort(function(a, b) { - return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); - }) - .attr('class', function(d) { - return d.col; - }) - .each(function(d) { - var cell = d3.select(this); //Apply text in data as html or as plain text. - - if (table.config.as_html) { - cell.html(d.text); - } else { - cell.text(d.text); - } - }); + }); + cells.exit().remove(); + cells.enter().append('td'); + cells.sort(function (a, b) { + return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); + }).attr('class', function (d) { + return d.col; + }).each(function (d) { + var cell = d3.select(this); //Apply text in data as html or as plain text. + + if (table.config.as_html) { + cell.html(d.text); + } else { + cell.text(d.text); + } + }); } function dynamicLayout() { - var widths = { - table: this.table.select('thead').node().offsetWidth, - top: - this.wrap.select('.table-top .searchable-container').node().offsetWidth + - this.wrap.select('.table-top .sortable-container').node().offsetWidth, - bottom: - this.wrap.select('.table-bottom .pagination-container').node().offsetWidth + - this.wrap.select('.table-bottom .exportable-container').node().offsetWidth - }; - - if ( - widths.table < Math.max(widths.top, widths.bottom) && - this.config.layout === 'horizontal' - ) { - this.config.layout = 'vertical'; - this.wrap - .style('display', 'inline-block') - .selectAll('.table-top,.table-bottom') - .style('display', 'inline-block') - .selectAll('.interactivity') - .style({ - display: 'block', - clear: 'both' - }); - } else if ( - widths.table >= Math.max(widths.top, widths.bottom) && - this.config.layout === 'vertical' - ) { - this.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 - }); - } + var widths = { + table: this.table.select('thead').node().offsetWidth, + top: this.wrap.select('.table-top .searchable-container').node().offsetWidth + this.wrap.select('.table-top .sortable-container').node().offsetWidth, + bottom: this.wrap.select('.table-bottom .pagination-container').node().offsetWidth + this.wrap.select('.table-bottom .exportable-container').node().offsetWidth + }; + + if (widths.table < Math.max(widths.top, widths.bottom) && this.config.layout === 'horizontal') { + this.config.layout = 'vertical'; + this.wrap.style('display', 'inline-block').selectAll('.table-top,.table-bottom').style('display', 'inline-block').selectAll('.interactivity').style({ + display: 'block', + clear: 'both' + }); + } else if (widths.table >= Math.max(widths.top, widths.bottom) && this.config.layout === 'vertical') { + this.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; // make passed data available on preprocess - - this.events.onPreprocess.call(this); - if (!passed_data) - //Apply filters if data is not passed to table.draw(). - applyFilters.call(this); - //Otherwise update data object. - else updateDataObject.call(this); //Compare current filter settings to previous filter settings, if any. - - checkFilters.call(this); //Filter data on search term if it exists and set data to searched data. - - applySearchTerm.call(this); - this.searchable.wrap - .select('.nNrecords') - .text( - this.data.processing.length === this.data.raw.length - ? ''.concat(this.data.raw.length, ' records displayed') - : '' - .concat(this.data.processing.length, '/') - .concat(this.data.raw.length, ' records displayed') - ); //Update table headers. - - updateTableHeaders.call(this); //Clear table body rows. - - this.tbody.selectAll('tr').remove(); //Print a note that no data was selected for empty tables. - - if (this.data.processing.length === 0) { - this.tbody - .append('tr') - .classed('no-data', true) - .append('td') - .attr('colspan', this.config.cols.length) - .text('No data selected.'); //Bind table filtered/searched data to table container. - - this.data.current = this.data.processing; - this.table.datum(this.table.current); //Add export. - - if (this.config.exportable) - this.config.exports.forEach(function(fmt) { - _this.exportable.exports[fmt].call(_this, _this.data.processing); - }); //Add pagination. - - if (this.config.pagination) - this.pagination.addPagination.call(this, this.data.processing); - } else { - //Sort data. - if (this.config.sortable) { - this.thead.selectAll('th').on('click', function(header) { - table.sortable.onClick.call(table, this, header); - }); - if (this.sortable.order.length) - this.sortable.sortData.call(this, this.data.processing); - } //Bind table filtered/searched data to table container. - - this.data.current = this.data.processing; - this.table.datum(this.data.current); //Add export. - - if (this.config.exportable) - this.config.exports.forEach(function(fmt) { - _this.exportable.exports[fmt].call(_this, _this.data.processing); - }); //Add pagination. - - if (this.config.pagination) { - this.pagination.addPagination.call(this, this.data.processing); //Apply pagination. - - this.data.processing = this.data.processing.filter(function(d, i) { - return _this.config.startIndex <= i && i < _this.config.endIndex; - }); - } //Define table body rows. - - drawTableBody.call(this); - } //Alter table layout if table is narrower than table top or bottom. - - if (this.config.dynamicPositioning) { - dynamicLayout.call(this); - } + var _this = this; + + var table = this; + var config = this.config; + this.data.passed = passed_data; // make passed data available on preprocess + + this.events.onPreprocess.call(this); + if (!passed_data) //Apply filters if data is not passed to table.draw(). + applyFilters.call(this); //Otherwise update data object. + else updateDataObject.call(this); //Compare current filter settings to previous filter settings, if any. + + checkFilters.call(this); //Filter data on search term if it exists and set data to searched data. + + applySearchTerm.call(this); + this.searchable.wrap.select('.nNrecords').text(this.data.processing.length === this.data.raw.length ? "".concat(this.data.raw.length, " records displayed") : "".concat(this.data.processing.length, "/").concat(this.data.raw.length, " records displayed")); //Update table headers. + + updateTableHeaders.call(this); //Clear table body rows. + + this.tbody.selectAll('tr').remove(); //Print a note that no data was selected for empty tables. + + if (this.data.processing.length === 0) { + this.tbody.append('tr').classed('no-data', true).append('td').attr('colspan', this.config.cols.length).text('No data selected.'); //Bind table filtered/searched data to table container. + + this.data.current = this.data.processing; + this.table.datum(this.table.current); //Add export. + + if (this.config.exportable) this.config.exports.forEach(function (fmt) { + _this.exportable.exports[fmt].call(_this, _this.data.processing); + }); //Add pagination. + + if (this.config.pagination) this.pagination.addPagination.call(this, this.data.processing); + } else { + //Sort data. + if (this.config.sortable) { + this.thead.selectAll('th').on('click', function (header) { + table.sortable.onClick.call(table, this, header); + }); + if (this.sortable.order.length) this.sortable.sortData.call(this, this.data.processing); + } //Bind table filtered/searched data to table container. + - this.events.onDraw.call(this); + this.data.current = this.data.processing; + this.table.datum(this.data.current); //Add export. + + if (this.config.exportable) this.config.exports.forEach(function (fmt) { + _this.exportable.exports[fmt].call(_this, _this.data.processing); + }); //Add pagination. + + if (this.config.pagination) { + this.pagination.addPagination.call(this, this.data.processing); //Apply pagination. + + this.data.processing = this.data.processing.filter(function (d, i) { + return _this.config.startIndex <= i && i < _this.config.endIndex; + }); + } //Define table body rows. + + + drawTableBody.call(this); + } //Alter table layout if table is narrower than table top or bottom. + + + 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; // first row shown - - context.config.endIndex = context.config.startIndex + context.config.nRowsPerPage; // last row shown - - context.draw(); - }); - this.searchable.wrap - .select('.search') - .append('span') - .classed('nNrecords', true); + 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; // first row shown + + context.config.endIndex = context.config.startIndex + context.config.nRowsPerPage; // last row shown + + context.draw(); + }); + this.searchable.wrap.select('.search').append('span').classed('nNrecords', true); } function searchable() { - return { - layout: layout$2 - }; + 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()); - }); + 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) { - //transform blob array into a blob of characters - var blob = new Blob(data, { - type: - fileType === 'csv' - ? 'text/csv;charset=utf-8;' - : fileType === 'xlsx' - ? 'application/octet-stream' - : console.warn('File type not supported: '.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) - //IE - navigator.msSaveBlob(blob, fileName); - else if (link.node().download !== undefined) { - //21st century browsers - var url = URL.createObjectURL(blob); - link.node().setAttribute('href', url); - link.node().setAttribute('download', fileName); - } + //transform blob array into a blob of characters + var blob = new Blob(data, { + type: fileType === 'csv' ? 'text/csv;charset=utf-8;' : fileType === 'xlsx' ? 'application/octet-stream' : console.warn("File type not supported: ".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) //IE + navigator.msSaveBlob(blob, fileName);else if (link.node().download !== undefined) { + //21st century browsers + var url = URL.createObjectURL(blob); + link.node().setAttribute('href', url); + link.node().setAttribute('download', fileName); + } } function csv(data) { - var _this = this; + var _this = this; - this.wrap.select('.export#csv').on('click', function() { - var CSVarray = []; //add headers to CSV array + this.wrap.select('.export#csv').on('click', function () { + var CSVarray = []; //add headers to CSV array - var headers = _this.config.headers.map(function(header) { - return '"'.concat(header.replace(/"/g, '""'), '"'); - }); + var headers = _this.config.headers.map(function (header) { + return "\"".concat(header.replace(/"/g, '""'), "\""); + }); - CSVarray.push(headers); //add rows to CSV array + CSVarray.push(headers); //add rows to CSV array - 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, '"'); - }); + 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 .csv file. + CSVarray.push(row); + }); //Download .csv file. - download.call(_this, 'csv', [CSVarray.join('\n')]); - }); + 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]; - }); - }); // convert data from array of objects to array of arrays. - - var workbook = { - SheetNames: [sheetName], - Sheets: {} - }; - var cols = []; //Convert headers and data from array of arrays to sheet. - - workbook.Sheets[sheetName] = XLSX.utils.aoa_to_sheet( - [_this.config.headers].concat(arrayOfArrays) - ); //Add filters to spreadsheet. - - workbook.Sheets[sheetName]['!autofilter'] = { - ref: 'A1:' - .concat(String.fromCharCode(64 + _this.config.cols.length)) - .concat(data.length + 1) - }; //Define column widths in spreadsheet. - - _this.table.selectAll('thead tr th').each(function() { - cols.push({ - wpx: this.offsetWidth - }); - }); + 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]; + }); + }); // convert data from array of objects to array of arrays. + + var workbook = { + SheetNames: [sheetName], + Sheets: {} + }; + var cols = []; //Convert headers and data from array of arrays to sheet. - workbook.Sheets[sheetName]['!cols'] = cols; - var xlsx = XLSX.write(workbook, options); + workbook.Sheets[sheetName] = XLSX.utils.aoa_to_sheet([_this.config.headers].concat(arrayOfArrays)); //Add filters to spreadsheet. - var s2ab = function s2ab(s) { - var buffer = new ArrayBuffer(s.length), - view = new Uint8Array(buffer); + workbook.Sheets[sheetName]['!autofilter'] = { + ref: "A1:".concat(String.fromCharCode(64 + _this.config.cols.length)).concat(data.length + 1) + }; //Define column widths in spreadsheet. - for (var i = 0; i !== s.length; ++i) { - view[i] = s.charCodeAt(i) & 0xff; - } + _this.table.selectAll('thead tr th').each(function () { + cols.push({ + wpx: this.offsetWidth + }); + }); - return buffer; - }; // convert spreadsheet to binary or something, i don't know - //Download .xlsx file. + workbook.Sheets[sheetName]['!cols'] = cols; + var xlsx = XLSX.write(workbook, options); - download.call(_this, 'xlsx', [s2ab(xlsx)]); - }); + 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) & 0xff; + } + + return buffer; + }; // convert spreadsheet to binary or something, i don't know + //Download .xlsx file. + + + download.call(_this, 'xlsx', [s2ab(xlsx)]); + }); } var exports$1 = { - csv: csv, - xlsx: xlsx + csv: csv, + xlsx: xlsx }; function exportable() { - return { - layout: layout$3, - exports: exports$1 - }; + 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.'); + + 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)]; //Check if column is already a part of current sort order. - - var sortItem = this.sortable.order.filter(function(item) { - return item.col === col; - })[0]; //If it isn't, add it to sort order. - - 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 { - //Otherwise reverse its sort direction. - sortItem.direction = sortItem.direction === 'ascending' ? 'descending' : 'ascending'; - sortItem.wrap - .select('span.sort-direction') - .html(sortItem.direction === 'ascending' ? '↓' : '↑'); - } //Hide sort instructions. - - this.sortable.wrap.select('.instruction').classed('hidden', true); //Add sort container deletion functionality. - - this.sortable.order.forEach(function(item, i) { - item.wrap.on('click', function(d) { - //Remove column's sort container. - d3.select(this).remove(); //Remove column from sort. - - context.sortable.order.splice( - context.sortable.order - .map(function(d) { - return d.col; - }) - .indexOf(d.key), - 1 - ); //Display sorting instruction. - - context.sortable.wrap - .select('.instruction') - .classed('hidden', context.sortable.order.length); //Redraw chart. - - context.draw(); - }); - }); //Redraw chart. + var context = this, + selection = d3.select(th), + col = this.config.cols[this.config.headers.indexOf(header)]; //Check if column is already a part of current sort order. + + var sortItem = this.sortable.order.filter(function (item) { + return item.col === col; + })[0]; //If it isn't, add it to sort order. + + 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 { + //Otherwise reverse its sort direction. + sortItem.direction = sortItem.direction === 'ascending' ? 'descending' : 'ascending'; + sortItem.wrap.select('span.sort-direction').html(sortItem.direction === 'ascending' ? '↓' : '↑'); + } //Hide sort instructions. + + + this.sortable.wrap.select('.instruction').classed('hidden', true); //Add sort container deletion functionality. + + this.sortable.order.forEach(function (item, i) { + item.wrap.on('click', function (d) { + //Remove column's sort container. + d3.select(this).remove(); //Remove column from sort. - this.draw(); + context.sortable.order.splice(context.sortable.order.map(function (d) { + return d.col; + }).indexOf(d.key), 1); //Display sorting instruction. + + context.sortable.wrap.select('.instruction').classed('hidden', context.sortable.order.length); //Redraw chart. + + context.draw(); + }); + }); //Redraw chart. + + 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; - }; - } + 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); + 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' && aCell < bCell) || - (item.direction === 'descending' && aCell > bCell) - ) - order = -1; - else if ( - (item.direction === 'ascending' && aCell > bCell) || - (item.direction === 'descending' && aCell < bCell) - ) - order = 1; - } - } - }); + 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]; - return order; + 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; + } + } }); + + return order; + }); } function sortable() { - return { - layout: layout$4, - onClick: onClick, - sortData: sortData, - order: [] - }; + return { + layout: layout$4, + onClick: onClick, + sortData: sortData, + order: [] + }; } function layout$5() { - this.pagination.wrap = this.wrap - .select('.table-bottom') - .append('div') - .classed('interactivity pagination-container', true) - .classed('hidden', !this.config.pagination); + this.pagination.wrap = this.wrap.select('.table-bottom').append('div').classed('interactivity pagination-container', true).classed('hidden', !this.config.pagination); } function updatePagination() { - var _this = this; + var _this = this; - //Reset pagination. - this.pagination.links.classed('active', false); //Set to active the selected page link. + //Reset pagination. + this.pagination.links.classed('active', false); //Set to active the selected page link. - var activePage = this.pagination.links - .filter(function(link) { - return +link.rel === +_this.config.activePage; - }) - .classed('active', true); //Define and draw selected page. + var activePage = this.pagination.links.filter(function (link) { + return +link.rel === +_this.config.activePage; + }).classed('active', true); //Define and draw selected page. - this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; - this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; //Redraw table. + this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; + this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; //Redraw table. - this.draw(); + this.draw(); } function addLinks() { - var _this = this; - - //Count rows. - this.pagination.wrap.selectAll('a,span').remove(); - - var _loop = function _loop(i) { - _this.pagination.wrap - .append('a') - .datum({ - rel: i - }) - .attr({ - rel: i - }) - .text(i + 1) - .classed('wc-button page-link', true) - .classed('active', function(d) { - return d.rel == _this.config.activePage; - }) - .classed('hidden', function() { - return _this.config.activePage < _this.config.nPageLinksDisplayed - ? i >= _this.config.nPageLinksDisplayed // first nPageLinksDisplayed pages - : _this.config.activePage >= - _this.config.nPages - _this.config.nPageLinksDisplayed - ? i < _this.config.nPages - _this.config.nPageLinksDisplayed // last nPageLinksDisplayed pages - : i < - _this.config.activePage - - (Math.ceil(_this.config.nPageLinksDisplayed / 2) - 1) || - _this.config.activePage + _this.config.nPageLinksDisplayed / 2 < i; // nPageLinksDisplayed < activePage or activePage < (nPages - nPageLinksDisplayed) - }); - }; + var _this = this; + + //Count rows. + this.pagination.wrap.selectAll('a,span').remove(); + + var _loop = function _loop(i) { + _this.pagination.wrap.append('a').datum({ + rel: i + }).attr({ + rel: i + }).text(i + 1).classed('wc-button page-link', true).classed('active', function (d) { + return d.rel == _this.config.activePage; + }).classed('hidden', function () { + return _this.config.activePage < _this.config.nPageLinksDisplayed ? i >= _this.config.nPageLinksDisplayed // first nPageLinksDisplayed pages + : _this.config.activePage >= _this.config.nPages - _this.config.nPageLinksDisplayed ? i < _this.config.nPages - _this.config.nPageLinksDisplayed // last nPageLinksDisplayed pages + : i < _this.config.activePage - (Math.ceil(_this.config.nPageLinksDisplayed / 2) - 1) || _this.config.activePage + _this.config.nPageLinksDisplayed / 2 < i; // nPageLinksDisplayed < activePage or activePage < (nPages - nPageLinksDisplayed) + }); + }; - for (var i = 0; i < this.config.nPages; i++) { - _loop(i); - } + for (var i = 0; i < this.config.nPages; i++) { + _loop(i); + } - this.pagination.links = this.pagination.wrap.selectAll('a.page-link'); + this.pagination.links = this.pagination.wrap.selectAll('a.page-link'); } function addArrows() { - var prev = this.config.activePage - 1, - next = this.config.activePage + 1; - if (prev < 0) prev = 0; // nothing before the first page + var prev = this.config.activePage - 1, + next = this.config.activePage + 1; + if (prev < 0) prev = 0; // nothing before the first page - if (next >= this.config.nPages) next = this.config.nPages - 1; // nothing after the last page + if (next >= this.config.nPages) next = this.config.nPages - 1; // nothing after the last page - /**-------------------------------------------------------------------------------------------\ + /**-------------------------------------------------------------------------------------------\ Left side \-------------------------------------------------------------------------------------------**/ - this.pagination.wrap - .insert('span', ':first-child') - .classed('dot-dot-dot', true) - .text('...') - .classed('hidden', this.config.activePage < this.config.nPageLinksDisplayed); - this.pagination.prev = this.pagination.wrap - .insert('a', ':first-child') - .classed('wc-button arrow-link wc-left', true) - .classed('hidden', this.config.activePage == 0) - .attr({ - rel: prev - }) - .text('<'); - this.pagination.doublePrev = this.pagination.wrap - .insert('a', ':first-child') - .classed('wc-button arrow-link wc-left double', true) - .classed('hidden', this.config.activePage == 0) - .attr({ - rel: 0 - }) - .text('<<'); - /**-------------------------------------------------------------------------------------------\ + this.pagination.wrap.insert('span', ':first-child').classed('dot-dot-dot', true).text('...').classed('hidden', this.config.activePage < this.config.nPageLinksDisplayed); + this.pagination.prev = this.pagination.wrap.insert('a', ':first-child').classed('wc-button arrow-link wc-left', true).classed('hidden', this.config.activePage == 0).attr({ + rel: prev + }).text('<'); + this.pagination.doublePrev = this.pagination.wrap.insert('a', ':first-child').classed('wc-button arrow-link wc-left double', true).classed('hidden', this.config.activePage == 0).attr({ + rel: 0 + }).text('<<'); + /**-------------------------------------------------------------------------------------------\ Right side \-------------------------------------------------------------------------------------------**/ - this.pagination.wrap - .append('span') - .classed('dot-dot-dot', true) - .text('...') - .classed( - 'hidden', - this.config.activePage >= - Math.max( - this.config.nPageLinksDisplayed, - this.config.nPages - this.config.nPageLinksDisplayed - ) || this.config.nPages <= this.config.nPageLinksDisplayed - ); - this.pagination.next = this.pagination.wrap - .append('a') - .classed('wc-button arrow-link wc-right', true) - .classed( - 'hidden', - this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0 - ) - .attr({ - rel: next - }) - .text('>'); - this.pagination.doubleNext = this.pagination.wrap - .append('a') - .classed('wc-button arrow-link wc-right double', true) - .classed( - 'hidden', - this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0 - ) - .attr({ - rel: this.config.nPages - 1 - }) - .text('>>'); - this.pagination.arrows = this.pagination.wrap.selectAll('a.arrow-link'); - this.pagination.doubleArrows = this.pagination.wrap.selectAll('a.double-arrow-link'); + this.pagination.wrap.append('span').classed('dot-dot-dot', true).text('...').classed('hidden', this.config.activePage >= Math.max(this.config.nPageLinksDisplayed, this.config.nPages - this.config.nPageLinksDisplayed) || this.config.nPages <= this.config.nPageLinksDisplayed); + this.pagination.next = this.pagination.wrap.append('a').classed('wc-button arrow-link wc-right', true).classed('hidden', this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0).attr({ + rel: next + }).text('>'); + this.pagination.doubleNext = this.pagination.wrap.append('a').classed('wc-button arrow-link wc-right double', true).classed('hidden', this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0).attr({ + rel: this.config.nPages - 1 + }).text('>>'); + this.pagination.arrows = this.pagination.wrap.selectAll('a.arrow-link'); + this.pagination.doubleArrows = this.pagination.wrap.selectAll('a.double-arrow-link'); } function addPagination(data) { - var context = this; //Calculate number of pages needed and create a link for each page. - - this.config.nRows = data.length; - this.config.nPages = Math.ceil(this.config.nRows / this.config.nRowsPerPage); //hide the pagination if there is only one page - - this.config.paginationHidden = this.config.nPages === 1; - this.pagination.wrap.classed('hidden', this.config.paginationHidden); //Render page links. - - addLinks.call(this); //Render a different page on click. - - this.pagination.links.on('click', function() { - context.config.activePage = +d3.select(this).attr('rel'); - updatePagination.call(context); - }); //Render arrow links. - - addArrows.call(this); //Render a different page on click. - - this.pagination.arrows.on('click', function() { - if (context.config.activePage !== +d3.select(this).attr('rel')) { - context.config.activePage = +d3.select(this).attr('rel'); - context.pagination.prev.attr( - 'rel', - context.config.activePage > 0 ? context.config.activePage - 1 : 0 - ); - context.pagination.next.attr( - 'rel', - context.config.activePage < context.config.nPages - ? context.config.activePage + 1 - : context.config.nPages - 1 - ); - updatePagination.call(context); - } - }); //Render a different page on click. + var context = this; //Calculate number of pages needed and create a link for each page. - this.pagination.doubleArrows.on('click', function() { - context.config.activePage = +d3.select(this).attr('rel'); - updatePagination.call(context); - }); - return { - addLinks: addLinks, - addArrows: addArrows, - updatePagination: updatePagination - }; + this.config.nRows = data.length; + this.config.nPages = Math.ceil(this.config.nRows / this.config.nRowsPerPage); //hide the pagination if there is only one page + + this.config.paginationHidden = this.config.nPages === 1; + this.pagination.wrap.classed('hidden', this.config.paginationHidden); //Render page links. + + addLinks.call(this); //Render a different page on click. + + this.pagination.links.on('click', function () { + context.config.activePage = +d3.select(this).attr('rel'); + updatePagination.call(context); + }); //Render arrow links. + + addArrows.call(this); //Render a different page on click. + + this.pagination.arrows.on('click', function () { + if (context.config.activePage !== +d3.select(this).attr('rel')) { + context.config.activePage = +d3.select(this).attr('rel'); + context.pagination.prev.attr('rel', context.config.activePage > 0 ? context.config.activePage - 1 : 0); + context.pagination.next.attr('rel', context.config.activePage < context.config.nPages ? context.config.activePage + 1 : context.config.nPages - 1); + updatePagination.call(context); + } + }); //Render a different page on click. + + this.pagination.doubleArrows.on('click', function () { + context.config.activePage = +d3.select(this).attr('rel'); + updatePagination.call(context); + }); + return { + addLinks: addLinks, + addArrows: addArrows, + updatePagination: updatePagination + }; } function pagination() { - this.config.nRows = this.data.raw.length; // total number of rows, i.e. the length of the data file + this.config.nRows = this.data.raw.length; // total number of rows, i.e. the length of the data file - this.config.nPages = Math.ceil(this.config.nRows / this.config.nRowsPerPage); // total number of pages given number of rows + this.config.nPages = Math.ceil(this.config.nRows / this.config.nRowsPerPage); // total number of pages given number of rows - this.config.activePage = 0; // current page, 0-indexed + this.config.activePage = 0; // current page, 0-indexed - this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; // first row shown + this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; // first row shown - this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown + this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown - this.config.paginationHidden = this.config.nPages == 1; - return { - layout: layout$5, - addPagination: addPagination - }; + this.config.paginationHidden = this.config.nPages == 1; + return { + layout: layout$5, + addPagination: addPagination + }; } function init$2(data) { - var _this = this; + var _this = this; - var test = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - this.test = test; + 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); - }); - } //Define default settings. + 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); + }); + } //Define default settings. - this.setDefaults.call(this, data[0]); //Assign classes to container element. - this.wrap.classed('wc-chart', true).classed('wc-table', this.config.applyCSS); //Define data object. + this.setDefaults.call(this, data[0]); //Assign classes to container element. - this.data = { - raw: data - }; //Attach searchable object to table object. + this.wrap.classed('wc-chart', true).classed('wc-table', this.config.applyCSS); //Define data object. - this.searchable = searchable.call(this); //Attach sortable object to table object. + this.data = { + raw: data + }; //Attach searchable object to table object. - this.sortable = sortable.call(this); //Attach pagination object to table object. + this.searchable = searchable.call(this); //Attach sortable object to table object. - this.pagination = pagination.call(this); //Attach pagination object to table object. + this.sortable = sortable.call(this); //Attach pagination object to table object. - this.exportable = exportable.call(this); + this.pagination = pagination.call(this); //Attach pagination object to table object. - var startup = function startup(data) { - //connect this table and its controls, if any - if (_this.controls) { - _this.controls.targets.push(_this); + this.exportable = exportable.call(this); - if (!_this.controls.ready) { - _this.controls.init(_this.data.raw); - } else { - _this.controls.layout(); - } - } //make sure container is visible (has height and width) before trying to initialize + var startup = function startup(data) { + //connect this table and its controls, if any + if (_this.controls) { + _this.controls.targets.push(_this); - var visible = d3.select(_this.div).property('offsetWidth') > 0 || test; + if (!_this.controls.ready) { + _this.controls.init(_this.data.raw); + } else { + _this.controls.layout(); + } + } //make sure container is visible (has height and width) before trying to initialize - 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(); + var visible = d3.select(_this.div).property('offsetWidth') > 0 || test; - _this.wrap.datum(_this); + 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; - _this.draw(); + if (visible_now) { + _this.layout(); - clearInterval(onVisible); - } - }, 500); - } else { - _this.layout(); + _this.wrap.datum(_this); - _this.wrap.datum(_this); + _this.draw(); - _this.draw(); + clearInterval(onVisible); } - }; + }, 500); + } else { + _this.layout(); - this.events.onInit.call(this); + _this.wrap.datum(_this); - if (this.data.raw.length) { - this.checkRequired(this.data.raw); + _this.draw(); } + }; + + this.events.onInit.call(this); + + if (this.data.raw.length) { + this.checkRequired(this.data.raw); + } - startup(); - return this; + startup(); + return this; } function layout$6() { - //Clear loading indicator. - d3.select(this.div) - .select('.loader') - .remove(); //Attach container before table. + //Clear loading indicator. + d3.select(this.div).select('.loader').remove(); //Attach container before table. - this.wrap.append('div').classed('table-top', true); //Attach search container. + this.wrap.append('div').classed('table-top', true); //Attach search container. - this.searchable.layout.call(this); //Attach sort container. + this.searchable.layout.call(this); //Attach sort container. - this.sortable.layout.call(this); //Attach table to DOM. + this.sortable.layout.call(this); //Attach table to DOM. - this.table = this.wrap.append('table').classed('table', this.config.bootstrap); // apply class to incorporate bootstrap styling + this.table = this.wrap.append('table').classed('table', this.config.bootstrap); // apply class to incorporate bootstrap styling - this.thead = this.table.append('thead'); - this.thead.append('tr'); - this.tbody = this.table.append('tbody'); //Attach container after table. + this.thead = this.table.append('thead'); + this.thead.append('tr'); + this.tbody = this.table.append('tbody'); //Attach container after table. - this.wrap.append('div').classed('table-bottom', true); //Attach pagination container. + this.wrap.append('div').classed('table-bottom', true); //Attach pagination container. - this.pagination.layout.call(this); //Attach data export container. + this.pagination.layout.call(this); //Attach data export container. - this.exportable.layout.call(this); //Call layout callback. + this.exportable.layout.call(this); //Call layout callback. - this.events.onLayout.call(this); + this.events.onLayout.call(this); } function destroy$2() { - var destroyControls = - arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - //run onDestroy callback - this.events.onDestroy.call(this); //destroy controls + var destroyControls = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + //run onDestroy callback + this.events.onDestroy.call(this); //destroy controls - if (destroyControls && this.controls) { - this.controls.destroy(); - } //unmount chart wrapper + if (destroyControls && this.controls) { + this.controls.destroy(); + } //unmount chart wrapper - this.wrap.remove(); + + this.wrap.remove(); } function setDefault(setting) { - var _default_ = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var _default_ = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - this.config[setting] = - this.config[setting] !== undefined ? this.config[setting] : _default_; + this.config[setting] = this.config[setting] !== undefined ? this.config[setting] : _default_; } function setDefaults$1(firstItem) { - var _this = this; - - // 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, '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'); + var _this = this; + + // 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, '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; + var _this = this; - //Transform data. - this.data.processed = this.transformData(this.wrap.datum); + //Transform data. + this.data.processed = this.transformData(this.wrap.datum); - if (!data) { - return; - } + if (!data) { + return; + } - this.config.cols = this.config.cols || d3.keys(data[0]); - this.config.headers = this.config.headers || this.config.cols; + 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); - } - }); + 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 = []; - 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; - } - }); + for (var x in m) { + arr.push({ + col: x, + text: m[x] }); - } + } - var slimmed = d3 - .nest() - .key(function(d) { - if (_this.config.row_per) { - return _this.config.row_per - .map(function(m) { - return d[m]; - }) - .join(' '); - } else { - return d; - } - }) - .rollup(function(r) { - if (_this.config.dataManipulate) { - r = _this.config.dataManipulate(r); - } - - 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: [] - } - ]; // dummy nested data array - //Reset pagination. - - this.pagination.wrap.selectAll('*').remove(); - this.events.onDatatransform.call(this); - /**-------------------------------------------------------------------------------------------\ + 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: [] + }]; // dummy nested data array + //Reset pagination. + + this.pagination.wrap.selectAll('*').remove(); + this.events.onDatatransform.call(this); + /**-------------------------------------------------------------------------------------------\ Code below associated with the former paradigm of a d3.nest() data array. \-------------------------------------------------------------------------------------------**/ - 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]; - }); - }); - } //Delete text from columns with repeated values? - - if (config.row_per) { - rows.filter(function(f, i) { - return i > 0; - }) - .selectAll('td') - .filter(function(f) { - return config.row_per.indexOf(f.col) > -1; - }) - .text(''); - } + 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]; + }); + }); + } //Delete text from columns with repeated values? + - return this.data.current; + 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 - } + 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() {} - }; + 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']; + thisTable.on = function (event, callback) { + var possible_events = ['init', 'layout', 'preprocess', 'draw', 'destroy']; - if (possible_events.indexOf(event) < 0) { - return; - } + if (possible_events.indexOf(event) < 0) { + return; + } - if (callback) { - thisTable.events['on' + event.charAt(0).toUpperCase() + event.slice(1)] = callback; - } - }; //increment thisChart count to get unique thisChart id + 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; + + 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); //Define container for legend that overrides multiples' legends. - - chart.master_legend = chart.wrap.append('ul').attr('class', 'legend'); - chart.master_legend.append('span').classed('legend-title', true); //Instantiate multiples array. - - 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)); - }); - } + var test = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; + chart.wrap.classed('wc-layout wc-small-multiples', true).classed('wc-chart', false); //Define container for legend that overrides multiples' legends. - 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); - }); - } + chart.master_legend = chart.wrap.append('ul').attr('class', 'legend'); + chart.master_legend.append('span').classed('legend-title', true); //Instantiate multiples array. + + chart.multiples = []; + + function goAhead(data) { + var split_vals = d3.set(data.map(function (m) { + return m[split_by]; + })).values().filter(function (f) { + return f; + }); - goAhead(data); + 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; - }); + 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'; - } + 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); - }); + 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; + }); + return my_data; } var dataOps = { - getValType: getValType, - lengthenRaw: lengthenRaw, - naturalSorter: naturalSorter, - summarize: summarize + getValType: getValType, + lengthenRaw: lengthenRaw, + naturalSorter: naturalSorter, + summarize: summarize }; var index = { - version: version, - createChart: createChart, - createControls: createControls, - createTable: createTable, - multiply: multiply, - dataOps: dataOps + version: version, + createChart: createChart, + createControls: createControls, + createTable: createTable, + multiply: multiply, + dataOps: dataOps }; return index; -}); + +}))); diff --git a/test-page/groupedBarChart/index.css b/test-page/groupedBarChart/index.css new file mode 100644 index 0000000..d075f13 --- /dev/null +++ b/test-page/groupedBarChart/index.css @@ -0,0 +1,7 @@ +#container { + display: flex; + justify-content: space-between; +} +.bar-chart { + width: 50%; +} diff --git a/test-page/groupedBarChart/index.html b/test-page/groupedBarChart/index.html new file mode 100644 index 0000000..56bfa60 --- /dev/null +++ b/test-page/groupedBarChart/index.html @@ -0,0 +1,26 @@ + + + + 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..8c7b58c --- /dev/null +++ b/test-page/groupedBarChart/index.js @@ -0,0 +1,62 @@ +const settings = { + 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: 'grouped', + }, + ], + color_by: 'AESEV', + legend: { + label: 'Severity', + order: null, + }, + resizable: false, + aspect: 2, +}; + +hSettings = JSON.parse(JSON.stringify(settings)); +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)); +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.init(data); + vChart.init(data); + } +); diff --git a/test-page/nestedBarChart/index.css b/test-page/nestedBarChart/index.css new file mode 100644 index 0000000..d075f13 --- /dev/null +++ b/test-page/nestedBarChart/index.css @@ -0,0 +1,7 @@ +#container { + display: flex; + justify-content: space-between; +} +.bar-chart { + width: 50%; +} diff --git a/test-page/nestedBarChart/index.html b/test-page/nestedBarChart/index.html new file mode 100644 index 0000000..56bfa60 --- /dev/null +++ b/test-page/nestedBarChart/index.html @@ -0,0 +1,26 @@ + + + + Webcharts - Grouped Bar Chart + + + + + + + + + + + + +
Webcharts
+
Grouped Bar Chart
+
+
+
+
+ + + + diff --git a/test-page/nestedBarChart/index.js b/test-page/nestedBarChart/index.js new file mode 100644 index 0000000..8c7b58c --- /dev/null +++ b/test-page/nestedBarChart/index.js @@ -0,0 +1,62 @@ +const settings = { + 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: 'grouped', + }, + ], + color_by: 'AESEV', + legend: { + label: 'Severity', + order: null, + }, + resizable: false, + aspect: 2, +}; + +hSettings = JSON.parse(JSON.stringify(settings)); +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)); +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.init(data); + vChart.init(data); + } +); diff --git a/test-page/stackedBarChart/index.css b/test-page/stackedBarChart/index.css new file mode 100644 index 0000000..d075f13 --- /dev/null +++ b/test-page/stackedBarChart/index.css @@ -0,0 +1,7 @@ +#container { + display: flex; + justify-content: space-between; +} +.bar-chart { + width: 50%; +} diff --git a/test-page/stackedBarChart/index.html b/test-page/stackedBarChart/index.html new file mode 100644 index 0000000..56bfa60 --- /dev/null +++ b/test-page/stackedBarChart/index.html @@ -0,0 +1,26 @@ + + + + Webcharts - Grouped Bar Chart + + + + + + + + + + + + +
Webcharts
+
Grouped Bar Chart
+
+
+
+
+ + + + diff --git a/test-page/stackedBarChart/index.js b/test-page/stackedBarChart/index.js new file mode 100644 index 0000000..8c7b58c --- /dev/null +++ b/test-page/stackedBarChart/index.js @@ -0,0 +1,62 @@ +const settings = { + 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: 'grouped', + }, + ], + color_by: 'AESEV', + legend: { + label: 'Severity', + order: null, + }, + resizable: false, + aspect: 2, +}; + +hSettings = JSON.parse(JSON.stringify(settings)); +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)); +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.init(data); + vChart.init(data); + } +); From 607f8554cbb7ef138e23ad7bd03dd178a63d0d36 Mon Sep 17 00:00:00 2001 From: Spencer Date: Fri, 13 Dec 2019 12:47:19 -0500 Subject: [PATCH 04/14] fix #159; fix #207 --- build/webcharts.js | 6947 ++++++++++------- build/webcharts.min.js | 6 +- .../consolidateData/transformData/makeNest.js | 30 +- src/chart/resize/updateDataMarks/drawBars.js | 390 +- .../resize/updateDataMarks/drawBars/xBin.js | 84 + .../updateDataMarks/drawBars/xOrdinal.js | 115 + .../resize/updateDataMarks/drawBars/yBin.js | 82 + .../updateDataMarks/drawBars/yOrdinal.js | 116 + 8 files changed, 4609 insertions(+), 3161 deletions(-) create mode 100644 src/chart/resize/updateDataMarks/drawBars/xBin.js create mode 100644 src/chart/resize/updateDataMarks/drawBars/xOrdinal.js create mode 100644 src/chart/resize/updateDataMarks/drawBars/yBin.js create mode 100644 src/chart/resize/updateDataMarks/drawBars/yOrdinal.js diff --git a/build/webcharts.js b/build/webcharts.js index c80fe8c..09b8600 100644 --- a/build/webcharts.js +++ b/build/webcharts.js @@ -1,671 +1,989 @@ -(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'; +(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); - }); - } + 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; + this.wrap.attr('class', 'wc-chart'); + this.setDefaults(); + this.raw_data = data; + this.initial_data = data; - var startup = function startup(data) { - //connect this chart and its controls, if any - if (_this.controls) { - _this.controls.targets.push(_this); + var startup = function startup(data) { + //connect this chart and its controls, if any + if (_this.controls) { + _this.controls.targets.push(_this); - if (!_this.controls.ready) { - _this.controls.init(_this.raw_data); - } else { - _this.controls.layout(); - } - } //make sure container is visible (has height and width) before trying to initialize + if (!_this.controls.ready) { + _this.controls.init(_this.raw_data); + } else { + _this.controls.layout(); + } + } //make sure container is visible (has height and width) before trying to initialize + var visible = d3.select(_this.div).property('offsetWidth') > 0 || test; - 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) { - 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(); - if (visible_now) { - _this.layout(); + _this.draw(); - _this.draw(); + clearInterval(onVisible); + } + }, 500); + } else { + _this.layout(); - clearInterval(onVisible); + _this.draw(); } - }, 500); - } else { - _this.layout(); - - _this.draw(); - } - }; + }; - this.events.onInit.call(this); + this.events.onInit.call(this); - if (this.raw_data.length) { - this.checkRequired(this.raw_data); - } + if (this.raw_data.length) { + this.checkRequired(this.raw_data); + } - startup(); - return this; + 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); - } + var _this = this; - if (this.config.y && this.config.y.column) { - requiredVars.push('this.config.y.column'); - requiredCols.push(this.config.y.column); - } + var colnames = Object.keys(data[0]); + var requiredVars = []; + var requiredCols = []; - 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 (this.config.x && this.config.x.column) { + requiredVars.push('this.config.x.column'); + requiredCols.push(this.config.x.column); } - if (e.split) { - requiredVars.push('this.config.marks[' + i + '].split'); - requiredCols.push(e.split); + if (this.config.y && this.config.y.column) { + requiredVars.push('this.config.y.column'); + requiredCols.push(this.config.y.column); } - if (e.values) { - for (var value in e.values) { - requiredVars.push('this.config.marks[' + i + "].values['" + value + "']"); - requiredCols.push(value); - } + if (this.config.color_by) { + requiredVars.push('this.config.color_by'); + requiredCols.push(this.config.color_by); } - }); - 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 - }; + 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; - }) // prevent data inheritance - .attr({ - "class": 'wc-svg', - xmlns: 'http://www.w3.org/2000/svg', - version: '1.1', - xlink: 'http://www.w3.org/1999/xlink' - }).append('g').style('display', 'inline-block'); + this.svg = this.wrap + .append('svg') + .datum(function() { + return null; + }) // prevent data inheritance + .attr({ + class: 'wc-svg', + xmlns: 'http://www.w3.org/2000/svg', + version: '1.1', + xlink: 'http://www.w3.org/1999/xlink' + }) + .append('g') + .style('display', 'inline-block'); } function addDefs() { - var defs = this.svg.append('defs'); //Add pattern. - - defs.append('pattern').attr({ - id: 'diagonal-stripes', - x: 0, - y: 0, - width: 3, - height: 8, - patternUnits: 'userSpaceOnUse', - patternTransform: 'rotate(30)' - }).append('rect').attr({ - x: '0', - y: '0', - width: '2', - height: '8' - }).style({ - stroke: 'none', - fill: 'black' - }); //Add clipPath. - - defs.append('clipPath').attr('id', this.id).append('rect').attr('class', 'plotting-area'); + var defs = this.svg.append('defs'); //Add pattern. + + defs.append('pattern') + .attr({ + id: 'diagonal-stripes', + x: 0, + y: 0, + width: 3, + height: 8, + patternUnits: 'userSpaceOnUse', + patternTransform: 'rotate(30)' + }) + .append('rect') + .attr({ + x: '0', + y: '0', + width: '2', + height: '8' + }) + .style({ + stroke: 'none', + fill: 'black' + }); //Add clipPath. + + defs.append('clipPath') + .attr('id', this.id) + .append('rect') + .attr('class', 'plotting-area'); } function addXAxis() { - this.svg.append('g').attr('class', 'x axis').append('text').attr('class', 'axis-title').attr('dy', '-.35em').attr('text-anchor', 'middle'); + this.svg + .append('g') + .attr('class', 'x axis') + .append('text') + .attr('class', 'axis-title') + .attr('dy', '-.35em') + .attr('text-anchor', 'middle'); } function addYAxis() { - this.svg.append('g').attr('class', 'y axis').append('text').attr('class', 'axis-title').attr('transform', 'rotate(-90)').attr('dy', '.75em').attr('text-anchor', 'middle'); + this.svg + .append('g') + .attr('class', 'y axis') + .append('text') + .attr('class', 'axis-title') + .attr('transform', 'rotate(-90)') + .attr('dy', '.75em') + .attr('text-anchor', 'middle'); } function addOverlay() { - this.overlay = this.svg.append('rect').attr('class', 'overlay').attr('opacity', 0).attr('fill', 'none').style('pointer-events', 'all'); + this.overlay = this.svg + .append('rect') + .attr('class', 'overlay') + .attr('opacity', 0) + .attr('fill', 'none') + .style('pointer-events', 'all'); } function addLegend() { - //The legend is contained in the parent object of multiples so each multiple does not need its own legend. - if (!this.parent) this.wrap.append('ul').datum(function () { - return null; - }) // prevent data inheritance - .attr('class', 'legend').style('vertical-align', 'top').append('span').attr('class', 'legend-title'); + //The legend is contained in the parent object of multiples so each multiple does not need its own legend. + if (!this.parent) + this.wrap + .append('ul') + .datum(function() { + return null; + }) // prevent data inheritance + .attr('class', 'legend') + .style('vertical-align', 'top') + .append('span') + .attr('class', 'legend-title'); } function clearLoader() { - d3.select(this.div).select('.loader').remove(); + 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); + 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; //if pre-processing callback, run it now - - this.events.onPreprocess.call(this); ///////////////////////// - // Data prep pipeline // - ///////////////////////// - // if user passed raw_data to chart.draw(), use that, otherwise use chart.raw_data - - var raw = raw_data ? raw_data : this.raw_data ? this.raw_data : []; // warn the user about the perils of "processed_data" - - if (processed_data) { - console.warn("Drawing the chart using user-defined 'processed_data', this is an experimental, untested feature."); - } //Call consolidateData - this applies filters from controls and prepares data for each set of marks. - - - this.consolidateData(raw); ///////////////////////////// - // Prepare scales and axes // - ///////////////////////////// - - 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); - } + var _this = this; + + var chart = this; + var config = this.config; //if pre-processing callback, run it now + + this.events.onPreprocess.call(this); ///////////////////////// + // Data prep pipeline // + ///////////////////////// + // if user passed raw_data to chart.draw(), use that, otherwise use chart.raw_data + + var raw = raw_data ? raw_data : this.raw_data ? this.raw_data : []; // warn the user about the perils of "processed_data" + + if (processed_data) { + console.warn( + "Drawing the chart using user-defined 'processed_data', this is an experimental, untested feature." + ); + } //Call consolidateData - this applies filters from controls and prepares data for each set of marks. + + this.consolidateData(raw); ///////////////////////////// + // Prepare scales and axes // + ///////////////////////////// + + 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); ////////////////////////////////////////////////////////////////////// - // Call resize - updates marks on the chart (amongst other things) // - ///////////////////////////////////////////////////////////////////// + this.events.onDraw.call(this); ////////////////////////////////////////////////////////////////////// + // Call resize - updates marks on the chart (amongst other things) // + ///////////////////////////////////////////////////////////////////// - this.resize(); + this.resize(); } function naturalSorter(a, b) { - //adapted from http://www.davekoelle.com/files/alphanum.js - 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; - } + //adapted from http://www.davekoelle.com/files/alphanum.js + 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; + } - tz[y] += j; + return tz; } - return tz; - } - - var aa = chunkify(a.toLowerCase()); - var bb = chunkify(b.toLowerCase()); + 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]); + 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; - } + if (c == aa[x] && d == bb[x]) { + return c - d; + } else { + return aa[x] > bb[x] ? 1 : -1; + } + } } - } - return aa.length - bb.length; + return aa.length - bb.length; } function setDomain(axis) { - var _this = this; - - var otherAxis = axis === 'x' ? 'y' : 'x'; - - if (this.config[axis].type === 'ordinal') { - //ordinal domains - if (this.config[axis].domain) { - //user-defined domain - this[axis + '_dom'] = this.config[axis].domain; - } else if (this.config[axis].order) { - //data-driven domain with user-defined domain order - this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { - return mark[axis + '_dom']; - }))).values().sort(function (a, b) { - return d3.ascending(_this.config[axis].order.indexOf(a), _this.config[axis].order.indexOf(b)); - }); - } else if (this.config[axis].sort && this.config[axis].sort === 'alphabetical-ascending') { - //data-driven domain with user-defined domain sort algorithm that sorts the axis - //alphanumerically, first to last - this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { - return mark[axis + '_dom']; - }))).values().sort(naturalSorter); - } else if (['time', 'linear'].indexOf(this.config[otherAxis].type) > -1 && this.config[axis].sort === 'earliest') { - //data-driven domain plotted against a time or linear axis that sorts the axis values - //by earliest event/datum; generally used with timeline charts - this[axis + '_dom'] = d3.nest().key(function (d) { - return d[_this.config[axis].column]; - }).rollup(function (d) { - return d.map(function (m) { - return m[_this.config[otherAxis].column]; - }).filter(function (f) { - return f instanceof Date; - }); - }).entries(this.filtered_data).sort(function (a, b) { - return d3.min(b.values) - d3.min(a.values); - }).map(function (m) { - return m.key; - }); - } else if (!this.config[axis].sort || this.config[axis].sort === 'alphabetical-descending') { - //data-driven domain with default/user-defined domain sort algorithm that sorts the - //axis alphanumerically, last to first - this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { - return mark[axis + '_dom']; - }))).values().sort(naturalSorter).reverse(); + var _this = this; + + var otherAxis = axis === 'x' ? 'y' : 'x'; + + if (this.config[axis].type === 'ordinal') { + //ordinal domains + if (this.config[axis].domain) { + //user-defined domain + this[axis + '_dom'] = this.config[axis].domain; + } else if (this.config[axis].order) { + //data-driven domain with user-defined domain order + this[axis + '_dom'] = d3 + .set( + d3.merge( + this.marks.map(function(mark) { + return mark[axis + '_dom']; + }) + ) + ) + .values() + .sort(function(a, b) { + return d3.ascending( + _this.config[axis].order.indexOf(a), + _this.config[axis].order.indexOf(b) + ); + }); + } else if ( + this.config[axis].sort && + this.config[axis].sort === 'alphabetical-ascending' + ) { + //data-driven domain with user-defined domain sort algorithm that sorts the axis + //alphanumerically, first to last + this[axis + '_dom'] = d3 + .set( + d3.merge( + this.marks.map(function(mark) { + return mark[axis + '_dom']; + }) + ) + ) + .values() + .sort(naturalSorter); + } else if ( + ['time', 'linear'].indexOf(this.config[otherAxis].type) > -1 && + this.config[axis].sort === 'earliest' + ) { + //data-driven domain plotted against a time or linear axis that sorts the axis values + //by earliest event/datum; generally used with timeline charts + this[axis + '_dom'] = d3 + .nest() + .key(function(d) { + return d[_this.config[axis].column]; + }) + .rollup(function(d) { + return d + .map(function(m) { + return m[_this.config[otherAxis].column]; + }) + .filter(function(f) { + return f instanceof Date; + }); + }) + .entries(this.filtered_data) + .sort(function(a, b) { + return d3.min(b.values) - d3.min(a.values); + }) + .map(function(m) { + return m.key; + }); + } else if ( + !this.config[axis].sort || + this.config[axis].sort === 'alphabetical-descending' + ) { + //data-driven domain with default/user-defined domain sort algorithm that sorts the + //axis alphanumerically, last to first + this[axis + '_dom'] = d3 + .set( + d3.merge( + this.marks.map(function(mark) { + return mark[axis + '_dom']; + }) + ) + ) + .values() + .sort(naturalSorter) + .reverse(); + } else { + //data-driven domain with an invalid user-defined sort algorithm that captures a unique + //set of values as they appear in the data + this[axis + '_dom'] = d3 + .set( + d3.merge( + this.marks.map(function(mark) { + return mark[axis + '_dom']; + }) + ) + ) + .values(); + } + } else if ( + this.config.marks + .map(function(m) { + return m['summarize' + axis.toUpperCase()] === 'percent'; + }) + .indexOf(true) > -1 + ) { + //rate domains run from 0 to 1 + this[axis + '_dom'] = [0, 1]; } else { - //data-driven domain with an invalid user-defined sort algorithm that captures a unique - //set of values as they appear in the data - this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { - return mark[axis + '_dom']; - }))).values(); - } - } else if (this.config.marks.map(function (m) { - return m['summarize' + axis.toUpperCase()] === 'percent'; - }).indexOf(true) > -1) { - //rate domains run from 0 to 1 - this[axis + '_dom'] = [0, 1]; - } else { - //continuous domains run from the minimum to the maximum raw (or is it summarized...?) value - //TODO: they should really run from the minimum to the maximum summarized value, e.g. a - //TODO: means over time chart should plot over the range of the means, not the range of the - //TODO: raw data - this[axis + '_dom'] = d3.extent(d3.merge(this.marks.map(function (mark) { - return mark[axis + '_dom']; - }))); - } //Give the domain a range when the range of the variable is 0. - - - if (this.config[axis].type === 'linear' && this[axis + '_dom'][0] === this[axis + '_dom'][1]) this[axis + '_dom'] = this[axis + '_dom'][0] !== 0 ? [this[axis + '_dom'][0] - this[axis + '_dom'][0] * 0.01, this[axis + '_dom'][1] + this[axis + '_dom'][1] * 0.01] : [-1, 1]; - return this[axis + '_dom']; + //continuous domains run from the minimum to the maximum raw (or is it summarized...?) value + //TODO: they should really run from the minimum to the maximum summarized value, e.g. a + //TODO: means over time chart should plot over the range of the means, not the range of the + //TODO: raw data + this[axis + '_dom'] = d3.extent( + d3.merge( + this.marks.map(function(mark) { + return mark[axis + '_dom']; + }) + ) + ); + } //Give the domain a range when the range of the variable is 0. + + if ( + this.config[axis].type === 'linear' && + this[axis + '_dom'][0] === this[axis + '_dom'][1] + ) + this[axis + '_dom'] = + this[axis + '_dom'][0] !== 0 + ? [ + this[axis + '_dom'][0] - this[axis + '_dom'][0] * 0.01, + this[axis + '_dom'][1] + this[axis + '_dom'][1] * 0.01 + ] + : [-1, 1]; + return this[axis + '_dom']; } function consolidateData(raw) { - var _this = this; - - this.setDefaults(); //Apply filters from associated controls objects to raw data. + var _this = this; - 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; - }); - }); - } //Summarize data for each mark. + this.setDefaults(); //Apply filters from associated controls objects to raw data. + this.filtered_data = raw; - this.config.marks.forEach(function (mark, i) { - if (mark.type !== 'bar') { - mark.arrange = null; - mark.split = null; - } + 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; + }); + }); + } //Summarize data for each mark. - var mark_info = mark.per ? _this.transformData(raw, mark) : { - data: [], - x_dom: [], - y_dom: [] - }; - _this.marks[i] = Object.assign({}, mark, mark_info); - }); //Set domains given extents of summarized mark data. + this.config.marks.forEach(function(mark, i) { + if (mark.type !== 'bar') { + mark.arrange = null; + mark.split = null; + } - setDomain.call(this, 'x'); - setDomain.call(this, 'y'); + var mark_info = mark.per + ? _this.transformData(raw, mark) + : { + data: [], + x_dom: [], + y_dom: [] + }; + _this.marks[i] = Object.assign({}, mark, mark_info); + }); //Set domains given extents of summarized mark data. + + 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 : 0.3; - this.config.outer_pad = this.config.outer_pad !== undefined ? this.config.outer_pad : 0.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; + 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 : 0.3; + this.config.outer_pad = this.config.outer_pad !== undefined ? this.config.outer_pad : 0.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; // only use data for the current mark + var _this = this; - clean = mark.per && mark.per.length ? clean.filter(function (f) { - return f[mark.per[0]] !== undefined; - }) : clean; // Make sure data has x and y values + var dateConvert = d3.time.format(this.config.date_format); + var clean = raw; // only use data for the current mark - if (this.config.x.column) { - clean = clean.filter(function (f) { - return [undefined, null].indexOf(f[_this.config.x.column]) < 0; - }); - } + clean = + mark.per && mark.per.length + ? clean.filter(function(f) { + return f[mark.per[0]] !== undefined; + }) + : clean; // Make sure data has x and y values - if (this.config.y.column) { - clean = clean.filter(function (f) { - return [undefined, null].indexOf(f[_this.config.y.column]) < 0; - }); - } //check that x and y have the correct formats + if (this.config.x.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; + }); + } //check that x and y have the correct formats - if (this.config.x.type === 'time') { - clean = clean.filter(function (f) { - return f[_this.config.x.column] instanceof Date ? f[_this.config.x.column] : dateConvert.parse(f[_this.config.x.column]); - }); - clean.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.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.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])) // is or coerces to a number and is not a string that coerces to 0 - : f; - }); - } + if ( + (this.config.x.type === 'linear' || this.config.x.type === 'log') && + this.config.x.column + ) { + clean = clean.filter(function(f) { + return mark.summarizeX !== 'count' && mark.summarizeX !== 'percent' + ? !(isNaN(f[_this.config.x.column]) || /^\s*$/.test(f[_this.config.x.column])) // is or coerces to a number and is not a string that coerces to 0 + : f; + }); + } - if ((this.config.y.type === 'linear' || this.config.y.type === 'log') && this.config.y.column) { - clean = clean.filter(function (f) { - return mark.summarizeY !== 'count' && mark.summarizeY !== 'percent' ? !(isNaN(f[_this.config.y.column]) || /^\s*$/.test(f[_this.config.y.column])) // is or coerces to a number and is not a string that coerces to 0 - : f; - }); - } + if ( + (this.config.y.type === 'linear' || this.config.y.type === 'log') && + this.config.y.column + ) { + clean = clean.filter(function(f) { + return mark.summarizeY !== 'count' && mark.summarizeY !== 'percent' + ? !(isNaN(f[_this.config.y.column]) || /^\s*$/.test(f[_this.config.y.column])) // is or coerces to a number and is not a string that coerces to 0 + : f; + }); + } - return clean; + return clean; } var stats = { - mean: d3.mean, - min: d3.min, - max: d3.max, - median: d3.median, - sum: d3.sum + 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; - }); + 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; - } + if (operation === 'cumulative') { + return null; + } - var mathed = operation === 'count' ? vals.length : operation === 'percent' ? vals.length : stats[operation](nvals); - return mathed; + 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(' '); - }); - } + 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); - }); - } + 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, 0.25) : obj.x; - obj.x_q75 = _this.config.error_bars && _this.config.y.type === 'ordinal' ? d3.quantile(x_vals, 0.75) : obj.x; - obj.y_q25 = _this.config.error_bars ? d3.quantile(y_vals, 0.25) : obj.y; - obj.y_q75 = _this.config.error_bars ? d3.quantile(y_vals, 0.75) : obj.y; - dom_xs.push([obj.x_q25, obj.x_q75, obj.x]); - dom_ys.push([obj.y_q25, obj.y_q75, obj.y]); - - if (mark.summarizeY === 'cumulative') { - var interm = entries.filter(function (f) { - return _this.config.x.type === 'time' ? new Date(f[_this.config.x.column]) <= new Date(r[0][_this.config.x.column]) : +f[_this.config.x.column] <= +r[0][_this.config.x.column]; - }); - - 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) { - //calculate percentages in bars - test.forEach(function (e) { - var axis = _this.config.x.type === 'ordinal' || _this.config.x.type === 'linear' && _this.config.x.bin ? 'y' : 'x'; - e.total = d3.sum(e.values.map(function (m) { - return +m.values[axis]; - })); - 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; + this_nest.rollup(function(r) { + var obj = { + raw: r + }; + var y_vals = r + .map(function(m) { + return m[_this.config.y.column]; + }) + .sort(d3.ascending); + var x_vals = r + .map(function(m) { + return m[_this.config.x.column]; + }) + .sort(d3.ascending); + obj.x = + _this.config.x.type === 'ordinal' + ? r[0][_this.config.x.column] + : summarize(x_vals, mark.summarizeX); + obj.y = + _this.config.y.type === 'ordinal' + ? r[0][_this.config.y.column] + : summarize(y_vals, mark.summarizeY); + obj.x_q25 = + _this.config.error_bars && _this.config.y.type === 'ordinal' + ? d3.quantile(x_vals, 0.25) + : obj.x; + obj.x_q75 = + _this.config.error_bars && _this.config.y.type === 'ordinal' + ? d3.quantile(x_vals, 0.75) + : obj.x; + obj.y_q25 = _this.config.error_bars ? d3.quantile(y_vals, 0.25) : obj.y; + obj.y_q75 = _this.config.error_bars ? d3.quantile(y_vals, 0.75) : obj.y; + dom_xs.push([obj.x_q25, obj.x_q75, obj.x]); + dom_ys.push([obj.y_q25, obj.y_q75, obj.y]); + + if (mark.summarizeY === 'cumulative') { + var interm = entries.filter(function(f) { + return _this.config.x.type === 'time' + ? new Date(f[_this.config.x.column]) <= + new Date(r[0][_this.config.x.column]) + : +f[_this.config.x.column] <= +r[0][_this.config.x.column]; + }); + + 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.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 (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; + } - 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; + return obj; }); - } 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; - }); - } + 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) { + //calculate percentages in bars + test.forEach(function(e) { + var axis = + _this.config.x.type === 'ordinal' || + (_this.config.x.type === 'linear' && _this.config.x.bin) + ? 'y' + : 'x'; + e.total = d3.sum( + e.values.map(function(m) { + return +m.values[axis]; + }) + ); + 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 - }; + return { + nested: test, + dom_x: dom_x, + dom_y: dom_y, + totalOrder: totalOrder + }; } // transformData(raw, mark) provides specifications and data for @@ -679,2626 +997,3705 @@ //////////////////////////////////////////////////////// function transformData(raw, mark) { - var _this = this; - - //convenience mappings - 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; ////////////////////////////////////////////////////////////////////////////////// - // DATA PREP - // prepare data based on the properties of the mark - drop missing records, etc - ////////////////////////////////////////////////////////////////////////////////// - - var cleaned = cleanData.call(this, mark, raw); //prepare nested data required for bar charts - - 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); - } // Get the domain for the mark based on the raw data - - - var raw_dom_x = mark.summarizeX === 'cumulative' ? [0, cleaned.length] : config.x.type === 'ordinal' ? d3.set(cleaned.map(function (m) { - return m[config.x.column]; - })).values().filter(function (f) { - return f; - }) : mark.split && mark.arrange !== 'stacked' ? d3.extent(d3.merge(raw_nest.nested.map(function (m) { - return m.values.map(function (p) { - return p.values.raw.length; - }); - }))) : mark.summarizeX === 'count' ? d3.extent(raw_nest.nested.map(function (m) { - return m.values.raw.length; - })) : d3.extent(cleaned.map(function (m) { - return +m[config.x.column]; - }).filter(function (f) { - return +f || +f === 0; - })); - var raw_dom_y = mark.summarizeY === 'cumulative' ? [0, cleaned.length] : config.y.type === 'ordinal' ? d3.set(cleaned.map(function (m) { - return m[config.y.column]; - })).values().filter(function (f) { - return f; - }) : mark.split && mark.arrange !== 'stacked' ? d3.extent(d3.merge(raw_nest.nested.map(function (m) { - return m.values.map(function (p) { - return p.values.raw.length; - }); - }))) : mark.summarizeY === 'count' ? d3.extent(raw_nest.nested.map(function (m) { - return m.values.raw.length; - })) : d3.extent(cleaned.map(function (m) { - return +m[config.y.column]; - }).filter(function (f) { - return +f || +f === 0; - })); - var 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; - }); - }); //get domain for all non-All values of first filter - - if (config.x.behavior === 'firstfilter' || config.y.behavior === 'firstfilter') { - this.filters[0].choices.filter(function (f) { - return f !== 'All'; - }).forEach(function (e) { - var perfilter = cleaned.filter(function (f) { - return f[_this.filters[0].col] === e; - }); - var filt_nested = makeNest.call(_this, mark, perfilter, sublevel); - filt1_xs.push(filt_nested.dom_x); - filt1_ys.push(filt_nested.dom_y); - }); - } - } //filter on mark-specific instructions - - - if (mark.values) { - var _loop = function _loop(a) { - filtered = filtered.filter(function (f) { - return mark.values[a].indexOf(f[a]) > -1; - }); - }; + var _this = this; + + //convenience mappings + 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; ////////////////////////////////////////////////////////////////////////////////// + // DATA PREP + // prepare data based on the properties of the mark - drop missing records, etc + ////////////////////////////////////////////////////////////////////////////////// + + var cleaned = cleanData.call(this, mark, raw); //prepare nested data required for bar charts + + 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); + } // Get the domain for the mark based on the raw data + + var raw_dom_x = + mark.summarizeX === 'cumulative' + ? [0, cleaned.length] + : config.x.type === 'ordinal' + ? d3 + .set( + cleaned.map(function(m) { + return m[config.x.column]; + }) + ) + .values() + .filter(function(f) { + return f; + }) + : mark.split && mark.arrange !== 'stacked' + ? d3.extent( + d3.merge( + raw_nest.nested.map(function(m) { + return m.values.map(function(p) { + return p.values.raw.length; + }); + }) + ) + ) + : mark.summarizeX === 'count' + ? d3.extent( + raw_nest.nested.map(function(m) { + return m.values.raw.length; + }) + ) + : d3.extent( + cleaned + .map(function(m) { + return +m[config.x.column]; + }) + .filter(function(f) { + return +f || +f === 0; + }) + ); + var raw_dom_y = + mark.summarizeY === 'cumulative' + ? [0, cleaned.length] + : config.y.type === 'ordinal' + ? d3 + .set( + cleaned.map(function(m) { + return m[config.y.column]; + }) + ) + .values() + .filter(function(f) { + return f; + }) + : mark.split && mark.arrange !== 'stacked' + ? d3.extent( + d3.merge( + raw_nest.nested.map(function(m) { + return m.values.map(function(p) { + return p.values.raw.length; + }); + }) + ) + ) + : mark.summarizeY === 'count' + ? d3.extent( + raw_nest.nested.map(function(m) { + return m.values.raw.length; + }) + ) + : d3.extent( + cleaned + .map(function(m) { + return +m[config.y.column]; + }) + .filter(function(f) { + return +f || +f === 0; + }) + ); + var 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; + }); + }); //get domain for all non-All values of first filter + + if (config.x.behavior === 'firstfilter' || config.y.behavior === 'firstfilter') { + this.filters[0].choices + .filter(function(f) { + return f !== 'All'; + }) + .forEach(function(e) { + var perfilter = cleaned.filter(function(f) { + return f[_this.filters[0].col] === e; + }); + var filt_nested = makeNest.call(_this, mark, perfilter, sublevel); + filt1_xs.push(filt_nested.dom_x); + filt1_ys.push(filt_nested.dom_y); + }); + } + } //filter on mark-specific instructions + + 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]; + } + } //several criteria must be met in order to use the 'firstfilter' domain + + var nonall = Boolean( + this.filters.length && + this.filters[0].val !== 'All' && + this.filters.slice(1).filter(function(f) { + return f.val === 'All'; + }).length === + this.filters.length - 1 + ); + var pre_x_dom = !this.filters.length + ? flex_dom_x + : x_behavior === 'raw' + ? raw_dom_x + : nonall && x_behavior === 'firstfilter' + ? filt1_dom_x + : flex_dom_x; + var pre_y_dom = !this.filters.length + ? flex_dom_y + : y_behavior === 'raw' + ? raw_dom_y + : nonall && y_behavior === 'firstfilter' + ? filt1_dom_y + : flex_dom_y; + var x_dom = config.x_dom + ? config.x_dom + : config.x.type === 'ordinal' && config.x.behavior === 'flex' + ? d3 + .set( + filtered.map(function(m) { + return m[config.x.column]; + }) + ) + .values() + : config.x.type === 'ordinal' + ? d3 + .set( + cleaned.map(function(m) { + return m[config.x.column]; + }) + ) + .values() + : pre_x_dom; + var y_dom = config.y_dom + ? config.y_dom + : config.y.type === 'ordinal' && config.y.behavior === 'flex' + ? d3 + .set( + filtered.map(function(m) { + return m[config.y.column]; + }) + ) + .values() + : config.y.type === 'ordinal' + ? d3 + .set( + cleaned.map(function(m) { + return m[config.y.column]; + }) + ) + .values() + : pre_y_dom; //set lower limit of linear domain to 0 when other axis is ordinal and mark type is set to 'bar', provided no values are negative + + if (mark.type === 'bar') { + if ( + config.x.behavior !== 'flex' && + config.x.type === 'linear' && + config.y.type === 'ordinal' && + raw_dom_x[0] >= 0 + ) + x_dom[0] = 0; + if ( + config.y.behavior !== 'flex' && + config.x.type === 'ordinal' && + config.y.type === 'linear' && + raw_dom_y[0] >= 0 + ) + y_dom[0] = 0; + } //update domains with those specified in the config + + if ( + config.x.domain && + (config.x.domain[0] || config.x.domain[0] === 0) && + !isNaN(+config.x.domain[0]) + ) { + 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]; + } - 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]; - } - } //several criteria must be met in order to use the 'firstfilter' domain - - - var nonall = Boolean(this.filters.length && this.filters[0].val !== 'All' && this.filters.slice(1).filter(function (f) { - return f.val === 'All'; - }).length === this.filters.length - 1); - var pre_x_dom = !this.filters.length ? flex_dom_x : x_behavior === 'raw' ? raw_dom_x : nonall && x_behavior === 'firstfilter' ? filt1_dom_x : flex_dom_x; - var pre_y_dom = !this.filters.length ? flex_dom_y : y_behavior === 'raw' ? raw_dom_y : nonall && y_behavior === 'firstfilter' ? filt1_dom_y : flex_dom_y; - var x_dom = config.x_dom ? config.x_dom : config.x.type === 'ordinal' && config.x.behavior === 'flex' ? d3.set(filtered.map(function (m) { - return m[config.x.column]; - })).values() : config.x.type === 'ordinal' ? d3.set(cleaned.map(function (m) { - return m[config.x.column]; - })).values() : pre_x_dom; - var y_dom = config.y_dom ? config.y_dom : config.y.type === 'ordinal' && config.y.behavior === 'flex' ? d3.set(filtered.map(function (m) { - return m[config.y.column]; - })).values() : config.y.type === 'ordinal' ? d3.set(cleaned.map(function (m) { - return m[config.y.column]; - })).values() : pre_y_dom; //set lower limit of linear domain to 0 when other axis is ordinal and mark type is set to 'bar', provided no values are negative - - if (mark.type === 'bar') { - if (config.x.behavior !== 'flex' && config.x.type === 'linear' && config.y.type === 'ordinal' && raw_dom_x[0] >= 0) x_dom[0] = 0; - if (config.y.behavior !== 'flex' && config.x.type === 'ordinal' && config.y.type === 'linear' && raw_dom_y[0] >= 0) y_dom[0] = 0; - } //update domains with those specified in the config - - - if (config.x.domain && (config.x.domain[0] || config.x.domain[0] === 0) && !isNaN(+config.x.domain[0])) { - 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 - }; + 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); + 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; + 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; + 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 < max_width ? div_width : this.raw_width; - this.textSize(preWidth); - this.margin = this.setMargins(); - var svg_width = config.x.type === 'ordinal' && +config.x.range_band ? this.raw_width + this.margin.left + this.margin.right : !config.resizable ? this.raw_width : !config.max_width || div_width < config.max_width ? div_width : this.raw_width; - this.plot_width = svg_width - this.margin.left - this.margin.right; - var svg_height = config.y.type === 'ordinal' && +config.y.range_band ? this.raw_height + this.margin.top + this.margin.bottom : !config.resizable && config.height ? config.height : !config.resizable ? svg_width * aspect2 : this.plot_width * aspect2; - this.plot_height = svg_height - this.margin.top - this.margin.bottom; - d3.select(this.svg.node().parentNode).attr('width', svg_width).attr('height', svg_height).select('g').attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')'); - this.svg.select('.overlay').attr('width', this.plot_width).attr('height', this.plot_height).classed('zoomable', config.zoomable); - this.svg.select('.plotting-area').attr('width', this.plot_width).attr('height', this.plot_height + 1).attr('transform', 'translate(0, -1)'); - this.xScaleAxis(); - this.yScaleAxis(); - var g_x_axis = this.svg.select('.x.axis'); - var g_y_axis = this.svg.select('.y.axis'); - var x_axis_label = g_x_axis.select('.axis-title'); - var y_axis_label = g_y_axis.select('.axis-title'); - - if (config.x_location !== 'top') { - g_x_axis.attr('transform', 'translate(0,' + this.plot_height + ')'); - } - - var gXAxisTrans = config.transitions ? g_x_axis.transition() : g_x_axis; - gXAxisTrans.call(this.xAxis); - var gYAxisTrans = config.transitions ? g_y_axis.transition() : g_y_axis; - gYAxisTrans.call(this.yAxis); - x_axis_label.attr('transform', 'translate(' + this.plot_width / 2 + ',' + (this.margin.bottom - 2) + ')'); - y_axis_label.attr('x', -1 * this.plot_height / 2).attr('y', -1 * this.margin.left); - this.svg.selectAll('.axis .domain').attr({ - fill: 'none', - stroke: '#ccc', - 'stroke-width': 1, - 'shape-rendering': 'crispEdges' - }); - this.svg.selectAll('.axis .tick line').attr({ - stroke: '#eee', - 'stroke-width': 1, - 'shape-rendering': 'crispEdges' - }); - this.drawGridlines(); //update legend - margins need to be set first - - this.makeLegend(); //update the chart's specific marks - - this.updateDataMarks(); //call .on("resize") function, if any - - this.events.onResize.call(this); + 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 < max_width + ? div_width + : this.raw_width; + this.textSize(preWidth); + this.margin = this.setMargins(); + var svg_width = + config.x.type === 'ordinal' && +config.x.range_band + ? this.raw_width + this.margin.left + this.margin.right + : !config.resizable + ? this.raw_width + : !config.max_width || div_width < config.max_width + ? div_width + : this.raw_width; + this.plot_width = svg_width - this.margin.left - this.margin.right; + var svg_height = + config.y.type === 'ordinal' && +config.y.range_band + ? this.raw_height + this.margin.top + this.margin.bottom + : !config.resizable && config.height + ? config.height + : !config.resizable + ? svg_width * aspect2 + : this.plot_width * aspect2; + this.plot_height = svg_height - this.margin.top - this.margin.bottom; + d3.select(this.svg.node().parentNode) + .attr('width', svg_width) + .attr('height', svg_height) + .select('g') + .attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')'); + this.svg + .select('.overlay') + .attr('width', this.plot_width) + .attr('height', this.plot_height) + .classed('zoomable', config.zoomable); + this.svg + .select('.plotting-area') + .attr('width', this.plot_width) + .attr('height', this.plot_height + 1) + .attr('transform', 'translate(0, -1)'); + this.xScaleAxis(); + this.yScaleAxis(); + var g_x_axis = this.svg.select('.x.axis'); + var g_y_axis = this.svg.select('.y.axis'); + var x_axis_label = g_x_axis.select('.axis-title'); + var y_axis_label = g_y_axis.select('.axis-title'); + + if (config.x_location !== 'top') { + g_x_axis.attr('transform', 'translate(0,' + this.plot_height + ')'); + } + + var gXAxisTrans = config.transitions ? g_x_axis.transition() : g_x_axis; + gXAxisTrans.call(this.xAxis); + var gYAxisTrans = config.transitions ? g_y_axis.transition() : g_y_axis; + gYAxisTrans.call(this.yAxis); + x_axis_label.attr( + 'transform', + 'translate(' + this.plot_width / 2 + ',' + (this.margin.bottom - 2) + ')' + ); + y_axis_label.attr('x', (-1 * this.plot_height) / 2).attr('y', -1 * this.margin.left); + this.svg.selectAll('.axis .domain').attr({ + fill: 'none', + stroke: '#ccc', + 'stroke-width': 1, + 'shape-rendering': 'crispEdges' + }); + this.svg.selectAll('.axis .tick line').attr({ + stroke: '#eee', + 'stroke-width': 1, + 'shape-rendering': 'crispEdges' + }); + this.drawGridlines(); //update legend - margins need to be set first + + this.makeLegend(); //update the chart's specific marks + + this.updateDataMarks(); //call .on("resize") function, if any + + this.events.onResize.call(this); } function textSize(width) { - var font_size = '14px'; - var point_size = 4; - var stroke_width = 2; - - if (!this.config.scale_text) { - font_size = this.config.font_size; - point_size = this.config.point_size || 4; - stroke_width = this.config.stroke_width || 2; - } else if (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; + var font_size = '14px'; + var point_size = 4; + var stroke_width = 2; + + if (!this.config.scale_text) { + font_size = this.config.font_size; + point_size = this.config.point_size || 4; + stroke_width = this.config.stroke_width || 2; + } else if (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 : 0.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 * 0.5 + font_size * y_label_on * 1.5 || 8; - var x_margin = font_size + font_size / 1.5 + font_size * x_label_on + font_size * x_second || 8; - 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 - }; + 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 : 0.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 * 0.5 + font_size * y_label_on * 1.5 || 8; + var x_margin = + font_size + font_size / 1.5 + font_size * x_label_on + font_size * x_second || 8; + 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); - } + 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) { - //singular chart - if (this.config.legend.location === 'top' || this.config.legend.location === 'left') { - this.wrap.node().insertBefore(legendOriginal.node(), this.svg.node().parentNode); + 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) { + //singular chart + 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 { - this.wrap.node().appendChild(legendOriginal.node()); + //multiples - keep legend outside of individual charts' wraps + if (this.config.legend.location === 'top' || this.config.legend.location === 'left') { + this.parent.wrap + .node() + .insertBefore( + legendOriginal.node(), + this.parent.wrap.select('.wc-chart').node() + ); + } else { + this.parent.wrap.node().appendChild(legendOriginal.node()); + } } - } else { - //multiples - keep legend outside of individual charts' wraps - if (this.config.legend.location === 'top' || this.config.legend.location === 'left') { - this.parent.wrap.node().insertBefore(legendOriginal.node(), this.parent.wrap.select('.wc-chart').node()); - } 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) + ); + }); } - } - 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').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; + 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'); + 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 : 0.3); //don't transition if config says not to - - var areaPathTransitions = this.config.transitions ? areaPaths.transition() : areaPaths; - areaPathTransitions.attr('d', area_drawer); - return area_grps; + 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 + : 0.3 + ); //don't transition if config says not to + + 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') { + 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 = bar_groups + .enter() + .append('g') + .attr('class', function(d) { + return 'bar-group ' + d.key; + }); nu_bar_groups.append('title'); - bars = bar_groups.selectAll('rect').data(function (d) { - return d.values instanceof Array ? d.values.sort(function (a, b) { - return _this.colorScale.domain().indexOf(b.key) - _this.colorScale.domain().indexOf(a.key); - }) : [d]; - }, function (d) { - return d.key; - }); + bars = bar_groups.selectAll('rect').data( + function(d) { + return d.values instanceof Array + ? d.values.sort(function(a, b) { + return ( + _this.colorScale.domain().indexOf(b.key) - + _this.colorScale.domain().indexOf(a.key) + ); + }) + : [d]; + }, + function(d) { + return d.key; + } + ); var exitBars = config.transitions ? bars.exit().transition() : bars.exit(); - exitBars.attr('y', this.y(0)).attr('height', 0).remove(); - bars.enter().append('rect').attr('class', function (d) { - return 'wc-data-mark bar ' + d.key; - }).style('clip-path', "url(#".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); + 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() + : 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 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 * 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') { + 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); + }); + } + + 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 = 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 = 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() + : mark.values && mark.values[mark.split] + ? mark.values[mark.split] + : d3 + .set( + rawData.map(function(m) { + return m[mark.split]; + }) + ) + .values() + .sort(); + d.tooltip = mark.tooltip; + d3.select(this).attr(mark.attributes); }); - 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 * 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); + + 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 _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]; - }); - }); + function xBin(oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars) { + var _this = this; - var _barsTrans = config.transitions ? bars.transition() : bars; - - _barsTrans.attr('x', function (d) { - if (d.arrange === 'stacked' || !d.arrange) { - return d.values.start !== undefined ? _this.x(d.values.start) : _this.x(0); - } else { - return _this.x(0); - } - }).attr('y', function (d) { - if (d.arrange === 'nested') { - var position = d.subcats.indexOf(d.key); - var offset = position ? _this.y.rangeBand() / (d.subcats.length * 0.75) / position : _this.y.rangeBand(); - return _this.y(d.values.y) + (_this.y.rangeBand() - offset) / 2; - } else if (d.arrange === 'grouped') { - var _position2 = d.subcats.indexOf(d.key); - - return _this.y(d.values.y) + _this.y.rangeBand() / d.subcats.length * _position2; - } else { - return _this.y(d.values.y); - } - }).attr('width', function (d) { - return _this.x(d.values.x) - _this.x(0); - }).attr('height', function (d) { - if (config.y.type === 'quantile') { - return 20; - } else if (d.arrange === 'nested') { - var position = d.subcats.indexOf(d.key); - return position ? _this.y.rangeBand() / (d.subcats.length * 0.75) / position : _this.y.rangeBand(); - } else if (d.arrange === 'grouped') { - return _this.y.rangeBand() / d.subcats.length; - } else { - return _this.y.rangeBand(); - } - }); - } else if (['linear', 'log'].indexOf(config.x.type) > -1 && config.x.bin) { + 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 = 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 = 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; }); - 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); + }); + } - 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]; - }); - }); + function yBin(oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars) { + var _this = this; - 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) { + 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 = 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 = 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; }); - 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); + }); + } - 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('-'); }); - - 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); + bar_supergroups + .enter() + .append('g') + .attr('class', function(d) { + return 'supergroup bar-supergroup ' + d.id; + }); + bar_supergroups.exit().remove(); // bar groups + + 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 + + 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(); + } //Link to the d3.selection from the data + + bar_supergroups.each(function(d) { + d.supergroup = d3.select(this); + d.groups = d.supergroup.selectAll('.bar-group'); }); - } else { - oldBarsTrans.attr('y', this.y(0)).attr('height', 0); - oldBarGroupsTrans.remove(); - bar_supergroups.remove(); - } //Link to the d3.selection from the data - - - 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]; + 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('-'); }); - }); //Link to the d3.selection from the data - - 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; + 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]; + }); + }); //Link to the d3.selection from the data + + 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'); //static attributes - - points.select('circle').style('clip-path', "url(#".concat(chart.id, ")")).attr('fill-opacity', config.fill_opacity || config.fill_opacity === 0 ? config.fill_opacity : 0.6).attr('fill', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }).attr('stroke', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); //attach mark info - - points.each(function (d) { - var mark = d3.select(this.parentNode).datum(); - d.mark = mark; - d3.select(this).select('circle').attr(mark.attributes); - }); //animated attributes - - var pointsTrans = config.transitions ? points.select('circle').transition() : points.select('circle'); - pointsTrans.attr('r', function (d) { - return d.mark.radius || config.flex_point_size; - }).attr('cx', function (d) { - var x_pos = _this.x(d.values.x) || 0; - return config.x.type === 'ordinal' ? x_pos + _this.x.rangeBand() / 2 : x_pos; - }).attr('cy', function (d) { - var y_pos = _this.y(d.values.y) || 0; - return config.y.type === 'ordinal' ? y_pos + _this.y.rangeBand() / 2 : y_pos; - }); - 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]; - }); - }); //Link to the d3.selection from the data + var _this = this; - 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; + 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'); //static attributes + + points + .select('circle') + .style('clip-path', 'url(#'.concat(chart.id, ')')) + .attr( + 'fill-opacity', + config.fill_opacity || config.fill_opacity === 0 ? config.fill_opacity : 0.6 + ) + .attr('fill', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }) + .attr('stroke', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); //attach mark info + + points.each(function(d) { + var mark = d3.select(this.parentNode).datum(); + d.mark = mark; + d3.select(this) + .select('circle') + .attr(mark.attributes); + }); //animated attributes + + var pointsTrans = config.transitions + ? points.select('circle').transition() + : points.select('circle'); + pointsTrans + .attr('r', function(d) { + return d.mark.radius || config.flex_point_size; + }) + .attr('cx', function(d) { + var x_pos = _this.x(d.values.x) || 0; + return config.x.type === 'ordinal' ? x_pos + _this.x.rangeBand() / 2 : x_pos; + }) + .attr('cy', function(d) { + var y_pos = _this.y(d.values.y) || 0; + return config.y.type === 'ordinal' ? y_pos + _this.y.rangeBand() / 2 : y_pos; + }); + 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]; + }); + }); //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'); + }); + 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(); // don't need to transition position of outgoing text - // const oldTextsTrans = config.transitions ? oldTexts.selectAll('text').transition() : oldTexts.selectAll('text'); - - 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'); // don't need to set initial location for incoming text - // attach mark info - - function attachMarks(d) { - d.mark = d3.select(this.parentNode).datum(); - d3.select(this).select('text').attr(d.mark.attributes); - } - - texts.each(attachMarks); // parse text like tooltips - - 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]; - }); - }); // animated attributes + var _this = this; - var textsTrans = config.transitions ? texts.select('text').transition() : texts.select('text'); - textsTrans.attr('x', function (d) { - var xPos = _this.x(d.values.x) || 0; - return config.x.type === 'ordinal' ? xPos + _this.x.rangeBand() / 2 : xPos; - }).attr('y', function (d) { - var yPos = _this.y(d.values.y) || 0; - return config.y.type === 'ordinal' ? yPos + _this.y.rangeBand() / 2 : yPos; - }); //add a reference to the selection from it's data + 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(); // don't need to transition position of outgoing text + // const oldTextsTrans = config.transitions ? oldTexts.selectAll('text').transition() : oldTexts.selectAll('text'); + + 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'); // don't need to set initial location for incoming text + // attach mark info + + function attachMarks(d) { + d.mark = d3.select(this.parentNode).datum(); + d3.select(this) + .select('text') + .attr(d.mark.attributes); + } - textSupergroups.each(function (d) { - d.supergroup = d3.select(this); - d.groups = d.supergroup.selectAll('g.text'); - d.texts = d.groups.select('text'); - }); - return texts; + texts.each(attachMarks); // parse text like tooltips + + 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]; + }); + }); // animated attributes + + var textsTrans = config.transitions + ? texts.select('text').transition() + : texts.select('text'); + textsTrans + .attr('x', function(d) { + var xPos = _this.x(d.values.x) || 0; + return config.x.type === 'ordinal' ? xPos + _this.x.rangeBand() / 2 : xPos; + }) + .attr('y', function(d) { + var yPos = _this.y(d.values.y) || 0; + return config.y.type === 'ordinal' ? yPos + _this.y.rangeBand() / 2 : yPos; + }); //add a reference to the selection from it's data + + 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; - //run onDestroy callback - this.events.onDestroy.call(this); //remove resize event listener + var destroyControls = + arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + //run onDestroy callback + this.events.onDestroy.call(this); //remove resize event listener - var context = this; - if (!this.test) d3.select(window).on('resize.' + context.element + context.id, null); //destroy controls + var context = this; + if (!this.test) d3.select(window).on('resize.' + context.element + context.id, null); //destroy controls - if (destroyControls && this.controls) { - this.controls.destroy(); - } //unmount chart wrapper + if (destroyControls && this.controls) { + this.controls.destroy(); + } //unmount chart wrapper - - this.wrap.remove(); + this.wrap.remove(); } var chartProto = { - raw_data: [], - config: {} + 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 - } + 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; - } + 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() {} + }; - if (callback) { - thisChart.events['on' + event.charAt(0).toUpperCase() + event.slice(1)] = callback; - } - }; //increment thisChart count to get unique thisChart id + 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; + } + }; //increment thisChart count to get unique thisChart id - chartCount++; - thisChart.id = chartCount; - return thisChart; + 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); - } //call callback function if provided + 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); + } //call callback function if provided - if (callback) { - callback(); - } + if (callback) { + callback(); + } - if (draw) target.draw(); - }); + 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.")); //Draw the chart when a control changes unless the user specifies otherwise. - - input.draw = input.draw === undefined ? true : input.draw; - }); + 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.' + ) + ); //Draw the chart when a control changes unless the user specifies otherwise. + + input.draw = input.draw === undefined ? true : input.draw; + }); } function controlUpdate() { - var _this = this; + var _this = this; - if (this.config.inputs && this.config.inputs.length && this.config.inputs[0]) this.config.inputs.forEach(function (input) { - return _this.makeControlItem(input); - }); + if (this.config.inputs && this.config.inputs.length && this.config.inputs[0]) + this.config.inputs.forEach(function(input) { + return _this.makeControlItem(input); + }); } function destroy$1() { - //unmount controls wrapper - this.wrap.remove(); + //unmount controls wrapper + this.wrap.remove(); } function init$1(data) { - this.data = data; - if (!this.config.builder) this.checkRequired(this.data); - this.layout(); + 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(); + 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); //Add control label span. - - var ctrl_label = control_wrap.append('span').attr('class', 'wc-control-label').text(control.label); //Add control _Required_ text to control label span. - - if (control.required) ctrl_label.append('span').attr('class', 'label label-required').text('Required'); //Add control description span. - - 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".'); - } + var control_wrap = this.wrap + .append('div') + .attr('class', 'control-group') + .classed('inline', control.inline) + .datum(control); //Add control label span. + + var ctrl_label = control_wrap + .append('span') + .attr('class', 'wc-control-label') + .text(control.label); //Add control _Required_ text to control label span. + + if (control.required) + ctrl_label + .append('span') + .attr('class', 'label label-required') + .text('Required'); //Add control description span. + + control_wrap + .append('span') + .attr('class', 'span-description') + .text(control.description); + + 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); - }); + 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); - }); + _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'); + 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); - }); + _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); + 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'); } - }); - return changer; - } - function makeListControl(control, control_wrap) { - var _this = this; + 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'; + }); + } - 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; + if (control.options) { + _this.changeOption(control.options, value, control.callback, control.draw); + } else { + _this.changeOption(control.option, value, control.callback, control.draw); + } + }); + return changer; + } - _this.changeOption(control.option, value, control.callback, control.draw); - }); + 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'); + 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); - }); + _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; - } - }); + 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); - }); + _this.changeOption(control.option, value, control.callback, control.draw); + }); } function makeSubsetterControl(control, control_wrap) { - var targets = this.targets; // associated charts and tables. - //dropdown selection - - var changer = control_wrap.append('select').classed('changer', true).attr('multiple', control.multiple ? true : null).datum(control); //dropdown option data - - var option_data = control.values ? control.values : d3.set(this.data.map(function (m) { - return m[control.value_col]; - }).filter(function (f) { - return f; - })).values().sort(naturalSorter); // only sort when values are derived - //initial dropdown option - - control.start = control.start ? control.start : control.loose ? option_data[0] : null; //conditionally add All option - - if (!control.multiple && !control.start) { - option_data.unshift('All'); - control.all = true; - } else { - control.all = false; - } //what does loose mean? - - - control.loose = !control.loose && control.start ? true : control.loose; //dropdown options selection - - var options = changer.selectAll('option').data(option_data).enter().append('option').text(function (d) { - return d; - }).property('selected', function (d) { - return d === control.start; - }); //define filter object for each associated target - - targets.forEach(function (e) { - var match = e.filters.slice().map(function (m) { - return m.col === control.value_col; - }).indexOf(true); - - 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 - }; + var targets = this.targets; // associated charts and tables. + //dropdown selection + + var changer = control_wrap + .append('select') + .classed('changer', true) + .attr('multiple', control.multiple ? true : null) + .datum(control); //dropdown option data + + var option_data = control.values + ? control.values + : d3 + .set( + this.data + .map(function(m) { + return m[control.value_col]; + }) + .filter(function(f) { + return f; + }) + ) + .values() + .sort(naturalSorter); // only sort when values are derived + //initial dropdown option + + control.start = control.start ? control.start : control.loose ? option_data[0] : null; //conditionally add All option + + if (!control.multiple && !control.start) { + option_data.unshift('All'); + control.all = true; } 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; - } + control.all = false; + } //what does loose mean? + + control.loose = !control.loose && control.start ? true : control.loose; //dropdown options selection + + var options = changer + .selectAll('option') + .data(option_data) + .enter() + .append('option') + .text(function(d) { + return d; + }) + .property('selected', function(d) { + return d === control.start; + }); //define filter object for each associated target + + targets.forEach(function(e) { + var match = e.filters + .slice() + .map(function(m) { + return m.col === control.value_col; + }) + .indexOf(true); + + 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 + }); + } }); - if (match > -1) { - target.filters[match] = obj; - } - } //add event listener to control - - - 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, - // could specify an array of indices but seems like a waste of resources give it doesn't inform anything without an overall 'All' - choices: option_data, - loose: control.loose, - all: control.all - }; - targets.forEach(function (e) { - setSubsetter(e, new_filter); //call callback function if provided - - if (control.callback) { - control.callback(); - } + function setSubsetter(target, obj) { + var match = -1; + target.filters.forEach(function(e, i) { + if (e.col === obj.col) { + match = i; + } + }); - 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); //call callback function if provided - - if (control.callback) { - control.callback(); + if (match > -1) { + target.filters[match] = obj; } - - e.draw(); - }); - } - }); + } //add event listener to control + + 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, + // could specify an array of indices but seems like a waste of resources give it doesn't inform anything without an overall 'All' + choices: option_data, + loose: control.loose, + all: control.all + }; + targets.forEach(function(e) { + setSubsetter(e, new_filter); //call callback function if provided + + 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); //call callback function if provided + + 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'); + 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); - }); + _this.changeOption(control.option, value, control.callback, control.draw); + }); } function stringAccessor(o, s, v) { - //adapted from http://jsfiddle.net/alnitak/hEsys/ - s = s.replace(/\[(\w+)\]/g, '.$1'); - s = s.replace(/^\./, ''); - var a = s.split('.'); + //adapted from http://jsfiddle.net/alnitak/hEsys/ + s = s.replace(/\[(\w+)\]/g, '.$1'); + s = s.replace(/^\./, ''); + var a = s.split('.'); - for (var i = 0, n = a.length; i < n; ++i) { - var k = a[i]; + for (var i = 0, n = a.length; i < n; ++i) { + var k = a[i]; - if (k in o) { - if (i == n - 1 && v !== undefined) o[k] = v; - o = o[k]; - } else { - return; + if (k in o) { + if (i == n - 1 && v !== undefined) o[k] = v; + o = o[k]; + } else { + return; + } } - } - return o; + return o; } var controls = { - changeOption: changeOption, - checkRequired: checkRequired$1, - controlUpdate: controlUpdate, - destroy: destroy$1, - init: init$1, - layout: layout$1, - makeControlItem: makeControlItem, - makeBtnGroupControl: makeBtnGroupControl, - makeCheckboxControl: makeCheckboxControl, - makeDropdownControl: makeDropdownControl, - makeListControl: makeListControl, - makeNumberControl: makeNumberControl, - makeRadioControl: makeRadioControl, - makeSubsetterControl: makeSubsetterControl, - makeTextControl: makeTextControl, - stringAccessor: stringAccessor + changeOption: changeOption, + checkRequired: checkRequired$1, + controlUpdate: controlUpdate, + destroy: destroy$1, + init: init$1, + layout: layout$1, + makeControlItem: makeControlItem, + makeBtnGroupControl: makeBtnGroupControl, + makeCheckboxControl: makeCheckboxControl, + makeDropdownControl: makeDropdownControl, + makeListControl: makeListControl, + makeNumberControl: makeNumberControl, + makeRadioControl: makeRadioControl, + makeSubsetterControl: makeSubsetterControl, + makeTextControl: makeTextControl, + stringAccessor: stringAccessor }; function createControls() { - var element = arguments.length > 0 && 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'); - } + var element = arguments.length > 0 && 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; + thisControls.wrap.datum(thisControls); + return thisControls; } function applyFilters() { - var _this = this; - - //If there are filters, return a filtered data array of the raw data. - //Otherwise return the raw data. - if (this.filters && this.filters.some(function (filter) { - return typeof filter.val === 'string' && !(filter.all === true && filter.index === 0) || Array.isArray(filter.val) && filter.val.length < filter.choices.length; - })) { - this.data.filtered = this.data.raw.slice(); - this.filters.filter(function (filter) { - return typeof filter.val === 'string' && !(filter.all === true && filter.index === 0) || Array.isArray(filter.val) && filter.val.length < filter.choices.length; - }).forEach(function (filter) { - _this.data.filtered = _this.data.filtered.filter(function (d) { - return Array.isArray(filter.val) ? filter.val.indexOf(d[filter.col]) > -1 : filter.val === d[filter.col]; - }); - }); - } else this.data.filtered = this.data.raw.slice(); + var _this = this; + + //If there are filters, return a filtered data array of the raw data. + //Otherwise return the raw data. + if ( + this.filters && + this.filters.some(function(filter) { + return ( + (typeof filter.val === 'string' && + !(filter.all === true && filter.index === 0)) || + (Array.isArray(filter.val) && filter.val.length < filter.choices.length) + ); + }) + ) { + this.data.filtered = this.data.raw.slice(); + this.filters + .filter(function(filter) { + return ( + (typeof filter.val === 'string' && + !(filter.all === true && filter.index === 0)) || + (Array.isArray(filter.val) && filter.val.length < filter.choices.length) + ); + }) + .forEach(function(filter) { + _this.data.filtered = _this.data.filtered.filter(function(d) { + return Array.isArray(filter.val) + ? filter.val.indexOf(d[filter.col]) > -1 + : filter.val === d[filter.col]; + }); + }); + } else this.data.filtered = this.data.raw.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; // first row shown + 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; // first row shown - this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown + this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown } function applySearchTerm(data) { - var _this = this; - - if (this.searchable.searchTerm) { - //Determine which rows contain input text. - 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 { - //Otherwise delete previously searched data and set data to filtered data. - delete this.data.searched; - this.data.processing = this.data.filtered; - } + var _this = this; + + if (this.searchable.searchTerm) { + //Determine which rows contain input text. + 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 { + //Otherwise delete previously searched data and set data to filtered data. + delete this.data.searched; + this.data.processing = this.data.filtered; + } } /*------------------------------------------------------------------------------------------------\ Check equality of two arrays (https://stackoverflow.com/questions/7837456/how-to-compare-arrays-in-javascript) \------------------------------------------------------------------------------------------------*/ // Warn if overriding existing method - if (Array.prototype.equals) console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code."); // attach the .equals method to Array's prototype to call it on any array - - Array.prototype.equals = function (array) { - // if the other array is a falsy value, return - if (!array) return false; // compare lengths - can save a lot of time - - if (this.length != array.length) return false; - - for (var i = 0, l = this.length; i < l; i++) { - // Check if we have nested arrays - if (this[i] instanceof Array && array[i] instanceof Array) { - // recurse into the nested arrays - if (!this[i].equals(array[i])) return false; - } else if (this[i] != array[i]) { - // Warning - two different object instances will never be equal: {x:20} != {x:20} - return false; + if (Array.prototype.equals) + console.warn( + "Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code." + ); // attach the .equals method to Array's prototype to call it on any array + + Array.prototype.equals = function(array) { + // if the other array is a falsy value, return + if (!array) return false; // compare lengths - can save a lot of time + + if (this.length != array.length) return false; + + for (var i = 0, l = this.length; i < l; i++) { + // Check if we have nested arrays + if (this[i] instanceof Array && array[i] instanceof Array) { + // recurse into the nested arrays + if (!this[i].equals(array[i])) return false; + } else if (this[i] != array[i]) { + // Warning - two different object instances will never be equal: {x:20} != {x:20} + return false; + } } - } - return true; + return true; }; // Hide method from for-in loops - Object.defineProperty(Array.prototype, 'equals', { - enumerable: false + enumerable: false }); function checkFilters() { - if (this.filters) { - this.currentFilters = this.filters.map(function (filter) { - return filter.val; - }); //Reset pagination if filters have changed. + if (this.filters) { + this.currentFilters = this.filters.map(function(filter) { + return filter.val; + }); //Reset pagination if filters have changed. - if (!this.currentFilters.equals(this.previousFilters)) { - this.config.activePage = 0; - this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; // first row shown + if (!this.currentFilters.equals(this.previousFilters)) { + this.config.activePage = 0; + this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; // first row shown - this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown - } + this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown + } - this.previousFilters = this.currentFilters; - } + this.previousFilters = this.currentFilters; + } } function updateTableHeaders() { - var _this = this; - - this.thead_cells = this.thead.select('tr').selectAll('th').data(this.config.headers, function (d) { - return d; - }); - this.thead_cells.exit().remove(); - this.thead_cells.enter().append('th'); - this.thead_cells.sort(function (a, b) { - return _this.config.headers.indexOf(a) - _this.config.headers.indexOf(b); - }).attr('class', function (d) { - return _this.config.cols[_this.config.headers.indexOf(d)]; - }) // associate column header with column name - .text(function (d) { - return d; - }); + var _this = this; + + this.thead_cells = this.thead + .select('tr') + .selectAll('th') + .data(this.config.headers, function(d) { + return d; + }); + this.thead_cells.exit().remove(); + this.thead_cells.enter().append('th'); + this.thead_cells + .sort(function(a, b) { + return _this.config.headers.indexOf(a) - _this.config.headers.indexOf(b); + }) + .attr('class', function(d) { + return _this.config.cols[_this.config.headers.indexOf(d)]; + }) // associate column header with column name + .text(function(d) { + return d; + }); } function drawTableBody() { - var _this = this; - - var table = this; //Define table body rows. - - var rows = this.tbody.selectAll('tr').data(this.data.processing).enter().append('tr'); //Define table body cells. - - var cells = rows.selectAll('td').data(function (d) { - return _this.config.cols.map(function (key) { - return { - col: key, - text: d[key] - }; + var _this = this; + + var table = this; //Define table body rows. + + var rows = this.tbody + .selectAll('tr') + .data(this.data.processing) + .enter() + .append('tr'); //Define table body cells. + + var cells = rows.selectAll('td').data(function(d) { + return _this.config.cols.map(function(key) { + return { + col: key, + text: d[key] + }; + }); }); - }); - cells.exit().remove(); - cells.enter().append('td'); - cells.sort(function (a, b) { - return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); - }).attr('class', function (d) { - return d.col; - }).each(function (d) { - var cell = d3.select(this); //Apply text in data as html or as plain text. - - if (table.config.as_html) { - cell.html(d.text); - } else { - cell.text(d.text); - } - }); + cells.exit().remove(); + cells.enter().append('td'); + cells + .sort(function(a, b) { + return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); + }) + .attr('class', function(d) { + return d.col; + }) + .each(function(d) { + var cell = d3.select(this); //Apply text in data as html or as plain text. + + if (table.config.as_html) { + cell.html(d.text); + } else { + cell.text(d.text); + } + }); } function dynamicLayout() { - var widths = { - table: this.table.select('thead').node().offsetWidth, - top: this.wrap.select('.table-top .searchable-container').node().offsetWidth + this.wrap.select('.table-top .sortable-container').node().offsetWidth, - bottom: this.wrap.select('.table-bottom .pagination-container').node().offsetWidth + this.wrap.select('.table-bottom .exportable-container').node().offsetWidth - }; - - if (widths.table < Math.max(widths.top, widths.bottom) && this.config.layout === 'horizontal') { - this.config.layout = 'vertical'; - this.wrap.style('display', 'inline-block').selectAll('.table-top,.table-bottom').style('display', 'inline-block').selectAll('.interactivity').style({ - display: 'block', - clear: 'both' - }); - } else if (widths.table >= Math.max(widths.top, widths.bottom) && this.config.layout === 'vertical') { - this.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 - }); - } + var widths = { + table: this.table.select('thead').node().offsetWidth, + top: + this.wrap.select('.table-top .searchable-container').node().offsetWidth + + this.wrap.select('.table-top .sortable-container').node().offsetWidth, + bottom: + this.wrap.select('.table-bottom .pagination-container').node().offsetWidth + + this.wrap.select('.table-bottom .exportable-container').node().offsetWidth + }; + + if ( + widths.table < Math.max(widths.top, widths.bottom) && + this.config.layout === 'horizontal' + ) { + this.config.layout = 'vertical'; + this.wrap + .style('display', 'inline-block') + .selectAll('.table-top,.table-bottom') + .style('display', 'inline-block') + .selectAll('.interactivity') + .style({ + display: 'block', + clear: 'both' + }); + } else if ( + widths.table >= Math.max(widths.top, widths.bottom) && + this.config.layout === 'vertical' + ) { + this.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; // make passed data available on preprocess - - this.events.onPreprocess.call(this); - if (!passed_data) //Apply filters if data is not passed to table.draw(). - applyFilters.call(this); //Otherwise update data object. - else updateDataObject.call(this); //Compare current filter settings to previous filter settings, if any. - - checkFilters.call(this); //Filter data on search term if it exists and set data to searched data. - - applySearchTerm.call(this); - this.searchable.wrap.select('.nNrecords').text(this.data.processing.length === this.data.raw.length ? "".concat(this.data.raw.length, " records displayed") : "".concat(this.data.processing.length, "/").concat(this.data.raw.length, " records displayed")); //Update table headers. - - updateTableHeaders.call(this); //Clear table body rows. - - this.tbody.selectAll('tr').remove(); //Print a note that no data was selected for empty tables. - - if (this.data.processing.length === 0) { - this.tbody.append('tr').classed('no-data', true).append('td').attr('colspan', this.config.cols.length).text('No data selected.'); //Bind table filtered/searched data to table container. - - this.data.current = this.data.processing; - this.table.datum(this.table.current); //Add export. - - if (this.config.exportable) this.config.exports.forEach(function (fmt) { - _this.exportable.exports[fmt].call(_this, _this.data.processing); - }); //Add pagination. - - if (this.config.pagination) this.pagination.addPagination.call(this, this.data.processing); - } else { - //Sort data. - if (this.config.sortable) { - this.thead.selectAll('th').on('click', function (header) { - table.sortable.onClick.call(table, this, header); - }); - if (this.sortable.order.length) this.sortable.sortData.call(this, this.data.processing); - } //Bind table filtered/searched data to table container. - - - this.data.current = this.data.processing; - this.table.datum(this.data.current); //Add export. - - if (this.config.exportable) this.config.exports.forEach(function (fmt) { - _this.exportable.exports[fmt].call(_this, _this.data.processing); - }); //Add pagination. - - if (this.config.pagination) { - this.pagination.addPagination.call(this, this.data.processing); //Apply pagination. - - this.data.processing = this.data.processing.filter(function (d, i) { - return _this.config.startIndex <= i && i < _this.config.endIndex; - }); - } //Define table body rows. - - - drawTableBody.call(this); - } //Alter table layout if table is narrower than table top or bottom. - - - if (this.config.dynamicPositioning) { - dynamicLayout.call(this); - } + var _this = this; + + var table = this; + var config = this.config; + this.data.passed = passed_data; // make passed data available on preprocess + + this.events.onPreprocess.call(this); + if (!passed_data) + //Apply filters if data is not passed to table.draw(). + applyFilters.call(this); + //Otherwise update data object. + else updateDataObject.call(this); //Compare current filter settings to previous filter settings, if any. + + checkFilters.call(this); //Filter data on search term if it exists and set data to searched data. + + applySearchTerm.call(this); + this.searchable.wrap + .select('.nNrecords') + .text( + this.data.processing.length === this.data.raw.length + ? ''.concat(this.data.raw.length, ' records displayed') + : '' + .concat(this.data.processing.length, '/') + .concat(this.data.raw.length, ' records displayed') + ); //Update table headers. + + updateTableHeaders.call(this); //Clear table body rows. + + this.tbody.selectAll('tr').remove(); //Print a note that no data was selected for empty tables. + + if (this.data.processing.length === 0) { + this.tbody + .append('tr') + .classed('no-data', true) + .append('td') + .attr('colspan', this.config.cols.length) + .text('No data selected.'); //Bind table filtered/searched data to table container. + + this.data.current = this.data.processing; + this.table.datum(this.table.current); //Add export. + + if (this.config.exportable) + this.config.exports.forEach(function(fmt) { + _this.exportable.exports[fmt].call(_this, _this.data.processing); + }); //Add pagination. + + if (this.config.pagination) + this.pagination.addPagination.call(this, this.data.processing); + } else { + //Sort data. + if (this.config.sortable) { + this.thead.selectAll('th').on('click', function(header) { + table.sortable.onClick.call(table, this, header); + }); + if (this.sortable.order.length) + this.sortable.sortData.call(this, this.data.processing); + } //Bind table filtered/searched data to table container. + + this.data.current = this.data.processing; + this.table.datum(this.data.current); //Add export. + + if (this.config.exportable) + this.config.exports.forEach(function(fmt) { + _this.exportable.exports[fmt].call(_this, _this.data.processing); + }); //Add pagination. + + if (this.config.pagination) { + this.pagination.addPagination.call(this, this.data.processing); //Apply pagination. + + this.data.processing = this.data.processing.filter(function(d, i) { + return _this.config.startIndex <= i && i < _this.config.endIndex; + }); + } //Define table body rows. + + drawTableBody.call(this); + } //Alter table layout if table is narrower than table top or bottom. + + if (this.config.dynamicPositioning) { + dynamicLayout.call(this); + } - this.events.onDraw.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; // first row shown - - context.config.endIndex = context.config.startIndex + context.config.nRowsPerPage; // last row shown - - context.draw(); - }); - this.searchable.wrap.select('.search').append('span').classed('nNrecords', true); + 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; // first row shown + + context.config.endIndex = context.config.startIndex + context.config.nRowsPerPage; // last row shown + + context.draw(); + }); + this.searchable.wrap + .select('.search') + .append('span') + .classed('nNrecords', true); } function searchable() { - return { - layout: layout$2 - }; + 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()); - }); + 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) { - //transform blob array into a blob of characters - var blob = new Blob(data, { - type: fileType === 'csv' ? 'text/csv;charset=utf-8;' : fileType === 'xlsx' ? 'application/octet-stream' : console.warn("File type not supported: ".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) //IE - navigator.msSaveBlob(blob, fileName);else if (link.node().download !== undefined) { - //21st century browsers - var url = URL.createObjectURL(blob); - link.node().setAttribute('href', url); - link.node().setAttribute('download', fileName); - } + //transform blob array into a blob of characters + var blob = new Blob(data, { + type: + fileType === 'csv' + ? 'text/csv;charset=utf-8;' + : fileType === 'xlsx' + ? 'application/octet-stream' + : console.warn('File type not supported: '.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) + //IE + navigator.msSaveBlob(blob, fileName); + else if (link.node().download !== undefined) { + //21st century browsers + var url = URL.createObjectURL(blob); + link.node().setAttribute('href', url); + link.node().setAttribute('download', fileName); + } } function csv(data) { - var _this = this; + var _this = this; - this.wrap.select('.export#csv').on('click', function () { - var CSVarray = []; //add headers to CSV array + this.wrap.select('.export#csv').on('click', function() { + var CSVarray = []; //add headers to CSV array - var headers = _this.config.headers.map(function (header) { - return "\"".concat(header.replace(/"/g, '""'), "\""); - }); + var headers = _this.config.headers.map(function(header) { + return '"'.concat(header.replace(/"/g, '""'), '"'); + }); - CSVarray.push(headers); //add rows to CSV array + CSVarray.push(headers); //add rows to CSV array - 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, "\""); - }); + 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 .csv file. + CSVarray.push(row); + }); //Download .csv file. - download.call(_this, 'csv', [CSVarray.join('\n')]); - }); + 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]; - }); - }); // convert data from array of objects to array of arrays. - - var workbook = { - SheetNames: [sheetName], - Sheets: {} - }; - var cols = []; //Convert headers and data from array of arrays to sheet. - - workbook.Sheets[sheetName] = XLSX.utils.aoa_to_sheet([_this.config.headers].concat(arrayOfArrays)); //Add filters to spreadsheet. - - workbook.Sheets[sheetName]['!autofilter'] = { - ref: "A1:".concat(String.fromCharCode(64 + _this.config.cols.length)).concat(data.length + 1) - }; //Define column widths in spreadsheet. - - _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 _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]; + }); + }); // convert data from array of objects to array of arrays. + + var workbook = { + SheetNames: [sheetName], + Sheets: {} + }; + var cols = []; //Convert headers and data from array of arrays to sheet. + + workbook.Sheets[sheetName] = XLSX.utils.aoa_to_sheet( + [_this.config.headers].concat(arrayOfArrays) + ); //Add filters to spreadsheet. + + workbook.Sheets[sheetName]['!autofilter'] = { + ref: 'A1:' + .concat(String.fromCharCode(64 + _this.config.cols.length)) + .concat(data.length + 1) + }; //Define column widths in spreadsheet. + + _this.table.selectAll('thead tr th').each(function() { + cols.push({ + wpx: this.offsetWidth + }); + }); - var s2ab = function s2ab(s) { - var buffer = new ArrayBuffer(s.length), - view = new Uint8Array(buffer); + workbook.Sheets[sheetName]['!cols'] = cols; + var xlsx = XLSX.write(workbook, options); - for (var i = 0; i !== s.length; ++i) { - view[i] = s.charCodeAt(i) & 0xff; - } + var s2ab = function s2ab(s) { + var buffer = new ArrayBuffer(s.length), + view = new Uint8Array(buffer); - return buffer; - }; // convert spreadsheet to binary or something, i don't know - //Download .xlsx file. + for (var i = 0; i !== s.length; ++i) { + view[i] = s.charCodeAt(i) & 0xff; + } + return buffer; + }; // convert spreadsheet to binary or something, i don't know + //Download .xlsx file. - download.call(_this, 'xlsx', [s2ab(xlsx)]); - }); + download.call(_this, 'xlsx', [s2ab(xlsx)]); + }); } var exports$1 = { - csv: csv, - xlsx: xlsx + csv: csv, + xlsx: xlsx }; function exportable() { - return { - layout: layout$3, - exports: exports$1 - }; + 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.'); + 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)]; //Check if column is already a part of current sort order. - - var sortItem = this.sortable.order.filter(function (item) { - return item.col === col; - })[0]; //If it isn't, add it to sort order. - - 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 { - //Otherwise reverse its sort direction. - sortItem.direction = sortItem.direction === 'ascending' ? 'descending' : 'ascending'; - sortItem.wrap.select('span.sort-direction').html(sortItem.direction === 'ascending' ? '↓' : '↑'); - } //Hide sort instructions. - - - this.sortable.wrap.select('.instruction').classed('hidden', true); //Add sort container deletion functionality. - - this.sortable.order.forEach(function (item, i) { - item.wrap.on('click', function (d) { - //Remove column's sort container. - d3.select(this).remove(); //Remove column from sort. - - context.sortable.order.splice(context.sortable.order.map(function (d) { - return d.col; - }).indexOf(d.key), 1); //Display sorting instruction. - - context.sortable.wrap.select('.instruction').classed('hidden', context.sortable.order.length); //Redraw chart. - - context.draw(); - }); - }); //Redraw chart. + var context = this, + selection = d3.select(th), + col = this.config.cols[this.config.headers.indexOf(header)]; //Check if column is already a part of current sort order. + + var sortItem = this.sortable.order.filter(function(item) { + return item.col === col; + })[0]; //If it isn't, add it to sort order. + + 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 { + //Otherwise reverse its sort direction. + sortItem.direction = sortItem.direction === 'ascending' ? 'descending' : 'ascending'; + sortItem.wrap + .select('span.sort-direction') + .html(sortItem.direction === 'ascending' ? '↓' : '↑'); + } //Hide sort instructions. + + this.sortable.wrap.select('.instruction').classed('hidden', true); //Add sort container deletion functionality. + + this.sortable.order.forEach(function(item, i) { + item.wrap.on('click', function(d) { + //Remove column's sort container. + d3.select(this).remove(); //Remove column from sort. + + context.sortable.order.splice( + context.sortable.order + .map(function(d) { + return d.col; + }) + .indexOf(d.key), + 1 + ); //Display sorting instruction. + + context.sortable.wrap + .select('.instruction') + .classed('hidden', context.sortable.order.length); //Redraw chart. + + context.draw(); + }); + }); //Redraw chart. - this.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; - }; - } + 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); + 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]; + 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' && 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; - } - } + return order; }); - - return order; - }); } function sortable() { - return { - layout: layout$4, - onClick: onClick, - sortData: sortData, - order: [] - }; + return { + layout: layout$4, + onClick: onClick, + sortData: sortData, + order: [] + }; } function layout$5() { - this.pagination.wrap = this.wrap.select('.table-bottom').append('div').classed('interactivity pagination-container', true).classed('hidden', !this.config.pagination); + this.pagination.wrap = this.wrap + .select('.table-bottom') + .append('div') + .classed('interactivity pagination-container', true) + .classed('hidden', !this.config.pagination); } function updatePagination() { - var _this = this; + var _this = this; - //Reset pagination. - this.pagination.links.classed('active', false); //Set to active the selected page link. + //Reset pagination. + this.pagination.links.classed('active', false); //Set to active the selected page link. - var activePage = this.pagination.links.filter(function (link) { - return +link.rel === +_this.config.activePage; - }).classed('active', true); //Define and draw selected page. + var activePage = this.pagination.links + .filter(function(link) { + return +link.rel === +_this.config.activePage; + }) + .classed('active', true); //Define and draw selected page. - this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; - this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; //Redraw table. + this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; + this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; //Redraw table. - this.draw(); + this.draw(); } function addLinks() { - var _this = this; - - //Count rows. - this.pagination.wrap.selectAll('a,span').remove(); - - var _loop = function _loop(i) { - _this.pagination.wrap.append('a').datum({ - rel: i - }).attr({ - rel: i - }).text(i + 1).classed('wc-button page-link', true).classed('active', function (d) { - return d.rel == _this.config.activePage; - }).classed('hidden', function () { - return _this.config.activePage < _this.config.nPageLinksDisplayed ? i >= _this.config.nPageLinksDisplayed // first nPageLinksDisplayed pages - : _this.config.activePage >= _this.config.nPages - _this.config.nPageLinksDisplayed ? i < _this.config.nPages - _this.config.nPageLinksDisplayed // last nPageLinksDisplayed pages - : i < _this.config.activePage - (Math.ceil(_this.config.nPageLinksDisplayed / 2) - 1) || _this.config.activePage + _this.config.nPageLinksDisplayed / 2 < i; // nPageLinksDisplayed < activePage or activePage < (nPages - nPageLinksDisplayed) - }); - }; + var _this = this; + + //Count rows. + this.pagination.wrap.selectAll('a,span').remove(); + + var _loop = function _loop(i) { + _this.pagination.wrap + .append('a') + .datum({ + rel: i + }) + .attr({ + rel: i + }) + .text(i + 1) + .classed('wc-button page-link', true) + .classed('active', function(d) { + return d.rel == _this.config.activePage; + }) + .classed('hidden', function() { + return _this.config.activePage < _this.config.nPageLinksDisplayed + ? i >= _this.config.nPageLinksDisplayed // first nPageLinksDisplayed pages + : _this.config.activePage >= + _this.config.nPages - _this.config.nPageLinksDisplayed + ? i < _this.config.nPages - _this.config.nPageLinksDisplayed // last nPageLinksDisplayed pages + : i < + _this.config.activePage - + (Math.ceil(_this.config.nPageLinksDisplayed / 2) - 1) || + _this.config.activePage + _this.config.nPageLinksDisplayed / 2 < i; // nPageLinksDisplayed < activePage or activePage < (nPages - nPageLinksDisplayed) + }); + }; - for (var i = 0; i < this.config.nPages; i++) { - _loop(i); - } + for (var i = 0; i < this.config.nPages; i++) { + _loop(i); + } - this.pagination.links = this.pagination.wrap.selectAll('a.page-link'); + this.pagination.links = this.pagination.wrap.selectAll('a.page-link'); } function addArrows() { - var prev = this.config.activePage - 1, - next = this.config.activePage + 1; - if (prev < 0) prev = 0; // nothing before the first page + var prev = this.config.activePage - 1, + next = this.config.activePage + 1; + if (prev < 0) prev = 0; // nothing before the first page - if (next >= this.config.nPages) next = this.config.nPages - 1; // nothing after the last page + if (next >= this.config.nPages) next = this.config.nPages - 1; // nothing after the last page - /**-------------------------------------------------------------------------------------------\ + /**-------------------------------------------------------------------------------------------\ Left side \-------------------------------------------------------------------------------------------**/ - this.pagination.wrap.insert('span', ':first-child').classed('dot-dot-dot', true).text('...').classed('hidden', this.config.activePage < this.config.nPageLinksDisplayed); - this.pagination.prev = this.pagination.wrap.insert('a', ':first-child').classed('wc-button arrow-link wc-left', true).classed('hidden', this.config.activePage == 0).attr({ - rel: prev - }).text('<'); - this.pagination.doublePrev = this.pagination.wrap.insert('a', ':first-child').classed('wc-button arrow-link wc-left double', true).classed('hidden', this.config.activePage == 0).attr({ - rel: 0 - }).text('<<'); - /**-------------------------------------------------------------------------------------------\ + this.pagination.wrap + .insert('span', ':first-child') + .classed('dot-dot-dot', true) + .text('...') + .classed('hidden', this.config.activePage < this.config.nPageLinksDisplayed); + this.pagination.prev = this.pagination.wrap + .insert('a', ':first-child') + .classed('wc-button arrow-link wc-left', true) + .classed('hidden', this.config.activePage == 0) + .attr({ + rel: prev + }) + .text('<'); + this.pagination.doublePrev = this.pagination.wrap + .insert('a', ':first-child') + .classed('wc-button arrow-link wc-left double', true) + .classed('hidden', this.config.activePage == 0) + .attr({ + rel: 0 + }) + .text('<<'); + /**-------------------------------------------------------------------------------------------\ Right side \-------------------------------------------------------------------------------------------**/ - this.pagination.wrap.append('span').classed('dot-dot-dot', true).text('...').classed('hidden', this.config.activePage >= Math.max(this.config.nPageLinksDisplayed, this.config.nPages - this.config.nPageLinksDisplayed) || this.config.nPages <= this.config.nPageLinksDisplayed); - this.pagination.next = this.pagination.wrap.append('a').classed('wc-button arrow-link wc-right', true).classed('hidden', this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0).attr({ - rel: next - }).text('>'); - this.pagination.doubleNext = this.pagination.wrap.append('a').classed('wc-button arrow-link wc-right double', true).classed('hidden', this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0).attr({ - rel: this.config.nPages - 1 - }).text('>>'); - this.pagination.arrows = this.pagination.wrap.selectAll('a.arrow-link'); - this.pagination.doubleArrows = this.pagination.wrap.selectAll('a.double-arrow-link'); + this.pagination.wrap + .append('span') + .classed('dot-dot-dot', true) + .text('...') + .classed( + 'hidden', + this.config.activePage >= + Math.max( + this.config.nPageLinksDisplayed, + this.config.nPages - this.config.nPageLinksDisplayed + ) || this.config.nPages <= this.config.nPageLinksDisplayed + ); + this.pagination.next = this.pagination.wrap + .append('a') + .classed('wc-button arrow-link wc-right', true) + .classed( + 'hidden', + this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0 + ) + .attr({ + rel: next + }) + .text('>'); + this.pagination.doubleNext = this.pagination.wrap + .append('a') + .classed('wc-button arrow-link wc-right double', true) + .classed( + 'hidden', + this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0 + ) + .attr({ + rel: this.config.nPages - 1 + }) + .text('>>'); + this.pagination.arrows = this.pagination.wrap.selectAll('a.arrow-link'); + this.pagination.doubleArrows = this.pagination.wrap.selectAll('a.double-arrow-link'); } function addPagination(data) { - var context = this; //Calculate number of pages needed and create a link for each page. - - this.config.nRows = data.length; - this.config.nPages = Math.ceil(this.config.nRows / this.config.nRowsPerPage); //hide the pagination if there is only one page - - this.config.paginationHidden = this.config.nPages === 1; - this.pagination.wrap.classed('hidden', this.config.paginationHidden); //Render page links. - - addLinks.call(this); //Render a different page on click. - - this.pagination.links.on('click', function () { - context.config.activePage = +d3.select(this).attr('rel'); - updatePagination.call(context); - }); //Render arrow links. - - addArrows.call(this); //Render a different page on click. - - this.pagination.arrows.on('click', function () { - if (context.config.activePage !== +d3.select(this).attr('rel')) { - context.config.activePage = +d3.select(this).attr('rel'); - context.pagination.prev.attr('rel', context.config.activePage > 0 ? context.config.activePage - 1 : 0); - context.pagination.next.attr('rel', context.config.activePage < context.config.nPages ? context.config.activePage + 1 : context.config.nPages - 1); - updatePagination.call(context); - } - }); //Render a different page on click. + var context = this; //Calculate number of pages needed and create a link for each page. + + this.config.nRows = data.length; + this.config.nPages = Math.ceil(this.config.nRows / this.config.nRowsPerPage); //hide the pagination if there is only one page + + this.config.paginationHidden = this.config.nPages === 1; + this.pagination.wrap.classed('hidden', this.config.paginationHidden); //Render page links. + + addLinks.call(this); //Render a different page on click. + + this.pagination.links.on('click', function() { + context.config.activePage = +d3.select(this).attr('rel'); + updatePagination.call(context); + }); //Render arrow links. + + addArrows.call(this); //Render a different page on click. + + this.pagination.arrows.on('click', function() { + if (context.config.activePage !== +d3.select(this).attr('rel')) { + context.config.activePage = +d3.select(this).attr('rel'); + context.pagination.prev.attr( + 'rel', + context.config.activePage > 0 ? context.config.activePage - 1 : 0 + ); + context.pagination.next.attr( + 'rel', + context.config.activePage < context.config.nPages + ? context.config.activePage + 1 + : context.config.nPages - 1 + ); + updatePagination.call(context); + } + }); //Render a different page on click. - this.pagination.doubleArrows.on('click', function () { - context.config.activePage = +d3.select(this).attr('rel'); - updatePagination.call(context); - }); - return { - addLinks: addLinks, - addArrows: addArrows, - updatePagination: updatePagination - }; + this.pagination.doubleArrows.on('click', function() { + context.config.activePage = +d3.select(this).attr('rel'); + updatePagination.call(context); + }); + return { + addLinks: addLinks, + addArrows: addArrows, + updatePagination: updatePagination + }; } function pagination() { - this.config.nRows = this.data.raw.length; // total number of rows, i.e. the length of the data file + this.config.nRows = this.data.raw.length; // total number of rows, i.e. the length of the data file - this.config.nPages = Math.ceil(this.config.nRows / this.config.nRowsPerPage); // total number of pages given number of rows + this.config.nPages = Math.ceil(this.config.nRows / this.config.nRowsPerPage); // total number of pages given number of rows - this.config.activePage = 0; // current page, 0-indexed + this.config.activePage = 0; // current page, 0-indexed - this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; // first row shown + this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; // first row shown - this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown + this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown - this.config.paginationHidden = this.config.nPages == 1; - return { - layout: layout$5, - addPagination: addPagination - }; + this.config.paginationHidden = this.config.nPages == 1; + return { + layout: layout$5, + addPagination: addPagination + }; } function init$2(data) { - var _this = this; + var _this = this; - var test = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - this.test = test; + 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); - }); - } //Define default settings. + 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); + }); + } //Define default settings. + this.setDefaults.call(this, data[0]); //Assign classes to container element. - this.setDefaults.call(this, data[0]); //Assign classes to container element. + this.wrap.classed('wc-chart', true).classed('wc-table', this.config.applyCSS); //Define data object. - this.wrap.classed('wc-chart', true).classed('wc-table', this.config.applyCSS); //Define data object. + this.data = { + raw: data + }; //Attach searchable object to table object. - this.data = { - raw: data - }; //Attach searchable object to table object. + this.searchable = searchable.call(this); //Attach sortable object to table object. - this.searchable = searchable.call(this); //Attach sortable object to table object. + this.sortable = sortable.call(this); //Attach pagination object to table object. - this.sortable = sortable.call(this); //Attach pagination object to table object. + this.pagination = pagination.call(this); //Attach pagination object to table object. - this.pagination = pagination.call(this); //Attach pagination object to table object. + this.exportable = exportable.call(this); - this.exportable = exportable.call(this); + var startup = function startup(data) { + //connect this table and its controls, if any + if (_this.controls) { + _this.controls.targets.push(_this); - var startup = function startup(data) { - //connect this table and its controls, if any - if (_this.controls) { - _this.controls.targets.push(_this); + if (!_this.controls.ready) { + _this.controls.init(_this.data.raw); + } else { + _this.controls.layout(); + } + } //make sure container is visible (has height and width) before trying to initialize - if (!_this.controls.ready) { - _this.controls.init(_this.data.raw); - } else { - _this.controls.layout(); - } - } //make sure container is visible (has height and width) before trying to initialize + var visible = d3.select(_this.div).property('offsetWidth') > 0 || test; + if (!visible) { + console.warn( + 'The table cannot be initialized inside an element with 0 width. The table will be initialized as soon as the container element is given a width > 0.' + ); + var onVisible = setInterval(function(i) { + var visible_now = d3.select(_this.div).property('offsetWidth') > 0; - var visible = d3.select(_this.div).property('offsetWidth') > 0 || test; + if (visible_now) { + _this.layout(); - 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; + _this.wrap.datum(_this); - if (visible_now) { - _this.layout(); + _this.draw(); - _this.wrap.datum(_this); + clearInterval(onVisible); + } + }, 500); + } else { + _this.layout(); - _this.draw(); + _this.wrap.datum(_this); - clearInterval(onVisible); + _this.draw(); } - }, 500); - } else { - _this.layout(); + }; - _this.wrap.datum(_this); + this.events.onInit.call(this); - _this.draw(); + if (this.data.raw.length) { + this.checkRequired(this.data.raw); } - }; - this.events.onInit.call(this); - - if (this.data.raw.length) { - this.checkRequired(this.data.raw); - } - - startup(); - return this; + startup(); + return this; } function layout$6() { - //Clear loading indicator. - d3.select(this.div).select('.loader').remove(); //Attach container before table. + //Clear loading indicator. + d3.select(this.div) + .select('.loader') + .remove(); //Attach container before table. - this.wrap.append('div').classed('table-top', true); //Attach search container. + this.wrap.append('div').classed('table-top', true); //Attach search container. - this.searchable.layout.call(this); //Attach sort container. + this.searchable.layout.call(this); //Attach sort container. - this.sortable.layout.call(this); //Attach table to DOM. + this.sortable.layout.call(this); //Attach table to DOM. - this.table = this.wrap.append('table').classed('table', this.config.bootstrap); // apply class to incorporate bootstrap styling + this.table = this.wrap.append('table').classed('table', this.config.bootstrap); // apply class to incorporate bootstrap styling - this.thead = this.table.append('thead'); - this.thead.append('tr'); - this.tbody = this.table.append('tbody'); //Attach container after table. + this.thead = this.table.append('thead'); + this.thead.append('tr'); + this.tbody = this.table.append('tbody'); //Attach container after table. - this.wrap.append('div').classed('table-bottom', true); //Attach pagination container. + this.wrap.append('div').classed('table-bottom', true); //Attach pagination container. - this.pagination.layout.call(this); //Attach data export container. + this.pagination.layout.call(this); //Attach data export container. - this.exportable.layout.call(this); //Call layout callback. + this.exportable.layout.call(this); //Call layout callback. - this.events.onLayout.call(this); + this.events.onLayout.call(this); } function destroy$2() { - var destroyControls = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - //run onDestroy callback - this.events.onDestroy.call(this); //destroy controls + var destroyControls = + arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + //run onDestroy callback + this.events.onDestroy.call(this); //destroy controls - if (destroyControls && this.controls) { - this.controls.destroy(); - } //unmount chart wrapper + if (destroyControls && this.controls) { + this.controls.destroy(); + } //unmount chart wrapper - - this.wrap.remove(); + this.wrap.remove(); } function setDefault(setting) { - var _default_ = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var _default_ = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - this.config[setting] = this.config[setting] !== undefined ? this.config[setting] : _default_; + this.config[setting] = + this.config[setting] !== undefined ? this.config[setting] : _default_; } function setDefaults$1(firstItem) { - var _this = this; - - // 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, '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'); + var _this = this; + + // 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, '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; - - //Transform data. - this.data.processed = this.transformData(this.wrap.datum); + var _this = this; - if (!data) { - return; - } + //Transform data. + this.data.processed = this.transformData(this.wrap.datum); - 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 (!data) { + return; + } - 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; - } - }); - }); - } + this.config.cols = this.config.cols || d3.keys(data[0]); + this.config.headers = this.config.headers || this.config.cols; - 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); + if (this.config.keep) { + this.config.keep.forEach(function(e) { + if (_this.config.cols.indexOf(e) === -1) { + _this.config.cols.unshift(e); + } + }); } - var nuarr = r.map(function (m) { - var arr = []; - - for (var x in m) { - arr.push({ - col: x, - text: m[x] + 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; + } + }); }); - } + } - 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: [] - }]; // dummy nested data array - //Reset pagination. - - this.pagination.wrap.selectAll('*').remove(); - this.events.onDatatransform.call(this); - /**-------------------------------------------------------------------------------------------\ + 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: [] + } + ]; // dummy nested data array + //Reset pagination. + + this.pagination.wrap.selectAll('*').remove(); + this.events.onDatatransform.call(this); + /**-------------------------------------------------------------------------------------------\ Code below associated with the former paradigm of a d3.nest() data array. \-------------------------------------------------------------------------------------------**/ - 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]; - }); - }); - } //Delete text from columns with repeated values? - - - if (config.row_per) { - rows.filter(function (f, i) { - return i > 0; - }).selectAll('td').filter(function (f) { - return config.row_per.indexOf(f.col) > -1; - }).text(''); - } + 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]; + }); + }); + } //Delete text from columns with repeated values? + + if (config.row_per) { + rows.filter(function(f, i) { + return i > 0; + }) + .selectAll('td') + .filter(function(f) { + return config.row_per.indexOf(f.col) > -1; + }) + .text(''); + } - return this.data.current; + 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 - } + 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']; + 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() {} + }; - if (possible_events.indexOf(event) < 0) { - return; - } + thisTable.on = function(event, callback) { + var possible_events = ['init', 'layout', 'preprocess', 'draw', 'destroy']; - if (callback) { - thisTable.events['on' + event.charAt(0).toUpperCase() + event.slice(1)] = callback; - } - }; //increment thisChart count to get unique thisChart id + if (possible_events.indexOf(event) < 0) { + return; + } + 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; + 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); //Define container for legend that overrides multiples' legends. - - chart.master_legend = chart.wrap.append('ul').attr('class', 'legend'); - chart.master_legend.append('span').classed('legend-title', true); //Instantiate multiples array. - - chart.multiples = []; - - function goAhead(data) { - var split_vals = d3.set(data.map(function (m) { - return m[split_by]; - })).values().filter(function (f) { - return f; - }); + var test = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; + chart.wrap.classed('wc-layout wc-small-multiples', true).classed('wc-chart', false); //Define container for legend that overrides multiples' legends. + + chart.master_legend = chart.wrap.append('ul').attr('class', 'legend'); + chart.master_legend.append('span').classed('legend-title', true); //Instantiate multiples array. + + 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)); + }); + } - 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); - }); - } + 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); + 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; - }); + 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'; - } + 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); + 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; + return my_data; } var dataOps = { - getValType: getValType, - lengthenRaw: lengthenRaw, - naturalSorter: naturalSorter, - summarize: summarize + getValType: getValType, + lengthenRaw: lengthenRaw, + naturalSorter: naturalSorter, + summarize: summarize }; var index = { - version: version, - createChart: createChart, - createControls: createControls, - createTable: createTable, - multiply: multiply, - dataOps: dataOps + version: version, + createChart: createChart, + createControls: createControls, + createTable: createTable, + multiply: multiply, + dataOps: dataOps }; return index; - -}))); +}); diff --git a/build/webcharts.min.js b/build/webcharts.min.js index 4f79562..1f109af 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.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}); +(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){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})});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 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(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():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(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():mark.values&&mark.values[mark.split]?mark.values[mark.split]:d3.set(rawData.map(function(m){return m[mark.split]})).values().sort();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 _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")});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.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/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/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..f9b33e9 --- /dev/null +++ b/src/chart/resize/updateDataMarks/drawBars/xOrdinal.js @@ -0,0 +1,115 @@ +import { select, set, format } from 'd3'; + +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(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() + : mark.values && mark.values[mark.split] + ? mark.values[mark.split] + : set(rawData.map(m => m[mark.split])) + .values() + .sort(); + 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..808c420 --- /dev/null +++ b/src/chart/resize/updateDataMarks/drawBars/yOrdinal.js @@ -0,0 +1,116 @@ +import { select, set, format } from 'd3'; + +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(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() + : mark.values && mark.values[mark.split] + ? mark.values[mark.split] + : set(rawData.map(m => m[mark.split])) + .values() + .sort(); + 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(); + } + }); +} From 142688e6ad8fe24f38bf0ba8f4c72aa3651c37a7 Mon Sep 17 00:00:00 2001 From: Spencer Date: Fri, 13 Dec 2019 15:37:42 -0500 Subject: [PATCH 05/14] fix #206 --- build/webcharts.js | 36 +++++++++----- build/webcharts.min.js | 4 +- .../updateDataMarks/drawBars/xOrdinal.js | 14 ++++-- .../updateDataMarks/drawBars/yOrdinal.js | 16 +++++-- .../index.css => arranged-bar-chart.css} | 5 +- test-page/arranged-bar-chart.js | 47 +++++++++++++++++++ test-page/groupedBarChart/index.html | 3 +- test-page/groupedBarChart/index.js | 37 ++------------- test-page/nestedBarChart/index.css | 7 --- test-page/nestedBarChart/index.html | 11 +++-- test-page/nestedBarChart/index.js | 37 ++------------- test-page/stackedBarChart/index.css | 7 --- test-page/stackedBarChart/index.html | 7 +-- test-page/stackedBarChart/index.js | 37 ++------------- 14 files changed, 123 insertions(+), 145 deletions(-) rename test-page/{groupedBarChart/index.css => arranged-bar-chart.css} (59%) create mode 100644 test-page/arranged-bar-chart.js delete mode 100644 test-page/nestedBarChart/index.css delete mode 100644 test-page/stackedBarChart/index.css diff --git a/build/webcharts.js b/build/webcharts.js index 09b8600..088a433 100644 --- a/build/webcharts.js +++ b/build/webcharts.js @@ -1892,10 +1892,10 @@ return d.values instanceof Array ? d.values.sort(function(a, b) { return ( - _this.colorScale.domain().indexOf(b.key) - - _this.colorScale.domain().indexOf(a.key) + _this.colorScale.domain().indexOf(a.key) - + _this.colorScale.domain().indexOf(b.key) ); - }) + }) // controls the order of the bars in the DOM : [d]; }, function(d) { @@ -1915,7 +1915,13 @@ .style('clip-path', 'url(#'.concat(chart.id, ')')) .attr('y', this.y(0)) .attr('height', 0) - .append('title'); + .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(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]); @@ -1938,7 +1944,8 @@ }) ) .values() - .sort(); + .sort(); // controls the order of the bars in the chart + d3.select(this).attr(mark.attributes); }); var xformat = @@ -2031,10 +2038,10 @@ return d.values instanceof Array ? d.values.sort(function(a, b) { return ( - _this.colorScale.domain().indexOf(b.key) - - _this.colorScale.domain().indexOf(a.key) + _this.colorScale.domain().indexOf(a.key) - + _this.colorScale.domain().indexOf(b.key) ); - }) + }) // controls the order of the bars in the DOM : [d]; }, function(d) { @@ -2054,7 +2061,13 @@ .style('clip-path', 'url(#'.concat(chart.id, ')')) .attr('x', this.x(0)) .attr('width', 0) - .append('title'); + .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(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]); @@ -2064,6 +2077,7 @@ }); 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() @@ -2076,8 +2090,8 @@ }) ) .values() - .sort(); - d.tooltip = mark.tooltip; + .sort(); // controls the order of the bars in the chart + d3.select(this).attr(mark.attributes); }); var xformat = diff --git a/build/webcharts.min.js b/build/webcharts.min.js index 1f109af..a936417 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){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})});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 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(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():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(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():mark.values&&mark.values[mark.split]?mark.values[mark.split]:d3.set(rawData.map(function(m){return m[mark.split]})).values().sort();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 _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")});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.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}); +;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")});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.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/resize/updateDataMarks/drawBars/xOrdinal.js b/src/chart/resize/updateDataMarks/drawBars/xOrdinal.js index f9b33e9..a1796a1 100644 --- a/src/chart/resize/updateDataMarks/drawBars/xOrdinal.js +++ b/src/chart/resize/updateDataMarks/drawBars/xOrdinal.js @@ -1,5 +1,6 @@ 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; @@ -20,9 +21,9 @@ export default function xOrdinal(oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, return d.values instanceof Array ? d.values.sort( (a, b) => - this.colorScale.domain().indexOf(b.key) - - this.colorScale.domain().indexOf(a.key) - ) + 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 @@ -41,6 +42,11 @@ export default function xOrdinal(oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, .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])); @@ -55,7 +61,7 @@ export default function xOrdinal(oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, ? mark.values[mark.split] : set(rawData.map(m => m[mark.split])) .values() - .sort(); + .sort(); // controls the order of the bars in the chart select(this).attr(mark.attributes); }); diff --git a/src/chart/resize/updateDataMarks/drawBars/yOrdinal.js b/src/chart/resize/updateDataMarks/drawBars/yOrdinal.js index 808c420..c9c543c 100644 --- a/src/chart/resize/updateDataMarks/drawBars/yOrdinal.js +++ b/src/chart/resize/updateDataMarks/drawBars/yOrdinal.js @@ -1,5 +1,6 @@ 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; @@ -20,9 +21,9 @@ export default function yOrdinal(oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, return d.values instanceof Array ? d.values.sort( (a, b) => - this.colorScale.domain().indexOf(b.key) - - this.colorScale.domain().indexOf(a.key) - ) + 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 @@ -41,12 +42,18 @@ export default function yOrdinal(oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, .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() @@ -54,8 +61,7 @@ export default function yOrdinal(oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, ? mark.values[mark.split] : set(rawData.map(m => m[mark.split])) .values() - .sort(); - d.tooltip = mark.tooltip; + .sort(); // controls the order of the bars in the chart select(this).attr(mark.attributes); }); diff --git a/test-page/groupedBarChart/index.css b/test-page/arranged-bar-chart.css similarity index 59% rename from test-page/groupedBarChart/index.css rename to test-page/arranged-bar-chart.css index d075f13..8bad0b7 100644 --- a/test-page/groupedBarChart/index.css +++ b/test-page/arranged-bar-chart.css @@ -3,5 +3,8 @@ justify-content: space-between; } .bar-chart { - width: 50%; + 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/groupedBarChart/index.html b/test-page/groupedBarChart/index.html index 56bfa60..13aeddf 100644 --- a/test-page/groupedBarChart/index.html +++ b/test-page/groupedBarChart/index.html @@ -7,10 +7,11 @@ + - + diff --git a/test-page/groupedBarChart/index.js b/test-page/groupedBarChart/index.js index 8c7b58c..3651961 100644 --- a/test-page/groupedBarChart/index.js +++ b/test-page/groupedBarChart/index.js @@ -1,35 +1,4 @@ -const settings = { - 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: 'grouped', - }, - ], - color_by: 'AESEV', - legend: { - label: 'Severity', - order: null, - }, - resizable: false, - aspect: 2, -}; - -hSettings = JSON.parse(JSON.stringify(settings)); +hSettings = JSON.parse(JSON.stringify(settings('grouped'))); hSettings.x = hSettings.ordinal; hSettings.y = hSettings.linear; hSettings.marks[0].tooltip = '$x: $y'; @@ -39,7 +8,7 @@ const hChart = new webCharts.createChart( hSettings, ); -vSettings = JSON.parse(JSON.stringify(settings)); +vSettings = JSON.parse(JSON.stringify(settings('grouped'))); vSettings.x = vSettings.linear; vSettings.y = vSettings.ordinal; hSettings.marks[0].tooltip = '$y: $x'; @@ -56,7 +25,9 @@ d3.csv( 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.css b/test-page/nestedBarChart/index.css deleted file mode 100644 index d075f13..0000000 --- a/test-page/nestedBarChart/index.css +++ /dev/null @@ -1,7 +0,0 @@ -#container { - display: flex; - justify-content: space-between; -} -.bar-chart { - width: 50%; -} diff --git a/test-page/nestedBarChart/index.html b/test-page/nestedBarChart/index.html index 56bfa60..bbf4f5e 100644 --- a/test-page/nestedBarChart/index.html +++ b/test-page/nestedBarChart/index.html @@ -1,24 +1,25 @@ - Webcharts - Grouped Bar Chart + Webcharts - Nested Bar Chart + - +
Webcharts
-
Grouped Bar Chart
+
Nested Bar Chart
-
-
+
+
diff --git a/test-page/nestedBarChart/index.js b/test-page/nestedBarChart/index.js index 8c7b58c..29ac872 100644 --- a/test-page/nestedBarChart/index.js +++ b/test-page/nestedBarChart/index.js @@ -1,35 +1,4 @@ -const settings = { - 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: 'grouped', - }, - ], - color_by: 'AESEV', - legend: { - label: 'Severity', - order: null, - }, - resizable: false, - aspect: 2, -}; - -hSettings = JSON.parse(JSON.stringify(settings)); +hSettings = JSON.parse(JSON.stringify(settings('nested'))); hSettings.x = hSettings.ordinal; hSettings.y = hSettings.linear; hSettings.marks[0].tooltip = '$x: $y'; @@ -39,7 +8,7 @@ const hChart = new webCharts.createChart( hSettings, ); -vSettings = JSON.parse(JSON.stringify(settings)); +vSettings = JSON.parse(JSON.stringify(settings('nested'))); vSettings.x = vSettings.linear; vSettings.y = vSettings.ordinal; hSettings.marks[0].tooltip = '$y: $x'; @@ -56,7 +25,9 @@ d3.csv( 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.css b/test-page/stackedBarChart/index.css deleted file mode 100644 index d075f13..0000000 --- a/test-page/stackedBarChart/index.css +++ /dev/null @@ -1,7 +0,0 @@ -#container { - display: flex; - justify-content: space-between; -} -.bar-chart { - width: 50%; -} diff --git a/test-page/stackedBarChart/index.html b/test-page/stackedBarChart/index.html index 56bfa60..4eea172 100644 --- a/test-page/stackedBarChart/index.html +++ b/test-page/stackedBarChart/index.html @@ -1,21 +1,22 @@ - Webcharts - Grouped Bar Chart + Webcharts - Stacked Bar Chart + - +
Webcharts
-
Grouped Bar Chart
+
Stacked Bar Chart
diff --git a/test-page/stackedBarChart/index.js b/test-page/stackedBarChart/index.js index 8c7b58c..c4df51f 100644 --- a/test-page/stackedBarChart/index.js +++ b/test-page/stackedBarChart/index.js @@ -1,35 +1,4 @@ -const settings = { - 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: 'grouped', - }, - ], - color_by: 'AESEV', - legend: { - label: 'Severity', - order: null, - }, - resizable: false, - aspect: 2, -}; - -hSettings = JSON.parse(JSON.stringify(settings)); +hSettings = JSON.parse(JSON.stringify(settings('stacked'))); hSettings.x = hSettings.ordinal; hSettings.y = hSettings.linear; hSettings.marks[0].tooltip = '$x: $y'; @@ -39,7 +8,7 @@ const hChart = new webCharts.createChart( hSettings, ); -vSettings = JSON.parse(JSON.stringify(settings)); +vSettings = JSON.parse(JSON.stringify(settings('stacked'))); vSettings.x = vSettings.linear; vSettings.y = vSettings.ordinal; hSettings.marks[0].tooltip = '$y: $x'; @@ -56,7 +25,9 @@ d3.csv( return d; }, function(data) { + hChart.on('layout', onLayout); hChart.init(data); + vChart.on('layout', onLayout); vChart.init(data); } ); From 3437ef6f250a6adf73539507088ca1130c84dd74 Mon Sep 17 00:00:00 2001 From: Spencer Date: Fri, 13 Dec 2019 16:23:49 -0500 Subject: [PATCH 06/14] fix #250 --- build/webcharts.js | 36 +++++++++++----- build/webcharts.min.js | 4 +- .../resize/updateDataMarks/drawPoints.js | 26 +++++++++--- src/chart/resize/updateDataMarks/drawText.js | 14 ++++--- test-page/createChart/index.js | 42 ++++++++++++++++--- 5 files changed, 93 insertions(+), 29 deletions(-) diff --git a/build/webcharts.js b/build/webcharts.js index 088a433..dd64cc7 100644 --- a/build/webcharts.js +++ b/build/webcharts.js @@ -2579,7 +2579,7 @@ .append('circle') .attr('class', 'wc-data-mark') .attr('r', 0); - nupoints.append('title'); //static attributes + nupoints.append('title'); // static attributes points .select('circle') @@ -2593,7 +2593,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(); @@ -2601,7 +2601,7 @@ d3.select(this) .select('circle') .attr(mark.attributes); - }); //animated attributes + }); // animated attributes var pointsTrans = config.transitions ? points.select('circle').transition() @@ -2644,13 +2644,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; } @@ -2659,17 +2675,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; }, @@ -2746,9 +2762,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'); diff --git a/build/webcharts.min.js b/build/webcharts.min.js index a936417..bcb922f 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){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})});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 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")});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.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}); +;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]}).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.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/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/test-page/createChart/index.js b/test-page/createChart/index.js index 1eeb793..df0c3e0 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: [ { @@ -36,17 +38,37 @@ const controls = new webCharts.createControls( value_col: 'species', label: 'Species', }, + //{ + // type: 'radio', + // option: 'x.domain.0', + // label: 'X-domain Lower Limit', + // values: ['minimum',0], + //}, + //{ + // type: 'radio', + // option: 'y.domain.0', + // label: 'Y-domain Lower Limit', + // values: ['minimum',0], + //}, { - type: 'radio', + 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 +87,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); } ); From f7037ad794c1e87e32b608a80a83101fba169987 Mon Sep 17 00:00:00 2001 From: Spencer Date: Fri, 13 Dec 2019 17:13:38 -0500 Subject: [PATCH 07/14] fix #261 --- build/webcharts.js | 7 ++++--- build/webcharts.min.js | 6 +++--- src/chart/draw/consolidateData/setDefaults.js | 1 + src/chart/init.js | 4 ++-- src/chart/init/checkRequired.js | 2 +- test-page/createChart/index.js | 12 ------------ 6 files changed, 11 insertions(+), 21 deletions(-) diff --git a/build/webcharts.js b/build/webcharts.js index dd64cc7..74faf37 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); @@ -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; diff --git a/build/webcharts.min.js b/build/webcharts.min.js index bcb922f..5a90cbd 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){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})});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 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]}).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.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}); +(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})});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 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]}).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.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/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/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/test-page/createChart/index.js b/test-page/createChart/index.js index df0c3e0..04f42f1 100644 --- a/test-page/createChart/index.js +++ b/test-page/createChart/index.js @@ -38,18 +38,6 @@ const controls = new webCharts.createControls( value_col: 'species', label: 'Species', }, - //{ - // type: 'radio', - // option: 'x.domain.0', - // label: 'X-domain Lower Limit', - // values: ['minimum',0], - //}, - //{ - // type: 'radio', - // option: 'y.domain.0', - // label: 'Y-domain Lower Limit', - // values: ['minimum',0], - //}, { type: 'number', option: 'x.domain.0', From 8ebb0ad1e84558ed6d9f1edb251ae6148a52039f Mon Sep 17 00:00:00 2001 From: Spencer Date: Fri, 13 Dec 2019 17:34:56 -0500 Subject: [PATCH 08/14] fix #249 --- build/webcharts.js | 22 +++++++------------ build/webcharts.min.js | 6 ++--- src/chart/draw/consolidateData.js | 2 +- .../draw/consolidateData/transformData.js | 2 +- src/chart/draw/setColorScale.js | 5 ++--- src/controls/index.js | 16 +++++++------- .../makeBtnGroupControl.js | 0 .../makeCheckboxControl.js | 0 .../makeDropdownControl.js | 0 .../{ => makeControlItem}/makeListControl.js | 0 .../makeNumberControl.js | 0 .../{ => makeControlItem}/makeRadioControl.js | 0 .../makeSubsetterControl.js | 4 ++-- .../{ => makeControlItem}/makeTextControl.js | 0 14 files changed, 25 insertions(+), 32 deletions(-) rename src/controls/{ => makeControlItem}/makeBtnGroupControl.js (100%) rename src/controls/{ => makeControlItem}/makeCheckboxControl.js (100%) rename src/controls/{ => makeControlItem}/makeDropdownControl.js (100%) rename src/controls/{ => makeControlItem}/makeListControl.js (100%) rename src/controls/{ => makeControlItem}/makeNumberControl.js (100%) rename src/controls/{ => makeControlItem}/makeRadioControl.js (100%) rename src/controls/{ => makeControlItem}/makeSubsetterControl.js (96%) rename src/controls/{ => makeControlItem}/makeTextControl.js (100%) diff --git a/build/webcharts.js b/build/webcharts.js index 74faf37..c24d660 100644 --- a/build/webcharts.js +++ b/build/webcharts.js @@ -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. @@ -1116,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 @@ -1302,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)); @@ -3221,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 diff --git a/build/webcharts.min.js b/build/webcharts.min.js index 5a90cbd..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&&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})});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 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]}).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.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}); +(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/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/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/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 From 4f94d0733c942e554b32ee6e63554cf539e2207f Mon Sep 17 00:00:00 2001 From: Spencer Date: Mon, 16 Dec 2019 17:05:44 -0500 Subject: [PATCH 09/14] fix #42 --- build/webcharts.js | 55 +++++++++--------- build/webcharts.min.js | 6 +- src/chart/resize/makeLegend.js | 8 +-- .../resize/updateDataMarks/drawPoints.js | 25 +++++---- src/chart/resize/updateDataMarks/drawText.js | 10 ++-- src/table/sortable/sortData.js | 8 +-- test-page/periodicTable/index.html | 22 ++++++++ test-page/periodicTable/index.js | 56 +++++++++++++++++++ 8 files changed, 133 insertions(+), 57 deletions(-) create mode 100644 test-page/periodicTable/index.html create mode 100644 test-page/periodicTable/index.js diff --git a/build/webcharts.js b/build/webcharts.js index c24d660..132166d 100644 --- a/build/webcharts.js +++ b/build/webcharts.js @@ -1641,13 +1641,10 @@ var label = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; var custom_data = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; var config = this.config; - config.legend.mark = config.legend.mark - ? config.legend.mark - : config.marks.length && config.marks[0].type === 'bar' - ? 'square' - : config.marks.length - ? config.marks[0].type - : 'square'; + config.legend.mark = (config.legend.mark || config.marks[0].type).replace( + /bar|text/, + 'square' + ); var legend_label = label ? label : typeof config.legend.label === 'string' @@ -2654,18 +2651,19 @@ 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 - ')' - ); + if (marks.length) + 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; } @@ -2708,9 +2706,6 @@ function attachMarks(d) { d.mark = d3.select(this.parentNode).datum(); - d3.select(this) - .select('text') - .attr(d.mark.attributes); } texts.each(attachMarks); // parse text like tooltips @@ -2718,6 +2713,9 @@ texts .select('text') .style('clip-path', 'url(#'.concat(chart.id, ')')) + .attr('fill', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }) .text(function(d) { var tt = d.mark.text || ''; var xformat = @@ -2748,6 +2746,9 @@ .replace(/\[(.+?)\]/g, function(str, orig) { return d.values.raw[0][orig]; }); + }) + .each(function(d) { + d3.select(this).attr(d.mark.attributes); }); // animated attributes var textsTrans = config.transitions @@ -2761,7 +2762,7 @@ .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 its data text_supergroups.each(function(d) { d.supergroup = d3.select(this); @@ -4042,10 +4043,10 @@ 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 (order === 0) { + if (item.type === 'number') { + order = item.direction === 'ascending' ? +aCell - +bCell : +bCell - +aCell; + } else { if ( (item.direction === 'ascending' && aCell < bCell) || (item.direction === 'descending' && aCell > bCell) diff --git a/build/webcharts.min.js b/build/webcharts.min.js index 4c3c426..5df8926 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&&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}); +(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.marks[0].type).replace(/bar|text/,"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});if(marks.length)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()}texts.each(attachMarks);texts.select("text").style("clip-path","url(#".concat(chart.id,")")).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).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]})}).each(function(d){d3.select(this).attr(d.mark.attributes)});var textsTrans=config.transitions?texts.select("text").transition():texts.select("text");textsTrans.attr("x",function(d){var xPos=_this.x(d.values.x)||0;return config.x.type==="ordinal"?xPos+_this.x.rangeBand()/2:xPos}).attr("y",function(d){var yPos=_this.y(d.values.y)||0;return config.y.type==="ordinal"?yPos+_this.y.rangeBand()/2:yPos});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(order===0){if(item.type==="number"){order=item.direction==="ascending"?+aCell-+bCell:+bCell-+aCell}else{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/resize/makeLegend.js b/src/chart/resize/makeLegend.js index d0c70c6..a6d3243 100644 --- a/src/chart/resize/makeLegend.js +++ b/src/chart/resize/makeLegend.js @@ -3,13 +3,7 @@ import { ascending, select } from 'd3'; export default function makeLegend(scale = this.colorScale, label = '', custom_data = null) { let config = this.config; - config.legend.mark = config.legend.mark - ? config.legend.mark - : config.marks.length && config.marks[0].type === 'bar' - ? 'square' - : config.marks.length - ? config.marks[0].type - : 'square'; + config.legend.mark = (config.legend.mark || config.marks[0].type).replace(/bar|text/, 'square'); let legend_label = label ? label diff --git a/src/chart/resize/updateDataMarks/drawPoints.js b/src/chart/resize/updateDataMarks/drawPoints.js index 5fb75a5..96b3b05 100644 --- a/src/chart/resize/updateDataMarks/drawPoints.js +++ b/src/chart/resize/updateDataMarks/drawPoints.js @@ -107,18 +107,19 @@ export default function drawPoints(marks) { // 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 - ')' - ); + if (marks.length) + 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 3060ed0..37611cd 100644 --- a/src/chart/resize/updateDataMarks/drawText.js +++ b/src/chart/resize/updateDataMarks/drawText.js @@ -37,9 +37,6 @@ export default function drawText(marks) { // attach mark info function attachMarks(d) { d.mark = select(this.parentNode).datum(); - select(this) - .select('text') - .attr(d.mark.attributes); } texts.each(attachMarks); @@ -47,6 +44,7 @@ export default function drawText(marks) { texts .select('text') .style('clip-path', `url(#${chart.id})`) + .attr('fill', d => this.colorScale(d.values.raw[0][config.color_by])) .text(d => { const tt = d.mark.text || ''; const xformat = @@ -71,7 +69,11 @@ export default function drawText(marks) { config.y.type === 'time' ? yformat(new Date(d.values.y)) : yformat(d.values.y) ) .replace(/\[(.+?)\]/g, (str, orig) => d.values.raw[0][orig]); + }) + .each(function(d) { + select(this).attr(d.mark.attributes); }); + // animated attributes const textsTrans = config.transitions ? texts.select('text').transition() @@ -86,7 +88,7 @@ export default function drawText(marks) { 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 its data text_supergroups.each(function(d) { d.supergroup = select(this); d.groups = d.supergroup.selectAll('g.text'); diff --git a/src/table/sortable/sortData.js b/src/table/sortable/sortData.js index fcfc189..5655a70 100644 --- a/src/table/sortable/sortData.js +++ b/src/table/sortable/sortData.js @@ -8,10 +8,10 @@ export default function sortData(data) { const aCell = a[item.col]; const bCell = b[item.col]; - if (item.type === 'number') { - order = item.direction === 'ascending' ? +aCell - +bCell : +bCell - +aCell; - } else { - if (order === 0) { + if (order === 0) { + if (item.type === 'number') { + order = item.direction === 'ascending' ? +aCell - +bCell : +bCell - +aCell; + } else { if ( (item.direction === 'ascending' && aCell < bCell) || (item.direction === 'descending' && aCell > bCell) diff --git a/test-page/periodicTable/index.html b/test-page/periodicTable/index.html new file mode 100644 index 0000000..e344c9f --- /dev/null +++ b/test-page/periodicTable/index.html @@ -0,0 +1,22 @@ + + + + Webcharts - Periodic Table + + + + + + + + + + + +
Webcharts
+
Periodic Table
+
+ + + + diff --git a/test-page/periodicTable/index.js b/test-page/periodicTable/index.js new file mode 100644 index 0000000..743734e --- /dev/null +++ b/test-page/periodicTable/index.js @@ -0,0 +1,56 @@ +const settings = { + x: { + column: 'Group', + type: 'ordinal', + label: 'Group', + sort: 'alphabetical-ascending' + }, + y: { + column: 'Period', + type: 'ordinal', + label: 'Period', + sort: 'alphabetical-descending' + }, + marks: [ + { + type: 'circle', + per: [ + 'Element' + ], + radius: 14, + attributes: { + fill: 'none', + 'stroke-width': 3, + }, + }, + { + type: 'text', + per: [ + 'Element' + ], + attributes: { + dy: 5, + 'text-anchor': 'middle', + }, + text: '[Symbol]', + }, + ], + color_by: 'Group', + aspect: 3, +} + +const chart = new webCharts.createChart( + '#container', + settings, +); + +d3.csv( + 'https://cdn.jsdelivr.net/gh/RhoInc/data-library/data/miscellaneous/elements.csv', + function(d,i) { + d.seq = i; + return d; + }, + function(data) { + chart.init(data.filter(d => d.Group !== '')); + } +); From 39e39203c1107dc458af28498dd89e6e8743dc08 Mon Sep 17 00:00:00 2001 From: Spencer Date: Mon, 16 Dec 2019 18:01:49 -0500 Subject: [PATCH 10/14] refactor the turd that is makeLegend.js --- build/webcharts.js | 7064 +++++++---------- css/webcharts.css | 2 +- src/chart/resize/makeLegend.js | 140 +- src/chart/resize/makeLegend/addLegendItems.js | 22 + src/chart/resize/makeLegend/addLegendMarks.js | 48 + src/chart/resize/makeLegend/addLegendTitle.js | 9 + .../resize/makeLegend/defineLegendData.js | 16 + src/chart/resize/makeLegend/moveLegend.js | 23 + .../resize/updateDataMarks/drawPoints.js | 7 +- 9 files changed, 3008 insertions(+), 4323 deletions(-) create mode 100644 src/chart/resize/makeLegend/addLegendItems.js create mode 100644 src/chart/resize/makeLegend/addLegendMarks.js create mode 100644 src/chart/resize/makeLegend/addLegendTitle.js create mode 100644 src/chart/resize/makeLegend/defineLegendData.js create mode 100644 src/chart/resize/makeLegend/moveLegend.js diff --git a/build/webcharts.js b/build/webcharts.js index 132166d..a334abc 100644 --- a/build/webcharts.js +++ b/build/webcharts.js @@ -1,990 +1,686 @@ -(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'; +(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); - }); - } + var _this = this; - this.wrap.attr('class', 'wc-chart'); - this.setDefaults(); - this.raw_data = data; - this.initial_data = data; + var test = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; + this.test = test; - var startup = function startup(data) { - // connect this chart and its controls, if any - if (_this.controls) { - _this.controls.targets.push(_this); + 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); + }); + } - if (!_this.controls.ready) { - _this.controls.init(_this.raw_data); - } else { - _this.controls.layout(); - } - } // make sure container is visible (has height and width) before trying to initialize + this.wrap.attr('class', 'wc-chart'); + this.setDefaults(); + this.raw_data = data; + this.initial_data = data; - var visible = d3.select(_this.div).property('offsetWidth') > 0 || test; + var startup = function startup(data) { + // connect this chart and its controls, if any + if (_this.controls) { + _this.controls.targets.push(_this); - 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 (!_this.controls.ready) { + _this.controls.init(_this.raw_data); + } else { + _this.controls.layout(); + } + } // make sure container is visible (has height and width) before trying to initialize - if (visible_now) { - _this.layout(); - _this.draw(); + var visible = d3.select(_this.div).property('offsetWidth') > 0 || test; - clearInterval(onVisible); - } - }, 500); - } else { - _this.layout(); + 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; - _this.draw(); - } - }; + if (visible_now) { + _this.layout(); + + _this.draw(); - this.events.onInit.call(this); + clearInterval(onVisible); + } + }, 500); + } else { + _this.layout(); - if (this.raw_data.length) { - this.checkRequired(this.raw_data); + _this.draw(); } + }; - startup(); - return this; + 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 _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); + } - var colnames = Object.keys(data[0]); - var requiredVars = []; - var requiredCols = []; + if (this.config.y && this.config.y.column) { + requiredVars.push('this.config.y.column'); + requiredCols.push(this.config.y.column); + } - if (this.config.x && this.config.x.column) { - requiredVars.push('this.config.x.column'); - requiredCols.push(this.config.x.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 (this.config.y && this.config.y.column) { - requiredVars.push('this.config.y.column'); - requiredCols.push(this.config.y.column); + if (e.split) { + requiredVars.push('this.config.marks[' + i + '].split'); + requiredCols.push(e.split); } - if (this.config.color_by) { - requiredVars.push('this.config.color_by'); - requiredCols.push(this.config.color_by); + 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(); - 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 - }; + _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; - }) // prevent data inheritance - .attr({ - class: 'wc-svg', - xmlns: 'http://www.w3.org/2000/svg', - version: '1.1', - xlink: 'http://www.w3.org/1999/xlink' - }) - .append('g') - .style('display', 'inline-block'); + this.svg = this.wrap.append('svg').datum(function () { + return null; + }) // prevent data inheritance + .attr({ + "class": 'wc-svg', + xmlns: 'http://www.w3.org/2000/svg', + version: '1.1', + xlink: 'http://www.w3.org/1999/xlink' + }).append('g').style('display', 'inline-block'); } function addDefs() { - var defs = this.svg.append('defs'); //Add pattern. - - defs.append('pattern') - .attr({ - id: 'diagonal-stripes', - x: 0, - y: 0, - width: 3, - height: 8, - patternUnits: 'userSpaceOnUse', - patternTransform: 'rotate(30)' - }) - .append('rect') - .attr({ - x: '0', - y: '0', - width: '2', - height: '8' - }) - .style({ - stroke: 'none', - fill: 'black' - }); //Add clipPath. - - defs.append('clipPath') - .attr('id', this.id) - .append('rect') - .attr('class', 'plotting-area'); + var defs = this.svg.append('defs'); //Add pattern. + + defs.append('pattern').attr({ + id: 'diagonal-stripes', + x: 0, + y: 0, + width: 3, + height: 8, + patternUnits: 'userSpaceOnUse', + patternTransform: 'rotate(30)' + }).append('rect').attr({ + x: '0', + y: '0', + width: '2', + height: '8' + }).style({ + stroke: 'none', + fill: 'black' + }); //Add clipPath. + + defs.append('clipPath').attr('id', this.id).append('rect').attr('class', 'plotting-area'); } function addXAxis() { - this.svg - .append('g') - .attr('class', 'x axis') - .append('text') - .attr('class', 'axis-title') - .attr('dy', '-.35em') - .attr('text-anchor', 'middle'); + this.svg.append('g').attr('class', 'x axis').append('text').attr('class', 'axis-title').attr('dy', '-.35em').attr('text-anchor', 'middle'); } function addYAxis() { - this.svg - .append('g') - .attr('class', 'y axis') - .append('text') - .attr('class', 'axis-title') - .attr('transform', 'rotate(-90)') - .attr('dy', '.75em') - .attr('text-anchor', 'middle'); + this.svg.append('g').attr('class', 'y axis').append('text').attr('class', 'axis-title').attr('transform', 'rotate(-90)').attr('dy', '.75em').attr('text-anchor', 'middle'); } function addOverlay() { - this.overlay = this.svg - .append('rect') - .attr('class', 'overlay') - .attr('opacity', 0) - .attr('fill', 'none') - .style('pointer-events', 'all'); + this.overlay = this.svg.append('rect').attr('class', 'overlay').attr('opacity', 0).attr('fill', 'none').style('pointer-events', 'all'); } function addLegend() { - //The legend is contained in the parent object of multiples so each multiple does not need its own legend. - if (!this.parent) - this.wrap - .append('ul') - .datum(function() { - return null; - }) // prevent data inheritance - .attr('class', 'legend') - .style('vertical-align', 'top') - .append('span') - .attr('class', 'legend-title'); + //The legend is contained in the parent object of multiples so each multiple does not need its own legend. + if (!this.parent) this.wrap.append('ul').datum(function () { + return null; + }) // prevent data inheritance + .attr('class', 'legend').style('vertical-align', 'top').append('span').attr('class', 'legend-title'); } function clearLoader() { - d3.select(this.div) - .select('.loader') - .remove(); + 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); + 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; //if pre-processing callback, run it now - - this.events.onPreprocess.call(this); ///////////////////////// - // Data prep pipeline // - ///////////////////////// - // if user passed raw_data to chart.draw(), use that, otherwise use chart.raw_data - - var raw = raw_data ? raw_data : this.raw_data ? this.raw_data : []; // warn the user about the perils of "processed_data" - - if (processed_data) { - console.warn( - "Drawing the chart using user-defined 'processed_data', this is an experimental, untested feature." - ); - } //Call consolidateData - this applies filters from controls and prepares data for each set of marks. - - this.consolidateData(raw); ///////////////////////////// - // Prepare scales and axes // - ///////////////////////////// - - 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); - } + var _this = this; + + var chart = this; + var config = this.config; //if pre-processing callback, run it now + + this.events.onPreprocess.call(this); ///////////////////////// + // Data prep pipeline // + ///////////////////////// + // if user passed raw_data to chart.draw(), use that, otherwise use chart.raw_data + + var raw = raw_data ? raw_data : this.raw_data ? this.raw_data : []; // warn the user about the perils of "processed_data" + + if (processed_data) { + console.warn("Drawing the chart using user-defined 'processed_data', this is an experimental, untested feature."); + } //Call consolidateData - this applies filters from controls and prepares data for each set of marks. + + + this.consolidateData(raw); ///////////////////////////// + // Prepare scales and axes // + ///////////////////////////// + + 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); ////////////////////////////////////////////////////////////////////// - // Call resize - updates marks on the chart (amongst other things) // - ///////////////////////////////////////////////////////////////////// + this.events.onDraw.call(this); ////////////////////////////////////////////////////////////////////// + // Call resize - updates marks on the chart (amongst other things) // + ///////////////////////////////////////////////////////////////////// - this.resize(); + this.resize(); } function naturalSorter(a, b) { - //adapted from http://www.davekoelle.com/files/alphanum.js - 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; - } + //adapted from http://www.davekoelle.com/files/alphanum.js + 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; - return tz; + if (m !== n) { + tz[++y] = ''; + n = m; + } + + tz[y] += j; } - var aa = chunkify(a.toLowerCase()); - var bb = chunkify(b.toLowerCase()); + return tz; + } - for (var x = 0; aa[x] && bb[x]; x++) { - if (aa[x] !== bb[x]) { - var c = Number(aa[x]), - d = Number(bb[x]); + var aa = chunkify(a.toLowerCase()); + var bb = chunkify(b.toLowerCase()); - if (c == aa[x] && d == bb[x]) { - return c - d; - } else { - return aa[x] > bb[x] ? 1 : -1; - } - } + 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; + return aa.length - bb.length; } function setDomain(axis) { - var _this = this; - - var otherAxis = axis === 'x' ? 'y' : 'x'; - - if (this.config[axis].type === 'ordinal') { - //ordinal domains - if (this.config[axis].domain) { - //user-defined domain - this[axis + '_dom'] = this.config[axis].domain; - } else if (this.config[axis].order) { - //data-driven domain with user-defined domain order - this[axis + '_dom'] = d3 - .set( - d3.merge( - this.marks.map(function(mark) { - return mark[axis + '_dom']; - }) - ) - ) - .values() - .sort(function(a, b) { - return d3.ascending( - _this.config[axis].order.indexOf(a), - _this.config[axis].order.indexOf(b) - ); - }); - } else if ( - this.config[axis].sort && - this.config[axis].sort === 'alphabetical-ascending' - ) { - //data-driven domain with user-defined domain sort algorithm that sorts the axis - //alphanumerically, first to last - this[axis + '_dom'] = d3 - .set( - d3.merge( - this.marks.map(function(mark) { - return mark[axis + '_dom']; - }) - ) - ) - .values() - .sort(naturalSorter); - } else if ( - ['time', 'linear'].indexOf(this.config[otherAxis].type) > -1 && - this.config[axis].sort === 'earliest' - ) { - //data-driven domain plotted against a time or linear axis that sorts the axis values - //by earliest event/datum; generally used with timeline charts - this[axis + '_dom'] = d3 - .nest() - .key(function(d) { - return d[_this.config[axis].column]; - }) - .rollup(function(d) { - return d - .map(function(m) { - return m[_this.config[otherAxis].column]; - }) - .filter(function(f) { - return f instanceof Date; - }); - }) - .entries(this.filtered_data) - .sort(function(a, b) { - return d3.min(b.values) - d3.min(a.values); - }) - .map(function(m) { - return m.key; - }); - } else if ( - !this.config[axis].sort || - this.config[axis].sort === 'alphabetical-descending' - ) { - //data-driven domain with default/user-defined domain sort algorithm that sorts the - //axis alphanumerically, last to first - this[axis + '_dom'] = d3 - .set( - d3.merge( - this.marks.map(function(mark) { - return mark[axis + '_dom']; - }) - ) - ) - .values() - .sort(naturalSorter) - .reverse(); - } else { - //data-driven domain with an invalid user-defined sort algorithm that captures a unique - //set of values as they appear in the data - this[axis + '_dom'] = d3 - .set( - d3.merge( - this.marks.map(function(mark) { - return mark[axis + '_dom']; - }) - ) - ) - .values(); - } - } else if ( - this.config.marks - .map(function(m) { - return m['summarize' + axis.toUpperCase()] === 'percent'; - }) - .indexOf(true) > -1 - ) { - //rate domains run from 0 to 1 - this[axis + '_dom'] = [0, 1]; + var _this = this; + + var otherAxis = axis === 'x' ? 'y' : 'x'; + + if (this.config[axis].type === 'ordinal') { + //ordinal domains + if (this.config[axis].domain) { + //user-defined domain + this[axis + '_dom'] = this.config[axis].domain; + } else if (this.config[axis].order) { + //data-driven domain with user-defined domain order + this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { + return mark[axis + '_dom']; + }))).values().sort(function (a, b) { + return d3.ascending(_this.config[axis].order.indexOf(a), _this.config[axis].order.indexOf(b)); + }); + } else if (this.config[axis].sort && this.config[axis].sort === 'alphabetical-ascending') { + //data-driven domain with user-defined domain sort algorithm that sorts the axis + //alphanumerically, first to last + this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { + return mark[axis + '_dom']; + }))).values().sort(naturalSorter); + } else if (['time', 'linear'].indexOf(this.config[otherAxis].type) > -1 && this.config[axis].sort === 'earliest') { + //data-driven domain plotted against a time or linear axis that sorts the axis values + //by earliest event/datum; generally used with timeline charts + this[axis + '_dom'] = d3.nest().key(function (d) { + return d[_this.config[axis].column]; + }).rollup(function (d) { + return d.map(function (m) { + return m[_this.config[otherAxis].column]; + }).filter(function (f) { + return f instanceof Date; + }); + }).entries(this.filtered_data).sort(function (a, b) { + return d3.min(b.values) - d3.min(a.values); + }).map(function (m) { + return m.key; + }); + } else if (!this.config[axis].sort || this.config[axis].sort === 'alphabetical-descending') { + //data-driven domain with default/user-defined domain sort algorithm that sorts the + //axis alphanumerically, last to first + this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { + return mark[axis + '_dom']; + }))).values().sort(naturalSorter).reverse(); } else { - //continuous domains run from the minimum to the maximum raw (or is it summarized...?) value - //TODO: they should really run from the minimum to the maximum summarized value, e.g. a - //TODO: means over time chart should plot over the range of the means, not the range of the - //TODO: raw data - this[axis + '_dom'] = d3.extent( - d3.merge( - this.marks.map(function(mark) { - return mark[axis + '_dom']; - }) - ) - ); - } //Give the domain a range when the range of the variable is 0. - - if ( - this.config[axis].type === 'linear' && - this[axis + '_dom'][0] === this[axis + '_dom'][1] - ) - this[axis + '_dom'] = - this[axis + '_dom'][0] !== 0 - ? [ - this[axis + '_dom'][0] - this[axis + '_dom'][0] * 0.01, - this[axis + '_dom'][1] + this[axis + '_dom'][1] * 0.01 - ] - : [-1, 1]; - return this[axis + '_dom']; + //data-driven domain with an invalid user-defined sort algorithm that captures a unique + //set of values as they appear in the data + this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { + return mark[axis + '_dom']; + }))).values(); + } + } else if (this.config.marks.map(function (m) { + return m['summarize' + axis.toUpperCase()] === 'percent'; + }).indexOf(true) > -1) { + //rate domains run from 0 to 1 + this[axis + '_dom'] = [0, 1]; + } else { + //continuous domains run from the minimum to the maximum raw (or is it summarized...?) value + //TODO: they should really run from the minimum to the maximum summarized value, e.g. a + //TODO: means over time chart should plot over the range of the means, not the range of the + //TODO: raw data + this[axis + '_dom'] = d3.extent(d3.merge(this.marks.map(function (mark) { + return mark[axis + '_dom']; + }))); + } //Give the domain a range when the range of the variable is 0. + + + if (this.config[axis].type === 'linear' && this[axis + '_dom'][0] === this[axis + '_dom'][1]) this[axis + '_dom'] = this[axis + '_dom'][0] !== 0 ? [this[axis + '_dom'][0] - this[axis + '_dom'][0] * 0.01, this[axis + '_dom'][1] + this[axis + '_dom'][1] * 0.01] : [-1, 1]; + return this[axis + '_dom']; } function consolidateData(raw) { - var _this = this; + var _this = this; - this.setDefaults(); //Apply filters from associated controls objects to raw data. + this.setDefaults(); //Apply filters from associated controls objects to raw data. - this.filtered_data = raw; + 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 + ''; - }); - }); - } //Summarize data for each mark. + 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 + ''; + }); + }); + } //Summarize data for each mark. - 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); - }); //Set domains given extents of summarized mark data. - - setDomain.call(this, 'x'); - setDomain.call(this, 'y'); + 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); + }); //Set domains given extents of summarized mark data. + + 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 : 0.3; - this.config.outer_pad = this.config.outer_pad !== undefined ? this.config.outer_pad : 0.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; + 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 : 0.3; + this.config.outer_pad = this.config.outer_pad !== undefined ? this.config.outer_pad : 0.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 _this = this; - var dateConvert = d3.time.format(this.config.date_format); - var clean = raw; // only use data for the current mark + var dateConvert = d3.time.format(this.config.date_format); + var clean = raw; // only use data for the current mark - clean = - mark.per && mark.per.length - ? clean.filter(function(f) { - return f[mark.per[0]] !== undefined; - }) - : clean; // Make sure data has x and y values + clean = mark.per && mark.per.length ? clean.filter(function (f) { + return f[mark.per[0]] !== undefined; + }) : clean; // Make sure data has x and y values - if (this.config.x.column) { - clean = clean.filter(function(f) { - return [undefined, null].indexOf(f[_this.config.x.column]) < 0; - }); - } + 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; - }); - } //check that x and y have the correct formats + if (this.config.y.column) { + clean = clean.filter(function (f) { + return [undefined, null].indexOf(f[_this.config.y.column]) < 0; + }); + } //check that x and y have the correct formats - if (this.config.x.type === 'time') { - clean = clean.filter(function(f) { - return f[_this.config.x.column] instanceof Date - ? f[_this.config.x.column] - : dateConvert.parse(f[_this.config.x.column]); - }); - clean.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 === '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.x.type === 'linear' || this.config.x.type === 'log') && - this.config.x.column - ) { - clean = clean.filter(function(f) { - return mark.summarizeX !== 'count' && mark.summarizeX !== 'percent' - ? !(isNaN(f[_this.config.x.column]) || /^\s*$/.test(f[_this.config.x.column])) // is or coerces to a number and is not a string that coerces to 0 - : f; - }); - } + if (this.config.y.type === '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.y.type === 'linear' || this.config.y.type === 'log') && - this.config.y.column - ) { - clean = clean.filter(function(f) { - return mark.summarizeY !== 'count' && mark.summarizeY !== 'percent' - ? !(isNaN(f[_this.config.y.column]) || /^\s*$/.test(f[_this.config.y.column])) // is or coerces to a number and is not a string that coerces to 0 - : f; - }); - } + if ((this.config.x.type === 'linear' || this.config.x.type === 'log') && this.config.x.column) { + clean = clean.filter(function (f) { + return mark.summarizeX !== 'count' && mark.summarizeX !== 'percent' ? !(isNaN(f[_this.config.x.column]) || /^\s*$/.test(f[_this.config.x.column])) // is or coerces to a number and is not a string that coerces to 0 + : f; + }); + } - return clean; + if ((this.config.y.type === 'linear' || this.config.y.type === 'log') && this.config.y.column) { + clean = clean.filter(function (f) { + return mark.summarizeY !== 'count' && mark.summarizeY !== 'percent' ? !(isNaN(f[_this.config.y.column]) || /^\s*$/.test(f[_this.config.y.column])) // is or coerces to a number and is not a string that coerces to 0 + : f; + }); + } + + return clean; } var stats = { - mean: d3.mean, - min: d3.min, - max: d3.max, - median: d3.median, - sum: d3.sum + 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; - }); + 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; - } + if (operation === 'cumulative') { + return null; + } - var mathed = - operation === 'count' - ? vals.length - : operation === 'percent' - ? vals.length - : stats[operation](nvals); - return mathed; + 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; - }); - } + 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(' '); + }); + } - this_nest.rollup(function(r) { - var obj = { - raw: r - }; - var y_vals = r - .map(function(m) { - return m[_this.config.y.column]; - }) - .sort(d3.ascending); - var x_vals = r - .map(function(m) { - return m[_this.config.x.column]; - }) - .sort(d3.ascending); - obj.x = - _this.config.x.type === 'ordinal' - ? r[0][_this.config.x.column] - : summarize(x_vals, mark.summarizeX); - obj.y = - _this.config.y.type === 'ordinal' - ? r[0][_this.config.y.column] - : summarize(y_vals, mark.summarizeY); - obj.x_q25 = - _this.config.error_bars && _this.config.y.type === 'ordinal' - ? d3.quantile(x_vals, 0.25) - : obj.x; - obj.x_q75 = - _this.config.error_bars && _this.config.y.type === 'ordinal' - ? d3.quantile(x_vals, 0.75) - : obj.x; - obj.y_q25 = _this.config.error_bars ? d3.quantile(y_vals, 0.25) : obj.y; - obj.y_q75 = _this.config.error_bars ? d3.quantile(y_vals, 0.75) : obj.y; - dom_xs.push([obj.x_q25, obj.x_q75, obj.x]); - dom_ys.push([obj.y_q25, obj.y_q75, obj.y]); - - if (mark.summarizeY === 'cumulative') { - var interm = entries.filter(function(f) { - return _this.config.x.type === 'time' - ? new Date(f[_this.config.x.column]) <= - new Date(r[0][_this.config.x.column]) - : +f[_this.config.x.column] <= +r[0][_this.config.x.column]; - }); - - 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 (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; + }); + } - 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; + this_nest.rollup(function (r) { + var obj = { + raw: r + }; + var y_vals = r.map(function (m) { + return m[_this.config.y.column]; + }).sort(d3.ascending); + var x_vals = r.map(function (m) { + return m[_this.config.x.column]; + }).sort(d3.ascending); + obj.x = _this.config.x.type === 'ordinal' ? r[0][_this.config.x.column] : summarize(x_vals, mark.summarizeX); + obj.y = _this.config.y.type === 'ordinal' ? r[0][_this.config.y.column] : summarize(y_vals, mark.summarizeY); + obj.x_q25 = _this.config.error_bars && _this.config.y.type === 'ordinal' ? d3.quantile(x_vals, 0.25) : obj.x; + obj.x_q75 = _this.config.error_bars && _this.config.y.type === 'ordinal' ? d3.quantile(x_vals, 0.75) : obj.x; + obj.y_q25 = _this.config.error_bars ? d3.quantile(y_vals, 0.25) : obj.y; + obj.y_q75 = _this.config.error_bars ? d3.quantile(y_vals, 0.75) : obj.y; + dom_xs.push([obj.x_q25, obj.x_q75, obj.x]); + dom_ys.push([obj.y_q25, obj.y_q75, obj.y]); + + if (mark.summarizeY === 'cumulative') { + var interm = entries.filter(function (f) { + return _this.config.x.type === 'time' ? new Date(f[_this.config.x.column]) <= new Date(r[0][_this.config.x.column]) : +f[_this.config.x.column] <= +r[0][_this.config.x.column]; + }); + + 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) { + //calculate percentages in bars + test.forEach(function (e) { + var axis = _this.config.x.type === 'ordinal' || _this.config.x.type === 'linear' && _this.config.x.bin ? 'y' : 'x'; + e.total = d3.sum(e.values.map(function (m) { + return +m.values[axis]; + })); + 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; } - - 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) { - //calculate percentages in bars - test.forEach(function(e) { - var axis = - _this.config.x.type === 'ordinal' || - (_this.config.x.type === 'linear' && _this.config.x.bin) - ? 'y' - : 'x'; - e.total = d3.sum( - e.values.map(function(m) { - return +m.values[axis]; - }) - ); - 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 (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; - }); - } + 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 - }; + return { + nested: test, + dom_x: dom_x, + dom_y: dom_y, + totalOrder: totalOrder + }; } // transformData(raw, mark) provides specifications and data for @@ -998,3730 +694,2688 @@ //////////////////////////////////////////////////////// function transformData(raw, mark) { - var _this = this; - - //convenience mappings - 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; ////////////////////////////////////////////////////////////////////////////////// - // DATA PREP - // prepare data based on the properties of the mark - drop missing records, etc - ////////////////////////////////////////////////////////////////////////////////// - - var cleaned = cleanData.call(this, mark, raw); //prepare nested data required for bar charts - - 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); - } // Get the domain for the mark based on the raw data - - var raw_dom_x = - mark.summarizeX === 'cumulative' - ? [0, cleaned.length] - : config.x.type === 'ordinal' - ? d3 - .set( - cleaned.map(function(m) { - return m[config.x.column]; - }) - ) - .values() - .filter(function(f) { - return f; - }) - : mark.split && mark.arrange !== 'stacked' - ? d3.extent( - d3.merge( - raw_nest.nested.map(function(m) { - return m.values.map(function(p) { - return p.values.raw.length; - }); - }) - ) - ) - : mark.summarizeX === 'count' - ? d3.extent( - raw_nest.nested.map(function(m) { - return m.values.raw.length; - }) - ) - : d3.extent( - cleaned - .map(function(m) { - return +m[config.x.column]; - }) - .filter(function(f) { - return +f || +f === 0; - }) - ); - var raw_dom_y = - mark.summarizeY === 'cumulative' - ? [0, cleaned.length] - : config.y.type === 'ordinal' - ? d3 - .set( - cleaned.map(function(m) { - return m[config.y.column]; - }) - ) - .values() - .filter(function(f) { - return f; - }) - : mark.split && mark.arrange !== 'stacked' - ? d3.extent( - d3.merge( - raw_nest.nested.map(function(m) { - return m.values.map(function(p) { - return p.values.raw.length; - }); - }) - ) - ) - : mark.summarizeY === 'count' - ? d3.extent( - raw_nest.nested.map(function(m) { - return m.values.raw.length; - }) - ) - : d3.extent( - cleaned - .map(function(m) { - return +m[config.y.column]; - }) - .filter(function(f) { - return +f || +f === 0; - }) - ); - var 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() + ''; - }); - }); //get domain for all non-All values of first filter - - if (config.x.behavior === 'firstfilter' || config.y.behavior === 'firstfilter') { - this.filters[0].choices - .filter(function(f) { - return f !== 'All'; - }) - .forEach(function(e) { - var perfilter = cleaned.filter(function(f) { - return f[_this.filters[0].col] === e; - }); - var filt_nested = makeNest.call(_this, mark, perfilter, sublevel); - filt1_xs.push(filt_nested.dom_x); - filt1_ys.push(filt_nested.dom_y); - }); - } - } //filter on mark-specific instructions - - 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]; - } - } //several criteria must be met in order to use the 'firstfilter' domain - - var nonall = Boolean( - this.filters.length && - this.filters[0].val !== 'All' && - this.filters.slice(1).filter(function(f) { - return f.val === 'All'; - }).length === - this.filters.length - 1 - ); - var pre_x_dom = !this.filters.length - ? flex_dom_x - : x_behavior === 'raw' - ? raw_dom_x - : nonall && x_behavior === 'firstfilter' - ? filt1_dom_x - : flex_dom_x; - var pre_y_dom = !this.filters.length - ? flex_dom_y - : y_behavior === 'raw' - ? raw_dom_y - : nonall && y_behavior === 'firstfilter' - ? filt1_dom_y - : flex_dom_y; - var x_dom = config.x_dom - ? config.x_dom - : config.x.type === 'ordinal' && config.x.behavior === 'flex' - ? d3 - .set( - filtered.map(function(m) { - return m[config.x.column]; - }) - ) - .values() - : config.x.type === 'ordinal' - ? d3 - .set( - cleaned.map(function(m) { - return m[config.x.column]; - }) - ) - .values() - : pre_x_dom; - var y_dom = config.y_dom - ? config.y_dom - : config.y.type === 'ordinal' && config.y.behavior === 'flex' - ? d3 - .set( - filtered.map(function(m) { - return m[config.y.column]; - }) - ) - .values() - : config.y.type === 'ordinal' - ? d3 - .set( - cleaned.map(function(m) { - return m[config.y.column]; - }) - ) - .values() - : pre_y_dom; //set lower limit of linear domain to 0 when other axis is ordinal and mark type is set to 'bar', provided no values are negative - - if (mark.type === 'bar') { - if ( - config.x.behavior !== 'flex' && - config.x.type === 'linear' && - config.y.type === 'ordinal' && - raw_dom_x[0] >= 0 - ) - x_dom[0] = 0; - if ( - config.y.behavior !== 'flex' && - config.x.type === 'ordinal' && - config.y.type === 'linear' && - raw_dom_y[0] >= 0 - ) - y_dom[0] = 0; - } //update domains with those specified in the config - - if ( - config.x.domain && - (config.x.domain[0] || config.x.domain[0] === 0) && - !isNaN(+config.x.domain[0]) - ) { - 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 + var _this = this; + + //convenience mappings + 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; ////////////////////////////////////////////////////////////////////////////////// + // DATA PREP + // prepare data based on the properties of the mark - drop missing records, etc + ////////////////////////////////////////////////////////////////////////////////// + + var cleaned = cleanData.call(this, mark, raw); //prepare nested data required for bar charts + + 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); + } // Get the domain for the mark based on the raw data + + + var raw_dom_x = mark.summarizeX === 'cumulative' ? [0, cleaned.length] : config.x.type === 'ordinal' ? d3.set(cleaned.map(function (m) { + return m[config.x.column]; + })).values().filter(function (f) { + return f; + }) : mark.split && mark.arrange !== 'stacked' ? d3.extent(d3.merge(raw_nest.nested.map(function (m) { + return m.values.map(function (p) { + return p.values.raw.length; + }); + }))) : mark.summarizeX === 'count' ? d3.extent(raw_nest.nested.map(function (m) { + return m.values.raw.length; + })) : d3.extent(cleaned.map(function (m) { + return +m[config.x.column]; + }).filter(function (f) { + return +f || +f === 0; + })); + var raw_dom_y = mark.summarizeY === 'cumulative' ? [0, cleaned.length] : config.y.type === 'ordinal' ? d3.set(cleaned.map(function (m) { + return m[config.y.column]; + })).values().filter(function (f) { + return f; + }) : mark.split && mark.arrange !== 'stacked' ? d3.extent(d3.merge(raw_nest.nested.map(function (m) { + return m.values.map(function (p) { + return p.values.raw.length; + }); + }))) : mark.summarizeY === 'count' ? d3.extent(raw_nest.nested.map(function (m) { + return m.values.raw.length; + })) : d3.extent(cleaned.map(function (m) { + return +m[config.y.column]; + }).filter(function (f) { + return +f || +f === 0; + })); + var 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() + ''; + }); + }); //get domain for all non-All values of first filter + + if (config.x.behavior === 'firstfilter' || config.y.behavior === 'firstfilter') { + this.filters[0].choices.filter(function (f) { + return f !== 'All'; + }).forEach(function (e) { + var perfilter = cleaned.filter(function (f) { + return f[_this.filters[0].col] === e; + }); + var filt_nested = makeNest.call(_this, mark, perfilter, sublevel); + filt1_xs.push(filt_nested.dom_x); + filt1_ys.push(filt_nested.dom_y); + }); + } + } //filter on mark-specific instructions + + + 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]; + } + } //several criteria must be met in order to use the 'firstfilter' domain + + + var nonall = Boolean(this.filters.length && this.filters[0].val !== 'All' && this.filters.slice(1).filter(function (f) { + return f.val === 'All'; + }).length === this.filters.length - 1); + var pre_x_dom = !this.filters.length ? flex_dom_x : x_behavior === 'raw' ? raw_dom_x : nonall && x_behavior === 'firstfilter' ? filt1_dom_x : flex_dom_x; + var pre_y_dom = !this.filters.length ? flex_dom_y : y_behavior === 'raw' ? raw_dom_y : nonall && y_behavior === 'firstfilter' ? filt1_dom_y : flex_dom_y; + var x_dom = config.x_dom ? config.x_dom : config.x.type === 'ordinal' && config.x.behavior === 'flex' ? d3.set(filtered.map(function (m) { + return m[config.x.column]; + })).values() : config.x.type === 'ordinal' ? d3.set(cleaned.map(function (m) { + return m[config.x.column]; + })).values() : pre_x_dom; + var y_dom = config.y_dom ? config.y_dom : config.y.type === 'ordinal' && config.y.behavior === 'flex' ? d3.set(filtered.map(function (m) { + return m[config.y.column]; + })).values() : config.y.type === 'ordinal' ? d3.set(cleaned.map(function (m) { + return m[config.y.column]; + })).values() : pre_y_dom; //set lower limit of linear domain to 0 when other axis is ordinal and mark type is set to 'bar', provided no values are negative + + if (mark.type === 'bar') { + if (config.x.behavior !== 'flex' && config.x.type === 'linear' && config.y.type === 'ordinal' && raw_dom_x[0] >= 0) x_dom[0] = 0; + if (config.y.behavior !== 'flex' && config.x.type === 'ordinal' && config.y.type === 'linear' && raw_dom_y[0] >= 0) y_dom[0] = 0; + } //update domains with those specified in the config + + + if (config.x.domain && (config.x.domain[0] || config.x.domain[0] === 0) && !isNaN(+config.x.domain[0])) { + 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(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)); - }); - else colordom.sort(naturalSorter); - this.colorScale = d3.scale - .ordinal() - .domain(colordom) - .range(config.colors); + 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(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)); + });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; + 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; + 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 < max_width - ? div_width - : this.raw_width; - this.textSize(preWidth); - this.margin = this.setMargins(); - var svg_width = - config.x.type === 'ordinal' && +config.x.range_band - ? this.raw_width + this.margin.left + this.margin.right - : !config.resizable - ? this.raw_width - : !config.max_width || div_width < config.max_width - ? div_width - : this.raw_width; - this.plot_width = svg_width - this.margin.left - this.margin.right; - var svg_height = - config.y.type === 'ordinal' && +config.y.range_band - ? this.raw_height + this.margin.top + this.margin.bottom - : !config.resizable && config.height - ? config.height - : !config.resizable - ? svg_width * aspect2 - : this.plot_width * aspect2; - this.plot_height = svg_height - this.margin.top - this.margin.bottom; - d3.select(this.svg.node().parentNode) - .attr('width', svg_width) - .attr('height', svg_height) - .select('g') - .attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')'); - this.svg - .select('.overlay') - .attr('width', this.plot_width) - .attr('height', this.plot_height) - .classed('zoomable', config.zoomable); - this.svg - .select('.plotting-area') - .attr('width', this.plot_width) - .attr('height', this.plot_height + 1) - .attr('transform', 'translate(0, -1)'); - this.xScaleAxis(); - this.yScaleAxis(); - var g_x_axis = this.svg.select('.x.axis'); - var g_y_axis = this.svg.select('.y.axis'); - var x_axis_label = g_x_axis.select('.axis-title'); - var y_axis_label = g_y_axis.select('.axis-title'); - - if (config.x_location !== 'top') { - g_x_axis.attr('transform', 'translate(0,' + this.plot_height + ')'); - } - - var gXAxisTrans = config.transitions ? g_x_axis.transition() : g_x_axis; - gXAxisTrans.call(this.xAxis); - var gYAxisTrans = config.transitions ? g_y_axis.transition() : g_y_axis; - gYAxisTrans.call(this.yAxis); - x_axis_label.attr( - 'transform', - 'translate(' + this.plot_width / 2 + ',' + (this.margin.bottom - 2) + ')' - ); - y_axis_label.attr('x', (-1 * this.plot_height) / 2).attr('y', -1 * this.margin.left); - this.svg.selectAll('.axis .domain').attr({ - fill: 'none', - stroke: '#ccc', - 'stroke-width': 1, - 'shape-rendering': 'crispEdges' - }); - this.svg.selectAll('.axis .tick line').attr({ - stroke: '#eee', - 'stroke-width': 1, - 'shape-rendering': 'crispEdges' - }); - this.drawGridlines(); //update legend - margins need to be set first - - this.makeLegend(); //update the chart's specific marks - - this.updateDataMarks(); //call .on("resize") function, if any - - this.events.onResize.call(this); + 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 < max_width ? div_width : this.raw_width; + this.textSize(preWidth); + this.margin = this.setMargins(); + var svg_width = config.x.type === 'ordinal' && +config.x.range_band ? this.raw_width + this.margin.left + this.margin.right : !config.resizable ? this.raw_width : !config.max_width || div_width < config.max_width ? div_width : this.raw_width; + this.plot_width = svg_width - this.margin.left - this.margin.right; + var svg_height = config.y.type === 'ordinal' && +config.y.range_band ? this.raw_height + this.margin.top + this.margin.bottom : !config.resizable && config.height ? config.height : !config.resizable ? svg_width * aspect2 : this.plot_width * aspect2; + this.plot_height = svg_height - this.margin.top - this.margin.bottom; + d3.select(this.svg.node().parentNode).attr('width', svg_width).attr('height', svg_height).select('g').attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')'); + this.svg.select('.overlay').attr('width', this.plot_width).attr('height', this.plot_height).classed('zoomable', config.zoomable); + this.svg.select('.plotting-area').attr('width', this.plot_width).attr('height', this.plot_height + 1).attr('transform', 'translate(0, -1)'); + this.xScaleAxis(); + this.yScaleAxis(); + var g_x_axis = this.svg.select('.x.axis'); + var g_y_axis = this.svg.select('.y.axis'); + var x_axis_label = g_x_axis.select('.axis-title'); + var y_axis_label = g_y_axis.select('.axis-title'); + + if (config.x_location !== 'top') { + g_x_axis.attr('transform', 'translate(0,' + this.plot_height + ')'); + } + + var gXAxisTrans = config.transitions ? g_x_axis.transition() : g_x_axis; + gXAxisTrans.call(this.xAxis); + var gYAxisTrans = config.transitions ? g_y_axis.transition() : g_y_axis; + gYAxisTrans.call(this.yAxis); + x_axis_label.attr('transform', 'translate(' + this.plot_width / 2 + ',' + (this.margin.bottom - 2) + ')'); + y_axis_label.attr('x', -1 * this.plot_height / 2).attr('y', -1 * this.margin.left); + this.svg.selectAll('.axis .domain').attr({ + fill: 'none', + stroke: '#ccc', + 'stroke-width': 1, + 'shape-rendering': 'crispEdges' + }); + this.svg.selectAll('.axis .tick line').attr({ + stroke: '#eee', + 'stroke-width': 1, + 'shape-rendering': 'crispEdges' + }); + this.drawGridlines(); //update legend - margins need to be set first + + this.makeLegend(); //update the chart's specific marks + + this.updateDataMarks(); //call .on("resize") function, if any + + this.events.onResize.call(this); } function textSize(width) { - var font_size = '14px'; - var point_size = 4; - var stroke_width = 2; - - if (!this.config.scale_text) { - font_size = this.config.font_size; - point_size = this.config.point_size || 4; - stroke_width = this.config.stroke_width || 2; - } else if (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; + var font_size = '14px'; + var point_size = 4; + var stroke_width = 2; + + if (!this.config.scale_text) { + font_size = this.config.font_size; + point_size = this.config.point_size || 4; + stroke_width = this.config.stroke_width || 2; + } else if (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 : 0.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 * 0.5 + font_size * y_label_on * 1.5 || 8; - var x_margin = - font_size + font_size / 1.5 + font_size * x_label_on + font_size * x_second || 8; - 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 - }; + 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 : 0.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 * 0.5 + font_size * y_label_on * 1.5 || 8; + var x_margin = font_size + font_size / 1.5 + font_size * x_label_on + font_size * x_second || 8; + 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); + 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 moveLegend() { + var legend = this.wrap.select('.legend'); + + if (!this.parent) { + //singular chart + if (this.config.legend.location === 'top' || this.config.legend.location === 'left') { + this.wrap.node().insertBefore(legend.node(), this.svg.node().parentNode); } else { - this.svg - .select('.y.axis') - .selectAll('.tick line') - .attr('x1', 0); - this.svg - .select('.x.axis') - .selectAll('.tick line') - .attr('y1', 0); + this.wrap.node().appendChild(legend.node()); } - } - - 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.marks[0].type).replace( - /bar|text/, - '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) { - //singular chart - 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 { + //multiples - keep legend outside of individual charts' wraps + if (this.config.legend.location === 'top' || this.config.legend.location === 'left') { + this.parent.wrap.node().insertBefore(legend.node(), this.parent.wrap.select('.wc-chart').node()); } else { - //multiples - keep legend outside of individual charts' wraps - if (this.config.legend.location === 'top' || this.config.legend.location === 'left') { - this.parent.wrap - .node() - .insertBefore( - legendOriginal.node(), - this.parent.wrap.select('.wc-chart').node() - ); - } else { - this.parent.wrap.node().appendChild(legendOriginal.node()); - } + this.parent.wrap.node().appendChild(legend.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) - ); - }); + return this.legend || legend; + } + + function defineLegendData(custom_data, scale) { + var _this = this; + + var legend_data = Array.isArray(custom_data) && custom_data.length ? custom_data : scale.domain().slice(0).filter(function (f) { + return f !== undefined && f !== null; + }).map(function (m) { + return { + label: m, + mark: _this.config.legend.mark + }; + }); + return legend_data; + } + + function addLegendTitle(legend_label) { + var legend_title = this.legend.select('.legend-title').text(legend_label).style('display', legend_label ? 'inline' : 'none').style('margin-right', '1em'); + return legend_title; + } + + function addLegendItems(leg_parts, scale) { + 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' + }); + return new_parts; + } + + function addLegendMarks(leg_parts, scale) { + 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); + }); + } - 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' - }); - } + function makeLegend() { + var _this = this; + + 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; + // should the legend be moved on layout? + this.legend = moveLegend.call(this); // determine appropriate legend mark type + + this.config.legend.mark = (this.config.legend.mark || this.config.marks[0].type).replace(/bar|text/, 'square'); + var legend_label = label || this.config.legend.label || ''; + var legend_data = defineLegendData.call(this, custom_data, scale); + var legend_title = addLegendTitle.call(this, legend_label); + var legend_items = this.legend.selectAll('.legend-item').data(legend_data, function (d) { + return d.label + d.mark; + }); + legend_items.exit().remove(); + var legendPartDisplay = this.config.legend.location === 'bottom' || this.config.legend.location === 'top' ? 'inline-block' : 'block'; + var new_parts = addLegendItems.call(this, legend_items, scale); + legend_items.style('display', legendPartDisplay); + + if (this.config.legend.order) { + legend_items.sort(function (a, b) { + return d3.ascending(_this.config.legend.order.indexOf(a.label), _this.config.legend.order.indexOf(b.label)); }); - 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'); - } + var legend_marks = addLegendMarks.call(this, legend_items, scale); + new_parts.append('span').attr('class', 'legend-label').style('margin-left', '0.25em').text(function (d) { + return d.label; + }); - this.legend = legend; + if (scale.domain().length > 0) { + var legendDisplay = (this.config.legend.location === 'bottom' || this.config.legend.location === 'top') && !this.parent ? 'block' : 'inline-block'; + this.legend.style('display', legendDisplay); + } else { + this.legend.style('display', 'none'); + } } 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'); + 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 - : 0.3 - ); //don't transition if config says not to - - var areaPathTransitions = this.config.transitions ? areaPaths.transition() : areaPaths; - areaPathTransitions.attr('d', area_drawer); - return area_grps; + 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 : 0.3); //don't transition if config says not to + + 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) - ); - }) // 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('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 - - bars.sort(function(a, b) { - return ( - _this.colorScale.domain().indexOf(a.key) - _this.colorScale.domain().indexOf(b.key) - ); + 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); + }) // 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('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 + + 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 + + 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]); - }); - 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 - - 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 * 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); - }); + }); + 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); + }); } 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 - - 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 - - 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 _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 + + 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 + + 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 * 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); - - 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 barsTrans = config.transitions ? bars.transition() : bars; + barsTrans.attr('x', function (d) { + if (d.arrange === 'stacked' || !d.arrange) { + return d.values.start !== undefined ? _this.x(d.values.start) : _this.x(0); + } else { + return _this.x(0); + } + }).attr('y', function (d) { + if (d.arrange === 'nested') { + var position = d.subcats.indexOf(d.key); + var offset = position ? _this.y.rangeBand() / (d.subcats.length * 0.75) / position : _this.y.rangeBand(); + return _this.y(d.values.y) + (_this.y.rangeBand() - offset) / 2; + } else if (d.arrange === 'grouped') { + var _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 * 0.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 _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; }); - 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]; - }); + 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); - }); + }); + 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 _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; }); - 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]; - }); + 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); - }); + }); + 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; // bar super-groups + var rawData = this.raw_data; + var config = this.config; // bar super-groups + + 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 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 + + 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(); + } //Link to the d3.selection from the data - 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 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 - - 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(); - } //Link to the d3.selection from the data - - bar_supergroups.each(function(d) { - d.supergroup = d3.select(this); - d.groups = d.supergroup.selectAll('.bar-group'); - }); + + 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); + 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_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]; - }); - }); //Link to the d3.selection from the data - - 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; + }); //Link to the d3.selection from the data + + 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'); // static attributes - - points - .select('circle') - .style('clip-path', 'url(#'.concat(chart.id, ')')) - .attr( - 'fill-opacity', - config.fill_opacity || config.fill_opacity === 0 ? config.fill_opacity : 0.6 - ) - .attr('fill', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }) - .attr('stroke', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); // attach mark info - - points.each(function(d) { - var mark = d3.select(this.parentNode).datum(); - d.mark = mark; - d3.select(this) - .select('circle') - .attr(mark.attributes); - }); // animated attributes - - var pointsTrans = config.transitions - ? points.select('circle').transition() - : points.select('circle'); - pointsTrans - .attr('r', function(d) { - return d.mark.radius || config.flex_point_size; - }) - .attr('cx', function(d) { - var x_pos = _this.x(d.values.x) || 0; - return config.x.type === 'ordinal' ? x_pos + _this.x.rangeBand() / 2 : x_pos; - }) - .attr('cy', function(d) { - var y_pos = _this.y(d.values.y) || 0; - return config.y.type === 'ordinal' ? y_pos + _this.y.rangeBand() / 2 : y_pos; - }); - 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]; - }); - }); // 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; + 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'); // static attributes + + points.select('circle').style('clip-path', "url(#".concat(chart.id, ")")).attr('fill-opacity', config.fill_opacity || config.fill_opacity === 0 ? config.fill_opacity : 0.6).attr('fill', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }).attr('stroke', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); // attach mark info + + points.each(function (d) { + var mark = d3.select(this.parentNode).datum(); + d.mark = mark; + d3.select(this).select('circle').attr(mark.attributes); + }); // animated attributes + + var pointsTrans = config.transitions ? points.select('circle').transition() : points.select('circle'); + pointsTrans.attr('r', function (d) { + return d.mark.radius || config.flex_point_size; + }).attr('cx', function (d) { + var x_pos = _this.x(d.values.x) || 0; + return config.x.type === 'ordinal' ? x_pos + _this.x.rangeBand() / 2 : x_pos; + }).attr('cy', function (d) { + var y_pos = _this.y(d.values.y) || 0; + return config.y.type === 'ordinal' ? y_pos + _this.y.rangeBand() / 2 : y_pos; + }); + 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]; }); - if (marks.length) - 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; - } + }); // Link to the d3.selection from the data - function drawText(marks) { - var _this = this; + 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 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('-')); + if (marks.length) { + var radius = d3.max(marks, function (mark) { + return mark.radius || _this.config.flex_point_size; }); - 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(); // don't need to transition position of outgoing text - // const oldTextsTrans = config.transitions ? oldTexts.selectAll('text').transition() : oldTexts.selectAll('text'); - - 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'); // don't need to set initial location for incoming text - // attach mark info + 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 + ')'); + } - function attachMarks(d) { - d.mark = d3.select(this.parentNode).datum(); - } + return points; + } - texts.each(attachMarks); // parse text like tooltips - - texts - .select('text') - .style('clip-path', 'url(#'.concat(chart.id, ')')) - .attr('fill', function(d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }) - .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]; - }); - }) - .each(function(d) { - d3.select(this).attr(d.mark.attributes); - }); // animated attributes - - var textsTrans = config.transitions - ? texts.select('text').transition() - : texts.select('text'); - textsTrans - .attr('x', function(d) { - var xPos = _this.x(d.values.x) || 0; - return config.x.type === 'ordinal' ? xPos + _this.x.rangeBand() / 2 : xPos; - }) - .attr('y', function(d) { - var yPos = _this.y(d.values.y) || 0; - return config.y.type === 'ordinal' ? yPos + _this.y.rangeBand() / 2 : yPos; - }); // add a reference to the selection from its data - - text_supergroups.each(function(d) { - d.supergroup = d3.select(this); - d.groups = d.supergroup.selectAll('g.text'); - d.texts = d.groups.select('text'); + 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(); // don't need to transition position of outgoing text + // const oldTextsTrans = config.transitions ? oldTexts.selectAll('text').transition() : oldTexts.selectAll('text'); + + 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'); // don't need to set initial location for incoming text + // attach mark info + + function attachMarks(d) { + d.mark = d3.select(this.parentNode).datum(); + } + + texts.each(attachMarks); // parse text like tooltips + + texts.select('text').style('clip-path', "url(#".concat(chart.id, ")")).attr('fill', function (d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }).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]; }); - return texts; + }).each(function (d) { + d3.select(this).attr(d.mark.attributes); + }); // animated attributes + + var textsTrans = config.transitions ? texts.select('text').transition() : texts.select('text'); + textsTrans.attr('x', function (d) { + var xPos = _this.x(d.values.x) || 0; + return config.x.type === 'ordinal' ? xPos + _this.x.rangeBand() / 2 : xPos; + }).attr('y', function (d) { + var yPos = _this.y(d.values.y) || 0; + return config.y.type === 'ordinal' ? yPos + _this.y.rangeBand() / 2 : yPos; + }); // add a reference to the selection from its data + + 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; - //run onDestroy callback - this.events.onDestroy.call(this); //remove resize event listener + var destroyControls = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + //run onDestroy callback + this.events.onDestroy.call(this); //remove resize event listener - var context = this; - if (!this.test) d3.select(window).on('resize.' + context.element + context.id, null); //destroy controls + var context = this; + if (!this.test) d3.select(window).on('resize.' + context.element + context.id, null); //destroy controls - if (destroyControls && this.controls) { - this.controls.destroy(); - } //unmount chart wrapper + if (destroyControls && this.controls) { + this.controls.destroy(); + } //unmount chart wrapper - this.wrap.remove(); + + this.wrap.remove(); } var chartProto = { - raw_data: [], - config: {} + 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 - } + 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() {} - }; + 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; - } + thisChart.on = function (event, callback) { + var possible_events = ['init', 'layout', 'preprocess', 'datatransform', 'draw', 'resize', 'destroy']; - if (callback) { - thisChart.events['on' + event.charAt(0).toUpperCase() + event.slice(1)] = callback; - } - }; //increment thisChart count to get unique thisChart id + if (possible_events.indexOf(event) < 0) { + return; + } - chartCount++; - thisChart.id = chartCount; - return thisChart; + if (callback) { + thisChart.events['on' + event.charAt(0).toUpperCase() + event.slice(1)] = callback; + } + }; //increment thisChart count to get unique thisChart id + + + chartCount++; + thisChart.id = chartCount; + return thisChart; } function changeOption(option, value, callback, draw) { - var _this = this; + 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); - } //call callback function if provided + 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); + } //call callback function if provided - if (callback) { - callback(); - } - if (draw) target.draw(); - }); + 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.' - ) - ); //Draw the chart when a control changes unless the user specifies otherwise. - - input.draw = input.draw === undefined ? true : input.draw; - }); + 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.")); //Draw the chart when a control changes unless the user specifies otherwise. + + input.draw = input.draw === undefined ? true : input.draw; + }); } function controlUpdate() { - var _this = this; + var _this = this; - if (this.config.inputs && this.config.inputs.length && this.config.inputs[0]) - this.config.inputs.forEach(function(input) { - return _this.makeControlItem(input); - }); + if (this.config.inputs && this.config.inputs.length && this.config.inputs[0]) this.config.inputs.forEach(function (input) { + return _this.makeControlItem(input); + }); } function destroy$1() { - //unmount controls wrapper - this.wrap.remove(); + //unmount controls wrapper + this.wrap.remove(); } function init$1(data) { - this.data = data; - if (!this.config.builder) this.checkRequired(this.data); - this.layout(); + 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(); + 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); //Add control label span. - - var ctrl_label = control_wrap - .append('span') - .attr('class', 'wc-control-label') - .text(control.label); //Add control _Required_ text to control label span. - - if (control.required) - ctrl_label - .append('span') - .attr('class', 'label label-required') - .text('Required'); //Add control description span. - - 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".' - ); - } + var control_wrap = this.wrap.append('div').attr('class', 'control-group').classed('inline', control.inline).datum(control); //Add control label span. + + var ctrl_label = control_wrap.append('span').attr('class', 'wc-control-label').text(control.label); //Add control _Required_ text to control label span. + + if (control.required) ctrl_label.append('span').attr('class', 'label label-required').text('Required'); //Add control description span. + + control_wrap.append('span').attr('class', 'span-description').text(control.description); + + 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); + 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'); + var _this = this; - _this.changeOption(d.option, value, control.callback, control.draw); - }); + 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 _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); } - - 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; + }); + 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); - }); + 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'); + var _this = this; - _this.changeOption(control.option, value, control.callback, control.draw); - }); + 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); + 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; // associated charts and tables. - //dropdown selection - - var changer = control_wrap - .append('select') - .classed('changer', true) - .attr('multiple', control.multiple ? true : null) - .datum(control); //dropdown option data - - var option_data = control.values - ? control.values - : d3 - .set( - this.data.map(function(m) { - return m[control.value_col]; - }) - ) //.filter(f => f)) - .values() - .sort(naturalSorter); // only sort when values are derived - //initial dropdown option - - control.start = control.start ? control.start : control.loose ? option_data[0] : null; //conditionally add All option - - if (!control.multiple && !control.start) { - option_data.unshift('All'); - control.all = true; + var targets = this.targets; // associated charts and tables. + //dropdown selection + + var changer = control_wrap.append('select').classed('changer', true).attr('multiple', control.multiple ? true : null).datum(control); //dropdown option data + + var option_data = control.values ? control.values : d3.set(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 + + control.start = control.start ? control.start : control.loose ? option_data[0] : null; //conditionally add All option + + if (!control.multiple && !control.start) { + option_data.unshift('All'); + control.all = true; + } else { + control.all = false; + } //what does loose mean? + + + control.loose = !control.loose && control.start ? true : control.loose; //dropdown options selection + + var options = changer.selectAll('option').data(option_data).enter().append('option').text(function (d) { + return d; + }).property('selected', function (d) { + return d === control.start; + }); //define filter object for each associated target + + targets.forEach(function (e) { + var match = e.filters.slice().map(function (m) { + return m.col === control.value_col; + }).indexOf(true); + + 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 { - control.all = false; - } //what does loose mean? - - control.loose = !control.loose && control.start ? true : control.loose; //dropdown options selection - - var options = changer - .selectAll('option') - .data(option_data) - .enter() - .append('option') - .text(function(d) { - return d; - }) - .property('selected', function(d) { - return d === control.start; - }); //define filter object for each associated target - - targets.forEach(function(e) { - var match = e.filters - .slice() - .map(function(m) { - return m.col === control.value_col; - }) - .indexOf(true); - - 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 - }); - } + 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; + } }); - 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; + if (match > -1) { + target.filters[match] = obj; + } + } //add event listener to control + + + 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, + // could specify an array of indices but seems like a waste of resources give it doesn't inform anything without an overall 'All' + choices: option_data, + loose: control.loose, + all: control.all + }; + targets.forEach(function (e) { + setSubsetter(e, new_filter); //call callback function if provided + + if (control.callback) { + control.callback(); } - } //add event listener to control - - 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, - // could specify an array of indices but seems like a waste of resources give it doesn't inform anything without an overall 'All' - choices: option_data, - loose: control.loose, - all: control.all - }; - targets.forEach(function(e) { - setSubsetter(e, new_filter); //call callback function if provided - - 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); //call callback function if provided - - if (control.callback) { - control.callback(); - } - - e.draw(); - }); + + 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); //call callback function if provided + + 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'); + var _this = this; - _this.changeOption(control.option, value, control.callback, control.draw); - }); + 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) { - //adapted from http://jsfiddle.net/alnitak/hEsys/ - s = s.replace(/\[(\w+)\]/g, '.$1'); - s = s.replace(/^\./, ''); - var a = s.split('.'); + //adapted from http://jsfiddle.net/alnitak/hEsys/ + s = s.replace(/\[(\w+)\]/g, '.$1'); + s = s.replace(/^\./, ''); + var a = s.split('.'); - for (var i = 0, n = a.length; i < n; ++i) { - var k = a[i]; + for (var i = 0, n = a.length; i < n; ++i) { + var k = a[i]; - if (k in o) { - if (i == n - 1 && v !== undefined) o[k] = v; - o = o[k]; - } else { - return; - } + if (k in o) { + if (i == n - 1 && v !== undefined) o[k] = v; + o = o[k]; + } else { + return; } + } - return o; + return o; } var controls = { - changeOption: changeOption, - checkRequired: checkRequired$1, - controlUpdate: controlUpdate, - destroy: destroy$1, - init: init$1, - layout: layout$1, - makeControlItem: makeControlItem, - makeBtnGroupControl: makeBtnGroupControl, - makeCheckboxControl: makeCheckboxControl, - makeDropdownControl: makeDropdownControl, - makeListControl: makeListControl, - makeNumberControl: makeNumberControl, - makeRadioControl: makeRadioControl, - makeSubsetterControl: makeSubsetterControl, - makeTextControl: makeTextControl, - stringAccessor: stringAccessor + changeOption: changeOption, + checkRequired: checkRequired$1, + controlUpdate: controlUpdate, + destroy: destroy$1, + init: init$1, + layout: layout$1, + makeControlItem: makeControlItem, + makeBtnGroupControl: makeBtnGroupControl, + makeCheckboxControl: makeCheckboxControl, + makeDropdownControl: makeDropdownControl, + makeListControl: makeListControl, + makeNumberControl: makeNumberControl, + makeRadioControl: makeRadioControl, + makeSubsetterControl: makeSubsetterControl, + makeTextControl: makeTextControl, + stringAccessor: stringAccessor }; function createControls() { - var element = arguments.length > 0 && 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'); - } + var element = arguments.length > 0 && 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 = []; - thisControls.wrap.datum(thisControls); - return thisControls; + 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 there are filters, return a filtered data array of the raw data. - //Otherwise return the raw data. - if ( - this.filters && - this.filters.some(function(filter) { - return ( - (typeof filter.val === 'string' && - !(filter.all === true && filter.index === 0)) || - (Array.isArray(filter.val) && filter.val.length < filter.choices.length) - ); - }) - ) { - this.data.filtered = this.data.raw.slice(); - this.filters - .filter(function(filter) { - return ( - (typeof filter.val === 'string' && - !(filter.all === true && filter.index === 0)) || - (Array.isArray(filter.val) && filter.val.length < filter.choices.length) - ); - }) - .forEach(function(filter) { - _this.data.filtered = _this.data.filtered.filter(function(d) { - return Array.isArray(filter.val) - ? filter.val.indexOf(d[filter.col]) > -1 - : filter.val === d[filter.col]; - }); - }); - } else this.data.filtered = this.data.raw.slice(); + var _this = this; + + //If there are filters, return a filtered data array of the raw data. + //Otherwise return the raw data. + if (this.filters && this.filters.some(function (filter) { + return typeof filter.val === 'string' && !(filter.all === true && filter.index === 0) || Array.isArray(filter.val) && filter.val.length < filter.choices.length; + })) { + this.data.filtered = this.data.raw.slice(); + this.filters.filter(function (filter) { + return typeof filter.val === 'string' && !(filter.all === true && filter.index === 0) || Array.isArray(filter.val) && filter.val.length < filter.choices.length; + }).forEach(function (filter) { + _this.data.filtered = _this.data.filtered.filter(function (d) { + return Array.isArray(filter.val) ? filter.val.indexOf(d[filter.col]) > -1 : filter.val === d[filter.col]; + }); + }); + } else this.data.filtered = this.data.raw.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; // first row shown + 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; // first row shown - this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown + this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown } function applySearchTerm(data) { - var _this = this; - - if (this.searchable.searchTerm) { - //Determine which rows contain input text. - 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 { - //Otherwise delete previously searched data and set data to filtered data. - delete this.data.searched; - this.data.processing = this.data.filtered; - } + var _this = this; + + if (this.searchable.searchTerm) { + //Determine which rows contain input text. + 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 { + //Otherwise delete previously searched data and set data to filtered data. + delete this.data.searched; + this.data.processing = this.data.filtered; + } } /*------------------------------------------------------------------------------------------------\ Check equality of two arrays (https://stackoverflow.com/questions/7837456/how-to-compare-arrays-in-javascript) \------------------------------------------------------------------------------------------------*/ // Warn if overriding existing method - if (Array.prototype.equals) - console.warn( - "Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code." - ); // attach the .equals method to Array's prototype to call it on any array - - Array.prototype.equals = function(array) { - // if the other array is a falsy value, return - if (!array) return false; // compare lengths - can save a lot of time - - if (this.length != array.length) return false; - - for (var i = 0, l = this.length; i < l; i++) { - // Check if we have nested arrays - if (this[i] instanceof Array && array[i] instanceof Array) { - // recurse into the nested arrays - if (!this[i].equals(array[i])) return false; - } else if (this[i] != array[i]) { - // Warning - two different object instances will never be equal: {x:20} != {x:20} - return false; - } + if (Array.prototype.equals) console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code."); // attach the .equals method to Array's prototype to call it on any array + + Array.prototype.equals = function (array) { + // if the other array is a falsy value, return + if (!array) return false; // compare lengths - can save a lot of time + + if (this.length != array.length) return false; + + for (var i = 0, l = this.length; i < l; i++) { + // Check if we have nested arrays + if (this[i] instanceof Array && array[i] instanceof Array) { + // recurse into the nested arrays + if (!this[i].equals(array[i])) return false; + } else if (this[i] != array[i]) { + // Warning - two different object instances will never be equal: {x:20} != {x:20} + return false; } + } - return true; + return true; }; // Hide method from for-in loops + Object.defineProperty(Array.prototype, 'equals', { - enumerable: false + enumerable: false }); function checkFilters() { - if (this.filters) { - this.currentFilters = this.filters.map(function(filter) { - return filter.val; - }); //Reset pagination if filters have changed. - - if (!this.currentFilters.equals(this.previousFilters)) { - this.config.activePage = 0; - this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; // first row shown + if (this.filters) { + this.currentFilters = this.filters.map(function (filter) { + return filter.val; + }); //Reset pagination if filters have changed. - this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown - } + if (!this.currentFilters.equals(this.previousFilters)) { + this.config.activePage = 0; + this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; // first row shown - this.previousFilters = this.currentFilters; + this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown } + + this.previousFilters = this.currentFilters; + } } function updateTableHeaders() { - var _this = this; - - this.thead_cells = this.thead - .select('tr') - .selectAll('th') - .data(this.config.headers, function(d) { - return d; - }); - this.thead_cells.exit().remove(); - this.thead_cells.enter().append('th'); - this.thead_cells - .sort(function(a, b) { - return _this.config.headers.indexOf(a) - _this.config.headers.indexOf(b); - }) - .attr('class', function(d) { - return _this.config.cols[_this.config.headers.indexOf(d)]; - }) // associate column header with column name - .text(function(d) { - return d; - }); + var _this = this; + + this.thead_cells = this.thead.select('tr').selectAll('th').data(this.config.headers, function (d) { + return d; + }); + this.thead_cells.exit().remove(); + this.thead_cells.enter().append('th'); + this.thead_cells.sort(function (a, b) { + return _this.config.headers.indexOf(a) - _this.config.headers.indexOf(b); + }).attr('class', function (d) { + return _this.config.cols[_this.config.headers.indexOf(d)]; + }) // associate column header with column name + .text(function (d) { + return d; + }); } function drawTableBody() { - var _this = this; - - var table = this; //Define table body rows. - - var rows = this.tbody - .selectAll('tr') - .data(this.data.processing) - .enter() - .append('tr'); //Define table body cells. - - var cells = rows.selectAll('td').data(function(d) { - return _this.config.cols.map(function(key) { - return { - col: key, - text: d[key] - }; - }); + var _this = this; + + var table = this; //Define table body rows. + + var rows = this.tbody.selectAll('tr').data(this.data.processing).enter().append('tr'); //Define table body cells. + + var cells = rows.selectAll('td').data(function (d) { + return _this.config.cols.map(function (key) { + return { + col: key, + text: d[key] + }; }); - cells.exit().remove(); - cells.enter().append('td'); - cells - .sort(function(a, b) { - return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); - }) - .attr('class', function(d) { - return d.col; - }) - .each(function(d) { - var cell = d3.select(this); //Apply text in data as html or as plain text. - - if (table.config.as_html) { - cell.html(d.text); - } else { - cell.text(d.text); - } - }); + }); + cells.exit().remove(); + cells.enter().append('td'); + cells.sort(function (a, b) { + return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); + }).attr('class', function (d) { + return d.col; + }).each(function (d) { + var cell = d3.select(this); //Apply text in data as html or as plain text. + + if (table.config.as_html) { + cell.html(d.text); + } else { + cell.text(d.text); + } + }); } function dynamicLayout() { - var widths = { - table: this.table.select('thead').node().offsetWidth, - top: - this.wrap.select('.table-top .searchable-container').node().offsetWidth + - this.wrap.select('.table-top .sortable-container').node().offsetWidth, - bottom: - this.wrap.select('.table-bottom .pagination-container').node().offsetWidth + - this.wrap.select('.table-bottom .exportable-container').node().offsetWidth - }; - - if ( - widths.table < Math.max(widths.top, widths.bottom) && - this.config.layout === 'horizontal' - ) { - this.config.layout = 'vertical'; - this.wrap - .style('display', 'inline-block') - .selectAll('.table-top,.table-bottom') - .style('display', 'inline-block') - .selectAll('.interactivity') - .style({ - display: 'block', - clear: 'both' - }); - } else if ( - widths.table >= Math.max(widths.top, widths.bottom) && - this.config.layout === 'vertical' - ) { - this.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 - }); - } + var widths = { + table: this.table.select('thead').node().offsetWidth, + top: this.wrap.select('.table-top .searchable-container').node().offsetWidth + this.wrap.select('.table-top .sortable-container').node().offsetWidth, + bottom: this.wrap.select('.table-bottom .pagination-container').node().offsetWidth + this.wrap.select('.table-bottom .exportable-container').node().offsetWidth + }; + + if (widths.table < Math.max(widths.top, widths.bottom) && this.config.layout === 'horizontal') { + this.config.layout = 'vertical'; + this.wrap.style('display', 'inline-block').selectAll('.table-top,.table-bottom').style('display', 'inline-block').selectAll('.interactivity').style({ + display: 'block', + clear: 'both' + }); + } else if (widths.table >= Math.max(widths.top, widths.bottom) && this.config.layout === 'vertical') { + this.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; // make passed data available on preprocess - - this.events.onPreprocess.call(this); - if (!passed_data) - //Apply filters if data is not passed to table.draw(). - applyFilters.call(this); - //Otherwise update data object. - else updateDataObject.call(this); //Compare current filter settings to previous filter settings, if any. - - checkFilters.call(this); //Filter data on search term if it exists and set data to searched data. - - applySearchTerm.call(this); - this.searchable.wrap - .select('.nNrecords') - .text( - this.data.processing.length === this.data.raw.length - ? ''.concat(this.data.raw.length, ' records displayed') - : '' - .concat(this.data.processing.length, '/') - .concat(this.data.raw.length, ' records displayed') - ); //Update table headers. - - updateTableHeaders.call(this); //Clear table body rows. - - this.tbody.selectAll('tr').remove(); //Print a note that no data was selected for empty tables. - - if (this.data.processing.length === 0) { - this.tbody - .append('tr') - .classed('no-data', true) - .append('td') - .attr('colspan', this.config.cols.length) - .text('No data selected.'); //Bind table filtered/searched data to table container. - - this.data.current = this.data.processing; - this.table.datum(this.table.current); //Add export. - - if (this.config.exportable) - this.config.exports.forEach(function(fmt) { - _this.exportable.exports[fmt].call(_this, _this.data.processing); - }); //Add pagination. - - if (this.config.pagination) - this.pagination.addPagination.call(this, this.data.processing); - } else { - //Sort data. - if (this.config.sortable) { - this.thead.selectAll('th').on('click', function(header) { - table.sortable.onClick.call(table, this, header); - }); - if (this.sortable.order.length) - this.sortable.sortData.call(this, this.data.processing); - } //Bind table filtered/searched data to table container. - - this.data.current = this.data.processing; - this.table.datum(this.data.current); //Add export. - - if (this.config.exportable) - this.config.exports.forEach(function(fmt) { - _this.exportable.exports[fmt].call(_this, _this.data.processing); - }); //Add pagination. - - if (this.config.pagination) { - this.pagination.addPagination.call(this, this.data.processing); //Apply pagination. - - this.data.processing = this.data.processing.filter(function(d, i) { - return _this.config.startIndex <= i && i < _this.config.endIndex; - }); - } //Define table body rows. - - drawTableBody.call(this); - } //Alter table layout if table is narrower than table top or bottom. - - if (this.config.dynamicPositioning) { - dynamicLayout.call(this); - } + var _this = this; + + var table = this; + var config = this.config; + this.data.passed = passed_data; // make passed data available on preprocess + + this.events.onPreprocess.call(this); + if (!passed_data) //Apply filters if data is not passed to table.draw(). + applyFilters.call(this); //Otherwise update data object. + else updateDataObject.call(this); //Compare current filter settings to previous filter settings, if any. + + checkFilters.call(this); //Filter data on search term if it exists and set data to searched data. + + applySearchTerm.call(this); + this.searchable.wrap.select('.nNrecords').text(this.data.processing.length === this.data.raw.length ? "".concat(this.data.raw.length, " records displayed") : "".concat(this.data.processing.length, "/").concat(this.data.raw.length, " records displayed")); //Update table headers. + + updateTableHeaders.call(this); //Clear table body rows. + + this.tbody.selectAll('tr').remove(); //Print a note that no data was selected for empty tables. + + if (this.data.processing.length === 0) { + this.tbody.append('tr').classed('no-data', true).append('td').attr('colspan', this.config.cols.length).text('No data selected.'); //Bind table filtered/searched data to table container. + + this.data.current = this.data.processing; + this.table.datum(this.table.current); //Add export. + + if (this.config.exportable) this.config.exports.forEach(function (fmt) { + _this.exportable.exports[fmt].call(_this, _this.data.processing); + }); //Add pagination. - this.events.onDraw.call(this); + if (this.config.pagination) this.pagination.addPagination.call(this, this.data.processing); + } else { + //Sort data. + if (this.config.sortable) { + this.thead.selectAll('th').on('click', function (header) { + table.sortable.onClick.call(table, this, header); + }); + if (this.sortable.order.length) this.sortable.sortData.call(this, this.data.processing); + } //Bind table filtered/searched data to table container. + + + this.data.current = this.data.processing; + this.table.datum(this.data.current); //Add export. + + if (this.config.exportable) this.config.exports.forEach(function (fmt) { + _this.exportable.exports[fmt].call(_this, _this.data.processing); + }); //Add pagination. + + if (this.config.pagination) { + this.pagination.addPagination.call(this, this.data.processing); //Apply pagination. + + this.data.processing = this.data.processing.filter(function (d, i) { + return _this.config.startIndex <= i && i < _this.config.endIndex; + }); + } //Define table body rows. + + + drawTableBody.call(this); + } //Alter table layout if table is narrower than table top or bottom. + + + 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; // first row shown - - context.config.endIndex = context.config.startIndex + context.config.nRowsPerPage; // last row shown - - context.draw(); - }); - this.searchable.wrap - .select('.search') - .append('span') - .classed('nNrecords', true); + 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; // first row shown + + context.config.endIndex = context.config.startIndex + context.config.nRowsPerPage; // last row shown + + context.draw(); + }); + this.searchable.wrap.select('.search').append('span').classed('nNrecords', true); } function searchable() { - return { - layout: layout$2 - }; + 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()); - }); + 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) { - //transform blob array into a blob of characters - var blob = new Blob(data, { - type: - fileType === 'csv' - ? 'text/csv;charset=utf-8;' - : fileType === 'xlsx' - ? 'application/octet-stream' - : console.warn('File type not supported: '.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) - //IE - navigator.msSaveBlob(blob, fileName); - else if (link.node().download !== undefined) { - //21st century browsers - var url = URL.createObjectURL(blob); - link.node().setAttribute('href', url); - link.node().setAttribute('download', fileName); - } + //transform blob array into a blob of characters + var blob = new Blob(data, { + type: fileType === 'csv' ? 'text/csv;charset=utf-8;' : fileType === 'xlsx' ? 'application/octet-stream' : console.warn("File type not supported: ".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) //IE + navigator.msSaveBlob(blob, fileName);else if (link.node().download !== undefined) { + //21st century browsers + var url = URL.createObjectURL(blob); + link.node().setAttribute('href', url); + link.node().setAttribute('download', fileName); + } } function csv(data) { - var _this = this; + var _this = this; - this.wrap.select('.export#csv').on('click', function() { - var CSVarray = []; //add headers to CSV array + this.wrap.select('.export#csv').on('click', function () { + var CSVarray = []; //add headers to CSV array - var headers = _this.config.headers.map(function(header) { - return '"'.concat(header.replace(/"/g, '""'), '"'); - }); + var headers = _this.config.headers.map(function (header) { + return "\"".concat(header.replace(/"/g, '""'), "\""); + }); - CSVarray.push(headers); //add rows to CSV array + CSVarray.push(headers); //add rows to CSV array - 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, '"'); - }); + 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 .csv file. + CSVarray.push(row); + }); //Download .csv file. - download.call(_this, 'csv', [CSVarray.join('\n')]); - }); + 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]; - }); - }); // convert data from array of objects to array of arrays. - - var workbook = { - SheetNames: [sheetName], - Sheets: {} - }; - var cols = []; //Convert headers and data from array of arrays to sheet. - - workbook.Sheets[sheetName] = XLSX.utils.aoa_to_sheet( - [_this.config.headers].concat(arrayOfArrays) - ); //Add filters to spreadsheet. - - workbook.Sheets[sheetName]['!autofilter'] = { - ref: 'A1:' - .concat(String.fromCharCode(64 + _this.config.cols.length)) - .concat(data.length + 1) - }; //Define column widths in spreadsheet. - - _this.table.selectAll('thead tr th').each(function() { - cols.push({ - wpx: this.offsetWidth - }); - }); + 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]; + }); + }); // convert data from array of objects to array of arrays. + + var workbook = { + SheetNames: [sheetName], + Sheets: {} + }; + var cols = []; //Convert headers and data from array of arrays to sheet. + + workbook.Sheets[sheetName] = XLSX.utils.aoa_to_sheet([_this.config.headers].concat(arrayOfArrays)); //Add filters to spreadsheet. - workbook.Sheets[sheetName]['!cols'] = cols; - var xlsx = XLSX.write(workbook, options); + workbook.Sheets[sheetName]['!autofilter'] = { + ref: "A1:".concat(String.fromCharCode(64 + _this.config.cols.length)).concat(data.length + 1) + }; //Define column widths in spreadsheet. - var s2ab = function s2ab(s) { - var buffer = new ArrayBuffer(s.length), - view = new Uint8Array(buffer); + _this.table.selectAll('thead tr th').each(function () { + cols.push({ + wpx: this.offsetWidth + }); + }); - for (var i = 0; i !== s.length; ++i) { - view[i] = s.charCodeAt(i) & 0xff; - } + workbook.Sheets[sheetName]['!cols'] = cols; + var xlsx = XLSX.write(workbook, options); - return buffer; - }; // convert spreadsheet to binary or something, i don't know - //Download .xlsx file. + var s2ab = function s2ab(s) { + var buffer = new ArrayBuffer(s.length), + view = new Uint8Array(buffer); - download.call(_this, 'xlsx', [s2ab(xlsx)]); - }); + for (var i = 0; i !== s.length; ++i) { + view[i] = s.charCodeAt(i) & 0xff; + } + + return buffer; + }; // convert spreadsheet to binary or something, i don't know + //Download .xlsx file. + + + download.call(_this, 'xlsx', [s2ab(xlsx)]); + }); } var exports$1 = { - csv: csv, - xlsx: xlsx + csv: csv, + xlsx: xlsx }; function exportable() { - return { - layout: layout$3, - exports: exports$1 - }; + 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.'); + + 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)]; //Check if column is already a part of current sort order. - - var sortItem = this.sortable.order.filter(function(item) { - return item.col === col; - })[0]; //If it isn't, add it to sort order. - - 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 { - //Otherwise reverse its sort direction. - sortItem.direction = sortItem.direction === 'ascending' ? 'descending' : 'ascending'; - sortItem.wrap - .select('span.sort-direction') - .html(sortItem.direction === 'ascending' ? '↓' : '↑'); - } //Hide sort instructions. - - this.sortable.wrap.select('.instruction').classed('hidden', true); //Add sort container deletion functionality. - - this.sortable.order.forEach(function(item, i) { - item.wrap.on('click', function(d) { - //Remove column's sort container. - d3.select(this).remove(); //Remove column from sort. - - context.sortable.order.splice( - context.sortable.order - .map(function(d) { - return d.col; - }) - .indexOf(d.key), - 1 - ); //Display sorting instruction. - - context.sortable.wrap - .select('.instruction') - .classed('hidden', context.sortable.order.length); //Redraw chart. - - context.draw(); - }); - }); //Redraw chart. + var context = this, + selection = d3.select(th), + col = this.config.cols[this.config.headers.indexOf(header)]; //Check if column is already a part of current sort order. + + var sortItem = this.sortable.order.filter(function (item) { + return item.col === col; + })[0]; //If it isn't, add it to sort order. + + 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 { + //Otherwise reverse its sort direction. + sortItem.direction = sortItem.direction === 'ascending' ? 'descending' : 'ascending'; + sortItem.wrap.select('span.sort-direction').html(sortItem.direction === 'ascending' ? '↓' : '↑'); + } //Hide sort instructions. + + + this.sortable.wrap.select('.instruction').classed('hidden', true); //Add sort container deletion functionality. - this.draw(); + this.sortable.order.forEach(function (item, i) { + item.wrap.on('click', function (d) { + //Remove column's sort container. + d3.select(this).remove(); //Remove column from sort. + + context.sortable.order.splice(context.sortable.order.map(function (d) { + return d.col; + }).indexOf(d.key), 1); //Display sorting instruction. + + context.sortable.wrap.select('.instruction').classed('hidden', context.sortable.order.length); //Redraw chart. + + context.draw(); + }); + }); //Redraw chart. + + 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; - }; - } + 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); + 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 (order === 0) { - if (item.type === 'number') { - order = item.direction === 'ascending' ? +aCell - +bCell : +bCell - +aCell; - } else { - 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; - } - } - }); + var _this = this; + + data = data.sort(function (a, b) { + var order = 0; - return order; + _this.sortable.order.forEach(function (item) { + var aCell = a[item.col]; + var bCell = b[item.col]; + + if (order === 0) { + if (item.type === 'number') { + order = item.direction === 'ascending' ? +aCell - +bCell : +bCell - +aCell; + } else { + 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; + } + } }); + + return order; + }); } function sortable() { - return { - layout: layout$4, - onClick: onClick, - sortData: sortData, - order: [] - }; + return { + layout: layout$4, + onClick: onClick, + sortData: sortData, + order: [] + }; } function layout$5() { - this.pagination.wrap = this.wrap - .select('.table-bottom') - .append('div') - .classed('interactivity pagination-container', true) - .classed('hidden', !this.config.pagination); + this.pagination.wrap = this.wrap.select('.table-bottom').append('div').classed('interactivity pagination-container', true).classed('hidden', !this.config.pagination); } function updatePagination() { - var _this = this; + var _this = this; - //Reset pagination. - this.pagination.links.classed('active', false); //Set to active the selected page link. + //Reset pagination. + this.pagination.links.classed('active', false); //Set to active the selected page link. - var activePage = this.pagination.links - .filter(function(link) { - return +link.rel === +_this.config.activePage; - }) - .classed('active', true); //Define and draw selected page. + var activePage = this.pagination.links.filter(function (link) { + return +link.rel === +_this.config.activePage; + }).classed('active', true); //Define and draw selected page. - this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; - this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; //Redraw table. + this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; + this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; //Redraw table. - this.draw(); + this.draw(); } function addLinks() { - var _this = this; - - //Count rows. - this.pagination.wrap.selectAll('a,span').remove(); - - var _loop = function _loop(i) { - _this.pagination.wrap - .append('a') - .datum({ - rel: i - }) - .attr({ - rel: i - }) - .text(i + 1) - .classed('wc-button page-link', true) - .classed('active', function(d) { - return d.rel == _this.config.activePage; - }) - .classed('hidden', function() { - return _this.config.activePage < _this.config.nPageLinksDisplayed - ? i >= _this.config.nPageLinksDisplayed // first nPageLinksDisplayed pages - : _this.config.activePage >= - _this.config.nPages - _this.config.nPageLinksDisplayed - ? i < _this.config.nPages - _this.config.nPageLinksDisplayed // last nPageLinksDisplayed pages - : i < - _this.config.activePage - - (Math.ceil(_this.config.nPageLinksDisplayed / 2) - 1) || - _this.config.activePage + _this.config.nPageLinksDisplayed / 2 < i; // nPageLinksDisplayed < activePage or activePage < (nPages - nPageLinksDisplayed) - }); - }; + var _this = this; + + //Count rows. + this.pagination.wrap.selectAll('a,span').remove(); + + var _loop = function _loop(i) { + _this.pagination.wrap.append('a').datum({ + rel: i + }).attr({ + rel: i + }).text(i + 1).classed('wc-button page-link', true).classed('active', function (d) { + return d.rel == _this.config.activePage; + }).classed('hidden', function () { + return _this.config.activePage < _this.config.nPageLinksDisplayed ? i >= _this.config.nPageLinksDisplayed // first nPageLinksDisplayed pages + : _this.config.activePage >= _this.config.nPages - _this.config.nPageLinksDisplayed ? i < _this.config.nPages - _this.config.nPageLinksDisplayed // last nPageLinksDisplayed pages + : i < _this.config.activePage - (Math.ceil(_this.config.nPageLinksDisplayed / 2) - 1) || _this.config.activePage + _this.config.nPageLinksDisplayed / 2 < i; // nPageLinksDisplayed < activePage or activePage < (nPages - nPageLinksDisplayed) + }); + }; - for (var i = 0; i < this.config.nPages; i++) { - _loop(i); - } + for (var i = 0; i < this.config.nPages; i++) { + _loop(i); + } - this.pagination.links = this.pagination.wrap.selectAll('a.page-link'); + this.pagination.links = this.pagination.wrap.selectAll('a.page-link'); } function addArrows() { - var prev = this.config.activePage - 1, - next = this.config.activePage + 1; - if (prev < 0) prev = 0; // nothing before the first page + var prev = this.config.activePage - 1, + next = this.config.activePage + 1; + if (prev < 0) prev = 0; // nothing before the first page - if (next >= this.config.nPages) next = this.config.nPages - 1; // nothing after the last page + if (next >= this.config.nPages) next = this.config.nPages - 1; // nothing after the last page - /**-------------------------------------------------------------------------------------------\ + /**-------------------------------------------------------------------------------------------\ Left side \-------------------------------------------------------------------------------------------**/ - this.pagination.wrap - .insert('span', ':first-child') - .classed('dot-dot-dot', true) - .text('...') - .classed('hidden', this.config.activePage < this.config.nPageLinksDisplayed); - this.pagination.prev = this.pagination.wrap - .insert('a', ':first-child') - .classed('wc-button arrow-link wc-left', true) - .classed('hidden', this.config.activePage == 0) - .attr({ - rel: prev - }) - .text('<'); - this.pagination.doublePrev = this.pagination.wrap - .insert('a', ':first-child') - .classed('wc-button arrow-link wc-left double', true) - .classed('hidden', this.config.activePage == 0) - .attr({ - rel: 0 - }) - .text('<<'); - /**-------------------------------------------------------------------------------------------\ + this.pagination.wrap.insert('span', ':first-child').classed('dot-dot-dot', true).text('...').classed('hidden', this.config.activePage < this.config.nPageLinksDisplayed); + this.pagination.prev = this.pagination.wrap.insert('a', ':first-child').classed('wc-button arrow-link wc-left', true).classed('hidden', this.config.activePage == 0).attr({ + rel: prev + }).text('<'); + this.pagination.doublePrev = this.pagination.wrap.insert('a', ':first-child').classed('wc-button arrow-link wc-left double', true).classed('hidden', this.config.activePage == 0).attr({ + rel: 0 + }).text('<<'); + /**-------------------------------------------------------------------------------------------\ Right side \-------------------------------------------------------------------------------------------**/ - this.pagination.wrap - .append('span') - .classed('dot-dot-dot', true) - .text('...') - .classed( - 'hidden', - this.config.activePage >= - Math.max( - this.config.nPageLinksDisplayed, - this.config.nPages - this.config.nPageLinksDisplayed - ) || this.config.nPages <= this.config.nPageLinksDisplayed - ); - this.pagination.next = this.pagination.wrap - .append('a') - .classed('wc-button arrow-link wc-right', true) - .classed( - 'hidden', - this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0 - ) - .attr({ - rel: next - }) - .text('>'); - this.pagination.doubleNext = this.pagination.wrap - .append('a') - .classed('wc-button arrow-link wc-right double', true) - .classed( - 'hidden', - this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0 - ) - .attr({ - rel: this.config.nPages - 1 - }) - .text('>>'); - this.pagination.arrows = this.pagination.wrap.selectAll('a.arrow-link'); - this.pagination.doubleArrows = this.pagination.wrap.selectAll('a.double-arrow-link'); + this.pagination.wrap.append('span').classed('dot-dot-dot', true).text('...').classed('hidden', this.config.activePage >= Math.max(this.config.nPageLinksDisplayed, this.config.nPages - this.config.nPageLinksDisplayed) || this.config.nPages <= this.config.nPageLinksDisplayed); + this.pagination.next = this.pagination.wrap.append('a').classed('wc-button arrow-link wc-right', true).classed('hidden', this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0).attr({ + rel: next + }).text('>'); + this.pagination.doubleNext = this.pagination.wrap.append('a').classed('wc-button arrow-link wc-right double', true).classed('hidden', this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0).attr({ + rel: this.config.nPages - 1 + }).text('>>'); + this.pagination.arrows = this.pagination.wrap.selectAll('a.arrow-link'); + this.pagination.doubleArrows = this.pagination.wrap.selectAll('a.double-arrow-link'); } function addPagination(data) { - var context = this; //Calculate number of pages needed and create a link for each page. - - this.config.nRows = data.length; - this.config.nPages = Math.ceil(this.config.nRows / this.config.nRowsPerPage); //hide the pagination if there is only one page - - this.config.paginationHidden = this.config.nPages === 1; - this.pagination.wrap.classed('hidden', this.config.paginationHidden); //Render page links. - - addLinks.call(this); //Render a different page on click. - - this.pagination.links.on('click', function() { - context.config.activePage = +d3.select(this).attr('rel'); - updatePagination.call(context); - }); //Render arrow links. - - addArrows.call(this); //Render a different page on click. - - this.pagination.arrows.on('click', function() { - if (context.config.activePage !== +d3.select(this).attr('rel')) { - context.config.activePage = +d3.select(this).attr('rel'); - context.pagination.prev.attr( - 'rel', - context.config.activePage > 0 ? context.config.activePage - 1 : 0 - ); - context.pagination.next.attr( - 'rel', - context.config.activePage < context.config.nPages - ? context.config.activePage + 1 - : context.config.nPages - 1 - ); - updatePagination.call(context); - } - }); //Render a different page on click. + var context = this; //Calculate number of pages needed and create a link for each page. - this.pagination.doubleArrows.on('click', function() { - context.config.activePage = +d3.select(this).attr('rel'); - updatePagination.call(context); - }); - return { - addLinks: addLinks, - addArrows: addArrows, - updatePagination: updatePagination - }; + this.config.nRows = data.length; + this.config.nPages = Math.ceil(this.config.nRows / this.config.nRowsPerPage); //hide the pagination if there is only one page + + this.config.paginationHidden = this.config.nPages === 1; + this.pagination.wrap.classed('hidden', this.config.paginationHidden); //Render page links. + + addLinks.call(this); //Render a different page on click. + + this.pagination.links.on('click', function () { + context.config.activePage = +d3.select(this).attr('rel'); + updatePagination.call(context); + }); //Render arrow links. + + addArrows.call(this); //Render a different page on click. + + this.pagination.arrows.on('click', function () { + if (context.config.activePage !== +d3.select(this).attr('rel')) { + context.config.activePage = +d3.select(this).attr('rel'); + context.pagination.prev.attr('rel', context.config.activePage > 0 ? context.config.activePage - 1 : 0); + context.pagination.next.attr('rel', context.config.activePage < context.config.nPages ? context.config.activePage + 1 : context.config.nPages - 1); + updatePagination.call(context); + } + }); //Render a different page on click. + + this.pagination.doubleArrows.on('click', function () { + context.config.activePage = +d3.select(this).attr('rel'); + updatePagination.call(context); + }); + return { + addLinks: addLinks, + addArrows: addArrows, + updatePagination: updatePagination + }; } function pagination() { - this.config.nRows = this.data.raw.length; // total number of rows, i.e. the length of the data file + this.config.nRows = this.data.raw.length; // total number of rows, i.e. the length of the data file - this.config.nPages = Math.ceil(this.config.nRows / this.config.nRowsPerPage); // total number of pages given number of rows + this.config.nPages = Math.ceil(this.config.nRows / this.config.nRowsPerPage); // total number of pages given number of rows - this.config.activePage = 0; // current page, 0-indexed + this.config.activePage = 0; // current page, 0-indexed - this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; // first row shown + this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; // first row shown - this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown + this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown - this.config.paginationHidden = this.config.nPages == 1; - return { - layout: layout$5, - addPagination: addPagination - }; + this.config.paginationHidden = this.config.nPages == 1; + return { + layout: layout$5, + addPagination: addPagination + }; } function init$2(data) { - var _this = this; + var _this = this; - var test = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - this.test = test; + 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); - }); - } //Define default settings. + 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); + }); + } //Define default settings. - this.setDefaults.call(this, data[0]); //Assign classes to container element. - this.wrap.classed('wc-chart', true).classed('wc-table', this.config.applyCSS); //Define data object. + this.setDefaults.call(this, data[0]); //Assign classes to container element. - this.data = { - raw: data - }; //Attach searchable object to table object. + this.wrap.classed('wc-chart', true).classed('wc-table', this.config.applyCSS); //Define data object. - this.searchable = searchable.call(this); //Attach sortable object to table object. + this.data = { + raw: data + }; //Attach searchable object to table object. - this.sortable = sortable.call(this); //Attach pagination object to table object. + this.searchable = searchable.call(this); //Attach sortable object to table object. - this.pagination = pagination.call(this); //Attach pagination object to table object. + this.sortable = sortable.call(this); //Attach pagination object to table object. - this.exportable = exportable.call(this); + this.pagination = pagination.call(this); //Attach pagination object to table object. - var startup = function startup(data) { - //connect this table and its controls, if any - if (_this.controls) { - _this.controls.targets.push(_this); + this.exportable = exportable.call(this); - if (!_this.controls.ready) { - _this.controls.init(_this.data.raw); - } else { - _this.controls.layout(); - } - } //make sure container is visible (has height and width) before trying to initialize + var startup = function startup(data) { + //connect this table and its controls, if any + if (_this.controls) { + _this.controls.targets.push(_this); - var visible = d3.select(_this.div).property('offsetWidth') > 0 || test; + if (!_this.controls.ready) { + _this.controls.init(_this.data.raw); + } else { + _this.controls.layout(); + } + } //make sure container is visible (has height and width) before trying to initialize - 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(); + var visible = d3.select(_this.div).property('offsetWidth') > 0 || test; - _this.wrap.datum(_this); + 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; - _this.draw(); + if (visible_now) { + _this.layout(); - clearInterval(onVisible); - } - }, 500); - } else { - _this.layout(); + _this.wrap.datum(_this); - _this.wrap.datum(_this); + _this.draw(); - _this.draw(); + clearInterval(onVisible); } - }; + }, 500); + } else { + _this.layout(); - this.events.onInit.call(this); + _this.wrap.datum(_this); - if (this.data.raw.length) { - this.checkRequired(this.data.raw); + _this.draw(); } + }; + + this.events.onInit.call(this); - startup(); - return this; + if (this.data.raw.length) { + this.checkRequired(this.data.raw); + } + + startup(); + return this; } function layout$6() { - //Clear loading indicator. - d3.select(this.div) - .select('.loader') - .remove(); //Attach container before table. + //Clear loading indicator. + d3.select(this.div).select('.loader').remove(); //Attach container before table. - this.wrap.append('div').classed('table-top', true); //Attach search container. + this.wrap.append('div').classed('table-top', true); //Attach search container. - this.searchable.layout.call(this); //Attach sort container. + this.searchable.layout.call(this); //Attach sort container. - this.sortable.layout.call(this); //Attach table to DOM. + this.sortable.layout.call(this); //Attach table to DOM. - this.table = this.wrap.append('table').classed('table', this.config.bootstrap); // apply class to incorporate bootstrap styling + this.table = this.wrap.append('table').classed('table', this.config.bootstrap); // apply class to incorporate bootstrap styling - this.thead = this.table.append('thead'); - this.thead.append('tr'); - this.tbody = this.table.append('tbody'); //Attach container after table. + this.thead = this.table.append('thead'); + this.thead.append('tr'); + this.tbody = this.table.append('tbody'); //Attach container after table. - this.wrap.append('div').classed('table-bottom', true); //Attach pagination container. + this.wrap.append('div').classed('table-bottom', true); //Attach pagination container. - this.pagination.layout.call(this); //Attach data export container. + this.pagination.layout.call(this); //Attach data export container. - this.exportable.layout.call(this); //Call layout callback. + this.exportable.layout.call(this); //Call layout callback. - this.events.onLayout.call(this); + this.events.onLayout.call(this); } function destroy$2() { - var destroyControls = - arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - //run onDestroy callback - this.events.onDestroy.call(this); //destroy controls + var destroyControls = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + //run onDestroy callback + this.events.onDestroy.call(this); //destroy controls + + if (destroyControls && this.controls) { + this.controls.destroy(); + } //unmount chart wrapper - if (destroyControls && this.controls) { - this.controls.destroy(); - } //unmount chart wrapper - this.wrap.remove(); + this.wrap.remove(); } function setDefault(setting) { - var _default_ = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var _default_ = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - this.config[setting] = - this.config[setting] !== undefined ? this.config[setting] : _default_; + this.config[setting] = this.config[setting] !== undefined ? this.config[setting] : _default_; } function setDefaults$1(firstItem) { - var _this = this; - - // 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, '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'); + var _this = this; + + // 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, '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; + var _this = this; - //Transform data. - this.data.processed = this.transformData(this.wrap.datum); + //Transform data. + this.data.processed = this.transformData(this.wrap.datum); - if (!data) { - return; - } + if (!data) { + return; + } - this.config.cols = this.config.cols || d3.keys(data[0]); - this.config.headers = this.config.headers || this.config.cols; + 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); - } - }); + 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 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 nuarr = r.map(function (m) { + var arr = []; + + for (var x in m) { + arr.push({ + col: x, + text: m[x] }); - } + } - var slimmed = d3 - .nest() - .key(function(d) { - if (_this.config.row_per) { - return _this.config.row_per - .map(function(m) { - return d[m]; - }) - .join(' '); - } else { - return d; - } - }) - .rollup(function(r) { - if (_this.config.dataManipulate) { - r = _this.config.dataManipulate(r); - } - - 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: [] - } - ]; // dummy nested data array - //Reset pagination. - - this.pagination.wrap.selectAll('*').remove(); - this.events.onDatatransform.call(this); - /**-------------------------------------------------------------------------------------------\ + 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: [] + }]; // dummy nested data array + //Reset pagination. + + this.pagination.wrap.selectAll('*').remove(); + this.events.onDatatransform.call(this); + /**-------------------------------------------------------------------------------------------\ Code below associated with the former paradigm of a d3.nest() data array. \-------------------------------------------------------------------------------------------**/ - 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]; - }); - }); - } //Delete text from columns with repeated values? - - if (config.row_per) { - rows.filter(function(f, i) { - return i > 0; - }) - .selectAll('td') - .filter(function(f) { - return config.row_per.indexOf(f.col) > -1; - }) - .text(''); - } + 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]; + }); + }); + } //Delete text from columns with repeated values? - return this.data.current; + + 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 - } + 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() {} - }; + 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']; + thisTable.on = function (event, callback) { + var possible_events = ['init', 'layout', 'preprocess', 'draw', 'destroy']; - if (possible_events.indexOf(event) < 0) { - return; - } + if (possible_events.indexOf(event) < 0) { + return; + } + + if (callback) { + thisTable.events['on' + event.charAt(0).toUpperCase() + event.slice(1)] = callback; + } + }; //increment thisChart count to get unique thisChart id - 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; + 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); //Define container for legend that overrides multiples' legends. - - chart.master_legend = chart.wrap.append('ul').attr('class', 'legend'); - chart.master_legend.append('span').classed('legend-title', true); //Instantiate multiples array. - - 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)); - }); - } + var test = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; + chart.wrap.classed('wc-layout wc-small-multiples', true).classed('wc-chart', false); //Define container for legend that overrides multiples' legends. - 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); - }); - } + chart.master_legend = chart.wrap.append('ul').attr('class', 'legend'); + chart.master_legend.append('span').classed('legend-title', true); //Instantiate multiples array. + + chart.multiples = []; + + function goAhead(data) { + var split_vals = d3.set(data.map(function (m) { + return m[split_by]; + })).values().filter(function (f) { + return f; + }); - goAhead(data); + 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; - }); + 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'; - } + 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); - }); + 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; + }); + return my_data; } var dataOps = { - getValType: getValType, - lengthenRaw: lengthenRaw, - naturalSorter: naturalSorter, - summarize: summarize + getValType: getValType, + lengthenRaw: lengthenRaw, + naturalSorter: naturalSorter, + summarize: summarize }; var index = { - version: version, - createChart: createChart, - createControls: createControls, - createTable: createTable, - multiply: multiply, - dataOps: dataOps + version: version, + createChart: createChart, + createControls: createControls, + createTable: createTable, + multiply: multiply, + dataOps: dataOps }; return index; -}); + +}))); diff --git a/css/webcharts.css b/css/webcharts.css index a64215a..8c4207b 100644 --- a/css/webcharts.css +++ b/css/webcharts.css @@ -71,7 +71,7 @@ } *[class*="wc-"] .legend { - width: 100%; + width: 100%; font-size: .9em; padding: 0; margin: 0; diff --git a/src/chart/resize/makeLegend.js b/src/chart/resize/makeLegend.js index a6d3243..eecea2f 100644 --- a/src/chart/resize/makeLegend.js +++ b/src/chart/resize/makeLegend.js @@ -1,130 +1,42 @@ +import moveLegend from './makeLegend/moveLegend'; +import defineLegendData from './makeLegend/defineLegendData'; +import addLegendTitle from './makeLegend/addLegendTitle'; +import addLegendItems from './makeLegend/addLegendItems'; +import addLegendMarks from './makeLegend/addLegendMarks'; import { ascending, select } from 'd3'; export default function makeLegend(scale = this.colorScale, label = '', custom_data = null) { - let config = this.config; + // should the legend be moved on layout? + this.legend = moveLegend.call(this); - config.legend.mark = (config.legend.mark || config.marks[0].type).replace(/bar|text/, 'square'); + // determine appropriate legend mark type + this.config.legend.mark = (this.config.legend.mark || this.config.marks[0].type).replace(/bar|text/, 'square'); - let legend_label = label - ? label - : typeof config.legend.label === 'string' - ? config.legend.label - : ''; + const legend_label = label || this.config.legend.label || ''; + const legend_data = defineLegendData.call(this, custom_data, scale); + const legend_title = addLegendTitle.call(this, legend_label); + const legend_items = this.legend + .selectAll('.legend-item') + .data(legend_data, d => d.label + d.mark); - let legendOriginal = this.legend || this.wrap.select('.legend'); - let legend = legendOriginal; - - if (!this.parent) { - //singular chart - 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 { - //multiples - keep legend outside of individual charts' wraps - if (this.config.legend.location === 'top' || this.config.legend.location === 'left') { - this.parent.wrap - .node() - .insertBefore(legendOriginal.node(), this.parent.wrap.select('.wc-chart').node()); - } else { - this.parent.wrap.node().appendChild(legendOriginal.node()); - } - } - - legend.style('padding', 0); - - let legend_data = - custom_data || - scale - .domain() - .slice(0) - .filter(f => f !== undefined && f !== null) - .map(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'); - - let leg_parts = legend.selectAll('.legend-item').data(legend_data, d => d.label + d.mark); - - leg_parts.exit().remove(); + legend_items.exit().remove(); const legendPartDisplay = this.config.legend.location === 'bottom' || this.config.legend.location === 'top' ? 'inline-block' : 'block'; - let 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', d => 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); + const new_parts = addLegendItems.call(this, legend_items, scale); + + legend_items.style('display', legendPartDisplay); - if (config.legend.order) { - leg_parts.sort((a, b) => - ascending(config.legend.order.indexOf(a.label), config.legend.order.indexOf(b.label)) + if (this.config.legend.order) { + legend_items.sort((a, b) => + ascending(this.config.legend.order.indexOf(a.label), this.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) { - let svg = 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', d => d.color || scale(d.label)) - .attr('stroke', d => d.color || scale(d.label)) - .each(function(e) { - select(this).attr(e.attributes); - }); + const legend_marks = addLegendMarks.call(this, legend_items, scale); new_parts .append('span') @@ -138,10 +50,8 @@ export default function makeLegend(scale = this.colorScale, label = '', custom_d !this.parent ? 'block' : 'inline-block'; - legend.style('display', legendDisplay); + this.legend.style('display', legendDisplay); } else { - legend.style('display', 'none'); + this.legend.style('display', 'none'); } - - this.legend = legend; } diff --git a/src/chart/resize/makeLegend/addLegendItems.js b/src/chart/resize/makeLegend/addLegendItems.js new file mode 100644 index 0000000..6ed7682 --- /dev/null +++ b/src/chart/resize/makeLegend/addLegendItems.js @@ -0,0 +1,22 @@ +export default function addLegendItems(leg_parts, scale) { + const 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', d => 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' + }); + + return new_parts; +} diff --git a/src/chart/resize/makeLegend/addLegendMarks.js b/src/chart/resize/makeLegend/addLegendMarks.js new file mode 100644 index 0000000..50c926a --- /dev/null +++ b/src/chart/resize/makeLegend/addLegendMarks.js @@ -0,0 +1,48 @@ +import { select } from 'd3'; + +export default function addLegendMarks(leg_parts, scale) { + leg_parts + .selectAll('.legend-color-block') + .select('.legend-mark') + .remove(); + + leg_parts + .selectAll('.legend-color-block') + .each(function(e) { + let svg = 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', d => d.color || scale(d.label)) + .attr('stroke', d => d.color || scale(d.label)) + .each(function(e) { + select(this).attr(e.attributes); + }); +} diff --git a/src/chart/resize/makeLegend/addLegendTitle.js b/src/chart/resize/makeLegend/addLegendTitle.js new file mode 100644 index 0000000..7ba2ba4 --- /dev/null +++ b/src/chart/resize/makeLegend/addLegendTitle.js @@ -0,0 +1,9 @@ +export default function addLegendTitle(legend_label) { + const legend_title = this.legend + .select('.legend-title') + .text(legend_label) + .style('display', legend_label ? 'inline' : 'none') + .style('margin-right', '1em'); + + return legend_title; +} diff --git a/src/chart/resize/makeLegend/defineLegendData.js b/src/chart/resize/makeLegend/defineLegendData.js new file mode 100644 index 0000000..e84bd5e --- /dev/null +++ b/src/chart/resize/makeLegend/defineLegendData.js @@ -0,0 +1,16 @@ +export default function defineLegendData(custom_data, scale) { + const legend_data = Array.isArray(custom_data) && custom_data.length + ? custom_data + : scale + .domain() + .slice(0) + .filter(f => f !== undefined && f !== null) + .map(m => { + return { + label: m, + mark: this.config.legend.mark + }; + }); + + return legend_data; +} diff --git a/src/chart/resize/makeLegend/moveLegend.js b/src/chart/resize/makeLegend/moveLegend.js new file mode 100644 index 0000000..27d3d10 --- /dev/null +++ b/src/chart/resize/makeLegend/moveLegend.js @@ -0,0 +1,23 @@ +export default function moveLegend() { + const legend = this.wrap.select('.legend'); + + if (!this.parent) { + //singular chart + if (this.config.legend.location === 'top' || this.config.legend.location === 'left') { + this.wrap.node().insertBefore(legend.node(), this.svg.node().parentNode); + } else { + this.wrap.node().appendChild(legend.node()); + } + } else { + //multiples - keep legend outside of individual charts' wraps + if (this.config.legend.location === 'top' || this.config.legend.location === 'left') { + this.parent.wrap + .node() + .insertBefore(legend.node(), this.parent.wrap.select('.wc-chart').node()); + } else { + this.parent.wrap.node().appendChild(legend.node()); + } + } + + return this.legend || legend; +} diff --git a/src/chart/resize/updateDataMarks/drawPoints.js b/src/chart/resize/updateDataMarks/drawPoints.js index 96b3b05..cc8a96d 100644 --- a/src/chart/resize/updateDataMarks/drawPoints.js +++ b/src/chart/resize/updateDataMarks/drawPoints.js @@ -49,6 +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 points.each(function(d) { let mark = select(this.parentNode).datum(); @@ -57,6 +58,7 @@ export default function drawPoints(marks) { .select('circle') .attr(mark.attributes); }); + // animated attributes let pointsTrans = config.transitions ? points.select('circle').transition() @@ -106,8 +108,8 @@ export default function drawPoints(marks) { }); // expand the plotting area slightly to prevent mark cutoff - const radius = max(marks, mark => mark.radius || this.config.flex_point_size); - if (marks.length) + if (marks.length) { + 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 @@ -120,6 +122,7 @@ export default function drawPoints(marks) { (radius + 1) + // translate up circle radius + circle stroke width ')' ); + } return points; } From 8bc03d061ba48f81f84794a96b5c0cd88b63bced Mon Sep 17 00:00:00 2001 From: Spencer Childress Date: Tue, 17 Dec 2019 18:34:45 -0500 Subject: [PATCH 11/14] need to present left- and right-oriented legend-items vertically --- build/webcharts.js | 168 ++++++++++-------- css/webcharts.css | 138 ++++++++------ src/chart/draw/consolidateData/setDefaults.js | 40 +++-- src/chart/draw/setColorScale.js | 4 +- src/chart/layout/addLegend.js | 11 +- src/chart/resize/makeLegend.js | 57 ++---- .../resize/makeLegend/addLegendColorBlocks.js | 11 ++ src/chart/resize/makeLegend/addLegendItems.js | 41 +++-- .../resize/makeLegend/addLegendLabels.js | 8 + .../resize/makeLegend/addLegendMarkTexts.js | 8 + src/chart/resize/makeLegend/addLegendMarks.js | 70 ++++---- src/chart/resize/makeLegend/addLegendTitle.js | 4 +- src/chart/resize/makeLegend/moveLegend.js | 7 +- test-page/createChart/index.js | 1 - 14 files changed, 321 insertions(+), 247 deletions(-) create mode 100644 src/chart/resize/makeLegend/addLegendColorBlocks.js create mode 100644 src/chart/resize/makeLegend/addLegendLabels.js create mode 100644 src/chart/resize/makeLegend/addLegendMarkTexts.js diff --git a/build/webcharts.js b/build/webcharts.js index a334abc..2a5e773 100644 --- a/build/webcharts.js +++ b/build/webcharts.js @@ -178,10 +178,13 @@ function addLegend() { //The legend is contained in the parent object of multiples so each multiple does not need its own legend. - if (!this.parent) this.wrap.append('ul').datum(function () { - return null; - }) // prevent data inheritance - .attr('class', 'legend').style('vertical-align', 'top').append('span').attr('class', 'legend-title'); + if (!this.parent) { + var legend = this.wrap.append('ul').datum(function () { + return null; + }) // prevent data inheritance + .classed('legend', true); + var legend_title = legend.append('span').classed('legend-title', true); + } } function clearLoader() { @@ -402,25 +405,32 @@ } function setDefaults() { + // x 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.x.range_band = this.config.x.range_band || this.config.range_band; // y + + this.config.y = this.config.y || {}; + this.config.y.label = this.config.y.label !== undefined ? this.config.y.label : this.config.y.column; + this.config.y.sort = this.config.y.sort || 'alphabetical-descending'; 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.y.range_band = this.config.y.range_band || this.config.range_band; // marks + 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; - }); + }); //legend + + 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.legend.mark = this.config.legend.mark !== undefined && typeof this.config.legend.mark === 'string' && ['bar', 'square', 'circle', 'line'].includes(this.config.legend.mark.toLowerCase()) ? this.config.legend.mark.toLowerCase().replace('bar', 'square') : this.config.marks[0].type !== undefined && typeof this.config.marks[0].type === 'string' && ['bar', 'circle', 'line'].includes(this.config.marks[0].type.toLowerCase()) ? this.config.marks[0].type.toLowerCase().replace('bar', 'square') : 'square'; // dimensions + + this.config.margin = this.config.margin || {}; // miscellaneous + this.config.date_format = this.config.date_format || '%x'; this.config.padding = this.config.padding !== undefined ? this.config.padding : 0.3; this.config.outer_pad = this.config.outer_pad !== undefined ? this.config.outer_pad : 0.1; @@ -860,8 +870,9 @@ 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(f => f && f !== 'undefined'); - + })).values().filter(function (f) { + return 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); @@ -1085,7 +1096,8 @@ } } - function moveLegend() { + // TODO: consider moving legend around DOM on layout rather than on resize + function moveLegend(scale) { var legend = this.wrap.select('.legend'); if (!this.parent) { @@ -1104,6 +1116,8 @@ } } + legend.classed("legend--".concat(this.config.legend.location), true).classed('legend--empty', scale.domain().length === 0); // display: none when color_by is not set? + return this.legend || legend; } @@ -1122,103 +1136,109 @@ } function addLegendTitle(legend_label) { - var legend_title = this.legend.select('.legend-title').text(legend_label).style('display', legend_label ? 'inline' : 'none').style('margin-right', '1em'); + var legend_title = this.legend.select('.legend-title').text(legend_label); return legend_title; } - function addLegendItems(leg_parts, scale) { - 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) { + function addLegendItems(legend_data, scale) { + var _this = this; + + // join data to legend-item selection + var all_legend_items = this.legend.selectAll('.legend-item').data(legend_data, function (d) { + return d.label + d.mark; + }); // exit and remove + + all_legend_items.exit().remove(); // enter and append + + var legend_items = all_legend_items.enter().append('li').classed('legend-item', true).classed("legend-item--".concat(this.config.legend.location), true); // update order of legend items in DOM + + if (this.config.legend.order) { + legend_items.sort(function (a, b) { + return d3.ascending(_this.config.legend.order.indexOf(a.label), _this.config.legend.order.indexOf(b.label)); + }); + } + + return legend_items; + } + + function addLegendMarkTexts(legend_items, scale) { + var legend_mark_texts = legend_items.append('span').classed('legend-mark-text', true).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' + return legend_mark_texts; + } + + function addLegendColorBlocks(legend_items) { + var legend_color_blocks = legend_items.append('svg').classed('legend-color-block', true).attr({ + width: '1.1em', + height: '1.1em' }); - return new_parts; + return legend_color_blocks; } - function addLegendMarks(leg_parts, scale) { - leg_parts.selectAll('.legend-color-block').select('.legend-mark').remove(); - leg_parts.selectAll('.legend-color-block').each(function (e) { + function addLegendMarks(legend_color_blocks, scale) { + legend_color_blocks.each(function (e) { var svg = d3.select(this); + svg.select('.legend-mark').remove(); if (e.mark === 'circle') { - svg.append('circle').attr({ + svg.append('circle').classed('legend-mark', true).attr({ cx: '.5em', cy: '.5em', - r: '.45em', - "class": 'legend-mark' + r: '.45em' }); } else if (e.mark === 'line') { - svg.append('line').attr({ + svg.append('line').classed('legend-mark', true).attr({ x1: 0, y1: '.5em', x2: '1em', y2: '.5em', 'stroke-width': 2, - 'shape-rendering': 'crispEdges', - "class": 'legend-mark' + 'shape-rendering': 'crispEdges' }); } else if (e.mark === 'square') { - svg.append('rect').attr({ + svg.append('rect').classed('legend-mark', true).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); + var legend_marks = legend_color_blocks.select('.legend-mark').attr({ + fill: function fill(d) { + return d.color || scale(d.label); + }, + stroke: function stroke(d) { + return d.color || scale(d.label); + } }).each(function (e) { + // apply custom mark attributes d3.select(this).attr(e.attributes); }); } - function makeLegend() { - var _this = this; + function addLegendLabels(legend_items) { + var legend_labels = legend_items.append('span').classed('legend-label', true).text(function (d) { + return d.label; + }); + return legend_labels; + } + 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; - // should the legend be moved on layout? - this.legend = moveLegend.call(this); // determine appropriate legend mark type + this.legend = moveLegend.call(this, scale); // determine appropriate legend settings and data - this.config.legend.mark = (this.config.legend.mark || this.config.marks[0].type).replace(/bar|text/, 'square'); var legend_label = label || this.config.legend.label || ''; - var legend_data = defineLegendData.call(this, custom_data, scale); - var legend_title = addLegendTitle.call(this, legend_label); - var legend_items = this.legend.selectAll('.legend-item').data(legend_data, function (d) { - return d.label + d.mark; - }); - legend_items.exit().remove(); - var legendPartDisplay = this.config.legend.location === 'bottom' || this.config.legend.location === 'top' ? 'inline-block' : 'block'; - var new_parts = addLegendItems.call(this, legend_items, scale); - legend_items.style('display', legendPartDisplay); - - if (this.config.legend.order) { - legend_items.sort(function (a, b) { - return d3.ascending(_this.config.legend.order.indexOf(a.label), _this.config.legend.order.indexOf(b.label)); - }); - } - - var legend_marks = addLegendMarks.call(this, legend_items, scale); - new_parts.append('span').attr('class', 'legend-label').style('margin-left', '0.25em').text(function (d) { - return d.label; - }); + var legend_data = defineLegendData.call(this, custom_data, scale); // add legend title and items - if (scale.domain().length > 0) { - var legendDisplay = (this.config.legend.location === 'bottom' || this.config.legend.location === 'top') && !this.parent ? 'block' : 'inline-block'; - this.legend.style('display', legendDisplay); - } else { - this.legend.style('display', 'none'); - } + var legend_title = addLegendTitle.call(this, legend_label); + var legend_items = addLegendItems.call(this, legend_data, scale); + var legend_mark_texts = addLegendMarkTexts.call(this, legend_items, scale); + var legend_color_blocks = addLegendColorBlocks.call(this, legend_items); + var legend_marks = addLegendMarks.call(this, legend_color_blocks, scale); + var legend_labels = addLegendLabels.call(this, legend_items); } function updateDataMarks() { diff --git a/css/webcharts.css b/css/webcharts.css index 8c4207b..f70871d 100644 --- a/css/webcharts.css +++ b/css/webcharts.css @@ -1,27 +1,3 @@ -/*------------------------------------------------------------------------------------------------\ - Small Multiple Layout -\------------------------------------------------------------------------------------------------*/ - - div.wc-layout.wc-small-multiples::after { - content: ""; - clear: both; - display: block; - } - - .wc-layout.wc-small-multiples > .wc-chart { - float: left; - padding: 0 2em 2em 0; - } - - .wc-layout.wc-small-multiples > .wc-chart > .wc-chart-title { - display: block; - font-weight: bold; - text-align: center; - } - .wc-small-multiples .wc-chart > .legend { - display: none; - } - /*------------------------------------------------------------------------------------------------\ Charts \------------------------------------------------------------------------------------------------*/ @@ -70,42 +46,104 @@ fill: #555; } - *[class*="wc-"] .legend { - width: 100%; - font-size: .9em; - padding: 0; - margin: 0; - display: inline-block; + .wc-chart .ordinal.axis .tick line, + .wc-chart .ordinal.axis path { + display: none; } - *[class*="wc-"] .legend .legend-title { - font-weight: bold; - margin-right: 1em; + .wc-chart.gridlines .ordinal.axis .tick line { + display: block; } - *[class*="wc-"] .legend .legend-item { - display: inline-block; - margin-right: 1em; - } + /**-------------------------------------------------------------------------------------------\ + Legend + \-------------------------------------------------------------------------------------------**/ - *[class*="wc-"] .legend .legend-item .legend-color-block { - position: relative; - top: .2em; - right: .25em; - display: inline-block; - } - *[class*="wc-"] .legend .legend-item .legend-mark-text { - font-weight: bold; - margin-right: .5em; + *[class*="wc-"] .legend { + width: 100%; + font-size: .9em; + padding: 0; + margin: 0; + display: inline-block; + } + + *[class*="wc-"] .legend--left, + *[class*="wc-"] .legend--right { + display: block; + } + + *[class*="wc-"] .legend--right { + float: right; + } + + *[class*="wc-"] .legend--empty { + display: none; + } + + *[class*="wc-"] .legend .legend-title { + display: inline; + font-weight: bold; + margin-right: 1em; + vertical-align: top; + } + + *[class*="wc-"] .legend .legend-title:empty { + display: none; + } + + *[class*="wc-"] .legend .legend-item { + display: inline-block; + list-style-type: none; + margin-right: 1em; + } + + *[class*="wc-"] .legend .legend-item--left, + *[class*="wc-"] .legend .legend-item--right { + display: block; + } + + *[class*="wc-"] .legend .legend-item--right { + float: right; + } + + *[class*="wc-"] .legend .legend-item .legend-color-block { + position: relative; + top: .2em; + right: .25em; + display: inline-block; + } + + *[class*="wc-"] .legend .legend-item .legend-mark-text { + font-weight: bold; + margin-right: .5em; + } + + *[class*="wc-"] .legend .legend-item .legend-label { + margin-left: 0.25em; + } + +/*------------------------------------------------------------------------------------------------\ + Small multiples +\------------------------------------------------------------------------------------------------*/ + + div.wc-layout.wc-small-multiples::after { + content: ""; + clear: both; + display: block; } - .wc-chart .ordinal.axis .tick line, - .wc-chart .ordinal.axis path { - display: none; + .wc-layout.wc-small-multiples > .wc-chart { + float: left; + padding: 0 2em 2em 0; } - .wc-chart.gridlines .ordinal.axis .tick line { + .wc-layout.wc-small-multiples > .wc-chart > .wc-chart-title { display: block; + font-weight: bold; + text-align: center; + } + .wc-small-multiples .wc-chart > .legend { + display: none; } /*------------------------------------------------------------------------------------------------\ diff --git a/src/chart/draw/consolidateData/setDefaults.js b/src/chart/draw/consolidateData/setDefaults.js index def69ab..9237bb3 100644 --- a/src/chart/draw/consolidateData/setDefaults.js +++ b/src/chart/draw/consolidateData/setDefaults.js @@ -1,33 +1,45 @@ export default function setDefaults() { + // x 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.x.sort = this.config.x.sort || 'alphabetical-ascending'; + this.config.x.type = this.config.x.type || 'linear'; + this.config.x.range_band = this.config.x.range_band || this.config.range_band; + + // y + this.config.y = this.config.y || {}; 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'; + // marks 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; }); + //legend + 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.legend.mark = this.config.legend.mark !== undefined && typeof this.config.legend.mark === 'string' && ['bar', 'square', 'circle', 'line'].includes(this.config.legend.mark.toLowerCase()) + ? this.config.legend.mark.toLowerCase().replace('bar', 'square') + : this.config.marks[0].type !== undefined && typeof this.config.marks[0].type === 'string' && ['bar', 'circle', 'line'].includes(this.config.marks[0].type.toLowerCase()) + ? this.config.marks[0].type.toLowerCase().replace('bar', 'square') + : 'square'; + + // dimensions + this.config.margin = this.config.margin || {}; + + // miscellaneous this.config.date_format = this.config.date_format || '%x'; this.config.padding = this.config.padding !== undefined ? this.config.padding : 0.3; diff --git a/src/chart/draw/setColorScale.js b/src/chart/draw/setColorScale.js index 8efeb35..d0c2a21 100644 --- a/src/chart/draw/setColorScale.js +++ b/src/chart/draw/setColorScale.js @@ -7,8 +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 !== 'undefined'); if (config.legend.order) colordom.sort((a, b) => diff --git a/src/chart/layout/addLegend.js b/src/chart/layout/addLegend.js index a3aa1cb..661c86f 100644 --- a/src/chart/layout/addLegend.js +++ b/src/chart/layout/addLegend.js @@ -1,11 +1,12 @@ export default function addLegend() { //The legend is contained in the parent object of multiples so each multiple does not need its own legend. - if (!this.parent) - this.wrap + if (!this.parent) { + const legend = this.wrap .append('ul') .datum(() => null) // prevent data inheritance - .attr('class', 'legend') - .style('vertical-align', 'top') + .classed('legend', true); + const legend_title = legend .append('span') - .attr('class', 'legend-title'); + .classed('legend-title', true); + } } diff --git a/src/chart/resize/makeLegend.js b/src/chart/resize/makeLegend.js index eecea2f..b1fff8f 100644 --- a/src/chart/resize/makeLegend.js +++ b/src/chart/resize/makeLegend.js @@ -2,56 +2,23 @@ import moveLegend from './makeLegend/moveLegend'; import defineLegendData from './makeLegend/defineLegendData'; import addLegendTitle from './makeLegend/addLegendTitle'; import addLegendItems from './makeLegend/addLegendItems'; +import addLegendMarkTexts from './makeLegend/addLegendMarkTexts'; +import addLegendColorBlocks from './makeLegend/addLegendColorBlocks'; import addLegendMarks from './makeLegend/addLegendMarks'; -import { ascending, select } from 'd3'; +import addLegendLabels from './makeLegend/addLegendLabels'; export default function makeLegend(scale = this.colorScale, label = '', custom_data = null) { - // should the legend be moved on layout? - this.legend = moveLegend.call(this); - - // determine appropriate legend mark type - this.config.legend.mark = (this.config.legend.mark || this.config.marks[0].type).replace(/bar|text/, 'square'); + this.legend = moveLegend.call(this, scale); + // determine appropriate legend settings and data const legend_label = label || this.config.legend.label || ''; const legend_data = defineLegendData.call(this, custom_data, scale); - const legend_title = addLegendTitle.call(this, legend_label); - const legend_items = this.legend - .selectAll('.legend-item') - .data(legend_data, d => d.label + d.mark); - - legend_items.exit().remove(); - - const legendPartDisplay = - this.config.legend.location === 'bottom' || this.config.legend.location === 'top' - ? 'inline-block' - : 'block'; - - const new_parts = addLegendItems.call(this, legend_items, scale); - legend_items.style('display', legendPartDisplay); - - if (this.config.legend.order) { - legend_items.sort((a, b) => - ascending(this.config.legend.order.indexOf(a.label), this.config.legend.order.indexOf(b.label)) - ); - } - - const legend_marks = addLegendMarks.call(this, legend_items, scale); - - new_parts - .append('span') - .attr('class', 'legend-label') - .style('margin-left', '0.25em') - .text(d => d.label); - - if (scale.domain().length > 0) { - const legendDisplay = - (this.config.legend.location === 'bottom' || this.config.legend.location === 'top') && - !this.parent - ? 'block' - : 'inline-block'; - this.legend.style('display', legendDisplay); - } else { - this.legend.style('display', 'none'); - } + // add legend title and items + const legend_title = addLegendTitle.call(this, legend_label); + const legend_items = addLegendItems.call(this, legend_data, scale); + const legend_mark_texts = addLegendMarkTexts.call(this, legend_items, scale); + const legend_color_blocks = addLegendColorBlocks.call(this, legend_items); + const legend_marks = addLegendMarks.call(this, legend_color_blocks, scale); + const legend_labels = addLegendLabels.call(this, legend_items); } diff --git a/src/chart/resize/makeLegend/addLegendColorBlocks.js b/src/chart/resize/makeLegend/addLegendColorBlocks.js new file mode 100644 index 0000000..a0b39f9 --- /dev/null +++ b/src/chart/resize/makeLegend/addLegendColorBlocks.js @@ -0,0 +1,11 @@ +export default function addLegendColorBlocks(legend_items) { + const legend_color_blocks = legend_items + .append('svg') + .classed('legend-color-block', true) + .attr({ + width: '1.1em', + height: '1.1em', + }); + + return legend_color_blocks; +} diff --git a/src/chart/resize/makeLegend/addLegendItems.js b/src/chart/resize/makeLegend/addLegendItems.js index 6ed7682..57bb3f0 100644 --- a/src/chart/resize/makeLegend/addLegendItems.js +++ b/src/chart/resize/makeLegend/addLegendItems.js @@ -1,22 +1,27 @@ -export default function addLegendItems(leg_parts, scale) { - const new_parts = leg_parts +import { ascending } from 'd3'; + +export default function addLegendItems(legend_data, scale) { + // join data to legend-item selection + const all_legend_items = this.legend + .selectAll('.legend-item') + .data(legend_data, d => d.label + d.mark); + + // exit and remove + all_legend_items.exit().remove(); + + // enter and append + const legend_items = all_legend_items .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', d => 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' - }); + .classed('legend-item', true) + .classed(`legend-item--${this.config.legend.location}`, true); + + // update order of legend items in DOM + if (this.config.legend.order) { + legend_items.sort((a, b) => + ascending(this.config.legend.order.indexOf(a.label), this.config.legend.order.indexOf(b.label)) + ); + } - return new_parts; + return legend_items; } diff --git a/src/chart/resize/makeLegend/addLegendLabels.js b/src/chart/resize/makeLegend/addLegendLabels.js new file mode 100644 index 0000000..d63145d --- /dev/null +++ b/src/chart/resize/makeLegend/addLegendLabels.js @@ -0,0 +1,8 @@ +export default function addLegendLabels(legend_items) { + const legend_labels = legend_items + .append('span') + .classed('legend-label', true) + .text(d => d.label); + + return legend_labels; +} diff --git a/src/chart/resize/makeLegend/addLegendMarkTexts.js b/src/chart/resize/makeLegend/addLegendMarkTexts.js new file mode 100644 index 0000000..04cdaf8 --- /dev/null +++ b/src/chart/resize/makeLegend/addLegendMarkTexts.js @@ -0,0 +1,8 @@ +export default function addLegendMarkTexts(legend_items, scale) { + const legend_mark_texts = legend_items + .append('span') + .classed('legend-mark-text', true) + .style('color', d => scale(d.label)); + + return legend_mark_texts; +} diff --git a/src/chart/resize/makeLegend/addLegendMarks.js b/src/chart/resize/makeLegend/addLegendMarks.js index 50c926a..bc228b6 100644 --- a/src/chart/resize/makeLegend/addLegendMarks.js +++ b/src/chart/resize/makeLegend/addLegendMarks.js @@ -1,48 +1,50 @@ import { select } from 'd3'; -export default function addLegendMarks(leg_parts, scale) { - leg_parts - .selectAll('.legend-color-block') - .select('.legend-mark') - .remove(); - - leg_parts - .selectAll('.legend-color-block') +export default function addLegendMarks(legend_color_blocks, scale) { + legend_color_blocks .each(function(e) { - let svg = select(this); + const svg = select(this); + svg.select('.legend-mark') + .remove(); + if (e.mark === 'circle') { - svg.append('circle').attr({ - cx: '.5em', - cy: '.5em', - r: '.45em', - class: 'legend-mark' - }); + svg.append('circle') + .classed('legend-mark', true) + .attr({ + cx: '.5em', + cy: '.5em', + r: '.45em', + }); } 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' - }); + svg.append('line') + .classed('legend-mark', true) + .attr({ + x1: 0, + y1: '.5em', + x2: '1em', + y2: '.5em', + 'stroke-width': 2, + 'shape-rendering': 'crispEdges', + }); } else if (e.mark === 'square') { - svg.append('rect').attr({ - height: '1em', - width: '1em', - class: 'legend-mark', - 'shape-rendering': 'crispEdges' - }); + svg.append('rect') + .classed('legend-mark', true) + .attr({ + height: '1em', + width: '1em', + 'shape-rendering': 'crispEdges' + }); } }); - leg_parts - .selectAll('.legend-color-block') + const legend_marks = legend_color_blocks .select('.legend-mark') - .attr('fill', d => d.color || scale(d.label)) - .attr('stroke', d => d.color || scale(d.label)) + .attr({ + fill: d => d.color || scale(d.label), + stroke: d => d.color || scale(d.label), + }) .each(function(e) { + // apply custom mark attributes select(this).attr(e.attributes); }); } diff --git a/src/chart/resize/makeLegend/addLegendTitle.js b/src/chart/resize/makeLegend/addLegendTitle.js index 7ba2ba4..55f393f 100644 --- a/src/chart/resize/makeLegend/addLegendTitle.js +++ b/src/chart/resize/makeLegend/addLegendTitle.js @@ -1,9 +1,7 @@ export default function addLegendTitle(legend_label) { const legend_title = this.legend .select('.legend-title') - .text(legend_label) - .style('display', legend_label ? 'inline' : 'none') - .style('margin-right', '1em'); + .text(legend_label); return legend_title; } diff --git a/src/chart/resize/makeLegend/moveLegend.js b/src/chart/resize/makeLegend/moveLegend.js index 27d3d10..7e4ae4f 100644 --- a/src/chart/resize/makeLegend/moveLegend.js +++ b/src/chart/resize/makeLegend/moveLegend.js @@ -1,4 +1,5 @@ -export default function moveLegend() { +// TODO: consider moving legend around DOM on layout rather than on resize +export default function moveLegend(scale) { const legend = this.wrap.select('.legend'); if (!this.parent) { @@ -19,5 +20,9 @@ export default function moveLegend() { } } + legend + .classed(`legend--${this.config.legend.location}`, true) + .classed('legend--empty', scale.domain().length === 0); // display: none when color_by is not set? + return this.legend || legend; } diff --git a/test-page/createChart/index.js b/test-page/createChart/index.js index 04f42f1..684192e 100644 --- a/test-page/createChart/index.js +++ b/test-page/createChart/index.js @@ -23,7 +23,6 @@ const settings = { color_by: 'species', legend: { label: 'Species', - mark: 'circle', location: 'bottom', }, aspect: 3, From f694996ac893864fd620cbee9d0437a70222dfd1 Mon Sep 17 00:00:00 2001 From: Spencer Childress Date: Tue, 17 Dec 2019 22:13:49 -0500 Subject: [PATCH 12/14] fix #75 --- build/webcharts.js | 7067 ++++++++++------- build/webcharts.min.js | 6 +- css/webcharts.css | 32 +- css/webcharts.min.css | 2 +- package-lock.json | 11 +- src/chart/draw/consolidateData/setDefaults.js | 25 +- src/chart/draw/setColorScale.js | 5 +- src/chart/layout/addLegend.js | 4 +- .../resize/makeLegend/addLegendColorBlocks.js | 2 +- src/chart/resize/makeLegend/addLegendItems.js | 8 +- src/chart/resize/makeLegend/addLegendMarks.js | 68 +- src/chart/resize/makeLegend/addLegendTitle.js | 4 +- .../resize/makeLegend/defineLegendData.js | 21 +- test-page/createChart/index.js | 1 - 14 files changed, 4312 insertions(+), 2944 deletions(-) diff --git a/build/webcharts.js b/build/webcharts.js index 2a5e773..917dd21 100644 --- a/build/webcharts.js +++ b/build/webcharts.js @@ -1,696 +1,1005 @@ -(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'; +(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); - }); - } + 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; + this.wrap.attr('class', 'wc-chart'); + this.setDefaults(); + this.raw_data = data; + this.initial_data = data; - var startup = function startup(data) { - // connect this chart and its controls, if any - if (_this.controls) { - _this.controls.targets.push(_this); + var startup = function startup(data) { + // connect this chart and its controls, if any + if (_this.controls) { + _this.controls.targets.push(_this); - if (!_this.controls.ready) { - _this.controls.init(_this.raw_data); - } else { - _this.controls.layout(); - } - } // make sure container is visible (has height and width) before trying to initialize + if (!_this.controls.ready) { + _this.controls.init(_this.raw_data); + } else { + _this.controls.layout(); + } + } // make sure container is visible (has height and width) before trying to initialize + var visible = d3.select(_this.div).property('offsetWidth') > 0 || test; - 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) { - 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(); - if (visible_now) { - _this.layout(); + _this.draw(); - _this.draw(); + clearInterval(onVisible); + } + }, 500); + } else { + _this.layout(); - clearInterval(onVisible); + _this.draw(); } - }, 500); - } else { - _this.layout(); - - _this.draw(); - } - }; + }; - this.events.onInit.call(this); + this.events.onInit.call(this); - if (this.raw_data.length) { - this.checkRequired(this.raw_data); - } + if (this.raw_data.length) { + this.checkRequired(this.raw_data); + } - startup(); - return this; + 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); - } + var _this = this; - if (this.config.color_by) { - requiredVars.push('this.config.color_by'); - requiredCols.push(this.config.color_by); - } + var colnames = Object.keys(data[0]); + var requiredVars = []; + var requiredCols = []; - 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 (this.config.x && this.config.x.column) { + requiredVars.push('this.config.x.column'); + requiredCols.push(this.config.x.column); } - if (e.split) { - requiredVars.push('this.config.marks[' + i + '].split'); - requiredCols.push(e.split); + if (this.config.y && this.config.y.column) { + requiredVars.push('this.config.y.column'); + requiredCols.push(this.config.y.column); } - if (e.values && e.checkColumns) { - for (var value in e.values) { - requiredVars.push('this.config.marks[' + i + "].values['" + value + "']"); - requiredCols.push(value); - } + if (this.config.color_by) { + requiredVars.push('this.config.color_by'); + requiredCols.push(this.config.color_by); } - }); - 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 - }; + 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; - }) // prevent data inheritance - .attr({ - "class": 'wc-svg', - xmlns: 'http://www.w3.org/2000/svg', - version: '1.1', - xlink: 'http://www.w3.org/1999/xlink' - }).append('g').style('display', 'inline-block'); + this.svg = this.wrap + .append('svg') + .datum(function() { + return null; + }) // prevent data inheritance + .attr({ + class: 'wc-svg', + xmlns: 'http://www.w3.org/2000/svg', + version: '1.1', + xlink: 'http://www.w3.org/1999/xlink' + }) + .append('g') + .style('display', 'inline-block'); } function addDefs() { - var defs = this.svg.append('defs'); //Add pattern. - - defs.append('pattern').attr({ - id: 'diagonal-stripes', - x: 0, - y: 0, - width: 3, - height: 8, - patternUnits: 'userSpaceOnUse', - patternTransform: 'rotate(30)' - }).append('rect').attr({ - x: '0', - y: '0', - width: '2', - height: '8' - }).style({ - stroke: 'none', - fill: 'black' - }); //Add clipPath. - - defs.append('clipPath').attr('id', this.id).append('rect').attr('class', 'plotting-area'); + var defs = this.svg.append('defs'); //Add pattern. + + defs.append('pattern') + .attr({ + id: 'diagonal-stripes', + x: 0, + y: 0, + width: 3, + height: 8, + patternUnits: 'userSpaceOnUse', + patternTransform: 'rotate(30)' + }) + .append('rect') + .attr({ + x: '0', + y: '0', + width: '2', + height: '8' + }) + .style({ + stroke: 'none', + fill: 'black' + }); //Add clipPath. + + defs.append('clipPath') + .attr('id', this.id) + .append('rect') + .attr('class', 'plotting-area'); } function addXAxis() { - this.svg.append('g').attr('class', 'x axis').append('text').attr('class', 'axis-title').attr('dy', '-.35em').attr('text-anchor', 'middle'); + this.svg + .append('g') + .attr('class', 'x axis') + .append('text') + .attr('class', 'axis-title') + .attr('dy', '-.35em') + .attr('text-anchor', 'middle'); } function addYAxis() { - this.svg.append('g').attr('class', 'y axis').append('text').attr('class', 'axis-title').attr('transform', 'rotate(-90)').attr('dy', '.75em').attr('text-anchor', 'middle'); + this.svg + .append('g') + .attr('class', 'y axis') + .append('text') + .attr('class', 'axis-title') + .attr('transform', 'rotate(-90)') + .attr('dy', '.75em') + .attr('text-anchor', 'middle'); } function addOverlay() { - this.overlay = this.svg.append('rect').attr('class', 'overlay').attr('opacity', 0).attr('fill', 'none').style('pointer-events', 'all'); + this.overlay = this.svg + .append('rect') + .attr('class', 'overlay') + .attr('opacity', 0) + .attr('fill', 'none') + .style('pointer-events', 'all'); } function addLegend() { - //The legend is contained in the parent object of multiples so each multiple does not need its own legend. - if (!this.parent) { - var legend = this.wrap.append('ul').datum(function () { - return null; - }) // prevent data inheritance - .classed('legend', true); - var legend_title = legend.append('span').classed('legend-title', true); - } + //The legend is contained in the parent object of multiples so each multiple does not need its own legend. + if (!this.parent) { + var legend = this.wrap + .append('ul') + .datum(function() { + return null; + }) // prevent data inheritance + .classed('legend', true); + var legend_title = legend.append('span').classed('legend-title', true); + } } function clearLoader() { - d3.select(this.div).select('.loader').remove(); + 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); + 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; //if pre-processing callback, run it now - - this.events.onPreprocess.call(this); ///////////////////////// - // Data prep pipeline // - ///////////////////////// - // if user passed raw_data to chart.draw(), use that, otherwise use chart.raw_data - - var raw = raw_data ? raw_data : this.raw_data ? this.raw_data : []; // warn the user about the perils of "processed_data" - - if (processed_data) { - console.warn("Drawing the chart using user-defined 'processed_data', this is an experimental, untested feature."); - } //Call consolidateData - this applies filters from controls and prepares data for each set of marks. - - - this.consolidateData(raw); ///////////////////////////// - // Prepare scales and axes // - ///////////////////////////// - - 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); - } + var _this = this; + + var chart = this; + var config = this.config; //if pre-processing callback, run it now + + this.events.onPreprocess.call(this); ///////////////////////// + // Data prep pipeline // + ///////////////////////// + // if user passed raw_data to chart.draw(), use that, otherwise use chart.raw_data + + var raw = raw_data ? raw_data : this.raw_data ? this.raw_data : []; // warn the user about the perils of "processed_data" + + if (processed_data) { + console.warn( + "Drawing the chart using user-defined 'processed_data', this is an experimental, untested feature." + ); + } //Call consolidateData - this applies filters from controls and prepares data for each set of marks. + + this.consolidateData(raw); ///////////////////////////// + // Prepare scales and axes // + ///////////////////////////// + + 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); - this.events.onDraw.call(this); ////////////////////////////////////////////////////////////////////// - // Call resize - updates marks on the chart (amongst other things) // - ///////////////////////////////////////////////////////////////////// + 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.resize(); + this.events.onDraw.call(this); ////////////////////////////////////////////////////////////////////// + // Call resize - updates marks on the chart (amongst other things) // + ///////////////////////////////////////////////////////////////////// + + this.resize(); } function naturalSorter(a, b) { - //adapted from http://www.davekoelle.com/files/alphanum.js - 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; - } + //adapted from http://www.davekoelle.com/files/alphanum.js + 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; + } - tz[y] += j; + return tz; } - return tz; - } + var aa = chunkify(a.toLowerCase()); + var bb = chunkify(b.toLowerCase()); - 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]); - 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; - } + if (c == aa[x] && d == bb[x]) { + return c - d; + } else { + return aa[x] > bb[x] ? 1 : -1; + } + } } - } - return aa.length - bb.length; + return aa.length - bb.length; } function setDomain(axis) { - var _this = this; - - var otherAxis = axis === 'x' ? 'y' : 'x'; - - if (this.config[axis].type === 'ordinal') { - //ordinal domains - if (this.config[axis].domain) { - //user-defined domain - this[axis + '_dom'] = this.config[axis].domain; - } else if (this.config[axis].order) { - //data-driven domain with user-defined domain order - this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { - return mark[axis + '_dom']; - }))).values().sort(function (a, b) { - return d3.ascending(_this.config[axis].order.indexOf(a), _this.config[axis].order.indexOf(b)); - }); - } else if (this.config[axis].sort && this.config[axis].sort === 'alphabetical-ascending') { - //data-driven domain with user-defined domain sort algorithm that sorts the axis - //alphanumerically, first to last - this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { - return mark[axis + '_dom']; - }))).values().sort(naturalSorter); - } else if (['time', 'linear'].indexOf(this.config[otherAxis].type) > -1 && this.config[axis].sort === 'earliest') { - //data-driven domain plotted against a time or linear axis that sorts the axis values - //by earliest event/datum; generally used with timeline charts - this[axis + '_dom'] = d3.nest().key(function (d) { - return d[_this.config[axis].column]; - }).rollup(function (d) { - return d.map(function (m) { - return m[_this.config[otherAxis].column]; - }).filter(function (f) { - return f instanceof Date; - }); - }).entries(this.filtered_data).sort(function (a, b) { - return d3.min(b.values) - d3.min(a.values); - }).map(function (m) { - return m.key; - }); - } else if (!this.config[axis].sort || this.config[axis].sort === 'alphabetical-descending') { - //data-driven domain with default/user-defined domain sort algorithm that sorts the - //axis alphanumerically, last to first - this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { - return mark[axis + '_dom']; - }))).values().sort(naturalSorter).reverse(); + var _this = this; + + var otherAxis = axis === 'x' ? 'y' : 'x'; + + if (this.config[axis].type === 'ordinal') { + //ordinal domains + if (this.config[axis].domain) { + //user-defined domain + this[axis + '_dom'] = this.config[axis].domain; + } else if (this.config[axis].order) { + //data-driven domain with user-defined domain order + this[axis + '_dom'] = d3 + .set( + d3.merge( + this.marks.map(function(mark) { + return mark[axis + '_dom']; + }) + ) + ) + .values() + .sort(function(a, b) { + return d3.ascending( + _this.config[axis].order.indexOf(a), + _this.config[axis].order.indexOf(b) + ); + }); + } else if ( + this.config[axis].sort && + this.config[axis].sort === 'alphabetical-ascending' + ) { + //data-driven domain with user-defined domain sort algorithm that sorts the axis + //alphanumerically, first to last + this[axis + '_dom'] = d3 + .set( + d3.merge( + this.marks.map(function(mark) { + return mark[axis + '_dom']; + }) + ) + ) + .values() + .sort(naturalSorter); + } else if ( + ['time', 'linear'].indexOf(this.config[otherAxis].type) > -1 && + this.config[axis].sort === 'earliest' + ) { + //data-driven domain plotted against a time or linear axis that sorts the axis values + //by earliest event/datum; generally used with timeline charts + this[axis + '_dom'] = d3 + .nest() + .key(function(d) { + return d[_this.config[axis].column]; + }) + .rollup(function(d) { + return d + .map(function(m) { + return m[_this.config[otherAxis].column]; + }) + .filter(function(f) { + return f instanceof Date; + }); + }) + .entries(this.filtered_data) + .sort(function(a, b) { + return d3.min(b.values) - d3.min(a.values); + }) + .map(function(m) { + return m.key; + }); + } else if ( + !this.config[axis].sort || + this.config[axis].sort === 'alphabetical-descending' + ) { + //data-driven domain with default/user-defined domain sort algorithm that sorts the + //axis alphanumerically, last to first + this[axis + '_dom'] = d3 + .set( + d3.merge( + this.marks.map(function(mark) { + return mark[axis + '_dom']; + }) + ) + ) + .values() + .sort(naturalSorter) + .reverse(); + } else { + //data-driven domain with an invalid user-defined sort algorithm that captures a unique + //set of values as they appear in the data + this[axis + '_dom'] = d3 + .set( + d3.merge( + this.marks.map(function(mark) { + return mark[axis + '_dom']; + }) + ) + ) + .values(); + } + } else if ( + this.config.marks + .map(function(m) { + return m['summarize' + axis.toUpperCase()] === 'percent'; + }) + .indexOf(true) > -1 + ) { + //rate domains run from 0 to 1 + this[axis + '_dom'] = [0, 1]; } else { - //data-driven domain with an invalid user-defined sort algorithm that captures a unique - //set of values as they appear in the data - this[axis + '_dom'] = d3.set(d3.merge(this.marks.map(function (mark) { - return mark[axis + '_dom']; - }))).values(); - } - } else if (this.config.marks.map(function (m) { - return m['summarize' + axis.toUpperCase()] === 'percent'; - }).indexOf(true) > -1) { - //rate domains run from 0 to 1 - this[axis + '_dom'] = [0, 1]; - } else { - //continuous domains run from the minimum to the maximum raw (or is it summarized...?) value - //TODO: they should really run from the minimum to the maximum summarized value, e.g. a - //TODO: means over time chart should plot over the range of the means, not the range of the - //TODO: raw data - this[axis + '_dom'] = d3.extent(d3.merge(this.marks.map(function (mark) { - return mark[axis + '_dom']; - }))); - } //Give the domain a range when the range of the variable is 0. - - - if (this.config[axis].type === 'linear' && this[axis + '_dom'][0] === this[axis + '_dom'][1]) this[axis + '_dom'] = this[axis + '_dom'][0] !== 0 ? [this[axis + '_dom'][0] - this[axis + '_dom'][0] * 0.01, this[axis + '_dom'][1] + this[axis + '_dom'][1] * 0.01] : [-1, 1]; - return this[axis + '_dom']; + //continuous domains run from the minimum to the maximum raw (or is it summarized...?) value + //TODO: they should really run from the minimum to the maximum summarized value, e.g. a + //TODO: means over time chart should plot over the range of the means, not the range of the + //TODO: raw data + this[axis + '_dom'] = d3.extent( + d3.merge( + this.marks.map(function(mark) { + return mark[axis + '_dom']; + }) + ) + ); + } //Give the domain a range when the range of the variable is 0. + + if ( + this.config[axis].type === 'linear' && + this[axis + '_dom'][0] === this[axis + '_dom'][1] + ) + this[axis + '_dom'] = + this[axis + '_dom'][0] !== 0 + ? [ + this[axis + '_dom'][0] - this[axis + '_dom'][0] * 0.01, + this[axis + '_dom'][1] + this[axis + '_dom'][1] * 0.01 + ] + : [-1, 1]; + return this[axis + '_dom']; } function consolidateData(raw) { - var _this = this; + var _this = this; - this.setDefaults(); //Apply filters from associated controls objects to raw data. + this.setDefaults(); //Apply filters from associated controls objects to raw data. - this.filtered_data = raw; + 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 + ''; - }); - }); - } //Summarize data for each mark. - - - this.config.marks.forEach(function (mark, i) { - if (mark.type !== 'bar') { - mark.arrange = null; - mark.split = null; - } + 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 + ''; + }); + }); + } //Summarize data for each mark. - var mark_info = mark.per ? _this.transformData(raw, mark) : { - data: [], - x_dom: [], - y_dom: [] - }; - _this.marks[i] = Object.assign({}, mark, mark_info); - }); //Set domains given extents of summarized mark data. + this.config.marks.forEach(function(mark, i) { + if (mark.type !== 'bar') { + mark.arrange = null; + mark.split = null; + } - setDomain.call(this, 'x'); - setDomain.call(this, 'y'); + var mark_info = mark.per + ? _this.transformData(raw, mark) + : { + data: [], + x_dom: [], + y_dom: [] + }; + _this.marks[i] = Object.assign({}, mark, mark_info); + }); //Set domains given extents of summarized mark data. + + setDomain.call(this, 'x'); + setDomain.call(this, 'y'); } function setDefaults() { - // x - this.config.x = this.config.x || {}; - this.config.x.label = this.config.x.label !== undefined ? this.config.x.label : this.config.x.column; - this.config.x.sort = this.config.x.sort || 'alphabetical-ascending'; - this.config.x.type = this.config.x.type || 'linear'; - this.config.x.range_band = this.config.x.range_band || this.config.range_band; // y - - this.config.y = this.config.y || {}; - this.config.y.label = this.config.y.label !== undefined ? this.config.y.label : this.config.y.column; - this.config.y.sort = this.config.y.sort || 'alphabetical-descending'; - this.config.y.type = this.config.y.type || 'linear'; - this.config.y.range_band = this.config.y.range_band || this.config.range_band; // marks - - 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; - }); //legend - - 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.legend.mark = this.config.legend.mark !== undefined && typeof this.config.legend.mark === 'string' && ['bar', 'square', 'circle', 'line'].includes(this.config.legend.mark.toLowerCase()) ? this.config.legend.mark.toLowerCase().replace('bar', 'square') : this.config.marks[0].type !== undefined && typeof this.config.marks[0].type === 'string' && ['bar', 'circle', 'line'].includes(this.config.marks[0].type.toLowerCase()) ? this.config.marks[0].type.toLowerCase().replace('bar', 'square') : 'square'; // dimensions - - this.config.margin = this.config.margin || {}; // miscellaneous - - this.config.date_format = this.config.date_format || '%x'; - this.config.padding = this.config.padding !== undefined ? this.config.padding : 0.3; - this.config.outer_pad = this.config.outer_pad !== undefined ? this.config.outer_pad : 0.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; + // x + this.config.x = this.config.x || {}; + this.config.x.label = + this.config.x.label !== undefined ? this.config.x.label : this.config.x.column; + this.config.x.sort = this.config.x.sort || 'alphabetical-ascending'; + this.config.x.type = this.config.x.type || 'linear'; + this.config.x.range_band = this.config.x.range_band || this.config.range_band; // y + + this.config.y = this.config.y || {}; + this.config.y.label = + this.config.y.label !== undefined ? this.config.y.label : this.config.y.column; + this.config.y.sort = this.config.y.sort || 'alphabetical-descending'; + this.config.y.type = this.config.y.type || 'linear'; + this.config.y.range_band = this.config.y.range_band || this.config.range_band; // marks + + 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; + }); //legend + + 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.legend.mark = + this.config.legend.mark !== undefined && + typeof this.config.legend.mark === 'string' && + ['bar', 'square', 'circle', 'line'].includes(this.config.legend.mark.toLowerCase()) + ? this.config.legend.mark.toLowerCase().replace('bar', 'square') + : this.config.marks[0].type !== undefined && + typeof this.config.marks[0].type === 'string' && + ['bar', 'circle', 'line'].includes(this.config.marks[0].type.toLowerCase()) + ? this.config.marks[0].type.toLowerCase().replace('bar', 'square') + : 'square'; // dimensions + + this.config.margin = this.config.margin || {}; // miscellaneous + + this.config.date_format = this.config.date_format || '%x'; + this.config.padding = this.config.padding !== undefined ? this.config.padding : 0.3; + this.config.outer_pad = this.config.outer_pad !== undefined ? this.config.outer_pad : 0.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 _this = this; - var dateConvert = d3.time.format(this.config.date_format); - var clean = raw; // only use data for the current mark + var dateConvert = d3.time.format(this.config.date_format); + var clean = raw; // only use data for the current mark - clean = mark.per && mark.per.length ? clean.filter(function (f) { - return f[mark.per[0]] !== undefined; - }) : clean; // Make sure data has x and y values - - if (this.config.x.column) { - clean = clean.filter(function (f) { - return [undefined, null].indexOf(f[_this.config.x.column]) < 0; - }); - } + clean = + mark.per && mark.per.length + ? clean.filter(function(f) { + return f[mark.per[0]] !== undefined; + }) + : clean; // Make sure data has x and y values - if (this.config.y.column) { - clean = clean.filter(function (f) { - return [undefined, null].indexOf(f[_this.config.y.column]) < 0; - }); - } //check that x and y have the correct formats + if (this.config.x.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; + }); + } //check that x and y have the correct formats - if (this.config.x.type === 'time') { - clean = clean.filter(function (f) { - return f[_this.config.x.column] instanceof Date ? f[_this.config.x.column] : dateConvert.parse(f[_this.config.x.column]); - }); - clean.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.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.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])) // is or coerces to a number and is not a string that coerces to 0 - : f; - }); - } + if ( + (this.config.x.type === 'linear' || this.config.x.type === 'log') && + this.config.x.column + ) { + clean = clean.filter(function(f) { + return mark.summarizeX !== 'count' && mark.summarizeX !== 'percent' + ? !(isNaN(f[_this.config.x.column]) || /^\s*$/.test(f[_this.config.x.column])) // is or coerces to a number and is not a string that coerces to 0 + : f; + }); + } - if ((this.config.y.type === 'linear' || this.config.y.type === 'log') && this.config.y.column) { - clean = clean.filter(function (f) { - return mark.summarizeY !== 'count' && mark.summarizeY !== 'percent' ? !(isNaN(f[_this.config.y.column]) || /^\s*$/.test(f[_this.config.y.column])) // is or coerces to a number and is not a string that coerces to 0 - : f; - }); - } + if ( + (this.config.y.type === 'linear' || this.config.y.type === 'log') && + this.config.y.column + ) { + clean = clean.filter(function(f) { + return mark.summarizeY !== 'count' && mark.summarizeY !== 'percent' + ? !(isNaN(f[_this.config.y.column]) || /^\s*$/.test(f[_this.config.y.column])) // is or coerces to a number and is not a string that coerces to 0 + : f; + }); + } - return clean; + return clean; } var stats = { - mean: d3.mean, - min: d3.min, - max: d3.max, - median: d3.median, - sum: d3.sum + 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; - }); + 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; - } + if (operation === 'cumulative') { + return null; + } - var mathed = operation === 'count' ? vals.length : operation === 'percent' ? vals.length : stats[operation](nvals); - return mathed; + 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(' '); - }); - } + 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; - }); - } + 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, 0.25) : obj.x; - obj.x_q75 = _this.config.error_bars && _this.config.y.type === 'ordinal' ? d3.quantile(x_vals, 0.75) : obj.x; - obj.y_q25 = _this.config.error_bars ? d3.quantile(y_vals, 0.25) : obj.y; - obj.y_q75 = _this.config.error_bars ? d3.quantile(y_vals, 0.75) : obj.y; - dom_xs.push([obj.x_q25, obj.x_q75, obj.x]); - dom_ys.push([obj.y_q25, obj.y_q75, obj.y]); - - if (mark.summarizeY === 'cumulative') { - var interm = entries.filter(function (f) { - return _this.config.x.type === 'time' ? new Date(f[_this.config.x.column]) <= new Date(r[0][_this.config.x.column]) : +f[_this.config.x.column] <= +r[0][_this.config.x.column]; - }); - - 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) { - //calculate percentages in bars - test.forEach(function (e) { - var axis = _this.config.x.type === 'ordinal' || _this.config.x.type === 'linear' && _this.config.x.bin ? 'y' : 'x'; - e.total = d3.sum(e.values.map(function (m) { - return +m.values[axis]; - })); - 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; + this_nest.rollup(function(r) { + var obj = { + raw: r + }; + var y_vals = r + .map(function(m) { + return m[_this.config.y.column]; + }) + .sort(d3.ascending); + var x_vals = r + .map(function(m) { + return m[_this.config.x.column]; + }) + .sort(d3.ascending); + obj.x = + _this.config.x.type === 'ordinal' + ? r[0][_this.config.x.column] + : summarize(x_vals, mark.summarizeX); + obj.y = + _this.config.y.type === 'ordinal' + ? r[0][_this.config.y.column] + : summarize(y_vals, mark.summarizeY); + obj.x_q25 = + _this.config.error_bars && _this.config.y.type === 'ordinal' + ? d3.quantile(x_vals, 0.25) + : obj.x; + obj.x_q75 = + _this.config.error_bars && _this.config.y.type === 'ordinal' + ? d3.quantile(x_vals, 0.75) + : obj.x; + obj.y_q25 = _this.config.error_bars ? d3.quantile(y_vals, 0.25) : obj.y; + obj.y_q75 = _this.config.error_bars ? d3.quantile(y_vals, 0.75) : obj.y; + dom_xs.push([obj.x_q25, obj.x_q75, obj.x]); + dom_ys.push([obj.y_q25, obj.y_q75, obj.y]); + + if (mark.summarizeY === 'cumulative') { + var interm = entries.filter(function(f) { + return _this.config.x.type === 'time' + ? new Date(f[_this.config.x.column]) <= + new Date(r[0][_this.config.x.column]) + : +f[_this.config.x.column] <= +r[0][_this.config.x.column]; + }); + + 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.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 (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; + } - 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 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) { + //calculate percentages in bars + test.forEach(function(e) { + var axis = + _this.config.x.type === 'ordinal' || + (_this.config.x.type === 'linear' && _this.config.x.bin) + ? 'y' + : 'x'; + e.total = d3.sum( + e.values.map(function(m) { + return +m.values[axis]; + }) + ); + 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; + } + }); + }); - return { - nested: test, - dom_x: dom_x, - dom_y: dom_y, - totalOrder: totalOrder - }; + 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 + }; } // transformData(raw, mark) provides specifications and data for @@ -704,2698 +1013,3746 @@ //////////////////////////////////////////////////////// function transformData(raw, mark) { - var _this = this; - - //convenience mappings - 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; ////////////////////////////////////////////////////////////////////////////////// - // DATA PREP - // prepare data based on the properties of the mark - drop missing records, etc - ////////////////////////////////////////////////////////////////////////////////// - - var cleaned = cleanData.call(this, mark, raw); //prepare nested data required for bar charts - - 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); - } // Get the domain for the mark based on the raw data - - - var raw_dom_x = mark.summarizeX === 'cumulative' ? [0, cleaned.length] : config.x.type === 'ordinal' ? d3.set(cleaned.map(function (m) { - return m[config.x.column]; - })).values().filter(function (f) { - return f; - }) : mark.split && mark.arrange !== 'stacked' ? d3.extent(d3.merge(raw_nest.nested.map(function (m) { - return m.values.map(function (p) { - return p.values.raw.length; - }); - }))) : mark.summarizeX === 'count' ? d3.extent(raw_nest.nested.map(function (m) { - return m.values.raw.length; - })) : d3.extent(cleaned.map(function (m) { - return +m[config.x.column]; - }).filter(function (f) { - return +f || +f === 0; - })); - var raw_dom_y = mark.summarizeY === 'cumulative' ? [0, cleaned.length] : config.y.type === 'ordinal' ? d3.set(cleaned.map(function (m) { - return m[config.y.column]; - })).values().filter(function (f) { - return f; - }) : mark.split && mark.arrange !== 'stacked' ? d3.extent(d3.merge(raw_nest.nested.map(function (m) { - return m.values.map(function (p) { - return p.values.raw.length; - }); - }))) : mark.summarizeY === 'count' ? d3.extent(raw_nest.nested.map(function (m) { - return m.values.raw.length; - })) : d3.extent(cleaned.map(function (m) { - return +m[config.y.column]; - }).filter(function (f) { - return +f || +f === 0; - })); - var 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() + ''; - }); - }); //get domain for all non-All values of first filter - - if (config.x.behavior === 'firstfilter' || config.y.behavior === 'firstfilter') { - this.filters[0].choices.filter(function (f) { - return f !== 'All'; - }).forEach(function (e) { - var perfilter = cleaned.filter(function (f) { - return f[_this.filters[0].col] === e; - }); - var filt_nested = makeNest.call(_this, mark, perfilter, sublevel); - filt1_xs.push(filt_nested.dom_x); - filt1_ys.push(filt_nested.dom_y); - }); - } - } //filter on mark-specific instructions - - - if (mark.values) { - var _loop = function _loop(a) { - filtered = filtered.filter(function (f) { - return mark.values[a].indexOf(f[a]) > -1; - }); - }; + var _this = this; + + //convenience mappings + 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; ////////////////////////////////////////////////////////////////////////////////// + // DATA PREP + // prepare data based on the properties of the mark - drop missing records, etc + ////////////////////////////////////////////////////////////////////////////////// + + var cleaned = cleanData.call(this, mark, raw); //prepare nested data required for bar charts + + 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); + } // Get the domain for the mark based on the raw data + + var raw_dom_x = + mark.summarizeX === 'cumulative' + ? [0, cleaned.length] + : config.x.type === 'ordinal' + ? d3 + .set( + cleaned.map(function(m) { + return m[config.x.column]; + }) + ) + .values() + .filter(function(f) { + return f; + }) + : mark.split && mark.arrange !== 'stacked' + ? d3.extent( + d3.merge( + raw_nest.nested.map(function(m) { + return m.values.map(function(p) { + return p.values.raw.length; + }); + }) + ) + ) + : mark.summarizeX === 'count' + ? d3.extent( + raw_nest.nested.map(function(m) { + return m.values.raw.length; + }) + ) + : d3.extent( + cleaned + .map(function(m) { + return +m[config.x.column]; + }) + .filter(function(f) { + return +f || +f === 0; + }) + ); + var raw_dom_y = + mark.summarizeY === 'cumulative' + ? [0, cleaned.length] + : config.y.type === 'ordinal' + ? d3 + .set( + cleaned.map(function(m) { + return m[config.y.column]; + }) + ) + .values() + .filter(function(f) { + return f; + }) + : mark.split && mark.arrange !== 'stacked' + ? d3.extent( + d3.merge( + raw_nest.nested.map(function(m) { + return m.values.map(function(p) { + return p.values.raw.length; + }); + }) + ) + ) + : mark.summarizeY === 'count' + ? d3.extent( + raw_nest.nested.map(function(m) { + return m.values.raw.length; + }) + ) + : d3.extent( + cleaned + .map(function(m) { + return +m[config.y.column]; + }) + .filter(function(f) { + return +f || +f === 0; + }) + ); + var 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() + ''; + }); + }); //get domain for all non-All values of first filter + + if (config.x.behavior === 'firstfilter' || config.y.behavior === 'firstfilter') { + this.filters[0].choices + .filter(function(f) { + return f !== 'All'; + }) + .forEach(function(e) { + var perfilter = cleaned.filter(function(f) { + return f[_this.filters[0].col] === e; + }); + var filt_nested = makeNest.call(_this, mark, perfilter, sublevel); + filt1_xs.push(filt_nested.dom_x); + filt1_ys.push(filt_nested.dom_y); + }); + } + } //filter on mark-specific instructions + + 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]; - } - } //several criteria must be met in order to use the 'firstfilter' domain - - - var nonall = Boolean(this.filters.length && this.filters[0].val !== 'All' && this.filters.slice(1).filter(function (f) { - return f.val === 'All'; - }).length === this.filters.length - 1); - var pre_x_dom = !this.filters.length ? flex_dom_x : x_behavior === 'raw' ? raw_dom_x : nonall && x_behavior === 'firstfilter' ? filt1_dom_x : flex_dom_x; - var pre_y_dom = !this.filters.length ? flex_dom_y : y_behavior === 'raw' ? raw_dom_y : nonall && y_behavior === 'firstfilter' ? filt1_dom_y : flex_dom_y; - var x_dom = config.x_dom ? config.x_dom : config.x.type === 'ordinal' && config.x.behavior === 'flex' ? d3.set(filtered.map(function (m) { - return m[config.x.column]; - })).values() : config.x.type === 'ordinal' ? d3.set(cleaned.map(function (m) { - return m[config.x.column]; - })).values() : pre_x_dom; - var y_dom = config.y_dom ? config.y_dom : config.y.type === 'ordinal' && config.y.behavior === 'flex' ? d3.set(filtered.map(function (m) { - return m[config.y.column]; - })).values() : config.y.type === 'ordinal' ? d3.set(cleaned.map(function (m) { - return m[config.y.column]; - })).values() : pre_y_dom; //set lower limit of linear domain to 0 when other axis is ordinal and mark type is set to 'bar', provided no values are negative - - if (mark.type === 'bar') { - if (config.x.behavior !== 'flex' && config.x.type === 'linear' && config.y.type === 'ordinal' && raw_dom_x[0] >= 0) x_dom[0] = 0; - if (config.y.behavior !== 'flex' && config.x.type === 'ordinal' && config.y.type === 'linear' && raw_dom_y[0] >= 0) y_dom[0] = 0; - } //update domains with those specified in the config - - - if (config.x.domain && (config.x.domain[0] || config.x.domain[0] === 0) && !isNaN(+config.x.domain[0])) { - 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 - }; + 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]; + } + } //several criteria must be met in order to use the 'firstfilter' domain + + var nonall = Boolean( + this.filters.length && + this.filters[0].val !== 'All' && + this.filters.slice(1).filter(function(f) { + return f.val === 'All'; + }).length === + this.filters.length - 1 + ); + var pre_x_dom = !this.filters.length + ? flex_dom_x + : x_behavior === 'raw' + ? raw_dom_x + : nonall && x_behavior === 'firstfilter' + ? filt1_dom_x + : flex_dom_x; + var pre_y_dom = !this.filters.length + ? flex_dom_y + : y_behavior === 'raw' + ? raw_dom_y + : nonall && y_behavior === 'firstfilter' + ? filt1_dom_y + : flex_dom_y; + var x_dom = config.x_dom + ? config.x_dom + : config.x.type === 'ordinal' && config.x.behavior === 'flex' + ? d3 + .set( + filtered.map(function(m) { + return m[config.x.column]; + }) + ) + .values() + : config.x.type === 'ordinal' + ? d3 + .set( + cleaned.map(function(m) { + return m[config.x.column]; + }) + ) + .values() + : pre_x_dom; + var y_dom = config.y_dom + ? config.y_dom + : config.y.type === 'ordinal' && config.y.behavior === 'flex' + ? d3 + .set( + filtered.map(function(m) { + return m[config.y.column]; + }) + ) + .values() + : config.y.type === 'ordinal' + ? d3 + .set( + cleaned.map(function(m) { + return m[config.y.column]; + }) + ) + .values() + : pre_y_dom; //set lower limit of linear domain to 0 when other axis is ordinal and mark type is set to 'bar', provided no values are negative + + if (mark.type === 'bar') { + if ( + config.x.behavior !== 'flex' && + config.x.type === 'linear' && + config.y.type === 'ordinal' && + raw_dom_x[0] >= 0 + ) + x_dom[0] = 0; + if ( + config.y.behavior !== 'flex' && + config.x.type === 'ordinal' && + config.y.type === 'linear' && + raw_dom_y[0] >= 0 + ) + y_dom[0] = 0; + } //update domains with those specified in the config + + if ( + config.x.domain && + (config.x.domain[0] || config.x.domain[0] === 0) && + !isNaN(+config.x.domain[0]) + ) { + 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 !== '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); + 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 !== '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; + 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; + 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 < max_width ? div_width : this.raw_width; - this.textSize(preWidth); - this.margin = this.setMargins(); - var svg_width = config.x.type === 'ordinal' && +config.x.range_band ? this.raw_width + this.margin.left + this.margin.right : !config.resizable ? this.raw_width : !config.max_width || div_width < config.max_width ? div_width : this.raw_width; - this.plot_width = svg_width - this.margin.left - this.margin.right; - var svg_height = config.y.type === 'ordinal' && +config.y.range_band ? this.raw_height + this.margin.top + this.margin.bottom : !config.resizable && config.height ? config.height : !config.resizable ? svg_width * aspect2 : this.plot_width * aspect2; - this.plot_height = svg_height - this.margin.top - this.margin.bottom; - d3.select(this.svg.node().parentNode).attr('width', svg_width).attr('height', svg_height).select('g').attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')'); - this.svg.select('.overlay').attr('width', this.plot_width).attr('height', this.plot_height).classed('zoomable', config.zoomable); - this.svg.select('.plotting-area').attr('width', this.plot_width).attr('height', this.plot_height + 1).attr('transform', 'translate(0, -1)'); - this.xScaleAxis(); - this.yScaleAxis(); - var g_x_axis = this.svg.select('.x.axis'); - var g_y_axis = this.svg.select('.y.axis'); - var x_axis_label = g_x_axis.select('.axis-title'); - var y_axis_label = g_y_axis.select('.axis-title'); - - if (config.x_location !== 'top') { - g_x_axis.attr('transform', 'translate(0,' + this.plot_height + ')'); - } - - var gXAxisTrans = config.transitions ? g_x_axis.transition() : g_x_axis; - gXAxisTrans.call(this.xAxis); - var gYAxisTrans = config.transitions ? g_y_axis.transition() : g_y_axis; - gYAxisTrans.call(this.yAxis); - x_axis_label.attr('transform', 'translate(' + this.plot_width / 2 + ',' + (this.margin.bottom - 2) + ')'); - y_axis_label.attr('x', -1 * this.plot_height / 2).attr('y', -1 * this.margin.left); - this.svg.selectAll('.axis .domain').attr({ - fill: 'none', - stroke: '#ccc', - 'stroke-width': 1, - 'shape-rendering': 'crispEdges' - }); - this.svg.selectAll('.axis .tick line').attr({ - stroke: '#eee', - 'stroke-width': 1, - 'shape-rendering': 'crispEdges' - }); - this.drawGridlines(); //update legend - margins need to be set first - - this.makeLegend(); //update the chart's specific marks - - this.updateDataMarks(); //call .on("resize") function, if any - - this.events.onResize.call(this); + 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 < max_width + ? div_width + : this.raw_width; + this.textSize(preWidth); + this.margin = this.setMargins(); + var svg_width = + config.x.type === 'ordinal' && +config.x.range_band + ? this.raw_width + this.margin.left + this.margin.right + : !config.resizable + ? this.raw_width + : !config.max_width || div_width < config.max_width + ? div_width + : this.raw_width; + this.plot_width = svg_width - this.margin.left - this.margin.right; + var svg_height = + config.y.type === 'ordinal' && +config.y.range_band + ? this.raw_height + this.margin.top + this.margin.bottom + : !config.resizable && config.height + ? config.height + : !config.resizable + ? svg_width * aspect2 + : this.plot_width * aspect2; + this.plot_height = svg_height - this.margin.top - this.margin.bottom; + d3.select(this.svg.node().parentNode) + .attr('width', svg_width) + .attr('height', svg_height) + .select('g') + .attr('transform', 'translate(' + this.margin.left + ',' + this.margin.top + ')'); + this.svg + .select('.overlay') + .attr('width', this.plot_width) + .attr('height', this.plot_height) + .classed('zoomable', config.zoomable); + this.svg + .select('.plotting-area') + .attr('width', this.plot_width) + .attr('height', this.plot_height + 1) + .attr('transform', 'translate(0, -1)'); + this.xScaleAxis(); + this.yScaleAxis(); + var g_x_axis = this.svg.select('.x.axis'); + var g_y_axis = this.svg.select('.y.axis'); + var x_axis_label = g_x_axis.select('.axis-title'); + var y_axis_label = g_y_axis.select('.axis-title'); + + if (config.x_location !== 'top') { + g_x_axis.attr('transform', 'translate(0,' + this.plot_height + ')'); + } + + var gXAxisTrans = config.transitions ? g_x_axis.transition() : g_x_axis; + gXAxisTrans.call(this.xAxis); + var gYAxisTrans = config.transitions ? g_y_axis.transition() : g_y_axis; + gYAxisTrans.call(this.yAxis); + x_axis_label.attr( + 'transform', + 'translate(' + this.plot_width / 2 + ',' + (this.margin.bottom - 2) + ')' + ); + y_axis_label.attr('x', (-1 * this.plot_height) / 2).attr('y', -1 * this.margin.left); + this.svg.selectAll('.axis .domain').attr({ + fill: 'none', + stroke: '#ccc', + 'stroke-width': 1, + 'shape-rendering': 'crispEdges' + }); + this.svg.selectAll('.axis .tick line').attr({ + stroke: '#eee', + 'stroke-width': 1, + 'shape-rendering': 'crispEdges' + }); + this.drawGridlines(); //update legend - margins need to be set first + + this.makeLegend(); //update the chart's specific marks + + this.updateDataMarks(); //call .on("resize") function, if any + + this.events.onResize.call(this); } function textSize(width) { - var font_size = '14px'; - var point_size = 4; - var stroke_width = 2; - - if (!this.config.scale_text) { - font_size = this.config.font_size; - point_size = this.config.point_size || 4; - stroke_width = this.config.stroke_width || 2; - } else if (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; + var font_size = '14px'; + var point_size = 4; + var stroke_width = 2; + + if (!this.config.scale_text) { + font_size = this.config.font_size; + point_size = this.config.point_size || 4; + stroke_width = this.config.stroke_width || 2; + } else if (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 : 0.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 * 0.5 + font_size * y_label_on * 1.5 || 8; - var x_margin = font_size + font_size / 1.5 + font_size * x_label_on + font_size * x_second || 8; - 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 - }; + 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 : 0.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 * 0.5 + font_size * y_label_on * 1.5 || 8; + var x_margin = + font_size + font_size / 1.5 + font_size * x_label_on + font_size * x_second || 8; + 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); - } + 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); + } } // TODO: consider moving legend around DOM on layout rather than on resize function moveLegend(scale) { - var legend = this.wrap.select('.legend'); + var legend = this.wrap.select('.legend'); - if (!this.parent) { - //singular chart - if (this.config.legend.location === 'top' || this.config.legend.location === 'left') { - this.wrap.node().insertBefore(legend.node(), this.svg.node().parentNode); - } else { - this.wrap.node().appendChild(legend.node()); - } - } else { - //multiples - keep legend outside of individual charts' wraps - if (this.config.legend.location === 'top' || this.config.legend.location === 'left') { - this.parent.wrap.node().insertBefore(legend.node(), this.parent.wrap.select('.wc-chart').node()); + if (!this.parent) { + //singular chart + if (this.config.legend.location === 'top' || this.config.legend.location === 'left') { + this.wrap.node().insertBefore(legend.node(), this.svg.node().parentNode); + } else { + this.wrap.node().appendChild(legend.node()); + } } else { - this.parent.wrap.node().appendChild(legend.node()); + //multiples - keep legend outside of individual charts' wraps + if (this.config.legend.location === 'top' || this.config.legend.location === 'left') { + this.parent.wrap + .node() + .insertBefore(legend.node(), this.parent.wrap.select('.wc-chart').node()); + } else { + this.parent.wrap.node().appendChild(legend.node()); + } } - } - legend.classed("legend--".concat(this.config.legend.location), true).classed('legend--empty', scale.domain().length === 0); // display: none when color_by is not set? + legend + .classed('legend--'.concat(this.config.legend.location), true) + .classed('legend--empty', scale.domain().length === 0); // display: none when color_by is not set? - return this.legend || legend; + return this.legend || legend; } function defineLegendData(custom_data, scale) { - var _this = this; - - var legend_data = Array.isArray(custom_data) && custom_data.length ? custom_data : scale.domain().slice(0).filter(function (f) { - return f !== undefined && f !== null; - }).map(function (m) { - return { - label: m, - mark: _this.config.legend.mark - }; - }); - return legend_data; + var _this = this; + + var legend_data = + Array.isArray(custom_data) && custom_data.length + ? custom_data + : scale + .domain() + .slice(0) + .filter(function(f) { + return f !== undefined && f !== null; + }) + .map(function(m) { + return { + label: m, + mark: _this.config.legend.mark + }; + }); + return legend_data; } function addLegendTitle(legend_label) { - var legend_title = this.legend.select('.legend-title').text(legend_label); - return legend_title; + var legend_title = this.legend.select('.legend-title').text(legend_label); + return legend_title; } function addLegendItems(legend_data, scale) { - var _this = this; - - // join data to legend-item selection - var all_legend_items = this.legend.selectAll('.legend-item').data(legend_data, function (d) { - return d.label + d.mark; - }); // exit and remove - - all_legend_items.exit().remove(); // enter and append - - var legend_items = all_legend_items.enter().append('li').classed('legend-item', true).classed("legend-item--".concat(this.config.legend.location), true); // update order of legend items in DOM - - if (this.config.legend.order) { - legend_items.sort(function (a, b) { - return d3.ascending(_this.config.legend.order.indexOf(a.label), _this.config.legend.order.indexOf(b.label)); - }); - } + var _this = this; + + // join data to legend-item selection + var all_legend_items = this.legend.selectAll('.legend-item').data(legend_data, function(d) { + return d.label + d.mark; + }); // exit and remove + + all_legend_items.exit().remove(); // enter and append + + var legend_items = all_legend_items + .enter() + .append('li') + .classed('legend-item', true); // update order of legend items in DOM + + if (this.config.legend.order) { + legend_items.sort(function(a, b) { + return d3.ascending( + _this.config.legend.order.indexOf(a.label), + _this.config.legend.order.indexOf(b.label) + ); + }); + } - return legend_items; + return legend_items; } function addLegendMarkTexts(legend_items, scale) { - var legend_mark_texts = legend_items.append('span').classed('legend-mark-text', true).style('color', function (d) { - return scale(d.label); - }); - return legend_mark_texts; + var legend_mark_texts = legend_items + .append('span') + .classed('legend-mark-text', true) + .style('color', function(d) { + return scale(d.label); + }); + return legend_mark_texts; } function addLegendColorBlocks(legend_items) { - var legend_color_blocks = legend_items.append('svg').classed('legend-color-block', true).attr({ - width: '1.1em', - height: '1.1em' - }); - return legend_color_blocks; + var legend_color_blocks = legend_items + .append('svg') + .classed('legend-color-block', true) + .attr({ + width: '1.1em', + height: '1.1em' + }); + return legend_color_blocks; } function addLegendMarks(legend_color_blocks, scale) { - legend_color_blocks.each(function (e) { - var svg = d3.select(this); - svg.select('.legend-mark').remove(); - - if (e.mark === 'circle') { - svg.append('circle').classed('legend-mark', true).attr({ - cx: '.5em', - cy: '.5em', - r: '.45em' - }); - } else if (e.mark === 'line') { - svg.append('line').classed('legend-mark', true).attr({ - x1: 0, - y1: '.5em', - x2: '1em', - y2: '.5em', - 'stroke-width': 2, - 'shape-rendering': 'crispEdges' - }); - } else if (e.mark === 'square') { - svg.append('rect').classed('legend-mark', true).attr({ - height: '1em', - width: '1em', - 'shape-rendering': 'crispEdges' - }); - } - }); - var legend_marks = legend_color_blocks.select('.legend-mark').attr({ - fill: function fill(d) { - return d.color || scale(d.label); - }, - stroke: function stroke(d) { - return d.color || scale(d.label); - } - }).each(function (e) { - // apply custom mark attributes - d3.select(this).attr(e.attributes); - }); + legend_color_blocks.each(function(e) { + var svg = d3.select(this); + svg.select('.legend-mark').remove(); + + if (e.mark === 'circle') { + svg.append('circle') + .classed('legend-mark', true) + .attr({ + cx: '.5em', + cy: '.5em', + r: '.45em' + }); + } else if (e.mark === 'line') { + svg.append('line') + .classed('legend-mark', true) + .attr({ + x1: 0, + y1: '.5em', + x2: '1em', + y2: '.5em', + 'stroke-width': 2, + 'shape-rendering': 'crispEdges' + }); + } else if (e.mark === 'square') { + svg.append('rect') + .classed('legend-mark', true) + .attr({ + height: '1em', + width: '1em', + 'shape-rendering': 'crispEdges' + }); + } + }); + var legend_marks = legend_color_blocks + .select('.legend-mark') + .attr({ + fill: function fill(d) { + return d.color || scale(d.label); + }, + stroke: function stroke(d) { + return d.color || scale(d.label); + } + }) + .each(function(e) { + // apply custom mark attributes + d3.select(this).attr(e.attributes); + }); } function addLegendLabels(legend_items) { - var legend_labels = legend_items.append('span').classed('legend-label', true).text(function (d) { - return d.label; - }); - return legend_labels; + var legend_labels = legend_items + .append('span') + .classed('legend-label', true) + .text(function(d) { + return d.label; + }); + return legend_labels; } 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; - this.legend = moveLegend.call(this, scale); // determine appropriate legend settings and data - - var legend_label = label || this.config.legend.label || ''; - var legend_data = defineLegendData.call(this, custom_data, scale); // add legend title and items - - var legend_title = addLegendTitle.call(this, legend_label); - var legend_items = addLegendItems.call(this, legend_data, scale); - var legend_mark_texts = addLegendMarkTexts.call(this, legend_items, scale); - var legend_color_blocks = addLegendColorBlocks.call(this, legend_items); - var legend_marks = addLegendMarks.call(this, legend_color_blocks, scale); - var legend_labels = addLegendLabels.call(this, legend_items); + 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; + this.legend = moveLegend.call(this, scale); // determine appropriate legend settings and data + + var legend_label = label || this.config.legend.label || ''; + var legend_data = defineLegendData.call(this, custom_data, scale); // add legend title and items + + var legend_title = addLegendTitle.call(this, legend_label); + var legend_items = addLegendItems.call(this, legend_data, scale); + var legend_mark_texts = addLegendMarkTexts.call(this, legend_items, scale); + var legend_color_blocks = addLegendColorBlocks.call(this, legend_items); + var legend_marks = addLegendMarks.call(this, legend_color_blocks, scale); + var legend_labels = addLegendLabels.call(this, legend_items); } 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'); + 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 : 0.3); //don't transition if config says not to - - var areaPathTransitions = this.config.transitions ? areaPaths.transition() : areaPaths; - areaPathTransitions.attr('d', area_drawer); - return area_grps; + 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 + : 0.3 + ); //don't transition if config says not to + + 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); - }) // 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('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 - - 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 - - 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 _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) + ); + }) // 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('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 + + bars.sort(function(a, b) { + return ( + _this.colorScale.domain().indexOf(a.key) - _this.colorScale.domain().indexOf(b.key) + ); }); - }); - 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); - }); + 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 + + 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 * 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); + }); } 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 - - 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 - - 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 * 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); + var _this = this; - 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 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 + + 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 + + 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 * 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); + + 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(); + } + }); } 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; + 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; }); - 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 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); - }); + 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; + 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; }); - 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 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); - }); + 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; // bar super-groups - - 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 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 - - 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(); - } //Link to the d3.selection from the data + var rawData = this.raw_data; + var config = this.config; // bar super-groups - - bar_supergroups.each(function (d) { - d.supergroup = d3.select(this); - d.groups = d.supergroup.selectAll('.bar-group'); - }); + 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 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 + + 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(); + } //Link to the d3.selection from the data + + 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]; + 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('-'); }); - }); //Link to the d3.selection from the data - - 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; + 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]; + }); + }); //Link to the d3.selection from the data + + 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'); // static attributes - - points.select('circle').style('clip-path', "url(#".concat(chart.id, ")")).attr('fill-opacity', config.fill_opacity || config.fill_opacity === 0 ? config.fill_opacity : 0.6).attr('fill', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }).attr('stroke', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }); // attach mark info - - points.each(function (d) { - var mark = d3.select(this.parentNode).datum(); - d.mark = mark; - d3.select(this).select('circle').attr(mark.attributes); - }); // animated attributes - - var pointsTrans = config.transitions ? points.select('circle').transition() : points.select('circle'); - pointsTrans.attr('r', function (d) { - return d.mark.radius || config.flex_point_size; - }).attr('cx', function (d) { - var x_pos = _this.x(d.values.x) || 0; - return config.x.type === 'ordinal' ? x_pos + _this.x.rangeBand() / 2 : x_pos; - }).attr('cy', function (d) { - var y_pos = _this.y(d.values.y) || 0; - return config.y.type === 'ordinal' ? y_pos + _this.y.rangeBand() / 2 : y_pos; - }); - points.select('title').text(function (d) { - var tt = d.mark.tooltip || ''; - var xformat = config.x.summary === 'percent' ? d3.format('0%') : config.x.type === 'time' ? d3.time.format(config.x.format) : d3.format(config.x.format); - var yformat = config.y.summary === 'percent' ? d3.format('0%') : config.y.type === 'time' ? d3.time.format(config.y.format) : d3.format(config.y.format); - return tt.replace(/\$x/g, config.x.type === 'time' ? xformat(new Date(d.values.x)) : xformat(d.values.x)).replace(/\$y/g, config.y.type === 'time' ? yformat(new Date(d.values.y)) : yformat(d.values.y)).replace(/\[(.+?)\]/g, function (str, orig) { - return d.values.raw[0][orig]; + var _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('-'); }); - }); // Link to the d3.selection from the data + 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'); // static attributes + + points + .select('circle') + .style('clip-path', 'url(#'.concat(chart.id, ')')) + .attr( + 'fill-opacity', + config.fill_opacity || config.fill_opacity === 0 ? config.fill_opacity : 0.6 + ) + .attr('fill', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }) + .attr('stroke', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }); // attach mark info + + points.each(function(d) { + var mark = d3.select(this.parentNode).datum(); + d.mark = mark; + d3.select(this) + .select('circle') + .attr(mark.attributes); + }); // animated attributes + + var pointsTrans = config.transitions + ? points.select('circle').transition() + : points.select('circle'); + pointsTrans + .attr('r', function(d) { + return d.mark.radius || config.flex_point_size; + }) + .attr('cx', function(d) { + var x_pos = _this.x(d.values.x) || 0; + return config.x.type === 'ordinal' ? x_pos + _this.x.rangeBand() / 2 : x_pos; + }) + .attr('cy', function(d) { + var y_pos = _this.y(d.values.y) || 0; + return config.y.type === 'ordinal' ? y_pos + _this.y.rangeBand() / 2 : y_pos; + }); + 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]; + }); + }); // 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 + + if (marks.length) { + 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; + } - 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 + function drawText(marks) { + var _this = this; - if (marks.length) { - var radius = d3.max(marks, function (mark) { - return mark.radius || _this.config.flex_point_size; + 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('-')); }); - 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 - ')'); - } + 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(); // don't need to transition position of outgoing text + // const oldTextsTrans = config.transitions ? oldTexts.selectAll('text').transition() : oldTexts.selectAll('text'); + + 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'); // don't need to set initial location for incoming text + // attach mark info - return points; - } + function attachMarks(d) { + d.mark = d3.select(this.parentNode).datum(); + } - 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(); // don't need to transition position of outgoing text - // const oldTextsTrans = config.transitions ? oldTexts.selectAll('text').transition() : oldTexts.selectAll('text'); - - 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'); // don't need to set initial location for incoming text - // attach mark info - - function attachMarks(d) { - d.mark = d3.select(this.parentNode).datum(); - } - - texts.each(attachMarks); // parse text like tooltips - - texts.select('text').style('clip-path', "url(#".concat(chart.id, ")")).attr('fill', function (d) { - return _this.colorScale(d.values.raw[0][config.color_by]); - }).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]; + texts.each(attachMarks); // parse text like tooltips + + texts + .select('text') + .style('clip-path', 'url(#'.concat(chart.id, ')')) + .attr('fill', function(d) { + return _this.colorScale(d.values.raw[0][config.color_by]); + }) + .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]; + }); + }) + .each(function(d) { + d3.select(this).attr(d.mark.attributes); + }); // animated attributes + + var textsTrans = config.transitions + ? texts.select('text').transition() + : texts.select('text'); + textsTrans + .attr('x', function(d) { + var xPos = _this.x(d.values.x) || 0; + return config.x.type === 'ordinal' ? xPos + _this.x.rangeBand() / 2 : xPos; + }) + .attr('y', function(d) { + var yPos = _this.y(d.values.y) || 0; + return config.y.type === 'ordinal' ? yPos + _this.y.rangeBand() / 2 : yPos; + }); // add a reference to the selection from its data + + text_supergroups.each(function(d) { + d.supergroup = d3.select(this); + d.groups = d.supergroup.selectAll('g.text'); + d.texts = d.groups.select('text'); }); - }).each(function (d) { - d3.select(this).attr(d.mark.attributes); - }); // animated attributes - - var textsTrans = config.transitions ? texts.select('text').transition() : texts.select('text'); - textsTrans.attr('x', function (d) { - var xPos = _this.x(d.values.x) || 0; - return config.x.type === 'ordinal' ? xPos + _this.x.rangeBand() / 2 : xPos; - }).attr('y', function (d) { - var yPos = _this.y(d.values.y) || 0; - return config.y.type === 'ordinal' ? yPos + _this.y.rangeBand() / 2 : yPos; - }); // add a reference to the selection from its data - - 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; + return texts; } function destroy() { - var destroyControls = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; - //run onDestroy callback - this.events.onDestroy.call(this); //remove resize event listener - - var context = this; - if (!this.test) d3.select(window).on('resize.' + context.element + context.id, null); //destroy controls + var destroyControls = + arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true; + //run onDestroy callback + this.events.onDestroy.call(this); //remove resize event listener - if (destroyControls && this.controls) { - this.controls.destroy(); - } //unmount chart wrapper + var context = this; + if (!this.test) d3.select(window).on('resize.' + context.element + context.id, null); //destroy controls + if (destroyControls && this.controls) { + this.controls.destroy(); + } //unmount chart wrapper - this.wrap.remove(); + this.wrap.remove(); } var chartProto = { - raw_data: [], - config: {} + 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 - } + 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; - } + 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() {} + }; - if (callback) { - thisChart.events['on' + event.charAt(0).toUpperCase() + event.slice(1)] = callback; - } - }; //increment thisChart count to get unique thisChart id + 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; + } + }; //increment thisChart count to get unique thisChart id - chartCount++; - thisChart.id = chartCount; - return thisChart; + 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); - } //call callback function if provided + 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); + } //call callback function if provided - if (callback) { - callback(); - } + if (callback) { + callback(); + } - if (draw) target.draw(); - }); + 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.")); //Draw the chart when a control changes unless the user specifies otherwise. - - input.draw = input.draw === undefined ? true : input.draw; - }); + 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.' + ) + ); //Draw the chart when a control changes unless the user specifies otherwise. + + input.draw = input.draw === undefined ? true : input.draw; + }); } function controlUpdate() { - var _this = this; + var _this = this; - if (this.config.inputs && this.config.inputs.length && this.config.inputs[0]) this.config.inputs.forEach(function (input) { - return _this.makeControlItem(input); - }); + if (this.config.inputs && this.config.inputs.length && this.config.inputs[0]) + this.config.inputs.forEach(function(input) { + return _this.makeControlItem(input); + }); } function destroy$1() { - //unmount controls wrapper - this.wrap.remove(); + //unmount controls wrapper + this.wrap.remove(); } function init$1(data) { - this.data = data; - if (!this.config.builder) this.checkRequired(this.data); - this.layout(); + 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(); + 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); //Add control label span. - - var ctrl_label = control_wrap.append('span').attr('class', 'wc-control-label').text(control.label); //Add control _Required_ text to control label span. - - if (control.required) ctrl_label.append('span').attr('class', 'label label-required').text('Required'); //Add control description span. - - 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".'); - } + var control_wrap = this.wrap + .append('div') + .attr('class', 'control-group') + .classed('inline', control.inline) + .datum(control); //Add control label span. + + var ctrl_label = control_wrap + .append('span') + .attr('class', 'wc-control-label') + .text(control.label); //Add control _Required_ text to control label span. + + if (control.required) + ctrl_label + .append('span') + .attr('class', 'label label-required') + .text('Required'); //Add control description span. + + control_wrap + .append('span') + .attr('class', 'span-description') + .text(control.description); + + 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); - }); + 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); - }); + _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'); + 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); - }); + _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); + 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'); } - }); - return changer; - } - function makeListControl(control, control_wrap) { - var _this = this; + 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'; + }); + } - 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; + if (control.options) { + _this.changeOption(control.options, value, control.callback, control.draw); + } else { + _this.changeOption(control.option, value, control.callback, control.draw); + } + }); + return changer; + } - _this.changeOption(control.option, value, control.callback, control.draw); - }); + 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'); + 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); - }); + _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; - } - }); + 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); - }); + _this.changeOption(control.option, value, control.callback, control.draw); + }); } function makeSubsetterControl(control, control_wrap) { - var targets = this.targets; // associated charts and tables. - //dropdown selection - - var changer = control_wrap.append('select').classed('changer', true).attr('multiple', control.multiple ? true : null).datum(control); //dropdown option data - - var option_data = control.values ? control.values : d3.set(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 - - control.start = control.start ? control.start : control.loose ? option_data[0] : null; //conditionally add All option - - if (!control.multiple && !control.start) { - option_data.unshift('All'); - control.all = true; - } else { - control.all = false; - } //what does loose mean? - - - control.loose = !control.loose && control.start ? true : control.loose; //dropdown options selection - - var options = changer.selectAll('option').data(option_data).enter().append('option').text(function (d) { - return d; - }).property('selected', function (d) { - return d === control.start; - }); //define filter object for each associated target - - targets.forEach(function (e) { - var match = e.filters.slice().map(function (m) { - return m.col === control.value_col; - }).indexOf(true); - - 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 - }; + var targets = this.targets; // associated charts and tables. + //dropdown selection + + var changer = control_wrap + .append('select') + .classed('changer', true) + .attr('multiple', control.multiple ? true : null) + .datum(control); //dropdown option data + + var option_data = control.values + ? control.values + : d3 + .set( + 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 + + control.start = control.start ? control.start : control.loose ? option_data[0] : null; //conditionally add All option + + if (!control.multiple && !control.start) { + option_data.unshift('All'); + control.all = true; } 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; - } + control.all = false; + } //what does loose mean? + + control.loose = !control.loose && control.start ? true : control.loose; //dropdown options selection + + var options = changer + .selectAll('option') + .data(option_data) + .enter() + .append('option') + .text(function(d) { + return d; + }) + .property('selected', function(d) { + return d === control.start; + }); //define filter object for each associated target + + targets.forEach(function(e) { + var match = e.filters + .slice() + .map(function(m) { + return m.col === control.value_col; + }) + .indexOf(true); + + 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 + }); + } }); - if (match > -1) { - target.filters[match] = obj; - } - } //add event listener to control - - - 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, - // could specify an array of indices but seems like a waste of resources give it doesn't inform anything without an overall 'All' - choices: option_data, - loose: control.loose, - all: control.all - }; - targets.forEach(function (e) { - setSubsetter(e, new_filter); //call callback function if provided - - if (control.callback) { - control.callback(); - } + function setSubsetter(target, obj) { + var match = -1; + target.filters.forEach(function(e, i) { + if (e.col === obj.col) { + match = i; + } + }); - 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); //call callback function if provided - - if (control.callback) { - control.callback(); + if (match > -1) { + target.filters[match] = obj; } - - e.draw(); - }); - } - }); + } //add event listener to control + + 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, + // could specify an array of indices but seems like a waste of resources give it doesn't inform anything without an overall 'All' + choices: option_data, + loose: control.loose, + all: control.all + }; + targets.forEach(function(e) { + setSubsetter(e, new_filter); //call callback function if provided + + 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); //call callback function if provided + + 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'); + 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); - }); + _this.changeOption(control.option, value, control.callback, control.draw); + }); } function stringAccessor(o, s, v) { - //adapted from http://jsfiddle.net/alnitak/hEsys/ - s = s.replace(/\[(\w+)\]/g, '.$1'); - s = s.replace(/^\./, ''); - var a = s.split('.'); + //adapted from http://jsfiddle.net/alnitak/hEsys/ + s = s.replace(/\[(\w+)\]/g, '.$1'); + s = s.replace(/^\./, ''); + var a = s.split('.'); - for (var i = 0, n = a.length; i < n; ++i) { - var k = a[i]; + for (var i = 0, n = a.length; i < n; ++i) { + var k = a[i]; - if (k in o) { - if (i == n - 1 && v !== undefined) o[k] = v; - o = o[k]; - } else { - return; + if (k in o) { + if (i == n - 1 && v !== undefined) o[k] = v; + o = o[k]; + } else { + return; + } } - } - return o; + return o; } var controls = { - changeOption: changeOption, - checkRequired: checkRequired$1, - controlUpdate: controlUpdate, - destroy: destroy$1, - init: init$1, - layout: layout$1, - makeControlItem: makeControlItem, - makeBtnGroupControl: makeBtnGroupControl, - makeCheckboxControl: makeCheckboxControl, - makeDropdownControl: makeDropdownControl, - makeListControl: makeListControl, - makeNumberControl: makeNumberControl, - makeRadioControl: makeRadioControl, - makeSubsetterControl: makeSubsetterControl, - makeTextControl: makeTextControl, - stringAccessor: stringAccessor + changeOption: changeOption, + checkRequired: checkRequired$1, + controlUpdate: controlUpdate, + destroy: destroy$1, + init: init$1, + layout: layout$1, + makeControlItem: makeControlItem, + makeBtnGroupControl: makeBtnGroupControl, + makeCheckboxControl: makeCheckboxControl, + makeDropdownControl: makeDropdownControl, + makeListControl: makeListControl, + makeNumberControl: makeNumberControl, + makeRadioControl: makeRadioControl, + makeSubsetterControl: makeSubsetterControl, + makeTextControl: makeTextControl, + stringAccessor: stringAccessor }; function createControls() { - var element = arguments.length > 0 && 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'); - } + var element = arguments.length > 0 && 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; + thisControls.wrap.datum(thisControls); + return thisControls; } function applyFilters() { - var _this = this; - - //If there are filters, return a filtered data array of the raw data. - //Otherwise return the raw data. - if (this.filters && this.filters.some(function (filter) { - return typeof filter.val === 'string' && !(filter.all === true && filter.index === 0) || Array.isArray(filter.val) && filter.val.length < filter.choices.length; - })) { - this.data.filtered = this.data.raw.slice(); - this.filters.filter(function (filter) { - return typeof filter.val === 'string' && !(filter.all === true && filter.index === 0) || Array.isArray(filter.val) && filter.val.length < filter.choices.length; - }).forEach(function (filter) { - _this.data.filtered = _this.data.filtered.filter(function (d) { - return Array.isArray(filter.val) ? filter.val.indexOf(d[filter.col]) > -1 : filter.val === d[filter.col]; - }); - }); - } else this.data.filtered = this.data.raw.slice(); + var _this = this; + + //If there are filters, return a filtered data array of the raw data. + //Otherwise return the raw data. + if ( + this.filters && + this.filters.some(function(filter) { + return ( + (typeof filter.val === 'string' && + !(filter.all === true && filter.index === 0)) || + (Array.isArray(filter.val) && filter.val.length < filter.choices.length) + ); + }) + ) { + this.data.filtered = this.data.raw.slice(); + this.filters + .filter(function(filter) { + return ( + (typeof filter.val === 'string' && + !(filter.all === true && filter.index === 0)) || + (Array.isArray(filter.val) && filter.val.length < filter.choices.length) + ); + }) + .forEach(function(filter) { + _this.data.filtered = _this.data.filtered.filter(function(d) { + return Array.isArray(filter.val) + ? filter.val.indexOf(d[filter.col]) > -1 + : filter.val === d[filter.col]; + }); + }); + } else this.data.filtered = this.data.raw.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; // first row shown + 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; // first row shown - this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown + this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown } function applySearchTerm(data) { - var _this = this; - - if (this.searchable.searchTerm) { - //Determine which rows contain input text. - 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 { - //Otherwise delete previously searched data and set data to filtered data. - delete this.data.searched; - this.data.processing = this.data.filtered; - } + var _this = this; + + if (this.searchable.searchTerm) { + //Determine which rows contain input text. + 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 { + //Otherwise delete previously searched data and set data to filtered data. + delete this.data.searched; + this.data.processing = this.data.filtered; + } } /*------------------------------------------------------------------------------------------------\ Check equality of two arrays (https://stackoverflow.com/questions/7837456/how-to-compare-arrays-in-javascript) \------------------------------------------------------------------------------------------------*/ // Warn if overriding existing method - if (Array.prototype.equals) console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code."); // attach the .equals method to Array's prototype to call it on any array - - Array.prototype.equals = function (array) { - // if the other array is a falsy value, return - if (!array) return false; // compare lengths - can save a lot of time - - if (this.length != array.length) return false; - - for (var i = 0, l = this.length; i < l; i++) { - // Check if we have nested arrays - if (this[i] instanceof Array && array[i] instanceof Array) { - // recurse into the nested arrays - if (!this[i].equals(array[i])) return false; - } else if (this[i] != array[i]) { - // Warning - two different object instances will never be equal: {x:20} != {x:20} - return false; + if (Array.prototype.equals) + console.warn( + "Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code." + ); // attach the .equals method to Array's prototype to call it on any array + + Array.prototype.equals = function(array) { + // if the other array is a falsy value, return + if (!array) return false; // compare lengths - can save a lot of time + + if (this.length != array.length) return false; + + for (var i = 0, l = this.length; i < l; i++) { + // Check if we have nested arrays + if (this[i] instanceof Array && array[i] instanceof Array) { + // recurse into the nested arrays + if (!this[i].equals(array[i])) return false; + } else if (this[i] != array[i]) { + // Warning - two different object instances will never be equal: {x:20} != {x:20} + return false; + } } - } - return true; + return true; }; // Hide method from for-in loops - Object.defineProperty(Array.prototype, 'equals', { - enumerable: false + enumerable: false }); function checkFilters() { - if (this.filters) { - this.currentFilters = this.filters.map(function (filter) { - return filter.val; - }); //Reset pagination if filters have changed. + if (this.filters) { + this.currentFilters = this.filters.map(function(filter) { + return filter.val; + }); //Reset pagination if filters have changed. - if (!this.currentFilters.equals(this.previousFilters)) { - this.config.activePage = 0; - this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; // first row shown + if (!this.currentFilters.equals(this.previousFilters)) { + this.config.activePage = 0; + this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; // first row shown - this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown - } + this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown + } - this.previousFilters = this.currentFilters; - } + this.previousFilters = this.currentFilters; + } } function updateTableHeaders() { - var _this = this; - - this.thead_cells = this.thead.select('tr').selectAll('th').data(this.config.headers, function (d) { - return d; - }); - this.thead_cells.exit().remove(); - this.thead_cells.enter().append('th'); - this.thead_cells.sort(function (a, b) { - return _this.config.headers.indexOf(a) - _this.config.headers.indexOf(b); - }).attr('class', function (d) { - return _this.config.cols[_this.config.headers.indexOf(d)]; - }) // associate column header with column name - .text(function (d) { - return d; - }); + var _this = this; + + this.thead_cells = this.thead + .select('tr') + .selectAll('th') + .data(this.config.headers, function(d) { + return d; + }); + this.thead_cells.exit().remove(); + this.thead_cells.enter().append('th'); + this.thead_cells + .sort(function(a, b) { + return _this.config.headers.indexOf(a) - _this.config.headers.indexOf(b); + }) + .attr('class', function(d) { + return _this.config.cols[_this.config.headers.indexOf(d)]; + }) // associate column header with column name + .text(function(d) { + return d; + }); } function drawTableBody() { - var _this = this; - - var table = this; //Define table body rows. - - var rows = this.tbody.selectAll('tr').data(this.data.processing).enter().append('tr'); //Define table body cells. - - var cells = rows.selectAll('td').data(function (d) { - return _this.config.cols.map(function (key) { - return { - col: key, - text: d[key] - }; + var _this = this; + + var table = this; //Define table body rows. + + var rows = this.tbody + .selectAll('tr') + .data(this.data.processing) + .enter() + .append('tr'); //Define table body cells. + + var cells = rows.selectAll('td').data(function(d) { + return _this.config.cols.map(function(key) { + return { + col: key, + text: d[key] + }; + }); }); - }); - cells.exit().remove(); - cells.enter().append('td'); - cells.sort(function (a, b) { - return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); - }).attr('class', function (d) { - return d.col; - }).each(function (d) { - var cell = d3.select(this); //Apply text in data as html or as plain text. - - if (table.config.as_html) { - cell.html(d.text); - } else { - cell.text(d.text); - } - }); + cells.exit().remove(); + cells.enter().append('td'); + cells + .sort(function(a, b) { + return _this.config.cols.indexOf(a.col) - _this.config.cols.indexOf(b.col); + }) + .attr('class', function(d) { + return d.col; + }) + .each(function(d) { + var cell = d3.select(this); //Apply text in data as html or as plain text. + + if (table.config.as_html) { + cell.html(d.text); + } else { + cell.text(d.text); + } + }); } function dynamicLayout() { - var widths = { - table: this.table.select('thead').node().offsetWidth, - top: this.wrap.select('.table-top .searchable-container').node().offsetWidth + this.wrap.select('.table-top .sortable-container').node().offsetWidth, - bottom: this.wrap.select('.table-bottom .pagination-container').node().offsetWidth + this.wrap.select('.table-bottom .exportable-container').node().offsetWidth - }; - - if (widths.table < Math.max(widths.top, widths.bottom) && this.config.layout === 'horizontal') { - this.config.layout = 'vertical'; - this.wrap.style('display', 'inline-block').selectAll('.table-top,.table-bottom').style('display', 'inline-block').selectAll('.interactivity').style({ - display: 'block', - clear: 'both' - }); - } else if (widths.table >= Math.max(widths.top, widths.bottom) && this.config.layout === 'vertical') { - this.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 - }); - } + var widths = { + table: this.table.select('thead').node().offsetWidth, + top: + this.wrap.select('.table-top .searchable-container').node().offsetWidth + + this.wrap.select('.table-top .sortable-container').node().offsetWidth, + bottom: + this.wrap.select('.table-bottom .pagination-container').node().offsetWidth + + this.wrap.select('.table-bottom .exportable-container').node().offsetWidth + }; + + if ( + widths.table < Math.max(widths.top, widths.bottom) && + this.config.layout === 'horizontal' + ) { + this.config.layout = 'vertical'; + this.wrap + .style('display', 'inline-block') + .selectAll('.table-top,.table-bottom') + .style('display', 'inline-block') + .selectAll('.interactivity') + .style({ + display: 'block', + clear: 'both' + }); + } else if ( + widths.table >= Math.max(widths.top, widths.bottom) && + this.config.layout === 'vertical' + ) { + this.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; // make passed data available on preprocess - - this.events.onPreprocess.call(this); - if (!passed_data) //Apply filters if data is not passed to table.draw(). - applyFilters.call(this); //Otherwise update data object. - else updateDataObject.call(this); //Compare current filter settings to previous filter settings, if any. - - checkFilters.call(this); //Filter data on search term if it exists and set data to searched data. - - applySearchTerm.call(this); - this.searchable.wrap.select('.nNrecords').text(this.data.processing.length === this.data.raw.length ? "".concat(this.data.raw.length, " records displayed") : "".concat(this.data.processing.length, "/").concat(this.data.raw.length, " records displayed")); //Update table headers. - - updateTableHeaders.call(this); //Clear table body rows. - - this.tbody.selectAll('tr').remove(); //Print a note that no data was selected for empty tables. - - if (this.data.processing.length === 0) { - this.tbody.append('tr').classed('no-data', true).append('td').attr('colspan', this.config.cols.length).text('No data selected.'); //Bind table filtered/searched data to table container. - - this.data.current = this.data.processing; - this.table.datum(this.table.current); //Add export. - - if (this.config.exportable) this.config.exports.forEach(function (fmt) { - _this.exportable.exports[fmt].call(_this, _this.data.processing); - }); //Add pagination. - - if (this.config.pagination) this.pagination.addPagination.call(this, this.data.processing); - } else { - //Sort data. - if (this.config.sortable) { - this.thead.selectAll('th').on('click', function (header) { - table.sortable.onClick.call(table, this, header); - }); - if (this.sortable.order.length) this.sortable.sortData.call(this, this.data.processing); - } //Bind table filtered/searched data to table container. - - - this.data.current = this.data.processing; - this.table.datum(this.data.current); //Add export. - - if (this.config.exportable) this.config.exports.forEach(function (fmt) { - _this.exportable.exports[fmt].call(_this, _this.data.processing); - }); //Add pagination. - - if (this.config.pagination) { - this.pagination.addPagination.call(this, this.data.processing); //Apply pagination. - - this.data.processing = this.data.processing.filter(function (d, i) { - return _this.config.startIndex <= i && i < _this.config.endIndex; - }); - } //Define table body rows. - - - drawTableBody.call(this); - } //Alter table layout if table is narrower than table top or bottom. - - - if (this.config.dynamicPositioning) { - dynamicLayout.call(this); - } + var _this = this; + + var table = this; + var config = this.config; + this.data.passed = passed_data; // make passed data available on preprocess + + this.events.onPreprocess.call(this); + if (!passed_data) + //Apply filters if data is not passed to table.draw(). + applyFilters.call(this); + //Otherwise update data object. + else updateDataObject.call(this); //Compare current filter settings to previous filter settings, if any. + + checkFilters.call(this); //Filter data on search term if it exists and set data to searched data. + + applySearchTerm.call(this); + this.searchable.wrap + .select('.nNrecords') + .text( + this.data.processing.length === this.data.raw.length + ? ''.concat(this.data.raw.length, ' records displayed') + : '' + .concat(this.data.processing.length, '/') + .concat(this.data.raw.length, ' records displayed') + ); //Update table headers. + + updateTableHeaders.call(this); //Clear table body rows. + + this.tbody.selectAll('tr').remove(); //Print a note that no data was selected for empty tables. + + if (this.data.processing.length === 0) { + this.tbody + .append('tr') + .classed('no-data', true) + .append('td') + .attr('colspan', this.config.cols.length) + .text('No data selected.'); //Bind table filtered/searched data to table container. + + this.data.current = this.data.processing; + this.table.datum(this.table.current); //Add export. + + if (this.config.exportable) + this.config.exports.forEach(function(fmt) { + _this.exportable.exports[fmt].call(_this, _this.data.processing); + }); //Add pagination. + + if (this.config.pagination) + this.pagination.addPagination.call(this, this.data.processing); + } else { + //Sort data. + if (this.config.sortable) { + this.thead.selectAll('th').on('click', function(header) { + table.sortable.onClick.call(table, this, header); + }); + if (this.sortable.order.length) + this.sortable.sortData.call(this, this.data.processing); + } //Bind table filtered/searched data to table container. + + this.data.current = this.data.processing; + this.table.datum(this.data.current); //Add export. + + if (this.config.exportable) + this.config.exports.forEach(function(fmt) { + _this.exportable.exports[fmt].call(_this, _this.data.processing); + }); //Add pagination. + + if (this.config.pagination) { + this.pagination.addPagination.call(this, this.data.processing); //Apply pagination. + + this.data.processing = this.data.processing.filter(function(d, i) { + return _this.config.startIndex <= i && i < _this.config.endIndex; + }); + } //Define table body rows. + + drawTableBody.call(this); + } //Alter table layout if table is narrower than table top or bottom. + + if (this.config.dynamicPositioning) { + dynamicLayout.call(this); + } - this.events.onDraw.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; // first row shown - - context.config.endIndex = context.config.startIndex + context.config.nRowsPerPage; // last row shown - - context.draw(); - }); - this.searchable.wrap.select('.search').append('span').classed('nNrecords', true); + 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; // first row shown + + context.config.endIndex = context.config.startIndex + context.config.nRowsPerPage; // last row shown + + context.draw(); + }); + this.searchable.wrap + .select('.search') + .append('span') + .classed('nNrecords', true); } function searchable() { - return { - layout: layout$2 - }; + 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()); - }); + 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) { - //transform blob array into a blob of characters - var blob = new Blob(data, { - type: fileType === 'csv' ? 'text/csv;charset=utf-8;' : fileType === 'xlsx' ? 'application/octet-stream' : console.warn("File type not supported: ".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) //IE - navigator.msSaveBlob(blob, fileName);else if (link.node().download !== undefined) { - //21st century browsers - var url = URL.createObjectURL(blob); - link.node().setAttribute('href', url); - link.node().setAttribute('download', fileName); - } + //transform blob array into a blob of characters + var blob = new Blob(data, { + type: + fileType === 'csv' + ? 'text/csv;charset=utf-8;' + : fileType === 'xlsx' + ? 'application/octet-stream' + : console.warn('File type not supported: '.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) + //IE + navigator.msSaveBlob(blob, fileName); + else if (link.node().download !== undefined) { + //21st century browsers + var url = URL.createObjectURL(blob); + link.node().setAttribute('href', url); + link.node().setAttribute('download', fileName); + } } function csv(data) { - var _this = this; + var _this = this; - this.wrap.select('.export#csv').on('click', function () { - var CSVarray = []; //add headers to CSV array + this.wrap.select('.export#csv').on('click', function() { + var CSVarray = []; //add headers to CSV array - var headers = _this.config.headers.map(function (header) { - return "\"".concat(header.replace(/"/g, '""'), "\""); - }); + var headers = _this.config.headers.map(function(header) { + return '"'.concat(header.replace(/"/g, '""'), '"'); + }); - CSVarray.push(headers); //add rows to CSV array + CSVarray.push(headers); //add rows to CSV array - 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, "\""); - }); + 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 .csv file. + CSVarray.push(row); + }); //Download .csv file. - download.call(_this, 'csv', [CSVarray.join('\n')]); - }); + 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]; - }); - }); // convert data from array of objects to array of arrays. - - var workbook = { - SheetNames: [sheetName], - Sheets: {} - }; - var cols = []; //Convert headers and data from array of arrays to sheet. - - workbook.Sheets[sheetName] = XLSX.utils.aoa_to_sheet([_this.config.headers].concat(arrayOfArrays)); //Add filters to spreadsheet. - - workbook.Sheets[sheetName]['!autofilter'] = { - ref: "A1:".concat(String.fromCharCode(64 + _this.config.cols.length)).concat(data.length + 1) - }; //Define column widths in spreadsheet. - - _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 _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]; + }); + }); // convert data from array of objects to array of arrays. + + var workbook = { + SheetNames: [sheetName], + Sheets: {} + }; + var cols = []; //Convert headers and data from array of arrays to sheet. + + workbook.Sheets[sheetName] = XLSX.utils.aoa_to_sheet( + [_this.config.headers].concat(arrayOfArrays) + ); //Add filters to spreadsheet. + + workbook.Sheets[sheetName]['!autofilter'] = { + ref: 'A1:' + .concat(String.fromCharCode(64 + _this.config.cols.length)) + .concat(data.length + 1) + }; //Define column widths in spreadsheet. + + _this.table.selectAll('thead tr th').each(function() { + cols.push({ + wpx: this.offsetWidth + }); + }); - var s2ab = function s2ab(s) { - var buffer = new ArrayBuffer(s.length), - view = new Uint8Array(buffer); + workbook.Sheets[sheetName]['!cols'] = cols; + var xlsx = XLSX.write(workbook, options); - for (var i = 0; i !== s.length; ++i) { - view[i] = s.charCodeAt(i) & 0xff; - } + var s2ab = function s2ab(s) { + var buffer = new ArrayBuffer(s.length), + view = new Uint8Array(buffer); - return buffer; - }; // convert spreadsheet to binary or something, i don't know - //Download .xlsx file. + for (var i = 0; i !== s.length; ++i) { + view[i] = s.charCodeAt(i) & 0xff; + } + return buffer; + }; // convert spreadsheet to binary or something, i don't know + //Download .xlsx file. - download.call(_this, 'xlsx', [s2ab(xlsx)]); - }); + download.call(_this, 'xlsx', [s2ab(xlsx)]); + }); } var exports$1 = { - csv: csv, - xlsx: xlsx + csv: csv, + xlsx: xlsx }; function exportable() { - return { - layout: layout$3, - exports: exports$1 - }; + 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.'); + 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)]; //Check if column is already a part of current sort order. - - var sortItem = this.sortable.order.filter(function (item) { - return item.col === col; - })[0]; //If it isn't, add it to sort order. - - 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 { - //Otherwise reverse its sort direction. - sortItem.direction = sortItem.direction === 'ascending' ? 'descending' : 'ascending'; - sortItem.wrap.select('span.sort-direction').html(sortItem.direction === 'ascending' ? '↓' : '↑'); - } //Hide sort instructions. - - - this.sortable.wrap.select('.instruction').classed('hidden', true); //Add sort container deletion functionality. - - this.sortable.order.forEach(function (item, i) { - item.wrap.on('click', function (d) { - //Remove column's sort container. - d3.select(this).remove(); //Remove column from sort. - - context.sortable.order.splice(context.sortable.order.map(function (d) { - return d.col; - }).indexOf(d.key), 1); //Display sorting instruction. - - context.sortable.wrap.select('.instruction').classed('hidden', context.sortable.order.length); //Redraw chart. - - context.draw(); - }); - }); //Redraw chart. + var context = this, + selection = d3.select(th), + col = this.config.cols[this.config.headers.indexOf(header)]; //Check if column is already a part of current sort order. + + var sortItem = this.sortable.order.filter(function(item) { + return item.col === col; + })[0]; //If it isn't, add it to sort order. + + 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 { + //Otherwise reverse its sort direction. + sortItem.direction = sortItem.direction === 'ascending' ? 'descending' : 'ascending'; + sortItem.wrap + .select('span.sort-direction') + .html(sortItem.direction === 'ascending' ? '↓' : '↑'); + } //Hide sort instructions. + + this.sortable.wrap.select('.instruction').classed('hidden', true); //Add sort container deletion functionality. + + this.sortable.order.forEach(function(item, i) { + item.wrap.on('click', function(d) { + //Remove column's sort container. + d3.select(this).remove(); //Remove column from sort. + + context.sortable.order.splice( + context.sortable.order + .map(function(d) { + return d.col; + }) + .indexOf(d.key), + 1 + ); //Display sorting instruction. + + context.sortable.wrap + .select('.instruction') + .classed('hidden', context.sortable.order.length); //Redraw chart. + + context.draw(); + }); + }); //Redraw chart. - this.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; - }; - } + 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); + 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]; + 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 (order === 0) { + if (item.type === 'number') { + order = item.direction === 'ascending' ? +aCell - +bCell : +bCell - +aCell; + } else { + 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 (order === 0) { - if (item.type === 'number') { - order = item.direction === 'ascending' ? +aCell - +bCell : +bCell - +aCell; - } else { - 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; - } - } + return order; }); - - return order; - }); } function sortable() { - return { - layout: layout$4, - onClick: onClick, - sortData: sortData, - order: [] - }; + return { + layout: layout$4, + onClick: onClick, + sortData: sortData, + order: [] + }; } function layout$5() { - this.pagination.wrap = this.wrap.select('.table-bottom').append('div').classed('interactivity pagination-container', true).classed('hidden', !this.config.pagination); + this.pagination.wrap = this.wrap + .select('.table-bottom') + .append('div') + .classed('interactivity pagination-container', true) + .classed('hidden', !this.config.pagination); } function updatePagination() { - var _this = this; + var _this = this; - //Reset pagination. - this.pagination.links.classed('active', false); //Set to active the selected page link. + //Reset pagination. + this.pagination.links.classed('active', false); //Set to active the selected page link. - var activePage = this.pagination.links.filter(function (link) { - return +link.rel === +_this.config.activePage; - }).classed('active', true); //Define and draw selected page. + var activePage = this.pagination.links + .filter(function(link) { + return +link.rel === +_this.config.activePage; + }) + .classed('active', true); //Define and draw selected page. - this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; - this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; //Redraw table. + this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; + this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; //Redraw table. - this.draw(); + this.draw(); } function addLinks() { - var _this = this; - - //Count rows. - this.pagination.wrap.selectAll('a,span').remove(); - - var _loop = function _loop(i) { - _this.pagination.wrap.append('a').datum({ - rel: i - }).attr({ - rel: i - }).text(i + 1).classed('wc-button page-link', true).classed('active', function (d) { - return d.rel == _this.config.activePage; - }).classed('hidden', function () { - return _this.config.activePage < _this.config.nPageLinksDisplayed ? i >= _this.config.nPageLinksDisplayed // first nPageLinksDisplayed pages - : _this.config.activePage >= _this.config.nPages - _this.config.nPageLinksDisplayed ? i < _this.config.nPages - _this.config.nPageLinksDisplayed // last nPageLinksDisplayed pages - : i < _this.config.activePage - (Math.ceil(_this.config.nPageLinksDisplayed / 2) - 1) || _this.config.activePage + _this.config.nPageLinksDisplayed / 2 < i; // nPageLinksDisplayed < activePage or activePage < (nPages - nPageLinksDisplayed) - }); - }; + var _this = this; + + //Count rows. + this.pagination.wrap.selectAll('a,span').remove(); + + var _loop = function _loop(i) { + _this.pagination.wrap + .append('a') + .datum({ + rel: i + }) + .attr({ + rel: i + }) + .text(i + 1) + .classed('wc-button page-link', true) + .classed('active', function(d) { + return d.rel == _this.config.activePage; + }) + .classed('hidden', function() { + return _this.config.activePage < _this.config.nPageLinksDisplayed + ? i >= _this.config.nPageLinksDisplayed // first nPageLinksDisplayed pages + : _this.config.activePage >= + _this.config.nPages - _this.config.nPageLinksDisplayed + ? i < _this.config.nPages - _this.config.nPageLinksDisplayed // last nPageLinksDisplayed pages + : i < + _this.config.activePage - + (Math.ceil(_this.config.nPageLinksDisplayed / 2) - 1) || + _this.config.activePage + _this.config.nPageLinksDisplayed / 2 < i; // nPageLinksDisplayed < activePage or activePage < (nPages - nPageLinksDisplayed) + }); + }; - for (var i = 0; i < this.config.nPages; i++) { - _loop(i); - } + for (var i = 0; i < this.config.nPages; i++) { + _loop(i); + } - this.pagination.links = this.pagination.wrap.selectAll('a.page-link'); + this.pagination.links = this.pagination.wrap.selectAll('a.page-link'); } function addArrows() { - var prev = this.config.activePage - 1, - next = this.config.activePage + 1; - if (prev < 0) prev = 0; // nothing before the first page + var prev = this.config.activePage - 1, + next = this.config.activePage + 1; + if (prev < 0) prev = 0; // nothing before the first page - if (next >= this.config.nPages) next = this.config.nPages - 1; // nothing after the last page + if (next >= this.config.nPages) next = this.config.nPages - 1; // nothing after the last page - /**-------------------------------------------------------------------------------------------\ + /**-------------------------------------------------------------------------------------------\ Left side \-------------------------------------------------------------------------------------------**/ - this.pagination.wrap.insert('span', ':first-child').classed('dot-dot-dot', true).text('...').classed('hidden', this.config.activePage < this.config.nPageLinksDisplayed); - this.pagination.prev = this.pagination.wrap.insert('a', ':first-child').classed('wc-button arrow-link wc-left', true).classed('hidden', this.config.activePage == 0).attr({ - rel: prev - }).text('<'); - this.pagination.doublePrev = this.pagination.wrap.insert('a', ':first-child').classed('wc-button arrow-link wc-left double', true).classed('hidden', this.config.activePage == 0).attr({ - rel: 0 - }).text('<<'); - /**-------------------------------------------------------------------------------------------\ + this.pagination.wrap + .insert('span', ':first-child') + .classed('dot-dot-dot', true) + .text('...') + .classed('hidden', this.config.activePage < this.config.nPageLinksDisplayed); + this.pagination.prev = this.pagination.wrap + .insert('a', ':first-child') + .classed('wc-button arrow-link wc-left', true) + .classed('hidden', this.config.activePage == 0) + .attr({ + rel: prev + }) + .text('<'); + this.pagination.doublePrev = this.pagination.wrap + .insert('a', ':first-child') + .classed('wc-button arrow-link wc-left double', true) + .classed('hidden', this.config.activePage == 0) + .attr({ + rel: 0 + }) + .text('<<'); + /**-------------------------------------------------------------------------------------------\ Right side \-------------------------------------------------------------------------------------------**/ - this.pagination.wrap.append('span').classed('dot-dot-dot', true).text('...').classed('hidden', this.config.activePage >= Math.max(this.config.nPageLinksDisplayed, this.config.nPages - this.config.nPageLinksDisplayed) || this.config.nPages <= this.config.nPageLinksDisplayed); - this.pagination.next = this.pagination.wrap.append('a').classed('wc-button arrow-link wc-right', true).classed('hidden', this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0).attr({ - rel: next - }).text('>'); - this.pagination.doubleNext = this.pagination.wrap.append('a').classed('wc-button arrow-link wc-right double', true).classed('hidden', this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0).attr({ - rel: this.config.nPages - 1 - }).text('>>'); - this.pagination.arrows = this.pagination.wrap.selectAll('a.arrow-link'); - this.pagination.doubleArrows = this.pagination.wrap.selectAll('a.double-arrow-link'); + this.pagination.wrap + .append('span') + .classed('dot-dot-dot', true) + .text('...') + .classed( + 'hidden', + this.config.activePage >= + Math.max( + this.config.nPageLinksDisplayed, + this.config.nPages - this.config.nPageLinksDisplayed + ) || this.config.nPages <= this.config.nPageLinksDisplayed + ); + this.pagination.next = this.pagination.wrap + .append('a') + .classed('wc-button arrow-link wc-right', true) + .classed( + 'hidden', + this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0 + ) + .attr({ + rel: next + }) + .text('>'); + this.pagination.doubleNext = this.pagination.wrap + .append('a') + .classed('wc-button arrow-link wc-right double', true) + .classed( + 'hidden', + this.config.activePage == this.config.nPages - 1 || this.config.nPages == 0 + ) + .attr({ + rel: this.config.nPages - 1 + }) + .text('>>'); + this.pagination.arrows = this.pagination.wrap.selectAll('a.arrow-link'); + this.pagination.doubleArrows = this.pagination.wrap.selectAll('a.double-arrow-link'); } function addPagination(data) { - var context = this; //Calculate number of pages needed and create a link for each page. - - this.config.nRows = data.length; - this.config.nPages = Math.ceil(this.config.nRows / this.config.nRowsPerPage); //hide the pagination if there is only one page - - this.config.paginationHidden = this.config.nPages === 1; - this.pagination.wrap.classed('hidden', this.config.paginationHidden); //Render page links. - - addLinks.call(this); //Render a different page on click. - - this.pagination.links.on('click', function () { - context.config.activePage = +d3.select(this).attr('rel'); - updatePagination.call(context); - }); //Render arrow links. - - addArrows.call(this); //Render a different page on click. - - this.pagination.arrows.on('click', function () { - if (context.config.activePage !== +d3.select(this).attr('rel')) { - context.config.activePage = +d3.select(this).attr('rel'); - context.pagination.prev.attr('rel', context.config.activePage > 0 ? context.config.activePage - 1 : 0); - context.pagination.next.attr('rel', context.config.activePage < context.config.nPages ? context.config.activePage + 1 : context.config.nPages - 1); - updatePagination.call(context); - } - }); //Render a different page on click. + var context = this; //Calculate number of pages needed and create a link for each page. + + this.config.nRows = data.length; + this.config.nPages = Math.ceil(this.config.nRows / this.config.nRowsPerPage); //hide the pagination if there is only one page + + this.config.paginationHidden = this.config.nPages === 1; + this.pagination.wrap.classed('hidden', this.config.paginationHidden); //Render page links. + + addLinks.call(this); //Render a different page on click. + + this.pagination.links.on('click', function() { + context.config.activePage = +d3.select(this).attr('rel'); + updatePagination.call(context); + }); //Render arrow links. + + addArrows.call(this); //Render a different page on click. + + this.pagination.arrows.on('click', function() { + if (context.config.activePage !== +d3.select(this).attr('rel')) { + context.config.activePage = +d3.select(this).attr('rel'); + context.pagination.prev.attr( + 'rel', + context.config.activePage > 0 ? context.config.activePage - 1 : 0 + ); + context.pagination.next.attr( + 'rel', + context.config.activePage < context.config.nPages + ? context.config.activePage + 1 + : context.config.nPages - 1 + ); + updatePagination.call(context); + } + }); //Render a different page on click. - this.pagination.doubleArrows.on('click', function () { - context.config.activePage = +d3.select(this).attr('rel'); - updatePagination.call(context); - }); - return { - addLinks: addLinks, - addArrows: addArrows, - updatePagination: updatePagination - }; + this.pagination.doubleArrows.on('click', function() { + context.config.activePage = +d3.select(this).attr('rel'); + updatePagination.call(context); + }); + return { + addLinks: addLinks, + addArrows: addArrows, + updatePagination: updatePagination + }; } function pagination() { - this.config.nRows = this.data.raw.length; // total number of rows, i.e. the length of the data file + this.config.nRows = this.data.raw.length; // total number of rows, i.e. the length of the data file - this.config.nPages = Math.ceil(this.config.nRows / this.config.nRowsPerPage); // total number of pages given number of rows + this.config.nPages = Math.ceil(this.config.nRows / this.config.nRowsPerPage); // total number of pages given number of rows - this.config.activePage = 0; // current page, 0-indexed + this.config.activePage = 0; // current page, 0-indexed - this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; // first row shown + this.config.startIndex = this.config.activePage * this.config.nRowsPerPage; // first row shown - this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown + this.config.endIndex = this.config.startIndex + this.config.nRowsPerPage; // last row shown - this.config.paginationHidden = this.config.nPages == 1; - return { - layout: layout$5, - addPagination: addPagination - }; + this.config.paginationHidden = this.config.nPages == 1; + return { + layout: layout$5, + addPagination: addPagination + }; } function init$2(data) { - var _this = this; + var _this = this; - var test = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - this.test = test; + 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); - }); - } //Define default settings. + 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); + }); + } //Define default settings. + this.setDefaults.call(this, data[0]); //Assign classes to container element. - this.setDefaults.call(this, data[0]); //Assign classes to container element. + this.wrap.classed('wc-chart', true).classed('wc-table', this.config.applyCSS); //Define data object. - this.wrap.classed('wc-chart', true).classed('wc-table', this.config.applyCSS); //Define data object. + this.data = { + raw: data + }; //Attach searchable object to table object. - this.data = { - raw: data - }; //Attach searchable object to table object. + this.searchable = searchable.call(this); //Attach sortable object to table object. - this.searchable = searchable.call(this); //Attach sortable object to table object. + this.sortable = sortable.call(this); //Attach pagination object to table object. - this.sortable = sortable.call(this); //Attach pagination object to table object. + this.pagination = pagination.call(this); //Attach pagination object to table object. - this.pagination = pagination.call(this); //Attach pagination object to table object. + this.exportable = exportable.call(this); - this.exportable = exportable.call(this); + var startup = function startup(data) { + //connect this table and its controls, if any + if (_this.controls) { + _this.controls.targets.push(_this); - var startup = function startup(data) { - //connect this table and its controls, if any - if (_this.controls) { - _this.controls.targets.push(_this); + if (!_this.controls.ready) { + _this.controls.init(_this.data.raw); + } else { + _this.controls.layout(); + } + } //make sure container is visible (has height and width) before trying to initialize - if (!_this.controls.ready) { - _this.controls.init(_this.data.raw); - } else { - _this.controls.layout(); - } - } //make sure container is visible (has height and width) before trying to initialize + var visible = d3.select(_this.div).property('offsetWidth') > 0 || test; + if (!visible) { + console.warn( + 'The table cannot be initialized inside an element with 0 width. The table will be initialized as soon as the container element is given a width > 0.' + ); + var onVisible = setInterval(function(i) { + var visible_now = d3.select(_this.div).property('offsetWidth') > 0; - var visible = d3.select(_this.div).property('offsetWidth') > 0 || test; + if (visible_now) { + _this.layout(); - 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; + _this.wrap.datum(_this); - if (visible_now) { - _this.layout(); + _this.draw(); - _this.wrap.datum(_this); + clearInterval(onVisible); + } + }, 500); + } else { + _this.layout(); - _this.draw(); + _this.wrap.datum(_this); - clearInterval(onVisible); + _this.draw(); } - }, 500); - } else { - _this.layout(); + }; - _this.wrap.datum(_this); + this.events.onInit.call(this); - _this.draw(); + if (this.data.raw.length) { + this.checkRequired(this.data.raw); } - }; - - this.events.onInit.call(this); - if (this.data.raw.length) { - this.checkRequired(this.data.raw); - } - - startup(); - return this; + startup(); + return this; } function layout$6() { - //Clear loading indicator. - d3.select(this.div).select('.loader').remove(); //Attach container before table. + //Clear loading indicator. + d3.select(this.div) + .select('.loader') + .remove(); //Attach container before table. - this.wrap.append('div').classed('table-top', true); //Attach search container. + this.wrap.append('div').classed('table-top', true); //Attach search container. - this.searchable.layout.call(this); //Attach sort container. + this.searchable.layout.call(this); //Attach sort container. - this.sortable.layout.call(this); //Attach table to DOM. + this.sortable.layout.call(this); //Attach table to DOM. - this.table = this.wrap.append('table').classed('table', this.config.bootstrap); // apply class to incorporate bootstrap styling + this.table = this.wrap.append('table').classed('table', this.config.bootstrap); // apply class to incorporate bootstrap styling - this.thead = this.table.append('thead'); - this.thead.append('tr'); - this.tbody = this.table.append('tbody'); //Attach container after table. + this.thead = this.table.append('thead'); + this.thead.append('tr'); + this.tbody = this.table.append('tbody'); //Attach container after table. - this.wrap.append('div').classed('table-bottom', true); //Attach pagination container. + this.wrap.append('div').classed('table-bottom', true); //Attach pagination container. - this.pagination.layout.call(this); //Attach data export container. + this.pagination.layout.call(this); //Attach data export container. - this.exportable.layout.call(this); //Call layout callback. + this.exportable.layout.call(this); //Call layout callback. - this.events.onLayout.call(this); + this.events.onLayout.call(this); } function destroy$2() { - var destroyControls = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; - //run onDestroy callback - this.events.onDestroy.call(this); //destroy controls - - if (destroyControls && this.controls) { - this.controls.destroy(); - } //unmount chart wrapper + var destroyControls = + arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false; + //run onDestroy callback + this.events.onDestroy.call(this); //destroy controls + if (destroyControls && this.controls) { + this.controls.destroy(); + } //unmount chart wrapper - this.wrap.remove(); + this.wrap.remove(); } function setDefault(setting) { - var _default_ = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; + var _default_ = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - this.config[setting] = this.config[setting] !== undefined ? this.config[setting] : _default_; + this.config[setting] = + this.config[setting] !== undefined ? this.config[setting] : _default_; } function setDefaults$1(firstItem) { - var _this = this; - - // 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, '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'); + var _this = this; + + // 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, '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; + var _this = this; - //Transform data. - 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); - } - }); - } + //Transform data. + this.data.processed = this.transformData(this.wrap.datum); - var filtered = data; + if (!data) { + return; + } - 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; - } - }); - }); - } + this.config.cols = this.config.cols || d3.keys(data[0]); + this.config.headers = this.config.headers || this.config.cols; - 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); + if (this.config.keep) { + this.config.keep.forEach(function(e) { + if (_this.config.cols.indexOf(e) === -1) { + _this.config.cols.unshift(e); + } + }); } - var nuarr = r.map(function (m) { - var arr = []; - - for (var x in m) { - arr.push({ - col: x, - text: m[x] + 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; + } + }); }); - } + } - 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: [] - }]; // dummy nested data array - //Reset pagination. - - this.pagination.wrap.selectAll('*').remove(); - this.events.onDatatransform.call(this); - /**-------------------------------------------------------------------------------------------\ + 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: [] + } + ]; // dummy nested data array + //Reset pagination. + + this.pagination.wrap.selectAll('*').remove(); + this.events.onDatatransform.call(this); + /**-------------------------------------------------------------------------------------------\ Code below associated with the former paradigm of a d3.nest() data array. \-------------------------------------------------------------------------------------------**/ - 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]; - }); - }); - } //Delete text from columns with repeated values? - - - if (config.row_per) { - rows.filter(function (f, i) { - return i > 0; - }).selectAll('td').filter(function (f) { - return config.row_per.indexOf(f.col) > -1; - }).text(''); - } + 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]; + }); + }); + } //Delete text from columns with repeated values? + + if (config.row_per) { + rows.filter(function(f, i) { + return i > 0; + }) + .selectAll('td') + .filter(function(f) { + return config.row_per.indexOf(f.col) > -1; + }) + .text(''); + } - return this.data.current; + 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 - } + 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']; + 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() {} + }; - if (possible_events.indexOf(event) < 0) { - return; - } + thisTable.on = function(event, callback) { + var possible_events = ['init', 'layout', 'preprocess', 'draw', 'destroy']; - if (callback) { - thisTable.events['on' + event.charAt(0).toUpperCase() + event.slice(1)] = callback; - } - }; //increment thisChart count to get unique thisChart id + if (possible_events.indexOf(event) < 0) { + return; + } + 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; + 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); //Define container for legend that overrides multiples' legends. - - chart.master_legend = chart.wrap.append('ul').attr('class', 'legend'); - chart.master_legend.append('span').classed('legend-title', true); //Instantiate multiples array. - - chart.multiples = []; - - function goAhead(data) { - var split_vals = d3.set(data.map(function (m) { - return m[split_by]; - })).values().filter(function (f) { - return f; - }); + var test = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false; + chart.wrap.classed('wc-layout wc-small-multiples', true).classed('wc-chart', false); //Define container for legend that overrides multiples' legends. + + chart.master_legend = chart.wrap.append('ul').attr('class', 'legend'); + chart.master_legend.append('span').classed('legend-title', true); //Instantiate multiples array. + + 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)); + }); + } - 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); - }); - } + 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); + 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; - }); + 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'; - } + 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); + 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; + return my_data; } var dataOps = { - getValType: getValType, - lengthenRaw: lengthenRaw, - naturalSorter: naturalSorter, - summarize: summarize + getValType: getValType, + lengthenRaw: lengthenRaw, + naturalSorter: naturalSorter, + summarize: summarize }; var index = { - version: version, - createChart: createChart, - createControls: createControls, - createTable: createTable, - multiply: multiply, - dataOps: dataOps + version: version, + createChart: createChart, + createControls: createControls, + createTable: createTable, + multiply: multiply, + dataOps: dataOps }; return index; - -}))); +}); diff --git a/build/webcharts.min.js b/build/webcharts.min.js index 5df8926..c4f83f1 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&&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.marks[0].type).replace(/bar|text/,"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});if(marks.length)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()}texts.each(attachMarks);texts.select("text").style("clip-path","url(#".concat(chart.id,")")).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).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]})}).each(function(d){d3.select(this).attr(d.mark.attributes)});var textsTrans=config.transitions?texts.select("text").transition():texts.select("text");textsTrans.attr("x",function(d){var xPos=_this.x(d.values.x)||0;return config.x.type==="ordinal"?xPos+_this.x.rangeBand()/2:xPos}).attr("y",function(d){var yPos=_this.y(d.values.y)||0;return config.y.type==="ordinal"?yPos+_this.y.rangeBand()/2:yPos});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(order===0){if(item.type==="number"){order=item.direction==="ascending"?+aCell-+bCell:+bCell-+aCell}else{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}); +(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){var legend=this.wrap.append("ul").datum(function(){return null}).classed("legend",true);var legend_title=legend.append("span").classed("legend-title",true)}}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.x.label=this.config.x.label!==undefined?this.config.x.label:this.config.x.column;this.config.x.sort=this.config.x.sort||"alphabetical-ascending";this.config.x.type=this.config.x.type||"linear";this.config.x.range_band=this.config.x.range_band||this.config.range_band;this.config.y=this.config.y||{};this.config.y.label=this.config.y.label!==undefined?this.config.y.label:this.config.y.column;this.config.y.sort=this.config.y.sort||"alphabetical-descending";this.config.y.type=this.config.y.type||"linear";this.config.y.range_band=this.config.y.range_band||this.config.range_band;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.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.legend.mark=this.config.legend.mark!==undefined&&typeof this.config.legend.mark==="string"&&["bar","square","circle","line"].includes(this.config.legend.mark.toLowerCase())?this.config.legend.mark.toLowerCase().replace("bar","square"):this.config.marks[0].type!==undefined&&typeof this.config.marks[0].type==="string"&&["bar","circle","line"].includes(this.config.marks[0].type.toLowerCase())?this.config.marks[0].type.toLowerCase().replace("bar","square"):"square";this.config.margin=this.config.margin||{};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().filter(function(f){return 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 moveLegend(scale){var legend=this.wrap.select(".legend");if(!this.parent){if(this.config.legend.location==="top"||this.config.legend.location==="left"){this.wrap.node().insertBefore(legend.node(),this.svg.node().parentNode)}else{this.wrap.node().appendChild(legend.node())}}else{if(this.config.legend.location==="top"||this.config.legend.location==="left"){this.parent.wrap.node().insertBefore(legend.node(),this.parent.wrap.select(".wc-chart").node())}else{this.parent.wrap.node().appendChild(legend.node())}}legend.classed("legend--".concat(this.config.legend.location),true).classed("legend--empty",scale.domain().length===0);return this.legend||legend}function defineLegendData(custom_data,scale){var _this=this;var legend_data=Array.isArray(custom_data)&&custom_data.length?custom_data:scale.domain().slice(0).filter(function(f){return f!==undefined&&f!==null}).map(function(m){return{label:m,mark:_this.config.legend.mark}});return legend_data}function addLegendTitle(legend_label){var legend_title=this.legend.select(".legend-title").text(legend_label);return legend_title} +function addLegendItems(legend_data,scale){var _this=this;var all_legend_items=this.legend.selectAll(".legend-item").data(legend_data,function(d){return d.label+d.mark});all_legend_items.exit().remove();var legend_items=all_legend_items.enter().append("li").classed("legend-item",true);if(this.config.legend.order){legend_items.sort(function(a,b){return d3.ascending(_this.config.legend.order.indexOf(a.label),_this.config.legend.order.indexOf(b.label))})}return legend_items}function addLegendMarkTexts(legend_items,scale){var legend_mark_texts=legend_items.append("span").classed("legend-mark-text",true).style("color",function(d){return scale(d.label)});return legend_mark_texts}function addLegendColorBlocks(legend_items){var legend_color_blocks=legend_items.append("svg").classed("legend-color-block",true).attr({width:"1.1em",height:"1.1em"});return legend_color_blocks}function addLegendMarks(legend_color_blocks,scale){legend_color_blocks.each(function(e){var svg=d3.select(this);svg.select(".legend-mark").remove();if(e.mark==="circle"){svg.append("circle").classed("legend-mark",true).attr({cx:".5em",cy:".5em",r:".45em"})}else if(e.mark==="line"){svg.append("line").classed("legend-mark",true).attr({x1:0,y1:".5em",x2:"1em",y2:".5em","stroke-width":2,"shape-rendering":"crispEdges"})}else if(e.mark==="square"){svg.append("rect").classed("legend-mark",true).attr({height:"1em",width:"1em","shape-rendering":"crispEdges"})}});var legend_marks=legend_color_blocks.select(".legend-mark").attr({fill:function fill(d){return d.color||scale(d.label)},stroke:function stroke(d){return d.color||scale(d.label)}}).each(function(e){d3.select(this).attr(e.attributes)})}function addLegendLabels(legend_items){var legend_labels=legend_items.append("span").classed("legend-label",true).text(function(d){return d.label});return legend_labels}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;this.legend=moveLegend.call(this,scale);var legend_label=label||this.config.legend.label||"";var legend_data=defineLegendData.call(this,custom_data,scale);var legend_title=addLegendTitle.call(this,legend_label);var legend_items=addLegendItems.call(this,legend_data,scale);var legend_mark_texts=addLegendMarkTexts.call(this,legend_items,scale);var legend_color_blocks=addLegendColorBlocks.call(this,legend_items);var legend_marks=addLegendMarks.call(this,legend_color_blocks,scale);var legend_labels=addLegendLabels.call(this,legend_items)}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")});if(marks.length){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()}texts.each(attachMarks);texts.select("text").style("clip-path","url(#".concat(chart.id,")")).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).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]})}).each(function(d){d3.select(this).attr(d.mark.attributes)});var textsTrans=config.transitions?texts.select("text").transition():texts.select("text");textsTrans.attr("x",function(d){var xPos=_this.x(d.values.x)||0;return config.x.type==="ordinal"?xPos+_this.x.rangeBand()/2:xPos}).attr("y",function(d){var yPos=_this.y(d.values.y)||0;return config.y.type==="ordinal"?yPos+_this.y.rangeBand()/2:yPos});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(order===0){if(item.type==="number"){order=item.direction==="ascending"?+aCell-+bCell:+bCell-+aCell}else{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/css/webcharts.css b/css/webcharts.css index f70871d..2de68bc 100644 --- a/css/webcharts.css +++ b/css/webcharts.css @@ -72,10 +72,24 @@ display: block; } + *[class*="wc-"] .legend--left { + float: left; + } + + *[class*="wc-"] .legend--left > * { + float: left; + clear: left; + } + *[class*="wc-"] .legend--right { float: right; } + *[class*="wc-"] .legend--right > * { + float: right; + clear: right; + } + *[class*="wc-"] .legend--empty { display: none; } @@ -97,15 +111,6 @@ margin-right: 1em; } - *[class*="wc-"] .legend .legend-item--left, - *[class*="wc-"] .legend .legend-item--right { - display: block; - } - - *[class*="wc-"] .legend .legend-item--right { - float: right; - } - *[class*="wc-"] .legend .legend-item .legend-color-block { position: relative; top: .2em; @@ -113,6 +118,11 @@ display: inline-block; } + *[class*="wc-"] .legend--right .legend-item .legend-color-block { + float: right; + left: .25em; + } + *[class*="wc-"] .legend .legend-item .legend-mark-text { font-weight: bold; margin-right: .5em; @@ -122,6 +132,10 @@ margin-left: 0.25em; } + *[class*="wc-"] .legend--right .legend-item .legend-label { + margin-right: 0.25em; + } + /*------------------------------------------------------------------------------------------------\ Small multiples \------------------------------------------------------------------------------------------------*/ diff --git a/css/webcharts.min.css b/css/webcharts.min.css index 588d285..adea45a 100644 --- a/css/webcharts.min.css +++ b/css/webcharts.min.css @@ -1 +1 @@ -div.wc-layout.wc-small-multiples::after{content:"";clear:both;display:block}.wc-layout.wc-small-multiples>.wc-chart{float:left;padding:0 2em 2em 0}.wc-layout.wc-small-multiples>.wc-chart>.wc-chart-title{display:block;font-weight:700;text-align:center}.wc-small-multiples .wc-chart>.legend{display:none}.wc-chart{position:relative;font-family:'Open Sans',Helvetica,Arial,sans-serif}.wc-chart line,.wc-chart rect{shape-rendering:crispEdges}.wc-chart.brushable .overlay{cursor:crosshair}.wc-chart rect.background{display:none}.wc-chart rect.extent{fill:#ccc;fill-opacity:.4;shape-rendering:crispEdges}.wc-chart .axis path.domain{fill:none;stroke:#ccc;shape-rendering:crispEdges}.wc-chart .axis .tick line{stroke:#eee;shape-rendering:crispEdges}.wc-chart .axis .tick text{font-size:.9em}.wc-chart .axis .axis-title{fill:#555}[class*=wc-] .legend{width:100%;font-size:.9em;padding:0;margin:0;display:inline-block}[class*=wc-] .legend .legend-title{font-weight:700;margin-right:1em}[class*=wc-] .legend .legend-item{display:inline-block;margin-right:1em}[class*=wc-] .legend .legend-item .legend-color-block{position:relative;top:.2em;right:.25em;display:inline-block}[class*=wc-] .legend .legend-item .legend-mark-text{font-weight:700;margin-right:.5em}.wc-chart .ordinal.axis .tick line,.wc-chart .ordinal.axis path{display:none}.wc-chart.gridlines .ordinal.axis .tick line{display:block}.wc-controls{display:block;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:.9em;margin-bottom:10px}.wc-controls:empty{display:none}.intro>.wc-controls{display:block}.wc-controls .control-group{display:inline-table;max-width:100%;margin:0 1em 1em 0}.wc-controls.bottom .control-group{display:inline-table}.wc-controls .control-group .wc-control-label{display:block}.wc-controls .control-group.inline .wc-control-label{display:inline;margin-right:.5em}.wc-controls .control-group.inline .changer{display:inline;margin-top:0}.wc-controls .control-group .wc-control-label+.changer{margin-top:2px}.wc-controls .control-group .wc-control-label.inline{display:inline;margin-right:.5em}.wc-controls .control-group .wc-control-label .label-required{color:#de2d26;padding:0 .25em;border:1px solid;margin-left:.5em}.wc-controls .span-description{display:block;font-size:.75em;color:#777;margin-bottom:3px}.wc-controls .span-description:empty{display:none}.wc-controls .span-description.standout{font-style:italic;color:#d9534f}.wc-controls .control-group label.filter-values,.wc-controls .control-group label.radio{display:inline-block;cursor:pointer;font-weight:400;font-size:.9em;padding:0;margin:5px 10px 0 0}.wc-controls .inline{display:inline}.wc-controls .control-group input[type=text],.wc-controls select{display:block;width:auto;max-width:100%;padding:0 2px;height:auto;border-radius:0}.wc-controls .control-group input[type=number]{width:70px;text-align:right;max-width:100%}.wc-controls .control-group input[type=checkbox],.wc-controls .control-group input[type=radio]{cursor:pointer;position:relative;top:.1em;float:none;margin:0}.wc-controls .control-group input[type=radio]{vertical-align:bottom;margin-left:.25em}.wc-controls .control-group input.inline{margin:0 2px 2px 0}.wc-controls .control-group .changer+.changer{margin-top:2px}.wc-controls .subsetter-ui{position:relative;display:inline-block;max-width:100%;padding:3px;border:1px dashed #888;margin:5px 5px 0 0}.wc-controls .subsetter-ui .remove-btn{cursor:pointer;position:absolute;top:2px;right:2px}.wc-table{display:block}.wc-table .hidden{display:none!important}.wc-table .invisible{visibility:hidden!important}.wc-table>*{display:block}.wc-table .interactivity{display:inline-block;vertical-align:middle;margin:10px 0;padding:0}.wc-table .interactivity .wc-button{display:inline-block;border:2px solid gray;border-radius:4px;padding:2px 8px;margin:0 2px;cursor:pointer;background:#fff;color:#000}.wc-table .interactivity .wc-button:hover{background:#000;color:#fff}.wc-table .searchable-container{float:right;overflow:hidden}.wc-table .searchable-container input{margin:0 10px 0 0;padding:4px}.wc-table .sortable-container{margin-right:10px}.wc-table .sortable-container .instruction{margin-top:4px}.wc-table .sortable-container .sort-box{cursor:default;padding:2px 4px}.wc-table .sortable-container .sort-direction{font-weight:700;margin:3px}.wc-table .sortable-container .sort-box .remove-sort{font-weight:700;float:right;border:1px solid gray;margin-top:3px;padding:2px 3px;font-size:8px;background:#fff;color:red}.wc-table .sortable-container .sort-box .remove-sort:hover{cursor:pointer;background:red;color:#fff}.wc-table table{font-size:.9em;border-collapse:collapse}.wc-table table thead tr th{cursor:pointer;padding:2px 5px;border-bottom:2px solid #000;text-align:left}.wc-table table tbody tr:nth-child(even){background:#eee}.wc-table table tbody tr:hover{background:#ccc}.wc-table table tbody tr td{padding:2px 5px}.wc-table table tbody tr:last-child{border-bottom:1px solid #000}.wc-table table tbody tr.no-data td{color:red;font-weight:700}.wc-table .pagination-container{float:right}.wc-table .pagination-container a{text-decoration:none}.wc-table .pagination-container a:not(.active){border:none}.wc-table .exportable-container{float:left}.wc-table .exportable-container a{text-decoration:none}.loader{position:relative;width:20px;height:25px}.blockG{position:absolute;background-color:#eee;width:3px;height:8px;-moz-border-radius:4px 4px 0 0;-moz-transform:scale(.4);-moz-animation-name:fadeG;-moz-animation-duration:.48s;-moz-animation-iteration-count:infinite;-moz-animation-direction:linear;-webkit-border-radius:4px 4px 0 0;-webkit-transform:scale(.4);-webkit-animation-name:fadeG;-webkit-animation-duration:.48s;-webkit-animation-iteration-count:infinite;-webkit-animation-direction:linear;-ms-border-radius:4px 4px 0 0;-ms-transform:scale(.4);-ms-animation-name:fadeG;-ms-animation-duration:.48s;-ms-animation-iteration-count:infinite;-ms-animation-direction:linear;-o-border-radius:4px 4px 0 0;-o-transform:scale(.4);-o-animation-name:fadeG;-o-animation-duration:.48s;-o-animation-iteration-count:infinite;-o-animation-direction:linear;border-radius:4px 4px 0 0;transform:scale(.4);animation-name:fadeG;animation-duration:.48s;animation-iteration-count:infinite;animation-direction:linear}.rotate1{left:0;top:9px;-moz-animation-delay:.18s;-moz-transform:rotate(-90deg);-webkit-animation-delay:.18s;-webkit-transform:rotate(-90deg);-ms-animation-delay:.18s;-ms-transform:rotate(-90deg);-o-animation-delay:.18s;-o-transform:rotate(-90deg);animation-delay:.18s;transform:rotate(-90deg)}.rotate2{left:3px;top:3px;-moz-animation-delay:.24s;-moz-transform:rotate(-45deg);-webkit-animation-delay:.24s;-webkit-transform:rotate(-45deg);-ms-animation-delay:.24s;-ms-transform:rotate(-45deg);-o-animation-delay:.24s;-o-transform:rotate(-45deg);animation-delay:.24s;transform:rotate(-45deg)}.rotate3{left:8px;top:1px;-moz-animation-delay:.3s;-moz-transform:rotate(0);-webkit-animation-delay:.3s;-webkit-transform:rotate(0);-ms-animation-delay:.3s;-ms-transform:rotate(0);-o-animation-delay:.3s;-o-transform:rotate(0);animation-delay:.3s;transform:rotate(0)}.rotate4{right:3px;top:3px;-moz-animation-delay:.36s;-moz-transform:rotate(45deg);-webkit-animation-delay:.36s;-webkit-transform:rotate(45deg);-ms-animation-delay:.36s;-ms-transform:rotate(45deg);-o-animation-delay:.36s;-o-transform:rotate(45deg);animation-delay:.36s;transform:rotate(45deg)}.rotate5{right:0;top:9px;-moz-animation-delay:.42000000000000004s;-moz-transform:rotate(90deg);-webkit-animation-delay:.42000000000000004s;-webkit-transform:rotate(90deg);-ms-animation-delay:.42000000000000004s;-ms-transform:rotate(90deg);-o-animation-delay:.42000000000000004s;-o-transform:rotate(90deg);animation-delay:.42000000000000004s;transform:rotate(90deg)}.rotate6{right:3px;bottom:2px;-moz-animation-delay:.48s;-moz-transform:rotate(135deg);-webkit-animation-delay:.48s;-webkit-transform:rotate(135deg);-ms-animation-delay:.48s;-ms-transform:rotate(135deg);-o-animation-delay:.48s;-o-transform:rotate(135deg);animation-delay:.48s;transform:rotate(135deg)}.rotate7{bottom:0;left:8px;-moz-animation-delay:.5399999999999999s;-moz-transform:rotate(180deg);-webkit-animation-delay:.5399999999999999s;-webkit-transform:rotate(180deg);-ms-animation-delay:.5399999999999999s;-ms-transform:rotate(180deg);-o-animation-delay:.5399999999999999s;-o-transform:rotate(180deg);animation-delay:.5399999999999999s;transform:rotate(180deg)}.rotate8{left:3px;bottom:2px;-moz-animation-delay:.6s;-moz-transform:rotate(-135deg);-webkit-animation-delay:.6s;-webkit-transform:rotate(-135deg);-ms-animation-delay:.6s;-ms-transform:rotate(-135deg);-o-animation-delay:.6s;-o-transform:rotate(-135deg);animation-delay:.6s;transform:rotate(-135deg)}@-moz-keyframes fadeG{0%{background-color:#000}100%{background-color:#eee}}@-webkit-keyframes fadeG{0%{background-color:#000}100%{background-color:#eee}}@-ms-keyframes fadeG{0%{background-color:#000}100%{background-color:#eee}}@-o-keyframes fadeG{0%{background-color:#000}100%{background-color:#eee}}@keyframes fadeG{0%{background-color:#000}100%{background-color:#eee}} \ No newline at end of file +.wc-chart{position:relative;font-family:'Open Sans',Helvetica,Arial,sans-serif}.wc-chart line,.wc-chart rect{shape-rendering:crispEdges}.wc-chart.brushable .overlay{cursor:crosshair}.wc-chart rect.background{display:none}.wc-chart rect.extent{fill:#ccc;fill-opacity:.4;shape-rendering:crispEdges}.wc-chart .axis path.domain{fill:none;stroke:#ccc;shape-rendering:crispEdges}.wc-chart .axis .tick line{stroke:#eee;shape-rendering:crispEdges}.wc-chart .axis .tick text{font-size:.9em}.wc-chart .axis .axis-title{fill:#555}.wc-chart .ordinal.axis .tick line,.wc-chart .ordinal.axis path{display:none}.wc-chart.gridlines .ordinal.axis .tick line{display:block}[class*=wc-] .legend{width:100%;font-size:.9em;padding:0;margin:0;display:inline-block}[class*=wc-] .legend--left,[class*=wc-] .legend--right{display:block}[class*=wc-] .legend--left{float:left}[class*=wc-] .legend--left>*{float:left;clear:left}[class*=wc-] .legend--right{float:right}[class*=wc-] .legend--right>*{float:right;clear:right}[class*=wc-] .legend--empty{display:none}[class*=wc-] .legend .legend-title{display:inline;font-weight:700;margin-right:1em;vertical-align:top}[class*=wc-] .legend .legend-title:empty{display:none}[class*=wc-] .legend .legend-item{display:inline-block;list-style-type:none;margin-right:1em}[class*=wc-] .legend .legend-item .legend-color-block{position:relative;top:.2em;right:.25em;display:inline-block}[class*=wc-] .legend--right .legend-item .legend-color-block{float:right;left:.25em}[class*=wc-] .legend .legend-item .legend-mark-text{font-weight:700;margin-right:.5em}[class*=wc-] .legend .legend-item .legend-label{margin-left:.25em}[class*=wc-] .legend--right .legend-item .legend-label{margin-right:.25em}div.wc-layout.wc-small-multiples::after{content:"";clear:both;display:block}.wc-layout.wc-small-multiples>.wc-chart{float:left;padding:0 2em 2em 0}.wc-layout.wc-small-multiples>.wc-chart>.wc-chart-title{display:block;font-weight:700;text-align:center}.wc-small-multiples .wc-chart>.legend{display:none}.wc-controls{display:block;font-family:'Open Sans',Helvetica,Arial,sans-serif;font-size:.9em;margin-bottom:10px}.wc-controls:empty{display:none}.intro>.wc-controls{display:block}.wc-controls .control-group{display:inline-table;max-width:100%;margin:0 1em 1em 0}.wc-controls.bottom .control-group{display:inline-table}.wc-controls .control-group .wc-control-label{display:block}.wc-controls .control-group.inline .wc-control-label{display:inline;margin-right:.5em}.wc-controls .control-group.inline .changer{display:inline;margin-top:0}.wc-controls .control-group .wc-control-label+.changer{margin-top:2px}.wc-controls .control-group .wc-control-label.inline{display:inline;margin-right:.5em}.wc-controls .control-group .wc-control-label .label-required{color:#de2d26;padding:0 .25em;border:1px solid;margin-left:.5em}.wc-controls .span-description{display:block;font-size:.75em;color:#777;margin-bottom:3px}.wc-controls .span-description:empty{display:none}.wc-controls .span-description.standout{font-style:italic;color:#d9534f}.wc-controls .control-group label.filter-values,.wc-controls .control-group label.radio{display:inline-block;cursor:pointer;font-weight:400;font-size:.9em;padding:0;margin:5px 10px 0 0}.wc-controls .inline{display:inline}.wc-controls .control-group input[type=text],.wc-controls select{display:block;width:auto;max-width:100%;padding:0 2px;height:auto;border-radius:0}.wc-controls .control-group input[type=number]{width:70px;text-align:right;max-width:100%}.wc-controls .control-group input[type=checkbox],.wc-controls .control-group input[type=radio]{cursor:pointer;position:relative;top:.1em;float:none;margin:0}.wc-controls .control-group input[type=radio]{vertical-align:bottom;margin-left:.25em}.wc-controls .control-group input.inline{margin:0 2px 2px 0}.wc-controls .control-group .changer+.changer{margin-top:2px}.wc-controls .subsetter-ui{position:relative;display:inline-block;max-width:100%;padding:3px;border:1px dashed #888;margin:5px 5px 0 0}.wc-controls .subsetter-ui .remove-btn{cursor:pointer;position:absolute;top:2px;right:2px}.wc-table{display:block}.wc-table .hidden{display:none!important}.wc-table .invisible{visibility:hidden!important}.wc-table>*{display:block}.wc-table .interactivity{display:inline-block;vertical-align:middle;margin:10px 0;padding:0}.wc-table .interactivity .wc-button{display:inline-block;border:2px solid gray;border-radius:4px;padding:2px 8px;margin:0 2px;cursor:pointer;background:#fff;color:#000}.wc-table .interactivity .wc-button:hover{background:#000;color:#fff}.wc-table .searchable-container{float:right;overflow:hidden}.wc-table .searchable-container input{margin:0 10px 0 0;padding:4px}.wc-table .sortable-container{margin-right:10px}.wc-table .sortable-container .instruction{margin-top:4px}.wc-table .sortable-container .sort-box{cursor:default;padding:2px 4px}.wc-table .sortable-container .sort-direction{font-weight:700;margin:3px}.wc-table .sortable-container .sort-box .remove-sort{font-weight:700;float:right;border:1px solid gray;margin-top:3px;padding:2px 3px;font-size:8px;background:#fff;color:red}.wc-table .sortable-container .sort-box .remove-sort:hover{cursor:pointer;background:red;color:#fff}.wc-table table{font-size:.9em;border-collapse:collapse}.wc-table table thead tr th{cursor:pointer;padding:2px 5px;border-bottom:2px solid #000;text-align:left}.wc-table table tbody tr:nth-child(even){background:#eee}.wc-table table tbody tr:hover{background:#ccc}.wc-table table tbody tr td{padding:2px 5px}.wc-table table tbody tr:last-child{border-bottom:1px solid #000}.wc-table table tbody tr.no-data td{color:red;font-weight:700}.wc-table .pagination-container{float:right}.wc-table .pagination-container a{text-decoration:none}.wc-table .pagination-container a:not(.active){border:none}.wc-table .exportable-container{float:left}.wc-table .exportable-container a{text-decoration:none}.loader{position:relative;width:20px;height:25px}.blockG{position:absolute;background-color:#eee;width:3px;height:8px;-moz-border-radius:4px 4px 0 0;-moz-transform:scale(.4);-moz-animation-name:fadeG;-moz-animation-duration:.48s;-moz-animation-iteration-count:infinite;-moz-animation-direction:linear;-webkit-border-radius:4px 4px 0 0;-webkit-transform:scale(.4);-webkit-animation-name:fadeG;-webkit-animation-duration:.48s;-webkit-animation-iteration-count:infinite;-webkit-animation-direction:linear;-ms-border-radius:4px 4px 0 0;-ms-transform:scale(.4);-ms-animation-name:fadeG;-ms-animation-duration:.48s;-ms-animation-iteration-count:infinite;-ms-animation-direction:linear;-o-border-radius:4px 4px 0 0;-o-transform:scale(.4);-o-animation-name:fadeG;-o-animation-duration:.48s;-o-animation-iteration-count:infinite;-o-animation-direction:linear;border-radius:4px 4px 0 0;transform:scale(.4);animation-name:fadeG;animation-duration:.48s;animation-iteration-count:infinite;animation-direction:linear}.rotate1{left:0;top:9px;-moz-animation-delay:.18s;-moz-transform:rotate(-90deg);-webkit-animation-delay:.18s;-webkit-transform:rotate(-90deg);-ms-animation-delay:.18s;-ms-transform:rotate(-90deg);-o-animation-delay:.18s;-o-transform:rotate(-90deg);animation-delay:.18s;transform:rotate(-90deg)}.rotate2{left:3px;top:3px;-moz-animation-delay:.24s;-moz-transform:rotate(-45deg);-webkit-animation-delay:.24s;-webkit-transform:rotate(-45deg);-ms-animation-delay:.24s;-ms-transform:rotate(-45deg);-o-animation-delay:.24s;-o-transform:rotate(-45deg);animation-delay:.24s;transform:rotate(-45deg)}.rotate3{left:8px;top:1px;-moz-animation-delay:.3s;-moz-transform:rotate(0);-webkit-animation-delay:.3s;-webkit-transform:rotate(0);-ms-animation-delay:.3s;-ms-transform:rotate(0);-o-animation-delay:.3s;-o-transform:rotate(0);animation-delay:.3s;transform:rotate(0)}.rotate4{right:3px;top:3px;-moz-animation-delay:.36s;-moz-transform:rotate(45deg);-webkit-animation-delay:.36s;-webkit-transform:rotate(45deg);-ms-animation-delay:.36s;-ms-transform:rotate(45deg);-o-animation-delay:.36s;-o-transform:rotate(45deg);animation-delay:.36s;transform:rotate(45deg)}.rotate5{right:0;top:9px;-moz-animation-delay:.42000000000000004s;-moz-transform:rotate(90deg);-webkit-animation-delay:.42000000000000004s;-webkit-transform:rotate(90deg);-ms-animation-delay:.42000000000000004s;-ms-transform:rotate(90deg);-o-animation-delay:.42000000000000004s;-o-transform:rotate(90deg);animation-delay:.42000000000000004s;transform:rotate(90deg)}.rotate6{right:3px;bottom:2px;-moz-animation-delay:.48s;-moz-transform:rotate(135deg);-webkit-animation-delay:.48s;-webkit-transform:rotate(135deg);-ms-animation-delay:.48s;-ms-transform:rotate(135deg);-o-animation-delay:.48s;-o-transform:rotate(135deg);animation-delay:.48s;transform:rotate(135deg)}.rotate7{bottom:0;left:8px;-moz-animation-delay:.5399999999999999s;-moz-transform:rotate(180deg);-webkit-animation-delay:.5399999999999999s;-webkit-transform:rotate(180deg);-ms-animation-delay:.5399999999999999s;-ms-transform:rotate(180deg);-o-animation-delay:.5399999999999999s;-o-transform:rotate(180deg);animation-delay:.5399999999999999s;transform:rotate(180deg)}.rotate8{left:3px;bottom:2px;-moz-animation-delay:.6s;-moz-transform:rotate(-135deg);-webkit-animation-delay:.6s;-webkit-transform:rotate(-135deg);-ms-animation-delay:.6s;-ms-transform:rotate(-135deg);-o-animation-delay:.6s;-o-transform:rotate(-135deg);animation-delay:.6s;transform:rotate(-135deg)}@-moz-keyframes fadeG{0%{background-color:#000}100%{background-color:#eee}}@-webkit-keyframes fadeG{0%{background-color:#000}100%{background-color:#eee}}@-ms-keyframes fadeG{0%{background-color:#000}100%{background-color:#eee}}@-o-keyframes fadeG{0%{background-color:#000}100%{background-color:#eee}}@keyframes fadeG{0%{background-color:#000}100%{background-color:#eee}} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 8d73922..6bfbfc5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1512,8 +1512,7 @@ "exit-on-epipe": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/exit-on-epipe/-/exit-on-epipe-1.0.1.tgz", - "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==", - "optional": true + "integrity": "sha512-h2z5mrROTxce56S+pnvAV890uu7ls7f1kEvVGJbw1OlFH3/mlJ5bkXu0KRyW94v37zzHPiUd55iLn3DA7TjWpw==" }, "expect": { "version": "1.20.2", @@ -2423,7 +2422,7 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, @@ -2484,8 +2483,7 @@ "printj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/printj/-/printj-1.1.0.tgz", - "integrity": "sha512-NbiNBOQ0GioHyeD3ni8wZB7ZmfU7mxIrqhWR5XSreX3rUVvk5UOwpzxOnWqrLdCtoBbdQ40sEwC+nXxxjlUo0A==", - "optional": true + "integrity": "sha512-NbiNBOQ0GioHyeD3ni8wZB7ZmfU7mxIrqhWR5XSreX3rUVvk5UOwpzxOnWqrLdCtoBbdQ40sEwC+nXxxjlUo0A==" }, "private": { "version": "0.1.8", @@ -3033,8 +3031,7 @@ "voc": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/voc/-/voc-1.0.0.tgz", - "integrity": "sha512-mQwxWlK+zosxxDTqiFb9ZQBNgd794scgkhVwca7h9sEhvA52f3VzbOK+TOWeS8eSrFXnfuKrxElSPc5oLAetfw==", - "optional": true + "integrity": "sha512-mQwxWlK+zosxxDTqiFb9ZQBNgd794scgkhVwca7h9sEhvA52f3VzbOK+TOWeS8eSrFXnfuKrxElSPc5oLAetfw==" }, "w3c-hr-time": { "version": "1.0.1", diff --git a/src/chart/draw/consolidateData/setDefaults.js b/src/chart/draw/consolidateData/setDefaults.js index 9237bb3..ea12318 100644 --- a/src/chart/draw/consolidateData/setDefaults.js +++ b/src/chart/draw/consolidateData/setDefaults.js @@ -24,17 +24,20 @@ export default function setDefaults() { //legend 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.legend.mark = this.config.legend.mark !== undefined && typeof this.config.legend.mark === 'string' && ['bar', 'square', 'circle', 'line'].includes(this.config.legend.mark.toLowerCase()) - ? this.config.legend.mark.toLowerCase().replace('bar', 'square') - : this.config.marks[0].type !== undefined && typeof this.config.marks[0].type === 'string' && ['bar', 'circle', 'line'].includes(this.config.marks[0].type.toLowerCase()) - ? this.config.marks[0].type.toLowerCase().replace('bar', 'square') - : 'square'; + 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.legend.mark = + this.config.legend.mark !== undefined && + typeof this.config.legend.mark === 'string' && + ['bar', 'square', 'circle', 'line'].includes(this.config.legend.mark.toLowerCase()) + ? this.config.legend.mark.toLowerCase().replace('bar', 'square') + : this.config.marks[0].type !== undefined && + typeof this.config.marks[0].type === 'string' && + ['bar', 'circle', 'line'].includes(this.config.marks[0].type.toLowerCase()) + ? this.config.marks[0].type.toLowerCase().replace('bar', 'square') + : 'square'; // dimensions this.config.margin = this.config.margin || {}; diff --git a/src/chart/draw/setColorScale.js b/src/chart/draw/setColorScale.js index d0c2a21..70ed331 100644 --- a/src/chart/draw/setColorScale.js +++ b/src/chart/draw/setColorScale.js @@ -7,8 +7,9 @@ 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 !== 'undefined'); + : set(data.map(m => m[config.color_by])) + .values() + .filter(f => f !== 'undefined'); if (config.legend.order) colordom.sort((a, b) => diff --git a/src/chart/layout/addLegend.js b/src/chart/layout/addLegend.js index 661c86f..cd21f17 100644 --- a/src/chart/layout/addLegend.js +++ b/src/chart/layout/addLegend.js @@ -5,8 +5,6 @@ export default function addLegend() { .append('ul') .datum(() => null) // prevent data inheritance .classed('legend', true); - const legend_title = legend - .append('span') - .classed('legend-title', true); + const legend_title = legend.append('span').classed('legend-title', true); } } diff --git a/src/chart/resize/makeLegend/addLegendColorBlocks.js b/src/chart/resize/makeLegend/addLegendColorBlocks.js index a0b39f9..58cded3 100644 --- a/src/chart/resize/makeLegend/addLegendColorBlocks.js +++ b/src/chart/resize/makeLegend/addLegendColorBlocks.js @@ -4,7 +4,7 @@ export default function addLegendColorBlocks(legend_items) { .classed('legend-color-block', true) .attr({ width: '1.1em', - height: '1.1em', + height: '1.1em' }); return legend_color_blocks; diff --git a/src/chart/resize/makeLegend/addLegendItems.js b/src/chart/resize/makeLegend/addLegendItems.js index 57bb3f0..c36cc9b 100644 --- a/src/chart/resize/makeLegend/addLegendItems.js +++ b/src/chart/resize/makeLegend/addLegendItems.js @@ -13,13 +13,15 @@ export default function addLegendItems(legend_data, scale) { const legend_items = all_legend_items .enter() .append('li') - .classed('legend-item', true) - .classed(`legend-item--${this.config.legend.location}`, true); + .classed('legend-item', true); // update order of legend items in DOM if (this.config.legend.order) { legend_items.sort((a, b) => - ascending(this.config.legend.order.indexOf(a.label), this.config.legend.order.indexOf(b.label)) + ascending( + this.config.legend.order.indexOf(a.label), + this.config.legend.order.indexOf(b.label) + ) ); } diff --git a/src/chart/resize/makeLegend/addLegendMarks.js b/src/chart/resize/makeLegend/addLegendMarks.js index bc228b6..4841fc1 100644 --- a/src/chart/resize/makeLegend/addLegendMarks.js +++ b/src/chart/resize/makeLegend/addLegendMarks.js @@ -1,47 +1,45 @@ import { select } from 'd3'; export default function addLegendMarks(legend_color_blocks, scale) { - legend_color_blocks - .each(function(e) { - const svg = select(this); - svg.select('.legend-mark') - .remove(); + legend_color_blocks.each(function(e) { + const svg = select(this); + svg.select('.legend-mark').remove(); - if (e.mark === 'circle') { - svg.append('circle') - .classed('legend-mark', true) - .attr({ - cx: '.5em', - cy: '.5em', - r: '.45em', - }); - } else if (e.mark === 'line') { - svg.append('line') - .classed('legend-mark', true) - .attr({ - x1: 0, - y1: '.5em', - x2: '1em', - y2: '.5em', - 'stroke-width': 2, - 'shape-rendering': 'crispEdges', - }); - } else if (e.mark === 'square') { - svg.append('rect') - .classed('legend-mark', true) - .attr({ - height: '1em', - width: '1em', - 'shape-rendering': 'crispEdges' - }); - } - }); + if (e.mark === 'circle') { + svg.append('circle') + .classed('legend-mark', true) + .attr({ + cx: '.5em', + cy: '.5em', + r: '.45em' + }); + } else if (e.mark === 'line') { + svg.append('line') + .classed('legend-mark', true) + .attr({ + x1: 0, + y1: '.5em', + x2: '1em', + y2: '.5em', + 'stroke-width': 2, + 'shape-rendering': 'crispEdges' + }); + } else if (e.mark === 'square') { + svg.append('rect') + .classed('legend-mark', true) + .attr({ + height: '1em', + width: '1em', + 'shape-rendering': 'crispEdges' + }); + } + }); const legend_marks = legend_color_blocks .select('.legend-mark') .attr({ fill: d => d.color || scale(d.label), - stroke: d => d.color || scale(d.label), + stroke: d => d.color || scale(d.label) }) .each(function(e) { // apply custom mark attributes diff --git a/src/chart/resize/makeLegend/addLegendTitle.js b/src/chart/resize/makeLegend/addLegendTitle.js index 55f393f..7be3259 100644 --- a/src/chart/resize/makeLegend/addLegendTitle.js +++ b/src/chart/resize/makeLegend/addLegendTitle.js @@ -1,7 +1,5 @@ export default function addLegendTitle(legend_label) { - const legend_title = this.legend - .select('.legend-title') - .text(legend_label); + const legend_title = this.legend.select('.legend-title').text(legend_label); return legend_title; } diff --git a/src/chart/resize/makeLegend/defineLegendData.js b/src/chart/resize/makeLegend/defineLegendData.js index e84bd5e..4cc5061 100644 --- a/src/chart/resize/makeLegend/defineLegendData.js +++ b/src/chart/resize/makeLegend/defineLegendData.js @@ -1,16 +1,17 @@ export default function defineLegendData(custom_data, scale) { - const legend_data = Array.isArray(custom_data) && custom_data.length + const legend_data = + Array.isArray(custom_data) && custom_data.length ? custom_data : scale - .domain() - .slice(0) - .filter(f => f !== undefined && f !== null) - .map(m => { - return { - label: m, - mark: this.config.legend.mark - }; - }); + .domain() + .slice(0) + .filter(f => f !== undefined && f !== null) + .map(m => { + return { + label: m, + mark: this.config.legend.mark + }; + }); return legend_data; } diff --git a/test-page/createChart/index.js b/test-page/createChart/index.js index 684192e..cb57e75 100644 --- a/test-page/createChart/index.js +++ b/test-page/createChart/index.js @@ -23,7 +23,6 @@ const settings = { color_by: 'species', legend: { label: 'Species', - location: 'bottom', }, aspect: 3, }; From eb703a27d7b44c2e3a280b2f122c21430603f83d Mon Sep 17 00:00:00 2001 From: Spencer Childress Date: Tue, 17 Dec 2019 22:34:05 -0500 Subject: [PATCH 13/14] fix moveLegend.js --- build/webcharts.js | 4 ++-- build/webcharts.min.js | 2 +- src/chart/resize/makeLegend/moveLegend.js | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/webcharts.js b/build/webcharts.js index 917dd21..4173532 100644 --- a/build/webcharts.js +++ b/build/webcharts.js @@ -1654,7 +1654,7 @@ // TODO: consider moving legend around DOM on layout rather than on resize function moveLegend(scale) { - var legend = this.wrap.select('.legend'); + var legend = this.legend || this.wrap.select('.legend'); if (!this.parent) { //singular chart @@ -1678,7 +1678,7 @@ .classed('legend--'.concat(this.config.legend.location), true) .classed('legend--empty', scale.domain().length === 0); // display: none when color_by is not set? - return this.legend || legend; + return legend; } function defineLegendData(custom_data, scale) { diff --git a/build/webcharts.min.js b/build/webcharts.min.js index c4f83f1..843a824 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&&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){var legend=this.wrap.append("ul").datum(function(){return null}).classed("legend",true);var legend_title=legend.append("span").classed("legend-title",true)}}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.x.label=this.config.x.label!==undefined?this.config.x.label:this.config.x.column;this.config.x.sort=this.config.x.sort||"alphabetical-ascending";this.config.x.type=this.config.x.type||"linear";this.config.x.range_band=this.config.x.range_band||this.config.range_band;this.config.y=this.config.y||{};this.config.y.label=this.config.y.label!==undefined?this.config.y.label:this.config.y.column;this.config.y.sort=this.config.y.sort||"alphabetical-descending";this.config.y.type=this.config.y.type||"linear";this.config.y.range_band=this.config.y.range_band||this.config.range_band;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.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.legend.mark=this.config.legend.mark!==undefined&&typeof this.config.legend.mark==="string"&&["bar","square","circle","line"].includes(this.config.legend.mark.toLowerCase())?this.config.legend.mark.toLowerCase().replace("bar","square"):this.config.marks[0].type!==undefined&&typeof this.config.marks[0].type==="string"&&["bar","circle","line"].includes(this.config.marks[0].type.toLowerCase())?this.config.marks[0].type.toLowerCase().replace("bar","square"):"square";this.config.margin=this.config.margin||{};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().filter(function(f){return 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 moveLegend(scale){var legend=this.wrap.select(".legend");if(!this.parent){if(this.config.legend.location==="top"||this.config.legend.location==="left"){this.wrap.node().insertBefore(legend.node(),this.svg.node().parentNode)}else{this.wrap.node().appendChild(legend.node())}}else{if(this.config.legend.location==="top"||this.config.legend.location==="left"){this.parent.wrap.node().insertBefore(legend.node(),this.parent.wrap.select(".wc-chart").node())}else{this.parent.wrap.node().appendChild(legend.node())}}legend.classed("legend--".concat(this.config.legend.location),true).classed("legend--empty",scale.domain().length===0);return this.legend||legend}function defineLegendData(custom_data,scale){var _this=this;var legend_data=Array.isArray(custom_data)&&custom_data.length?custom_data:scale.domain().slice(0).filter(function(f){return f!==undefined&&f!==null}).map(function(m){return{label:m,mark:_this.config.legend.mark}});return legend_data}function addLegendTitle(legend_label){var legend_title=this.legend.select(".legend-title").text(legend_label);return legend_title} +(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){var legend=this.wrap.append("ul").datum(function(){return null}).classed("legend",true);var legend_title=legend.append("span").classed("legend-title",true)}}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.x.label=this.config.x.label!==undefined?this.config.x.label:this.config.x.column;this.config.x.sort=this.config.x.sort||"alphabetical-ascending";this.config.x.type=this.config.x.type||"linear";this.config.x.range_band=this.config.x.range_band||this.config.range_band;this.config.y=this.config.y||{};this.config.y.label=this.config.y.label!==undefined?this.config.y.label:this.config.y.column;this.config.y.sort=this.config.y.sort||"alphabetical-descending";this.config.y.type=this.config.y.type||"linear";this.config.y.range_band=this.config.y.range_band||this.config.range_band;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.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.legend.mark=this.config.legend.mark!==undefined&&typeof this.config.legend.mark==="string"&&["bar","square","circle","line"].includes(this.config.legend.mark.toLowerCase())?this.config.legend.mark.toLowerCase().replace("bar","square"):this.config.marks[0].type!==undefined&&typeof this.config.marks[0].type==="string"&&["bar","circle","line"].includes(this.config.marks[0].type.toLowerCase())?this.config.marks[0].type.toLowerCase().replace("bar","square"):"square";this.config.margin=this.config.margin||{};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().filter(function(f){return 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 moveLegend(scale){var legend=this.legend||this.wrap.select(".legend");if(!this.parent){if(this.config.legend.location==="top"||this.config.legend.location==="left"){this.wrap.node().insertBefore(legend.node(),this.svg.node().parentNode)}else{this.wrap.node().appendChild(legend.node())}}else{if(this.config.legend.location==="top"||this.config.legend.location==="left"){this.parent.wrap.node().insertBefore(legend.node(),this.parent.wrap.select(".wc-chart").node())}else{this.parent.wrap.node().appendChild(legend.node())}}legend.classed("legend--".concat(this.config.legend.location),true).classed("legend--empty",scale.domain().length===0);return legend}function defineLegendData(custom_data,scale){var _this=this;var legend_data=Array.isArray(custom_data)&&custom_data.length?custom_data:scale.domain().slice(0).filter(function(f){return f!==undefined&&f!==null}).map(function(m){return{label:m,mark:_this.config.legend.mark}});return legend_data}function addLegendTitle(legend_label){var legend_title=this.legend.select(".legend-title").text(legend_label);return legend_title} function addLegendItems(legend_data,scale){var _this=this;var all_legend_items=this.legend.selectAll(".legend-item").data(legend_data,function(d){return d.label+d.mark});all_legend_items.exit().remove();var legend_items=all_legend_items.enter().append("li").classed("legend-item",true);if(this.config.legend.order){legend_items.sort(function(a,b){return d3.ascending(_this.config.legend.order.indexOf(a.label),_this.config.legend.order.indexOf(b.label))})}return legend_items}function addLegendMarkTexts(legend_items,scale){var legend_mark_texts=legend_items.append("span").classed("legend-mark-text",true).style("color",function(d){return scale(d.label)});return legend_mark_texts}function addLegendColorBlocks(legend_items){var legend_color_blocks=legend_items.append("svg").classed("legend-color-block",true).attr({width:"1.1em",height:"1.1em"});return legend_color_blocks}function addLegendMarks(legend_color_blocks,scale){legend_color_blocks.each(function(e){var svg=d3.select(this);svg.select(".legend-mark").remove();if(e.mark==="circle"){svg.append("circle").classed("legend-mark",true).attr({cx:".5em",cy:".5em",r:".45em"})}else if(e.mark==="line"){svg.append("line").classed("legend-mark",true).attr({x1:0,y1:".5em",x2:"1em",y2:".5em","stroke-width":2,"shape-rendering":"crispEdges"})}else if(e.mark==="square"){svg.append("rect").classed("legend-mark",true).attr({height:"1em",width:"1em","shape-rendering":"crispEdges"})}});var legend_marks=legend_color_blocks.select(".legend-mark").attr({fill:function fill(d){return d.color||scale(d.label)},stroke:function stroke(d){return d.color||scale(d.label)}}).each(function(e){d3.select(this).attr(e.attributes)})}function addLegendLabels(legend_items){var legend_labels=legend_items.append("span").classed("legend-label",true).text(function(d){return d.label});return legend_labels}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;this.legend=moveLegend.call(this,scale);var legend_label=label||this.config.legend.label||"";var legend_data=defineLegendData.call(this,custom_data,scale);var legend_title=addLegendTitle.call(this,legend_label);var legend_items=addLegendItems.call(this,legend_data,scale);var legend_mark_texts=addLegendMarkTexts.call(this,legend_items,scale);var legend_color_blocks=addLegendColorBlocks.call(this,legend_items);var legend_marks=addLegendMarks.call(this,legend_color_blocks,scale);var legend_labels=addLegendLabels.call(this,legend_items)}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")});if(marks.length){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()}texts.each(attachMarks);texts.select("text").style("clip-path","url(#".concat(chart.id,")")).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).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]})}).each(function(d){d3.select(this).attr(d.mark.attributes)});var textsTrans=config.transitions?texts.select("text").transition():texts.select("text");textsTrans.attr("x",function(d){var xPos=_this.x(d.values.x)||0;return config.x.type==="ordinal"?xPos+_this.x.rangeBand()/2:xPos}).attr("y",function(d){var yPos=_this.y(d.values.y)||0;return config.y.type==="ordinal"?yPos+_this.y.rangeBand()/2:yPos});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(order===0){if(item.type==="number"){order=item.direction==="ascending"?+aCell-+bCell:+bCell-+aCell}else{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/resize/makeLegend/moveLegend.js b/src/chart/resize/makeLegend/moveLegend.js index 7e4ae4f..a61a0e9 100644 --- a/src/chart/resize/makeLegend/moveLegend.js +++ b/src/chart/resize/makeLegend/moveLegend.js @@ -1,6 +1,6 @@ // TODO: consider moving legend around DOM on layout rather than on resize export default function moveLegend(scale) { - const legend = this.wrap.select('.legend'); + const legend = this.legend || this.wrap.select('.legend'); if (!this.parent) { //singular chart @@ -24,5 +24,5 @@ export default function moveLegend(scale) { .classed(`legend--${this.config.legend.location}`, true) .classed('legend--empty', scale.domain().length === 0); // display: none when color_by is not set? - return this.legend || legend; + return legend; } From 7c2fbb6568006ba958b65f1dbdf05fbfc4206882 Mon Sep 17 00:00:00 2001 From: Spencer Childress Date: Sun, 12 Jan 2020 17:16:53 -0500 Subject: [PATCH 14/14] fix #274 --- package.json | 2 +- test/table/configTester.js | 56 +++++++++++------------- test/table/createTable.js | 1 + test/table/sortTable.js | 2 - test/{testNewUnitTests.js => testNew.js} | 4 +- 5 files changed, 29 insertions(+), 36 deletions(-) rename test/{testNewUnitTests.js => testNew.js} (74%) diff --git a/package.json b/package.json index 5bba091..9b4b265 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,7 @@ "test-controls": "mocha --timeout 5000 --require @babel/register --recursive ./test/controls/*.js", "test-miscellaneous": "mocha --timeout 5000 --require @babel/register --recursive ./test/miscellaneous/*.js", "test-multiply": "mocha --timeout 5000 --require @babel/register --recursive ./test/multiply/*.js", - "test-new": "mocha --require @babel/register ./test/testNewUnitTests.js", + "test-new": "mocha --require @babel/register ./test/testNew.js", "test-page": "start chrome ./test-page/createChart/index.html && start chrome ./test-page/createTable/index.html && start chrome ./test-page/multiply/index.html", "test-table": "mocha --timeout 5000 --require @babel/register --recursive ./test/table/*.js", "watch": "rollup -c -w" diff --git a/test/table/configTester.js b/test/table/configTester.js index c77b236..1ee2542 100644 --- a/test/table/configTester.js +++ b/test/table/configTester.js @@ -1,44 +1,23 @@ import testSettingList from '../samples/chart-config/testSettingList'; - -import { readFile, readFileSync } from 'fs'; -import d3 from 'd3'; -import { merge } from 'd3'; -import jsdom from 'jsdom'; -import webcharts from '../../build/webcharts'; -import expect from 'expect'; - +import { join } from 'path'; +import { readFileSync } from 'fs'; +import { merge, csv } from 'd3'; import testCreateTable from '../table/createTable'; import testRendering from '../table/rendering'; -var settingsList = []; -var numLoaded = 0; - -var testSettingList_tables = testSettingList.filter(function(d) { - return d.type == 'tables'; -}); - -testSettingList_tables.forEach(function(d) { - var path = require('path'); - var jsonPath = path.join(__dirname, '..', 'samples', 'chart-config', d.filename); - - var jsonRaw = readFileSync(jsonPath, 'utf8'); - var jsonData = JSON.parse(jsonRaw); - settingsList = merge([settingsList, jsonData]); - numLoaded = numLoaded + 1; - if (numLoaded == testSettingList_tables.length) runTests(settingsList); - //if (numLoaded == 1) runTests(settingsList); -}); - +// Run ./createTable.js and ./rendering.js for each settings object ../samples/chart-config/testSettingsList.json function runTests(settingsList) { - it('run tests once for each settings object', done => { + it('runs tests once for each settings object', done => { settingsList.forEach((settings, i) => { - const dataFile = `./test/samples/data/${settings.filename}`, - raw = readFileSync(dataFile, 'utf8'), - data = d3.csv.parse(raw); + const dataFile = `./test/samples/data/${settings.filename}`; + const text = readFileSync(dataFile, 'utf8'); + const data = csv.parse(text); + describe(`Table Test ${i + 1} of ${settingsList.length}: ${settings.label}. `, () => { describe('Create Table. ', () => { testCreateTable(settings.settings); }); + describe('Render Table. ', () => { testRendering(settings.settings, data); }); @@ -47,3 +26,18 @@ function runTests(settingsList) { done(); }); } + +let settingsList = []; // capture each settings object in an array +let numLoaded = 0; // capture number of settings objects +const testSettingList_tables = testSettingList.filter(d => d.type == 'tables'); + +testSettingList_tables.forEach(function(d) { + const jsonPath = join(__dirname, '..', 'samples', 'chart-config', d.filename); + const jsonRaw = readFileSync(jsonPath, 'utf8'); + const jsonData = JSON.parse(jsonRaw); + settingsList = merge([settingsList, jsonData]); + numLoaded = numLoaded + 1; + + // Run tests once all settings objects have been loaded. + if (numLoaded === testSettingList_tables.length) runTests(settingsList); +}); diff --git a/test/table/createTable.js b/test/table/createTable.js index d99194b..0889bc9 100644 --- a/test/table/createTable.js +++ b/test/table/createTable.js @@ -28,6 +28,7 @@ export default function testCreateTable(settings) { 'config', 'controls', 'filters', + 'id', 'required_cols', 'wrap', 'events', diff --git a/test/table/sortTable.js b/test/table/sortTable.js index ddf9f9c..6c47a4d 100644 --- a/test/table/sortTable.js +++ b/test/table/sortTable.js @@ -19,7 +19,6 @@ export default function testSortTable(settings, data) { return i < 5; }) .data(); - console.log(JSON.stringify(table.first5, null, 4)); }); it('a sort div should exist', () => { @@ -46,7 +45,6 @@ export default function testSortTable(settings, data) { return i < 5; }) .data(); - console.log(JSON.stringify(sorted5, null, 4)); expect(sorted5).toNotEqual(table.first5); }); it('ascending sort works as expected', () => { diff --git a/test/testNewUnitTests.js b/test/testNew.js similarity index 74% rename from test/testNewUnitTests.js rename to test/testNew.js index d5aab24..52e8805 100644 --- a/test/testNewUnitTests.js +++ b/test/testNew.js @@ -12,5 +12,5 @@ // test(settings, data); import data from './samples/irisData'; -import testSortTable from './table/sortTable'; -testSortTable({ sortable: true, searchable: false, exportable: false, pagination: false }, data); +import testCreateTable from './table/createTable'; +testCreateTable({ exportable: false });