Skip to content

Instantly share code, notes, and snippets.

@blakedietz
Created August 10, 2013 21:33
Show Gist options
  • Save blakedietz/6202230 to your computer and use it in GitHub Desktop.
Save blakedietz/6202230 to your computer and use it in GitHub Desktop.
Reusable and Configurable Pyramid Charts
var data = [
{
"state":"Alaska",
"percentage": -3.2
},
{
"state":"Alabama",
"percentage": -39.8
},
{
"state":"Arizona",
"percentage": -50.4
},
{
"state":"Arkansas",
"percentage":-18.9
},
{
"state":"California",
"percentage":-29.3
},
{
"state":"Colorado",
"percentage":-32.3
},
{
"state":"Connecticut",
"percentage":-23.1
},
{
"state":"Delaware",
"percentage":-25
},
{
"state":"Florida",
"percentage": -41.2
},
{
"state":"Georgia",
"percentage":-29.5
},
{
"state":"Hawaii",
"percentage":-25.3
},
{
"state":"Idaho",
"percentage": -39.6
},
{
"state":"Illinois",
"percentage":-23.3
},
{
"state":"Indiana",
"percentage":-17.2
},
{
"state":"Iowa",
"percentage":-27.7
},
{
"state":"Kansas",
"percentage":-24.5
},
{
"state":"Kentucky",
"percentage":-26.3
},
{
"state":"Louisiana",
"percentage": -42
},
{
"state":"Maine",
"percentage":-15.7
},
{
"state":"Maryland",
"percentage":-18.3
},
{
"state":"Massachusetts",
"percentage": -37.4
},
{
"state":"Michigan",
"percentage": -32.4
},
{
"state":"Minnesota",
"percentage":-30.4
},
{
"state":"Mississippi",
"percentage":-32.4
},
{
"state":"Missouri",
"percentage":-29.7
},
{
"state":"Montana",
"percentage":-16.6
},
{
"state":"Nebraska",
"percentage":-16.6
},
{
"state":"Nevada",
"percentage":-31.2
},
{
"state":"New Hampshire",
"percentage": -49.9
},
{
"state":"New Jersey",
"percentage": -27.2
},
{
"state":"New Mexico",
"percentage": -36.7
},
{
"state":"New York",
"percentage": -14.7
},
{
"state":"North Carolina",
"percentage": -14.6
},
{
"state":"North Dakota",
"percentage": 16.5
},
{
"state":"Ohio",
"percentage":-28.9
},
{
"state":"Oklahoma",
"percentage": -26.2
},
{
"state":"Oregon ",
"percentage": -43.6
},
{
"state":"Pennsylvania",
"percentage":-29.9
},
{
"state":"Rhode Island",
"percentage":-24.8
},
{
"state":"South Carolina",
"percentage": -38.8
},
{
"state":"South Dakota",
"percentage": -22.1
},
{
"state":"Tennessee",
"percentage":-30.1
},
{
"state":"Texas",
"percentage":-22.7
},
{
"state":"Utah",
"percentage":-30.6
},
{
"state":"Vermont",
"percentage":-18.6
},
{
"state":"Virginia",
"percentage":-27.8
},
{
"state":"Washington",
"percentage": -37.5
},
{
"state":"West Virginia",
"percentage": -17.8
},
{
"state":"Wisconsin",
"percentage":-17.5
},
{
"state":"Wyoming",
"percentage":7
},
];
<!DOCTYPE HTML>
<html>
<head>
<title></title>
<meta charset="utf-8">
<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
<style>
path.domain
{
display:none;
}
</style>
</head>
<body>
<div></div>
<script type="text/javascript" src="data.js"></script>
<script src="pyramidChart.js"></script>
<script type="text/javascript" src="render.js"></script>
</body>
</html>
function PyramidChart()
{
var margin = {top: 0, right: 50, bottom: 20, left: 50};
var width = 650 - margin.right - margin.left;
var height = 650 - margin.top - margin.bottom;
var selector = "body";
var xScaleLeft,
xScaleRight,
yScale;
var highestMagnitude;
var yAxis;
var svg,
gy;
var data;
var leftBarColor = "#c33";
var rightBarColor = "#16a";
function chart()
{
}
// Accessor Methods
chart.margin = function(obj)
{
if(!arguments.length)
{
return margin;
}
else
{
margin = obj;
}
};
chart.width = function(w)
{
if(!arguments.length)
{
return width;
}
else
{
width = w - margin.right - margin.left;
}
};
chart.height = function(h)
{
if(!arguments.length)
{
return height;
}
else
{
height = h - margin.top - margin.bottom;
}
};
chart.data = function(d)
{
if(!arguments.length)
{
return data;
}
else
{
data = d;
highestMagnitude = d3.max(data.map(function(d)
{
return Math.abs(d.percentage);
}));
chart.sort();
}
};
chart.barColor = function(obj)
{
if(!arguments.length)
{
return {
"left": leftBarColor,
"right": rightBarColor
};
}
else
{
leftBarColor = obj.left;
rightBarColor = obj.right;
}
};
// Helper Methods
chart.sort = function()
{
data.sort(function(a,b)
{
return a.percentage < b.percentage ? -1 : a.percentage > b.percentage ? 1: 0;
});
};
chart.createCanvas = function()
{
svg = d3.select(selector)
.append("svg")
.attr("height",height + margin.top + margin.bottom)
.attr("width",width + margin.left + margin.right)
.append("g")
.attr("transform","translate(" + margin.left + "," + margin.top + ")");
};
chart.createScales = function()
{
xScaleLeft = d3.scale.linear()
.domain([-highestMagnitude,0])
.range([width/2,0]);
xScaleRight = d3.scale.linear()
.domain([0,highestMagnitude])
.range([0,width/2]);
yScale = d3.scale.ordinal()
.domain(data.map(function(d){return d.state;}))
.rangeRoundBands([margin.top,height - margin.bottom],.4);
};
chart.createAxes = function()
{
yAxis = d3.svg.axis().scale(yScale).orient("left");
};
chart.drawAxes = function()
{
gy = svg.append("g")
.attr("class", "y axis")
.attr("transform","translate(" + width/2 + ", 0)")
.call(yAxis)
.selectAll("text")
.style("text-anchor",function(d,i)
{
if(data[i].percentage < 0)
{
return "start";
}
else
{
return "end";
}
})
.attr("dx",function(d,i)
{
if(data[i].percentage < 0)
{
return 15;
}
else
{
return 3 ;
}
})
.attr("font-family","sans-serif")
.attr("font-size",yScale.rangeBand() + parseInt(.005 * width))
.attr("renderStyle","crisp-edges");
}
chart.drawBars = function()
{
svg.selectAll("rect").data(data).enter().append("rect")
.attr({
"x":function(d)
{
if(d.percentage < 0)
{
return width/2 - xScaleLeft(d.percentage);
}
else
{
return width/2;
}
},
"y":function(d)
{
return yScale(d.state);
},
"width":function(d)
{
if(d.percentage < 0)
{
return xScaleLeft(d.percentage);
}
else
{
return xScaleRight(d.percentage);
}
} ,
"height":yScale.rangeBand(),
"fill":function(d)
{
if(d.percentage < 0)
{
return leftBarColor;
}
else
{
return rightBarColor;
}
}
});
};
chart.moveLabels = function()
{
svg.selectAll("text.statePercentage")
.data(data)
.enter().append("text")
.attr("class","statePercentage")
.attr("transform","translate(" + width/2 + ",0)")
.text(function(d)
{
return d.percentage + "%";
})
.style("text-anchor",function(d,i)
{
if(data[i].percentage < 0)
{
return "end";
}
else
{
return "start";
}
})
.attr("x",function(d,i)
{
if(data[i].percentage < 0)
{
return -xScaleLeft(data[i].percentage);
}
else
{
return xScaleRight(data[i].percentage);
}
})
.attr("y",function(d,i)
{
return yScale(i) + yScale.rangeBand() / 2;
})
.attr("dx",function(d,i)
{
return data[i].percentage < 0 ? (-.01 * width) : (.01 * width);
})
.attr("dy",.005 * width)
.attr("font-family","sans-serif")
.attr("font-size",parseInt(yScale.rangeBand()) + .005 * width)
.attr("renderStyle","crisp-edges");
};
chart.styleAxes = function()
{
// Remove large bar in the middle
svg.selectAll(".domain").attr("fill","none");
};
chart.draw = function()
{
chart.createCanvas();
chart.createScales();
chart.createAxes();
chart.drawAxes();
chart.drawBars();
chart.styleAxes();
chart.moveLabels();
};
return chart;
}
var pyChart0 = PyramidChart();
pyChart0.data(data);
pyChart0.barColor({"left":"green","right":"purple"});
pyChart0.draw();
var pyChart1 = PyramidChart();
pyChart1.data(data);
pyChart1.barColor({"left":"pink","right":"black"});
pyChart1.height(400);
pyChart1.width(400);
pyChart1.draw();
var pyChart2 = PyramidChart();
pyChart2.data(data);
pyChart2.height(200);
pyChart2.width(200);
pyChart2.draw();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment