From b654b84fe9b5efc9aa6ee2393873153acfda642d Mon Sep 17 00:00:00 2001 From: Jake Zatecky Date: Fri, 15 Jul 2016 00:54:21 -0400 Subject: [PATCH] Bump version --- CHANGELOG.md | 2 +- dist/d3-funnel.js | 444 ++++++++++++++++++++++++++++++++++++++---- dist/d3-funnel.min.js | 4 +- package.json | 2 +- 4 files changed, 409 insertions(+), 43 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b2ac585..c043d16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## v0.7.7 (TBA) +## v0.7.7 (July 15, 2016) ### New Features diff --git a/dist/d3-funnel.js b/dist/d3-funnel.js index 08795d7..0e121cd 100644 --- a/dist/d3-funnel.js +++ b/dist/d3-funnel.js @@ -99,6 +99,8 @@ return /******/ (function(modules) { // webpackBootstrap function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var D3Funnel = function () { @@ -199,6 +201,7 @@ return /******/ (function(modules) { // webpackBootstrap this.bottomPinch = settings.chart.bottomPinch; this.isInverted = settings.chart.inverted; this.isCurved = settings.chart.curve.enabled; + this.addValueOverlay = settings.block.barOverlay; this.curveHeight = settings.chart.curve.height; this.fillType = settings.block.fill.type; this.hoverEffects = settings.block.highlight; @@ -206,6 +209,7 @@ return /******/ (function(modules) { // webpackBootstrap this.dynamicSlope = settings.block.dynamicSlope; this.minHeight = settings.block.minHeight; this.animation = settings.chart.animate; + this.totalCount = settings.chart.totalCount; // Support for events this.onBlockClick = settings.events.click.block; @@ -298,6 +302,8 @@ return /******/ (function(modules) { // webpackBootstrap /** * Return the total count of all blocks. * + * @param {Array} data + * * @return {Number} */ @@ -306,6 +312,10 @@ return /******/ (function(modules) { // webpackBootstrap value: function _getTotalCount(data) { var _this = this; + if (this.totalCount !== null) { + return this.totalCount || 0; + } + var total = 0; data.forEach(function (block) { @@ -333,7 +343,7 @@ return /******/ (function(modules) { // webpackBootstrap data.forEach(function (block, index) { var count = _this2._getRawBlockCount(block); - var ratio = count / totalCount; + var ratio = count / totalCount || 0; var label = block[0]; standardized.push({ @@ -409,7 +419,9 @@ return /******/ (function(modules) { // webpackBootstrap // Add the SVG this.svg = _d2.default.select(this.selector).append('svg').attr('width', this.width).attr('height', this.height); - this.blockPaths = this._makePaths(); + var newPaths = this._makePaths(); + this.blockPaths = newPaths[0]; + this.overlayPaths = newPaths[1]; // Define color gradients if (this.fillType === 'gradient') { @@ -429,7 +441,7 @@ return /******/ (function(modules) { // webpackBootstrap * Create the paths to be used to define the discrete funnel blocks and * returns the results in an array. * - * @return {Array} + * @return {Array, Array} */ }, { @@ -438,6 +450,7 @@ return /******/ (function(modules) { // webpackBootstrap var _this3 = this; var paths = []; + var overlayPaths = []; // Initialize velocity var dx = this.dx; @@ -459,7 +472,7 @@ return /******/ (function(modules) { // webpackBootstrap var nextRightX = 0; var nextHeight = 0; - var middle = this.width / 2; + var centerX = this.width / 2; // Move down if there is an initial curve if (this.isCurved) { @@ -553,7 +566,7 @@ return /******/ (function(modules) { // webpackBootstrap var nextBlockValue = _this3.blocks[i + 1] ? _this3.blocks[i + 1].value : block.value; var widthPercent = 1 - nextBlockValue / block.value; - dx = widthPercent * (middle - prevLeftX); + dx = widthPercent * (centerX - prevLeftX); } // Stop velocity for pinched blocks @@ -590,31 +603,31 @@ return /******/ (function(modules) { // webpackBootstrap nextRightX = prevRightX + dx; } - // Plot curved lines + var dimensions = { + centerX: centerX, + prevLeftX: prevLeftX, + prevRightX: prevRightX, + prevHeight: prevHeight, + nextLeftX: nextLeftX, + nextRightX: nextRightX, + nextHeight: nextHeight, + curveHeight: _this3.curveHeight, + ratio: block.ratio + }; + 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 + paths = [].concat(_toConsumableArray(paths), [_this3.navigator.makeCurvedPaths(dimensions)]); + + if (_this3.addValueOverlay) { + overlayPaths = [].concat(_toConsumableArray(overlayPaths), [_this3.navigator.makeCurvedPaths(dimensions, true)]); + } } 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']]); + paths = [].concat(_toConsumableArray(paths), [_this3.navigator.makeStraightPaths(dimensions)]); + + if (_this3.addValueOverlay) { + overlayPaths = [].concat(_toConsumableArray(overlayPaths), [_this3.navigator.makeStraightPaths(dimensions, true)]); } + } // Set the next block's previous position prevLeftX = nextLeftX; @@ -622,7 +635,7 @@ return /******/ (function(modules) { // webpackBootstrap prevHeight = nextHeight; }); - return paths; + return [paths, overlayPaths]; } /** @@ -720,24 +733,62 @@ return /******/ (function(modules) { // webpackBootstrap // Attach data to the element this._attachData(path, this.blocks[index]); + var overlayPath = null; + var pathColor = this.blocks[index].fill.actual; + + if (this.addValueOverlay) { + overlayPath = this._getOverlayPath(group, index); + this._attachData(overlayPath, this.blocks[index]); + + // Add data attribute to distinguish between paths + path.node().setAttribute('pathType', 'background'); + overlayPath.node().setAttribute('pathType', 'foreground'); + + // Default path becomes background of lighter shade + pathColor = this.colorizer.shade(this.blocks[index].fill.raw, 0.3); + } + // 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 () { + path.transition().duration(this.animation).ease('linear').attr('fill', pathColor).attr('d', this._getPathDefinition(index)).each('end', function () { _this5._drawBlock(index + 1); }); } else { - path.attr('fill', this.blocks[index].fill.actual).attr('d', this._getPathDefinition(index)); + path.attr('fill', pathColor).attr('d', this._getPathDefinition(index)); this._drawBlock(index + 1); } + // Add path overlay + if (this.addValueOverlay) { + path.attr('stroke', this.blocks[index].fill.raw); + + if (this.animation !== 0) { + overlayPath.transition().duration(this.animation).ease('linear').attr('fill', this.blocks[index].fill.actual).attr('d', this._getOverlayPathDefinition(index)); + } else { + overlayPath.attr('fill', this.blocks[index].fill.actual).attr('d', this._getOverlayPathDefinition(index)); + } + } + // Add the hover events if (this.hoverEffects) { - path.on('mouseover', this._onMouseOver.bind(this)).on('mouseout', this._onMouseOut.bind(this)); + [path, overlayPath].forEach(function (target) { + if (!target) { + return; + } + + target.on('mouseover', _this5._onMouseOver.bind(_this5)).on('mouseout', _this5._onMouseOut.bind(_this5)); + }); } // Add block click event if (this.onBlockClick !== null) { - path.on('click', this.onBlockClick); + [path, overlayPath].forEach(function (target) { + if (!target) { + return; + } + + target.on('click', _this5.onBlockClick); + }); } this._addBlockLabel(group, index); @@ -762,19 +813,39 @@ return /******/ (function(modules) { // webpackBootstrap return path; } + /** + * @param {Object} group + * @param {int} index + * + * @return {Object} + */ + + }, { + key: '_getOverlayPath', + value: function _getOverlayPath(group, index) { + var path = group.append('path'); + + if (this.animation !== 0) { + this._addBeforeTransition(path, index, true); + } + + return path; + } + /** * Set the attributes of a path element before its animation. * - * @param {Object} path - * @param {int} index + * @param {Object} path + * @param {int} index + * @param {boolean} isOverlay * * @return {void} */ }, { key: '_addBeforeTransition', - value: function _addBeforeTransition(path, index) { - var paths = this.blockPaths[index]; + value: function _addBeforeTransition(path, index, isOverlay) { + var paths = isOverlay ? this.overlayPaths[index] : this.blockPaths[index]; var beforePath = ''; var beforeFill = ''; @@ -836,6 +907,24 @@ return /******/ (function(modules) { // webpackBootstrap return this.navigator.plot(commands); } + /** + * @param {int} index + * + * @return {string} + */ + + }, { + key: '_getOverlayPathDefinition', + value: function _getOverlayPathDefinition(index) { + var commands = []; + + this.overlayPaths[index].forEach(function (command) { + commands.push([command[2], command[0], command[1]]); + }); + + return this.navigator.plot(commands); + } + /** * @param {Object} data * @@ -845,7 +934,22 @@ return /******/ (function(modules) { // webpackBootstrap }, { key: '_onMouseOver', value: function _onMouseOver(data) { - _d2.default.select(_d2.default.event.target).attr('fill', this.colorizer.shade(data.fill.raw, -0.2)); + var children = _d2.default.event.target.parentElement.childNodes; + + for (var i = 0; i < children.length; i++) { + // Highlight all paths within one block + var node = children[i]; + + if (node.nodeName.toLowerCase() === 'path') { + var type = node.getAttribute('pathType') || ''; + + if (type === 'foreground') { + _d2.default.select(node).attr('fill', this.colorizer.shade(data.fill.raw, -0.5)); + } else { + _d2.default.select(node).attr('fill', this.colorizer.shade(data.fill.raw, -0.2)); + } + } + } } /** @@ -857,12 +961,29 @@ return /******/ (function(modules) { // webpackBootstrap }, { key: '_onMouseOut', value: function _onMouseOut(data) { - _d2.default.select(_d2.default.event.target).attr('fill', data.fill.actual); + var children = _d2.default.event.target.parentElement.childNodes; + + for (var i = 0; i < children.length; i++) { + // Restore original color for all paths of a block + var node = children[i]; + + if (node.nodeName.toLowerCase() === 'path') { + var type = node.getAttribute('pathType') || ''; + + if (type === 'background') { + var backgroundColor = this.colorizer.shade(data.fill.raw, 0.3); + _d2.default.select(node).attr('fill', backgroundColor); + } else { + _d2.default.select(node).attr('fill', data.fill.actual); + } + } + } } /** * @param {Object} group * @param {int} index + * * @return {void} */ @@ -926,11 +1047,13 @@ return /******/ (function(modules) { // webpackBootstrap curve: { enabled: false, height: 20 - } + }, + totalCount: null }, block: { dynamicHeight: false, dynamicSlope: false, + barOverlay: false, fill: { scale: _d2.default.scale.category10().domain(_d2.default.range(0, 10)), type: 'solid' @@ -1301,6 +1424,249 @@ return /******/ (function(modules) { // webpackBootstrap return path.replace(/ +/g, ' ').trim(); } + + /** + * @param {Object} dimensions + * @param {boolean} isValueOverlay + * + * @return {Array} + */ + + }, { + key: 'makeCurvedPaths', + value: function makeCurvedPaths(dimensions) { + var isValueOverlay = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; + + var points = this.makeBezierPoints(dimensions); + + if (isValueOverlay) { + return this.makeBezierPath(points, dimensions.ratio); + } + + return this.makeBezierPath(points); + } + + /** + * @param {Number} centerX + * @param {Number} prevLeftX + * @param {Number} prevRightX + * @param {Number} prevHeight + * @param {Number} nextLeftX + * @param {Number} nextRightX + * @param {Number} nextHeight + * @param {Number} curveHeight + * + * @returns {Object} + */ + + }, { + key: 'makeBezierPoints', + value: function makeBezierPoints(_ref) { + var centerX = _ref.centerX; + var prevLeftX = _ref.prevLeftX; + var prevRightX = _ref.prevRightX; + var prevHeight = _ref.prevHeight; + var nextLeftX = _ref.nextLeftX; + var nextRightX = _ref.nextRightX; + var nextHeight = _ref.nextHeight; + var curveHeight = _ref.curveHeight; + + return { + p00: { + x: prevLeftX, + y: prevHeight + }, + p01: { + x: centerX, + y: prevHeight + curveHeight - 10 + }, + p02: { + x: prevRightX, + y: prevHeight + }, + + p10: { + x: nextLeftX, + y: nextHeight + }, + p11: { + x: centerX, + y: nextHeight + curveHeight + }, + p12: { + x: nextRightX, + y: nextHeight + } + }; + } + + /** + * @param {Object} p00 + * @param {Object} p01 + * @param {Object} p02 + * @param {Object} p10 + * @param {Object} p11 + * @param {Object} p12 + * @param {Number} ratio + * + * @returns {Array} + */ + + }, { + key: 'makeBezierPath', + value: function makeBezierPath(_ref2) { + var p00 = _ref2.p00; + var p01 = _ref2.p01; + var p02 = _ref2.p02; + var p10 = _ref2.p10; + var p11 = _ref2.p11; + var p12 = _ref2.p12; + var ratio = arguments.length <= 1 || arguments[1] === undefined ? 1 : arguments[1]; + + var curve0 = this.getQuadraticBezierCurve(p00, p01, p02, ratio); + var curve1 = this.getQuadraticBezierCurve(p10, p11, p12, ratio); + + return [ + // Top Bezier curve + [curve0.p0.x, curve0.p0.y, 'M'], [curve0.p1.x, curve0.p1.y, 'Q'], [curve0.p2.x, curve0.p2.y, ''], + // Right line + [curve1.p2.x, curve1.p2.y, 'L'], + // Bottom Bezier curve + [curve1.p2.x, curve1.p2.y, 'M'], [curve1.p1.x, curve1.p1.y, 'Q'], [curve1.p0.x, curve1.p0.y, ''], + // Left line + [curve0.p0.x, curve0.p0.y, 'L']]; + } + + /** + * @param {Object} p0 + * @param {Object} p1 + * @param {Object} p2 + * @param {Number} t + * + * @return {Object} + */ + + }, { + key: 'getQuadraticBezierCurve', + value: function getQuadraticBezierCurve(p0, p1, p2) { + var t = arguments.length <= 3 || arguments[3] === undefined ? 1 : arguments[3]; + + // Quadratic Bezier curve syntax: M(P0) Q(P1) P2 + // Where P0, P2 are the curve endpoints and P1 is the control point + + // More generally, at 0 <= t <= 1, we have the following: + // Q0(t), which varies linearly from P0 to P1 + // Q1(t), which varies linearly from P1 to P2 + // B(t), which is interpolated linearly between Q0(t) and Q1(t) + + // For an intermediate curve at 0 <= t <= 1: + // P1(t) = Q0(t) + // P2(t) = B(t) + + return { + p0: p0, + p1: { + x: this.getLinearInterpolation(p0, p1, t, 'x'), + y: this.getLinearInterpolation(p0, p1, t, 'y') + }, + p2: { + x: this.getQuadraticInterpolation(p0, p1, p2, t, 'x'), + y: this.getQuadraticInterpolation(p0, p1, p2, t, 'y') + } + }; + } + + /** + * @param {Object} p0 + * @param {Object} p1 + * @param {Number} t + * @param {string} axis + * + * @return {Number} + */ + + }, { + key: 'getLinearInterpolation', + value: function getLinearInterpolation(p0, p1, t, axis) { + return p0[axis] + t * (p1[axis] - p0[axis]); + } + + /** + * @param {Object} p0 + * @param {Object} p1 + * @param {Object} p2 + * @param {Number} t + * @param {string} axis + * + * @return {Number} + */ + + }, { + key: 'getQuadraticInterpolation', + value: function getQuadraticInterpolation(p0, p1, p2, t, axis) { + return Math.pow(1 - t, 2) * p0[axis] + 2 * (1 - t) * t * p1[axis] + Math.pow(t, 2) * p2[axis]; + } + + /** + * @param {Number} prevLeftX + * @param {Number} prevRightX + * @param {Number} prevHeight + * @param {Number} nextLeftX + * @param {Number} nextRightX + * @param {Number} nextHeight + * @param {Number} ratio + * @param {boolean} isValueOverlay + * + * @return {Object} + */ + + }, { + key: 'makeStraightPaths', + value: function makeStraightPaths(_ref3) { + var prevLeftX = _ref3.prevLeftX; + var prevRightX = _ref3.prevRightX; + var prevHeight = _ref3.prevHeight; + var nextLeftX = _ref3.nextLeftX; + var nextRightX = _ref3.nextRightX; + var nextHeight = _ref3.nextHeight; + var ratio = _ref3.ratio; + var isValueOverlay = arguments.length <= 1 || arguments[1] === undefined ? false : arguments[1]; + + if (isValueOverlay) { + var lengthTop = prevRightX - prevLeftX; + var lengthBtm = nextRightX - nextLeftX; + var rightSideTop = lengthTop * (ratio || 0) + prevLeftX; + var rightSideBtm = lengthBtm * (ratio || 0) + nextLeftX; + + // Overlay should not be longer than the max length of the path + rightSideTop = Math.min(rightSideTop, lengthTop); + rightSideBtm = Math.min(rightSideBtm, lengthBtm); + + return [ + // Start position + [prevLeftX, prevHeight, 'M'], + // Move to right + [rightSideTop, prevHeight, 'L'], + // Move down + [rightSideBtm, nextHeight, 'L'], + // Move to left + [nextLeftX, nextHeight, 'L'], + // Wrap back to top + [prevLeftX, prevHeight, 'L']]; + } + + return [ + // 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']]; + } }]); return Navigator; diff --git a/dist/d3-funnel.min.js b/dist/d3-funnel.min.js index 4df833a..1c04e47 100644 --- a/dist/d3-funnel.min.js +++ b/dist/d3-funnel.min.js @@ -1,2 +1,2 @@ -/*! d3-funnel - v0.7.6 | 2016 */ -!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")}Object.defineProperty(e,"__esModule",{value:!0});var r=Object.assign||function(t){for(var e=1;e0?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=s["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,c=this.width/2;this.isCurved&&(o=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.blocks.length-t.bottomPinch&&(f-=e.height))});var d=2*f/(this.width-this.bottomWidth);return this.blocks.forEach(function(f,v){if(t.dynamicHeight&&(n=u*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.dynamicSlope){var b=t.blocks[v+1]?t.blocks[v+1].value:f.value,y=1-b/f.value;i=y*(c-a)}t.bottomPinch>0&&(t.isInverted?(t.dynamicHeight||(i=t.dx),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"],[c,o+(t.curveHeight-10),"Q"],[r,o,""],[s,h,"L"],[s,h,"M"],[c,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=this,i=t.append("defs");this.blocks.forEach(function(t,n){var a=t.fill.raw,r=e.colorizer.shade(a,-.2),o=i.append("linearGradient").attr({id:"gradient-"+n}),l=[[0,r],[40,a],[60,a],[100,r]];l.forEach(function(t){o.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",this.colorizer.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);this._attachData(n,this.blocks[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.bind(this)).on("mouseout",this._onMouseOut.bind(this)),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:"_attachData",value:function(t,e){var i=r({},e,{node:t.node()});t.data([i])}},{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){s["default"].select(s["default"].event.target).attr("fill",this.colorizer.shade(t.fill.raw,-.2))}},{key:"_onMouseOut",value:function(t){s["default"].select(s["default"].event.target).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),l=t.append("text").text(n).attr({x:r,y:o,fill:a,"text-anchor":"middle","dominant-baseline":"middle","pointer-events":"none"}).attr("font-size",this.label.fontSize);null!==this.label.fontFamily&&l.attr("font-family",this.label.fontFamily)}},{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}();g.defaults={chart:{width:350,height:400,bottomWidth:1/3,bottomPinch:0,inverted:!1,horizontal:!1,animate:0,curve:{enabled:!1,height:20}},block:{dynamicHeight:!1,dynamicSlope:!1,fill:{scale:s["default"].scale.category10().domain(s["default"].range(0,10)),type:"solid"},minHeight:0,highlight:!1},label:{fontFamily:null,fontSize:"14px",fill:"#fff",format:"{l}: {f}"},events:{click:{block:null}}},e["default"]=g},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")}Object.defineProperty(e,"__esModule",{value:!0});var n=function(){function t(t,e){for(var i=0;i2&&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(t,e){var i=t.slice(1);3===i.length&&(i=this.expandHex(i));var n=parseInt(i,16),a=0>e?0:255,r=0>e?-1*e:e,o=n>>16,l=n>>8&255,s=255&n,h=16777216+65536*(Math.round((a-o)*r)+o)+256*(Math.round((a-l)*r)+l)+(Math.round((a-s)*r)+s);return"#"+h.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")}Object.defineProperty(e,"__esModule",{value:!0});var n=function(){function t(t,e){for(var i=0;i0&&(n=t.extend({},e)),Object.keys(i).forEach(function(a){t.isExtendableObject(i[a])?t.isExtendableObject(e[a])?n[a]=t.extend(e[a],i[a]):n[a]=t.extend({},i[a]):n[a]=i[a]}),n}}]),t}();e["default"]=r}])}); \ No newline at end of file +/*! d3-funnel - v0.7.7 | 2016 */ +!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(a){if(i[a])return i[a].exports;var n=i[a]={exports:{},id:a,loaded:!1};return t[a].call(n.exports,n,n.exports,e),n.loaded=!0,n.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 a(t){return t&&t.__esModule?t:{"default":t}}function n(t){if(Array.isArray(t)){for(var e=0,i=Array(t.length);e0?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=s["default"].select(this.selector).append("svg").attr("width",this.width).attr("height",this.height);var t=this._makePaths();this.blockPaths=t[0],this.overlayPaths=t[1],"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=[],a=this.dx,r=this.dy,o=0,l=this.width,h=0;this.isInverted&&(o=this.bottomLeftX,l=this.width-this.bottomLeftX);var s=0,u=0,c=0,f=this.width/2;this.isCurved&&(h=10);var d=this.height;0!==this.minHeight&&(d=this.height-this.minHeight*this.blocks.length);var v=this.height;this.blocks.forEach(function(e,i){t.bottomPinch>0&&(t.isInverted?i=t.blocks.length-t.bottomPinch&&(v-=e.height))});var y=2*v/(this.width-this.bottomWidth);return this.blocks.forEach(function(v,g){if(t.dynamicHeight&&(r=d*v.ratio,0!==t.minHeight&&(r+=t.minHeight),t.isCurved&&(r-=t.curveHeight/t.blocks.length),s=(h+r)/y,t.isInverted&&(s=(h+r-t.height)/(-1*y)),0===t.bottomWidth&&g===t.blocks.length-1&&(s=t.width/2,t.isInverted&&(s=0)),t.bottomWidth===t.width&&(s=o),a=s-o,t.isInverted&&(a=o-s)),t.dynamicSlope){var p=t.blocks[g+1]?t.blocks[g+1].value:v.value,b=1-p/v.value;a=b*(f-o)}t.bottomPinch>0&&(t.isInverted?(t.dynamicHeight||(a=t.dx),a=g=t.blocks.length-t.bottomPinch&&(a=0)),s=o+a,u=l-a,c=h+r,t.isInverted&&(s=o-a,u=l+a);var k={centerX:f,prevLeftX:o,prevRightX:l,prevHeight:h,nextLeftX:s,nextRightX:u,nextHeight:c,curveHeight:t.curveHeight,ratio:v.ratio};t.isCurved?(e=[].concat(n(e),[t.navigator.makeCurvedPaths(k)]),t.addValueOverlay&&(i=[].concat(n(i),[t.navigator.makeCurvedPaths(k,!0)]))):(e=[].concat(n(e),[t.navigator.makeStraightPaths(k)]),t.addValueOverlay&&(i=[].concat(n(i),[t.navigator.makeStraightPaths(k,!0)]))),o=s,l=u,h=c}),[e,i]}},{key:"_defineColorGradients",value:function(t){var e=this,i=t.append("defs");this.blocks.forEach(function(t,a){var n=t.fill.raw,r=e.colorizer.shade(n,-.2),o=i.append("linearGradient").attr({id:"gradient-"+a}),l=[[0,r],[40,n],[60,n],[100,r]];l.forEach(function(t){o.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],o=r[1][1]+this.curveHeight-10,l=this.navigator.plot([["M",i,r[0][1]],["Q",n,o],[" ",a,r[2][1]],["M",a,10],["Q",n,0],[" ",i,10]]);t.append("path").attr("fill",this.colorizer.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"),a=this._getBlockPath(i,t);this._attachData(a,this.blocks[t]);var n=null,r=this.blocks[t].fill.actual;this.addValueOverlay&&(n=this._getOverlayPath(i,t),this._attachData(n,this.blocks[t]),a.node().setAttribute("pathType","background"),n.node().setAttribute("pathType","foreground"),r=this.colorizer.shade(this.blocks[t].fill.raw,.3)),0!==this.animation?a.transition().duration(this.animation).ease("linear").attr("fill",r).attr("d",this._getPathDefinition(t)).each("end",function(){e._drawBlock(t+1)}):(a.attr("fill",r).attr("d",this._getPathDefinition(t)),this._drawBlock(t+1)),this.addValueOverlay&&(a.attr("stroke",this.blocks[t].fill.raw),0!==this.animation?n.transition().duration(this.animation).ease("linear").attr("fill",this.blocks[t].fill.actual).attr("d",this._getOverlayPathDefinition(t)):n.attr("fill",this.blocks[t].fill.actual).attr("d",this._getOverlayPathDefinition(t))),this.hoverEffects&&[a,n].forEach(function(t){t&&t.on("mouseover",e._onMouseOver.bind(e)).on("mouseout",e._onMouseOut.bind(e))}),null!==this.onBlockClick&&[a,n].forEach(function(t){t&&t.on("click",e.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:"_getOverlayPath",value:function(t,e){var i=t.append("path");return 0!==this.animation&&this._addBeforeTransition(i,e,!0),i}},{key:"_addBeforeTransition",value:function(t,e,i){var a=i?this.overlayPaths[e]:this.blockPaths[e],n="",r="";n=this.isCurved?this.navigator.plot([["M",a[0][0],a[0][1]],["Q",a[1][0],a[1][1]],[" ",a[2][0],a[2][1]],["L",a[2][0],a[2][1]],["M",a[2][0],a[2][1]],["Q",a[1][0],a[1][1]],[" ",a[0][0],a[0][1]]]):this.navigator.plot([["M",a[0][0],a[0][1]],["L",a[1][0],a[1][1]],["L",a[1][0],a[1][1]],["L",a[0][0],a[0][1]]]),r="solid"===this.fillType&&e>0?this.blocks[e-1].fill.actual:this.blocks[e].fill.actual,t.attr("d",n).attr("fill",r)}},{key:"_attachData",value:function(t,e){var i=o({},e,{node:t.node()});t.data([i])}},{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:"_getOverlayPathDefinition",value:function(t){var e=[];return this.overlayPaths[t].forEach(function(t){e.push([t[2],t[0],t[1]])}),this.navigator.plot(e)}},{key:"_onMouseOver",value:function(t){for(var e=s["default"].event.target.parentElement.childNodes,i=0;i2&&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(t,e){var i=t.slice(1);3===i.length&&(i=this.expandHex(i));var a=parseInt(i,16),n=0>e?0:255,r=0>e?-1*e:e,o=a>>16,l=a>>8&255,h=255&a,s=16777216+65536*(Math.round((n-o)*r)+o)+256*(Math.round((n-l)*r)+l)+(Math.round((n-h)*r)+h);return"#"+s.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"]=n},function(t,e){"use strict";function i(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0});var a=function(){function t(t,e){for(var i=0;i0&&(a=t.extend({},e)),Object.keys(i).forEach(function(n){t.isExtendableObject(i[n])?t.isExtendableObject(e[n])?a[n]=t.extend(e[n],i[n]):a[n]=t.extend({},i[n]):a[n]=i[n]}),a}}]),t}();e["default"]=r}])}); \ No newline at end of file diff --git a/package.json b/package.json index 25d567f..41ea029 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "d3-funnel", - "version": "0.7.6", + "version": "0.7.7", "description": "A library for rendering SVG funnel charts using D3.js", "author": "Jake Zatecky", "license": "MIT",