Comparing version 0.7.3 to 0.7.4
@@ -0,1 +1,12 @@ | ||
## v0.7.4 (December 11, 2015) | ||
## Build Changes | ||
* [#42]: Use ES6 imports and exports in source files | ||
* [#43]: Require D3.js for CommonJS environments | ||
## v0.7.3 (skipped) | ||
D3Funnel v0.7.3 is an NPM-only hotfix that adds in missing compiled files. | ||
## v0.7.2 (November 18, 2015) | ||
@@ -2,0 +13,0 @@ |
@@ -0,1203 +1,1344 @@ | ||
(function webpackUniversalModuleDefinition(root, factory) { | ||
if(typeof exports === 'object' && typeof module === 'object') | ||
module.exports = factory(require("d3")); | ||
else if(typeof define === 'function' && define.amd) | ||
define(["d3"], factory); | ||
else if(typeof exports === 'object') | ||
exports["D3Funnel"] = factory(require("d3")); | ||
else | ||
root["D3Funnel"] = factory(root["d3"]); | ||
})(this, function(__WEBPACK_EXTERNAL_MODULE_2__) { | ||
return /******/ (function(modules) { // webpackBootstrap | ||
/******/ // The module cache | ||
/******/ var installedModules = {}; | ||
(function(root, factory) { | ||
if (typeof define === 'function' && define.amd) { | ||
define(["d3"], factory); | ||
} else if (typeof exports === 'object') { | ||
module.exports = factory(require('d3')); | ||
} else { | ||
root.D3Funnel = factory(root.d3); | ||
} | ||
}(this, function(d3) { | ||
/******/ // The require function | ||
/******/ function __webpack_require__(moduleId) { | ||
'use strict'; | ||
/******/ // Check if module is in cache | ||
/******/ if(installedModules[moduleId]) | ||
/******/ return installedModules[moduleId].exports; | ||
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; }; })(); | ||
/******/ // Create a new module (and put it into the cache) | ||
/******/ var module = installedModules[moduleId] = { | ||
/******/ exports: {}, | ||
/******/ id: moduleId, | ||
/******/ loaded: false | ||
/******/ }; | ||
function _typeof(obj) { return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj; } | ||
/******/ // Execute the module function | ||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
/******/ // Flag the module as loaded | ||
/******/ module.loaded = true; | ||
/* global d3, Colorizer, LabelFormatter, Navigator, Utils */ | ||
/* exported D3Funnel */ | ||
/******/ // Return the exports of the module | ||
/******/ return module.exports; | ||
/******/ } | ||
var D3Funnel = (function () { | ||
/** | ||
* @param {string} selector A selector for the container element. | ||
* | ||
* @return {void} | ||
*/ | ||
/******/ // expose the modules object (__webpack_modules__) | ||
/******/ __webpack_require__.m = modules; | ||
function D3Funnel(selector) { | ||
_classCallCheck(this, D3Funnel); | ||
/******/ // expose the module cache | ||
/******/ __webpack_require__.c = installedModules; | ||
this.selector = selector; | ||
/******/ // __webpack_public_path__ | ||
/******/ __webpack_require__.p = ""; | ||
this.colorizer = new Colorizer(); | ||
/******/ // Load entry module and return exports | ||
/******/ return __webpack_require__(0); | ||
/******/ }) | ||
/************************************************************************/ | ||
/******/ ([ | ||
/* 0 */ | ||
/***/ function(module, exports, __webpack_require__) { | ||
this.labelFormatter = new LabelFormatter(); | ||
'use strict'; | ||
this.navigator = new Navigator(); | ||
} | ||
// Use CommonJS export to trick Webpack into working around the issues that | ||
// window.[module].default is set rather than window.[module] | ||
// | ||
// See: https://github.com/webpack/webpack/issues/706 | ||
/** | ||
* Remove the funnel and its events from the DOM. | ||
* | ||
* @return {void} | ||
*/ | ||
module.exports = __webpack_require__(1).default; | ||
_createClass(D3Funnel, [{ | ||
key: 'destroy', | ||
value: function destroy() { | ||
var container = d3.select(this.selector); | ||
/***/ }, | ||
/* 1 */ | ||
/***/ function(module, exports, __webpack_require__) { | ||
// D3's remove method appears to be sufficient for removing the events | ||
container.selectAll('svg').remove(); | ||
'use strict'; | ||
// Remove other elements from container | ||
container.selectAll('*').remove(); | ||
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; }; })(); | ||
// Remove inner text from container | ||
container.text(''); | ||
} | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
/** | ||
* Draw the chart inside the container with the data and configuration | ||
* specified. This will remove any previous SVG elements in the container | ||
* and draw a new funnel chart on top of it. | ||
* | ||
* @param {Array} data A list of rows containing a category, a count, | ||
* and optionally a color (in hex). | ||
* @param {Object} options An optional configuration object to override | ||
* defaults. See the docs. | ||
* | ||
* @return {void} | ||
*/ | ||
var _d = __webpack_require__(2); | ||
}, { | ||
key: 'draw', | ||
value: function draw(data) { | ||
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
var _d2 = _interopRequireDefault(_d); | ||
this.destroy(); | ||
var _colorizer = __webpack_require__(3); | ||
this._initialize(data, options); | ||
var _colorizer2 = _interopRequireDefault(_colorizer); | ||
this._draw(); | ||
} | ||
var _labelFormatter = __webpack_require__(4); | ||
/** | ||
* Initialize and calculate important variables for drawing the chart. | ||
* | ||
* @param {Array} data | ||
* @param {Object} options | ||
* | ||
* @return {void} | ||
*/ | ||
var _labelFormatter2 = _interopRequireDefault(_labelFormatter); | ||
}, { | ||
key: '_initialize', | ||
value: function _initialize(data, options) { | ||
this._validateData(data); | ||
var _navigator = __webpack_require__(5); | ||
var settings = this._getSettings(options); | ||
var _navigator2 = _interopRequireDefault(_navigator); | ||
// Set labels | ||
this.label = settings.label; | ||
this.labelFormatter.setFormat(this.label.format); | ||
var _utils = __webpack_require__(6); | ||
// Set color scales | ||
this.colorizer.setLabelFill(settings.label.fill); | ||
this.colorizer.setScale(settings.block.fill.scale); | ||
var _utils2 = _interopRequireDefault(_utils); | ||
// Initialize funnel chart settings | ||
this.width = settings.chart.width; | ||
this.height = settings.chart.height; | ||
this.bottomWidth = settings.chart.width * settings.chart.bottomWidth; | ||
this.bottomPinch = settings.chart.bottomPinch; | ||
this.isInverted = settings.chart.inverted; | ||
this.isCurved = settings.chart.curve.enabled; | ||
this.curveHeight = settings.chart.curve.height; | ||
this.fillType = settings.block.fill.type; | ||
this.hoverEffects = settings.block.highlight; | ||
this.dynamicHeight = settings.block.dynamicHeight; | ||
this.minHeight = settings.block.minHeight; | ||
this.animation = settings.chart.animate; | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
// Support for events | ||
this.onBlockClick = settings.events.click.block; | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
this._setBlocks(data); | ||
var D3Funnel = (function () { | ||
// Calculate the bottom left x position | ||
this.bottomLeftX = (this.width - this.bottomWidth) / 2; | ||
/** | ||
* @param {string} selector A selector for the container element. | ||
* | ||
* @return {void} | ||
*/ | ||
// Change in x direction | ||
this.dx = this._getDx(); | ||
function D3Funnel(selector) { | ||
_classCallCheck(this, D3Funnel); | ||
// Change in y direction | ||
this.dy = this._getDy(); | ||
this.selector = selector; | ||
this.colorizer = new _colorizer2.default(); | ||
this.labelFormatter = new _labelFormatter2.default(); | ||
this.navigator = new _navigator2.default(); | ||
} | ||
/** | ||
* @param {Array} data | ||
* | ||
* @return void | ||
*/ | ||
* Remove the funnel and its events from the DOM. | ||
* | ||
* @return {void} | ||
*/ | ||
}, { | ||
key: '_validateData', | ||
value: function _validateData(data) { | ||
if (Array.isArray(data) === false) { | ||
throw new Error('Data must be an array.'); | ||
} | ||
_createClass(D3Funnel, [{ | ||
key: 'destroy', | ||
value: function destroy() { | ||
var container = _d2.default.select(this.selector); | ||
if (data.length === 0) { | ||
throw new Error('Data array must contain at least one element.'); | ||
} | ||
// D3's remove method appears to be sufficient for removing the events | ||
container.selectAll('svg').remove(); | ||
if (Array.isArray(data[0]) === false) { | ||
throw new Error('Data array elements must be arrays.'); | ||
} | ||
// Remove other elements from container | ||
container.selectAll('*').remove(); | ||
if (data[0].length < 2) { | ||
throw new Error('Data array elements must contain a label and value.'); | ||
// Remove inner text from container | ||
container.text(''); | ||
} | ||
} | ||
/** | ||
* @param {Object} options | ||
* | ||
* @returns {Object} | ||
*/ | ||
/** | ||
* Draw the chart inside the container with the data and configuration | ||
* specified. This will remove any previous SVG elements in the container | ||
* and draw a new funnel chart on top of it. | ||
* | ||
* @param {Array} data A list of rows containing a category, a count, | ||
* and optionally a color (in hex). | ||
* @param {Object} options An optional configuration object to override | ||
* defaults. See the docs. | ||
* | ||
* @return {void} | ||
*/ | ||
}, { | ||
key: '_getSettings', | ||
value: function _getSettings(options) { | ||
// Prepare the configuration settings based on the defaults | ||
// Set the default width and height based on the container | ||
var settings = Utils.extend({}, D3Funnel.defaults); | ||
settings.chart.width = parseInt(d3.select(this.selector).style('width'), 10); | ||
settings.chart.height = parseInt(d3.select(this.selector).style('height'), 10); | ||
}, { | ||
key: 'draw', | ||
value: function draw(data) { | ||
var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; | ||
// Overwrite default settings with user options | ||
settings = Utils.extend(settings, options); | ||
this.destroy(); | ||
// In the case that the width or height is not valid, set | ||
// the width/height as its default hard-coded value | ||
if (settings.chart.width <= 0) { | ||
settings.chart.width = D3Funnel.defaults.chart.width; | ||
this._initialize(data, options); | ||
this._draw(); | ||
} | ||
if (settings.chart.height <= 0) { | ||
settings.chart.height = D3Funnel.defaults.chart.height; | ||
} | ||
return settings; | ||
} | ||
/** | ||
* Initialize and calculate important variables for drawing the chart. | ||
* | ||
* @param {Array} data | ||
* @param {Object} options | ||
* | ||
* @return {void} | ||
*/ | ||
/** | ||
* Register the raw data into a standard block format and pre-calculate | ||
* some values. | ||
* | ||
* @param {Array} data | ||
* | ||
* @return void | ||
*/ | ||
}, { | ||
key: '_initialize', | ||
value: function _initialize(data, options) { | ||
this._validateData(data); | ||
}, { | ||
key: '_setBlocks', | ||
value: function _setBlocks(data) { | ||
var totalCount = this._getTotalCount(data); | ||
var settings = this._getSettings(options); | ||
this.blocks = this._standardizeData(data, totalCount); | ||
} | ||
// Set labels | ||
this.label = settings.label; | ||
this.labelFormatter.setFormat(this.label.format); | ||
/** | ||
* Return the total count of all blocks. | ||
* | ||
* @return {Number} | ||
*/ | ||
// Set color scales | ||
this.colorizer.setLabelFill(settings.label.fill); | ||
this.colorizer.setScale(settings.block.fill.scale); | ||
}, { | ||
key: '_getTotalCount', | ||
value: function _getTotalCount(data) { | ||
var _this = this; | ||
// Initialize funnel chart settings | ||
this.width = settings.chart.width; | ||
this.height = settings.chart.height; | ||
this.bottomWidth = settings.chart.width * settings.chart.bottomWidth; | ||
this.bottomPinch = settings.chart.bottomPinch; | ||
this.isInverted = settings.chart.inverted; | ||
this.isCurved = settings.chart.curve.enabled; | ||
this.curveHeight = settings.chart.curve.height; | ||
this.fillType = settings.block.fill.type; | ||
this.hoverEffects = settings.block.highlight; | ||
this.dynamicHeight = settings.block.dynamicHeight; | ||
this.minHeight = settings.block.minHeight; | ||
this.animation = settings.chart.animate; | ||
var total = 0; | ||
// Support for events | ||
this.onBlockClick = settings.events.click.block; | ||
data.forEach(function (block) { | ||
total += _this._getRawBlockCount(block); | ||
}); | ||
this._setBlocks(data); | ||
return total; | ||
} | ||
// Calculate the bottom left x position | ||
this.bottomLeftX = (this.width - this.bottomWidth) / 2; | ||
/** | ||
* Convert the raw data into a standardized format. | ||
* | ||
* @param {Array} data | ||
* @param {Number} totalCount | ||
* | ||
* @return {Array} | ||
*/ | ||
// Change in x direction | ||
this.dx = this._getDx(); | ||
}, { | ||
key: '_standardizeData', | ||
value: function _standardizeData(data, totalCount) { | ||
var _this2 = this; | ||
// Change in y direction | ||
this.dy = this._getDy(); | ||
} | ||
var standardized = []; | ||
/** | ||
* @param {Array} data | ||
* | ||
* @return void | ||
*/ | ||
var count = undefined; | ||
var ratio = undefined; | ||
var label = undefined; | ||
}, { | ||
key: '_validateData', | ||
value: function _validateData(data) { | ||
if (Array.isArray(data) === false) { | ||
throw new Error('Data must be an array.'); | ||
} | ||
data.forEach(function (block, index) { | ||
count = _this2._getRawBlockCount(block); | ||
ratio = count / totalCount; | ||
label = block[0]; | ||
if (data.length === 0) { | ||
throw new Error('Data array must contain at least one element.'); | ||
} | ||
standardized.push({ | ||
index: index, | ||
value: count, | ||
ratio: ratio, | ||
height: _this2.height * ratio, | ||
fill: _this2.colorizer.getBlockFill(block, index, _this2.fillType), | ||
label: { | ||
raw: label, | ||
formatted: _this2.labelFormatter.format(label, count), | ||
color: _this2.colorizer.getLabelFill(block) | ||
} | ||
}); | ||
}); | ||
if (Array.isArray(data[0]) === false) { | ||
throw new Error('Data array elements must be arrays.'); | ||
} | ||
return standardized; | ||
} | ||
if (data[0].length < 2) { | ||
throw new Error('Data array elements must contain a label and value.'); | ||
} | ||
} | ||
/** | ||
* Given a raw data block, return its count. | ||
* | ||
* @param {Array} block | ||
* | ||
* @return {Number} | ||
*/ | ||
/** | ||
* @param {Object} options | ||
* | ||
* @returns {Object} | ||
*/ | ||
}, { | ||
key: '_getRawBlockCount', | ||
value: function _getRawBlockCount(block) { | ||
return Array.isArray(block[1]) ? block[1][0] : block[1]; | ||
} | ||
}, { | ||
key: '_getSettings', | ||
value: function _getSettings(options) { | ||
// Prepare the configuration settings based on the defaults | ||
// Set the default width and height based on the container | ||
var settings = _utils2.default.extend({}, D3Funnel.defaults); | ||
settings.chart.width = parseInt(_d2.default.select(this.selector).style('width'), 10); | ||
settings.chart.height = parseInt(_d2.default.select(this.selector).style('height'), 10); | ||
/** | ||
* @return {Number} | ||
*/ | ||
// Overwrite default settings with user options | ||
settings = _utils2.default.extend(settings, options); | ||
}, { | ||
key: '_getDx', | ||
value: function _getDx() { | ||
// Will be sharper if there is a pinch | ||
if (this.bottomPinch > 0) { | ||
return this.bottomLeftX / (this.blocks.length - this.bottomPinch); | ||
// In the case that the width or height is not valid, set | ||
// the width/height as its default hard-coded value | ||
if (settings.chart.width <= 0) { | ||
settings.chart.width = D3Funnel.defaults.chart.width; | ||
} | ||
if (settings.chart.height <= 0) { | ||
settings.chart.height = D3Funnel.defaults.chart.height; | ||
} | ||
return settings; | ||
} | ||
return this.bottomLeftX / this.blocks.length; | ||
} | ||
/** | ||
* Register the raw data into a standard block format and pre-calculate | ||
* some values. | ||
* | ||
* @param {Array} data | ||
* | ||
* @return void | ||
*/ | ||
/** | ||
* @return {Number} | ||
*/ | ||
}, { | ||
key: '_setBlocks', | ||
value: function _setBlocks(data) { | ||
var totalCount = this._getTotalCount(data); | ||
}, { | ||
key: '_getDy', | ||
value: function _getDy() { | ||
// Curved chart needs reserved pixels to account for curvature | ||
if (this.isCurved) { | ||
return (this.height - this.curveHeight) / this.blocks.length; | ||
this.blocks = this._standardizeData(data, totalCount); | ||
} | ||
return this.height / this.blocks.length; | ||
} | ||
/** | ||
* Return the total count of all blocks. | ||
* | ||
* @return {Number} | ||
*/ | ||
/** | ||
* Draw the chart onto the DOM. | ||
* | ||
* @return {void} | ||
*/ | ||
}, { | ||
key: '_getTotalCount', | ||
value: function _getTotalCount(data) { | ||
var _this = this; | ||
}, { | ||
key: '_draw', | ||
value: function _draw() { | ||
// Add the SVG | ||
this.svg = d3.select(this.selector).append('svg').attr('width', this.width).attr('height', this.height); | ||
var total = 0; | ||
this.blockPaths = this._makePaths(); | ||
data.forEach(function (block) { | ||
total += _this._getRawBlockCount(block); | ||
}); | ||
// Define color gradients | ||
if (this.fillType === 'gradient') { | ||
this._defineColorGradients(this.svg); | ||
return total; | ||
} | ||
// Add top oval if curved | ||
if (this.isCurved) { | ||
this._drawTopOval(this.svg, this.blockPaths); | ||
} | ||
/** | ||
* Convert the raw data into a standardized format. | ||
* | ||
* @param {Array} data | ||
* @param {Number} totalCount | ||
* | ||
* @return {Array} | ||
*/ | ||
// Add each block | ||
this._drawBlock(0); | ||
} | ||
}, { | ||
key: '_standardizeData', | ||
value: function _standardizeData(data, totalCount) { | ||
var _this2 = this; | ||
/** | ||
* Create the paths to be used to define the discrete funnel blocks and | ||
* returns the results in an array. | ||
* | ||
* @return {Array} | ||
*/ | ||
var standardized = []; | ||
}, { | ||
key: '_makePaths', | ||
value: function _makePaths() { | ||
var _this3 = this; | ||
var count = undefined; | ||
var ratio = undefined; | ||
var label = undefined; | ||
var paths = []; | ||
data.forEach(function (block, index) { | ||
count = _this2._getRawBlockCount(block); | ||
ratio = count / totalCount; | ||
label = block[0]; | ||
// Initialize velocity | ||
var dx = this.dx; | ||
var dy = this.dy; | ||
standardized.push({ | ||
index: index, | ||
value: count, | ||
ratio: ratio, | ||
height: _this2.height * ratio, | ||
fill: _this2.colorizer.getBlockFill(block, index, _this2.fillType), | ||
label: { | ||
raw: label, | ||
formatted: _this2.labelFormatter.format(label, count), | ||
color: _this2.colorizer.getLabelFill(block) | ||
} | ||
}); | ||
}); | ||
// Initialize starting positions | ||
var prevLeftX = 0; | ||
var prevRightX = this.width; | ||
var prevHeight = 0; | ||
return standardized; | ||
} | ||
// Start from the bottom for inverted | ||
if (this.isInverted) { | ||
prevLeftX = this.bottomLeftX; | ||
prevRightX = this.width - this.bottomLeftX; | ||
/** | ||
* Given a raw data block, return its count. | ||
* | ||
* @param {Array} block | ||
* | ||
* @return {Number} | ||
*/ | ||
}, { | ||
key: '_getRawBlockCount', | ||
value: function _getRawBlockCount(block) { | ||
return Array.isArray(block[1]) ? block[1][0] : block[1]; | ||
} | ||
// Initialize next positions | ||
var nextLeftX = 0; | ||
var nextRightX = 0; | ||
var nextHeight = 0; | ||
/** | ||
* @return {Number} | ||
*/ | ||
var middle = this.width / 2; | ||
}, { | ||
key: '_getDx', | ||
value: function _getDx() { | ||
// Will be sharper if there is a pinch | ||
if (this.bottomPinch > 0) { | ||
return this.bottomLeftX / (this.blocks.length - this.bottomPinch); | ||
} | ||
// Move down if there is an initial curve | ||
if (this.isCurved) { | ||
prevHeight = 10; | ||
return this.bottomLeftX / this.blocks.length; | ||
} | ||
var totalHeight = this.height; | ||
/** | ||
* @return {Number} | ||
*/ | ||
// This is greedy in that the block will have a guaranteed height | ||
// and the remaining is shared among the ratio, instead of being | ||
// shared according to the remaining minus the guaranteed | ||
if (this.minHeight !== 0) { | ||
totalHeight = this.height - this.minHeight * this.blocks.length; | ||
}, { | ||
key: '_getDy', | ||
value: function _getDy() { | ||
// Curved chart needs reserved pixels to account for curvature | ||
if (this.isCurved) { | ||
return (this.height - this.curveHeight) / this.blocks.length; | ||
} | ||
return this.height / this.blocks.length; | ||
} | ||
var slopeHeight = this.height; | ||
/** | ||
* Draw the chart onto the DOM. | ||
* | ||
* @return {void} | ||
*/ | ||
// Correct slope height if there are blocks being pinched (and thus | ||
// requiring a sharper curve) | ||
this.blocks.forEach(function (block, i) { | ||
if (_this3.bottomPinch > 0) { | ||
if (_this3.isInverted) { | ||
if (i < _this3.bottomPinch) { | ||
slopeHeight -= block.height; | ||
} | ||
} else if (i >= _this3.blocks.length - _this3.bottomPinch) { | ||
slopeHeight -= block.height; | ||
} | ||
}, { | ||
key: '_draw', | ||
value: function _draw() { | ||
// Add the SVG | ||
this.svg = _d2.default.select(this.selector).append('svg').attr('width', this.width).attr('height', this.height); | ||
this.blockPaths = this._makePaths(); | ||
// Define color gradients | ||
if (this.fillType === 'gradient') { | ||
this._defineColorGradients(this.svg); | ||
} | ||
}); | ||
// The slope will determine the where the x points on each block | ||
// iteration | ||
var slope = 2 * slopeHeight / (this.width - this.bottomWidth); | ||
// Add top oval if curved | ||
if (this.isCurved) { | ||
this._drawTopOval(this.svg, this.blockPaths); | ||
} | ||
// Create the path definition for each funnel block | ||
// Remember to loop back to the beginning point for a closed path | ||
this.blocks.forEach(function (block, i) { | ||
// Make heights proportional to block weight | ||
if (_this3.dynamicHeight) { | ||
// Slice off the height proportional to this block | ||
dy = totalHeight * block.ratio; | ||
// Add each block | ||
this._drawBlock(0); | ||
} | ||
// Add greedy minimum height | ||
if (_this3.minHeight !== 0) { | ||
dy += _this3.minHeight; | ||
} | ||
/** | ||
* Create the paths to be used to define the discrete funnel blocks and | ||
* returns the results in an array. | ||
* | ||
* @return {Array} | ||
*/ | ||
// Account for any curvature | ||
if (_this3.isCurved) { | ||
dy = dy - _this3.curveHeight / _this3.blocks.length; | ||
} | ||
}, { | ||
key: '_makePaths', | ||
value: function _makePaths() { | ||
var _this3 = this; | ||
// Given: y = mx + b | ||
// Given: b = 0 (when funnel), b = this.height (when pyramid) | ||
// For funnel, x_i = y_i / slope | ||
nextLeftX = (prevHeight + dy) / slope; | ||
var paths = []; | ||
// For pyramid, x_i = y_i - this.height / -slope | ||
if (_this3.isInverted) { | ||
nextLeftX = (prevHeight + dy - _this3.height) / (-1 * slope); | ||
} | ||
// Initialize velocity | ||
var dx = this.dx; | ||
var dy = this.dy; | ||
// If bottomWidth is 0, adjust last x position (to circumvent | ||
// errors associated with rounding) | ||
if (_this3.bottomWidth === 0 && i === _this3.blocks.length - 1) { | ||
// For funnel, last position is the center | ||
nextLeftX = _this3.width / 2; | ||
// Initialize starting positions | ||
var prevLeftX = 0; | ||
var prevRightX = this.width; | ||
var prevHeight = 0; | ||
// For pyramid, last position is the origin | ||
// Start from the bottom for inverted | ||
if (this.isInverted) { | ||
prevLeftX = this.bottomLeftX; | ||
prevRightX = this.width - this.bottomLeftX; | ||
} | ||
// Initialize next positions | ||
var nextLeftX = 0; | ||
var nextRightX = 0; | ||
var nextHeight = 0; | ||
var middle = this.width / 2; | ||
// Move down if there is an initial curve | ||
if (this.isCurved) { | ||
prevHeight = 10; | ||
} | ||
var totalHeight = this.height; | ||
// This is greedy in that the block will have a guaranteed height | ||
// and the remaining is shared among the ratio, instead of being | ||
// shared according to the remaining minus the guaranteed | ||
if (this.minHeight !== 0) { | ||
totalHeight = this.height - this.minHeight * this.blocks.length; | ||
} | ||
var slopeHeight = this.height; | ||
// Correct slope height if there are blocks being pinched (and thus | ||
// requiring a sharper curve) | ||
this.blocks.forEach(function (block, i) { | ||
if (_this3.bottomPinch > 0) { | ||
if (_this3.isInverted) { | ||
nextLeftX = 0; | ||
if (i < _this3.bottomPinch) { | ||
slopeHeight -= block.height; | ||
} | ||
} else if (i >= _this3.blocks.length - _this3.bottomPinch) { | ||
slopeHeight -= block.height; | ||
} | ||
} | ||
}); | ||
// If bottomWidth is same as width, stop x velocity | ||
if (_this3.bottomWidth === _this3.width) { | ||
nextLeftX = prevLeftX; | ||
} | ||
// The slope will determine the where the x points on each block | ||
// iteration | ||
var slope = 2 * slopeHeight / (this.width - this.bottomWidth); | ||
// Calculate the shift necessary for both x points | ||
dx = nextLeftX - prevLeftX; | ||
// Create the path definition for each funnel block | ||
// Remember to loop back to the beginning point for a closed path | ||
this.blocks.forEach(function (block, i) { | ||
// Make heights proportional to block weight | ||
if (_this3.dynamicHeight) { | ||
// Slice off the height proportional to this block | ||
dy = totalHeight * block.ratio; | ||
if (_this3.isInverted) { | ||
dx = prevLeftX - nextLeftX; | ||
} | ||
} | ||
// Add greedy minimum height | ||
if (_this3.minHeight !== 0) { | ||
dy += _this3.minHeight; | ||
} | ||
// Stop velocity for pinched blocks | ||
if (_this3.bottomPinch > 0) { | ||
// Check if we've reached the bottom of the pinch | ||
// If so, stop changing on x | ||
if (!_this3.isInverted) { | ||
if (i >= _this3.blocks.length - _this3.bottomPinch) { | ||
dx = 0; | ||
// Account for any curvature | ||
if (_this3.isCurved) { | ||
dy = dy - _this3.curveHeight / _this3.blocks.length; | ||
} | ||
// Pinch at the first blocks relating to the bottom pinch | ||
// Revert back to normal velocity after pinch | ||
} else { | ||
// Revert velocity back to the initial if we are using | ||
// static area's (prevents zero velocity if isInverted | ||
// and bottomPinch are non trivial and dynamicHeight is | ||
// false) | ||
if (!_this3.dynamicHeight) { | ||
dx = _this3.dx; | ||
// Given: y = mx + b | ||
// Given: b = 0 (when funnel), b = this.height (when pyramid) | ||
// For funnel, x_i = y_i / slope | ||
nextLeftX = (prevHeight + dy) / slope; | ||
// For pyramid, x_i = y_i - this.height / -slope | ||
if (_this3.isInverted) { | ||
nextLeftX = (prevHeight + dy - _this3.height) / (-1 * slope); | ||
} | ||
// If bottomWidth is 0, adjust last x position (to circumvent | ||
// errors associated with rounding) | ||
if (_this3.bottomWidth === 0 && i === _this3.blocks.length - 1) { | ||
// For funnel, last position is the center | ||
nextLeftX = _this3.width / 2; | ||
// For pyramid, last position is the origin | ||
if (_this3.isInverted) { | ||
nextLeftX = 0; | ||
} | ||
} | ||
dx = i < _this3.bottomPinch ? 0 : dx; | ||
// If bottomWidth is same as width, stop x velocity | ||
if (_this3.bottomWidth === _this3.width) { | ||
nextLeftX = prevLeftX; | ||
} | ||
} | ||
// Calculate the position of next block | ||
nextLeftX = prevLeftX + dx; | ||
nextRightX = prevRightX - dx; | ||
nextHeight = prevHeight + dy; | ||
// Calculate the shift necessary for both x points | ||
dx = nextLeftX - prevLeftX; | ||
// Expand outward if inverted | ||
if (_this3.isInverted) { | ||
nextLeftX = prevLeftX - dx; | ||
nextRightX = prevRightX + dx; | ||
} | ||
if (_this3.isInverted) { | ||
dx = prevLeftX - nextLeftX; | ||
} | ||
} | ||
// Plot curved lines | ||
if (_this3.isCurved) { | ||
paths.push([ | ||
// Top Bezier curve | ||
[prevLeftX, prevHeight, 'M'], [middle, prevHeight + (_this3.curveHeight - 10), 'Q'], [prevRightX, prevHeight, ''], | ||
// Right line | ||
[nextRightX, nextHeight, 'L'], | ||
// Bottom Bezier curve | ||
[nextRightX, nextHeight, 'M'], [middle, nextHeight + _this3.curveHeight, 'Q'], [nextLeftX, nextHeight, ''], | ||
// Left line | ||
[prevLeftX, prevHeight, 'L']]); | ||
// Plot straight lines | ||
} else { | ||
// Stop velocity for pinched blocks | ||
if (_this3.bottomPinch > 0) { | ||
// Check if we've reached the bottom of the pinch | ||
// If so, stop changing on x | ||
if (!_this3.isInverted) { | ||
if (i >= _this3.blocks.length - _this3.bottomPinch) { | ||
dx = 0; | ||
} | ||
// Pinch at the first blocks relating to the bottom pinch | ||
// Revert back to normal velocity after pinch | ||
} else { | ||
// Revert velocity back to the initial if we are using | ||
// static area's (prevents zero velocity if isInverted | ||
// and bottomPinch are non trivial and dynamicHeight is | ||
// false) | ||
if (!_this3.dynamicHeight) { | ||
dx = _this3.dx; | ||
} | ||
dx = i < _this3.bottomPinch ? 0 : dx; | ||
} | ||
} | ||
// Calculate the position of next block | ||
nextLeftX = prevLeftX + dx; | ||
nextRightX = prevRightX - dx; | ||
nextHeight = prevHeight + dy; | ||
// Expand outward if inverted | ||
if (_this3.isInverted) { | ||
nextLeftX = prevLeftX - dx; | ||
nextRightX = prevRightX + dx; | ||
} | ||
// Plot curved lines | ||
if (_this3.isCurved) { | ||
paths.push([ | ||
// Start position | ||
[prevLeftX, prevHeight, 'M'], | ||
// Move to right | ||
[prevRightX, prevHeight, 'L'], | ||
// Move down | ||
// Top Bezier curve | ||
[prevLeftX, prevHeight, 'M'], [middle, prevHeight + (_this3.curveHeight - 10), 'Q'], [prevRightX, prevHeight, ''], | ||
// Right line | ||
[nextRightX, nextHeight, 'L'], | ||
// Move to left | ||
[nextLeftX, nextHeight, 'L'], | ||
// Wrap back to top | ||
// Bottom Bezier curve | ||
[nextRightX, nextHeight, 'M'], [middle, nextHeight + _this3.curveHeight, 'Q'], [nextLeftX, nextHeight, ''], | ||
// Left line | ||
[prevLeftX, prevHeight, 'L']]); | ||
} | ||
// Plot straight lines | ||
} else { | ||
paths.push([ | ||
// Start position | ||
[prevLeftX, prevHeight, 'M'], | ||
// Move to right | ||
[prevRightX, prevHeight, 'L'], | ||
// Move down | ||
[nextRightX, nextHeight, 'L'], | ||
// Move to left | ||
[nextLeftX, nextHeight, 'L'], | ||
// Wrap back to top | ||
[prevLeftX, prevHeight, 'L']]); | ||
} | ||
// Set the next block's previous position | ||
prevLeftX = nextLeftX; | ||
prevRightX = nextRightX; | ||
prevHeight = nextHeight; | ||
}); | ||
// Set the next block's previous position | ||
prevLeftX = nextLeftX; | ||
prevRightX = nextRightX; | ||
prevHeight = nextHeight; | ||
}); | ||
return paths; | ||
} | ||
return paths; | ||
} | ||
/** | ||
* Define the linear color gradients. | ||
* | ||
* @param {Object} svg | ||
* | ||
* @return {void} | ||
*/ | ||
/** | ||
* Define the linear color gradients. | ||
* | ||
* @param {Object} svg | ||
* | ||
* @return {void} | ||
*/ | ||
}, { | ||
key: '_defineColorGradients', | ||
value: function _defineColorGradients(svg) { | ||
var defs = svg.append('defs'); | ||
}, { | ||
key: '_defineColorGradients', | ||
value: function _defineColorGradients(svg) { | ||
var defs = svg.append('defs'); | ||
// Create a gradient for each block | ||
this.blocks.forEach(function (block, index) { | ||
var color = block.fill.raw; | ||
var shade = Colorizer.shade(color, -0.2); | ||
// Create a gradient for each block | ||
this.blocks.forEach(function (block, index) { | ||
var color = block.fill.raw; | ||
var shade = _colorizer2.default.shade(color, -0.2); | ||
// Create linear gradient | ||
var gradient = defs.append('linearGradient').attr({ | ||
id: 'gradient-' + index | ||
}); | ||
// Create linear gradient | ||
var gradient = defs.append('linearGradient').attr({ | ||
id: 'gradient-' + index | ||
}); | ||
// Define the gradient stops | ||
var stops = [[0, shade], [40, color], [60, color], [100, shade]]; | ||
// Define the gradient stops | ||
var stops = [[0, shade], [40, color], [60, color], [100, shade]]; | ||
// Add the gradient stops | ||
stops.forEach(function (stop) { | ||
gradient.append('stop').attr({ | ||
offset: stop[0] + '%', | ||
style: 'stop-color:' + stop[1] | ||
// Add the gradient stops | ||
stops.forEach(function (stop) { | ||
gradient.append('stop').attr({ | ||
offset: stop[0] + '%', | ||
style: 'stop-color:' + stop[1] | ||
}); | ||
}); | ||
}); | ||
}); | ||
} | ||
} | ||
/** | ||
* Draw the top oval of a curved funnel. | ||
* | ||
* @param {Object} svg | ||
* @param {Array} blockPaths | ||
* | ||
* @return {void} | ||
*/ | ||
/** | ||
* Draw the top oval of a curved funnel. | ||
* | ||
* @param {Object} svg | ||
* @param {Array} blockPaths | ||
* | ||
* @return {void} | ||
*/ | ||
}, { | ||
key: '_drawTopOval', | ||
value: function _drawTopOval(svg, blockPaths) { | ||
var leftX = 0; | ||
var rightX = this.width; | ||
var centerX = this.width / 2; | ||
}, { | ||
key: '_drawTopOval', | ||
value: function _drawTopOval(svg, blockPaths) { | ||
var leftX = 0; | ||
var rightX = this.width; | ||
var centerX = this.width / 2; | ||
if (this.isInverted) { | ||
leftX = this.bottomLeftX; | ||
rightX = this.width - this.bottomLeftX; | ||
if (this.isInverted) { | ||
leftX = this.bottomLeftX; | ||
rightX = this.width - this.bottomLeftX; | ||
} | ||
// Create path from top-most block | ||
var paths = blockPaths[0]; | ||
var topCurve = paths[1][1] + this.curveHeight - 10; | ||
var path = this.navigator.plot([['M', leftX, paths[0][1]], ['Q', centerX, topCurve], [' ', rightX, paths[2][1]], ['M', rightX, 10], ['Q', centerX, 0], [' ', leftX, 10]]); | ||
// Draw top oval | ||
svg.append('path').attr('fill', _colorizer2.default.shade(this.blocks[0].fill.raw, -0.4)).attr('d', path); | ||
} | ||
// Create path from top-most block | ||
var paths = blockPaths[0]; | ||
var topCurve = paths[1][1] + this.curveHeight - 10; | ||
/** | ||
* Draw the next block in the iteration. | ||
* | ||
* @param {int} index | ||
* | ||
* @return {void} | ||
*/ | ||
var path = this.navigator.plot([['M', leftX, paths[0][1]], ['Q', centerX, topCurve], [' ', rightX, paths[2][1]], ['M', rightX, 10], ['Q', centerX, 0], [' ', leftX, 10]]); | ||
}, { | ||
key: '_drawBlock', | ||
value: function _drawBlock(index) { | ||
var _this4 = this; | ||
// Draw top oval | ||
svg.append('path').attr('fill', Colorizer.shade(this.blocks[0].fill.raw, -0.4)).attr('d', path); | ||
} | ||
if (index === this.blocks.length) { | ||
return; | ||
} | ||
/** | ||
* Draw the next block in the iteration. | ||
* | ||
* @param {int} index | ||
* | ||
* @return {void} | ||
*/ | ||
// Create a group just for this block | ||
var group = this.svg.append('g'); | ||
}, { | ||
key: '_drawBlock', | ||
value: function _drawBlock(index) { | ||
var _this4 = this; | ||
// Fetch path element | ||
var path = this._getBlockPath(group, index); | ||
path.data(this._getD3Data(index)); | ||
if (index === this.blocks.length) { | ||
return; | ||
// Add animation components | ||
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 () { | ||
_this4._drawBlock(index + 1); | ||
}); | ||
} else { | ||
path.attr('fill', this.blocks[index].fill.actual).attr('d', this._getPathDefinition(index)); | ||
this._drawBlock(index + 1); | ||
} | ||
// Add the hover events | ||
if (this.hoverEffects) { | ||
path.on('mouseover', this._onMouseOver).on('mouseout', this._onMouseOut); | ||
} | ||
// Add block click event | ||
if (this.onBlockClick !== null) { | ||
path.on('click', this.onBlockClick); | ||
} | ||
this._addBlockLabel(group, index); | ||
} | ||
// Create a group just for this block | ||
var group = this.svg.append('g'); | ||
/** | ||
* @param {Object} group | ||
* @param {int} index | ||
* | ||
* @return {Object} | ||
*/ | ||
// Fetch path element | ||
var path = this._getBlockPath(group, index); | ||
path.data(this._getD3Data(index)); | ||
}, { | ||
key: '_getBlockPath', | ||
value: function _getBlockPath(group, index) { | ||
var path = group.append('path'); | ||
// Add animation components | ||
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 () { | ||
_this4._drawBlock(index + 1); | ||
}); | ||
} else { | ||
path.attr('fill', this.blocks[index].fill.actual).attr('d', this._getPathDefinition(index)); | ||
this._drawBlock(index + 1); | ||
if (this.animation !== 0) { | ||
this._addBeforeTransition(path, index); | ||
} | ||
return path; | ||
} | ||
// Add the hover events | ||
if (this.hoverEffects) { | ||
path.on('mouseover', this._onMouseOver).on('mouseout', this._onMouseOut); | ||
/** | ||
* Set the attributes of a path element before its animation. | ||
* | ||
* @param {Object} path | ||
* @param {int} index | ||
* | ||
* @return {void} | ||
*/ | ||
}, { | ||
key: '_addBeforeTransition', | ||
value: function _addBeforeTransition(path, index) { | ||
var paths = this.blockPaths[index]; | ||
var beforePath = ''; | ||
var beforeFill = ''; | ||
// Construct the top of the trapezoid and leave the other elements | ||
// hovering around to expand downward on animation | ||
if (!this.isCurved) { | ||
beforePath = this.navigator.plot([['M', paths[0][0], paths[0][1]], ['L', paths[1][0], paths[1][1]], ['L', paths[1][0], paths[1][1]], ['L', paths[0][0], paths[0][1]]]); | ||
} else { | ||
beforePath = this.navigator.plot([['M', paths[0][0], paths[0][1]], ['Q', paths[1][0], paths[1][1]], [' ', paths[2][0], paths[2][1]], ['L', paths[2][0], paths[2][1]], ['M', paths[2][0], paths[2][1]], ['Q', paths[1][0], paths[1][1]], [' ', paths[0][0], paths[0][1]]]); | ||
} | ||
// Use previous fill color, if available | ||
if (this.fillType === 'solid' && index > 0) { | ||
beforeFill = this.blocks[index - 1].fill.actual; | ||
// Otherwise use current background | ||
} else { | ||
beforeFill = this.blocks[index].fill.actual; | ||
} | ||
path.attr('d', beforePath).attr('fill', beforeFill); | ||
} | ||
// Add block click event | ||
if (this.onBlockClick !== null) { | ||
path.on('click', this.onBlockClick); | ||
/** | ||
* Return d3 formatted data for the given block. | ||
* | ||
* @param {int} index | ||
* | ||
* @return {Array} | ||
*/ | ||
}, { | ||
key: '_getD3Data', | ||
value: function _getD3Data(index) { | ||
return [this.blocks[index]]; | ||
} | ||
this._addBlockLabel(group, index); | ||
} | ||
/** | ||
* @param {int} index | ||
* | ||
* @return {string} | ||
*/ | ||
/** | ||
* @param {Object} group | ||
* @param {int} index | ||
* | ||
* @return {Object} | ||
*/ | ||
}, { | ||
key: '_getPathDefinition', | ||
value: function _getPathDefinition(index) { | ||
var commands = []; | ||
}, { | ||
key: '_getBlockPath', | ||
value: function _getBlockPath(group, index) { | ||
var path = group.append('path'); | ||
this.blockPaths[index].forEach(function (command) { | ||
commands.push([command[2], command[0], command[1]]); | ||
}); | ||
if (this.animation !== 0) { | ||
this._addBeforeTransition(path, index); | ||
return this.navigator.plot(commands); | ||
} | ||
return path; | ||
} | ||
/** | ||
* @param {Object} data | ||
* | ||
* @return {void} | ||
*/ | ||
/** | ||
* Set the attributes of a path element before its animation. | ||
* | ||
* @param {Object} path | ||
* @param {int} index | ||
* | ||
* @return {void} | ||
*/ | ||
}, { | ||
key: '_onMouseOver', | ||
value: function _onMouseOver(data) { | ||
_d2.default.select(this).attr('fill', _colorizer2.default.shade(data.fill.raw, -0.2)); | ||
} | ||
}, { | ||
key: '_addBeforeTransition', | ||
value: function _addBeforeTransition(path, index) { | ||
var paths = this.blockPaths[index]; | ||
/** | ||
* @param {Object} data | ||
* | ||
* @return {void} | ||
*/ | ||
var beforePath = ''; | ||
var beforeFill = ''; | ||
}, { | ||
key: '_onMouseOut', | ||
value: function _onMouseOut(data) { | ||
_d2.default.select(this).attr('fill', data.fill.actual); | ||
} | ||
// Construct the top of the trapezoid and leave the other elements | ||
// hovering around to expand downward on animation | ||
if (!this.isCurved) { | ||
beforePath = this.navigator.plot([['M', paths[0][0], paths[0][1]], ['L', paths[1][0], paths[1][1]], ['L', paths[1][0], paths[1][1]], ['L', paths[0][0], paths[0][1]]]); | ||
} else { | ||
beforePath = this.navigator.plot([['M', paths[0][0], paths[0][1]], ['Q', paths[1][0], paths[1][1]], [' ', paths[2][0], paths[2][1]], ['L', paths[2][0], paths[2][1]], ['M', paths[2][0], paths[2][1]], ['Q', paths[1][0], paths[1][1]], [' ', paths[0][0], paths[0][1]]]); | ||
/** | ||
* @param {Object} group | ||
* @param {int} index | ||
* @return {void} | ||
*/ | ||
}, { | ||
key: '_addBlockLabel', | ||
value: function _addBlockLabel(group, index) { | ||
var paths = this.blockPaths[index]; | ||
var text = this.blocks[index].label.formatted; | ||
var fill = this.blocks[index].label.color; | ||
var x = this.width / 2; // Center the text | ||
var y = this._getTextY(paths); | ||
group.append('text').text(text).attr({ | ||
'x': x, | ||
'y': y, | ||
'text-anchor': 'middle', | ||
'dominant-baseline': 'middle', | ||
'fill': fill, | ||
'pointer-events': 'none' | ||
}).style('font-size', this.label.fontSize); | ||
} | ||
// Use previous fill color, if available | ||
if (this.fillType === 'solid' && index > 0) { | ||
beforeFill = this.blocks[index - 1].fill.actual; | ||
// Otherwise use current background | ||
} else { | ||
beforeFill = this.blocks[index].fill.actual; | ||
/** | ||
* Returns the y position of the given label's text. This is determined by | ||
* taking the mean of the bases. | ||
* | ||
* @param {Array} paths | ||
* | ||
* @return {Number} | ||
*/ | ||
}, { | ||
key: '_getTextY', | ||
value: function _getTextY(paths) { | ||
if (this.isCurved) { | ||
return (paths[2][1] + paths[3][1]) / 2 + this.curveHeight / this.blocks.length; | ||
} | ||
path.attr('d', beforePath).attr('fill', beforeFill); | ||
} | ||
return (paths[1][1] + paths[2][1]) / 2; | ||
} | ||
}]); | ||
/** | ||
* Return d3 formatted data for the given block. | ||
* | ||
* @param {int} index | ||
* | ||
* @return {Array} | ||
*/ | ||
return D3Funnel; | ||
})(); | ||
}, { | ||
key: '_getD3Data', | ||
value: function _getD3Data(index) { | ||
return [this.blocks[index]]; | ||
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: _d2.default.scale.category10().domain(_d2.default.range(0, 10)), | ||
type: 'solid' | ||
}, | ||
minHeight: 0, | ||
highlight: false | ||
}, | ||
label: { | ||
fontSize: '14px', | ||
fill: '#fff', | ||
format: '{l}: {f}' | ||
}, | ||
events: { | ||
click: { | ||
block: null | ||
} | ||
} | ||
}; | ||
exports.default = D3Funnel; | ||
/** | ||
* @param {int} index | ||
* | ||
* @return {string} | ||
*/ | ||
/***/ }, | ||
/* 2 */ | ||
/***/ function(module, exports) { | ||
}, { | ||
key: '_getPathDefinition', | ||
value: function _getPathDefinition(index) { | ||
var commands = []; | ||
module.exports = __WEBPACK_EXTERNAL_MODULE_2__; | ||
this.blockPaths[index].forEach(function (command) { | ||
commands.push([command[2], command[0], command[1]]); | ||
}); | ||
/***/ }, | ||
/* 3 */ | ||
/***/ function(module, exports) { | ||
return this.navigator.plot(commands); | ||
} | ||
'use strict'; | ||
/** | ||
* @param {Object} data | ||
* | ||
* @return {void} | ||
*/ | ||
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; }; })(); | ||
}, { | ||
key: '_onMouseOver', | ||
value: function _onMouseOver(data) { | ||
d3.select(this).attr('fill', Colorizer.shade(data.fill.raw, -0.2)); | ||
} | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
/** | ||
* @param {Object} data | ||
* | ||
* @return {void} | ||
*/ | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
}, { | ||
key: '_onMouseOut', | ||
value: function _onMouseOut(data) { | ||
d3.select(this).attr('fill', data.fill.actual); | ||
var Colorizer = (function () { | ||
function Colorizer() { | ||
_classCallCheck(this, Colorizer); | ||
this.hexExpression = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i; | ||
this.labelFill = null; | ||
this.scale = null; | ||
} | ||
/** | ||
* @param {Object} group | ||
* @param {int} index | ||
* @return {void} | ||
*/ | ||
* @param {string} fill | ||
* | ||
* @return {void} | ||
*/ | ||
}, { | ||
key: '_addBlockLabel', | ||
value: function _addBlockLabel(group, index) { | ||
var paths = this.blockPaths[index]; | ||
_createClass(Colorizer, [{ | ||
key: 'setLabelFill', | ||
value: function setLabelFill(fill) { | ||
this.labelFill = fill; | ||
} | ||
var text = this.blocks[index].label.formatted; | ||
var fill = this.blocks[index].label.color; | ||
/** | ||
* @param {function|Array} scale | ||
* | ||
* @return {void} | ||
*/ | ||
var x = this.width / 2; // Center the text | ||
var y = this._getTextY(paths); | ||
}, { | ||
key: 'setScale', | ||
value: function setScale(scale) { | ||
this.scale = scale; | ||
} | ||
group.append('text').text(text).attr({ | ||
'x': x, | ||
'y': y, | ||
'text-anchor': 'middle', | ||
'dominant-baseline': 'middle', | ||
'fill': fill, | ||
'pointer-events': 'none' | ||
}).style('font-size', this.label.fontSize); | ||
} | ||
/** | ||
* Given a raw data block, return an appropriate color for the block. | ||
* | ||
* @param {Array} block | ||
* @param {Number} index | ||
* @param {string} type | ||
* | ||
* @return {Object} | ||
*/ | ||
/** | ||
* Returns the y position of the given label's text. This is determined by | ||
* taking the mean of the bases. | ||
* | ||
* @param {Array} paths | ||
* | ||
* @return {Number} | ||
*/ | ||
}, { | ||
key: 'getBlockFill', | ||
value: function getBlockFill(block, index, type) { | ||
var raw = this.getBlockRawFill(block, index); | ||
}, { | ||
key: '_getTextY', | ||
value: function _getTextY(paths) { | ||
if (this.isCurved) { | ||
return (paths[2][1] + paths[3][1]) / 2 + this.curveHeight / this.blocks.length; | ||
return { | ||
raw: raw, | ||
actual: this.getBlockActualFill(raw, index, type) | ||
}; | ||
} | ||
return (paths[1][1] + paths[2][1]) / 2; | ||
} | ||
}]); | ||
/** | ||
* Return the raw hex color for the block. | ||
* | ||
* @param {Array} block | ||
* @param {Number} index | ||
* | ||
* @return {string} | ||
*/ | ||
return D3Funnel; | ||
})(); | ||
}, { | ||
key: 'getBlockRawFill', | ||
value: function getBlockRawFill(block, index) { | ||
// Use the block's color, if set and valid | ||
if (block.length > 2 && this.hexExpression.test(block[2])) { | ||
return block[2]; | ||
} | ||
/* exported Colorizer */ | ||
/* jshint bitwise: false */ | ||
// Otherwise, attempt to use the array scale | ||
if (Array.isArray(this.scale)) { | ||
return this.scale[index]; | ||
} | ||
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 | ||
} | ||
} | ||
}; | ||
// Finally, use a functional scale | ||
return this.scale(index); | ||
} | ||
var Colorizer = (function () { | ||
function Colorizer() { | ||
_classCallCheck(this, Colorizer); | ||
/** | ||
* Return the actual background for the block. | ||
* | ||
* @param {string} raw | ||
* @param {Number} index | ||
* @param {string} type | ||
* | ||
* @return {string} | ||
*/ | ||
this.hexExpression = /^#([0-9a-f]{3}|[0-9a-f]{6})$/i; | ||
}, { | ||
key: 'getBlockActualFill', | ||
value: function getBlockActualFill(raw, index, type) { | ||
if (type === 'solid') { | ||
return raw; | ||
} | ||
this.labelFill = null; | ||
return 'url(#gradient-' + index + ')'; | ||
} | ||
this.scale = null; | ||
} | ||
/** | ||
* Given a raw data block, return an appropriate label color. | ||
* | ||
* @param {Array} block | ||
* | ||
* @return {string} | ||
*/ | ||
/** | ||
* @param {string} fill | ||
* | ||
* @return {void} | ||
*/ | ||
}, { | ||
key: 'getLabelFill', | ||
value: function getLabelFill(block) { | ||
// Use the label's color, if set and valid | ||
if (block.length > 3 && this.hexExpression.test(block[3])) { | ||
return block[3]; | ||
} | ||
_createClass(Colorizer, [{ | ||
key: 'setLabelFill', | ||
value: function setLabelFill(fill) { | ||
this.labelFill = fill; | ||
} | ||
return this.labelFill; | ||
} | ||
/** | ||
* @param {function|Array} scale | ||
* | ||
* @return {void} | ||
*/ | ||
/** | ||
* Shade a color to the given percentage. | ||
* | ||
* @param {string} color A hex color. | ||
* @param {number} shade The shade adjustment. Can be positive or negative. | ||
* | ||
* @return {string} | ||
*/ | ||
}, { | ||
key: 'setScale', | ||
value: function setScale(scale) { | ||
this.scale = scale; | ||
} | ||
}], [{ | ||
key: 'shade', | ||
value: function shade(color, _shade) { | ||
var hex = color.slice(1); | ||
/** | ||
* Given a raw data block, return an appropriate color for the block. | ||
* | ||
* @param {Array} block | ||
* @param {Number} index | ||
* @param {string} type | ||
* | ||
* @return {Object} | ||
*/ | ||
if (hex.length === 3) { | ||
hex = Colorizer.expandHex(hex); | ||
} | ||
}, { | ||
key: 'getBlockFill', | ||
value: function getBlockFill(block, index, type) { | ||
var raw = this.getBlockRawFill(block, index); | ||
var f = parseInt(hex, 16); | ||
var t = _shade < 0 ? 0 : 255; | ||
var p = _shade < 0 ? _shade * -1 : _shade; | ||
return { | ||
raw: raw, | ||
actual: this.getBlockActualFill(raw, index, type) | ||
}; | ||
} | ||
var R = f >> 16; | ||
var G = f >> 8 & 0x00FF; | ||
var B = f & 0x0000FF; | ||
/** | ||
* Return the raw hex color for the block. | ||
* | ||
* @param {Array} block | ||
* @param {Number} index | ||
* | ||
* @return {string} | ||
*/ | ||
var converted = 0x1000000 + (Math.round((t - R) * p) + R) * 0x10000 + (Math.round((t - G) * p) + G) * 0x100 + (Math.round((t - B) * p) + B); | ||
}, { | ||
key: 'getBlockRawFill', | ||
value: function getBlockRawFill(block, index) { | ||
// Use the block's color, if set and valid | ||
if (block.length > 2 && this.hexExpression.test(block[2])) { | ||
return block[2]; | ||
return '#' + converted.toString(16).slice(1); | ||
} | ||
// Otherwise, attempt to use the array scale | ||
if (Array.isArray(this.scale)) { | ||
return this.scale[index]; | ||
} | ||
/** | ||
* Expands a three character hex code to six characters. | ||
* | ||
* @param {string} hex | ||
* | ||
* @return {string} | ||
*/ | ||
// Finally, use a functional scale | ||
return this.scale(index); | ||
} | ||
/** | ||
* Return the actual background for the block. | ||
* | ||
* @param {string} raw | ||
* @param {Number} index | ||
* @param {string} type | ||
* | ||
* @return {string} | ||
*/ | ||
}, { | ||
key: 'getBlockActualFill', | ||
value: function getBlockActualFill(raw, index, type) { | ||
if (type === 'solid') { | ||
return raw; | ||
}, { | ||
key: 'expandHex', | ||
value: function expandHex(hex) { | ||
return hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]; | ||
} | ||
}]); | ||
return 'url(#gradient-' + index + ')'; | ||
} | ||
return Colorizer; | ||
})(); | ||
/** | ||
* Given a raw data block, return an appropriate label color. | ||
* | ||
* @param {Array} block | ||
* | ||
* @return {string} | ||
*/ | ||
exports.default = Colorizer; | ||
}, { | ||
key: 'getLabelFill', | ||
value: function getLabelFill(block) { | ||
// Use the label's color, if set and valid | ||
if (block.length > 3 && this.hexExpression.test(block[3])) { | ||
return block[3]; | ||
} | ||
/***/ }, | ||
/* 4 */ | ||
/***/ function(module, exports) { | ||
return this.labelFill; | ||
} | ||
'use strict'; | ||
/** | ||
* Shade a color to the given percentage. | ||
* | ||
* @param {string} color A hex color. | ||
* @param {number} shade The shade adjustment. Can be positive or negative. | ||
* | ||
* @return {string} | ||
*/ | ||
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; }; })(); | ||
}], [{ | ||
key: 'shade', | ||
value: function shade(color, _shade) { | ||
var hex = color.slice(1); | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
if (hex.length === 3) { | ||
hex = Colorizer.expandHex(hex); | ||
} | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
var f = parseInt(hex, 16); | ||
var t = _shade < 0 ? 0 : 255; | ||
var p = _shade < 0 ? _shade * -1 : _shade; | ||
var LabelFormatter = (function () { | ||
var R = f >> 16; | ||
var G = f >> 8 & 0x00FF; | ||
var B = f & 0x0000FF; | ||
/** | ||
* Initial the formatter. | ||
* | ||
* @return {void} | ||
*/ | ||
var converted = 0x1000000 + (Math.round((t - R) * p) + R) * 0x10000 + (Math.round((t - G) * p) + G) * 0x100 + (Math.round((t - B) * p) + B); | ||
function LabelFormatter() { | ||
_classCallCheck(this, LabelFormatter); | ||
return '#' + converted.toString(16).slice(1); | ||
this.expression = null; | ||
} | ||
/** | ||
* Expands a three character hex code to six characters. | ||
* | ||
* @param {string} hex | ||
* | ||
* @return {string} | ||
*/ | ||
* Register the format function. | ||
* | ||
* @param {string|function} format | ||
* | ||
* @return {void} | ||
*/ | ||
}, { | ||
key: 'expandHex', | ||
value: function expandHex(hex) { | ||
return hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2]; | ||
} | ||
}]); | ||
_createClass(LabelFormatter, [{ | ||
key: 'setFormat', | ||
value: function setFormat(format) { | ||
if (typeof format === 'function') { | ||
this.formatter = format; | ||
} else { | ||
this.expression = format; | ||
this.formatter = this.stringFormatter; | ||
} | ||
} | ||
return Colorizer; | ||
})(); | ||
/** | ||
* Format the given value according to the data point or the format. | ||
* | ||
* @param {string} label | ||
* @param {number} value | ||
* | ||
* @return string | ||
*/ | ||
/* exported LabelFormatter */ | ||
}, { | ||
key: 'format', | ||
value: function format(label, value) { | ||
// Try to use any formatted value specified through the data | ||
// Otherwise, attempt to use the format function | ||
if (Array.isArray(value)) { | ||
return this.formatter(label, value[0], value[1]); | ||
} | ||
var LabelFormatter = (function () { | ||
return this.formatter(label, value, null); | ||
} | ||
/** | ||
* Initial the formatter. | ||
* | ||
* @return {void} | ||
*/ | ||
/** | ||
* Format the string according to a simple expression. | ||
* | ||
* {l}: label | ||
* {v}: raw value | ||
* {f}: formatted value | ||
* | ||
* @param {string} label | ||
* @param {number} value | ||
* @param {*} fValue | ||
* | ||
* @return {string} | ||
*/ | ||
function LabelFormatter() { | ||
_classCallCheck(this, LabelFormatter); | ||
}, { | ||
key: 'stringFormatter', | ||
value: function stringFormatter(label, value) { | ||
var fValue = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2]; | ||
this.expression = null; | ||
} | ||
var formatted = fValue; | ||
/** | ||
* Register the format function. | ||
* | ||
* @param {string|function} format | ||
* | ||
* @return {void} | ||
*/ | ||
// Attempt to use supplied formatted value | ||
// Otherwise, use the default | ||
if (fValue === null) { | ||
formatted = this.getDefaultFormattedValue(value); | ||
} | ||
_createClass(LabelFormatter, [{ | ||
key: 'setFormat', | ||
value: function setFormat(format) { | ||
if (typeof format === 'function') { | ||
this.formatter = format; | ||
} else { | ||
this.expression = format; | ||
this.formatter = this.stringFormatter; | ||
return this.expression.split('{l}').join(label).split('{v}').join(value).split('{f}').join(formatted); | ||
} | ||
} | ||
/** | ||
* Format the given value according to the data point or the format. | ||
* | ||
* @param {string} label | ||
* @param {number} value | ||
* | ||
* @return string | ||
*/ | ||
/** | ||
* @param {number} value | ||
* | ||
* @return {string} | ||
*/ | ||
}, { | ||
key: 'format', | ||
value: function format(label, value) { | ||
// Try to use any formatted value specified through the data | ||
// Otherwise, attempt to use the format function | ||
if (Array.isArray(value)) { | ||
return this.formatter(label, value[0], value[1]); | ||
}, { | ||
key: 'getDefaultFormattedValue', | ||
value: function getDefaultFormattedValue(value) { | ||
return value.toLocaleString(); | ||
} | ||
}]); | ||
return this.formatter(label, value, null); | ||
} | ||
return LabelFormatter; | ||
})(); | ||
/** | ||
* Format the string according to a simple expression. | ||
* | ||
* {l}: label | ||
* {v}: raw value | ||
* {f}: formatted value | ||
* | ||
* @param {string} label | ||
* @param {number} value | ||
* @param {*} fValue | ||
* | ||
* @return {string} | ||
*/ | ||
exports.default = LabelFormatter; | ||
}, { | ||
key: 'stringFormatter', | ||
value: function stringFormatter(label, value) { | ||
var fValue = arguments.length <= 2 || arguments[2] === undefined ? null : arguments[2]; | ||
/***/ }, | ||
/* 5 */ | ||
/***/ function(module, exports) { | ||
var formatted = fValue; | ||
'use strict'; | ||
// Attempt to use supplied formatted value | ||
// Otherwise, use the default | ||
if (fValue === null) { | ||
formatted = this.getDefaultFormattedValue(value); | ||
} | ||
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; }; })(); | ||
return this.expression.split('{l}').join(label).split('{v}').join(value).split('{f}').join(formatted); | ||
} | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
/** | ||
* @param {number} value | ||
* | ||
* @return {string} | ||
*/ | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
}, { | ||
key: 'getDefaultFormattedValue', | ||
value: function getDefaultFormattedValue(value) { | ||
return value.toLocaleString(); | ||
var Navigator = (function () { | ||
function Navigator() { | ||
_classCallCheck(this, Navigator); | ||
} | ||
}]); | ||
return LabelFormatter; | ||
})(); | ||
_createClass(Navigator, [{ | ||
key: 'plot', | ||
/* exported Navigator */ | ||
/** | ||
* Given a list of path commands, returns the compiled description. | ||
* | ||
* @param {Array} commands | ||
* | ||
* @returns {string} | ||
*/ | ||
value: function plot(commands) { | ||
var path = ''; | ||
var Navigator = (function () { | ||
function Navigator() { | ||
_classCallCheck(this, Navigator); | ||
} | ||
commands.forEach(function (command) { | ||
path += command[0] + command[1] + ',' + command[2] + ' '; | ||
}); | ||
_createClass(Navigator, [{ | ||
key: 'plot', | ||
return path.replace(/ +/g, ' ').trim(); | ||
} | ||
}]); | ||
/** | ||
* Given a list of path commands, returns the compiled description. | ||
* | ||
* @param {Array} commands | ||
* | ||
* @returns {string} | ||
*/ | ||
value: function plot(commands) { | ||
var path = ''; | ||
return Navigator; | ||
})(); | ||
commands.forEach(function (command) { | ||
path += command[0] + command[1] + ',' + command[2] + ' '; | ||
}); | ||
exports.default = Navigator; | ||
return path.replace(/ +/g, ' ').trim(); | ||
} | ||
}]); | ||
/***/ }, | ||
/* 6 */ | ||
/***/ function(module, exports) { | ||
return Navigator; | ||
})(); | ||
'use strict'; | ||
/* exported Utils */ | ||
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; }; })(); | ||
/** | ||
* Simple utility class. | ||
*/ | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
var Utils = (function () { | ||
function Utils() { | ||
_classCallCheck(this, Utils); | ||
} | ||
function _typeof(obj) { return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj; } | ||
_createClass(Utils, null, [{ | ||
key: 'extend', | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | ||
/** | ||
* Extends an object with the members of another. | ||
* | ||
* @param {Object} a The object to be extended. | ||
* @param {Object} b The object to clone from. | ||
* | ||
* @return {Object} | ||
*/ | ||
value: function extend(a, b) { | ||
var prop = undefined; | ||
var Utils = (function () { | ||
function Utils() { | ||
_classCallCheck(this, Utils); | ||
} | ||
for (prop in b) { | ||
if (b.hasOwnProperty(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]); | ||
_createClass(Utils, null, [{ | ||
key: 'extend', | ||
/** | ||
* Extends an object with the members of another. | ||
* | ||
* @param {Object} a The object to be extended. | ||
* @param {Object} b The object to clone from. | ||
* | ||
* @return {Object} | ||
*/ | ||
value: function extend(a, b) { | ||
var prop = undefined; | ||
for (prop in b) { | ||
if (b.hasOwnProperty(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]); | ||
} else { | ||
a[prop] = Utils.extend({}, b[prop]); | ||
} | ||
} else { | ||
a[prop] = Utils.extend({}, b[prop]); | ||
a[prop] = b[prop]; | ||
} | ||
} else { | ||
a[prop] = b[prop]; | ||
} | ||
} | ||
return a; | ||
} | ||
}]); | ||
return a; | ||
} | ||
}]); | ||
return Utils; | ||
})(); | ||
return Utils; | ||
})(); | ||
return D3Funnel; | ||
exports.default = Utils; | ||
})); | ||
/***/ } | ||
/******/ ]) | ||
}); | ||
; |
/*! d3-funnel - v0.7.3 | 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){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}); | ||
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e(require("d3")):"function"==typeof define&&define.amd?define(["d3"],e):"object"==typeof exports?exports.D3Funnel=e(require("d3")):t.D3Funnel=e(t.d3)}(this,function(t){return function(t){function e(n){if(i[n])return i[n].exports;var a=i[n]={exports:{},id:n,loaded:!1};return t[n].call(a.exports,a,a.exports,e),a.loaded=!0,a.exports}var i={};return e.m=t,e.c=i,e.p="",e(0)}([function(t,e,i){"use strict";t.exports=i(1)["default"]},function(t,e,i){"use strict";function n(t){return t&&t.__esModule?t:{"default":t}}function a(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var r=function(){function t(t,e){for(var i=0;i<e.length;i++){var n=e[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,i,n){return i&&t(e.prototype,i),n&&t(e,n),e}}();Object.defineProperty(e,"__esModule",{value:!0});var o=i(2),l=n(o),s=i(3),h=n(s),u=i(4),c=n(u),f=i(5),d=n(f),v=i(6),g=n(v),b=function(){function t(e){a(this,t),this.selector=e,this.colorizer=new h["default"],this.labelFormatter=new c["default"],this.navigator=new d["default"]}return r(t,[{key:"destroy",value:function(){var t=l["default"].select(this.selector);t.selectAll("svg").remove(),t.selectAll("*").remove(),t.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=g["default"].extend({},t.defaults);return i.chart.width=parseInt(l["default"].select(this.selector).style("width"),10),i.chart.height=parseInt(l["default"].select(this.selector).style("height"),10),i=g["default"].extend(i,e),i.chart.width<=0&&(i.chart.width=t.defaults.chart.width),i.chart.height<=0&&(i.chart.height=t.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,n=[],a=void 0,r=void 0,o=void 0;return t.forEach(function(t,l){a=i._getRawBlockCount(t),r=a/e,o=t[0],n.push({index:l,value:a,ratio:r,height:i.height*r,fill:i.colorizer.getBlockFill(t,l,i.fillType),label:{raw:o,formatted:i.labelFormatter.format(o,a),color:i.colorizer.getLabelFill(t)}})}),n}},{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=l["default"].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,n=this.dy,a=0,r=this.width,o=0;this.isInverted&&(a=this.bottomLeftX,r=this.width-this.bottomLeftX);var l=0,s=0,h=0,u=this.width/2;this.isCurved&&(o=10);var c=this.height;0!==this.minHeight&&(c=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&&(n=c*f.ratio,0!==t.minHeight&&(n+=t.minHeight),t.isCurved&&(n-=t.curveHeight/t.blocks.length),l=(o+n)/d,t.isInverted&&(l=(o+n-t.height)/(-1*d)),0===t.bottomWidth&&v===t.blocks.length-1&&(l=t.width/2,t.isInverted&&(l=0)),t.bottomWidth===t.width&&(l=a),i=l-a,t.isInverted&&(i=a-l)),t.bottomPinch>0&&(t.isInverted?(t.dynamicHeight||(i=t.dx),i=v<t.bottomPinch?0:i):v>=t.blocks.length-t.bottomPinch&&(i=0)),l=a+i,s=r-i,h=o+n,t.isInverted&&(l=a-i,s=r+i),t.isCurved?e.push([[a,o,"M"],[u,o+(t.curveHeight-10),"Q"],[r,o,""],[s,h,"L"],[s,h,"M"],[u,h+t.curveHeight,"Q"],[l,h,""],[a,o,"L"]]):e.push([[a,o,"M"],[r,o,"L"],[s,h,"L"],[l,h,"L"],[a,o,"L"]]),a=l,r=s,o=h}),e}},{key:"_defineColorGradients",value:function(t){var e=t.append("defs");this.blocks.forEach(function(t,i){var n=t.fill.raw,a=h["default"].shade(n,-.2),r=e.append("linearGradient").attr({id:"gradient-"+i}),o=[[0,a],[40,n],[60,n],[100,a]];o.forEach(function(t){r.append("stop").attr({offset:t[0]+"%",style:"stop-color:"+t[1]})})})}},{key:"_drawTopOval",value:function(t,e){var i=0,n=this.width,a=this.width/2;this.isInverted&&(i=this.bottomLeftX,n=this.width-this.bottomLeftX);var r=e[0],o=r[1][1]+this.curveHeight-10,l=this.navigator.plot([["M",i,r[0][1]],["Q",a,o],[" ",n,r[2][1]],["M",n,10],["Q",a,0],[" ",i,10]]);t.append("path").attr("fill",h["default"].shade(this.blocks[0].fill.raw,-.4)).attr("d",l)}},{key:"_drawBlock",value:function(t){var e=this;if(t!==this.blocks.length){var i=this.svg.append("g"),n=this._getBlockPath(i,t);n.data(this._getD3Data(t)),0!==this.animation?n.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)}):(n.attr("fill",this.blocks[t].fill.actual).attr("d",this._getPathDefinition(t)),this._drawBlock(t+1)),this.hoverEffects&&n.on("mouseover",this._onMouseOver).on("mouseout",this._onMouseOut),null!==this.onBlockClick&&n.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],n="",a="";n=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]]]),a="solid"===this.fillType&&e>0?this.blocks[e-1].fill.actual:this.blocks[e].fill.actual,t.attr("d",n).attr("fill",a)}},{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(t){l["default"].select(this).attr("fill",h["default"].shade(t.fill.raw,-.2))}},{key:"_onMouseOut",value:function(t){l["default"].select(this).attr("fill",t.fill.actual)}},{key:"_addBlockLabel",value:function(t,e){var i=this.blockPaths[e],n=this.blocks[e].label.formatted,a=this.blocks[e].label.color,r=this.width/2,o=this._getTextY(i);t.append("text").text(n).attr({x:r,y:o,"text-anchor":"middle","dominant-baseline":"middle",fill:a,"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}}]),t}();b.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:l["default"].scale.category10().domain(l["default"].range(0,10)),type:"solid"},minHeight:0,highlight:!1},label:{fontSize:"14px",fill:"#fff",format:"{l}: {f}"},events:{click:{block:null}}},e["default"]=b},function(e,i){e.exports=t},function(t,e){"use strict";function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var n=function(){function t(t,e){for(var i=0;i<e.length;i++){var n=e[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,i,n){return i&&t(e.prototype,i),n&&t(e,n),e}}();Object.defineProperty(e,"__esModule",{value:!0});var a=function(){function t(){i(this,t),this.hexExpression=/^#([0-9a-f]{3}|[0-9a-f]{6})$/i,this.labelFill=null,this.scale=null}return n(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 n=this.getBlockRawFill(t,e);return{raw:n,actual:this.getBlockActualFill(n,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 n=e.slice(1);3===n.length&&(n=t.expandHex(n));var a=parseInt(n,16),r=0>i?0:255,o=0>i?-1*i:i,l=a>>16,s=a>>8&255,h=255&a,u=16777216+65536*(Math.round((r-l)*o)+l)+256*(Math.round((r-s)*o)+s)+(Math.round((r-h)*o)+h);return"#"+u.toString(16).slice(1)}},{key:"expandHex",value:function(t){return t[0]+t[0]+t[1]+t[1]+t[2]+t[2]}}]),t}();e["default"]=a},function(t,e){"use strict";function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var n=function(){function t(t,e){for(var i=0;i<e.length;i++){var n=e[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,i,n){return i&&t(e.prototype,i),n&&t(e,n),e}}();Object.defineProperty(e,"__esModule",{value:!0});var a=function(){function t(){i(this,t),this.expression=null}return n(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],n=i;return null===i&&(n=this.getDefaultFormattedValue(e)),this.expression.split("{l}").join(t).split("{v}").join(e).split("{f}").join(n)}},{key:"getDefaultFormattedValue",value:function(t){return t.toLocaleString()}}]),t}();e["default"]=a},function(t,e){"use strict";function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}var n=function(){function t(t,e){for(var i=0;i<e.length;i++){var n=e[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,i,n){return i&&t(e.prototype,i),n&&t(e,n),e}}();Object.defineProperty(e,"__esModule",{value:!0});var a=function(){function t(){i(this,t)}return n(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}();e["default"]=a},function(t,e){"use strict";function i(t){return t&&"undefined"!=typeof Symbol&&t.constructor===Symbol?"symbol":typeof t}function n(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 n=e[i];n.enumerable=n.enumerable||!1,n.configurable=!0,"value"in n&&(n.writable=!0),Object.defineProperty(t,n.key,n)}}return function(e,i,n){return i&&t(e.prototype,i),n&&t(e,n),e}}();Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function t(){n(this,t)}return a(t,null,[{key:"extend",value:function(e,n){var a=void 0;for(a in n)n.hasOwnProperty(a)&&("object"!==i(n[a])||Array.isArray(n[a])||null===n[a]?e[a]=n[a]:"object"!==i(e[a])||Array.isArray(e[a])||null===n[a]?e[a]=t.extend({},n[a]):e[a]=t.extend(e[a],n[a]));return e}}]),t}();e["default"]=r}])}); |
@@ -1,11 +0,9 @@ | ||
var gulp = require('gulp'); | ||
var umd = require('gulp-wrap-umd'); | ||
var concat = require('gulp-concat'); | ||
var eslint = require('gulp-eslint'); | ||
var babel = require('gulp-babel'); | ||
var mocha = require('gulp-mocha-phantomjs'); | ||
var rename = require('gulp-rename'); | ||
var uglify = require('gulp-uglify'); | ||
var header = require('gulp-header'); | ||
var pkg = require('./package.json'); | ||
var gulp = require('gulp'); | ||
var eslint = require('gulp-eslint'); | ||
var mocha = require('gulp-mocha-phantomjs'); | ||
var rename = require('gulp-rename'); | ||
var uglify = require('gulp-uglify'); | ||
var header = require('gulp-header'); | ||
var webpack = require('webpack-stream'); | ||
var pkg = require('./package.json'); | ||
@@ -21,14 +19,5 @@ var banner = '/*! <%= pkg.name %> - v<%= pkg.version %> | <%= new Date().getFullYear() %> */\n'; | ||
]; | ||
var umdOptions = { | ||
exports: 'D3Funnel', | ||
namespace: 'D3Funnel', | ||
deps: [{ | ||
name: 'd3', | ||
globalName: 'd3', | ||
paramName: 'd3', | ||
}], | ||
}; | ||
gulp.task('test-format', function () { | ||
return gulp.src(src) | ||
return gulp.src(['./src/d3-funnel/**/*.js']) | ||
.pipe(eslint()) | ||
@@ -40,11 +29,4 @@ .pipe(eslint.format()) | ||
gulp.task('compile', function () { | ||
return gulp.src(src) | ||
.pipe(concat('d3-funnel.js')) | ||
.pipe(babel({ | ||
presets: [ | ||
'es2015', | ||
'stage-0', | ||
], | ||
})) | ||
.pipe(umd(umdOptions)) | ||
return gulp.src(['./src/index.js']) | ||
.pipe(webpack(require('./webpack.config.js'))) | ||
.pipe(gulp.dest('./compiled/')); | ||
@@ -51,0 +33,0 @@ }); |
{ | ||
"name": "d3-funnel", | ||
"version": "0.7.3", | ||
"version": "0.7.4", | ||
"description": "A library for rendering SVG funnel charts using D3.js", | ||
@@ -14,3 +14,5 @@ "author": "Jake Zatecky", | ||
"devDependencies": { | ||
"babel-core": "^6.3.17", | ||
"babel-eslint": "^4.1.5", | ||
"babel-loader": "^6.2.0", | ||
"babel-preset-es2015": "^6.1.2", | ||
@@ -21,6 +23,4 @@ "babel-preset-stage-0": "^6.1.2", | ||
"eslint": "^1.9.0", | ||
"eslint-config-airbnb": "^1.0.0", | ||
"eslint-config-airbnb": "^2.0.0", | ||
"gulp": "^3.9.0", | ||
"gulp-babel": "^6.1.0", | ||
"gulp-concat": "^2.6.0", | ||
"gulp-eslint": "^1.0.0", | ||
@@ -31,5 +31,5 @@ "gulp-header": "^1.7.1", | ||
"gulp-uglify": "^1.4.2", | ||
"gulp-wrap-umd": "^0.2.1", | ||
"lodash": "^3.10.1", | ||
"mocha": "^2.3.3" | ||
"mocha": "^2.3.3", | ||
"webpack-stream": "^3.0.0" | ||
}, | ||
@@ -36,0 +36,0 @@ "dependencies": { |
@@ -26,3 +26,4 @@ # D3 Funnel | ||
Alternatively, if you are using Webpack or Browserify, you can install the npm | ||
package and `require` the module: | ||
package and `require` or `import` the module. This will include a compatible | ||
version of D3.js for you: | ||
@@ -34,3 +35,7 @@ ``` | ||
``` javascript | ||
// CommonJS | ||
var D3Funnel = require('d3-funnel'); | ||
// ES6 | ||
import D3Funnel from 'd3-funnel'; | ||
``` | ||
@@ -171,4 +176,4 @@ | ||
If you want to pass formatted values to be shown in the funnel, pass in an array | ||
containing the value and formatted value: | ||
In addition to using `label.format`, you can also pass formatted values in an | ||
array: | ||
@@ -175,0 +180,0 @@ ``` javascript |
@@ -1,4 +0,1 @@ | ||
/* exported Colorizer */ | ||
/* jshint bitwise: false */ | ||
class Colorizer { | ||
@@ -149,1 +146,3 @@ | ||
} | ||
export default Colorizer; |
@@ -1,4 +0,8 @@ | ||
/* global d3, Colorizer, LabelFormatter, Navigator, Utils */ | ||
/* exported D3Funnel */ | ||
import d3 from 'd3'; | ||
import Colorizer from './colorizer'; | ||
import LabelFormatter from './label-formatter'; | ||
import Navigator from './navigator'; | ||
import Utils from './utils'; | ||
class D3Funnel { | ||
@@ -791,1 +795,3 @@ | ||
} | ||
export default D3Funnel; |
@@ -1,3 +0,1 @@ | ||
/* exported LabelFormatter */ | ||
class LabelFormatter { | ||
@@ -86,1 +84,3 @@ | ||
} | ||
export default LabelFormatter; |
@@ -1,3 +0,1 @@ | ||
/* exported Navigator */ | ||
class Navigator { | ||
@@ -23,1 +21,3 @@ | ||
} | ||
export default Navigator; |
@@ -1,6 +0,1 @@ | ||
/* exported Utils */ | ||
/** | ||
* Simple utility class. | ||
*/ | ||
class Utils { | ||
@@ -37,1 +32,3 @@ | ||
} | ||
export default Utils; |
@@ -626,3 +626,3 @@ /* global d3, assert, chai, D3Funnel */ | ||
it('should not trigger when null', function () { | ||
it('should not trigger errors when null', function () { | ||
var event = document.createEvent('CustomEvent'); | ||
@@ -629,0 +629,0 @@ event.initCustomEvent('click', false, false, null); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
108188
24
2766
194