diff --git a/build/webcharts.js b/build/webcharts.js
index a0f4a51..773db65 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);
@@ -241,16 +241,15 @@
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) {
+ var legend = this.wrap
.append('ul')
.datum(function() {
return null;
}) // prevent data inheritance
- .attr('class', 'legend')
- .style('vertical-align', 'top')
- .append('span')
- .attr('class', 'legend-title');
+ .classed('legend', true);
+ var legend_title = legend.append('span').classed('legend-title', true);
+ }
}
function clearLoader() {
@@ -400,18 +399,18 @@
}
function setDomain(axis) {
- var _this = this;
-
- var otherAxis = axis === 'x' ? 'y' : 'x';
+ var thisAxis = this.config[axis];
+ var thatAxis = this.config[axis === 'x' ? 'y' : 'x'];
+ var dom;
- if (this.config[axis].type === 'ordinal') {
+ if (thisAxis.type === 'ordinal') {
//ordinal domains
- if (this.config[axis].domain) {
+ if (thisAxis.domain) {
//user-defined domain
- this[axis + '_dom'] = this.config[axis].domain;
- } else if (this.config[axis].order) {
+ dom = thisAxis.domain;
+ } else if (thisAxis.order) {
//data-driven domain with user-defined domain order
- this[axis + '_dom'] = d3
+ dom = d3
.set(
d3.merge(
this.marks.map(function(mark) {
@@ -421,18 +420,12 @@
)
.values()
.sort(function(a, b) {
- return d3.ascending(
- _this.config[axis].order.indexOf(a),
- _this.config[axis].order.indexOf(b)
- );
+ return d3.ascending(thisAxis.order.indexOf(a), thisAxis.order.indexOf(b));
});
- } else if (
- this.config[axis].sort &&
- this.config[axis].sort === 'alphabetical-ascending'
- ) {
+ } else if (thisAxis.sort && thisAxis.sort === 'alphabetical-ascending') {
//data-driven domain with user-defined domain sort algorithm that sorts the axis
//alphanumerically, first to last
- this[axis + '_dom'] = d3
+ dom = d3
.set(
d3.merge(
this.marks.map(function(mark) {
@@ -443,20 +436,20 @@
.values()
.sort(naturalSorter);
} else if (
- ['time', 'linear'].indexOf(this.config[otherAxis].type) > -1 &&
- this.config[axis].sort === 'earliest'
+ ['time', 'linear'].indexOf(thatAxis.type) > -1 &&
+ thisAxis.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
+ dom = d3
.nest()
.key(function(d) {
- return d[_this.config[axis].column];
+ return d[thisAxis.column];
})
.rollup(function(d) {
return d
.map(function(m) {
- return m[_this.config[otherAxis].column];
+ return m[thatAxis.column];
})
.filter(function(f) {
return f instanceof Date;
@@ -469,13 +462,10 @@
.map(function(m) {
return m.key;
});
- } else if (
- !this.config[axis].sort ||
- this.config[axis].sort === 'alphabetical-descending'
- ) {
+ } else if (!thisAxis.sort || thisAxis.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
+ dom = d3
.set(
d3.merge(
this.marks.map(function(mark) {
@@ -489,7 +479,7 @@
} 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
+ dom = d3
.set(
d3.merge(
this.marks.map(function(mark) {
@@ -507,13 +497,13 @@
.indexOf(true) > -1
) {
//rate domains run from 0 to 1
- this[axis + '_dom'] = [0, 1];
+ 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(
+ dom = d3.extent(
d3.merge(
this.marks.map(function(mark) {
return mark[axis + '_dom'];
@@ -522,18 +512,10 @@
);
} //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'];
+ if (thisAxis.type === 'linear' && dom[0] === dom[1])
+ dom = dom[0] !== 0 ? [dom[0] - dom[0] * 0.01, dom[1] + dom[1] * 0.01] : [-1, 1];
+ this[axis + '_dom'] = dom;
+ return dom;
}
function consolidateData(raw) {
@@ -550,7 +532,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.
@@ -576,19 +558,28 @@
}
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.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
@@ -596,11 +587,19 @@
: 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.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;
@@ -776,18 +775,27 @@
return d[sublevel];
});
this_nest.sortKeys(function(a, b) {
- return _this.config.x.type === 'time'
- ? d3.ascending(new Date(a), new Date(b))
- : _this.config.x.order
- ? d3.ascending(_this.config.x.order.indexOf(a), _this.config.x.order.indexOf(b))
- : sublevel === _this.config.color_by && _this.config.legend.order
- ? d3.ascending(
- _this.config.legend.order.indexOf(a),
- _this.config.legend.order.indexOf(b)
- )
- : _this.config.x.type === 'ordinal' || _this.config.y.type === 'ordinal'
- ? naturalSorter(a, b)
- : d3.ascending(+a, +b);
+ var sort;
+
+ if (_this.config.x.type === 'time') {
+ sort = d3.ascending(new Date(a), new Date(b));
+ } else if (_this.config.x.order) {
+ sort = d3.ascending(
+ _this.config.x.order.indexOf(a),
+ _this.config.x.order.indexOf(b)
+ );
+ } else if (sublevel === _this.config.color_by && _this.config.legend.order) {
+ sort = d3.ascending(
+ _this.config.legend.order.indexOf(a),
+ _this.config.legend.order.indexOf(b)
+ );
+ } else if (_this.config.x.type === 'ordinal' || _this.config.y.type === 'ordinal') {
+ sort = naturalSorter(a, b);
+ } else {
+ sort = d3.ascending(+a, +b);
+ }
+
+ return sort;
});
}
@@ -967,7 +975,10 @@
.map(function(m) {
return m.key;
});
- }
+ } else
+ totalOrder = test.map(function(m) {
+ return m.key;
+ });
return {
nested: test,
@@ -1106,7 +1117,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
@@ -1139,7 +1150,8 @@
}
var filt1_dom_x = d3.extent(d3.merge(filt1_xs));
- var filt1_dom_y = d3.extent(d3.merge(filt1_ys));
+ var filt1_dom_y = d3.extent(d3.merge(filt1_ys)); // why are we calling makeNest twice?
+
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;
@@ -1263,11 +1275,15 @@
}
if (config.x.type === 'ordinal' && !config.x.order) {
- config.x.order = current_nested.totalOrder;
+ x_dom.sort(function(a, b) {
+ return current_nested.totalOrder.indexOf(a) - current_nested.totalOrder.indexOf(b);
+ });
}
if (config.y.type === 'ordinal' && !config.y.order) {
- config.y.order = current_nested.totalOrder;
+ y_dom.sort(function(a, b) {
+ return current_nested.totalOrder.indexOf(a) - current_nested.totalOrder.indexOf(b);
+ });
}
this.current_data = current_nested.nested;
@@ -1294,7 +1310,7 @@
)
.values()
.filter(function(f) {
- return f && f !== 'undefined';
+ return f !== 'undefined';
});
if (config.legend.order)
colordom.sort(function(a, b) {
@@ -1627,176 +1643,185 @@
}
}
- 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;
+ // TODO: consider moving legend around DOM on layout rather than on resize
+ function moveLegend(scale) {
+ var legend = this.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(legendOriginal.node(), this.svg.node().parentNode);
+ this.wrap.node().insertBefore(legend.node(), this.svg.node().parentNode);
} else {
- this.wrap.node().appendChild(legendOriginal.node());
+ 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(
- legendOriginal.node(),
- this.parent.wrap.select('.wc-chart').node()
- );
+ .insertBefore(legend.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) {
+ .classed('legend--'.concat(this.config.legend.location), true)
+ .classed('legend--empty', scale.domain().length === 0); // display: none when color_by is not set?
+
+ 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;
+
+ // 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;
- });
- leg_parts.exit().remove();
- var legendPartDisplay =
- this.config.legend.location === 'bottom' || this.config.legend.location === 'top'
- ? 'inline-block'
- : 'block';
- var new_parts = leg_parts
+ }); // exit and remove
+
+ all_legend_items.exit().remove(); // enter and append
+
+ var legend_items = all_legend_items
.enter()
.append('li')
- .attr('class', 'legend-item')
- .style({
- 'list-style-type': 'none',
- 'margin-right': '1em'
+ .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)
+ );
});
- new_parts
+ }
+
+ return legend_items;
+ }
+
+ function addLegendMarkTexts(legend_items, scale) {
+ var legend_mark_texts = legend_items
.append('span')
- .attr('class', 'legend-mark-text')
+ .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'
- });
- leg_parts.style('display', legendPartDisplay);
+ return legend_mark_texts;
+ }
- 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)
- );
+ 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;
+ }
- 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({
- 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')
+ var legend_marks = legend_color_blocks
.select('.legend-mark')
- .attr('fill', function(d) {
- return d.color || scale(d.label);
- })
- .attr('stroke', function(d) {
- return d.color || scale(d.label);
+ .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);
});
- new_parts
+ }
+
+ function addLegendLabels(legend_items) {
+ var legend_labels = legend_items
.append('span')
- .attr('class', 'legend-label')
- .style('margin-left', '0.25em')
+ .classed('legend-label', true)
.text(function(d) {
return d.label;
});
+ return legend_labels;
+ }
- 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');
- }
+ 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
- this.legend = legend;
+ 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() {
@@ -1851,24 +1876,537 @@
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;
+ .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 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);
+
+ 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 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 _this = this;
-
- var chart = this;
var rawData = this.raw_data;
- var config = this.config;
+ 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('-');
});
@@ -1878,7 +2416,8 @@
.attr('class', function(d) {
return 'supergroup bar-supergroup ' + d.id;
});
- bar_supergroups.exit().remove();
+ bar_supergroups.exit().remove(); // bar groups
+
var bar_groups = bar_supergroups.selectAll('.bar-group').data(
function(d) {
return d.data;
@@ -1889,515 +2428,25 @@
);
var old_bar_groups = bar_groups.exit();
var nu_bar_groups;
- var bars;
+ 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') {
- 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);
- });
+ 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', 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 * 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();
- }
- });
+ 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', 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);
- });
+ 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', 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);
- });
+ yBin.call(this, oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars);
} else {
oldBarsTrans.attr('y', this.y(0)).attr('height', 0);
oldBarGroupsTrans.remove();
@@ -2546,7 +2595,7 @@
.append('circle')
.attr('class', 'wc-data-mark')
.attr('r', 0);
- nupoints.append('title'); //static attributes
+ nupoints.append('title'); // static attributes
points
.select('circle')
@@ -2560,7 +2609,7 @@
})
.attr('stroke', function(d) {
return _this.colorScale(d.values.raw[0][config.color_by]);
- }); //attach mark info
+ }); // attach mark info
points.each(function(d) {
var mark = d3.select(this.parentNode).datum();
@@ -2568,7 +2617,7 @@
d3.select(this)
.select('circle')
.attr(mark.attributes);
- }); //animated attributes
+ }); // animated attributes
var pointsTrans = config.transitions
? points.select('circle').transition()
@@ -2611,13 +2660,32 @@
.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
+
+ 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;
}
@@ -2626,17 +2694,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;
},
@@ -2660,9 +2728,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
@@ -2670,6 +2735,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 =
@@ -2700,6 +2768,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
@@ -2713,9 +2784,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 its data
- textSupergroups.each(function(d) {
+ text_supergroups.each(function(d) {
d.supergroup = d3.select(this);
d.groups = d.supergroup.selectAll('g.text');
d.texts = d.groups.select('text');
@@ -3171,14 +3242,10 @@
? control.values
: d3
.set(
- this.data
- .map(function(m) {
- return m[control.value_col];
- })
- .filter(function(f) {
- return f;
- })
- )
+ this.data.map(function(m) {
+ return m[control.value_col];
+ })
+ ) //.filter(f => f))
.values()
.sort(naturalSorter); // only sort when values are derived
//initial dropdown option
@@ -3402,7 +3469,7 @@
);
})
) {
- this.data.filtered = this.data.raw;
+ this.data.filtered = this.data.raw.slice();
this.filters
.filter(function(filter) {
return (
@@ -3418,7 +3485,7 @@
: filter.val === d[filter.col];
});
});
- } else this.data.filtered = this.data.raw;
+ } else this.data.filtered = this.data.raw.slice();
}
function updateDataObject() {
@@ -3828,15 +3895,16 @@
bookSST: true,
type: 'binary'
};
- var arrayOfArrays = data.map(function(d) {
- return Object.keys(d)
- .filter(function(key) {
- return _this.config.cols.indexOf(key) > -1;
- })
- .map(function(key) {
- return d[key];
+ var arrayOfArrays = data.map(
+ function(d) {
+ return _this.config.cols.map(function(col) {
+ return d[col];
});
- }); // convert data from array of objects to array of arrays.
+ } //Object.keys(d)
+ // .filter(key => this.config.cols.indexOf(key) > -1)
+ // .sort((a,b) => this.config.cols.indexOf(a) - this.config.cols.indexOf(b))
+ // .map(key => d[key])
+ ); // convert data from array of objects to array of arrays.
var workbook = {
SheetNames: [sheetName],
@@ -3922,7 +3990,8 @@
key: col
})
.classed('wc-button sort-box', true)
- .text(header)
+ .text(header),
+ type: this.config.types[col]
};
sortItem.wrap
.append('span')
@@ -3968,6 +4037,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 +4063,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 (
+ (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 +4439,39 @@
}
function setDefaults$1(firstItem) {
- //Set data-driven defaults.
- if (this.config.cols instanceof Array && this.config.headers instanceof Array) {
- if (this.config.cols.length === 0) delete this.config.cols;
- if (
- this.config.headers.length === 0 ||
- this.config.headers.length !== this.config.cols.length
- )
- delete this.config.headers;
- }
+ var _this = this;
- this.config.cols = this.config.cols || d3.keys(firstItem);
- this.config.headers = this.config.headers || this.config.cols;
- this.config.layout = 'horizontal'; // placeholder setting to align table components vertically or horizontally
- //Set all other defaults.
+ // cols
+ if (
+ !Array.isArray(this.config.cols) ||
+ (Array.isArray(this.config.cols) && this.config.cols.length === 0)
+ )
+ this.config.cols = d3.keys(firstItem); // headers
+
+ if (
+ !Array.isArray(this.config.headers) ||
+ (Array.isArray(this.config.headers) && this.config.headers.length === 0) ||
+ (Array.isArray(this.config.headers) &&
+ this.config.headers.length !== this.config.cols.length)
+ )
+ this.config.headers = this.config.cols.slice(); // types
+
+ if (_typeof(this.config.types) !== 'object') this.config.types = {};
+ this.config.cols.forEach(function(col) {
+ if (!['string', 'number'].includes(_this.config.types[col]))
+ _this.config.types[col] = 'string';
+ }); // Set all other defaults.
setDefault.call(this, 'searchable');
- setDefault.call(this, 'exportable');
- setDefault.call(this, 'exports', ['csv']);
setDefault.call(this, 'sortable');
setDefault.call(this, 'pagination');
+ setDefault.call(this, 'exportable');
+ setDefault.call(this, 'exports', ['csv']);
setDefault.call(this, 'nRowsPerPage', 10);
setDefault.call(this, 'nPageLinksDisplayed', 5);
setDefault.call(this, 'applyCSS');
setDefault.call(this, 'dynamicPositioning');
+ setDefault.call(this, 'layout', 'horizontal');
}
function transformData$1(processed_data) {
@@ -4508,6 +4609,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 +4642,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..853a15e 100644
--- a/build/webcharts.min.js
+++ b/build/webcharts.min.js
@@ -1,3 +1,3 @@
-(function(global,factory){typeof exports==="object"&&typeof module!=="undefined"?module.exports=factory(require("d3")):typeof define==="function"&&define.amd?define(["d3"],factory):(global=global||self,global.webCharts=factory(global.d3))})(this,function(d3){"use strict";var version="1.11.7";function init(data){var _this=this;var test=arguments.length>1&&arguments[1]!==undefined?arguments[1]:false;this.test=test;if(d3.select(this.div).select(".loader").empty()){d3.select(this.div).insert("div",":first-child").attr("class","loader").selectAll(".blockG").data(d3.range(8)).enter().append("div").attr("class",function(d){return"blockG rotate"+(d+1)})}this.wrap.attr("class","wc-chart");this.setDefaults();this.raw_data=data;this.initial_data=data;var startup=function startup(data){if(_this.controls){_this.controls.targets.push(_this);if(!_this.controls.ready){_this.controls.init(_this.raw_data)}else{_this.controls.layout()}}var visible=d3.select(_this.div).property("offsetWidth")>0||test;if(!visible){console.warn("The chart cannot be initialized inside an element with 0 width. The chart will be initialized as soon as the container element is given a width > 0.");var onVisible=setInterval(function(i){var visible_now=d3.select(_this.div).property("offsetWidth")>0;if(visible_now){_this.layout();_this.draw();clearInterval(onVisible)}},500)}else{_this.layout();_this.draw()}};this.events.onInit.call(this);if(this.raw_data.length){this.checkRequired(this.raw_data)}startup();return this}function checkRequired(data){var _this=this;var colnames=Object.keys(data[0]);var requiredVars=[];var requiredCols=[];if(this.config.x&&this.config.x.column){requiredVars.push("this.config.x.column");requiredCols.push(this.config.x.column)}if(this.config.y&&this.config.y.column){requiredVars.push("this.config.y.column");requiredCols.push(this.config.y.column)}if(this.config.color_by){requiredVars.push("this.config.color_by");requiredCols.push(this.config.color_by)}if(this.config.marks)this.config.marks.forEach(function(e,i){if(e.per&&e.per.length){e.per.forEach(function(p,j){requiredVars.push("this.config.marks["+i+"].per["+j+"]");requiredCols.push(p)})}if(e.split){requiredVars.push("this.config.marks["+i+"].split");requiredCols.push(e.split)}if(e.values){for(var value in e.values){requiredVars.push("this.config.marks["+i+"].values['"+value+"']");requiredCols.push(value)}}});var missingDataField=false;requiredCols.forEach(function(e,i){if(colnames.indexOf(e)<0){missingDataField=true;d3.select(_this.div).select(".loader").remove();_this.wrap.append("div").style("color","red").html('The value "'+e+'" for the '+requiredVars[i]+"
setting does not match any column in the provided dataset.");throw new Error('Error in settings object: The value "'+e+'" for the '+requiredVars[i]+" setting does not match any column in the provided dataset.")}});return{missingDataField:missingDataField,dataFieldArguments:requiredVars,requiredDataFields:requiredCols}}function addSVG(){this.svg=this.wrap.append("svg").datum(function(){return null}).attr({class:"wc-svg",xmlns:"http://www.w3.org/2000/svg",version:"1.1",xlink:"http://www.w3.org/1999/xlink"}).append("g").style("display","inline-block")}function addDefs(){var defs=this.svg.append("defs");defs.append("pattern").attr({id:"diagonal-stripes",x:0,y:0,width:3,height:8,patternUnits:"userSpaceOnUse",patternTransform:"rotate(30)"}).append("rect").attr({x:"0",y:"0",width:"2",height:"8"}).style({stroke:"none",fill:"black"});defs.append("clipPath").attr("id",this.id).append("rect").attr("class","plotting-area")}function addXAxis(){this.svg.append("g").attr("class","x axis").append("text").attr("class","axis-title").attr("dy","-.35em").attr("text-anchor","middle")}function addYAxis(){this.svg.append("g").attr("class","y axis").append("text").attr("class","axis-title").attr("transform","rotate(-90)").attr("dy",".75em").attr("text-anchor","middle")}function addOverlay(){this.overlay=this.svg.append("rect").attr("class","overlay").attr("opacity",0).attr("fill","none").style("pointer-events","all")}function addLegend(){if(!this.parent)this.wrap.append("ul").datum(function(){return null}).attr("class","legend").style("vertical-align","top").append("span").attr("class","legend-title")}function clearLoader(){d3.select(this.div).select(".loader").remove()}function layout(){addSVG.call(this);addDefs.call(this);addXAxis.call(this);addYAxis.call(this);addOverlay.call(this);addLegend.call(this);clearLoader.call(this);this.events.onLayout.call(this)}function draw(raw_data,processed_data){var _this=this;var chart=this;var config=this.config;this.events.onPreprocess.call(this);var raw=raw_data?raw_data:this.raw_data?this.raw_data:[];if(processed_data){console.warn("Drawing the chart using user-defined 'processed_data', this is an experimental, untested feature.")}this.consolidateData(raw);var div_width=parseInt(this.wrap.style("width"));this.setColorScale();var max_width=config.max_width?config.max_width:div_width;this.raw_width=config.x.type==="ordinal"&&+config.x.range_band?(+config.x.range_band+config.x.range_band*config.padding)*this.x_dom.length:config.resizable?max_width:config.width?config.width:div_width;this.raw_height=config.y.type==="ordinal"&&+config.y.range_band?(+config.y.range_band+config.y.range_band*config.padding)*this.y_dom.length:config.resizable?max_width*(1/config.aspect):config.height?config.height:div_width*(1/config.aspect);var pseudo_width=this.svg.select(".overlay").attr("width")?this.svg.select(".overlay").attr("width"):this.raw_width;var pseudo_height=this.svg.select(".overlay").attr("height")?this.svg.select(".overlay").attr("height"):this.raw_height;this.svg.select(".x.axis").select(".axis-title").text(function(d){return typeof config.x.label==="string"?config.x.label:typeof config.x.label==="function"?config.x.label.call(_this):null});this.svg.select(".y.axis").select(".axis-title").text(function(d){return typeof config.y.label==="string"?config.y.label:typeof config.y.label==="function"?config.y.label.call(_this):null});this.xScaleAxis(pseudo_width);this.yScaleAxis(pseudo_height);if(config.resizable&&typeof window!=="undefined"){d3.select(window).on("resize."+this.element+this.id,function(){chart.resize()})}else if(typeof window!=="undefined"){d3.select(window).on("resize."+this.element+this.id,null)}this.events.onDraw.call(this);this.resize()}function naturalSorter(a,b){function chunkify(t){var tz=[];var x=0,y=-1,n=0,i,j;while(i=(j=t.charAt(x++)).charCodeAt(0)){var m=i==46||i>=48&&i<=57;if(m!==n){tz[++y]="";n=m}tz[y]+=j}return tz}var aa=chunkify(a.toLowerCase());var bb=chunkify(b.toLowerCase());for(var x=0;aa[x]&&bb[x];x++){if(aa[x]!==bb[x]){var c=Number(aa[x]),d=Number(bb[x]);if(c==aa[x]&&d==bb[x]){return c-d}else{return aa[x]>bb[x]?1:-1}}}return aa.length-bb.length}function setDomain(axis){var _this=this;var otherAxis=axis==="x"?"y":"x";if(this.config[axis].type==="ordinal"){if(this.config[axis].domain){this[axis+"_dom"]=this.config[axis].domain}else if(this.config[axis].order){this[axis+"_dom"]=d3.set(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]}))).values().sort(function(a,b){return d3.ascending(_this.config[axis].order.indexOf(a),_this.config[axis].order.indexOf(b))})}else if(this.config[axis].sort&&this.config[axis].sort==="alphabetical-ascending"){this[axis+"_dom"]=d3.set(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]}))).values().sort(naturalSorter)}else if(["time","linear"].indexOf(this.config[otherAxis].type)>-1&&this.config[axis].sort==="earliest"){this[axis+"_dom"]=d3.nest().key(function(d){return d[_this.config[axis].column]}).rollup(function(d){return d.map(function(m){return m[_this.config[otherAxis].column]}).filter(function(f){return f instanceof Date})}).entries(this.filtered_data).sort(function(a,b){return d3.min(b.values)-d3.min(a.values)}).map(function(m){return m.key})}else if(!this.config[axis].sort||this.config[axis].sort==="alphabetical-descending"){this[axis+"_dom"]=d3.set(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]}))).values().sort(naturalSorter).reverse()}else{this[axis+"_dom"]=d3.set(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]}))).values()}}else if(this.config.marks.map(function(m){return m["summarize"+axis.toUpperCase()]==="percent"}).indexOf(true)>-1){this[axis+"_dom"]=[0,1]}else{this[axis+"_dom"]=d3.extent(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]})))}if(this.config[axis].type==="linear"&&this[axis+"_dom"][0]===this[axis+"_dom"][1])this[axis+"_dom"]=this[axis+"_dom"][0]!==0?[this[axis+"_dom"][0]-this[axis+"_dom"][0]*.01,this[axis+"_dom"][1]+this[axis+"_dom"][1]*.01]:[-1,1];return this[axis+"_dom"]}function consolidateData(raw){var _this=this;this.setDefaults();this.filtered_data=raw;if(this.filters.length){this.filters.forEach(function(filter){_this.filtered_data=_this.filtered_data.filter(function(d){return filter.all===true&&filter.index===0?d:filter.val instanceof Array?filter.val.indexOf(d[filter.col])>-1:d[filter.col]===filter.val})})}this.config.marks.forEach(function(mark,i){if(mark.type!=="bar"){mark.arrange=null;mark.split=null}var mark_info=mark.per?_this.transformData(raw,mark):{data:[],x_dom:[],y_dom:[]};_this.marks[i]=Object.assign({},mark,mark_info)});setDomain.call(this,"x");setDomain.call(this,"y")}function setDefaults(){this.config.x=this.config.x||{};this.config.y=this.config.y||{};this.config.x.label=this.config.x.label!==undefined?this.config.x.label:this.config.x.column;this.config.y.label=this.config.y.label!==undefined?this.config.y.label:this.config.y.column;this.config.x.sort=this.config.x.sort||"alphabetical-ascending";this.config.y.sort=this.config.y.sort||"alphabetical-descending";this.config.x.type=this.config.x.type||"linear";this.config.y.type=this.config.y.type||"linear";this.config.x.range_band=this.config.x.range_band||this.config.range_band;this.config.y.range_band=this.config.y.range_band||this.config.range_band;this.config.margin=this.config.margin||{};this.config.legend=this.config.legend||{};this.config.legend.label=this.config.legend.label!==undefined?this.config.legend.label:this.config.color_by;this.config.legend.location=this.config.legend.location!==undefined?this.config.legend.location:"bottom";this.config.marks=this.config.marks&&this.config.marks.length?this.config.marks:[{}];this.config.marks.forEach(function(m,i){m.id=m.id?m.id:"mark"+(i+1)});this.config.date_format=this.config.date_format||"%x";this.config.padding=this.config.padding!==undefined?this.config.padding:.3;this.config.outer_pad=this.config.outer_pad!==undefined?this.config.outer_pad:.1;this.config.resizable=this.config.resizable!==undefined?this.config.resizable:true;this.config.aspect=this.config.aspect||1.33;this.config.colors=this.config.colors||["rgb(102,194,165)","rgb(252,141,98)","rgb(141,160,203)","rgb(231,138,195)","rgb(166,216,84)","rgb(255,217,47)","rgb(229,196,148)","rgb(179,179,179)"];this.config.scale_text=this.config.scale_text===undefined?true:this.config.scale_text;this.config.transitions=this.config.transitions===undefined?true:this.config.transitions}function cleanData(mark,raw){var _this=this;var dateConvert=d3.time.format(this.config.date_format);var clean=raw;clean=mark.per&&mark.per.length?clean.filter(function(f){return f[mark.per[0]]!==undefined}):clean;if(this.config.x.column){clean=clean.filter(function(f){return[undefined,null].indexOf(f[_this.config.x.column])<0})}if(this.config.y.column){clean=clean.filter(function(f){return[undefined,null].indexOf(f[_this.config.y.column])<0})}if(this.config.x.type==="time"){clean=clean.filter(function(f){return f[_this.config.x.column]instanceof Date?f[_this.config.x.column]:dateConvert.parse(f[_this.config.x.column])});clean.forEach(function(e){return e[_this.config.x.column]=e[_this.config.x.column]instanceof Date?e[_this.config.x.column]:dateConvert.parse(e[_this.config.x.column])})}if(this.config.y.type==="time"){clean=clean.filter(function(f){return f[_this.config.y.column]instanceof Date?f[_this.config.y.column]:dateConvert.parse(f[_this.config.y.column])});clean.forEach(function(e){return e[_this.config.y.column]=e[_this.config.y.column]instanceof Date?e[_this.config.y.column]:dateConvert.parse(e[_this.config.y.column])})}if((this.config.x.type==="linear"||this.config.x.type==="log")&&this.config.x.column){clean=clean.filter(function(f){return mark.summarizeX!=="count"&&mark.summarizeX!=="percent"?!(isNaN(f[_this.config.x.column])||/^\s*$/.test(f[_this.config.x.column])):f})}if((this.config.y.type==="linear"||this.config.y.type==="log")&&this.config.y.column){clean=clean.filter(function(f){return mark.summarizeY!=="count"&&mark.summarizeY!=="percent"?!(isNaN(f[_this.config.y.column])||/^\s*$/.test(f[_this.config.y.column])):f})}return clean}var stats={mean:d3.mean,min:d3.min,max:d3.max,median:d3.median,sum:d3.sum};function summarize(vals){var operation=arguments.length>1&&arguments[1]!==undefined?arguments[1]:"mean";var nvals=vals.filter(function(f){return+f||+f===0}).map(function(m){return+m});if(operation==="cumulative"){return null}var mathed=operation==="count"?vals.length:operation==="percent"?vals.length:stats[operation](nvals);return mathed}function makeNest(mark,entries,sublevel){var _this=this;var dom_xs=[];var dom_ys=[];var this_nest=d3.nest();var totalOrder;if(this.config.x.type==="linear"&&this.config.x.bin||this.config.y.type==="linear"&&this.config.y.bin){var xy=this.config.x.type==="linear"&&this.config.x.bin?"x":"y";mark.quant=d3.scale.quantile().domain(this.config[xy].domain?this.config[xy].domain:d3.extent(entries.map(function(m){return+m[_this.config[xy].column]}))).range(d3.range(+this.config[xy].bin));entries.forEach(function(e){return e.wc_bin=mark.quant(e[_this.config[xy].column])});this_nest.key(function(d){return mark.quant.invertExtent(d.wc_bin)})}else{this_nest.key(function(d){return mark.per.map(function(m){return d[m]}).join(" ")})}if(sublevel){this_nest.key(function(d){return d[sublevel]});this_nest.sortKeys(function(a,b){return _this.config.x.type==="time"?d3.ascending(new Date(a),new Date(b)):_this.config.x.order?d3.ascending(_this.config.x.order.indexOf(a),_this.config.x.order.indexOf(b)):sublevel===_this.config.color_by&&_this.config.legend.order?d3.ascending(_this.config.legend.order.indexOf(a),_this.config.legend.order.indexOf(b)):_this.config.x.type==="ordinal"||_this.config.y.type==="ordinal"?naturalSorter(a,b):d3.ascending(+a,+b)})}this_nest.rollup(function(r){var obj={raw:r};var y_vals=r.map(function(m){return m[_this.config.y.column]}).sort(d3.ascending);var x_vals=r.map(function(m){return m[_this.config.x.column]}).sort(d3.ascending);obj.x=_this.config.x.type==="ordinal"?r[0][_this.config.x.column]:summarize(x_vals,mark.summarizeX);obj.y=_this.config.y.type==="ordinal"?r[0][_this.config.y.column]:summarize(y_vals,mark.summarizeY);obj.x_q25=_this.config.error_bars&&_this.config.y.type==="ordinal"?d3.quantile(x_vals,.25):obj.x;obj.x_q75=_this.config.error_bars&&_this.config.y.type==="ordinal"?d3.quantile(x_vals,.75):obj.x;obj.y_q25=_this.config.error_bars?d3.quantile(y_vals,.25):obj.y;obj.y_q75=_this.config.error_bars?d3.quantile(y_vals,.75):obj.y;dom_xs.push([obj.x_q25,obj.x_q75,obj.x]);dom_ys.push([obj.y_q25,obj.y_q75,obj.y]);if(mark.summarizeY==="cumulative"){var interm=entries.filter(function(f){return _this.config.x.type==="time"?new Date(f[_this.config.x.column])<=new Date(r[0][_this.config.x.column]):+f[_this.config.x.column]<=+r[0][_this.config.x.column]});if(mark.per.length){interm=interm.filter(function(f){return f[mark.per[0]]===r[0][mark.per[0]]})}var cumul=_this.config.x.type==="time"?interm.length:d3.sum(interm.map(function(m){return+m[_this.config.y.column]||+m[_this.config.y.column]===0?+m[_this.config.y.column]:1}));dom_ys.push([cumul]);obj.y=cumul}if(mark.summarizeX==="cumulative"){var _interm=entries.filter(function(f){return _this.config.y.type==="time"?new Date(f[_this.config.y.column])<=new Date(r[0][_this.config.y.column]):+f[_this.config.y.column]<=+r[0][_this.config.y.column]});if(mark.per.length){_interm=_interm.filter(function(f){return f[mark.per[0]]===r[0][mark.per[0]]})}dom_xs.push([_interm.length]);obj.x=_interm.length}return obj});var test=this_nest.entries(entries);var dom_x=d3.extent(d3.merge(dom_xs));var dom_y=d3.extent(d3.merge(dom_ys));if(sublevel&&mark.type==="bar"&&mark.split){test.forEach(function(e){var axis=_this.config.x.type==="ordinal"||_this.config.x.type==="linear"&&_this.config.x.bin?"y":"x";e.total=d3.sum(e.values.map(function(m){return+m.values[axis]}));var counter=0;e.values.forEach(function(v,i){if(_this.config.x.type==="ordinal"||_this.config.x.type==="linear"&&_this.config.x.bin){v.values.y=mark.summarizeY==="percent"?v.values.y/e.total:v.values.y||0;counter+=+v.values.y;v.values.start=e.values[i-1]?counter:v.values.y}else{v.values.x=mark.summarizeX==="percent"?v.values.x/e.total:v.values.x||0;v.values.start=counter;counter+=+v.values.x}})});if(mark.arrange==="stacked"){if(this.config.x.type==="ordinal"||this.config.x.type==="linear"&&this.config.x.bin){dom_y=d3.extent(test.map(function(m){return m.total}))}if(this.config.y.type==="ordinal"||this.config.y.type==="linear"&&this.config.y.bin){dom_x=d3.extent(test.map(function(m){return m.total}))}}}else{var axis=this.config.x.type==="ordinal"||this.config.x.type==="linear"&&this.config.x.bin?"y":"x";test.forEach(function(e){return e.total=e.values[axis]})}if(this.config.x.sort==="total-ascending"&&this.config.x.type=="ordinal"||this.config.y.sort==="total-descending"&&this.config.y.type=="ordinal"){totalOrder=test.sort(function(a,b){return d3.ascending(a.total,b.total)}).map(function(m){return m.key})}else if(this.config.x.sort==="total-descending"&&this.config.x.type=="ordinal"||this.config.y.sort==="total-ascending"&&this.config.y.type=="ordinal"){totalOrder=test.sort(function(a,b){return d3.descending(+a.total,+b.total)}).map(function(m){return m.key})}return{nested:test,dom_x:dom_x,dom_y:dom_y,totalOrder:totalOrder}}function transformData(raw,mark){var _this=this;var config=this.config;var x_behavior=config.x.behavior||"raw";var y_behavior=config.y.behavior||"raw";var sublevel=mark.type==="line"?config.x.column:mark.type==="bar"&&mark.split?mark.split:null;var cleaned=cleanData.call(this,mark,raw);var raw_nest;if(mark.type==="bar"){raw_nest=mark.arrange!=="stacked"?makeNest.call(this,mark,cleaned,sublevel):makeNest.call(this,mark,cleaned)}else if(mark.summarizeX==="count"||mark.summarizeY==="count"){raw_nest=makeNest.call(this,mark,cleaned)}var raw_dom_x=mark.summarizeX==="cumulative"?[0,cleaned.length]:config.x.type==="ordinal"?d3.set(cleaned.map(function(m){return m[config.x.column]})).values().filter(function(f){return f}):mark.split&&mark.arrange!=="stacked"?d3.extent(d3.merge(raw_nest.nested.map(function(m){return m.values.map(function(p){return p.values.raw.length})}))):mark.summarizeX==="count"?d3.extent(raw_nest.nested.map(function(m){return m.values.raw.length})):d3.extent(cleaned.map(function(m){return+m[config.x.column]}).filter(function(f){return+f||+f===0}));var raw_dom_y=mark.summarizeY==="cumulative"?[0,cleaned.length]:config.y.type==="ordinal"?d3.set(cleaned.map(function(m){return m[config.y.column]})).values().filter(function(f){return f}):mark.split&&mark.arrange!=="stacked"?d3.extent(d3.merge(raw_nest.nested.map(function(m){return m.values.map(function(p){return p.values.raw.length})}))):mark.summarizeY==="count"?d3.extent(raw_nest.nested.map(function(m){return m.values.raw.length})):d3.extent(cleaned.map(function(m){return+m[config.y.column]}).filter(function(f){return+f||+f===0}));var filtered=cleaned;var filt1_xs=[];var filt1_ys=[];if(this.filters.length){this.filters.forEach(function(e){filtered=filtered.filter(function(d){return e.all===true&&e.index===0?d:e.val instanceof Array?e.val.indexOf(d[e.col])>-1:d[e.col]===e.val})});if(config.x.behavior==="firstfilter"||config.y.behavior==="firstfilter"){this.filters[0].choices.filter(function(f){return f!=="All"}).forEach(function(e){var perfilter=cleaned.filter(function(f){return f[_this.filters[0].col]===e});var filt_nested=makeNest.call(_this,mark,perfilter,sublevel);filt1_xs.push(filt_nested.dom_x);filt1_ys.push(filt_nested.dom_y)})}}if(mark.values){var _loop=function _loop(a){filtered=filtered.filter(function(f){return mark.values[a].indexOf(f[a])>-1})};for(var a in mark.values){_loop(a)}}var filt1_dom_x=d3.extent(d3.merge(filt1_xs));var filt1_dom_y=d3.extent(d3.merge(filt1_ys));var current_nested=makeNest.call(this,mark,filtered,sublevel);var flex_dom_x=current_nested.dom_x;var flex_dom_y=current_nested.dom_y;if(mark.type==="bar"){if(config.y.type==="ordinal"&&mark.summarizeX==="count"){config.x.domain=config.x.domain?[0,config.x.domain[1]]:[0,null]}else if(config.x.type==="ordinal"&&mark.summarizeY==="count"){config.y.domain=config.y.domain?[0,config.y.domain[1]]:[0,null]}}var nonall=Boolean(this.filters.length&&this.filters[0].val!=="All"&&this.filters.slice(1).filter(function(f){return f.val==="All"}).length===this.filters.length-1);var pre_x_dom=!this.filters.length?flex_dom_x:x_behavior==="raw"?raw_dom_x:nonall&&x_behavior==="firstfilter"?filt1_dom_x:flex_dom_x;var pre_y_dom=!this.filters.length?flex_dom_y:y_behavior==="raw"?raw_dom_y:nonall&&y_behavior==="firstfilter"?filt1_dom_y:flex_dom_y;var x_dom=config.x_dom?config.x_dom:config.x.type==="ordinal"&&config.x.behavior==="flex"?d3.set(filtered.map(function(m){return m[config.x.column]})).values():config.x.type==="ordinal"?d3.set(cleaned.map(function(m){return m[config.x.column]})).values():pre_x_dom;var y_dom=config.y_dom?config.y_dom:config.y.type==="ordinal"&&config.y.behavior==="flex"?d3.set(filtered.map(function(m){return m[config.y.column]})).values():config.y.type==="ordinal"?d3.set(cleaned.map(function(m){return m[config.y.column]})).values():pre_y_dom;if(mark.type==="bar"){if(config.x.behavior!=="flex"&&config.x.type==="linear"&&config.y.type==="ordinal"&&raw_dom_x[0]>=0)x_dom[0]=0;if(config.y.behavior!=="flex"&&config.x.type==="ordinal"&&config.y.type==="linear"&&raw_dom_y[0]>=0)y_dom[0]=0}if(config.x.domain&&(config.x.domain[0]||config.x.domain[0]===0)&&!isNaN(+config.x.domain[0])){x_dom[0]=config.x.domain[0]}if(config.x.domain&&(config.x.domain[1]||config.x.domain[1]===0)&&!isNaN(+config.x.domain[1])){x_dom[1]=config.x.domain[1]}if(config.y.domain&&(config.y.domain[0]||config.y.domain[0]===0)&&!isNaN(+config.y.domain[0])){y_dom[0]=config.y.domain[0]}if(config.y.domain&&(config.y.domain[1]||config.y.domain[1]===0)&&!isNaN(+config.y.domain[1])){y_dom[1]=config.y.domain[1]}if(config.x.type==="ordinal"&&!config.x.order){config.x.order=current_nested.totalOrder}if(config.y.type==="ordinal"&&!config.y.order){config.y.order=current_nested.totalOrder}this.current_data=current_nested.nested;this.events.onDatatransform.call(this);return{config:mark,data:current_nested.nested,x_dom:x_dom,y_dom:y_dom}}function setColorScale(){var config=this.config;var data=config.legend.behavior==="flex"?this.filtered_data:this.raw_data;var colordom=Array.isArray(config.color_dom)&&config.color_dom.length?config.color_dom.slice():d3.set(data.map(function(m){return m[config.color_by]})).values().filter(function(f){return f&&f!=="undefined"});if(config.legend.order)colordom.sort(function(a,b){return d3.ascending(config.legend.order.indexOf(a),config.legend.order.indexOf(b))});else colordom.sort(naturalSorter);this.colorScale=d3.scale.ordinal().domain(colordom).range(config.colors)}function xScaleAxis(max_range,domain,type){if(max_range===undefined){max_range=this.plot_width}if(domain===undefined){domain=this.x_dom}if(type===undefined){type=this.config.x.type}var config=this.config;var x;if(type==="log"){x=d3.scale.log()}else if(type==="ordinal"){x=d3.scale.ordinal()}else if(type==="time"){x=d3.time.scale()}else{x=d3.scale.linear()}x.domain(domain);if(type==="ordinal"){x.rangeBands([0,+max_range],config.padding,config.outer_pad)}else{x.range([0,+max_range]).clamp(Boolean(config.x.clamp))}var xFormat=config.x.format?config.x.format:config.marks.map(function(m){return m.summarizeX==="percent"}).indexOf(true)>-1?"0%":type==="time"?"%x":".0f";var tick_count=Math.max(2,Math.min(max_range/80,8));var xAxis=d3.svg.axis().scale(x).orient(config.x.location).ticks(tick_count).tickFormat(type==="ordinal"?null:type==="time"?d3.time.format(xFormat):d3.format(xFormat)).tickValues(config.x.ticks?config.x.ticks:null).innerTickSize(6).outerTickSize(3);this.svg.select("g.x.axis").attr("class","x axis "+type);this.x=x;this.xAxis=xAxis}function yScaleAxis(max_range,domain,type){if(max_range===undefined){max_range=this.plot_height}if(domain===undefined){domain=this.y_dom}if(type===undefined){type=this.config.y.type}var config=this.config;var y;if(type==="log"){y=d3.scale.log()}else if(type==="ordinal"){y=d3.scale.ordinal()}else if(type==="time"){y=d3.time.scale()}else{y=d3.scale.linear()}y.domain(domain);if(type==="ordinal"){y.rangeBands([+max_range,0],config.padding,config.outer_pad)}else{y.range([+max_range,0]).clamp(Boolean(config.y_clamp))}var yFormat=config.y.format?config.y.format:config.marks.map(function(m){return m.summarizeY==="percent"}).indexOf(true)>-1?"0%":".0f";var tick_count=Math.max(2,Math.min(max_range/80,8));var yAxis=d3.svg.axis().scale(y).orient("left").ticks(tick_count).tickFormat(type==="ordinal"?null:type==="time"?d3.time.format(yFormat):d3.format(yFormat)).tickValues(config.y.ticks?config.y.ticks:null).innerTickSize(6).outerTickSize(3);this.svg.select("g.y.axis").attr("class","y axis "+type);this.y=y;this.yAxis=yAxis}function resize(){var config=this.config;var aspect2=1/config.aspect;var div_width=parseInt(this.wrap.style("width"));var max_width=config.max_width?config.max_width:div_width;var preWidth=!config.resizable?config.width:!max_width||div_width=600){font_size="14px";point_size=4;stroke_width=2}else if(width>450&&width<600){font_size="12px";point_size=3;stroke_width=2}else if(width>300&&width<450){font_size="10px";point_size=2;stroke_width=2}else if(width<=300){font_size="10px";point_size=2;stroke_width=1}this.wrap.style("font-size",font_size);this.config.flex_point_size=point_size;this.config.flex_stroke_width=stroke_width}function setMargins(){var _this=this;var y_ticks=this.yAxis.tickFormat()?this.y.domain().map(function(m){return _this.yAxis.tickFormat()(m)}):this.y.domain();var max_y_text_length=d3.max(y_ticks.map(function(m){return String(m).length}));if(this.config.y_format&&this.config.y_format.indexOf("%")>-1){max_y_text_length+=1}max_y_text_length=Math.max(2,max_y_text_length);var x_label_on=this.config.x.label?1.5:0;var y_label_on=this.config.y.label?1.5:.25;var font_size=parseInt(this.wrap.style("font-size"));var x_second=this.config.x2_interval?1:0;var y_margin=max_y_text_length*font_size*.5+font_size*y_label_on*1.5||8;var x_margin=font_size+font_size/1.5+font_size*x_label_on+font_size*x_second||8;y_margin+=6;x_margin+=3;return{top:this.config.margin&&this.config.margin.top?this.config.margin.top:8,right:this.config.margin&&this.config.margin.right?this.config.margin.right:16,bottom:this.config.margin&&this.config.margin.bottom?this.config.margin.bottom:x_margin,left:this.config.margin&&this.config.margin.left?this.config.margin.left:y_margin}}function drawGridLines(){this.wrap.classed("gridlines",this.config.gridlines);if(this.config.gridlines){this.svg.select(".y.axis").selectAll(".tick line").attr("x1",0);this.svg.select(".x.axis").selectAll(".tick line").attr("y1",0);if(this.config.gridlines==="y"||this.config.gridlines==="xy")this.svg.select(".y.axis").selectAll(".tick line").attr("x1",this.plot_width);if(this.config.gridlines==="x"||this.config.gridlines==="xy")this.svg.select(".x.axis").selectAll(".tick line").attr("y1",-this.plot_height)}else{this.svg.select(".y.axis").selectAll(".tick line").attr("x1",0);this.svg.select(".x.axis").selectAll(".tick line").attr("y1",0)}}function makeLegend(){var scale=arguments.length>0&&arguments[0]!==undefined?arguments[0]:this.colorScale;var label=arguments.length>1&&arguments[1]!==undefined?arguments[1]:"";var custom_data=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;var config=this.config;config.legend.mark=config.legend.mark?config.legend.mark:config.marks.length&&config.marks[0].type==="bar"?"square":config.marks.length?config.marks[0].type:"square";var legend_label=label?label:typeof config.legend.label==="string"?config.legend.label:"";var legendOriginal=this.legend||this.wrap.select(".legend");var legend=legendOriginal;if(!this.parent){if(this.config.legend.location==="top"||this.config.legend.location==="left"){this.wrap.node().insertBefore(legendOriginal.node(),this.svg.node().parentNode)}else{this.wrap.node().appendChild(legendOriginal.node())}}else{if(this.config.legend.location==="top"||this.config.legend.location==="left"){this.parent.wrap.node().insertBefore(legendOriginal.node(),this.parent.wrap.select(".wc-chart").node())}else{this.parent.wrap.node().appendChild(legendOriginal.node())}}legend.style("padding",0);var legend_data=custom_data||scale.domain().slice(0).filter(function(f){return f!==undefined&&f!==null}).map(function(m){return{label:m,mark:config.legend.mark}});legend.select(".legend-title").text(legend_label).style("display",legend_label?"inline":"none").style("margin-right","1em");var leg_parts=legend.selectAll(".legend-item").data(legend_data,function(d){return d.label+d.mark});leg_parts.exit().remove();var legendPartDisplay=this.config.legend.location==="bottom"||this.config.legend.location==="top"?"inline-block":"block";var new_parts=leg_parts.enter().append("li").attr("class","legend-item").style({
-"list-style-type":"none","margin-right":"1em"});new_parts.append("span").attr("class","legend-mark-text").style("color",function(d){return scale(d.label)});new_parts.append("svg").attr("class","legend-color-block").attr("width","1.1em").attr("height","1.1em").style({position:"relative",top:"0.2em"});leg_parts.style("display",legendPartDisplay);if(config.legend.order){leg_parts.sort(function(a,b){return d3.ascending(config.legend.order.indexOf(a.label),config.legend.order.indexOf(b.label))})}leg_parts.selectAll(".legend-color-block").select(".legend-mark").remove();leg_parts.selectAll(".legend-color-block").each(function(e){var svg=d3.select(this);if(e.mark==="circle"){svg.append("circle").attr({cx:".5em",cy:".5em",r:".45em",class:"legend-mark"})}else if(e.mark==="line"){svg.append("line").attr({x1:0,y1:".5em",x2:"1em",y2:".5em","stroke-width":2,"shape-rendering":"crispEdges",class:"legend-mark"})}else if(e.mark==="square"){svg.append("rect").attr({height:"1em",width:"1em",class:"legend-mark","shape-rendering":"crispEdges"})}});leg_parts.selectAll(".legend-color-block").select(".legend-mark").attr("fill",function(d){return d.color||scale(d.label)}).attr("stroke",function(d){return d.color||scale(d.label)}).each(function(e){d3.select(this).attr(e.attributes)});new_parts.append("span").attr("class","legend-label").style("margin-left","0.25em").text(function(d){return d.label});if(scale.domain().length>0){var legendDisplay=(this.config.legend.location==="bottom"||this.config.legend.location==="top")&&!this.parent?"block":"inline-block";legend.style("display",legendDisplay)}else{legend.style("display","none")}this.legend=legend}function updateDataMarks(){this.drawBars(this.marks.filter(function(f){return f.type==="bar"}));this.drawLines(this.marks.filter(function(f){return f.type==="line"}));this.drawPoints(this.marks.filter(function(f){return f.type==="circle"}));this.drawText(this.marks.filter(function(f){return f.type==="text"}));this.marks.supergroups=this.svg.selectAll("g.supergroup")}function drawArea(area_drawer,area_data,datum_accessor){var _this=this;var class_match=arguments.length>3&&arguments[3]!==undefined?arguments[3]:"chart-area";var bind_accessor=arguments.length>4?arguments[4]:undefined;var attr_accessor=arguments.length>5&&arguments[5]!==undefined?arguments[5]:function(d){return d};var area_grps=this.svg.selectAll("."+class_match).data(area_data,bind_accessor);area_grps.exit().remove();area_grps.enter().append("g").attr("class",function(d){return class_match+" "+d.key}).append("path");var areaPaths=area_grps.select("path").datum(datum_accessor).attr("fill",function(d){var d_attr=attr_accessor(d);return d_attr?_this.colorScale(d_attr[_this.config.color_by]):null}).attr("fill-opacity",this.config.fill_opacity||this.config.fill_opacity===0?this.config.fill_opacity:.3);var areaPathTransitions=this.config.transitions?areaPaths.transition():areaPaths;areaPathTransitions.attr("d",area_drawer);return area_grps}function drawBars(marks){var _this=this;var chart=this;var rawData=this.raw_data;var config=this.config;var bar_supergroups=this.svg.selectAll(".bar-supergroup").data(marks,function(d,i){return i+"-"+d.per.join("-")});bar_supergroups.enter().append("g").attr("class",function(d){return"supergroup bar-supergroup "+d.id});bar_supergroups.exit().remove();var bar_groups=bar_supergroups.selectAll(".bar-group").data(function(d){return d.data},function(d){return d.key});var old_bar_groups=bar_groups.exit();var nu_bar_groups;var bars;var oldBarsTrans=config.transitions?old_bar_groups.selectAll(".bar").transition():old_bar_groups.selectAll(".bar");var oldBarGroupsTrans=config.transitions?old_bar_groups.transition():old_bar_groups;if(config.x.type==="ordinal"){oldBarsTrans.attr("y",this.y(0)).attr("height",0);oldBarGroupsTrans.remove();nu_bar_groups=bar_groups.enter().append("g").attr("class",function(d){return"bar-group "+d.key});nu_bar_groups.append("title");bars=bar_groups.selectAll("rect").data(function(d){return d.values instanceof Array?d.values.sort(function(a,b){return _this.colorScale.domain().indexOf(b.key)-_this.colorScale.domain().indexOf(a.key)}):[d]},function(d){return d.key});var exitBars=config.transitions?bars.exit().transition():bars.exit();exitBars.attr("y",this.y(0)).attr("height",0).remove();bars.enter().append("rect").attr("class",function(d){return"wc-data-mark bar "+d.key}).style("clip-path","url(#".concat(chart.id,")")).attr("y",this.y(0)).attr("height",0).append("title");bars.attr("shape-rendering","crispEdges").attr("stroke",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])});bars.each(function(d){var mark=d3.select(this.parentNode.parentNode).datum();d.tooltip=mark.tooltip;d.arrange=mark.split&&mark.arrange?mark.arrange:mark.split?"grouped":null;d.subcats=config.legend.order?config.legend.order.slice().reverse():mark.values&&mark.values[mark.split]?mark.values[mark.split]:d3.set(rawData.map(function(m){return m[mark.split]})).values();d3.select(this).attr(mark.attributes)});var xformat=config.marks.map(function(m){return m.summarizeX==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.x.format);var yformat=config.marks.map(function(m){return m.summarizeY==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.y.format);bars.select("title").text(function(d){var tt=d.tooltip||"";return tt.replace(/\$x/g,xformat(d.values.x)).replace(/\$y/g,yformat(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});var barsTrans=config.transitions?bars.transition():bars;barsTrans.attr("x",function(d){var position;if(!d.arrange||d.arrange==="stacked"){return _this.x(d.values.x)}else if(d.arrange==="nested"){var _position=d.subcats.indexOf(d.key);var offset=_position?_this.x.rangeBand()/(d.subcats.length*.75)/_position:_this.x.rangeBand();return _this.x(d.values.x)+(_this.x.rangeBand()-offset)/2}else{position=d.subcats.indexOf(d.key);return _this.x(d.values.x)+_this.x.rangeBand()/d.subcats.length*position}}).attr("y",function(d){if(d.arrange!=="stacked"){return _this.y(d.values.y)}else{return _this.y(d.values.start)}}).attr("width",function(d){if(!d.arrange||d.arrange==="stacked"){return _this.x.rangeBand()}else if(d.arrange==="nested"){var position=d.subcats.indexOf(d.key);return position?_this.x.rangeBand()/(d.subcats.length*.75)/position:_this.x.rangeBand()}else{return _this.x.rangeBand()/d.subcats.length}}).attr("height",function(d){return _this.y(0)-_this.y(d.values.y)})}else if(config.y.type==="ordinal"){oldBarsTrans.attr("x",this.x(0)).attr("width",0);oldBarGroupsTrans.remove();nu_bar_groups=bar_groups.enter().append("g").attr("class",function(d){return"bar-group "+d.key});nu_bar_groups.append("title");bars=bar_groups.selectAll("rect").data(function(d){return d.values instanceof Array?d.values.sort(function(a,b){return _this.colorScale.domain().indexOf(b.key)-_this.colorScale.domain().indexOf(a.key)}):[d]},function(d){return d.key});var _exitBars=config.transitions?bars.exit().transition():bars.exit();_exitBars.attr("x",this.x(0)).attr("width",0).remove();bars.enter().append("rect").attr("class",function(d){return"wc-data-mark bar "+d.key}).style("clip-path","url(#".concat(chart.id,")")).attr("x",this.x(0)).attr("width",0).append("title");bars.attr("shape-rendering","crispEdges").attr("stroke",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])});bars.each(function(d){var mark=d3.select(this.parentNode.parentNode).datum();d.arrange=mark.split&&mark.arrange?mark.arrange:mark.split?"grouped":null;d.subcats=config.legend.order?config.legend.order.slice().reverse():mark.values&&mark.values[mark.split]?mark.values[mark.split]:d3.set(rawData.map(function(m){return m[mark.split]})).values();d.tooltip=mark.tooltip;d3.select(this).attr(mark.attributes)});var _xformat=config.marks.map(function(m){return m.summarizeX==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.x.format);var _yformat=config.marks.map(function(m){return m.summarizeY==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.y.format);bars.select("title").text(function(d){var tt=d.tooltip||"";return tt.replace(/\$x/g,_xformat(d.values.x)).replace(/\$y/g,_yformat(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});var _barsTrans=config.transitions?bars.transition():bars;_barsTrans.attr("x",function(d){if(d.arrange==="stacked"||!d.arrange){return d.values.start!==undefined?_this.x(d.values.start):_this.x(0)}else{return _this.x(0)}}).attr("y",function(d){if(d.arrange==="nested"){var position=d.subcats.indexOf(d.key);var offset=position?_this.y.rangeBand()/(d.subcats.length*.75)/position:_this.y.rangeBand();return _this.y(d.values.y)+(_this.y.rangeBand()-offset)/2}else if(d.arrange==="grouped"){var _position2=d.subcats.indexOf(d.key);return _this.y(d.values.y)+_this.y.rangeBand()/d.subcats.length*_position2}else{return _this.y(d.values.y)}}).attr("width",function(d){return _this.x(d.values.x)-_this.x(0)}).attr("height",function(d){if(config.y.type==="quantile"){return 20}else if(d.arrange==="nested"){var position=d.subcats.indexOf(d.key);return position?_this.y.rangeBand()/(d.subcats.length*.75)/position:_this.y.rangeBand()}else if(d.arrange==="grouped"){return _this.y.rangeBand()/d.subcats.length}else{return _this.y.rangeBand()}})}else if(["linear","log"].indexOf(config.x.type)>-1&&config.x.bin){oldBarsTrans.attr("y",this.y(0)).attr("height",0);oldBarGroupsTrans.remove();nu_bar_groups=bar_groups.enter().append("g").attr("class",function(d){return"bar-group "+d.key});nu_bar_groups.append("title");bars=bar_groups.selectAll("rect").data(function(d){return d.values instanceof Array?d.values:[d]},function(d){return d.key});var _exitBars2=config.transitions?bars.exit().transition():bars.exit();_exitBars2.attr("y",this.y(0)).attr("height",0).remove();bars.enter().append("rect").attr("class",function(d){return"wc-data-mark bar "+d.key}).style("clip-path","url(#".concat(chart.id,")")).attr("y",this.y(0)).attr("height",0).append("title");bars.attr("shape-rendering","crispEdges").attr("stroke",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])});bars.each(function(d){var mark=d3.select(this.parentNode.parentNode).datum();d.arrange=mark.split?mark.arrange:null;d.subcats=config.legend.order?config.legend.order.slice().reverse():mark.values&&mark.values[mark.split]?mark.values[mark.split]:d3.set(rawData.map(function(m){return m[mark.split]})).values();d3.select(this).attr(mark.attributes);var parent=d3.select(this.parentNode).datum();var rangeSet=parent.key.split(",").map(function(m){return+m});d.rangeLow=d3.min(rangeSet);d.rangeHigh=d3.max(rangeSet);d.tooltip=mark.tooltip});var _xformat2=config.marks.map(function(m){return m.summarizeX==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.x.format);var _yformat2=config.marks.map(function(m){return m.summarizeY==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.y.format);bars.select("title").text(function(d){var tt=d.tooltip||"";return tt.replace(/\$x/g,_xformat2(d.values.x)).replace(/\$y/g,_yformat2(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});var _barsTrans2=config.transitions?bars.transition():bars;_barsTrans2.attr("x",function(d){return _this.x(d.rangeLow)}).attr("y",function(d){if(d.arrange!=="stacked"){return _this.y(d.values.y)}else{return _this.y(d.values.start)}}).attr("width",function(d){return _this.x(d.rangeHigh)-_this.x(d.rangeLow)}).attr("height",function(d){return _this.y(0)-_this.y(d.values.y)})}else if(["linear","log"].indexOf(config.y.type)>-1&&config.y.type==="linear"&&config.y.bin){oldBarsTrans.attr("x",this.x(0)).attr("width",0);oldBarGroupsTrans.remove();nu_bar_groups=bar_groups.enter().append("g").attr("class",function(d){return"bar-group "+d.key});nu_bar_groups.append("title");bars=bar_groups.selectAll("rect").data(function(d){return d.values instanceof Array?d.values:[d]},function(d){return d.key});var _exitBars3=config.transitions?bars.exit().transition():bars.exit();_exitBars3.attr("x",this.x(0)).attr("width",0).remove();bars.enter().append("rect").attr("class",function(d){return"wc-data-mark bar "+d.key}).style("clip-path","url(#".concat(chart.id,")")).attr("x",this.x(0)).attr("width",0).append("title");bars.attr("shape-rendering","crispEdges").attr("stroke",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])});bars.each(function(d){var mark=d3.select(this.parentNode.parentNode).datum();d.arrange=mark.split?mark.arrange:null;d.subcats=config.legend.order?config.legend.order.slice().reverse():mark.values&&mark.values[mark.split]?mark.values[mark.split]:d3.set(rawData.map(function(m){return m[mark.split]})).values();var parent=d3.select(this.parentNode).datum();var rangeSet=parent.key.split(",").map(function(m){return+m});d.rangeLow=d3.min(rangeSet);d.rangeHigh=d3.max(rangeSet);d.tooltip=mark.tooltip});var _xformat3=config.marks.map(function(m){return m.summarizeX==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.x.format);var _yformat3=config.marks.map(function(m){return m.summarizeY==="percent"}).indexOf(true)>-1?d3.format("0%"):d3.format(config.y.format);bars.select("title").text(function(d){var tt=d.tooltip||"";return tt.replace(/\$x/g,_xformat3(d.values.x)).replace(/\$y/g,_yformat3(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});var _barsTrans3=config.transitions?bars.transition():bars;_barsTrans3.attr("x",function(d){if(d.arrange==="stacked"){return _this.x(d.values.start)}else{return _this.x(0)}}).attr("y",function(d){return _this.y(d.rangeHigh)}).attr("width",function(d){return _this.x(d.values.x)}).attr("height",function(d){return _this.y(d.rangeLow)-_this.y(d.rangeHigh)})}else{oldBarsTrans.attr("y",this.y(0)).attr("height",0);oldBarGroupsTrans.remove();bar_supergroups.remove()}bar_supergroups.each(function(d){d.supergroup=d3.select(this);d.groups=d.supergroup.selectAll(".bar-group")})}function drawLines(marks){var _this=this;var chart=this;var config=this.config;var line=d3.svg.line().interpolate(config.interpolate).x(function(d){return config.x.type==="linear"||config.x.type=="log"?_this.x(+d.values.x):config.x.type==="time"?_this.x(new Date(d.values.x)):_this.x(d.values.x)+_this.x.rangeBand()/2}).y(function(d){return config.y.type==="linear"||config.y.type=="log"?_this.y(+d.values.y):config.y.type==="time"?_this.y(new Date(d.values.y)):_this.y(d.values.y)+_this.y.rangeBand()/2});var line_supergroups=this.svg.selectAll(".line-supergroup").data(marks,function(d,i){return i+"-"+d.per.join("-")});line_supergroups.enter().append("g").attr("class",function(d){return"supergroup line-supergroup "+d.id});line_supergroups.exit().remove();var line_grps=line_supergroups.selectAll(".line").data(function(d){return d.data},function(d){return d.key});line_grps.exit().remove();var nu_line_grps=line_grps.enter().append("g").attr("class",function(d){return d.key+" line"});nu_line_grps.append("path");nu_line_grps.append("title");var linePaths=line_grps.select("path").attr("class","wc-data-mark").style("clip-path","url(#".concat(chart.id,")")).datum(function(d){return d.values}).attr("stroke",function(d){return _this.colorScale(d[0].values.raw[0][config.color_by])}).attr("stroke-width",config.stroke_width?config.stroke_width:config.flex_stroke_width).attr("stroke-linecap","round").attr("fill","none");var linePathsTrans=config.transitions?linePaths.transition():linePaths;linePathsTrans.attr("d",line);line_grps.each(function(d){var mark=d3.select(this.parentNode).datum();d.tooltip=mark.tooltip;d3.select(this).select("path").attr(mark.attributes)});line_grps.select("title").text(function(d){var tt=d.tooltip||"";var xformat=config.x.summary==="percent"?d3.format("0%"):d3.format(config.x.format);var yformat=config.y.summary==="percent"?d3.format("0%"):d3.format(config.y.format);return tt.replace(/\$x/g,xformat(d.values.x)).replace(/\$y/g,yformat(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values[0].values.raw[0][orig]})});line_supergroups.each(function(d){d.supergroup=d3.select(this);d.groups=d.supergroup.selectAll("g.line");d.paths=d.groups.select("path")});return line_grps}function drawPoints(marks){var _this=this;var chart=this;var config=this.config;var point_supergroups=this.svg.selectAll(".point-supergroup").data(marks,function(d,i){return i+"-"+d.per.join("-")});point_supergroups.enter().append("g").attr("class",function(d){return"supergroup point-supergroup "+d.id});point_supergroups.exit().remove();var points=point_supergroups.selectAll(".point").data(function(d){return d.data},function(d){return d.key});var oldPoints=points.exit();var oldPointsTrans=config.transitions?oldPoints.selectAll("circle").transition():oldPoints.selectAll("circle");oldPointsTrans.attr("r",0);var oldPointGroupTrans=config.transitions?oldPoints.transition():oldPoints;oldPointGroupTrans.remove();var nupoints=points.enter().append("g").attr("class",function(d){return d.key+" point"});nupoints.append("circle").attr("class","wc-data-mark").attr("r",0);nupoints.append("title");points.select("circle").style("clip-path","url(#".concat(chart.id,")")).attr("fill-opacity",config.fill_opacity||config.fill_opacity===0?config.fill_opacity:.6).attr("fill",function(d){return _this.colorScale(d.values.raw[0][config.color_by])}).attr("stroke",function(d){return _this.colorScale(d.values.raw[0][config.color_by])});points.each(function(d){var mark=d3.select(this.parentNode).datum();d.mark=mark;d3.select(this).select("circle").attr(mark.attributes)});var pointsTrans=config.transitions?points.select("circle").transition():points.select("circle");pointsTrans.attr("r",function(d){return d.mark.radius||config.flex_point_size}).attr("cx",function(d){var x_pos=_this.x(d.values.x)||0;return config.x.type==="ordinal"?x_pos+_this.x.rangeBand()/2:x_pos}).attr("cy",function(d){var y_pos=_this.y(d.values.y)||0;return config.y.type==="ordinal"?y_pos+_this.y.rangeBand()/2:y_pos});points.select("title").text(function(d){var tt=d.mark.tooltip||"";var xformat=config.x.summary==="percent"?d3.format("0%"):config.x.type==="time"?d3.time.format(config.x.format):d3.format(config.x.format);var yformat=config.y.summary==="percent"?d3.format("0%"):config.y.type==="time"?d3.time.format(config.y.format):d3.format(config.y.format);return tt.replace(/\$x/g,config.x.type==="time"?xformat(new Date(d.values.x)):xformat(d.values.x)).replace(/\$y/g,config.y.type==="time"?yformat(new Date(d.values.y)):yformat(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});point_supergroups.each(function(d){d.supergroup=d3.select(this);d.groups=d.supergroup.selectAll("g.point");d.circles=d.groups.select("circle")});return points}function drawText(marks){var _this=this;var chart=this;var config=this.config;var textSupergroups=this.svg.selectAll(".text-supergroup").data(marks,function(d,i){return"".concat(i,"-").concat(d.per.join("-"))});textSupergroups.enter().append("g").attr("class",function(d){return"supergroup text-supergroup "+d.id});textSupergroups.exit().remove();var texts=textSupergroups.selectAll(".text").data(function(d){return d.data},function(d){return d.key});var oldTexts=texts.exit();var oldTextGroupTrans=config.transitions?oldTexts.transition():oldTexts;oldTextGroupTrans.remove();var nutexts=texts.enter().append("g").attr("class",function(d){return"".concat(d.key," text")});nutexts.append("text").attr("class","wc-data-mark");function attachMarks(d){d.mark=d3.select(this.parentNode).datum();d3.select(this).select("text").attr(d.mark.attributes)}texts.each(attachMarks);texts.select("text").style("clip-path","url(#".concat(chart.id,")")).text(function(d){var tt=d.mark.text||"";var xformat=config.x.summary==="percent"?d3.format("0%"):config.x.type==="time"?d3.time.format(config.x.format):d3.format(config.x.format);var yformat=config.y.summary==="percent"?d3.format("0%"):config.y.type==="time"?d3.time.format(config.y.format):d3.format(config.y.format);return tt.replace(/\$x/g,config.x.type==="time"?xformat(new Date(d.values.x)):xformat(d.values.x)).replace(/\$y/g,config.y.type==="time"?yformat(new Date(d.values.y)):yformat(d.values.y)).replace(/\[(.+?)\]/g,function(str,orig){return d.values.raw[0][orig]})});var textsTrans=config.transitions?texts.select("text").transition():texts.select("text");textsTrans.attr("x",function(d){var xPos=_this.x(d.values.x)||0;return config.x.type==="ordinal"?xPos+_this.x.rangeBand()/2:xPos}).attr("y",function(d){var yPos=_this.y(d.values.y)||0;return config.y.type==="ordinal"?yPos+_this.y.rangeBand()/2:yPos});textSupergroups.each(function(d){d.supergroup=d3.select(this);d.groups=d.supergroup.selectAll("g.text");d.texts=d.groups.select("text")});return texts}function destroy(){var destroyControls=arguments.length>0&&arguments[0]!==undefined?arguments[0]:true;this.events.onDestroy.call(this);var context=this;if(!this.test)d3.select(window).on("resize."+context.element+context.id,null);if(destroyControls&&this.controls){this.controls.destroy()}this.wrap.remove()}var chartProto={raw_data:[],config:{}};var chart=Object.create(chartProto,{checkRequired:{value:checkRequired},consolidateData:{value:consolidateData},draw:{value:draw},destroy:{value:destroy},drawArea:{value:drawArea},drawBars:{value:drawBars},drawGridlines:{value:drawGridLines},drawLines:{value:drawLines},drawPoints:{value:drawPoints},drawText:{value:drawText},init:{value:init},layout:{value:layout},makeLegend:{value:makeLegend},resize:{value:resize},setColorScale:{value:setColorScale},setDefaults:{value:setDefaults},setMargins:{value:setMargins},textSize:{value:textSize},transformData:{value:transformData},updateDataMarks:{value:updateDataMarks},xScaleAxis:{value:xScaleAxis},yScaleAxis:{value:yScaleAxis}});var chartCount=0;function createChart(){var element=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"body";var config=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var controls=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;var thisChart=Object.create(chart);thisChart.div=element;thisChart.config=Object.create(config);thisChart.controls=controls;thisChart.raw_data=[];thisChart.filters=[];thisChart.marks=[];thisChart.wrap=d3.select(thisChart.div).append("div").datum(thisChart);thisChart.events={onInit:function onInit(){},onLayout:function onLayout(){},onPreprocess:function onPreprocess(){},onDatatransform:function onDatatransform(){},onDraw:function onDraw(){},onResize:function onResize(){},onDestroy:function onDestroy(){}};thisChart.on=function(event,callback){var possible_events=["init","layout","preprocess","datatransform","draw","resize","destroy"];if(possible_events.indexOf(event)<0){return}if(callback){thisChart.events["on"+event.charAt(0).toUpperCase()+event.slice(1)]=callback}};chartCount++;thisChart.id=chartCount;return thisChart}function changeOption(option,value,callback,draw){var _this=this;this.targets.forEach(function(target){if(option instanceof Array){option.forEach(function(o){return _this.stringAccessor(target.config,o,value)})}else{_this.stringAccessor(target.config,option,value)}if(callback){callback()}if(draw)target.draw()})}function checkRequired$1(dataset){if(!dataset[0]||!this.config.inputs)return;var colNames=d3.keys(dataset[0]);this.config.inputs.forEach(function(input,i){if(input.type==="subsetter"&&colNames.indexOf(input.value_col)===-1)throw new Error('Error in settings object: the value "'.concat(input.value_col,'" does not match any column in the provided dataset.'));input.draw=input.draw===undefined?true:input.draw})}function controlUpdate(){var _this=this;if(this.config.inputs&&this.config.inputs.length&&this.config.inputs[0])this.config.inputs.forEach(function(input){return _this.makeControlItem(input)})}function destroy$1(){this.wrap.remove()}function init$1(data){this.data=data;if(!this.config.builder)this.checkRequired(this.data);this.layout()}function layout$1(){this.wrap.selectAll("*").remove();this.ready=true;this.controlUpdate()}function makeControlItem(control){var control_wrap=this.wrap.append("div").attr("class","control-group").classed("inline",control.inline).datum(control);var ctrl_label=control_wrap.append("span").attr("class","wc-control-label").text(control.label);if(control.required)ctrl_label.append("span").attr("class","label label-required").text("Required");control_wrap.append("span").attr("class","span-description").text(control.description);if(control.type==="text"){this.makeTextControl(control,control_wrap)}else if(control.type==="number"){this.makeNumberControl(control,control_wrap)}else if(control.type==="list"){this.makeListControl(control,control_wrap)}else if(control.type==="dropdown"){this.makeDropdownControl(control,control_wrap)}else if(control.type==="btngroup"){this.makeBtnGroupControl(control,control_wrap)}else if(control.type==="checkbox"){this.makeCheckboxControl(control,control_wrap)}else if(control.type==="radio"){this.makeRadioControl(control,control_wrap)}else if(control.type==="subsetter"){this.makeSubsetterControl(control,control_wrap)}else{throw new Error('Each control must have a type! Choose from: "text", "number", "list", "dropdown", "btngroup", "checkbox", "radio", or "subsetter".')}}function makeBtnGroupControl(control,control_wrap){var _this=this;var option_data=control.values?control.values:d3.keys(this.data[0]);var btn_wrap=control_wrap.append("div").attr("class","btn-group");var changers=btn_wrap.selectAll("button").data(option_data).enter().append("button").attr("class","btn btn-default btn-sm").text(function(d){return d}).classed("btn-primary",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)===d});changers.on("click",function(d){changers.each(function(e){d3.select(this).classed("btn-primary",e===d)});_this.changeOption(control.option,d,control.callback,control.draw)})}function makeCheckboxControl(control,control_wrap){var _this=this;var changer=control_wrap.append("input").attr("type","checkbox").attr("class","changer").datum(control).property("checked",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)});changer.on("change",function(d){var value=changer.property("checked");_this.changeOption(d.option,value,control.callback,control.draw)})}function makeDropdownControl(control,control_wrap){var _this=this;var mainOption=control.option||control.options[0];var changer=control_wrap.append("select").attr("class","changer").attr("multiple",control.multiple?true:null).datum(control);var opt_values=control.values&&control.values instanceof Array?control.values:control.values?d3.set(this.data.map(function(m){return m[_this.targets[0].config[control.values]]})).values():d3.keys(this.data[0]);if(!control.require||control.none){opt_values.unshift("None")}var options=changer.selectAll("option").data(opt_values).enter().append("option").text(function(d){return d}).property("selected",function(d){return _this.stringAccessor(_this.targets[0].config,mainOption)===d});changer.on("change",function(d){var value=changer.property("value")==="None"?null:changer.property("value");if(control.multiple){value=options.filter(function(f){return d3.select(this).property("selected")})[0].map(function(m){return d3.select(m).property("value")}).filter(function(f){return f!=="None"})}if(control.options){_this.changeOption(control.options,value,control.callback,control.draw)}else{_this.changeOption(control.option,value,control.callback,control.draw)}});return changer}function makeListControl(control,control_wrap){var _this=this;var changer=control_wrap.append("input").attr("type","text").attr("class","changer").datum(control).property("value",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)});changer.on("change",function(d){var value=changer.property("value")?changer.property("value").split(",").map(function(m){return m.trim()}):null;_this.changeOption(control.option,value,control.callback,control.draw)})}function makeNumberControl(control,control_wrap){var _this=this;var changer=control_wrap.append("input").attr("type","number").attr("min",control.min!==undefined?control.min:0).attr("max",control.max).attr("step",control.step||1).attr("class","changer").datum(control).property("value",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)});changer.on("change",function(d){var value=+changer.property("value");_this.changeOption(control.option,value,control.callback,control.draw)})}function makeRadioControl(control,control_wrap){var _this=this;var changers=control_wrap.selectAll("label").data(control.values||d3.keys(this.data[0])).enter().append("label").attr("class","radio").text(function(d,i){return control.relabels?control.relabels[i]:d}).append("input").attr("type","radio").attr("class","changer").attr("name",control.option.replace(".","-")+"-"+this.targets[0].id).property("value",function(d){return d}).property("checked",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)===d});changers.on("change",function(d){var value=null;changers.each(function(c){if(d3.select(this).property("checked")){value=d3.select(this).property("value")==="none"?null:c}});_this.changeOption(control.option,value,control.callback,control.draw)})}function makeSubsetterControl(control,control_wrap){var targets=this.targets;var changer=control_wrap.append("select").classed("changer",true).attr("multiple",control.multiple?true:null).datum(control);var option_data=control.values?control.values:d3.set(this.data.map(function(m){return m[control.value_col]}).filter(function(f){return f})).values().sort(naturalSorter);control.start=control.start?control.start:control.loose?option_data[0]:null;if(!control.multiple&&!control.start){option_data.unshift("All");control.all=true}else{control.all=false}control.loose=!control.loose&&control.start?true:control.loose;var options=changer.selectAll("option").data(option_data).enter().append("option").text(function(d){return d}).property("selected",function(d){return d===control.start});targets.forEach(function(e){var match=e.filters.slice().map(function(m){return m.col===control.value_col}).indexOf(true);if(match>-1){e.filters[match]={col:control.value_col,val:control.start?control.start:!control.multiple?"All":option_data,index:0,choices:option_data,loose:control.loose,all:control.all}}else{e.filters.push({col:control.value_col,val:control.start?control.start:!control.multiple?"All":option_data,index:0,choices:option_data,loose:control.loose,all:control.all})}});function setSubsetter(target,obj){var match=-1;target.filters.forEach(function(e,i){if(e.col===obj.col){match=i}});if(match>-1){target.filters[match]=obj}}changer.on("change",function(d){if(control.multiple){var values=options.filter(function(f){return d3.select(this).property("selected")})[0].map(function(m){return d3.select(m).property("text")});var new_filter={col:control.value_col,val:values,index:null,choices:option_data,loose:control.loose,all:control.all};targets.forEach(function(e){setSubsetter(e,new_filter);if(control.callback){control.callback()}if(control.draw)e.draw()})}else{var value=d3.select(this).select("option:checked").property("text");var index=d3.select(this).select("option:checked").property("index");var _new_filter={col:control.value_col,val:value,index:index,choices:option_data,loose:control.loose,all:control.all};targets.forEach(function(e){setSubsetter(e,_new_filter);if(control.callback){control.callback()}e.draw()})}})}function makeTextControl(control,control_wrap){var _this=this
-;var changer=control_wrap.append("input").attr("type","text").attr("class","changer").datum(control).property("value",function(d){return _this.stringAccessor(_this.targets[0].config,control.option)});changer.on("change",function(d){var value=changer.property("value");_this.changeOption(control.option,value,control.callback,control.draw)})}function stringAccessor(o,s,v){s=s.replace(/\[(\w+)\]/g,".$1");s=s.replace(/^\./,"");var a=s.split(".");for(var i=0,n=a.length;i0&&arguments[0]!==undefined?arguments[0]:"body";var config=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var thisControls=Object.create(controls);thisControls.div=element;thisControls.config=Object.create(config);thisControls.config.inputs=thisControls.config.inputs||[];thisControls.targets=[];if(config.location==="bottom"){thisControls.wrap=d3.select(element).append("div").attr("class","wc-controls")}else{thisControls.wrap=d3.select(element).insert("div",":first-child").attr("class","wc-controls")}thisControls.wrap.datum(thisControls);return thisControls}function applyFilters(){var _this=this;if(this.filters&&this.filters.some(function(filter){return typeof filter.val==="string"&&!(filter.all===true&&filter.index===0)||Array.isArray(filter.val)&&filter.val.length-1:filter.val===d[filter.col]})})}else this.data.filtered=this.data.raw}function updateDataObject(){this.data.raw=this.data.passed;this.data.filtered=this.data.passed;this.config.activePage=0;this.config.startIndex=this.config.activePage*this.config.nRowsPerPage;this.config.endIndex=this.config.startIndex+this.config.nRowsPerPage}function applySearchTerm(data){var _this=this;if(this.searchable.searchTerm){this.data.searched=this.data.filtered.filter(function(d){var match=false;Object.keys(d).filter(function(key){return _this.config.cols.indexOf(key)>-1}).forEach(function(var_name){if(match===false){var cellText=""+d[var_name];match=cellText.toLowerCase().indexOf(_this.searchable.searchTerm)>-1}});return match});this.data.processing=this.data.searched}else{delete this.data.searched;this.data.processing=this.data.filtered}}if(Array.prototype.equals)console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code.");Array.prototype.equals=function(array){if(!array)return false;if(this.length!=array.length)return false;for(var i=0,l=this.length;i=Math.max(widths.top,widths.bottom)&&this.config.layout==="vertical"){this.config.layout="horizontal";this.wrap.style("display","table").selectAll(".table-top,.table-bottom").style("display","block").selectAll(".interactivity").style({display:"inline-block",float:function float(){return d3.select(this).classed("searchable-container")||d3.select(this).classed("pagination-container")?"right":null},clear:null})}}function draw$1(passed_data){var _this=this;var table=this;var config=this.config;this.data.passed=passed_data;this.events.onPreprocess.call(this);if(!passed_data)applyFilters.call(this);else updateDataObject.call(this);checkFilters.call(this);applySearchTerm.call(this);this.searchable.wrap.select(".nNrecords").text(this.data.processing.length===this.data.raw.length?"".concat(this.data.raw.length," records displayed"):"".concat(this.data.processing.length,"/").concat(this.data.raw.length," records displayed"));updateTableHeaders.call(this);this.tbody.selectAll("tr").remove();if(this.data.processing.length===0){this.tbody.append("tr").classed("no-data",true).append("td").attr("colspan",this.config.cols.length).text("No data selected.");this.data.current=this.data.processing;this.table.datum(this.table.current);if(this.config.exportable)this.config.exports.forEach(function(fmt){_this.exportable.exports[fmt].call(_this,_this.data.processing)});if(this.config.pagination)this.pagination.addPagination.call(this,this.data.processing)}else{if(this.config.sortable){this.thead.selectAll("th").on("click",function(header){table.sortable.onClick.call(table,this,header)});if(this.sortable.order.length)this.sortable.sortData.call(this,this.data.processing)}this.data.current=this.data.processing;this.table.datum(this.data.current);if(this.config.exportable)this.config.exports.forEach(function(fmt){_this.exportable.exports[fmt].call(_this,_this.data.processing)});if(this.config.pagination){this.pagination.addPagination.call(this,this.data.processing);this.data.processing=this.data.processing.filter(function(d,i){return _this.config.startIndex<=i&&i<_this.config.endIndex})}drawTableBody.call(this)}if(this.config.dynamicPositioning){dynamicLayout.call(this)}this.events.onDraw.call(this)}function layout$2(){var context=this;this.searchable.wrap=this.wrap.select(".table-top").append("div").classed("interactivity searchable-container",true).classed("hidden",!this.config.searchable);this.searchable.wrap.append("div").classed("search",true);this.searchable.wrap.select(".search").append("input").classed("search-box",true).attr("placeholder","Search").on("input",function(){context.searchable.searchTerm=this.value.toLowerCase()||null;context.config.activePage=0;context.config.startIndex=context.config.activePage*context.config.nRowsPerPage;context.config.endIndex=context.config.startIndex+context.config.nRowsPerPage;context.draw()});this.searchable.wrap.select(".search").append("span").classed("nNrecords",true)}function searchable(){return{layout:layout$2}}function layout$3(){var _this=this;this.exportable.wrap=this.wrap.select(".table-bottom").append("div").classed("interactivity exportable-container",true).classed("hidden",!this.config.exportable);this.exportable.wrap.append("span").text("Export:");if(this.config.exports&&this.config.exports.length)this.config.exports.forEach(function(fmt){_this.exportable.wrap.append("a").classed("wc-button export",true).attr({id:fmt}).style(!_this.test&&navigator.msSaveBlob?{cursor:"pointer","text-decoration":"underline",color:"blue"}:null).text(fmt.toUpperCase())})}function download(fileType,data){var blob=new Blob(data,{type:fileType==="csv"?"text/csv;charset=utf-8;":fileType==="xlsx"?"application/octet-stream":console.warn("File type not supported: ".concat(fileType))});var fileName="webchartsTableExport_".concat(d3.time.format("%Y-%m-%dT%H-%M-%S")(new Date),".").concat(fileType);var link=this.wrap.select(".export#".concat(fileType));if(navigator.msSaveBlob)navigator.msSaveBlob(blob,fileName);else if(link.node().download!==undefined){var url=URL.createObjectURL(blob);link.node().setAttribute("href",url);link.node().setAttribute("download",fileName)}}function csv(data){var _this=this;this.wrap.select(".export#csv").on("click",function(){var CSVarray=[];var headers=_this.config.headers.map(function(header){return'"'.concat(header.replace(/"/g,'""'),'"')});CSVarray.push(headers);data.forEach(function(d,i){var row=_this.config.cols.map(function(col){var value=d[col];if(typeof value==="string")value=value.replace(/"/g,'""');return'"'.concat(value,'"')});CSVarray.push(row)});download.call(_this,"csv",[CSVarray.join("\n")])})}function xlsx(data){var _this=this;this.wrap.select(".export#xlsx").on("click",function(){var sheetName="Selected Data";var options={bookType:"xlsx",bookSST:true,type:"binary"};var arrayOfArrays=data.map(function(d){return Object.keys(d).filter(function(key){return _this.config.cols.indexOf(key)>-1}).map(function(key){return d[key]})});var workbook={SheetNames:[sheetName],Sheets:{}};var cols=[];workbook.Sheets[sheetName]=XLSX.utils.aoa_to_sheet([_this.config.headers].concat(arrayOfArrays));workbook.Sheets[sheetName]["!autofilter"]={ref:"A1:".concat(String.fromCharCode(64+_this.config.cols.length)).concat(data.length+1)};_this.table.selectAll("thead tr th").each(function(){cols.push({wpx:this.offsetWidth})});workbook.Sheets[sheetName]["!cols"]=cols;var xlsx=XLSX.write(workbook,options);var s2ab=function s2ab(s){var buffer=new ArrayBuffer(s.length),view=new Uint8Array(buffer);for(var i=0;i!==s.length;++i){view[i]=s.charCodeAt(i)&255}return buffer};download.call(_this,"xlsx",[s2ab(xlsx)])})}var exports$1={csv:csv,xlsx:xlsx};function exportable(){return{layout:layout$3,exports:exports$1}}function layout$4(){this.sortable.wrap=this.wrap.select(".table-top").append("div").classed("interactivity sortable-container",true).classed("hidden",!this.config.sortable);this.sortable.wrap.append("div").classed("instruction",true).text("Click column headers to sort.")}function onClick(th,header){var context=this,selection=d3.select(th),col=this.config.cols[this.config.headers.indexOf(header)];var sortItem=this.sortable.order.filter(function(item){return item.col===col})[0];if(!sortItem){sortItem={col:col,direction:"ascending",wrap:this.sortable.wrap.append("div").datum({key:col}).classed("wc-button sort-box",true).text(header)};sortItem.wrap.append("span").classed("sort-direction",true).html("↓");sortItem.wrap.append("span").classed("remove-sort",true).html("❌");this.sortable.order.push(sortItem)}else{sortItem.direction=sortItem.direction==="ascending"?"descending":"ascending";sortItem.wrap.select("span.sort-direction").html(sortItem.direction==="ascending"?"↓":"↑")}this.sortable.wrap.select(".instruction").classed("hidden",true);this.sortable.order.forEach(function(item,i){item.wrap.on("click",function(d){d3.select(this).remove();context.sortable.order.splice(context.sortable.order.map(function(d){return d.col}).indexOf(d.key),1);context.sortable.wrap.select(".instruction").classed("hidden",context.sortable.order.length);context.draw()})});this.draw()}function sortData(data){var _this=this;data=data.sort(function(a,b){var order=0;_this.sortable.order.forEach(function(item){var aCell=a[item.col],bCell=b[item.col];if(order===0){if(item.direction==="ascending"&&aCellbCell)order=-1;else if(item.direction==="ascending"&&aCell>bCell||item.direction==="descending"&&aCell=_this.config.nPageLinksDisplayed:_this.config.activePage>=_this.config.nPages-_this.config.nPageLinksDisplayed?i<_this.config.nPages-_this.config.nPageLinksDisplayed:i<_this.config.activePage-(Math.ceil(_this.config.nPageLinksDisplayed/2)-1)||_this.config.activePage+_this.config.nPageLinksDisplayed/2=this.config.nPages)next=this.config.nPages-1;this.pagination.wrap.insert("span",":first-child").classed("dot-dot-dot",true).text("...").classed("hidden",this.config.activePage=Math.max(this.config.nPageLinksDisplayed,this.config.nPages-this.config.nPageLinksDisplayed)||this.config.nPages<=this.config.nPageLinksDisplayed);this.pagination.next=this.pagination.wrap.append("a").classed("wc-button arrow-link wc-right",true).classed("hidden",this.config.activePage==this.config.nPages-1||this.config.nPages==0).attr({rel:next}).text(">");this.pagination.doubleNext=this.pagination.wrap.append("a").classed("wc-button arrow-link wc-right double",true).classed("hidden",this.config.activePage==this.config.nPages-1||this.config.nPages==0).attr({rel:this.config.nPages-1}).text(">>");this.pagination.arrows=this.pagination.wrap.selectAll("a.arrow-link");this.pagination.doubleArrows=this.pagination.wrap.selectAll("a.double-arrow-link")}function addPagination(data){var context=this;this.config.nRows=data.length;this.config.nPages=Math.ceil(this.config.nRows/this.config.nRowsPerPage);this.config.paginationHidden=this.config.nPages===1;this.pagination.wrap.classed("hidden",this.config.paginationHidden);addLinks.call(this);this.pagination.links.on("click",function(){context.config.activePage=+d3.select(this).attr("rel");updatePagination.call(context)});addArrows.call(this);this.pagination.arrows.on("click",function(){if(context.config.activePage!==+d3.select(this).attr("rel")){context.config.activePage=+d3.select(this).attr("rel");context.pagination.prev.attr("rel",context.config.activePage>0?context.config.activePage-1:0);context.pagination.next.attr("rel",context.config.activePage1&&arguments[1]!==undefined?arguments[1]:false;this.test=test;if(d3.select(this.div).select(".loader").empty()){d3.select(this.div).insert("div",":first-child").attr("class","loader").selectAll(".blockG").data(d3.range(8)).enter().append("div").attr("class",function(d){return"blockG rotate"+(d+1)})}this.setDefaults.call(this,data[0]);this.wrap.classed("wc-chart",true).classed("wc-table",this.config.applyCSS);this.data={raw:data};this.searchable=searchable.call(this);this.sortable=sortable.call(this);this.pagination=pagination.call(this);this.exportable=exportable.call(this);var startup=function startup(data){if(_this.controls){_this.controls.targets.push(_this);if(!_this.controls.ready){_this.controls.init(_this.data.raw)}else{_this.controls.layout()}}var visible=d3.select(_this.div).property("offsetWidth")>0||test;if(!visible){console.warn("The table cannot be initialized inside an element with 0 width. The table will be initialized as soon as the container element is given a width > 0.");var onVisible=setInterval(function(i){var visible_now=d3.select(_this.div).property("offsetWidth")>0;if(visible_now){_this.layout();_this.wrap.datum(_this);_this.draw();clearInterval(onVisible)}},500)}else{_this.layout();_this.wrap.datum(_this);_this.draw()}};this.events.onInit.call(this);if(this.data.raw.length){this.checkRequired(this.data.raw)}startup();return this}function layout$6(){d3.select(this.div).select(".loader").remove();this.wrap.append("div").classed("table-top",true);this.searchable.layout.call(this);this.sortable.layout.call(this);this.table=this.wrap.append("table").classed("table",this.config.bootstrap);this.thead=this.table.append("thead");this.thead.append("tr");this.tbody=this.table.append("tbody");this.wrap.append("div").classed("table-bottom",true);this.pagination.layout.call(this);this.exportable.layout.call(this);this.events.onLayout.call(this)}function destroy$2(){var destroyControls=arguments.length>0&&arguments[0]!==undefined?arguments[0]:false;this.events.onDestroy.call(this);if(destroyControls&&this.controls){this.controls.destroy()}this.wrap.remove()}function setDefault(setting){var _default_=arguments.length>1&&arguments[1]!==undefined?arguments[1]:true;this.config[setting]=this.config[setting]!==undefined?this.config[setting]:_default_}function setDefaults$1(firstItem){if(this.config.cols instanceof Array&&this.config.headers instanceof Array){if(this.config.cols.length===0)delete this.config.cols;if(this.config.headers.length===0||this.config.headers.length!==this.config.cols.length)delete this.config.headers}this.config.cols=this.config.cols||d3.keys(firstItem);this.config.headers=this.config.headers||this.config.cols;this.config.layout="horizontal";setDefault.call(this,"searchable");setDefault.call(this,"exportable");setDefault.call(this,"exports",["csv"]);setDefault.call(this,"sortable");setDefault.call(this,"pagination");setDefault.call(this,"nRowsPerPage",10);setDefault.call(this,"nPageLinksDisplayed",5);setDefault.call(this,"applyCSS");setDefault.call(this,"dynamicPositioning")}function transformData$1(processed_data){var _this=this;this.data.processed=this.transformData(this.wrap.datum);if(!data){return}this.config.cols=this.config.cols||d3.keys(data[0]);this.config.headers=this.config.headers||this.config.cols;if(this.config.keep){this.config.keep.forEach(function(e){if(_this.config.cols.indexOf(e)===-1){_this.config.cols.unshift(e)}})}var filtered=data;if(this.filters.length){this.filters.forEach(function(e){var is_array=e.val instanceof Array;filtered=filtered.filter(function(d){if(is_array){return e.val.indexOf(d[e.col])!==-1}else{return e.val!=="All"?d[e.col]===e.val:d}})})}var slimmed=d3.nest().key(function(d){if(_this.config.row_per){return _this.config.row_per.map(function(m){return d[m]}).join(" ")}else{return d}}).rollup(function(r){if(_this.config.dataManipulate){r=_this.config.dataManipulate(r)}var nuarr=r.map(function(m){var arr=[];for(var x in m){arr.push({col:x,text:m[x]})}arr.sort(function(a,b){return _this.config.cols.indexOf(a.col)-_this.config.cols.indexOf(b.col)});return{cells:arr,raw:m}});return nuarr}).entries(filtered);this.data.current=slimmed.length?slimmed:[{key:null,values:[]}];this.pagination.wrap.selectAll("*").remove();this.events.onDatatransform.call(this);if(config.row_per){var rev_order=config.row_per.slice(0).reverse();rev_order.forEach(function(e){tbodies.sort(function(a,b){return a.values[0].raw[e]-b.values[0].raw[e]})})}if(config.row_per){rows.filter(function(f,i){return i>0}).selectAll("td").filter(function(f){return config.row_per.indexOf(f.col)>-1}).text("")}return this.data.current}var table=Object.create(chart,{draw:{value:draw$1},init:{value:init$2},layout:{value:layout$6},setDefaults:{value:setDefaults$1},transformData:{value:transformData$1},destroy:{value:destroy$2}});function createTable(){var element=arguments.length>0&&arguments[0]!==undefined?arguments[0]:"body";var config=arguments.length>1&&arguments[1]!==undefined?arguments[1]:{};var controls=arguments.length>2&&arguments[2]!==undefined?arguments[2]:null;var thisTable=Object.create(table);thisTable.div=element;thisTable.config=Object.create(config);thisTable.controls=controls;thisTable.filters=[];thisTable.required_cols=[];thisTable.wrap=d3.select(thisTable.div).append("div").datum(thisTable);thisTable.events={onInit:function onInit(){},onLayout:function onLayout(){},onPreprocess:function onPreprocess(){},onDraw:function onDraw(){},onDestroy:function onDestroy(){}};thisTable.on=function(event,callback){var possible_events=["init","layout","preprocess","draw","destroy"];if(possible_events.indexOf(event)<0){return}if(callback){thisTable.events["on"+event.charAt(0).toUpperCase()+event.slice(1)]=callback}};return thisTable}function multiply(chart,data,split_by,order){var test=arguments.length>4&&arguments[4]!==undefined?arguments[4]:false;chart.wrap.classed("wc-layout wc-small-multiples",true).classed("wc-chart",false);chart.master_legend=chart.wrap.append("ul").attr("class","legend");chart.master_legend.append("span").classed("legend-title",true);chart.multiples=[];function goAhead(data){var split_vals=d3.set(data.map(function(m){return m[split_by]})).values().filter(function(f){return f});if(order){split_vals=split_vals.sort(function(a,b){return d3.ascending(order.indexOf(a),order.indexOf(b))})}split_vals.forEach(function(e){var mchart=createChart(chart.wrap.node(),chart.config,chart.controls);chart.multiples.push(mchart);mchart.parent=chart;mchart.events=chart.events;mchart.legend=chart.master_legend;mchart.filters.unshift({col:split_by,val:e,choices:split_vals});mchart.wrap.insert("span","svg").attr("class","wc-chart-title").text(e);mchart.init(data,test)})}goAhead(data)}function getValType(data,variable){var var_vals=d3.set(data.map(function(m){return m[variable]})).values();var vals_numbers=var_vals.filter(function(f){return+f||+f===0});if(var_vals.length===vals_numbers.length&&var_vals.length>4){return"continuous"}else{return"categorical"}}function lengthenRaw(data,columns){var my_data=[];data.forEach(function(e){columns.forEach(function(g){var obj=Object.create(e);obj.wc_category=g;obj.wc_value=e[g];my_data.push(obj)})});return my_data}var dataOps={getValType:getValType,lengthenRaw:lengthenRaw,naturalSorter:naturalSorter,summarize:summarize};var index={version:version,createChart:createChart,createControls:createControls,createTable:createTable,multiply:multiply,dataOps:dataOps};return index});
+(function(global,factory){typeof exports==="object"&&typeof module!=="undefined"?module.exports=factory(require("d3")):typeof define==="function"&&define.amd?define(["d3"],factory):(global=global||self,global.webCharts=factory(global.d3))})(this,function(d3){"use strict";var version="1.11.7";function init(data){var _this=this;var test=arguments.length>1&&arguments[1]!==undefined?arguments[1]:false;this.test=test;if(d3.select(this.div).select(".loader").empty()){d3.select(this.div).insert("div",":first-child").attr("class","loader").selectAll(".blockG").data(d3.range(8)).enter().append("div").attr("class",function(d){return"blockG rotate"+(d+1)})}this.wrap.attr("class","wc-chart");this.setDefaults();this.raw_data=data;this.initial_data=data;var startup=function startup(data){if(_this.controls){_this.controls.targets.push(_this);if(!_this.controls.ready){_this.controls.init(_this.raw_data)}else{_this.controls.layout()}}var visible=d3.select(_this.div).property("offsetWidth")>0||test;if(!visible){console.warn("The chart cannot be initialized inside an element with 0 width. The chart will be initialized as soon as the container element is given a width > 0.");var onVisible=setInterval(function(i){var visible_now=d3.select(_this.div).property("offsetWidth")>0;if(visible_now){_this.layout();_this.draw();clearInterval(onVisible)}},500)}else{_this.layout();_this.draw()}};this.events.onInit.call(this);if(this.raw_data.length){this.checkRequired(this.raw_data)}startup();return this}function checkRequired(data){var _this=this;var colnames=Object.keys(data[0]);var requiredVars=[];var requiredCols=[];if(this.config.x&&this.config.x.column){requiredVars.push("this.config.x.column");requiredCols.push(this.config.x.column)}if(this.config.y&&this.config.y.column){requiredVars.push("this.config.y.column");requiredCols.push(this.config.y.column)}if(this.config.color_by){requiredVars.push("this.config.color_by");requiredCols.push(this.config.color_by)}if(this.config.marks)this.config.marks.forEach(function(e,i){if(e.per&&e.per.length){e.per.forEach(function(p,j){requiredVars.push("this.config.marks["+i+"].per["+j+"]");requiredCols.push(p)})}if(e.split){requiredVars.push("this.config.marks["+i+"].split");requiredCols.push(e.split)}if(e.values&&e.checkColumns){for(var value in e.values){requiredVars.push("this.config.marks["+i+"].values['"+value+"']");requiredCols.push(value)}}});var missingDataField=false;requiredCols.forEach(function(e,i){if(colnames.indexOf(e)<0){missingDataField=true;d3.select(_this.div).select(".loader").remove();_this.wrap.append("div").style("color","red").html('The value "'+e+'" for the '+requiredVars[i]+"
setting does not match any column in the provided dataset.");throw new Error('Error in settings object: The value "'+e+'" for the '+requiredVars[i]+" setting does not match any column in the provided dataset.")}});return{missingDataField:missingDataField,dataFieldArguments:requiredVars,requiredDataFields:requiredCols}}function addSVG(){this.svg=this.wrap.append("svg").datum(function(){return null}).attr({class:"wc-svg",xmlns:"http://www.w3.org/2000/svg",version:"1.1",xlink:"http://www.w3.org/1999/xlink"}).append("g").style("display","inline-block")}function addDefs(){var defs=this.svg.append("defs");defs.append("pattern").attr({id:"diagonal-stripes",x:0,y:0,width:3,height:8,patternUnits:"userSpaceOnUse",patternTransform:"rotate(30)"}).append("rect").attr({x:"0",y:"0",width:"2",height:"8"}).style({stroke:"none",fill:"black"});defs.append("clipPath").attr("id",this.id).append("rect").attr("class","plotting-area")}function addXAxis(){this.svg.append("g").attr("class","x axis").append("text").attr("class","axis-title").attr("dy","-.35em").attr("text-anchor","middle")}function addYAxis(){this.svg.append("g").attr("class","y axis").append("text").attr("class","axis-title").attr("transform","rotate(-90)").attr("dy",".75em").attr("text-anchor","middle")}function addOverlay(){this.overlay=this.svg.append("rect").attr("class","overlay").attr("opacity",0).attr("fill","none").style("pointer-events","all")}function addLegend(){if(!this.parent){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 thisAxis=this.config[axis];var thatAxis=this.config[axis==="x"?"y":"x"];var dom;if(thisAxis.type==="ordinal"){if(thisAxis.domain){dom=thisAxis.domain}else if(thisAxis.order){dom=d3.set(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]}))).values().sort(function(a,b){return d3.ascending(thisAxis.order.indexOf(a),thisAxis.order.indexOf(b))})}else if(thisAxis.sort&&thisAxis.sort==="alphabetical-ascending"){dom=d3.set(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]}))).values().sort(naturalSorter)}else if(["time","linear"].indexOf(thatAxis.type)>-1&&thisAxis.sort==="earliest"){dom=d3.nest().key(function(d){return d[thisAxis.column]}).rollup(function(d){return d.map(function(m){return m[thatAxis.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(!thisAxis.sort||thisAxis.sort==="alphabetical-descending"){dom=d3.set(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]}))).values().sort(naturalSorter).reverse()}else{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){dom=[0,1]}else{dom=d3.extent(d3.merge(this.marks.map(function(mark){return mark[axis+"_dom"]})))}if(thisAxis.type==="linear"&&dom[0]===dom[1])dom=dom[0]!==0?[dom[0]-dom[0]*.01,dom[1]+dom[1]*.01]:[-1,1];this[axis+"_dom"]=dom;return 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})}else totalOrder=test.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){x_dom.sort(function(a,b){return current_nested.totalOrder.indexOf(a)-current_nested.totalOrder.indexOf(b)})}if(config.y.type==="ordinal"&&!config.y.order){y_dom.sort(function(a,b){return current_nested.totalOrder.indexOf(a)-current_nested.totalOrder.indexOf(b)})}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 _this.config.cols.map(function(col){return d[col]})});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 a64215a..2de68bc 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,118 @@
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--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: 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 .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: bold;
+ margin-right: .5em;
+ }
+
+ *[class*="wc-"] .legend .legend-item .legend-label {
+ margin-left: 0.25em;
+ }
+
+ *[class*="wc-"] .legend--right .legend-item .legend-label {
+ margin-right: 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/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/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/src/chart/draw/consolidateData.js b/src/chart/draw/consolidateData.js
index e9200c3..3f18049 100644
--- a/src/chart/draw/consolidateData.js
+++ b/src/chart/draw/consolidateData.js
@@ -14,7 +14,7 @@ export default function consolidateData(raw) {
? d
: filter.val instanceof Array
? filter.val.indexOf(d[filter.col]) > -1
- : d[filter.col] === filter.val;
+ : d[filter.col] + '' === filter.val + '';
});
});
}
diff --git a/src/chart/draw/consolidateData/setDefaults.js b/src/chart/draw/consolidateData/setDefaults.js
index d212d61..ea12318 100644
--- a/src/chart/draw/consolidateData/setDefaults.js
+++ b/src/chart/draw/consolidateData/setDefaults.js
@@ -1,32 +1,48 @@
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 || {};
+ // 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.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.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/consolidateData/setDomain.js b/src/chart/draw/consolidateData/setDomain.js
index 2c04ecd..d99633a 100644
--- a/src/chart/draw/consolidateData/setDomain.js
+++ b/src/chart/draw/consolidateData/setDomain.js
@@ -2,59 +2,48 @@ import naturalSorter from '../../../dataOps/naturalSorter';
import { set, merge, ascending, nest, min, extent } from 'd3';
export default function setDomain(axis) {
- const otherAxis = axis === 'x' ? 'y' : 'x';
+ const thisAxis = this.config[axis];
+ const thatAxis = this.config[axis === 'x' ? 'y' : 'x'];
+ let dom;
- if (this.config[axis].type === 'ordinal') {
+ if (thisAxis.type === 'ordinal') {
//ordinal domains
- if (this.config[axis].domain) {
+ if (thisAxis.domain) {
//user-defined domain
- this[axis + '_dom'] = this.config[axis].domain;
- } else if (this.config[axis].order) {
+ dom = thisAxis.domain;
+ } else if (thisAxis.order) {
//data-driven domain with user-defined domain order
- this[axis + '_dom'] = set(merge(this.marks.map(mark => mark[axis + '_dom'])))
+ dom = set(merge(this.marks.map(mark => mark[axis + '_dom'])))
.values()
- .sort((a, b) =>
- 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') {
+ .sort((a, b) => ascending(thisAxis.order.indexOf(a), thisAxis.order.indexOf(b)));
+ } else if (thisAxis.sort && thisAxis.sort === 'alphabetical-ascending') {
//data-driven domain with user-defined domain sort algorithm that sorts the axis
//alphanumerically, first to last
- this[axis + '_dom'] = set(merge(this.marks.map(mark => mark[axis + '_dom'])))
+ dom = set(merge(this.marks.map(mark => mark[axis + '_dom'])))
.values()
.sort(naturalSorter);
- } else if (
- ['time', 'linear'].indexOf(this.config[otherAxis].type) > -1 &&
- this.config[axis].sort === 'earliest'
- ) {
+ } else if (['time', 'linear'].indexOf(thatAxis.type) > -1 && thisAxis.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'] = nest()
- .key(d => d[this.config[axis].column])
+ dom = nest()
+ .key(d => d[thisAxis.column])
.rollup(d => {
- return d
- .map(m => m[this.config[otherAxis].column])
- .filter(f => f instanceof Date);
+ return d.map(m => m[thatAxis.column]).filter(f => f instanceof Date);
})
.entries(this.filtered_data)
.sort((a, b) => min(b.values) - min(a.values))
.map(m => m.key);
- } else if (
- !this.config[axis].sort ||
- this.config[axis].sort === 'alphabetical-descending'
- ) {
+ } else if (!thisAxis.sort || thisAxis.sort === 'alphabetical-descending') {
//data-driven domain with default/user-defined domain sort algorithm that sorts the
//axis alphanumerically, last to first
- this[axis + '_dom'] = set(merge(this.marks.map(mark => mark[axis + '_dom'])))
+ dom = set(merge(this.marks.map(mark => 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'] = set(merge(this.marks.map(mark => mark[axis + '_dom']))).values();
+ dom = set(merge(this.marks.map(mark => mark[axis + '_dom']))).values();
}
} else if (
this.config.marks
@@ -62,24 +51,20 @@ export default function setDomain(axis) {
.indexOf(true) > -1
) {
//rate domains run from 0 to 1
- this[axis + '_dom'] = [0, 1];
+ 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'] = extent(merge(this.marks.map(mark => mark[axis + '_dom'])));
+ dom = extent(merge(this.marks.map(mark => mark[axis + '_dom'])));
}
//Give the domain a range when the range of the variable is 0.
- if (this.config[axis].type === 'linear' && this[axis + '_dom'][0] === this[axis + '_dom'][1])
- this[axis + '_dom'] =
- this[axis + '_dom'][0] !== 0
- ? [
- this[axis + '_dom'][0] - this[axis + '_dom'][0] * 0.01,
- this[axis + '_dom'][1] + this[axis + '_dom'][1] * 0.01
- ]
- : [-1, 1];
+ if (thisAxis.type === 'linear' && dom[0] === dom[1])
+ dom = dom[0] !== 0 ? [dom[0] - dom[0] * 0.01, dom[1] + dom[1] * 0.01] : [-1, 1];
- return this[axis + '_dom'];
+ this[axis + '_dom'] = dom;
+
+ return dom;
}
diff --git a/src/chart/draw/consolidateData/transformData.js b/src/chart/draw/consolidateData/transformData.js
index 5eab8a3..3c9da06 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
@@ -107,6 +107,7 @@ export default function transformData(raw, mark) {
let filt1_dom_x = extent(merge(filt1_xs));
let filt1_dom_y = extent(merge(filt1_ys));
+ // why are we calling makeNest twice?
let current_nested = makeNest.call(this, mark, filtered, sublevel);
let flex_dom_x = current_nested.dom_x;
@@ -208,10 +209,14 @@ export default function transformData(raw, mark) {
}
if (config.x.type === 'ordinal' && !config.x.order) {
- config.x.order = current_nested.totalOrder;
+ x_dom.sort(
+ (a, b) => current_nested.totalOrder.indexOf(a) - current_nested.totalOrder.indexOf(b)
+ );
}
if (config.y.type === 'ordinal' && !config.y.order) {
- config.y.order = current_nested.totalOrder;
+ y_dom.sort(
+ (a, b) => current_nested.totalOrder.indexOf(a) - current_nested.totalOrder.indexOf(b)
+ );
}
this.current_data = current_nested.nested;
diff --git a/src/chart/draw/consolidateData/transformData/makeNest.js b/src/chart/draw/consolidateData/transformData/makeNest.js
index 65f343e..cf0ef10 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 => {
@@ -177,7 +183,7 @@ export default function makeNest(mark, entries, sublevel) {
(this.config.y.sort === 'total-ascending' && this.config.y.type == 'ordinal')
) {
totalOrder = test.sort((a, b) => descending(+a.total, +b.total)).map(m => m.key);
- }
+ } else totalOrder = test.map(m => m.key);
return { nested: test, dom_x: dom_x, dom_y: dom_y, totalOrder: totalOrder };
}
diff --git a/src/chart/draw/setColorScale.js b/src/chart/draw/setColorScale.js
index 7bb76f3..70ed331 100644
--- a/src/chart/draw/setColorScale.js
+++ b/src/chart/draw/setColorScale.js
@@ -9,7 +9,7 @@ export default function setColorScale() {
? config.color_dom.slice()
: set(data.map(m => m[config.color_by]))
.values()
- .filter(f => f && f !== 'undefined');
+ .filter(f => f !== 'undefined');
if (config.legend.order)
colordom.sort((a, b) =>
diff --git a/src/chart/init.js b/src/chart/init.js
index 1208974..1396e14 100644
--- a/src/chart/init.js
+++ b/src/chart/init.js
@@ -26,7 +26,7 @@ export default function init(data, test = false) {
this.initial_data = data;
let startup = data => {
- //connect this chart and its controls, if any
+ // connect this chart and its controls, if any
if (this.controls) {
this.controls.targets.push(this);
if (!this.controls.ready) {
@@ -36,7 +36,7 @@ export default function init(data, test = false) {
}
}
- //make sure container is visible (has height and width) before trying to initialize
+ // make sure container is visible (has height and width) before trying to initialize
var visible = select(this.div).property('offsetWidth') > 0 || test;
if (!visible) {
console.warn(
diff --git a/src/chart/init/checkRequired.js b/src/chart/init/checkRequired.js
index a879e38..ca2a1e0 100644
--- a/src/chart/init/checkRequired.js
+++ b/src/chart/init/checkRequired.js
@@ -28,7 +28,7 @@ export default function checkRequired(data) {
requiredVars.push('this.config.marks[' + i + '].split');
requiredCols.push(e.split);
}
- if (e.values) {
+ if (e.values && e.checkColumns) {
for (const value in e.values) {
requiredVars.push('this.config.marks[' + i + "].values['" + value + "']");
requiredCols.push(value);
diff --git a/src/chart/layout/addLegend.js b/src/chart/layout/addLegend.js
index a3aa1cb..cd21f17 100644
--- a/src/chart/layout/addLegend.js
+++ b/src/chart/layout/addLegend.js
@@ -1,11 +1,10 @@
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')
- .append('span')
- .attr('class', 'legend-title');
+ .classed('legend', true);
+ const legend_title = legend.append('span').classed('legend-title', true);
+ }
}
diff --git a/src/chart/resize/makeLegend.js b/src/chart/resize/makeLegend.js
index d0c70c6..b1fff8f 100644
--- a/src/chart/resize/makeLegend.js
+++ b/src/chart/resize/makeLegend.js
@@ -1,153 +1,24 @@
-import { ascending, select } from 'd3';
+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 addLegendLabels from './makeLegend/addLegendLabels';
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';
-
- let legend_label = label
- ? label
- : typeof config.legend.label === 'string'
- ? config.legend.label
- : '';
-
- 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();
-
- 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);
-
- if (config.legend.order) {
- leg_parts.sort((a, b) =>
- 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) {
- 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);
- });
-
- 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';
- legend.style('display', legendDisplay);
- } else {
- legend.style('display', 'none');
- }
-
- this.legend = legend;
+ 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);
+
+ // 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..58cded3
--- /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
new file mode 100644
index 0000000..c36cc9b
--- /dev/null
+++ b/src/chart/resize/makeLegend/addLegendItems.js
@@ -0,0 +1,29 @@
+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')
+ .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)
+ )
+ );
+ }
+
+ 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
new file mode 100644
index 0000000..4841fc1
--- /dev/null
+++ b/src/chart/resize/makeLegend/addLegendMarks.js
@@ -0,0 +1,48 @@
+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();
+
+ 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)
+ })
+ .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
new file mode 100644
index 0000000..7be3259
--- /dev/null
+++ b/src/chart/resize/makeLegend/addLegendTitle.js
@@ -0,0 +1,5 @@
+export default function addLegendTitle(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
new file mode 100644
index 0000000..4cc5061
--- /dev/null
+++ b/src/chart/resize/makeLegend/defineLegendData.js
@@ -0,0 +1,17 @@
+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..a61a0e9
--- /dev/null
+++ b/src/chart/resize/makeLegend/moveLegend.js
@@ -0,0 +1,28 @@
+// TODO: consider moving legend around DOM on layout rather than on resize
+export default function moveLegend(scale) {
+ const legend = this.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());
+ }
+ }
+
+ legend
+ .classed(`legend--${this.config.legend.location}`, true)
+ .classed('legend--empty', scale.domain().length === 0); // display: none when color_by is not set?
+
+ return legend;
+}
diff --git a/src/chart/resize/updateDataMarks/drawBars.js b/src/chart/resize/updateDataMarks/drawBars.js
index cf6fa73..67c0261 100644
--- a/src/chart/resize/updateDataMarks/drawBars.js
+++ b/src/chart/resize/updateDataMarks/drawBars.js
@@ -1,404 +1,52 @@
import { select, set, format, min, max } from 'd3';
+import xOrdinal from './drawBars/xOrdinal';
+import yOrdinal from './drawBars/yOrdinal';
+import xBin from './drawBars/xBin';
+import yBin from './drawBars/yBin';
export default function drawBars(marks) {
- let chart = this;
- let rawData = this.raw_data;
- let config = this.config;
+ const chart = this;
+ const rawData = this.raw_data;
+ const config = this.config;
- let bar_supergroups = this.svg
+ // bar super-groups
+ const bar_supergroups = this.svg
.selectAll('.bar-supergroup')
.data(marks, (d, i) => i + '-' + d.per.join('-'));
-
bar_supergroups
.enter()
.append('g')
.attr('class', d => 'supergroup bar-supergroup ' + d.id);
-
bar_supergroups.exit().remove();
- let bar_groups = bar_supergroups.selectAll('.bar-group').data(
+ // bar groups
+ const bar_groups = bar_supergroups.selectAll('.bar-group').data(
d => d.data,
d => d.key
);
- let old_bar_groups = bar_groups.exit();
+ const old_bar_groups = bar_groups.exit();
let nu_bar_groups;
let bars;
- let oldBarsTrans = config.transitions
+ // bar transitions
+ const oldBarsTrans = config.transitions
? old_bar_groups.selectAll('.bar').transition()
: old_bar_groups.selectAll('.bar');
- let oldBarGroupsTrans = config.transitions ? old_bar_groups.transition() : old_bar_groups;
+ const oldBarGroupsTrans = config.transitions ? old_bar_groups.transition() : old_bar_groups;
if (config.x.type === 'ordinal') {
- oldBarsTrans.attr('y', this.y(0)).attr('height', 0);
-
- oldBarGroupsTrans.remove();
-
- nu_bar_groups = bar_groups
- .enter()
- .append('g')
- .attr('class', d => 'bar-group ' + d.key);
- nu_bar_groups.append('title');
-
- bars = bar_groups.selectAll('rect').data(
- d => {
- return d.values instanceof Array
- ? d.values.sort(
- (a, b) =>
- this.colorScale.domain().indexOf(b.key) -
- this.colorScale.domain().indexOf(a.key)
- )
- : [d];
- },
- d => d.key
- );
-
- let exitBars = config.transitions ? bars.exit().transition() : bars.exit();
- exitBars
- .attr('y', this.y(0))
- .attr('height', 0)
- .remove();
- bars.enter()
- .append('rect')
- .attr('class', d => 'wc-data-mark bar ' + d.key)
- .style('clip-path', `url(#${chart.id})`)
- .attr('y', this.y(0))
- .attr('height', 0)
- .append('title');
-
- bars.attr('shape-rendering', 'crispEdges')
- .attr('stroke', d => this.colorScale(d.values.raw[0][config.color_by]))
- .attr('fill', d => this.colorScale(d.values.raw[0][config.color_by]));
-
- bars.each(function(d) {
- let mark = select(this.parentNode.parentNode).datum();
- d.tooltip = mark.tooltip;
- d.arrange = mark.split && mark.arrange ? mark.arrange : mark.split ? 'grouped' : null;
- d.subcats = config.legend.order
- ? config.legend.order.slice().reverse()
- : mark.values && mark.values[mark.split]
- ? mark.values[mark.split]
- : set(rawData.map(m => m[mark.split])).values();
- select(this).attr(mark.attributes);
- });
-
- let xformat =
- config.marks.map(m => m.summarizeX === 'percent').indexOf(true) > -1
- ? format('0%')
- : format(config.x.format);
- let yformat =
- config.marks.map(m => m.summarizeY === 'percent').indexOf(true) > -1
- ? format('0%')
- : format(config.y.format);
- bars.select('title').text(d => {
- let tt = d.tooltip || '';
- return tt
- .replace(/\$x/g, xformat(d.values.x))
- .replace(/\$y/g, yformat(d.values.y))
- .replace(/\[(.+?)\]/g, (str, orig) => d.values.raw[0][orig]);
- });
-
- let barsTrans = config.transitions ? bars.transition() : bars;
- barsTrans
- .attr('x', d => {
- let position;
- if (!d.arrange || d.arrange === 'stacked') {
- return this.x(d.values.x);
- } else if (d.arrange === 'nested') {
- let position = d.subcats.indexOf(d.key);
- let offset = position
- ? this.x.rangeBand() / (d.subcats.length * 0.75) / position
- : this.x.rangeBand();
- return this.x(d.values.x) + (this.x.rangeBand() - offset) / 2;
- } else {
- position = d.subcats.indexOf(d.key);
- return this.x(d.values.x) + (this.x.rangeBand() / d.subcats.length) * position;
- }
- })
- .attr('y', d => {
- if (d.arrange !== 'stacked') {
- return this.y(d.values.y);
- } else {
- return this.y(d.values.start);
- }
- })
- .attr('width', d => {
- if (!d.arrange || d.arrange === 'stacked') {
- return this.x.rangeBand();
- } else if (d.arrange === 'nested') {
- let position = d.subcats.indexOf(d.key);
- return position
- ? this.x.rangeBand() / (d.subcats.length * 0.75) / position
- : this.x.rangeBand();
- } else {
- return this.x.rangeBand() / d.subcats.length;
- }
- })
- .attr('height', d => this.y(0) - this.y(d.values.y));
+ xOrdinal.call(this, oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars);
} else if (config.y.type === 'ordinal') {
- oldBarsTrans.attr('x', this.x(0)).attr('width', 0);
-
- oldBarGroupsTrans.remove();
-
- nu_bar_groups = bar_groups
- .enter()
- .append('g')
- .attr('class', d => 'bar-group ' + d.key);
- nu_bar_groups.append('title');
-
- bars = bar_groups.selectAll('rect').data(
- d => {
- return d.values instanceof Array
- ? d.values.sort(
- (a, b) =>
- this.colorScale.domain().indexOf(b.key) -
- this.colorScale.domain().indexOf(a.key)
- )
- : [d];
- },
- d => d.key
- );
-
- let exitBars = config.transitions ? bars.exit().transition() : bars.exit();
- exitBars
- .attr('x', this.x(0))
- .attr('width', 0)
- .remove();
- bars.enter()
- .append('rect')
- .attr('class', d => 'wc-data-mark bar ' + d.key)
- .style('clip-path', `url(#${chart.id})`)
- .attr('x', this.x(0))
- .attr('width', 0)
- .append('title');
-
- bars.attr('shape-rendering', 'crispEdges')
- .attr('stroke', d => this.colorScale(d.values.raw[0][config.color_by]))
- .attr('fill', d => this.colorScale(d.values.raw[0][config.color_by]));
-
- bars.each(function(d) {
- let mark = select(this.parentNode.parentNode).datum();
- d.arrange = mark.split && mark.arrange ? mark.arrange : mark.split ? 'grouped' : null;
- d.subcats = config.legend.order
- ? config.legend.order.slice().reverse()
- : mark.values && mark.values[mark.split]
- ? mark.values[mark.split]
- : set(rawData.map(m => m[mark.split])).values();
- d.tooltip = mark.tooltip;
- select(this).attr(mark.attributes);
- });
-
- let xformat =
- config.marks.map(m => m.summarizeX === 'percent').indexOf(true) > -1
- ? format('0%')
- : format(config.x.format);
- let yformat =
- config.marks.map(m => m.summarizeY === 'percent').indexOf(true) > -1
- ? format('0%')
- : format(config.y.format);
- bars.select('title').text(d => {
- let tt = d.tooltip || '';
- return tt
- .replace(/\$x/g, xformat(d.values.x))
- .replace(/\$y/g, yformat(d.values.y))
- .replace(/\[(.+?)\]/g, (str, orig) => d.values.raw[0][orig]);
- });
-
- let barsTrans = config.transitions ? bars.transition() : bars;
- barsTrans
- .attr('x', d => {
- if (d.arrange === 'stacked' || !d.arrange) {
- return d.values.start !== undefined ? this.x(d.values.start) : this.x(0);
- } else {
- return this.x(0);
- }
- })
- .attr('y', d => {
- if (d.arrange === 'nested') {
- let position = d.subcats.indexOf(d.key);
- let offset = position
- ? this.y.rangeBand() / (d.subcats.length * 0.75) / position
- : this.y.rangeBand();
- return this.y(d.values.y) + (this.y.rangeBand() - offset) / 2;
- } else if (d.arrange === 'grouped') {
- let position = d.subcats.indexOf(d.key);
- return this.y(d.values.y) + (this.y.rangeBand() / d.subcats.length) * position;
- } else {
- return this.y(d.values.y);
- }
- })
- .attr('width', d => this.x(d.values.x) - this.x(0))
- .attr('height', d => {
- if (config.y.type === 'quantile') {
- return 20;
- } else if (d.arrange === 'nested') {
- let position = d.subcats.indexOf(d.key);
- return position
- ? this.y.rangeBand() / (d.subcats.length * 0.75) / position
- : this.y.rangeBand();
- } else if (d.arrange === 'grouped') {
- return this.y.rangeBand() / d.subcats.length;
- } else {
- return this.y.rangeBand();
- }
- });
+ yOrdinal.call(this, oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars);
} else if (['linear', 'log'].indexOf(config.x.type) > -1 && config.x.bin) {
- oldBarsTrans.attr('y', this.y(0)).attr('height', 0);
-
- oldBarGroupsTrans.remove();
-
- nu_bar_groups = bar_groups
- .enter()
- .append('g')
- .attr('class', d => 'bar-group ' + d.key);
- nu_bar_groups.append('title');
-
- bars = bar_groups.selectAll('rect').data(
- d => (d.values instanceof Array ? d.values : [d]),
- d => d.key
- );
-
- let exitBars = config.transitions ? bars.exit().transition() : bars.exit();
- exitBars
- .attr('y', this.y(0))
- .attr('height', 0)
- .remove();
- bars.enter()
- .append('rect')
- .attr('class', d => 'wc-data-mark bar ' + d.key)
- .style('clip-path', `url(#${chart.id})`)
- .attr('y', this.y(0))
- .attr('height', 0)
- .append('title');
-
- bars.attr('shape-rendering', 'crispEdges')
- .attr('stroke', d => this.colorScale(d.values.raw[0][config.color_by]))
- .attr('fill', d => this.colorScale(d.values.raw[0][config.color_by]));
-
- bars.each(function(d) {
- let mark = select(this.parentNode.parentNode).datum();
- d.arrange = mark.split ? mark.arrange : null;
- d.subcats = config.legend.order
- ? config.legend.order.slice().reverse()
- : mark.values && mark.values[mark.split]
- ? mark.values[mark.split]
- : set(rawData.map(m => m[mark.split])).values();
- select(this).attr(mark.attributes);
- let parent = select(this.parentNode).datum();
- let rangeSet = parent.key.split(',').map(m => +m);
- d.rangeLow = min(rangeSet);
- d.rangeHigh = max(rangeSet);
- d.tooltip = mark.tooltip;
- });
-
- let xformat =
- config.marks.map(m => m.summarizeX === 'percent').indexOf(true) > -1
- ? format('0%')
- : format(config.x.format);
- let yformat =
- config.marks.map(m => m.summarizeY === 'percent').indexOf(true) > -1
- ? format('0%')
- : format(config.y.format);
- bars.select('title').text(d => {
- let tt = d.tooltip || '';
- return tt
- .replace(/\$x/g, xformat(d.values.x))
- .replace(/\$y/g, yformat(d.values.y))
- .replace(/\[(.+?)\]/g, (str, orig) => d.values.raw[0][orig]);
- });
-
- let barsTrans = config.transitions ? bars.transition() : bars;
- barsTrans
- .attr('x', d => this.x(d.rangeLow))
- .attr('y', d => {
- if (d.arrange !== 'stacked') {
- return this.y(d.values.y);
- } else {
- return this.y(d.values.start);
- }
- })
- .attr('width', d => this.x(d.rangeHigh) - this.x(d.rangeLow))
- .attr('height', d => this.y(0) - this.y(d.values.y));
+ xBin.call(this, oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars);
} else if (
['linear', 'log'].indexOf(config.y.type) > -1 &&
config.y.type === 'linear' &&
config.y.bin
) {
- oldBarsTrans.attr('x', this.x(0)).attr('width', 0);
- oldBarGroupsTrans.remove();
-
- nu_bar_groups = bar_groups
- .enter()
- .append('g')
- .attr('class', d => 'bar-group ' + d.key);
- nu_bar_groups.append('title');
-
- bars = bar_groups.selectAll('rect').data(
- d => (d.values instanceof Array ? d.values : [d]),
- d => d.key
- );
-
- let exitBars = config.transitions ? bars.exit().transition() : bars.exit();
- exitBars
- .attr('x', this.x(0))
- .attr('width', 0)
- .remove();
- bars.enter()
- .append('rect')
- .attr('class', d => 'wc-data-mark bar ' + d.key)
- .style('clip-path', `url(#${chart.id})`)
- .attr('x', this.x(0))
- .attr('width', 0)
- .append('title');
-
- bars.attr('shape-rendering', 'crispEdges')
- .attr('stroke', d => this.colorScale(d.values.raw[0][config.color_by]))
- .attr('fill', d => this.colorScale(d.values.raw[0][config.color_by]));
-
- bars.each(function(d) {
- let mark = select(this.parentNode.parentNode).datum();
- d.arrange = mark.split ? mark.arrange : null;
- d.subcats = config.legend.order
- ? config.legend.order.slice().reverse()
- : mark.values && mark.values[mark.split]
- ? mark.values[mark.split]
- : set(rawData.map(m => m[mark.split])).values();
- let parent = select(this.parentNode).datum();
- let rangeSet = parent.key.split(',').map(m => +m);
- d.rangeLow = min(rangeSet);
- d.rangeHigh = max(rangeSet);
- d.tooltip = mark.tooltip;
- });
-
- let xformat =
- config.marks.map(m => m.summarizeX === 'percent').indexOf(true) > -1
- ? format('0%')
- : format(config.x.format);
- let yformat =
- config.marks.map(m => m.summarizeY === 'percent').indexOf(true) > -1
- ? format('0%')
- : format(config.y.format);
- bars.select('title').text(d => {
- let tt = d.tooltip || '';
- return tt
- .replace(/\$x/g, xformat(d.values.x))
- .replace(/\$y/g, yformat(d.values.y))
- .replace(/\[(.+?)\]/g, (str, orig) => d.values.raw[0][orig]);
- });
-
- let barsTrans = config.transitions ? bars.transition() : bars;
- barsTrans
- .attr('x', d => {
- if (d.arrange === 'stacked') {
- return this.x(d.values.start);
- } else {
- return this.x(0);
- }
- })
- .attr('y', d => this.y(d.rangeHigh))
- .attr('width', d => this.x(d.values.x))
- .attr('height', d => this.y(d.rangeLow) - this.y(d.rangeHigh));
+ yBin.call(this, oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars);
} else {
oldBarsTrans.attr('y', this.y(0)).attr('height', 0);
oldBarGroupsTrans.remove();
diff --git a/src/chart/resize/updateDataMarks/drawBars/xBin.js b/src/chart/resize/updateDataMarks/drawBars/xBin.js
new file mode 100644
index 0000000..f03c30e
--- /dev/null
+++ b/src/chart/resize/updateDataMarks/drawBars/xBin.js
@@ -0,0 +1,84 @@
+import { select, set, format, min, max } from 'd3';
+
+export default function xBin(oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars) {
+ const chart = this;
+ const rawData = this.raw_data;
+ const config = this.config;
+
+ oldBarsTrans.attr('y', this.y(0)).attr('height', 0);
+
+ oldBarGroupsTrans.remove();
+
+ nu_bar_groups = bar_groups
+ .enter()
+ .append('g')
+ .attr('class', d => 'bar-group ' + d.key);
+ nu_bar_groups.append('title');
+
+ bars = bar_groups.selectAll('rect').data(
+ d => (d.values instanceof Array ? d.values : [d]),
+ d => d.key
+ );
+
+ let exitBars = config.transitions ? bars.exit().transition() : bars.exit();
+ exitBars
+ .attr('y', this.y(0))
+ .attr('height', 0)
+ .remove();
+ bars.enter()
+ .append('rect')
+ .attr('class', d => 'wc-data-mark bar ' + d.key)
+ .style('clip-path', `url(#${chart.id})`)
+ .attr('y', this.y(0))
+ .attr('height', 0)
+ .append('title');
+
+ bars.attr('shape-rendering', 'crispEdges')
+ .attr('stroke', d => this.colorScale(d.values.raw[0][config.color_by]))
+ .attr('fill', d => this.colorScale(d.values.raw[0][config.color_by]));
+
+ bars.each(function(d) {
+ let mark = select(this.parentNode.parentNode).datum();
+ d.arrange = mark.split ? mark.arrange : null;
+ d.subcats = config.legend.order
+ ? config.legend.order.slice().reverse()
+ : mark.values && mark.values[mark.split]
+ ? mark.values[mark.split]
+ : set(rawData.map(m => m[mark.split])).values();
+ select(this).attr(mark.attributes);
+ let parent = select(this.parentNode).datum();
+ let rangeSet = parent.key.split(',').map(m => +m);
+ d.rangeLow = min(rangeSet);
+ d.rangeHigh = max(rangeSet);
+ d.tooltip = mark.tooltip;
+ });
+
+ let xformat =
+ config.marks.map(m => m.summarizeX === 'percent').indexOf(true) > -1
+ ? format('0%')
+ : format(config.x.format);
+ let yformat =
+ config.marks.map(m => m.summarizeY === 'percent').indexOf(true) > -1
+ ? format('0%')
+ : format(config.y.format);
+ bars.select('title').text(d => {
+ let tt = d.tooltip || '';
+ return tt
+ .replace(/\$x/g, xformat(d.values.x))
+ .replace(/\$y/g, yformat(d.values.y))
+ .replace(/\[(.+?)\]/g, (str, orig) => d.values.raw[0][orig]);
+ });
+
+ let barsTrans = config.transitions ? bars.transition() : bars;
+ barsTrans
+ .attr('x', d => this.x(d.rangeLow))
+ .attr('y', d => {
+ if (d.arrange !== 'stacked') {
+ return this.y(d.values.y);
+ } else {
+ return this.y(d.values.start);
+ }
+ })
+ .attr('width', d => this.x(d.rangeHigh) - this.x(d.rangeLow))
+ .attr('height', d => this.y(0) - this.y(d.values.y));
+}
diff --git a/src/chart/resize/updateDataMarks/drawBars/xOrdinal.js b/src/chart/resize/updateDataMarks/drawBars/xOrdinal.js
new file mode 100644
index 0000000..a1796a1
--- /dev/null
+++ b/src/chart/resize/updateDataMarks/drawBars/xOrdinal.js
@@ -0,0 +1,121 @@
+import { select, set, format } from 'd3';
+
+// TODO: merge xOrdinal and yOrdinal into a single function
+export default function xOrdinal(oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars) {
+ const chart = this;
+ const rawData = this.raw_data;
+ const config = this.config;
+
+ oldBarsTrans.attr('y', this.y(0)).attr('height', 0);
+
+ oldBarGroupsTrans.remove();
+
+ nu_bar_groups = bar_groups
+ .enter()
+ .append('g')
+ .attr('class', d => 'bar-group ' + d.key);
+ nu_bar_groups.append('title');
+
+ bars = bar_groups.selectAll('rect').data(
+ d => {
+ return d.values instanceof Array
+ ? d.values.sort(
+ (a, b) =>
+ this.colorScale.domain().indexOf(a.key) -
+ this.colorScale.domain().indexOf(b.key)
+ ) // controls the order of the bars in the DOM
+ : [d];
+ },
+ d => d.key
+ );
+
+ let exitBars = config.transitions ? bars.exit().transition() : bars.exit();
+ exitBars
+ .attr('y', this.y(0))
+ .attr('height', 0)
+ .remove();
+ bars.enter()
+ .append('rect')
+ .attr('class', d => 'wc-data-mark bar ' + d.key)
+ .style('clip-path', `url(#${chart.id})`)
+ .attr('y', this.y(0))
+ .attr('height', 0)
+ .append('title');
+
+ // sort bars in DOM to display widest bar behind every other bar and narrowest bar in front of every other bar - that's poorly worded but you get the gist
+ bars.sort(
+ (a, b) => this.colorScale.domain().indexOf(a.key) - this.colorScale.domain().indexOf(b.key)
+ );
+
+ bars.attr('shape-rendering', 'crispEdges')
+ .attr('stroke', d => this.colorScale(d.values.raw[0][config.color_by]))
+ .attr('fill', d => this.colorScale(d.values.raw[0][config.color_by]));
+
+ bars.each(function(d) {
+ let mark = select(this.parentNode.parentNode).datum();
+ d.tooltip = mark.tooltip;
+ d.arrange = mark.split && mark.arrange ? mark.arrange : mark.split ? 'grouped' : null;
+ d.subcats = config.legend.order
+ ? config.legend.order.slice()
+ : mark.values && mark.values[mark.split]
+ ? mark.values[mark.split]
+ : set(rawData.map(m => m[mark.split]))
+ .values()
+ .sort(); // controls the order of the bars in the chart
+ select(this).attr(mark.attributes);
+ });
+
+ let xformat =
+ config.marks.map(m => m.summarizeX === 'percent').indexOf(true) > -1
+ ? format('0%')
+ : format(config.x.format);
+ let yformat =
+ config.marks.map(m => m.summarizeY === 'percent').indexOf(true) > -1
+ ? format('0%')
+ : format(config.y.format);
+ bars.select('title').text(d => {
+ let tt = d.tooltip || '';
+ return tt
+ .replace(/\$x/g, xformat(d.values.x))
+ .replace(/\$y/g, yformat(d.values.y))
+ .replace(/\[(.+?)\]/g, (str, orig) => d.values.raw[0][orig]);
+ });
+
+ let barsTrans = config.transitions ? bars.transition() : bars;
+ barsTrans
+ .attr('x', d => {
+ let position;
+ if (!d.arrange || d.arrange === 'stacked') {
+ return this.x(d.values.x);
+ } else if (d.arrange === 'nested') {
+ let position = d.subcats.indexOf(d.key);
+ let offset = position
+ ? this.x.rangeBand() / (d.subcats.length * 0.75) / position
+ : this.x.rangeBand();
+ return this.x(d.values.x) + (this.x.rangeBand() - offset) / 2;
+ } else {
+ position = d.subcats.indexOf(d.key);
+ return this.x(d.values.x) + (this.x.rangeBand() / d.subcats.length) * position;
+ }
+ })
+ .attr('y', d => {
+ if (d.arrange !== 'stacked') {
+ return this.y(d.values.y);
+ } else {
+ return this.y(d.values.start);
+ }
+ })
+ .attr('width', d => {
+ if (!d.arrange || d.arrange === 'stacked') {
+ return this.x.rangeBand();
+ } else if (d.arrange === 'nested') {
+ let position = d.subcats.indexOf(d.key);
+ return position
+ ? this.x.rangeBand() / (d.subcats.length * 0.75) / position
+ : this.x.rangeBand();
+ } else {
+ return this.x.rangeBand() / d.subcats.length;
+ }
+ })
+ .attr('height', d => this.y(0) - this.y(d.values.y));
+}
diff --git a/src/chart/resize/updateDataMarks/drawBars/yBin.js b/src/chart/resize/updateDataMarks/drawBars/yBin.js
new file mode 100644
index 0000000..f79394b
--- /dev/null
+++ b/src/chart/resize/updateDataMarks/drawBars/yBin.js
@@ -0,0 +1,82 @@
+import { select, set, format, min, max } from 'd3';
+
+export default function yBin(oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars) {
+ const chart = this;
+ const rawData = this.raw_data;
+ const config = this.config;
+
+ oldBarsTrans.attr('x', this.x(0)).attr('width', 0);
+ oldBarGroupsTrans.remove();
+
+ nu_bar_groups = bar_groups
+ .enter()
+ .append('g')
+ .attr('class', d => 'bar-group ' + d.key);
+ nu_bar_groups.append('title');
+
+ bars = bar_groups.selectAll('rect').data(
+ d => (d.values instanceof Array ? d.values : [d]),
+ d => d.key
+ );
+
+ let exitBars = config.transitions ? bars.exit().transition() : bars.exit();
+ exitBars
+ .attr('x', this.x(0))
+ .attr('width', 0)
+ .remove();
+ bars.enter()
+ .append('rect')
+ .attr('class', d => 'wc-data-mark bar ' + d.key)
+ .style('clip-path', `url(#${chart.id})`)
+ .attr('x', this.x(0))
+ .attr('width', 0)
+ .append('title');
+
+ bars.attr('shape-rendering', 'crispEdges')
+ .attr('stroke', d => this.colorScale(d.values.raw[0][config.color_by]))
+ .attr('fill', d => this.colorScale(d.values.raw[0][config.color_by]));
+
+ bars.each(function(d) {
+ let mark = select(this.parentNode.parentNode).datum();
+ d.arrange = mark.split ? mark.arrange : null;
+ d.subcats = config.legend.order
+ ? config.legend.order.slice().reverse()
+ : mark.values && mark.values[mark.split]
+ ? mark.values[mark.split]
+ : set(rawData.map(m => m[mark.split])).values();
+ let parent = select(this.parentNode).datum();
+ let rangeSet = parent.key.split(',').map(m => +m);
+ d.rangeLow = min(rangeSet);
+ d.rangeHigh = max(rangeSet);
+ d.tooltip = mark.tooltip;
+ });
+
+ let xformat =
+ config.marks.map(m => m.summarizeX === 'percent').indexOf(true) > -1
+ ? format('0%')
+ : format(config.x.format);
+ let yformat =
+ config.marks.map(m => m.summarizeY === 'percent').indexOf(true) > -1
+ ? format('0%')
+ : format(config.y.format);
+ bars.select('title').text(d => {
+ let tt = d.tooltip || '';
+ return tt
+ .replace(/\$x/g, xformat(d.values.x))
+ .replace(/\$y/g, yformat(d.values.y))
+ .replace(/\[(.+?)\]/g, (str, orig) => d.values.raw[0][orig]);
+ });
+
+ let barsTrans = config.transitions ? bars.transition() : bars;
+ barsTrans
+ .attr('x', d => {
+ if (d.arrange === 'stacked') {
+ return this.x(d.values.start);
+ } else {
+ return this.x(0);
+ }
+ })
+ .attr('y', d => this.y(d.rangeHigh))
+ .attr('width', d => this.x(d.values.x))
+ .attr('height', d => this.y(d.rangeLow) - this.y(d.rangeHigh));
+}
diff --git a/src/chart/resize/updateDataMarks/drawBars/yOrdinal.js b/src/chart/resize/updateDataMarks/drawBars/yOrdinal.js
new file mode 100644
index 0000000..c9c543c
--- /dev/null
+++ b/src/chart/resize/updateDataMarks/drawBars/yOrdinal.js
@@ -0,0 +1,122 @@
+import { select, set, format } from 'd3';
+
+// TODO: merge yOrdinal and xOrdinal into a single function
+export default function yOrdinal(oldBarsTrans, oldBarGroupsTrans, nu_bar_groups, bar_groups, bars) {
+ const chart = this;
+ const rawData = this.raw_data;
+ const config = this.config;
+
+ oldBarsTrans.attr('x', this.x(0)).attr('width', 0);
+
+ oldBarGroupsTrans.remove();
+
+ nu_bar_groups = bar_groups
+ .enter()
+ .append('g')
+ .attr('class', d => 'bar-group ' + d.key);
+ nu_bar_groups.append('title');
+
+ bars = bar_groups.selectAll('rect').data(
+ d => {
+ return d.values instanceof Array
+ ? d.values.sort(
+ (a, b) =>
+ this.colorScale.domain().indexOf(a.key) -
+ this.colorScale.domain().indexOf(b.key)
+ ) // controls the order of the bars in the DOM
+ : [d];
+ },
+ d => d.key
+ );
+
+ let exitBars = config.transitions ? bars.exit().transition() : bars.exit();
+ exitBars
+ .attr('x', this.x(0))
+ .attr('width', 0)
+ .remove();
+ bars.enter()
+ .append('rect')
+ .attr('class', d => 'wc-data-mark bar ' + d.key)
+ .style('clip-path', `url(#${chart.id})`)
+ .attr('x', this.x(0))
+ .attr('width', 0)
+ .append('title');
+
+ // sort bars in DOM to display widest bar behind every other bar and narrowest bar in front of every other bar - that's poorly worded but you get the gist
+ bars.sort(
+ (a, b) => this.colorScale.domain().indexOf(a.key) - this.colorScale.domain().indexOf(b.key)
+ );
+
+ bars.attr('shape-rendering', 'crispEdges')
+ .attr('stroke', d => this.colorScale(d.values.raw[0][config.color_by]))
+ .attr('fill', d => this.colorScale(d.values.raw[0][config.color_by]));
+
+ bars.each(function(d) {
+ let mark = select(this.parentNode.parentNode).datum();
+ d.tooltip = mark.tooltip;
+ d.arrange = mark.split && mark.arrange ? mark.arrange : mark.split ? 'grouped' : null;
+ d.subcats = config.legend.order
+ ? config.legend.order.slice()
+ : mark.values && mark.values[mark.split]
+ ? mark.values[mark.split]
+ : set(rawData.map(m => m[mark.split]))
+ .values()
+ .sort(); // controls the order of the bars in the chart
+ select(this).attr(mark.attributes);
+ });
+
+ let xformat =
+ config.marks.map(m => m.summarizeX === 'percent').indexOf(true) > -1
+ ? format('0%')
+ : format(config.x.format);
+ let yformat =
+ config.marks.map(m => m.summarizeY === 'percent').indexOf(true) > -1
+ ? format('0%')
+ : format(config.y.format);
+ bars.select('title').text(d => {
+ let tt = d.tooltip || '';
+ return tt
+ .replace(/\$x/g, xformat(d.values.x))
+ .replace(/\$y/g, yformat(d.values.y))
+ .replace(/\[(.+?)\]/g, (str, orig) => d.values.raw[0][orig]);
+ });
+
+ let barsTrans = config.transitions ? bars.transition() : bars;
+ barsTrans
+ .attr('x', d => {
+ if (d.arrange === 'stacked' || !d.arrange) {
+ return d.values.start !== undefined ? this.x(d.values.start) : this.x(0);
+ } else {
+ return this.x(0);
+ }
+ })
+ .attr('y', d => {
+ if (d.arrange === 'nested') {
+ let position = d.subcats.indexOf(d.key);
+ let offset = position
+ ? this.y.rangeBand() / (d.subcats.length * 0.75) / position
+ : this.y.rangeBand();
+ return this.y(d.values.y) + (this.y.rangeBand() - offset) / 2;
+ } else if (d.arrange === 'grouped') {
+ let position = d.subcats.indexOf(d.key);
+ return this.y(d.values.y) + (this.y.rangeBand() / d.subcats.length) * position;
+ } else {
+ return this.y(d.values.y);
+ }
+ })
+ .attr('width', d => this.x(d.values.x) - this.x(0))
+ .attr('height', d => {
+ if (config.y.type === 'quantile') {
+ return 20;
+ } else if (d.arrange === 'nested') {
+ let position = d.subcats.indexOf(d.key);
+ return position
+ ? this.y.rangeBand() / (d.subcats.length * 0.75) / position
+ : this.y.rangeBand();
+ } else if (d.arrange === 'grouped') {
+ return this.y.rangeBand() / d.subcats.length;
+ } else {
+ return this.y.rangeBand();
+ }
+ });
+}
diff --git a/src/chart/resize/updateDataMarks/drawPoints.js b/src/chart/resize/updateDataMarks/drawPoints.js
index 8a16650..cc8a96d 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,8 @@ 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 +58,8 @@ 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 +100,29 @@ 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
+ 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
+ .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..37611cd 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
);
@@ -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()
@@ -85,11 +87,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 its data
+ text_supergroups.each(function(d) {
d.supergroup = select(this);
d.groups = d.supergroup.selectAll('g.text');
d.texts = d.groups.select('text');
});
+
return texts;
}
diff --git a/src/controls/index.js b/src/controls/index.js
index 51b2872..35d2034 100644
--- a/src/controls/index.js
+++ b/src/controls/index.js
@@ -5,14 +5,14 @@ import destroy from './destroy';
import init from './init';
import layout from './layout';
import makeControlItem from './makeControlItem';
-import makeBtnGroupControl from './makeBtnGroupControl';
-import makeCheckboxControl from './makeCheckboxControl';
-import makeDropdownControl from './makeDropdownControl';
-import makeListControl from './makeListControl';
-import makeNumberControl from './makeNumberControl';
-import makeRadioControl from './makeRadioControl';
-import makeSubsetterControl from './makeSubsetterControl';
-import makeTextControl from './makeTextControl';
+import makeBtnGroupControl from './makeControlItem/makeBtnGroupControl';
+import makeCheckboxControl from './makeControlItem/makeCheckboxControl';
+import makeDropdownControl from './makeControlItem/makeDropdownControl';
+import makeListControl from './makeControlItem/makeListControl';
+import makeNumberControl from './makeControlItem/makeNumberControl';
+import makeRadioControl from './makeControlItem/makeRadioControl';
+import makeSubsetterControl from './makeControlItem/makeSubsetterControl';
+import makeTextControl from './makeControlItem/makeTextControl';
import stringAccessor from './stringAccessor';
export default {
diff --git a/src/controls/makeBtnGroupControl.js b/src/controls/makeControlItem/makeBtnGroupControl.js
similarity index 100%
rename from src/controls/makeBtnGroupControl.js
rename to src/controls/makeControlItem/makeBtnGroupControl.js
diff --git a/src/controls/makeCheckboxControl.js b/src/controls/makeControlItem/makeCheckboxControl.js
similarity index 100%
rename from src/controls/makeCheckboxControl.js
rename to src/controls/makeControlItem/makeCheckboxControl.js
diff --git a/src/controls/makeDropdownControl.js b/src/controls/makeControlItem/makeDropdownControl.js
similarity index 100%
rename from src/controls/makeDropdownControl.js
rename to src/controls/makeControlItem/makeDropdownControl.js
diff --git a/src/controls/makeListControl.js b/src/controls/makeControlItem/makeListControl.js
similarity index 100%
rename from src/controls/makeListControl.js
rename to src/controls/makeControlItem/makeListControl.js
diff --git a/src/controls/makeNumberControl.js b/src/controls/makeControlItem/makeNumberControl.js
similarity index 100%
rename from src/controls/makeNumberControl.js
rename to src/controls/makeControlItem/makeNumberControl.js
diff --git a/src/controls/makeRadioControl.js b/src/controls/makeControlItem/makeRadioControl.js
similarity index 100%
rename from src/controls/makeRadioControl.js
rename to src/controls/makeControlItem/makeRadioControl.js
diff --git a/src/controls/makeSubsetterControl.js b/src/controls/makeControlItem/makeSubsetterControl.js
similarity index 96%
rename from src/controls/makeSubsetterControl.js
rename to src/controls/makeControlItem/makeSubsetterControl.js
index 1bcc046..70ab52b 100644
--- a/src/controls/makeSubsetterControl.js
+++ b/src/controls/makeControlItem/makeSubsetterControl.js
@@ -1,4 +1,4 @@
-import naturalSorter from '../dataOps/naturalSorter';
+import naturalSorter from '../../dataOps/naturalSorter';
import { set, select } from 'd3';
export default function makeSubsetterControl(control, control_wrap) {
@@ -14,7 +14,7 @@ export default function makeSubsetterControl(control, control_wrap) {
//dropdown option data
const option_data = control.values
? control.values
- : set(this.data.map(m => m[control.value_col]).filter(f => f))
+ : set(this.data.map(m => m[control.value_col])) //.filter(f => f))
.values()
.sort(naturalSorter); // only sort when values are derived
diff --git a/src/controls/makeTextControl.js b/src/controls/makeControlItem/makeTextControl.js
similarity index 100%
rename from src/controls/makeTextControl.js
rename to src/controls/makeControlItem/makeTextControl.js
diff --git a/src/createTable.js b/src/createTable.js
index fe2bf5a..a63474a 100644
--- a/src/createTable.js
+++ b/src/createTable.js
@@ -1,6 +1,8 @@
import table from './table/index';
import { select } from 'd3';
+export var tableCount = 0;
+
export default function createTable(element = 'body', config = {}, controls = null) {
let thisTable = Object.create(table);
@@ -36,5 +38,10 @@ export default function createTable(element = 'body', config = {}, controls = nu
}
};
+ //increment thisChart count to get unique thisChart id
+ tableCount++;
+
+ thisTable.id = tableCount;
+
return thisTable;
}
diff --git a/src/table/draw/applyFilters.js b/src/table/draw/applyFilters.js
index 7104fd5..2c20776 100644
--- a/src/table/draw/applyFilters.js
+++ b/src/table/draw/applyFilters.js
@@ -9,7 +9,7 @@ export default function applyFilters() {
(Array.isArray(filter.val) && filter.val.length < filter.choices.length)
)
) {
- this.data.filtered = this.data.raw;
+ this.data.filtered = this.data.raw.slice();
this.filters
.filter(
filter =>
@@ -24,5 +24,5 @@ export default function applyFilters() {
: filter.val === d[filter.col]
);
});
- } else this.data.filtered = this.data.raw;
+ } else this.data.filtered = this.data.raw.slice();
}
diff --git a/src/table/exportable/exports/xlsx.js b/src/table/exportable/exports/xlsx.js
index 11cccb8..9a17042 100644
--- a/src/table/exportable/exports/xlsx.js
+++ b/src/table/exportable/exports/xlsx.js
@@ -8,10 +8,12 @@ export default function xlsx(data) {
bookSST: true,
type: 'binary'
};
- const arrayOfArrays = data.map(d =>
- Object.keys(d)
- .filter(key => this.config.cols.indexOf(key) > -1)
- .map(key => d[key])
+ const arrayOfArrays = data.map(
+ d => this.config.cols.map(col => d[col])
+ //Object.keys(d)
+ // .filter(key => this.config.cols.indexOf(key) > -1)
+ // .sort((a,b) => this.config.cols.indexOf(a) - this.config.cols.indexOf(b))
+ // .map(key => d[key])
); // convert data from array of objects to array of arrays.
const workbook = {
SheetNames: [sheetName],
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..5655a70 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 (
+ (item.direction === 'ascending' && aCell < bCell) ||
+ (item.direction === 'descending' && aCell > bCell)
+ )
+ order = -1;
+ else if (
+ (item.direction === 'ascending' && aCell > bCell) ||
+ (item.direction === 'descending' && aCell < bCell)
+ )
+ order = 1;
+ }
}
});
diff --git a/test-page/arranged-bar-chart.css b/test-page/arranged-bar-chart.css
new file mode 100644
index 0000000..8bad0b7
--- /dev/null
+++ b/test-page/arranged-bar-chart.css
@@ -0,0 +1,10 @@
+#container {
+ display: flex;
+ justify-content: space-between;
+}
+.bar-chart {
+ width: 49%;
+}
+.randomize-bar-order {
+ float: right;
+}
diff --git a/test-page/arranged-bar-chart.js b/test-page/arranged-bar-chart.js
new file mode 100644
index 0000000..6368013
--- /dev/null
+++ b/test-page/arranged-bar-chart.js
@@ -0,0 +1,47 @@
+const settings = function(arrange) {
+ return {
+ ordinal: {
+ type: 'ordinal',
+ column: 'AEREL',
+ label: 'Relationship',
+ },
+ linear: {
+ type: 'linear',
+ column: null,
+ label: '# of Adverse Events',
+ },
+ marks: [
+ {
+ type: 'bar',
+ per: ['AEREL'],
+ summarizeX: 'count',
+ summarizeY: 'count',
+ tooltip: null,
+ split: 'AESEV',
+ arrange: arrange,
+ },
+ ],
+ color_by: 'AESEV',
+ legend: {
+ label: 'Severity',
+ order: ['MILD', 'MODERATE', 'SEVERE'],
+ },
+ resizable: false,
+ aspect: 2,
+ };
+};
+
+const onLayout = function() {
+ this.wrap.select('.legend')
+ .append('button')
+ .classed('randomize-bar-order', true)
+ .text('Randomize Bar Order')
+ .on('click', () => {
+ let randomOrder = this.colorScale.domain().sort(() => Math.random() < .5 ? -1 : 1);
+ while (this.config.legend.order.join('|') === randomOrder.join('|')) {
+ randomOrder = this.colorScale.domain().sort(() => Math.random() < .5 ? -1 : 1)
+ }
+ this.config.legend.order = randomOrder;
+ this.draw();
+ });
+};
diff --git a/test-page/createChart/index.js b/test-page/createChart/index.js
index 1eeb793..cb57e75 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: [
{
@@ -21,8 +23,6 @@ const settings = {
color_by: 'species',
legend: {
label: 'Species',
- mark: 'circle',
- location: 'bottom',
},
aspect: 3,
};
@@ -37,16 +37,24 @@ const controls = new webCharts.createControls(
label: 'Species',
},
{
- type: 'radio',
+ type: 'number',
option: 'x.domain.0',
label: 'X-domain Lower Limit',
- values: ['minimum',0],
},
{
- type: 'radio',
+ type: 'number',
+ option: 'x.domain.1',
+ label: 'X-domain Upper Limit',
+ },
+ {
+ type: 'number',
option: 'y.domain.0',
label: 'Y-domain Lower Limit',
- values: ['minimum',0],
+ },
+ {
+ type: 'number',
+ option: 'y.domain.1',
+ label: 'Y-domain Upper Limit',
},
],
},
@@ -65,6 +73,14 @@ d3.csv(
return d;
},
function(data) {
+ chart.config.x.domain = d3.extent(data, d => +d[chart.config.x.column]);
+ chart.config.y.domain = d3.extent(data, d => +d[chart.config.y.column]);
+ chart.on('layout', function() {
+ this.controls.wrap
+ .selectAll('.control-group input')
+ .filter(d => d.type === 'number')
+ .attr('step', .1);
+ });
chart.init(data);
}
);
diff --git a/test-page/createTable/index.js b/test-page/createTable/index.js
index 2ccf69e..d6d2de9 100644
--- a/test-page/createTable/index.js
+++ b/test-page/createTable/index.js
@@ -1,10 +1,10 @@
function createTable(element, settings) {
- var controls = webCharts.createControls(
+ const controls = webCharts.createControls(
element,
{
inputs: [
{type: 'subsetter', value_col: 'Period', label: 'Filter by Period'},
- {type: 'subsetter', value_col: 'Group', label: 'Filter by Group'}
+ {type: 'subsetter', value_col: 'Group', label: 'Filter by Group'},
]
}
);
@@ -12,7 +12,7 @@ function createTable(element, settings) {
return webCharts.createTable(element, settings, controls);
}
-var table = createTable(
+const table = createTable(
'.table',
{
'sortable': true,
@@ -27,17 +27,36 @@ var table = createTable(
);
d3.csv(
- 'https://cdn.jsdelivr.net/gh/RhoInc/data-library/data/miscellaneous/elements.csv',
+ 'https://raw.githubusercontent.com/RhoInc/data-library/master/data/miscellaneous/elements.csv',
function(d) {
return d;
},
function(data) {
+ table.config.types = Object.keys(data[0])
+ .map(col => {
+ let type = 'string';
+
+ const vector = data
+ .map(d => d[col]).filter(d => d !== '');
+
+ if (vector.length > 0 && vector.every(d => !isNaN(parseFloat(d))))
+ type = 'number';
+
+ return [col, type];
+ })
+ .reduce(
+ (acc,cur) => {
+ acc[cur[0]] = cur[1];
+ return acc;
+ },
+ {}
+ );
table.init(data);
//Update settings.
d3.selectAll('.controls input')
.on('change',function(){
- var settings = {
+ const settings = {
sortable: d3.select('input.sortable').property('checked'),
searchable: d3.select('input.searchable').property('checked'),
nRowsPerPage: +d3.select('input.items').node().value,
@@ -47,10 +66,8 @@ d3.csv(
applyCSS: d3.select('input.applyCSS').property('checked'),
};
- console.log(settings);
-
d3.select('.table').selectAll('*').remove()
- var table = createTable(
+ const table = createTable(
'.table',
settings
);
@@ -62,21 +79,20 @@ 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) {
return Math.random() >= .5;
});
table.config.headers = table.config.cols;
- console.log(table.config.cols);
table.draw();
});
//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 = [];
@@ -91,6 +107,5 @@ d3.select('button.randomize-headers')
return strArr.join('');
});
- console.log(table.config.headers);
table.draw();
});
diff --git a/test-page/groupedBarChart/index.html b/test-page/groupedBarChart/index.html
new file mode 100644
index 0000000..13aeddf
--- /dev/null
+++ b/test-page/groupedBarChart/index.html
@@ -0,0 +1,27 @@
+
+
+
+ Webcharts - Grouped Bar Chart
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Webcharts
+ Grouped Bar Chart
+
+
+
+
+
diff --git a/test-page/groupedBarChart/index.js b/test-page/groupedBarChart/index.js
new file mode 100644
index 0000000..3651961
--- /dev/null
+++ b/test-page/groupedBarChart/index.js
@@ -0,0 +1,33 @@
+hSettings = JSON.parse(JSON.stringify(settings('grouped')));
+hSettings.x = hSettings.ordinal;
+hSettings.y = hSettings.linear;
+hSettings.marks[0].tooltip = '$x: $y';
+
+const hChart = new webCharts.createChart(
+ '.bar-chart--horizontal',
+ hSettings,
+);
+
+vSettings = JSON.parse(JSON.stringify(settings('grouped')));
+vSettings.x = vSettings.linear;
+vSettings.y = vSettings.ordinal;
+hSettings.marks[0].tooltip = '$y: $x';
+
+const vChart = new webCharts.createChart(
+ '.bar-chart--vertical',
+ vSettings,
+);
+
+d3.csv(
+ 'https://raw.githubusercontent.com/RhoInc/data-library/master/data/clinical-trials/sdtm/ae.csv',
+ function(d,i) {
+ d.seq = i;
+ return d;
+ },
+ function(data) {
+ hChart.on('layout', onLayout);
+ hChart.init(data);
+ vChart.on('layout', onLayout);
+ vChart.init(data);
+ }
+);
diff --git a/test-page/nestedBarChart/index.html b/test-page/nestedBarChart/index.html
new file mode 100644
index 0000000..bbf4f5e
--- /dev/null
+++ b/test-page/nestedBarChart/index.html
@@ -0,0 +1,27 @@
+
+
+
+ Webcharts - Nested Bar Chart
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Webcharts
+ Nested Bar Chart
+
+
+
+
+
diff --git a/test-page/nestedBarChart/index.js b/test-page/nestedBarChart/index.js
new file mode 100644
index 0000000..29ac872
--- /dev/null
+++ b/test-page/nestedBarChart/index.js
@@ -0,0 +1,33 @@
+hSettings = JSON.parse(JSON.stringify(settings('nested')));
+hSettings.x = hSettings.ordinal;
+hSettings.y = hSettings.linear;
+hSettings.marks[0].tooltip = '$x: $y';
+
+const hChart = new webCharts.createChart(
+ '.bar-chart--horizontal',
+ hSettings,
+);
+
+vSettings = JSON.parse(JSON.stringify(settings('nested')));
+vSettings.x = vSettings.linear;
+vSettings.y = vSettings.ordinal;
+hSettings.marks[0].tooltip = '$y: $x';
+
+const vChart = new webCharts.createChart(
+ '.bar-chart--vertical',
+ vSettings,
+);
+
+d3.csv(
+ 'https://raw.githubusercontent.com/RhoInc/data-library/master/data/clinical-trials/sdtm/ae.csv',
+ function(d,i) {
+ d.seq = i;
+ return d;
+ },
+ function(data) {
+ hChart.on('layout', onLayout);
+ hChart.init(data);
+ vChart.on('layout', onLayout);
+ vChart.init(data);
+ }
+);
diff --git a/test-page/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 !== ''));
+ }
+);
diff --git a/test-page/simpleBarchart/OlympicMedals2012.csv b/test-page/simpleBarchart/OlympicMedals2012.csv
deleted file mode 100644
index 58f6c1e..0000000
--- a/test-page/simpleBarchart/OlympicMedals2012.csv
+++ /dev/null
@@ -1,205 +0,0 @@
-"Country","Total"
-"US",104
-"China",88
-"Russia",82
-"UK",65
-"Germany",44
-"Japan",38
-"Australia",35
-"France",34
-"Italy",28
-"South Korea",28
-"Netherlands",20
-"Ukraine",20
-"Canada",18
-"Brazil",17
-"Hungary",17
-"Spain",17
-"Cuba",14
-"Kazakhstan",13
-"New Zealand",13
-"Belarus",12
-"Iran",12
-"Jamaica",12
-"Kenya",11
-"Azerbaijan",10
-"Czech Republic",10
-"Poland",10
-"Denmark",9
-"Romania",9
-"Colombia",8
-"Sweden",8
-"Ethiopia",7
-"Georgia",7
-"Mexico",7
-"Croatia",6
-"India",6
-"North Korea",6
-"South Africa",6
-"Ireland",5
-"Lithuania",5
-"Mongolia",5
-"Turkey",5
-"Argentina",4
-"Norway",4
-"Serbia",4
-"Slovakia",4
-"Slovenia",4
-"Switzerland",4
-"Trinidad and Tobago",4
-"Uzbekistan",4
-"Armenia",3
-"Belgium",3
-"Finland",3
-"Thailand",3
-"Tunisia",3
-"Bulgaria",2
-"Dominican Republic",2
-"Egypt",2
-"Estonia",2
-"Greece",2
-"Indonesia",2
-"Latvia",2
-"Malaysia",2
-"Moldova",2
-"Puerto Rico",2
-"Qatar",2
-"Singapore",2
-"Taiwan",2
-"Afghanistan",1
-"Algeria",1
-"Bahamas",1
-"Bahrain",1
-"Botswana",1
-"Cyprus",1
-"Gabon",1
-"Grenada",1
-"Guatemala",1
-"Hong Kong",1
-"Kuwait",1
-"Montenegro",1
-"Morocco",1
-"Portugal",1
-"Saudi Arabia",1
-"Tajikistan",1
-"Uganda",1
-"Venezuela",1
-"Albania",0
-"American Samoa",0
-"Andorra",0
-"Angola",0
-"Antigua and Barbuda",0
-"Aruba",0
-"Austria",0
-"Bangladesh",0
-"Barbados",0
-"Belize",0
-"Benin",0
-"Bermuda",0
-"Bhutan",0
-"Bolivia",0
-"Bosnia and Herzegovina",0
-"British Virgin Islands",0
-"Brunei",0
-"Burkina Faso",0
-"Burma",0
-"Burundi",0
-"Cambodia",0
-"Cameroon",0
-"Cape Verde",0
-"Cayman Islands",0
-"Central African Republic",0
-"Chad",0
-"Chile",0
-"Comoros",0
-"Congo-Brazzaville",0
-"Cook Islands",0
-"Costa Rica",0
-"Democratic Republic of Congo",0
-"Djibouti",0
-"Dominica",0
-"East Timor",0
-"Ecuador",0
-"El Salvador",0
-"Equatorial Guinea",0
-"Eritrea",0
-"Fiji",0
-"Gambia",0
-"Ghana",0
-"Guam",0
-"Guinea",0
-"Guinea-Bissau",0
-"Guyana",0
-"Haiti",0
-"Honduras",0
-"Iceland",0
-"Iraq",0
-"Israel",0
-"Ivory Coast",0
-"Jordan",0
-"Kiribati",0
-"Kyrgyzstan",0
-"Laos",0
-"Lebanon",0
-"Lesotho",0
-"Liberia",0
-"Libya",0
-"Liechtenstein",0
-"Luxembourg",0
-"Macedonia",0
-"Madagascar",0
-"Malawi",0
-"Maldives",0
-"Mali",0
-"Malta",0
-"Marshall Islands",0
-"Mauritania",0
-"Mauritius",0
-"Micronesia",0
-"Monaco",0
-"Mozambique",0
-"Namibia",0
-"Nauru",0
-"Nepal",0
-"Nicaragua",0
-"Niger",0
-"Nigeria",0
-"Oman",0
-"Pakistan",0
-"Palau",0
-"Palestine",0
-"Panama",0
-"Papua New Guinea",0
-"Paraguay",0
-"Peru",0
-"Philippines",0
-"Rwanda",0
-"Saint Kitts and Nevis",0
-"Saint Lucia",0
-"Saint Vincent and the Grenadines",0
-"Samoa",0
-"San Marino",0
-"Sao Tome and Principe",0
-"Senegal",0
-"Seychelles",0
-"Sierra Leone",0
-"Solomon Islands",0
-"Somalia",0
-"Sri Lanka",0
-"Sudan",0
-"Surinam",0
-"Swaziland",0
-"Syria",0
-"Tanzania",0
-"Togo",0
-"Tonga",0
-"Turkmenistan",0
-"Tuvalu",0
-"United Arab Emirates",0
-"Uruguay",0
-"Vanuatu",0
-"Vietnam",0
-"Virgin Islands",0
-"Yemen",0
-"Zambia",0
-"Zimbabwe",0
diff --git a/test-page/simpleBarchart/OlympicMedals2018.csv b/test-page/simpleBarchart/OlympicMedals2018.csv
new file mode 100644
index 0000000..9ffd0cd
--- /dev/null
+++ b/test-page/simpleBarchart/OlympicMedals2018.csv
@@ -0,0 +1,148 @@
+country_code,n_summer_game,n_summer_gold,n_summer_silver,n_summer_bronze,n_summer_total,n_winter_game,n_winter_gold,n_winter_silver,n_winter_bronze,n_winter_total,n_combined_game,n_combined_gold,n_combined_silver,n_combined_bronze,n_combined_total
+Afghanistan (AFG),14,0,0,2,2,0,0,0,0,0,14,0,0,2,2
+Algeria (ALG),13,5,4,8,17,3,0,0,0,0,16,5,4,8,17
+Argentina (ARG),24,21,25,28,74,19,0,0,0,0,43,21,25,28,74
+Armenia (ARM),6,2,6,6,14,7,0,0,0,0,13,2,6,6,14
+Australasia (ANZ),2,3,4,5,12,0,0,0,0,0,2,3,4,5,12
+Australia (AUS),26,147,163,187,497,19,5,5,5,15,45,152,168,192,512
+Austria (AUT),27,18,33,36,87,23,64,81,87,232,50,82,114,123,319
+Azerbaijan (AZE),6,7,11,24,42,6,0,0,0,0,12,7,11,24,42
+Bahamas (BAH),16,6,2,6,14,0,0,0,0,0,16,6,2,6,14
+Bahrain (BRN),9,2,1,0,3,0,0,0,0,0,9,2,1,0,3
+Barbados (BAR),12,0,0,1,1,0,0,0,0,0,12,0,0,1,1
+Belarus (BLR),6,12,27,39,78,7,8,5,5,18,13,20,32,44,96
+Belgium (BEL),26,40,53,55,148,21,1,2,3,6,47,41,55,58,154
+Bermuda (BER),18,0,0,1,1,8,0,0,0,0,26,0,0,1,1
+Bohemia (BOH),3,0,1,3,4,0,0,0,0,0,3,0,1,3,4
+Botswana (BOT),10,0,1,0,1,0,0,0,0,0,10,0,1,0,1
+Brazil (BRA),22,30,36,63,129,8,0,0,0,0,30,30,36,63,129
+British West Indies (BWI),1,0,0,2,2,0,0,0,0,0,1,0,0,2,2
+Bulgaria (BUL),20,51,87,80,218,20,1,2,3,6,40,52,89,83,224
+Burundi (BDI),6,1,1,0,2,0,0,0,0,0,6,1,1,0,2
+Cameroon (CMR),14,3,1,2,6,1,0,0,0,0,15,3,1,2,6
+Canada (CAN),26,64,102,136,302,23,73,64,62,199,49,137,166,198,501
+Chile (CHI),23,2,7,4,13,17,0,0,0,0,40,2,7,4,13
+China (CHN),10,224,167,155,546,11,13,28,21,62,21,237,195,176,608
+Colombia (COL),19,5,9,14,28,2,0,0,0,0,21,5,9,14,28
+Costa Rica (CRC),15,1,1,2,4,6,0,0,0,0,21,1,1,2,4
+Ivory Coast (CIV),13,1,1,1,3,0,0,0,0,0,13,1,1,1,3
+Croatia (CRO),7,11,10,12,33,8,4,6,1,11,15,15,16,13,44
+Cuba (CUB),20,78,68,80,226,0,0,0,0,0,20,78,68,80,226
+Cyprus (CYP),10,0,1,0,1,11,0,0,0,0,21,0,1,0,1
+Czech Republic (CZE),6,15,17,24,56,7,9,11,11,31,13,24,28,35,87
+Czechoslovakia (TCH),16,49,49,45,143,16,2,8,15,25,32,51,57,60,168
+Denmark (DEN),27,45,74,75,194,14,0,1,0,1,41,45,75,75,195
+Djibouti (DJI),8,0,0,1,1,0,0,0,0,0,8,0,0,1,1
+Dominican Republic (DOM),14,3,2,2,7,0,0,0,0,0,14,3,2,2,7
+Ecuador (ECU),14,1,1,0,2,1,0,0,0,0,15,1,1,0,2
+Egypt (EGY),22,7,10,15,32,1,0,0,0,0,23,7,10,15,32
+Eritrea (ERI),5,0,0,1,1,1,0,0,0,0,6,0,0,1,1
+Estonia (EST),12,9,9,16,34,10,4,2,1,7,22,13,11,17,41
+Ethiopia (ETH),13,22,11,21,54,2,0,0,0,0,15,22,11,21,54
+Fiji (FIJ),14,1,0,0,1,3,0,0,0,0,17,1,0,0,1
+Finland (FIN),25,101,85,117,303,23,43,63,61,167,48,144,148,178,470
+France (FRA),28,212,241,263,716,23,36,35,53,124,51,248,276,316,840
+Gabon (GAB),10,0,1,0,1,0,0,0,0,0,10,0,1,0,1
+Georgia (GEO),6,8,7,17,32,7,0,0,0,0,13,8,7,17,32
+Germany (GER),16,191,194,230,615,12,92,88,60,240,28,283,282,290,855
+United Team of Germany (EUA),3,28,54,36,118,3,8,6,5,19,6,36,60,41,137
+East Germany (GDR),5,153,129,127,409,6,39,36,35,110,11,192,165,162,519
+West Germany (FRG),5,56,67,81,204,6,11,15,13,39,11,67,82,94,243
+Ghana (GHA),14,0,1,3,4,2,0,0,0,0,16,0,1,3,4
+Great Britain (GBR),28,263,295,293,851,23,11,4,17,32,51,274,299,310,883
+Greece (GRE),28,33,43,40,116,19,0,0,0,0,47,33,43,40,116
+Grenada (GRN),9,1,1,0,2,0,0,0,0,0,9,1,1,0,2
+Guatemala (GUA),14,0,1,0,1,1,0,0,0,0,15,0,1,0,1
+Guyana (GUY),17,0,0,1,1,0,0,0,0,0,17,0,0,1,1
+Haiti (HAI),15,0,1,1,2,0,0,0,0,0,15,0,1,1,2
+Hong Kong (HKG),16,1,1,1,3,5,0,0,0,0,21,1,1,1,3
+Hungary (HUN),26,175,147,169,491,23,1,2,4,7,49,176,149,173,498
+Iceland (ISL),20,0,2,2,4,18,0,0,0,0,38,0,2,2,4
+India (IND),24,9,7,12,28,10,0,0,0,0,34,9,7,12,28
+Indonesia (INA),15,7,13,12,32,0,0,0,0,0,15,7,13,12,32
+Iran (IRI),16,21,21,27,69,11,0,0,0,0,27,21,21,27,69
+Iraq (IRQ),14,0,0,1,1,0,0,0,0,0,14,0,0,1,1
+Ireland (IRL),21,9,10,12,31,7,0,0,0,0,28,9,10,12,31
+Israel (ISR),16,1,1,7,9,7,0,0,0,0,23,1,1,7,9
+Italy (ITA),27,206,178,193,577,23,40,36,48,124,50,246,214,241,701
+Jamaica (JAM),17,22,35,21,78,8,0,0,0,0,25,22,35,21,78
+Japan (JPN),22,142,136,161,439,21,14,22,22,58,43,156,158,183,497
+Jordan (JOR),10,1,0,0,1,0,0,0,0,0,10,1,0,0,1
+Kazakhstan (KAZ),6,15,21,27,63,7,1,3,4,8,13,16,24,31,71
+Kenya (KEN),14,31,38,34,103,4,0,0,0,0,18,31,38,34,103
+Kosovo (KOS),1,1,0,0,1,1,0,0,0,0,2,1,0,0,1
+North Korea (PRK),10,16,16,22,54,9,0,1,1,2,19,16,17,23,56
+South Korea (KOR),17,90,87,90,267,18,31,25,14,70,35,121,112,104,337
+Kuwait (KUW),12,0,0,2,2,0,0,0,0,0,12,0,0,2,2
+Kyrgyzstan (KGZ),6,0,1,3,4,7,0,0,0,0,13,0,1,3,4
+Latvia (LAT),11,3,11,5,19,11,1,3,5,9,22,4,14,10,28
+Lebanon (LIB),17,0,2,2,4,17,0,0,0,0,34,0,2,2,4
+Liechtenstein (LIE),17,0,0,0,0,19,2,2,6,10,36,2,2,6,10
+Lithuania (LTU),9,6,6,13,25,9,0,0,0,0,18,6,6,13,25
+Luxembourg (LUX),23,1,1,0,2,9,0,2,0,2,32,1,3,0,4
+Macedonia (MKD),6,0,0,1,1,6,0,0,0,0,12,0,0,1,1
+Malaysia (MAS),13,0,7,4,11,1,0,0,0,0,14,0,7,4,11
+Mauritius (MRI),9,0,0,1,1,0,0,0,0,0,9,0,0,1,1
+Mexico (MEX),23,13,24,32,69,9,0,0,0,0,32,13,24,32,69
+Moldova (MDA),6,0,2,3,5,7,0,0,0,0,13,0,2,3,5
+Mongolia (MGL),13,2,10,14,26,14,0,0,0,0,27,2,10,14,26
+Montenegro (MNE),3,0,1,0,1,3,0,0,0,0,6,0,1,0,1
+Morocco (MAR),14,6,5,12,23,7,0,0,0,0,21,6,5,12,23
+Mozambique (MOZ),10,1,0,1,2,0,0,0,0,0,10,1,0,1,2
+Namibia (NAM),7,0,4,0,4,0,0,0,0,0,7,0,4,0,4
+Netherlands (NED),26,85,92,108,285,21,45,44,41,130,47,130,136,149,415
+Netherlands Antilles (AHO),13,0,1,0,1,2,0,0,0,0,15,0,1,0,1
+New Zealand (NZL),23,46,27,44,117,16,0,1,2,3,39,46,28,46,120
+Niger (NIG),12,0,1,1,2,0,0,0,0,0,12,0,1,1,2
+Nigeria (NGR),16,3,10,12,25,1,0,0,0,0,17,3,10,12,25
+Norway (NOR),25,56,49,47,152,23,132,125,111,368,48,188,174,158,520
+Pakistan (PAK),17,3,3,4,10,3,0,0,0,0,20,3,3,4,10
+Panama (PAN),17,1,0,2,3,0,0,0,0,0,17,1,0,2,3
+Paraguay (PAR),12,0,1,0,1,1,0,0,0,0,13,0,1,0,1
+Peru (PER),18,1,3,0,4,2,0,0,0,0,20,1,3,0,4
+Philippines (PHI),21,0,3,7,10,5,0,0,0,0,26,0,3,7,10
+Poland (POL),21,68,84,132,284,23,7,7,8,22,44,75,91,140,306
+Portugal (POR),24,4,8,12,24,8,0,0,0,0,32,4,8,12,24
+Puerto Rico (PUR),18,1,2,6,9,7,0,0,0,0,25,1,2,6,9
+Qatar (QAT),9,0,1,4,5,0,0,0,0,0,9,0,1,4,5
+Romania (ROU),21,89,95,122,306,21,0,0,1,1,42,89,95,123,307
+Russia (RUS),6,148,125,153,426,6,47,38,35,120,12,195,163,188,546
+Russian Empire (RU1),3,1,4,3,8,0,0,0,0,0,3,1,4,3,8
+Soviet Union (URS),9,395,319,296,1,010,9,78,57,59,194,18,473,376,355,1,204
+Saudi Arabia (KSA),11,0,1,2,3,0,0,0,0,0,11,0,1,2,3
+Samoa (SAM),9,0,1,0,1,0,0,0,0,0,9,0,1,0,1
+Senegal (SEN),14,0,1,0,1,5,0,0,0,0,19,0,1,0,1
+Serbia (SRB),4,3,6,6,15,3,0,0,0,0,7,3,6,6,15
+Serbia and Montenegro (SCG),1,0,2,0,2,1,0,0,0,0,2,0,2,0,2
+Singapore (SIN),16,1,2,2,5,1,0,0,0,0,17,1,2,2,5
+Slovakia (SVK),6,9,12,7,28,7,3,4,1,8,13,12,16,8,36
+Slovenia (SLO),7,5,8,10,23,8,2,5,10,17,15,7,13,20,40
+South Africa (RSA),19,26,31,29,86,7,0,0,0,0,26,26,31,29,86
+Spain (ESP),23,45,64,41,150,20,1,0,3,4,43,46,64,44,154
+Sri Lanka (SRI),17,0,2,0,2,0,0,0,0,0,17,0,2,0,2
+Sudan (SUD),12,0,1,0,1,0,0,0,0,0,12,0,1,0,1
+Suriname (SUR),12,1,0,1,2,0,0,0,0,0,12,1,0,1,2
+Sweden (SWE),27,145,170,179,494,23,57,46,55,158,50,202,216,234,652
+Switzerland (SUI),28,50,75,67,192,23,56,45,52,153,51,106,120,119,345
+Syria (SYR),13,1,1,1,3,0,0,0,0,0,13,1,1,1,3
+Chinese Taipei (TPE),14,5,7,12,24,12,0,0,0,0,26,5,7,12,24
+Tajikistan (TJK),6,1,1,2,4,4,0,0,0,0,10,1,1,2,4
+Tanzania (TAN),13,0,2,0,2,0,0,0,0,0,13,0,2,0,2
+Thailand (THA),16,9,8,16,33,4,0,0,0,0,20,9,8,16,33
+Togo (TOG),10,0,0,1,1,2,0,0,0,0,12,0,0,1,1
+Tonga (TGA),9,0,1,0,1,2,0,0,0,0,11,0,1,0,1
+Trinidad and Tobago (TTO),17,3,5,11,19,3,0,0,0,0,20,3,5,11,19
+Tunisia (TUN),14,4,2,7,13,0,0,0,0,0,14,4,2,7,13
+Turkey (TUR),22,39,24,28,91,17,0,0,0,0,39,39,24,28,91
+Uganda (UGA),15,2,3,2,7,0,0,0,0,0,15,2,3,2,7
+Ukraine (UKR),6,34,30,56,120,7,3,1,4,8,13,37,31,60,128
+United Arab Emirates (UAE),9,1,0,1,2,0,0,0,0,0,9,1,0,1,2
+United States (USA),27,1,022,795,705,2,522,23,105,112,88,305,50,1,127,907,793,2,827
+Uruguay (URU),21,2,2,6,10,1,0,0,0,0,22,2,2,6,10
+Uzbekistan (UZB),6,7,6,18,31,7,1,0,0,1,13,8,6,18,32
+Venezuela (VEN),18,2,4,9,15,4,0,0,0,0,22,2,4,9,15
+Vietnam (VIE),15,1,3,0,4,0,0,0,0,0,15,1,3,0,4
+Virgin Islands (ISV),12,0,1,0,1,7,0,0,0,0,19,0,1,0,1
+Yugoslavia (YUG),18,28,31,31,90,16,0,3,1,4,34,28,34,32,94
+Zambia (ZAM),13,0,1,1,2,0,0,0,0,0,13,0,1,1,2
+Zimbabwe (ZIM),13,3,4,1,8,1,0,0,0,0,14,3,4,1,8
diff --git a/test-page/simpleBarchart/index.html b/test-page/simpleBarchart/index.html
index f6343a9..fd638fd 100644
--- a/test-page/simpleBarchart/index.html
+++ b/test-page/simpleBarchart/index.html
@@ -1,22 +1,51 @@
-
+
Webcharts - Simple Bar Chart
-
+
-
-
+
+
-
+
+
+
Webcharts
Simple Bar Chart
-
+
diff --git a/test-page/simpleBarchart/index.js b/test-page/simpleBarchart/index.js
index f986265..b41c7e3 100644
--- a/test-page/simpleBarchart/index.js
+++ b/test-page/simpleBarchart/index.js
@@ -1,33 +1,122 @@
-var settings = {
- max_width: "500",
- x: {
- label: "Total",
- type: "linear",
- column: "Total",
- domain: [0, null]
- },
- y: {
- type: "ordinal",
- column: "Country",
- sort: "total-descending"
- },
- marks: [
- {
- type: "bar",
- per: ["Country"],
- tooltip: "[Country] won [Total] medals"
- }
- ],
- gridlines: "x"
-};
+d3.csv(
+ './OlympicMedals2018.csv',
+ function(d) {
+ return d;
+ },
+ function(data) {
+ const settings = {
+ marks: [
+ {
+ type: 'bar',
+ per: ['country_code'],
+ tooltip: '[country_code] won $ medals'
+ }
+ ],
+ resizable: false,
+ };
+ const linearAxis = {
+ type: 'linear',
+ label: '',
+ column: 'n_combined_gold',
+ };
+ const ordinalAxis = {
+ type: 'ordinal',
+ label: 'Country (IOC code)',
+ column: 'country_code',
+ sort: 'total-descending',
+ range_band: 15,
+ };
+
+ // controls
+ const controls = new webCharts.createControls(
+ '.controls',
+ {
+ inputs: [
+ {
+ type: 'dropdown',
+ label: 'Variable',
+ option: 'column',
+ require: true,
+ values: Object.keys(data[0]).filter(key => key !== 'country_code'),
+ },
+ {
+ type: 'dropdown',
+ label: 'Sort',
+ option: 'sort',
+ require: true,
+ values: [
+ 'alphabetical-ascending',
+ 'alphabetical-descending',
+ 'total-ascending',
+ 'total-descending'
+ ],
+ },
+ ],
+ }
+ );
-var medalChart = webCharts.createChart(".chart", settings);
+ // ordinal y-axis
+ const verticalSettings = JSON.parse(JSON.stringify(settings));
+ verticalSettings.linearAxis = 'x';
+ verticalSettings.ordinalAxis = 'y';
+ verticalSettings.x = Object.assign({}, linearAxis);
+ verticalSettings.y = Object.assign({}, ordinalAxis);
+ verticalSettings.marks[0].tooltip = verticalSettings.marks[0].tooltip.replace('$', '$x');
+ verticalSettings.gridlines = 'x';
+ const verticalChart = webCharts.createChart(
+ '.chart--vertical',
+ verticalSettings,
+ controls
+ );
+ verticalChart.init(data);
-d3.csv("OlympicMedals2012.csv", function(error, data) {
- //just keep the countries with the 10 most medals
- var sub = data.filter(function(d, i) {
- return i <= 11;
- });
+ // ordinal x-axis
+ const horizontalSettings = JSON.parse(JSON.stringify(settings));
+ horizontalSettings.linearAxis = 'y';
+ horizontalSettings.ordinalAxis = 'x';
+ horizontalSettings.x = Object.assign({}, ordinalAxis);
+ horizontalSettings.y = Object.assign({}, linearAxis);
+ horizontalSettings.marks[0].tooltip = horizontalSettings.marks[0].tooltip.replace('$', '$y');
+ horizontalSettings.gridlines = 'y';
+ horizontalSettings.height = 500;
+ horizontalSettings.margin = {
+ bottom: 150,
+ left: 100,
+ };
+ const horizontalChart = webCharts.createChart(
+ '.chart--horizontal',
+ horizontalSettings,
+ controls
+ );
+ horizontalChart.on('resize', function() {
+ this.svg
+ .selectAll('.x.axis .tick text')
+ .attr('transform', 'rotate(-45) translate(-5,-5)')
+ .style('text-anchor', 'end');
+ });
+ horizontalChart.init(data);
- medalChart.init(sub);
-});
+ const variableControl = controls.wrap
+ .selectAll('.control-group select')
+ .filter(d => d.label === 'Variable');
+ variableControl.selectAll('option').property('selected', d => d === linearAxis.column);
+ variableControl
+ .on('change', function(d) {
+ controls.targets.forEach(target => {
+ target.config[target.config.linearAxis].column = this.value;
+ target.draw();
+ });
+ });
+ const sortControl = controls.wrap
+ .selectAll('.control-group select')
+ .filter(d => d.label === 'Sort');
+ sortControl.selectAll('option').property('selected', d => d === ordinalAxis.sort);
+ sortControl
+ .on('change', function(d) {
+ controls.targets.forEach(target => {
+ target.config[target.config.ordinalAxis].sort = this.value;
+ target.draw();
+ });
+ });
+ }
+);
diff --git a/test-page/stackedBarChart/index.html b/test-page/stackedBarChart/index.html
new file mode 100644
index 0000000..4eea172
--- /dev/null
+++ b/test-page/stackedBarChart/index.html
@@ -0,0 +1,27 @@
+
+
+
+ Webcharts - Stacked Bar Chart
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Webcharts
+ Stacked Bar Chart
+
+
+
+
+
diff --git a/test-page/stackedBarChart/index.js b/test-page/stackedBarChart/index.js
new file mode 100644
index 0000000..c4df51f
--- /dev/null
+++ b/test-page/stackedBarChart/index.js
@@ -0,0 +1,33 @@
+hSettings = JSON.parse(JSON.stringify(settings('stacked')));
+hSettings.x = hSettings.ordinal;
+hSettings.y = hSettings.linear;
+hSettings.marks[0].tooltip = '$x: $y';
+
+const hChart = new webCharts.createChart(
+ '.bar-chart--horizontal',
+ hSettings,
+);
+
+vSettings = JSON.parse(JSON.stringify(settings('stacked')));
+vSettings.x = vSettings.linear;
+vSettings.y = vSettings.ordinal;
+hSettings.marks[0].tooltip = '$y: $x';
+
+const vChart = new webCharts.createChart(
+ '.bar-chart--vertical',
+ vSettings,
+);
+
+d3.csv(
+ 'https://raw.githubusercontent.com/RhoInc/data-library/master/data/clinical-trials/sdtm/ae.csv',
+ function(d,i) {
+ d.seq = i;
+ return d;
+ },
+ function(data) {
+ hChart.on('layout', onLayout);
+ hChart.init(data);
+ vChart.on('layout', onLayout);
+ vChart.init(data);
+ }
+);
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 });