Socket
Socket
Sign inDemoInstall

d3-funnel

Package Overview
Dependencies
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

d3-funnel - npm Package Compare versions

Comparing version 0.6.3 to 0.6.4

299

dist/d3-funnel.js

@@ -14,3 +14,4 @@ (function(global) {

*/
function D3Funnel(selector) {
var D3Funnel = function(selector)
{
this.selector = selector;

@@ -30,7 +31,9 @@

dynamicArea: false,
animation: false,
label: {
fontSize: "14px"
fontSize: "14px",
fill: "#fff"
}
};
}
};

@@ -44,3 +47,4 @@ /**

*/
D3Funnel.prototype._isArray = function(value) {
D3Funnel.prototype.__isArray = function(value)
{
return Object.prototype.toString.call(value) === "[object Array]";

@@ -57,3 +61,4 @@ };

*/
D3Funnel.prototype._extend = function(a, b) {
D3Funnel.prototype.__extend = function(a, b)
{
var prop;

@@ -98,8 +103,11 @@ for (prop in b) {

* data counts.
* @param {int} options.animation The load animation speed. If empty,
* there will be no load animation.
* @param {Object} options.label
* @param {Object} options.label.fontSize
*/
D3Funnel.prototype.draw = function(data, options) {
D3Funnel.prototype.draw = function(data, options)
{
// Initialize chart options
this._initialize(data, options);
this.__initialize(data, options);

@@ -110,3 +118,3 @@ // Remove any previous drawings

// Add the SVG and group element
var svg = d3.select(this.selector)
this.svg = d3.select(this.selector)
.append("svg")

@@ -116,10 +124,8 @@ .attr("width", this.width)

.append("g");
var group = {};
var path = {};
var sectionPaths = this._makePaths();
this.sectionPaths = this.__makePaths();
// Define color gradients
if (this.fillType === "gradient") {
this._defineColorGradients(svg);
this.__defineColorGradients(this.svg);
}

@@ -129,64 +135,67 @@

if (this.isCurved) {
this._drawTopOval(svg, sectionPaths);
this.__drawTopOval(this.svg, this.sectionPaths);
}
// Add each block section
for (var i = 0; i < sectionPaths.length; i++) {
// Set the background color
var fill = this.fillType !== "gradient" ?
this.data[i][2] :
"url(#gradient-" + i + ")";
this.__drawSection(0);
};
// Prepare data to assign to the section
data = {
index: i,
label: this.data[i][0],
value: this.data[i][1],
baseColor: this.data[i][2],
fill: fill
};
/**
* Draw the next section in the iteration.
*
* @param {int} index
*/
D3Funnel.prototype.__drawSection = function(index)
{
if (index === this.data.length) {
return;
}
// Construct path string
var paths = sectionPaths[i];
var pathStr = "";
// Create a group just for this block
var group = this.svg.append("g");
// Iterate through each point
for (var j = 0; j < paths.length; j++) {
path = paths[j];
pathStr += path[2] + path[0] + "," + path[1] + " ";
}
// Fetch path element
var path = this.__getSectionPath(group, index);
path.data(this.__getSectionData(index));
// Create a group just for this block
group = svg.append("g");
// Add animation components
if (this.animation !== false) {
var self = this;
path.transition()
.duration(this.animation)
.ease("linear")
.attr("fill", this.__getColor(index))
.attr("d", this.__getPathDefinition(index))
.each("end", function() {
self.__drawSection(index + 1);
});
} else {
path.attr("fill", this.__getColor(index))
.attr("d", this.__getPathDefinition(index));
this.__drawSection(index + 1);
}
// Draw the sections's path and append the data
path = group.append("path")
.attr("fill", fill)
.attr("d", pathStr)
.data([data]);
console.log(":(");
// Add the hover events
if (this.hoverEffects) {
path.on("mouseover", this._onMouseOver)
.on("mouseout", this._onMouseOut);
}
// Add the section label
var textStr = this.data[i][0] + ": " + this.data[i][1].toLocaleString();
var textX = this.width / 2; // Center the text
var textY = !this.isCurved ? // Average height of bases
(paths[1][1] + paths[2][1]) / 2 :
(paths[2][1] + paths[3][1]) / 2 + (this.curveHeight / this.data.length);
// Add the hover events
if (this.hoverEffects) {
path.on("mouseover", this.__onMouseOver)
.on("mouseout", this.__onMouseOut);
}
group.append("text")
.text(textStr)
.attr({
"x": textX,
"y": textY,
"text-anchor": "middle",
"dominant-baseline": "middle",
"fill": "#fff",
"pointer-events": "none"
})
.style("font-size", this.label.fontSize);
this.__addSectionLabel(group, index);
};
/**
* Return the color for the given index.
*
* @param {int} index
*/
D3Funnel.prototype.__getColor = function(index)
{
if (this.fillType === "solid") {
return this.data[index][2];
} else {
return "url(#gradient-" + index + ")";
}

@@ -196,2 +205,125 @@ };

/**
* @param {Object} group
* @param {int} index
*
* @return {Object}
*/
D3Funnel.prototype.__getSectionPath = function(group, index)
{
var path = group.append("path");
if (this.animation !== false) {
this.__addBeforeTransition(path, index);
}
return path;
};
/**
* Set the attributes of a path element before its animation.
*
* @param {Object} path
* @param {int} index
*/
D3Funnel.prototype.__addBeforeTransition = function(path, index)
{
var paths = this.sectionPaths[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 = "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 = "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") {
beforeFill = index > 0 ? this.__getColor(index - 1) : this.__getColor(index);
// Use current background if gradient (gradients do not transition)
} else {
beforeFill = this.__getColor(index);
}
path.attr("d", beforePath)
.attr("fill", beforeFill);
};
/**
* @param {int} index
*
* @return {array}
*/
D3Funnel.prototype.__getSectionData = function(index)
{
return [{
index: index,
label: this.data[index][0],
value: this.data[index][1],
baseColor: this.data[index][2],
fill: this.__getColor(index)
}];
};
/**
* @param {int} index
*
* @return {string}
*/
D3Funnel.prototype.__getPathDefinition = function(index)
{
var pathStr = "";
var point = [];
var paths = this.sectionPaths[index];
for (var j = 0; j < paths.length; j++) {
point = paths[j];
pathStr += point[2] + point[0] + "," + point[1] + " ";
}
return pathStr;
};
/**
* @param {Object} group
* @param {int} index
*/
D3Funnel.prototype.__addSectionLabel = function(group, index)
{
var i = index;
var paths = this.sectionPaths[index];
var textStr = this.data[i][0] + ": " + this.data[i][1].toLocaleString();
var textFill = this.data[i][3] || this.label.fill;
var textX = this.width / 2; // Center the text
var textY = !this.isCurved ? // Average height of bases
(paths[1][1] + paths[2][1]) / 2 :
(paths[2][1] + paths[3][1]) / 2 + (this.curveHeight / this.data.length);
group.append("text")
.text(textStr)
.attr({
"x": textX,
"y": textY,
"text-anchor": "middle",
"dominant-baseline": "middle",
"fill": textFill,
"pointer-events": "none"
})
.style("font-size", this.label.fontSize);
};
/**
* Initialize and calculate important variables for drawing the chart.

@@ -202,5 +334,6 @@ *

*/
D3Funnel.prototype._initialize = function(data, options) {
if (!this._isArray(data) || data.length === 0 ||
!this._isArray(data[0]) || data[0].length < 2) {
D3Funnel.prototype.__initialize = function(data, options)
{
if (!this.__isArray(data) || data.length === 0 ||
!this.__isArray(data[0]) || data[0].length < 2) {
throw {

@@ -222,3 +355,3 @@ name: "D3 Funnel Data Error",

// Set the default width and height based on the container
var settings = this._extend({}, this.defaults);
var settings = this.__extend({}, this.defaults);
settings.width = parseInt(d3.select(this.selector).style("width"), 10);

@@ -237,4 +370,8 @@ settings.height = parseInt(d3.select(this.selector).style("height"), 10);

if ("label" in options) {
if ("fontSize" in options.label) {
settings.label.fontSize = options.label.fontSize;
var validLabelOptions = /fontSize|fill/;
var labelOption;
for (labelOption in options.label) {
if (labelOption.match(validLabelOptions)) {
settings.label[labelOption] = options.label[labelOption];
}
}

@@ -259,4 +396,3 @@ }

// If a color is not set for the record, add one
if (typeof this.data[i][2] === "undefined" ||
!hexExpression.test(this.data[i][2])) {
if (!("2" in this.data[i]) || !hexExpression.test(this.data[i][2])) {
this.data[i][2] = colorScale(i);

@@ -277,2 +413,3 @@ }

this.dynamicArea = settings.dynamicArea;
this.animation = settings.animation;

@@ -300,3 +437,4 @@ // Calculate the bottom left x position

*/
D3Funnel.prototype._makePaths = function() {
D3Funnel.prototype.__makePaths = function()
{
var paths = [];

@@ -448,3 +586,4 @@

*/
D3Funnel.prototype._defineColorGradients = function(svg) {
D3Funnel.prototype.__defineColorGradients = function(svg)
{
var defs = svg.append("defs");

@@ -488,3 +627,4 @@

*/
D3Funnel.prototype._drawTopOval = function(svg, sectionPaths) {
D3Funnel.prototype.__drawTopOval = function(svg, sectionPaths)
{
var leftX = 0;

@@ -517,3 +657,4 @@ var rightX = this.width;

*/
D3Funnel.prototype._onMouseOver = function(data) {
D3Funnel.prototype.__onMouseOver = function(data)
{
d3.select(this).attr("fill", shadeColor(data.baseColor, -0.2));

@@ -525,3 +666,4 @@ };

*/
D3Funnel.prototype._onMouseOut = function(data) {
D3Funnel.prototype.__onMouseOut = function(data)
{
d3.select(this).attr("fill", data.fill);

@@ -536,3 +678,4 @@ };

*/
function shadeColor(color, shade) {
function shadeColor(color, shade)
{
var f = parseInt(color.slice(1), 16);

@@ -553,2 +696,2 @@ var t = shade < 0 ? 0 : 255;

})(this);
})(window);

@@ -1,2 +0,2 @@

/*! d3-funnel - v0.6.2 | 2015-02-04 */
!function(a){"use strict";function b(a){this.selector=a,this.defaults={width:350,height:400,bottomWidth:1/3,bottomPinch:0,isCurved:!1,curveHeight:20,fillType:"solid",isInverted:!1,hoverEffects:!1,dynamicArea:!1,label:{fontSize:"14px"}}}function c(a,b){var c=parseInt(a.slice(1),16),d=0>b?0:255,e=0>b?-1*b:b,f=c>>16,g=c>>8&255,h=255&c,i=16777216+65536*(Math.round((d-f)*e)+f)+256*(Math.round((d-g)*e)+g)+(Math.round((d-h)*e)+h);return"#"+i.toString(16).slice(1)}b.prototype._isArray=function(a){return"[object Array]"===Object.prototype.toString.call(a)},b.prototype._extend=function(a,b){var c;for(c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return a},b.prototype.draw=function(a,b){this._initialize(a,b),d3.select(this.selector).selectAll("svg").remove();var c=d3.select(this.selector).append("svg").attr("width",this.width).attr("height",this.height).append("g"),d={},e={},f=this._makePaths();"gradient"===this.fillType&&this._defineColorGradients(c),this.isCurved&&this._drawTopOval(c,f);for(var g=0;g<f.length;g++){var h="gradient"!==this.fillType?this.data[g][2]:"url(#gradient-"+g+")";a={index:g,label:this.data[g][0],value:this.data[g][1],baseColor:this.data[g][2],fill:h};for(var i=f[g],j="",k=0;k<i.length;k++)e=i[k],j+=e[2]+e[0]+","+e[1]+" ";d=c.append("g"),e=d.append("path").attr("fill",h).attr("d",j).data([a]),this.hoverEffects&&e.on("mouseover",this._onMouseOver).on("mouseout",this._onMouseOut);var l=this.data[g][0]+": "+this.data[g][1].toLocaleString(),m=this.width/2,n=this.isCurved?(i[2][1]+i[3][1])/2+this.curveHeight/this.data.length:(i[1][1]+i[2][1])/2;d.append("text").text(l).attr({x:m,y:n,"text-anchor":"middle","dominant-baseline":"middle",fill:"#fff","pointer-events":"none"}).style("font-size",this.label.fontSize)}},b.prototype._initialize=function(a,b){if(!this._isArray(a)||0===a.length||!this._isArray(a[0])||a[0].length<2)throw{name:"D3 Funnel Data Error",message:"Funnel data is not valid."};b="undefined"!=typeof b?b:{},this.data=a;var c=0,d=this._extend({},this.defaults);d.width=parseInt(d3.select(this.selector).style("width"),10),d.height=parseInt(d3.select(this.selector).style("height"),10);var e=Object.keys(b);for(c=0;c<e.length;c++)"label"!==e[c]&&(d[e[c]]=b[e[c]]);"label"in b&&"fontSize"in b.label&&(d.label.fontSize=b.label.fontSize),this.label=d.label,d.width<=0&&(d.width=this.defaults.width),d.height<=0&&(d.height=this.defaults.height);var f=d3.scale.category10();for(c=0;c<this.data.length;c++){var g=/^#([0-9a-f]{3}|[0-9a-f]{6})$/i;"undefined"!=typeof this.data[c][2]&&g.test(this.data[c][2])||(this.data[c][2]=f(c))}this.width=d.width,this.height=d.height,this.bottomWidth=d.width*d.bottomWidth,this.bottomPinch=d.bottomPinch,this.isCurved=d.isCurved,this.curveHeight=d.curveHeight,this.fillType=d.fillType,this.isInverted=d.isInverted,this.hoverEffects=d.hoverEffects,this.dynamicArea=d.dynamicArea,this.bottomLeftX=(this.width-this.bottomWidth)/2,this.dx=this.bottomPinch>0?this.bottomLeftX/(a.length-this.bottomPinch):this.bottomLeftX/a.length,this.dy=this.isCurved?(this.height-this.curveHeight)/a.length:this.height/a.length},b.prototype._makePaths=function(){var a=[],b=this.dx,c=this.dy,d=0,e=this.width,f=0;this.isInverted&&(d=this.bottomLeftX,e=this.width-this.bottomLeftX);var g=0,h=0,i=0,j=this.width/2;this.isCurved&&(f=10);for(var k=this.width,l=0,m=this.height*(this.width+this.bottomWidth)/2,n=2*this.height/(this.width-this.bottomWidth),o=0,p=0,q=0;q<this.data.length;q++)o+=this.data[q][1];for(q=0;q<this.data.length;q++){if(p=this.data[q][1],this.dynamicArea){var r=p/o,s=r*m;l=Math.sqrt((n*k*k-4*s)/n),b=k/2-l/2,c=2*s/(k+l),this.isCurved&&(c-=this.curveHeight/this.data.length),k=l}this.bottomPinch>0&&(this.isInverted?(this.dynamicArea||(b=this.dx),b=q<this.bottomPinch?0:b):q>=this.data.length-this.bottomPinch&&(b=0)),g=d+b,h=e-b,i=f+c,this.isInverted&&(g=d-b,h=e+b),a.push(this.isCurved?[[d,f,"M"],[j,f+(this.curveHeight-10),"Q"],[e,f,""],[h,i,"L"],[h,i,"M"],[j,i+this.curveHeight,"Q"],[g,i,""],[d,f,"L"]]:[[d,f,"M"],[e,f,"L"],[h,i,"L"],[g,i,"L"],[d,f,"L"]]),d=g,e=h,f=i}return a},b.prototype._defineColorGradients=function(a){for(var b=a.append("defs"),d=0;d<this.data.length;d++)for(var e=this.data[d][2],f=c(e,-.25),g=b.append("linearGradient").attr({id:"gradient-"+d}),h=[[0,f],[40,e],[60,e],[100,f]],i=0;i<h.length;i++){var j=h[i];g.append("stop").attr({offset:j[0]+"%",style:"stop-color:"+j[1]})}},b.prototype._drawTopOval=function(a,b){var d=0,e=this.width,f=this.width/2;this.isInverted&&(d=this.bottomLeftX,e=this.width-this.bottomLeftX);var g=b[0],h="M"+d+","+g[0][1]+" Q"+f+","+(g[1][1]+this.curveHeight-10)+" "+e+","+g[2][1]+" M"+e+",10 Q"+f+",0 "+d+",10";a.append("path").attr("fill",c(this.data[0][2],-.4)).attr("d",h)},b.prototype._onMouseOver=function(a){d3.select(this).attr("fill",c(a.baseColor,-.2))},b.prototype._onMouseOut=function(a){d3.select(this).attr("fill",a.fill)},a.D3Funnel=b}(this);
/*! d3-funnel - v0.6.4 | 2015-03-08 */
!function(a){"use strict";function b(a,b){var c=parseInt(a.slice(1),16),d=0>b?0:255,e=0>b?-1*b:b,f=c>>16,g=c>>8&255,h=255&c,i=16777216+65536*(Math.round((d-f)*e)+f)+256*(Math.round((d-g)*e)+g)+(Math.round((d-h)*e)+h);return"#"+i.toString(16).slice(1)}var c=function(a){this.selector=a,this.defaults={width:350,height:400,bottomWidth:1/3,bottomPinch:0,isCurved:!1,curveHeight:20,fillType:"solid",isInverted:!1,hoverEffects:!1,dynamicArea:!1,animation:!1,label:{fontSize:"14px",fill:"#fff"}}};c.prototype.__isArray=function(a){return"[object Array]"===Object.prototype.toString.call(a)},c.prototype.__extend=function(a,b){var c;for(c in b)b.hasOwnProperty(c)&&(a[c]=b[c]);return a},c.prototype.draw=function(a,b){this.__initialize(a,b),d3.select(this.selector).selectAll("svg").remove(),this.svg=d3.select(this.selector).append("svg").attr("width",this.width).attr("height",this.height).append("g"),this.sectionPaths=this.__makePaths(),"gradient"===this.fillType&&this.__defineColorGradients(this.svg),this.isCurved&&this.__drawTopOval(this.svg,this.sectionPaths),this.__drawSection(0)},c.prototype.__drawSection=function(a){if(a!==this.data.length){var b=this.svg.append("g"),c=this.__getSectionPath(b,a);if(c.data(this.__getSectionData(a)),this.animation!==!1){var d=this;c.transition().duration(this.animation).ease("linear").attr("fill",this.__getColor(a)).attr("d",this.__getPathDefinition(a)).each("end",function(){d.__drawSection(a+1)})}else c.attr("fill",this.__getColor(a)).attr("d",this.__getPathDefinition(a)),this.__drawSection(a+1);console.log(":("),this.hoverEffects&&c.on("mouseover",this.__onMouseOver).on("mouseout",this.__onMouseOut),this.__addSectionLabel(b,a)}},c.prototype.__getColor=function(a){return"solid"===this.fillType?this.data[a][2]:"url(#gradient-"+a+")"},c.prototype.__getSectionPath=function(a,b){var c=a.append("path");return this.animation!==!1&&this.__addBeforeTransition(c,b),c},c.prototype.__addBeforeTransition=function(a,b){var c=this.sectionPaths[b],d="",e="";d=this.isCurved?"M"+c[0][0]+","+c[0][1]+" Q"+c[1][0]+","+c[1][1]+" "+c[2][0]+","+c[2][1]+" L"+c[2][0]+","+c[2][1]+" M"+c[2][0]+","+c[2][1]+" Q"+c[1][0]+","+c[1][1]+" "+c[0][0]+","+c[0][1]:"M"+c[0][0]+","+c[0][1]+" L"+c[1][0]+","+c[1][1]+" L"+c[1][0]+","+c[1][1]+" L"+c[0][0]+","+c[0][1],e=this.__getColor("solid"===this.fillType?b>0?b-1:b:b),a.attr("d",d).attr("fill",e)},c.prototype.__getSectionData=function(a){return[{index:a,label:this.data[a][0],value:this.data[a][1],baseColor:this.data[a][2],fill:this.__getColor(a)}]},c.prototype.__getPathDefinition=function(a){for(var b="",c=[],d=this.sectionPaths[a],e=0;e<d.length;e++)c=d[e],b+=c[2]+c[0]+","+c[1]+" ";return b},c.prototype.__addSectionLabel=function(a,b){var c=b,d=this.sectionPaths[b],e=this.data[c][0]+": "+this.data[c][1].toLocaleString(),f=this.data[c][3]||this.label.fill,g=this.width/2,h=this.isCurved?(d[2][1]+d[3][1])/2+this.curveHeight/this.data.length:(d[1][1]+d[2][1])/2;a.append("text").text(e).attr({x:g,y:h,"text-anchor":"middle","dominant-baseline":"middle",fill:f,"pointer-events":"none"}).style("font-size",this.label.fontSize)},c.prototype.__initialize=function(a,b){if(!this.__isArray(a)||0===a.length||!this.__isArray(a[0])||a[0].length<2)throw{name:"D3 Funnel Data Error",message:"Funnel data is not valid."};b="undefined"!=typeof b?b:{},this.data=a;var c=0,d=this.__extend({},this.defaults);d.width=parseInt(d3.select(this.selector).style("width"),10),d.height=parseInt(d3.select(this.selector).style("height"),10);var e=Object.keys(b);for(c=0;c<e.length;c++)"label"!==e[c]&&(d[e[c]]=b[e[c]]);if("label"in b){var f,g=/fontSize|fill/;for(f in b.label)f.match(g)&&(d.label[f]=b.label[f])}this.label=d.label,d.width<=0&&(d.width=this.defaults.width),d.height<=0&&(d.height=this.defaults.height);var h=d3.scale.category10();for(c=0;c<this.data.length;c++){var i=/^#([0-9a-f]{3}|[0-9a-f]{6})$/i;"2"in this.data[c]&&i.test(this.data[c][2])||(this.data[c][2]=h(c))}this.width=d.width,this.height=d.height,this.bottomWidth=d.width*d.bottomWidth,this.bottomPinch=d.bottomPinch,this.isCurved=d.isCurved,this.curveHeight=d.curveHeight,this.fillType=d.fillType,this.isInverted=d.isInverted,this.hoverEffects=d.hoverEffects,this.dynamicArea=d.dynamicArea,this.animation=d.animation,this.bottomLeftX=(this.width-this.bottomWidth)/2,this.dx=this.bottomPinch>0?this.bottomLeftX/(a.length-this.bottomPinch):this.bottomLeftX/a.length,this.dy=this.isCurved?(this.height-this.curveHeight)/a.length:this.height/a.length},c.prototype.__makePaths=function(){var a=[],b=this.dx,c=this.dy,d=0,e=this.width,f=0;this.isInverted&&(d=this.bottomLeftX,e=this.width-this.bottomLeftX);var g=0,h=0,i=0,j=this.width/2;this.isCurved&&(f=10);for(var k=this.width,l=0,m=this.height*(this.width+this.bottomWidth)/2,n=2*this.height/(this.width-this.bottomWidth),o=0,p=0,q=0;q<this.data.length;q++)o+=this.data[q][1];for(q=0;q<this.data.length;q++){if(p=this.data[q][1],this.dynamicArea){var r=p/o,s=r*m;l=Math.sqrt((n*k*k-4*s)/n),b=k/2-l/2,c=2*s/(k+l),this.isCurved&&(c-=this.curveHeight/this.data.length),k=l}this.bottomPinch>0&&(this.isInverted?(this.dynamicArea||(b=this.dx),b=q<this.bottomPinch?0:b):q>=this.data.length-this.bottomPinch&&(b=0)),g=d+b,h=e-b,i=f+c,this.isInverted&&(g=d-b,h=e+b),a.push(this.isCurved?[[d,f,"M"],[j,f+(this.curveHeight-10),"Q"],[e,f,""],[h,i,"L"],[h,i,"M"],[j,i+this.curveHeight,"Q"],[g,i,""],[d,f,"L"]]:[[d,f,"M"],[e,f,"L"],[h,i,"L"],[g,i,"L"],[d,f,"L"]]),d=g,e=h,f=i}return a},c.prototype.__defineColorGradients=function(a){for(var c=a.append("defs"),d=0;d<this.data.length;d++)for(var e=this.data[d][2],f=b(e,-.25),g=c.append("linearGradient").attr({id:"gradient-"+d}),h=[[0,f],[40,e],[60,e],[100,f]],i=0;i<h.length;i++){var j=h[i];g.append("stop").attr({offset:j[0]+"%",style:"stop-color:"+j[1]})}},c.prototype.__drawTopOval=function(a,c){var d=0,e=this.width,f=this.width/2;this.isInverted&&(d=this.bottomLeftX,e=this.width-this.bottomLeftX);var g=c[0],h="M"+d+","+g[0][1]+" Q"+f+","+(g[1][1]+this.curveHeight-10)+" "+e+","+g[2][1]+" M"+e+",10 Q"+f+",0 "+d+",10";a.append("path").attr("fill",b(this.data[0][2],-.4)).attr("d",h)},c.prototype.__onMouseOver=function(a){d3.select(this).attr("fill",b(a.baseColor,-.2))},c.prototype.__onMouseOut=function(a){d3.select(this).attr("fill",a.fill)},a.D3Funnel=c}(window);
{
"name": "d3-funnel",
"version": "0.6.3",
"version": "0.6.4",
"description": "A library for rendering SVG funnel charts using D3.js",

@@ -5,0 +5,0 @@ "author": "Jake Zatecky",

@@ -62,4 +62,6 @@ # D3 Funnel

// the count values rather than equal heights
animation: false, // The load animation speed in millseconds
label: {
fontSize: "14px" // Any valid font size
fontSize: "14px", // Any valid font size,
fill: "#000" // Hex color to change default #fff label color
}

@@ -81,2 +83,13 @@ };

Further more, you can even set colors for any data point label (hex only):
``` javascript
var data = [
["Teal", 12000, "#008080" "#080800"],
["Byzantium", 4000, "#702963"], // Defaults to options.label.fill label color
["Persimmon", 2500, "#ff634d" "#6f34fd"],
["Azure", 1500, "#007fff" "#07fff0"]
];
```
# License

@@ -87,2 +100,2 @@

[d3]: http://d3js.org/
[examples]: https://cdn.rawgit.com/jakezatecky/d3-funnel/master/examples/index.html
[examples]: http://jakezatecky.github.io/d3-funnel/

@@ -14,3 +14,4 @@ (function(global) {

*/
function D3Funnel(selector) {
var D3Funnel = function(selector)
{
this.selector = selector;

@@ -30,7 +31,9 @@

dynamicArea: false,
animation: false,
label: {
fontSize: "14px"
fontSize: "14px",
fill: "#fff"
}
};
}
};

@@ -44,3 +47,4 @@ /**

*/
D3Funnel.prototype._isArray = function(value) {
D3Funnel.prototype.__isArray = function(value)
{
return Object.prototype.toString.call(value) === "[object Array]";

@@ -57,3 +61,4 @@ };

*/
D3Funnel.prototype._extend = function(a, b) {
D3Funnel.prototype.__extend = function(a, b)
{
var prop;

@@ -98,8 +103,11 @@ for (prop in b) {

* data counts.
* @param {int} options.animation The load animation speed. If empty,
* there will be no load animation.
* @param {Object} options.label
* @param {Object} options.label.fontSize
*/
D3Funnel.prototype.draw = function(data, options) {
D3Funnel.prototype.draw = function(data, options)
{
// Initialize chart options
this._initialize(data, options);
this.__initialize(data, options);

@@ -110,3 +118,3 @@ // Remove any previous drawings

// Add the SVG and group element
var svg = d3.select(this.selector)
this.svg = d3.select(this.selector)
.append("svg")

@@ -116,10 +124,8 @@ .attr("width", this.width)

.append("g");
var group = {};
var path = {};
var sectionPaths = this._makePaths();
this.sectionPaths = this.__makePaths();
// Define color gradients
if (this.fillType === "gradient") {
this._defineColorGradients(svg);
this.__defineColorGradients(this.svg);
}

@@ -129,64 +135,67 @@

if (this.isCurved) {
this._drawTopOval(svg, sectionPaths);
this.__drawTopOval(this.svg, this.sectionPaths);
}
// Add each block section
for (var i = 0; i < sectionPaths.length; i++) {
// Set the background color
var fill = this.fillType !== "gradient" ?
this.data[i][2] :
"url(#gradient-" + i + ")";
this.__drawSection(0);
};
// Prepare data to assign to the section
data = {
index: i,
label: this.data[i][0],
value: this.data[i][1],
baseColor: this.data[i][2],
fill: fill
};
/**
* Draw the next section in the iteration.
*
* @param {int} index
*/
D3Funnel.prototype.__drawSection = function(index)
{
if (index === this.data.length) {
return;
}
// Construct path string
var paths = sectionPaths[i];
var pathStr = "";
// Create a group just for this block
var group = this.svg.append("g");
// Iterate through each point
for (var j = 0; j < paths.length; j++) {
path = paths[j];
pathStr += path[2] + path[0] + "," + path[1] + " ";
}
// Fetch path element
var path = this.__getSectionPath(group, index);
path.data(this.__getSectionData(index));
// Create a group just for this block
group = svg.append("g");
// Add animation components
if (this.animation !== false) {
var self = this;
path.transition()
.duration(this.animation)
.ease("linear")
.attr("fill", this.__getColor(index))
.attr("d", this.__getPathDefinition(index))
.each("end", function() {
self.__drawSection(index + 1);
});
} else {
path.attr("fill", this.__getColor(index))
.attr("d", this.__getPathDefinition(index));
this.__drawSection(index + 1);
}
// Draw the sections's path and append the data
path = group.append("path")
.attr("fill", fill)
.attr("d", pathStr)
.data([data]);
console.log(":(");
// Add the hover events
if (this.hoverEffects) {
path.on("mouseover", this._onMouseOver)
.on("mouseout", this._onMouseOut);
}
// Add the section label
var textStr = this.data[i][0] + ": " + this.data[i][1].toLocaleString();
var textX = this.width / 2; // Center the text
var textY = !this.isCurved ? // Average height of bases
(paths[1][1] + paths[2][1]) / 2 :
(paths[2][1] + paths[3][1]) / 2 + (this.curveHeight / this.data.length);
// Add the hover events
if (this.hoverEffects) {
path.on("mouseover", this.__onMouseOver)
.on("mouseout", this.__onMouseOut);
}
group.append("text")
.text(textStr)
.attr({
"x": textX,
"y": textY,
"text-anchor": "middle",
"dominant-baseline": "middle",
"fill": "#fff",
"pointer-events": "none"
})
.style("font-size", this.label.fontSize);
this.__addSectionLabel(group, index);
};
/**
* Return the color for the given index.
*
* @param {int} index
*/
D3Funnel.prototype.__getColor = function(index)
{
if (this.fillType === "solid") {
return this.data[index][2];
} else {
return "url(#gradient-" + index + ")";
}

@@ -196,2 +205,125 @@ };

/**
* @param {Object} group
* @param {int} index
*
* @return {Object}
*/
D3Funnel.prototype.__getSectionPath = function(group, index)
{
var path = group.append("path");
if (this.animation !== false) {
this.__addBeforeTransition(path, index);
}
return path;
};
/**
* Set the attributes of a path element before its animation.
*
* @param {Object} path
* @param {int} index
*/
D3Funnel.prototype.__addBeforeTransition = function(path, index)
{
var paths = this.sectionPaths[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 = "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 = "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") {
beforeFill = index > 0 ? this.__getColor(index - 1) : this.__getColor(index);
// Use current background if gradient (gradients do not transition)
} else {
beforeFill = this.__getColor(index);
}
path.attr("d", beforePath)
.attr("fill", beforeFill);
};
/**
* @param {int} index
*
* @return {array}
*/
D3Funnel.prototype.__getSectionData = function(index)
{
return [{
index: index,
label: this.data[index][0],
value: this.data[index][1],
baseColor: this.data[index][2],
fill: this.__getColor(index)
}];
};
/**
* @param {int} index
*
* @return {string}
*/
D3Funnel.prototype.__getPathDefinition = function(index)
{
var pathStr = "";
var point = [];
var paths = this.sectionPaths[index];
for (var j = 0; j < paths.length; j++) {
point = paths[j];
pathStr += point[2] + point[0] + "," + point[1] + " ";
}
return pathStr;
};
/**
* @param {Object} group
* @param {int} index
*/
D3Funnel.prototype.__addSectionLabel = function(group, index)
{
var i = index;
var paths = this.sectionPaths[index];
var textStr = this.data[i][0] + ": " + this.data[i][1].toLocaleString();
var textFill = this.data[i][3] || this.label.fill;
var textX = this.width / 2; // Center the text
var textY = !this.isCurved ? // Average height of bases
(paths[1][1] + paths[2][1]) / 2 :
(paths[2][1] + paths[3][1]) / 2 + (this.curveHeight / this.data.length);
group.append("text")
.text(textStr)
.attr({
"x": textX,
"y": textY,
"text-anchor": "middle",
"dominant-baseline": "middle",
"fill": textFill,
"pointer-events": "none"
})
.style("font-size", this.label.fontSize);
};
/**
* Initialize and calculate important variables for drawing the chart.

@@ -202,5 +334,6 @@ *

*/
D3Funnel.prototype._initialize = function(data, options) {
if (!this._isArray(data) || data.length === 0 ||
!this._isArray(data[0]) || data[0].length < 2) {
D3Funnel.prototype.__initialize = function(data, options)
{
if (!this.__isArray(data) || data.length === 0 ||
!this.__isArray(data[0]) || data[0].length < 2) {
throw {

@@ -222,3 +355,3 @@ name: "D3 Funnel Data Error",

// Set the default width and height based on the container
var settings = this._extend({}, this.defaults);
var settings = this.__extend({}, this.defaults);
settings.width = parseInt(d3.select(this.selector).style("width"), 10);

@@ -237,4 +370,8 @@ settings.height = parseInt(d3.select(this.selector).style("height"), 10);

if ("label" in options) {
if ("fontSize" in options.label) {
settings.label.fontSize = options.label.fontSize;
var validLabelOptions = /fontSize|fill/;
var labelOption;
for (labelOption in options.label) {
if (labelOption.match(validLabelOptions)) {
settings.label[labelOption] = options.label[labelOption];
}
}

@@ -259,4 +396,3 @@ }

// If a color is not set for the record, add one
if (typeof this.data[i][2] === "undefined" ||
!hexExpression.test(this.data[i][2])) {
if (!("2" in this.data[i]) || !hexExpression.test(this.data[i][2])) {
this.data[i][2] = colorScale(i);

@@ -277,2 +413,3 @@ }

this.dynamicArea = settings.dynamicArea;
this.animation = settings.animation;

@@ -300,3 +437,4 @@ // Calculate the bottom left x position

*/
D3Funnel.prototype._makePaths = function() {
D3Funnel.prototype.__makePaths = function()
{
var paths = [];

@@ -448,3 +586,4 @@

*/
D3Funnel.prototype._defineColorGradients = function(svg) {
D3Funnel.prototype.__defineColorGradients = function(svg)
{
var defs = svg.append("defs");

@@ -488,3 +627,4 @@

*/
D3Funnel.prototype._drawTopOval = function(svg, sectionPaths) {
D3Funnel.prototype.__drawTopOval = function(svg, sectionPaths)
{
var leftX = 0;

@@ -517,3 +657,4 @@ var rightX = this.width;

*/
D3Funnel.prototype._onMouseOver = function(data) {
D3Funnel.prototype.__onMouseOver = function(data)
{
d3.select(this).attr("fill", shadeColor(data.baseColor, -0.2));

@@ -525,3 +666,4 @@ };

*/
D3Funnel.prototype._onMouseOut = function(data) {
D3Funnel.prototype.__onMouseOut = function(data)
{
d3.select(this).attr("fill", data.fill);

@@ -536,3 +678,4 @@ };

*/
function shadeColor(color, shade) {
function shadeColor(color, shade)
{
var f = parseInt(color.slice(1), 16);

@@ -553,2 +696,2 @@ var t = shade < 0 ? 0 : 255;

})(this);
})(window);

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

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

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc