Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

d3-funnel

Package Overview
Dependencies
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

d3-funnel - npm Package Compare versions

Comparing version 0.7.1 to 0.7.2

examples/examples.js

6

CHANGELOG.md

@@ -0,1 +1,7 @@

## v0.7.2 (November 18, 2015)
### Bug Fixes
* [#41]: Fix issue where `events.click.block` would error on `null`
## v0.7.1 (October 28, 2015)

@@ -2,0 +8,0 @@

176

dist/d3-funnel.js

@@ -12,55 +12,20 @@

/* global d3, Colorizer, LabelFormatter, Navigator, Utils */
/* exported D3Funnel */
'use strict';
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
function _typeof(obj) { return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/* global d3, Colorizer, LabelFormatter, Navigator, Utils */
/* exported D3Funnel */
var D3Funnel = (function () {
_createClass(D3Funnel, null, [{
key: 'defaults',
value: {
chart: {
width: 350,
height: 400,
bottomWidth: 1 / 3,
bottomPinch: 0,
inverted: false,
animate: false,
curve: {
enabled: false,
height: 20
}
},
block: {
dynamicHeight: false,
fill: {
scale: d3.scale.category10().domain(d3.range(0, 10)),
type: 'solid'
},
minHeight: false,
highlight: false
},
label: {
fontSize: '14px',
fill: '#fff',
format: '{l}: {f}'
},
events: {
click: {
block: null
}
}
},
/**
* @param {string} selector A selector for the container element.
*
* @return {void}
*/
enumerable: true
}]);
/**
* @param {string} selector A selector for the container element.
*
* @return {void}
*/

@@ -79,5 +44,2 @@ function D3Funnel(selector) {

/* exported Colorizer */
/* jshint bitwise: false */
/**

@@ -93,2 +55,3 @@ * Remove the funnel and its events from the DOM.

var container = d3.select(this.selector);
// D3's remove method appears to be sufficient for removing the events

@@ -116,2 +79,3 @@ container.selectAll('svg').remove();

*/
}, {

@@ -137,2 +101,3 @@ key: 'draw',

*/
}, {

@@ -187,2 +152,3 @@ key: '_initialize',

*/
}, {

@@ -213,2 +179,3 @@ key: '_validateData',

*/
}, {

@@ -246,2 +213,3 @@ key: '_getSettings',

*/
}, {

@@ -260,2 +228,3 @@ key: '_setBlocks',

*/
}, {

@@ -283,2 +252,3 @@ key: '_getTotalCount',

*/
}, {

@@ -305,3 +275,2 @@ key: '_standardizeData',

height: _this2.height * ratio,
formatted: _this2.labelFormatter.format(label, count),
fill: _this2.colorizer.getBlockFill(block, index, _this2.fillType),

@@ -311,3 +280,3 @@ label: {

formatted: _this2.labelFormatter.format(label, count),
color: _this2.colorizer.getLabelFill(block, index)
color: _this2.colorizer.getLabelFill(block)
}

@@ -327,2 +296,3 @@ });

*/
}, {

@@ -337,2 +307,3 @@ key: '_getRawBlockCount',

*/
}, {

@@ -352,2 +323,3 @@ key: '_getDx',

*/
}, {

@@ -369,2 +341,3 @@ key: '_getDy',

*/
}, {

@@ -398,2 +371,3 @@ key: '_draw',

*/
}, {

@@ -438,3 +412,3 @@ key: '_makePaths',

// shared according to the remaining minus the guaranteed
if (this.minHeight !== false) {
if (this.minHeight !== 0) {
totalHeight = this.height - this.minHeight * this.blocks.length;

@@ -472,3 +446,3 @@ }

// Add greedy minimum height
if (_this3.minHeight !== false) {
if (_this3.minHeight !== 0) {
dy += _this3.minHeight;

@@ -593,2 +567,3 @@ }

*/
}, {

@@ -630,2 +605,3 @@ key: '_defineColorGradients',

*/
}, {

@@ -660,2 +636,3 @@ key: '_drawTopOval',

*/
}, {

@@ -678,3 +655,3 @@ key: '_drawBlock',

// Add animation components
if (this.animation !== false) {
if (this.animation !== 0) {
path.transition().duration(this.animation).ease('linear').attr('fill', this.blocks[index].fill.actual).attr('d', this._getPathDefinition(index)).each('end', function () {

@@ -707,2 +684,3 @@ _this4._drawBlock(index + 1);

*/
}, {

@@ -713,3 +691,3 @@ key: '_getBlockPath',

if (this.animation !== false) {
if (this.animation !== 0) {
this._addBeforeTransition(path, index);

@@ -729,2 +707,3 @@ }

*/
}, {

@@ -764,2 +743,3 @@ key: '_addBeforeTransition',

*/
}, {

@@ -776,2 +756,3 @@ key: '_getD3Data',

*/
}, {

@@ -794,2 +775,3 @@ key: '_getPathDefinition',

*/
}, {

@@ -802,6 +784,7 @@ key: '_onMouseOver',

/**
* @param {Object} data
*
* @return {void}
*/
* @param {Object} data
*
* @return {void}
*/
}, {

@@ -818,2 +801,3 @@ key: '_onMouseOut',

*/
}, {

@@ -848,2 +832,3 @@ key: '_addBlockLabel',

*/
}, {

@@ -863,2 +848,39 @@ key: '_getTextY',

/* exported Colorizer */
/* jshint bitwise: false */
D3Funnel.defaults = {
chart: {
width: 350,
height: 400,
bottomWidth: 1 / 3,
bottomPinch: 0,
inverted: false,
animate: 0,
curve: {
enabled: false,
height: 20
}
},
block: {
dynamicHeight: false,
fill: {
scale: d3.scale.category10().domain(d3.range(0, 10)),
type: 'solid'
},
minHeight: 0,
highlight: false
},
label: {
fontSize: '14px',
fill: '#fff',
format: '{l}: {f}'
},
events: {
click: {
block: null
}
}
};
var Colorizer = (function () {

@@ -875,4 +897,2 @@ function Colorizer() {

/* exported LabelFormatter */
/**

@@ -895,2 +915,3 @@ * @param {string} fill

*/
}, {

@@ -911,2 +932,3 @@ key: 'setScale',

*/
}, {

@@ -931,2 +953,3 @@ key: 'getBlockFill',

*/
}, {

@@ -958,2 +981,3 @@ key: 'getBlockRawFill',

*/
}, {

@@ -976,2 +1000,3 @@ key: 'getBlockActualFill',

*/
}, {

@@ -996,2 +1021,3 @@ key: 'getLabelFill',

*/
}], [{

@@ -1026,2 +1052,3 @@ key: 'shade',

*/
}, {

@@ -1037,2 +1064,4 @@ key: 'expandHex',

/* exported LabelFormatter */
var LabelFormatter = (function () {

@@ -1052,4 +1081,2 @@

/* exported Navigator */
/**

@@ -1082,2 +1109,3 @@ * Register the format function.

*/
}, {

@@ -1108,2 +1136,3 @@ key: 'format',

*/
}, {

@@ -1130,2 +1159,3 @@ key: 'stringFormatter',

*/
}, {

@@ -1141,2 +1171,4 @@ key: 'getDefaultFormattedValue',

/* exported Navigator */
var Navigator = (function () {

@@ -1147,8 +1179,2 @@ function Navigator() {

/* exported Utils */
/**
* Simple utility class.
*/
_createClass(Navigator, [{

@@ -1178,2 +1204,8 @@ key: 'plot',

/* exported Utils */
/**
* Simple utility class.
*/
var Utils = (function () {

@@ -1200,4 +1232,4 @@ function Utils() {

if (b.hasOwnProperty(prop)) {
if (typeof b[prop] === 'object' && !Array.isArray(b[prop])) {
if (typeof a[prop] === 'object' && !Array.isArray(a[prop])) {
if (_typeof(b[prop]) === 'object' && !Array.isArray(b[prop]) && b[prop] !== null) {
if (_typeof(a[prop]) === 'object' && !Array.isArray(a[prop]) && b[prop] !== null) {
a[prop] = Utils.extend(a[prop], b[prop]);

@@ -1204,0 +1236,0 @@ } else {

/*! d3-funnel - v0.7.1 | 2015 */
!function(t,e){"function"==typeof define&&define.amd?define(["d3"],e):"object"==typeof exports?module.exports=e(require("d3")):t.D3Funnel=e(t.d3)}(this,function(t){"use strict";function e(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var i=function(){function t(t,e){for(var i=0;i<e.length;i++){var a=e[i];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(t,a.key,a)}}return function(e,i,a){return i&&t(e.prototype,i),a&&t(e,a),e}}(),a=function(){function a(t){e(this,a),this.selector=t,this.colorizer=new n,this.labelFormatter=new l,this.navigator=new r}return i(a,null,[{key:"defaults",value:{chart:{width:350,height:400,bottomWidth:1/3,bottomPinch:0,inverted:!1,animate:!1,curve:{enabled:!1,height:20}},block:{dynamicHeight:!1,fill:{scale:t.scale.category10().domain(t.range(0,10)),type:"solid"},minHeight:!1,highlight:!1},label:{fontSize:"14px",fill:"#fff",format:"{l}: {f}"},events:{click:{block:null}}},enumerable:!0}]),i(a,[{key:"destroy",value:function(){var e=t.select(this.selector);e.selectAll("svg").remove(),e.selectAll("*").remove(),e.text("")}},{key:"draw",value:function(t){var e=arguments.length<=1||void 0===arguments[1]?{}:arguments[1];this.destroy(),this._initialize(t,e),this._draw()}},{key:"_initialize",value:function(t,e){this._validateData(t);var i=this._getSettings(e);this.label=i.label,this.labelFormatter.setFormat(this.label.format),this.colorizer.setLabelFill(i.label.fill),this.colorizer.setScale(i.block.fill.scale),this.width=i.chart.width,this.height=i.chart.height,this.bottomWidth=i.chart.width*i.chart.bottomWidth,this.bottomPinch=i.chart.bottomPinch,this.isInverted=i.chart.inverted,this.isCurved=i.chart.curve.enabled,this.curveHeight=i.chart.curve.height,this.fillType=i.block.fill.type,this.hoverEffects=i.block.highlight,this.dynamicHeight=i.block.dynamicHeight,this.minHeight=i.block.minHeight,this.animation=i.chart.animate,this.onBlockClick=i.events.click.block,this._setBlocks(t),this.bottomLeftX=(this.width-this.bottomWidth)/2,this.dx=this._getDx(),this.dy=this._getDy()}},{key:"_validateData",value:function(t){if(Array.isArray(t)===!1)throw new Error("Data must be an array.");if(0===t.length)throw new Error("Data array must contain at least one element.");if(Array.isArray(t[0])===!1)throw new Error("Data array elements must be arrays.");if(t[0].length<2)throw new Error("Data array elements must contain a label and value.")}},{key:"_getSettings",value:function(e){var i=h.extend({},a.defaults);return i.chart.width=parseInt(t.select(this.selector).style("width"),10),i.chart.height=parseInt(t.select(this.selector).style("height"),10),i=h.extend(i,e),i.chart.width<=0&&(i.chart.width=a.defaults.chart.width),i.chart.height<=0&&(i.chart.height=a.defaults.chart.height),i}},{key:"_setBlocks",value:function(t){var e=this._getTotalCount(t);this.blocks=this._standardizeData(t,e)}},{key:"_getTotalCount",value:function(t){var e=this,i=0;return t.forEach(function(t){i+=e._getRawBlockCount(t)}),i}},{key:"_standardizeData",value:function(t,e){var i=this,a=[],n=void 0,l=void 0,r=void 0;return t.forEach(function(t,h){n=i._getRawBlockCount(t),l=n/e,r=t[0],a.push({index:h,value:n,ratio:l,height:i.height*l,formatted:i.labelFormatter.format(r,n),fill:i.colorizer.getBlockFill(t,h,i.fillType),label:{raw:r,formatted:i.labelFormatter.format(r,n),color:i.colorizer.getLabelFill(t,h)}})}),a}},{key:"_getRawBlockCount",value:function(t){return Array.isArray(t[1])?t[1][0]:t[1]}},{key:"_getDx",value:function(){return this.bottomPinch>0?this.bottomLeftX/(this.blocks.length-this.bottomPinch):this.bottomLeftX/this.blocks.length}},{key:"_getDy",value:function(){return this.isCurved?(this.height-this.curveHeight)/this.blocks.length:this.height/this.blocks.length}},{key:"_draw",value:function(){this.svg=t.select(this.selector).append("svg").attr("width",this.width).attr("height",this.height),this.blockPaths=this._makePaths(),"gradient"===this.fillType&&this._defineColorGradients(this.svg),this.isCurved&&this._drawTopOval(this.svg,this.blockPaths),this._drawBlock(0)}},{key:"_makePaths",value:function(){var t=this,e=[],i=this.dx,a=this.dy,n=0,l=this.width,r=0;this.isInverted&&(n=this.bottomLeftX,l=this.width-this.bottomLeftX);var h=0,o=0,s=0,c=this.width/2;this.isCurved&&(r=10);var u=this.height;this.minHeight!==!1&&(u=this.height-this.minHeight*this.blocks.length);var f=this.height;this.blocks.forEach(function(e,i){t.bottomPinch>0&&(t.isInverted?i<t.bottomPinch&&(f-=e.height):i>=t.blocks.length-t.bottomPinch&&(f-=e.height))});var d=2*f/(this.width-this.bottomWidth);return this.blocks.forEach(function(f,v){t.dynamicHeight&&(a=u*f.ratio,t.minHeight!==!1&&(a+=t.minHeight),t.isCurved&&(a-=t.curveHeight/t.blocks.length),h=(r+a)/d,t.isInverted&&(h=(r+a-t.height)/(-1*d)),0===t.bottomWidth&&v===t.blocks.length-1&&(h=t.width/2,t.isInverted&&(h=0)),t.bottomWidth===t.width&&(h=n),i=h-n,t.isInverted&&(i=n-h)),t.bottomPinch>0&&(t.isInverted?(t.dynamicHeight||(i=t.dx),i=v<t.bottomPinch?0:i):v>=t.blocks.length-t.bottomPinch&&(i=0)),h=n+i,o=l-i,s=r+a,t.isInverted&&(h=n-i,o=l+i),t.isCurved?e.push([[n,r,"M"],[c,r+(t.curveHeight-10),"Q"],[l,r,""],[o,s,"L"],[o,s,"M"],[c,s+t.curveHeight,"Q"],[h,s,""],[n,r,"L"]]):e.push([[n,r,"M"],[l,r,"L"],[o,s,"L"],[h,s,"L"],[n,r,"L"]]),n=h,l=o,r=s}),e}},{key:"_defineColorGradients",value:function(t){var e=t.append("defs");this.blocks.forEach(function(t,i){var a=t.fill.raw,l=n.shade(a,-.2),r=e.append("linearGradient").attr({id:"gradient-"+i}),h=[[0,l],[40,a],[60,a],[100,l]];h.forEach(function(t){r.append("stop").attr({offset:t[0]+"%",style:"stop-color:"+t[1]})})})}},{key:"_drawTopOval",value:function(t,e){var i=0,a=this.width,l=this.width/2;this.isInverted&&(i=this.bottomLeftX,a=this.width-this.bottomLeftX);var r=e[0],h=r[1][1]+this.curveHeight-10,o=this.navigator.plot([["M",i,r[0][1]],["Q",l,h],[" ",a,r[2][1]],["M",a,10],["Q",l,0],[" ",i,10]]);t.append("path").attr("fill",n.shade(this.blocks[0].fill.raw,-.4)).attr("d",o)}},{key:"_drawBlock",value:function(t){var e=this;if(t!==this.blocks.length){var i=this.svg.append("g"),a=this._getBlockPath(i,t);a.data(this._getD3Data(t)),this.animation!==!1?a.transition().duration(this.animation).ease("linear").attr("fill",this.blocks[t].fill.actual).attr("d",this._getPathDefinition(t)).each("end",function(){e._drawBlock(t+1)}):(a.attr("fill",this.blocks[t].fill.actual).attr("d",this._getPathDefinition(t)),this._drawBlock(t+1)),this.hoverEffects&&a.on("mouseover",this._onMouseOver).on("mouseout",this._onMouseOut),null!==this.onBlockClick&&a.on("click",this.onBlockClick),this._addBlockLabel(i,t)}}},{key:"_getBlockPath",value:function(t,e){var i=t.append("path");return this.animation!==!1&&this._addBeforeTransition(i,e),i}},{key:"_addBeforeTransition",value:function(t,e){var i=this.blockPaths[e],a="",n="";a=this.isCurved?this.navigator.plot([["M",i[0][0],i[0][1]],["Q",i[1][0],i[1][1]],[" ",i[2][0],i[2][1]],["L",i[2][0],i[2][1]],["M",i[2][0],i[2][1]],["Q",i[1][0],i[1][1]],[" ",i[0][0],i[0][1]]]):this.navigator.plot([["M",i[0][0],i[0][1]],["L",i[1][0],i[1][1]],["L",i[1][0],i[1][1]],["L",i[0][0],i[0][1]]]),n="solid"===this.fillType&&e>0?this.blocks[e-1].fill.actual:this.blocks[e].fill.actual,t.attr("d",a).attr("fill",n)}},{key:"_getD3Data",value:function(t){return[this.blocks[t]]}},{key:"_getPathDefinition",value:function(t){var e=[];return this.blockPaths[t].forEach(function(t){e.push([t[2],t[0],t[1]])}),this.navigator.plot(e)}},{key:"_onMouseOver",value:function(e){t.select(this).attr("fill",n.shade(e.fill.raw,-.2))}},{key:"_onMouseOut",value:function(e){t.select(this).attr("fill",e.fill.actual)}},{key:"_addBlockLabel",value:function(t,e){var i=this.blockPaths[e],a=this.blocks[e].label.formatted,n=this.blocks[e].label.color,l=this.width/2,r=this._getTextY(i);t.append("text").text(a).attr({x:l,y:r,"text-anchor":"middle","dominant-baseline":"middle",fill:n,"pointer-events":"none"}).style("font-size",this.label.fontSize)}},{key:"_getTextY",value:function(t){return this.isCurved?(t[2][1]+t[3][1])/2+this.curveHeight/this.blocks.length:(t[1][1]+t[2][1])/2}}]),a}(),n=function(){function t(){e(this,t),this.hexExpression=/^#([0-9a-f]{3}|[0-9a-f]{6})$/i,this.labelFill=null,this.scale=null}return i(t,[{key:"setLabelFill",value:function(t){this.labelFill=t}},{key:"setScale",value:function(t){this.scale=t}},{key:"getBlockFill",value:function(t,e,i){var a=this.getBlockRawFill(t,e);return{raw:a,actual:this.getBlockActualFill(a,e,i)}}},{key:"getBlockRawFill",value:function(t,e){return t.length>2&&this.hexExpression.test(t[2])?t[2]:Array.isArray(this.scale)?this.scale[e]:this.scale(e)}},{key:"getBlockActualFill",value:function(t,e,i){return"solid"===i?t:"url(#gradient-"+e+")"}},{key:"getLabelFill",value:function(t){return t.length>3&&this.hexExpression.test(t[3])?t[3]:this.labelFill}}],[{key:"shade",value:function(e,i){var a=e.slice(1);3===a.length&&(a=t.expandHex(a));var n=parseInt(a,16),l=0>i?0:255,r=0>i?-1*i:i,h=n>>16,o=n>>8&255,s=255&n,c=16777216+65536*(Math.round((l-h)*r)+h)+256*(Math.round((l-o)*r)+o)+(Math.round((l-s)*r)+s);return"#"+c.toString(16).slice(1)}},{key:"expandHex",value:function(t){return t[0]+t[0]+t[1]+t[1]+t[2]+t[2]}}]),t}(),l=function(){function t(){e(this,t),this.expression=null}return i(t,[{key:"setFormat",value:function(t){"function"==typeof t?this.formatter=t:(this.expression=t,this.formatter=this.stringFormatter)}},{key:"format",value:function(t,e){return Array.isArray(e)?this.formatter(t,e[0],e[1]):this.formatter(t,e,null)}},{key:"stringFormatter",value:function(t,e){var i=arguments.length<=2||void 0===arguments[2]?null:arguments[2],a=i;return null===i&&(a=this.getDefaultFormattedValue(e)),this.expression.split("{l}").join(t).split("{v}").join(e).split("{f}").join(a)}},{key:"getDefaultFormattedValue",value:function(t){return t.toLocaleString()}}]),t}(),r=function(){function t(){e(this,t)}return i(t,[{key:"plot",value:function(t){var e="";return t.forEach(function(t){e+=t[0]+t[1]+","+t[2]+" "}),e.replace(/ +/g," ").trim()}}]),t}(),h=function(){function t(){e(this,t)}return i(t,null,[{key:"extend",value:function(e,i){var a=void 0;for(a in i)i.hasOwnProperty(a)&&("object"!=typeof i[a]||Array.isArray(i[a])?e[a]=i[a]:"object"!=typeof e[a]||Array.isArray(e[a])?e[a]=t.extend({},i[a]):e[a]=t.extend(e[a],i[a]));return e}}]),t}();return a});
!function(t,e){"function"==typeof define&&define.amd?define(["d3"],e):"object"==typeof exports?module.exports=e(require("d3")):t.D3Funnel=e(t.d3)}(this,function(t){"use strict";function e(t){return t&&"undefined"!=typeof Symbol&&t.constructor===Symbol?"symbol":typeof t}function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var a=function(){function t(t,e){for(var i=0;i<e.length;i++){var a=e[i];a.enumerable=a.enumerable||!1,a.configurable=!0,"value"in a&&(a.writable=!0),Object.defineProperty(t,a.key,a)}}return function(e,i,a){return i&&t(e.prototype,i),a&&t(e,a),e}}(),n=function(){function e(t){i(this,e),this.selector=t,this.colorizer=new l,this.labelFormatter=new r,this.navigator=new h}return a(e,[{key:"destroy",value:function(){var e=t.select(this.selector);e.selectAll("svg").remove(),e.selectAll("*").remove(),e.text("")}},{key:"draw",value:function(t){var e=arguments.length<=1||void 0===arguments[1]?{}:arguments[1];this.destroy(),this._initialize(t,e),this._draw()}},{key:"_initialize",value:function(t,e){this._validateData(t);var i=this._getSettings(e);this.label=i.label,this.labelFormatter.setFormat(this.label.format),this.colorizer.setLabelFill(i.label.fill),this.colorizer.setScale(i.block.fill.scale),this.width=i.chart.width,this.height=i.chart.height,this.bottomWidth=i.chart.width*i.chart.bottomWidth,this.bottomPinch=i.chart.bottomPinch,this.isInverted=i.chart.inverted,this.isCurved=i.chart.curve.enabled,this.curveHeight=i.chart.curve.height,this.fillType=i.block.fill.type,this.hoverEffects=i.block.highlight,this.dynamicHeight=i.block.dynamicHeight,this.minHeight=i.block.minHeight,this.animation=i.chart.animate,this.onBlockClick=i.events.click.block,this._setBlocks(t),this.bottomLeftX=(this.width-this.bottomWidth)/2,this.dx=this._getDx(),this.dy=this._getDy()}},{key:"_validateData",value:function(t){if(Array.isArray(t)===!1)throw new Error("Data must be an array.");if(0===t.length)throw new Error("Data array must contain at least one element.");if(Array.isArray(t[0])===!1)throw new Error("Data array elements must be arrays.");if(t[0].length<2)throw new Error("Data array elements must contain a label and value.")}},{key:"_getSettings",value:function(i){var a=o.extend({},e.defaults);return a.chart.width=parseInt(t.select(this.selector).style("width"),10),a.chart.height=parseInt(t.select(this.selector).style("height"),10),a=o.extend(a,i),a.chart.width<=0&&(a.chart.width=e.defaults.chart.width),a.chart.height<=0&&(a.chart.height=e.defaults.chart.height),a}},{key:"_setBlocks",value:function(t){var e=this._getTotalCount(t);this.blocks=this._standardizeData(t,e)}},{key:"_getTotalCount",value:function(t){var e=this,i=0;return t.forEach(function(t){i+=e._getRawBlockCount(t)}),i}},{key:"_standardizeData",value:function(t,e){var i=this,a=[],n=void 0,l=void 0,r=void 0;return t.forEach(function(t,h){n=i._getRawBlockCount(t),l=n/e,r=t[0],a.push({index:h,value:n,ratio:l,height:i.height*l,fill:i.colorizer.getBlockFill(t,h,i.fillType),label:{raw:r,formatted:i.labelFormatter.format(r,n),color:i.colorizer.getLabelFill(t)}})}),a}},{key:"_getRawBlockCount",value:function(t){return Array.isArray(t[1])?t[1][0]:t[1]}},{key:"_getDx",value:function(){return this.bottomPinch>0?this.bottomLeftX/(this.blocks.length-this.bottomPinch):this.bottomLeftX/this.blocks.length}},{key:"_getDy",value:function(){return this.isCurved?(this.height-this.curveHeight)/this.blocks.length:this.height/this.blocks.length}},{key:"_draw",value:function(){this.svg=t.select(this.selector).append("svg").attr("width",this.width).attr("height",this.height),this.blockPaths=this._makePaths(),"gradient"===this.fillType&&this._defineColorGradients(this.svg),this.isCurved&&this._drawTopOval(this.svg,this.blockPaths),this._drawBlock(0)}},{key:"_makePaths",value:function(){var t=this,e=[],i=this.dx,a=this.dy,n=0,l=this.width,r=0;this.isInverted&&(n=this.bottomLeftX,l=this.width-this.bottomLeftX);var h=0,o=0,s=0,c=this.width/2;this.isCurved&&(r=10);var u=this.height;0!==this.minHeight&&(u=this.height-this.minHeight*this.blocks.length);var f=this.height;this.blocks.forEach(function(e,i){t.bottomPinch>0&&(t.isInverted?i<t.bottomPinch&&(f-=e.height):i>=t.blocks.length-t.bottomPinch&&(f-=e.height))});var d=2*f/(this.width-this.bottomWidth);return this.blocks.forEach(function(f,v){t.dynamicHeight&&(a=u*f.ratio,0!==t.minHeight&&(a+=t.minHeight),t.isCurved&&(a-=t.curveHeight/t.blocks.length),h=(r+a)/d,t.isInverted&&(h=(r+a-t.height)/(-1*d)),0===t.bottomWidth&&v===t.blocks.length-1&&(h=t.width/2,t.isInverted&&(h=0)),t.bottomWidth===t.width&&(h=n),i=h-n,t.isInverted&&(i=n-h)),t.bottomPinch>0&&(t.isInverted?(t.dynamicHeight||(i=t.dx),i=v<t.bottomPinch?0:i):v>=t.blocks.length-t.bottomPinch&&(i=0)),h=n+i,o=l-i,s=r+a,t.isInverted&&(h=n-i,o=l+i),t.isCurved?e.push([[n,r,"M"],[c,r+(t.curveHeight-10),"Q"],[l,r,""],[o,s,"L"],[o,s,"M"],[c,s+t.curveHeight,"Q"],[h,s,""],[n,r,"L"]]):e.push([[n,r,"M"],[l,r,"L"],[o,s,"L"],[h,s,"L"],[n,r,"L"]]),n=h,l=o,r=s}),e}},{key:"_defineColorGradients",value:function(t){var e=t.append("defs");this.blocks.forEach(function(t,i){var a=t.fill.raw,n=l.shade(a,-.2),r=e.append("linearGradient").attr({id:"gradient-"+i}),h=[[0,n],[40,a],[60,a],[100,n]];h.forEach(function(t){r.append("stop").attr({offset:t[0]+"%",style:"stop-color:"+t[1]})})})}},{key:"_drawTopOval",value:function(t,e){var i=0,a=this.width,n=this.width/2;this.isInverted&&(i=this.bottomLeftX,a=this.width-this.bottomLeftX);var r=e[0],h=r[1][1]+this.curveHeight-10,o=this.navigator.plot([["M",i,r[0][1]],["Q",n,h],[" ",a,r[2][1]],["M",a,10],["Q",n,0],[" ",i,10]]);t.append("path").attr("fill",l.shade(this.blocks[0].fill.raw,-.4)).attr("d",o)}},{key:"_drawBlock",value:function(t){var e=this;if(t!==this.blocks.length){var i=this.svg.append("g"),a=this._getBlockPath(i,t);a.data(this._getD3Data(t)),0!==this.animation?a.transition().duration(this.animation).ease("linear").attr("fill",this.blocks[t].fill.actual).attr("d",this._getPathDefinition(t)).each("end",function(){e._drawBlock(t+1)}):(a.attr("fill",this.blocks[t].fill.actual).attr("d",this._getPathDefinition(t)),this._drawBlock(t+1)),this.hoverEffects&&a.on("mouseover",this._onMouseOver).on("mouseout",this._onMouseOut),null!==this.onBlockClick&&a.on("click",this.onBlockClick),this._addBlockLabel(i,t)}}},{key:"_getBlockPath",value:function(t,e){var i=t.append("path");return 0!==this.animation&&this._addBeforeTransition(i,e),i}},{key:"_addBeforeTransition",value:function(t,e){var i=this.blockPaths[e],a="",n="";a=this.isCurved?this.navigator.plot([["M",i[0][0],i[0][1]],["Q",i[1][0],i[1][1]],[" ",i[2][0],i[2][1]],["L",i[2][0],i[2][1]],["M",i[2][0],i[2][1]],["Q",i[1][0],i[1][1]],[" ",i[0][0],i[0][1]]]):this.navigator.plot([["M",i[0][0],i[0][1]],["L",i[1][0],i[1][1]],["L",i[1][0],i[1][1]],["L",i[0][0],i[0][1]]]),n="solid"===this.fillType&&e>0?this.blocks[e-1].fill.actual:this.blocks[e].fill.actual,t.attr("d",a).attr("fill",n)}},{key:"_getD3Data",value:function(t){return[this.blocks[t]]}},{key:"_getPathDefinition",value:function(t){var e=[];return this.blockPaths[t].forEach(function(t){e.push([t[2],t[0],t[1]])}),this.navigator.plot(e)}},{key:"_onMouseOver",value:function(e){t.select(this).attr("fill",l.shade(e.fill.raw,-.2))}},{key:"_onMouseOut",value:function(e){t.select(this).attr("fill",e.fill.actual)}},{key:"_addBlockLabel",value:function(t,e){var i=this.blockPaths[e],a=this.blocks[e].label.formatted,n=this.blocks[e].label.color,l=this.width/2,r=this._getTextY(i);t.append("text").text(a).attr({x:l,y:r,"text-anchor":"middle","dominant-baseline":"middle",fill:n,"pointer-events":"none"}).style("font-size",this.label.fontSize)}},{key:"_getTextY",value:function(t){return this.isCurved?(t[2][1]+t[3][1])/2+this.curveHeight/this.blocks.length:(t[1][1]+t[2][1])/2}}]),e}();n.defaults={chart:{width:350,height:400,bottomWidth:1/3,bottomPinch:0,inverted:!1,animate:0,curve:{enabled:!1,height:20}},block:{dynamicHeight:!1,fill:{scale:t.scale.category10().domain(t.range(0,10)),type:"solid"},minHeight:0,highlight:!1},label:{fontSize:"14px",fill:"#fff",format:"{l}: {f}"},events:{click:{block:null}}};var l=function(){function t(){i(this,t),this.hexExpression=/^#([0-9a-f]{3}|[0-9a-f]{6})$/i,this.labelFill=null,this.scale=null}return a(t,[{key:"setLabelFill",value:function(t){this.labelFill=t}},{key:"setScale",value:function(t){this.scale=t}},{key:"getBlockFill",value:function(t,e,i){var a=this.getBlockRawFill(t,e);return{raw:a,actual:this.getBlockActualFill(a,e,i)}}},{key:"getBlockRawFill",value:function(t,e){return t.length>2&&this.hexExpression.test(t[2])?t[2]:Array.isArray(this.scale)?this.scale[e]:this.scale(e)}},{key:"getBlockActualFill",value:function(t,e,i){return"solid"===i?t:"url(#gradient-"+e+")"}},{key:"getLabelFill",value:function(t){return t.length>3&&this.hexExpression.test(t[3])?t[3]:this.labelFill}}],[{key:"shade",value:function(e,i){var a=e.slice(1);3===a.length&&(a=t.expandHex(a));var n=parseInt(a,16),l=0>i?0:255,r=0>i?-1*i:i,h=n>>16,o=n>>8&255,s=255&n,c=16777216+65536*(Math.round((l-h)*r)+h)+256*(Math.round((l-o)*r)+o)+(Math.round((l-s)*r)+s);return"#"+c.toString(16).slice(1)}},{key:"expandHex",value:function(t){return t[0]+t[0]+t[1]+t[1]+t[2]+t[2]}}]),t}(),r=function(){function t(){i(this,t),this.expression=null}return a(t,[{key:"setFormat",value:function(t){"function"==typeof t?this.formatter=t:(this.expression=t,this.formatter=this.stringFormatter)}},{key:"format",value:function(t,e){return Array.isArray(e)?this.formatter(t,e[0],e[1]):this.formatter(t,e,null)}},{key:"stringFormatter",value:function(t,e){var i=arguments.length<=2||void 0===arguments[2]?null:arguments[2],a=i;return null===i&&(a=this.getDefaultFormattedValue(e)),this.expression.split("{l}").join(t).split("{v}").join(e).split("{f}").join(a)}},{key:"getDefaultFormattedValue",value:function(t){return t.toLocaleString()}}]),t}(),h=function(){function t(){i(this,t)}return a(t,[{key:"plot",value:function(t){var e="";return t.forEach(function(t){e+=t[0]+t[1]+","+t[2]+" "}),e.replace(/ +/g," ").trim()}}]),t}(),o=function(){function t(){i(this,t)}return a(t,null,[{key:"extend",value:function(i,a){var n=void 0;for(n in a)a.hasOwnProperty(n)&&("object"!==e(a[n])||Array.isArray(a[n])||null===a[n]?i[n]=a[n]:"object"!==e(i[n])||Array.isArray(i[n])||null===a[n]?i[n]=t.extend({},a[n]):i[n]=t.extend(i[n],a[n]));return i}}]),t}();return n});

@@ -42,3 +42,6 @@ var gulp = require('gulp');

.pipe(babel({
stage: 0,
presets: [
'es2015',
'stage-0',
],
}))

@@ -45,0 +48,0 @@ .pipe(umd(umdOptions))

{
"name": "d3-funnel",
"version": "0.7.1",
"version": "0.7.2",
"description": "A library for rendering SVG funnel charts using D3.js",

@@ -14,9 +14,11 @@ "author": "Jake Zatecky",

"devDependencies": {
"babel-eslint": "^4.1.3",
"babel-eslint": "^4.1.5",
"babel-preset-es2015": "^6.1.2",
"babel-preset-stage-0": "^6.1.2",
"chai": "^3.4.0",
"chai-spies": "^0.7.1",
"eslint": "^1.7.3",
"eslint-config-airbnb": "^0.1.0",
"eslint": "^1.9.0",
"eslint-config-airbnb": "^1.0.0",
"gulp": "^3.9.0",
"gulp-babel": "^5.3.0",
"gulp-babel": "^6.1.0",
"gulp-concat": "^2.6.0",

@@ -23,0 +25,0 @@ "gulp-eslint": "^1.0.0",

@@ -60,21 +60,21 @@ # D3 Funnel

| Option | Description | Type | Default |
| --------------------- | --------------------------------------------------------------------------- | -------------- | ----------------------- |
| `chart.width` | The pixel width of the chart. | int | Container's width |
| `chart.height` | The pixel height of the chart. | int | Container's height |
| `chart.bottomWidth` | The percent of total width the bottom should be. | float | `1 / 3` |
| `chart.bottomPinch` | How many blocks to pinch on the bottom to create a "neck". | int | `0` |
| `chart.inverted` | Whether the funnel is inverted (like a pyramid). | bool | `false` |
| `chart.animate` | The load animation speed in milliseconds. | int/bool | `false` |
| `chart.curve.enabled` | Whether the funnel is curved. | bool | `false` |
| `chart.curve.height` | The curvature amount. | int | `20` |
| `block.dynamicHeight` | Whether the block heights are proportional to its weight. | bool | `false` |
| `block.fill.scale` | The block background color scale. Expects an index and returns a color. | function/array | `d3.scale.category10()` |
| `block.fill.type` | Either `'solid'` or `'gradient'`. | string | `'solid'` |
| `block.minHeight` | The minimum pixel height of a block. | int/bool | `false` |
| `block.highlight` | Whether the blocks are highlighted on hover. | bool | `false` |
| `label.fontSize` | Any valid font size for the labels. | string | `'14px'` |
| `label.fill` | Any valid hex color for the label color | string | `'#fff'` |
| `label.format` | Either `function(label, value)` or a format string. See below. | function/array | `'{l}: {f}'` |
| `events.click.block` | Callback for when a block is clicked. | function | `null` |
| Option | Description | Type | Default |
| --------------------- | ------------------------------------------------------------------------- | -------- | ----------------------- |
| `chart.width` | The pixel width of the chart. | number | Container's width |
| `chart.height` | The pixel height of the chart. | number | Container's height |
| `chart.bottomWidth` | The percent of total width the bottom should be. | number | `1 / 3` |
| `chart.bottomPinch` | How many blocks to pinch on the bottom to create a funnel "neck". | number | `0` |
| `chart.inverted` | Whether the funnel is inverted (like a pyramid). | bool | `false` |
| `chart.animate` | The load animation speed in milliseconds. | number | `0` (disabled) |
| `chart.curve.enabled` | Whether the funnel is curved. | bool | `false` |
| `chart.curve.height` | The curvature amount. | number | `20` |
| `block.dynamicHeight` | Whether the block heights are proportional to its weight. | bool | `false` |
| `block.fill.scale` | The background color scale as an array or function. | mixed | `d3.scale.category10()` |
| `block.fill.type` | Either `'solid'` or `'gradient'`. | string | `'solid'` |
| `block.minHeight` | The minimum pixel height of a block. | number | `0` |
| `block.highlight` | Whether the blocks are highlighted on hover. | bool | `false` |
| `label.fontSize` | Any valid font size for the labels. | string | `'14px'` |
| `label.fill` | Any valid hex color for the label color. | string | `'#fff'` |
| `label.format` | Either `function(label, value)`, an array, or a format string. See below. | mixed | `'{l}: {f}'` |
| `events.click.block` | Callback `function(data)` for when a block is clicked. | function | `null` |

@@ -92,2 +92,30 @@ ### Label Format

### Event Data
Block-based events are passed a `data` object containing the following elements:
| Key | Type | Description |
| --------------- | ------ | ------------------------------------- |
| index | number | The index of the block. |
| value | number | The numerical value. |
| fill | string | The background color. |
| label.raw | string | The unformatted label. |
| label.formatted | string | The result of `options.label.format`. |
| label.color | string | The label color. |
Example:
``` javascript
{
index: 0,
value: 150,
fill: '#c33',
label: {
raw: 'Visitors',
formatted: 'Visitors: 150',
color: '#fff',
},
},
```
### Overriding Defaults

@@ -94,0 +122,0 @@

@@ -42,3 +42,3 @@ /* exported Colorizer */

getBlockFill(block, index, type) {
let raw = this.getBlockRawFill(block, index);
const raw = this.getBlockRawFill(block, index);

@@ -122,11 +122,11 @@ return {

let f = parseInt(hex, 16);
let t = shade < 0 ? 0 : 255;
let p = shade < 0 ? shade * -1 : shade;
const f = parseInt(hex, 16);
const t = shade < 0 ? 0 : 255;
const p = shade < 0 ? shade * -1 : shade;
let R = f >> 16;
let G = f >> 8 & 0x00FF;
let B = f & 0x0000FF;
const R = f >> 16;
const G = f >> 8 & 0x00FF;
const B = f & 0x0000FF;
let converted = 0x1000000 +
const converted = 0x1000000 +
(Math.round((t - R) * p) + R) * 0x10000 +

@@ -133,0 +133,0 @@ (Math.round((t - G) * p) + G) * 0x100 +

@@ -13,3 +13,3 @@ /* global d3, Colorizer, LabelFormatter, Navigator, Utils */

inverted: false,
animate: false,
animate: 0,
curve: {

@@ -26,3 +26,3 @@ enabled: false,

},
minHeight: false,
minHeight: 0,
highlight: false,

@@ -63,3 +63,4 @@ },

destroy() {
let container = d3.select(this.selector);
const container = d3.select(this.selector);
// D3's remove method appears to be sufficient for removing the events

@@ -106,3 +107,3 @@ container.selectAll('svg').remove();

let settings = this._getSettings(options);
const settings = this._getSettings(options);

@@ -205,3 +206,3 @@ // Set labels

_setBlocks(data) {
let totalCount = this._getTotalCount(data);
const totalCount = this._getTotalCount(data);

@@ -235,3 +236,3 @@ this.blocks = this._standardizeData(data, totalCount);

_standardizeData(data, totalCount) {
let standardized = [];
const standardized = [];

@@ -252,3 +253,2 @@ let count;

height: this.height * ratio,
formatted: this.labelFormatter.format(label, count),
fill: this.colorizer.getBlockFill(block, index, this.fillType),

@@ -258,3 +258,3 @@ label: {

formatted: this.labelFormatter.format(label, count),
color: this.colorizer.getLabelFill(block, index),
color: this.colorizer.getLabelFill(block),
},

@@ -337,3 +337,3 @@ });

_makePaths() {
let paths = [];
const paths = [];

@@ -360,3 +360,3 @@ // Initialize velocity

let middle = this.width / 2;
const middle = this.width / 2;

@@ -373,3 +373,3 @@ // Move down if there is an initial curve

// shared according to the remaining minus the guaranteed
if (this.minHeight !== false) {
if (this.minHeight !== 0) {
totalHeight = this.height - this.minHeight * this.blocks.length;

@@ -396,3 +396,3 @@ }

// iteration
let slope = 2 * slopeHeight / (this.width - this.bottomWidth);
const slope = 2 * slopeHeight / (this.width - this.bottomWidth);

@@ -408,3 +408,3 @@ // Create the path definition for each funnel block

// Add greedy minimum height
if (this.minHeight !== false) {
if (this.minHeight !== 0) {
dy += this.minHeight;

@@ -536,11 +536,11 @@ }

_defineColorGradients(svg) {
let defs = svg.append('defs');
const defs = svg.append('defs');
// Create a gradient for each block
this.blocks.forEach((block, index) => {
let color = block.fill.raw;
let shade = Colorizer.shade(color, -0.2);
const color = block.fill.raw;
const shade = Colorizer.shade(color, -0.2);
// Create linear gradient
let gradient = defs.append('linearGradient')
const gradient = defs.append('linearGradient')
.attr({

@@ -551,3 +551,3 @@ id: 'gradient-' + index,

// Define the gradient stops
let stops = [
const stops = [
[0, shade],

@@ -580,3 +580,3 @@ [40, color],

let rightX = this.width;
let centerX = this.width / 2;
const centerX = this.width / 2;

@@ -589,6 +589,6 @@ if (this.isInverted) {

// Create path from top-most block
let paths = blockPaths[0];
let topCurve = paths[1][1] + this.curveHeight - 10;
const paths = blockPaths[0];
const topCurve = paths[1][1] + this.curveHeight - 10;
let path = this.navigator.plot([
const path = this.navigator.plot([
['M', leftX, paths[0][1]],

@@ -621,10 +621,10 @@ ['Q', centerX, topCurve],

// Create a group just for this block
let group = this.svg.append('g');
const group = this.svg.append('g');
// Fetch path element
let path = this._getBlockPath(group, index);
const path = this._getBlockPath(group, index);
path.data(this._getD3Data(index));
// Add animation components
if (this.animation !== false) {
if (this.animation !== 0) {
path.transition()

@@ -665,5 +665,5 @@ .duration(this.animation)

_getBlockPath(group, index) {
let path = group.append('path');
const path = group.append('path');
if (this.animation !== false) {
if (this.animation !== 0) {
this._addBeforeTransition(path, index);

@@ -684,3 +684,3 @@ }

_addBeforeTransition(path, index) {
let paths = this.blockPaths[index];
const paths = this.blockPaths[index];

@@ -740,3 +740,3 @@ let beforePath = '';

_getPathDefinition(index) {
let commands = [];
const commands = [];

@@ -759,3 +759,3 @@ this.blockPaths[index].forEach((command) => {

/**
/**
* @param {Object} data

@@ -775,9 +775,9 @@ *

_addBlockLabel(group, index) {
let paths = this.blockPaths[index];
const paths = this.blockPaths[index];
let text = this.blocks[index].label.formatted;
let fill = this.blocks[index].label.color;
const text = this.blocks[index].label.formatted;
const fill = this.blocks[index].label.color;
let x = this.width / 2; // Center the text
let y = this._getTextY(paths);
const x = this.width / 2; // Center the text
const y = this._getTextY(paths);

@@ -784,0 +784,0 @@ group.append('text')

@@ -21,4 +21,4 @@ /* exported Utils */

if (b.hasOwnProperty(prop)) {
if (typeof b[prop] === 'object' && !Array.isArray(b[prop])) {
if (typeof a[prop] === 'object' && !Array.isArray(a[prop])) {
if (typeof b[prop] === 'object' && !Array.isArray(b[prop]) && b[prop] !== null) {
if (typeof a[prop] === 'object' && !Array.isArray(a[prop]) && b[prop] !== null) {
a[prop] = Utils.extend(a[prop], b[prop]);

@@ -25,0 +25,0 @@ } else {

@@ -15,12 +15,35 @@ /* global d3, assert, chai, D3Funnel */

function getPathBottomWidth(path) {
var commands = path.attr('d').split(' ');
return getCommandPoint(commands[2]).x - getCommandPoint(commands[3]).x;
}
function getPathHeight(path) {
var commands = path.attr('d').split(' ');
return getCommandHeight(commands[2]) - getCommandHeight(commands[0]);
return getCommandPoint(commands[2]).y - getCommandPoint(commands[0]).y;
}
function getCommandHeight(command) {
return parseFloat(command.split(',')[1]);
function getCommandPoint(command) {
var points = command.split(',');
var x = points[0];
var y = points[1];
// Strip any letter in front of number
if (isLetter(x[0])) {
x = x.substr(1);
}
return {
x: parseFloat(x),
y: parseFloat(y),
};
}
function isLetter(str) {
return str.length === 1 && str.match(/[a-z]/i);
}
var defaults = _.clone(D3Funnel.defaults, true);

@@ -140,4 +163,4 @@

it('should remove other elements from container', function () {
var container = d3.select('#funnel'),
funnel = getFunnel();
var container = d3.select('#funnel');
var funnel = getFunnel();

@@ -150,6 +173,5 @@ // Make sure the container has no children

var funnelChildrenSize = getSvg().selectAll('*').size(),
// expect funnel children count plus funnel itself
expected = funnelChildrenSize + 1,
actual = container.selectAll('*').size();
// Expect funnel children count plus funnel itself
var expected = getSvg().selectAll('*').size() + 1;
var actual = container.selectAll('*').size();

@@ -160,4 +182,4 @@ assert.equal(expected, actual);

it('should remove inner text from container', function () {
var container = d3.select('#funnel'),
funnel = getFunnel();
var container = d3.select('#funnel');
var funnel = getFunnel();

@@ -199,3 +221,3 @@ // Make sure the container has no text

describe('chart.width', function () {
it ('should default to the container\'s width', function () {
it('should default to the container\'s width', function () {
d3.select('#funnel').style('width', '250px');

@@ -220,3 +242,3 @@

describe('chart.height', function () {
it ('should default to the container\'s height', function () {
it('should default to the container\'s height', function () {
d3.select('#funnel').style('height', '250px');

@@ -240,2 +262,36 @@

describe('chart.bottomWidth', function () {
it('should set the bottom tip width to the specified percentage', function () {
getFunnel().draw(getBasicData(), {
chart: {
width: 200,
bottomWidth: 1 / 2,
},
});
assert.equal(100, getPathBottomWidth(d3.select('path')));
});
});
describe('chart.bottomPinch', function () {
it('should set the last n number of blocks to have the width of chart.bottomWidth', function () {
getFunnel().draw([
['A', 1],
['B', 2],
['C', 3],
], {
chart: {
width: 450,
bottomWidth: 1 / 3,
bottomPinch: 2,
},
});
var paths = d3.selectAll('path');
assert.equal(150, paths[0][1].getBBox().width);
assert.equal(150, paths[0][2].getBBox().width);
});
});
describe('chart.curve.enabled', function () {

@@ -334,8 +390,6 @@ it('should create an additional path on top of the trapezoids', function () {

assert.equal(-1, d3.select(paths[3]).attr('d').indexOf('NaN'))
assert.equal(-1, d3.select(paths[3]).attr('d').indexOf('NaN'));
});
it('should not error when bottomWidth is equal to 100%', function () {
var paths;
getFunnel().draw([

@@ -353,5 +407,2 @@ ['A', 1],

});
paths = d3.selectAll('#funnel path')[0];
});

@@ -362,2 +413,4 @@ });

it('should use a function\'s return value', function () {
var paths;
getFunnel().draw([

@@ -387,2 +440,4 @@ ['A', 1],

it('should use an array\'s return value', function () {
var paths;
getFunnel().draw([

@@ -544,4 +599,4 @@ ['A', 1],

return label + '/' + value + '/' + fValue;
}
}
},
},
});

@@ -582,4 +637,19 @@

});
it('should not trigger when null', function () {
var event = document.createEvent('CustomEvent');
event.initCustomEvent('click', false, false, null);
getFunnel().draw(getBasicData(), {
events: {
click: {
block: null,
},
},
});
d3.select('#funnel path').node().dispatchEvent(event);
});
});
});
});

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc