Skip to content

Instantly share code, notes, and snippets.

@eesur
Last active August 29, 2015 14:10
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eesur/c6a7de5530c624567250 to your computer and use it in GitHub Desktop.
Save eesur/c6a7de5530c624567250 to your computer and use it in GitHub Desktop.
d3 | d3xter
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>D3xter test</title>
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.4.2/d3.js"></script>
<script src="lib.js" charset="utf-8"></script>
<style>
body {font-family: monospace; line-height: 160%; font-size: 18px; }
svg path, svg line {
fill: none;
stroke: black;
}
svg text {
font-size: 11px;
}
</style>
</head>
<body>
<div id='elementID'></div>
<script type="text/javascript">
var x = [-0.8234, 0.0952, 1.9594, -0.2831, -0.4147, 1.5859, 0.5326, 0.0925, 0.3293, 1.3635, 0.3396, 0.0677, -0.6739, 0.4084, -1.4487, -0.1101, -0.7521, -1.2118, 1.7191, 0.2020, -0.1573, -0.2298, -0.8230, 1.7924, 0.4511];
var y = [-1.4166, 1.353, -0.6294, 0.0567, 1.4157, 0.32806, 0.2377, -0.2262, -1.0602, -1.8150, 0.1075, -1.3516, 1.0137, 0.0183, -0.5466, 0.6416, -0.6655, 0.6874, -0.4616, -0.2808, 1.3443, -1.0518, -0.1332, -1.0097, 0.3643];
var z = [1.1011, 0.8724, -1.5972, -0.2027, -1.2296, -0.0543, 0.2415, 0.3584, 1.0202, -1.7524, -0.6787, 0.8113, 0.0206, -1.9769, 1.2008, 1.0440, 1.0141, -0.6452, -0.6115, 0.6687, 2.9415, -1.1146, -1.2889, -0.2562, -1.1781];
var config = {
xLab: 'random x-values', //x-axis label (defaults to '')
yLab: 'random y-values', //y-axis label (defaults to '')
selector: '#elementID', //Selector for DOM element to append the plot to (defaults to < body >)
width: 900, //pixel width (defaults to 500)
height: 500, //pixel height (defaults to 500)
//size and sizeLab are used in bubble charts like the top-right example.
size: z, //array of numeric values which map to sizes of the circles plotted at the corresponding x-y point (defaults to undefined for a standard scatter)
sizeLab: 'random size values' //label for size values (defaults to '')
}
var scatter = scatter(x,y,config);
//modify the color of the circles with D3 syntax
scatter.selectAll('circle').style('fill','#EE3124');
</script>
</body>
</html>
</html>
// START FUNCTION: This function creates the canvas, the everything bundle within the canvas, the axes (given scale functions), and the axes labels
start = function(xLab,yLab,xMap,yMap,canvasWidth,canvasHeight,width,height,selector){
var canvas = d3.select(selector)
.append('svg')
.attr('height',canvasHeight)
.attr('width', canvasWidth);
var everything = canvas.append('g');
everything.attr('transform','translate('+(width * 0.2)+','+height*0.1+')');
var xAxis = d3.svg.axis()
.scale(xMap);
var yAxis = d3.svg.axis()
.scale(yMap)
.orient('left');
everything.append('g')
.attr('transform','translate(0,'+height+')')
.call(xAxis);
everything.append('g')
.call(yAxis);
var xLabel = everything.append('text')
.attr('x',canvasWidth*0.4)
.attr('y',height+45)
.text(xLab)
.attr('text-anchor','middle');
var yLabel = everything.append('text')
.attr('x', -canvasHeight*0.4)
.attr('y', -canvasWidth*0.1)
.attr('transform','rotate(-90)')
.text(yLab)
.attr('text-anchor','middle');
var objects = [canvas,everything];
return objects;
}
// END OF START FUNCTION
// HISTO FUNCTION: creats histogram plot
histo = function(data,config){
if (typeof config === 'undefined'){config = {}};
var xLab=config.xLab,selector=config.selector,canvasWidth=config.width,canvasHeight=config.height;
if(typeof canvasWidth === 'undefined'){
canvasWidth = 500;
}
if(typeof canvasHeight === 'undefined'){
canvasHeight = 500;
}
if(typeof selector === 'undefined'){
selector = 'body';
}
if(typeof xLab === 'undefined'){
xLab = '';
}
var hist = function(arr){
var newArr = arr.slice().sort(function(a,b){
return a-b;
});
var max = newArr[arr.length -1];
var min = newArr[0];
var bins = Math.round(Math.sqrt(arr.length));
var binSize = (max-min)/bins;
var obj= {};
var keys = [];
for (var i=0; i<bins; i++){
var key = min + (i*binSize);
keys.push(key);
obj[key] = 0;
}
for (var j=0; j<arr.length; j++){
var val = min;
var temp_key = 0;
while(true){
if (newArr[j] == newArr[newArr.length-1]){
obj[keys[keys.length-1]] += 1;
break;
}
else if (newArr[j]<val+binSize){
obj[keys[temp_key]]+= 1;
break;
}
else{
temp_key += 1;
val += binSize;
}
}
}
return [obj,min,max,binSize];
};
var height = canvasHeight/1.3;
var width = canvasWidth/1.3;
if (canvasHeight - height < 75){height -= 45};
var allData = hist(data);
var xMap = d3.scale.linear()
.domain([allData[1],allData[2]])
.range([0,width]);
var maxfreq = Math.max.apply( null,Object.keys(allData[0]).map(function ( key ) { return allData[0][key]; }) );
var yMap = d3.scale.linear()
.domain([maxfreq,0])
.range([0,height]);
var objects = start(xLab,'Frequency',xMap,yMap,canvasWidth,canvasHeight,width,height,selector);
var canvas = objects[0];
var everything = objects[1];
//MAKE AN ARRAY OF THE DATA TO BIND
var obj = allData[0];
var keys = Object.keys(obj);
var arr = [];
for (var i=0;i<keys.length;i++){
arr.push(obj[keys[i]]);
}
// obj,min,max,binSize
var binSize = xMap(allData[3] + allData[1]);
var padding = binSize * 0.075;
//padding used to create a buffer around each bin
everything.selectAll('rect')
.data(arr)
.enter()
.append('rect')
.attr('x', function(d,index){
return (index*binSize + padding/2);
})
.attr('y', function(d){
return yMap(d);
})
.attr('height', function(d){
return Math.max(yMap(maxfreq - d) - 0.5, 0);
})
.attr('width', binSize-padding)
.style('fill', 'steelBlue');
return canvas;
};
// END OF HIST FUNCTION
// BEGINNING OF XY PLOT FUNCTION
xyPlot = function(x,y,config){
if (typeof config === 'undefined'){config = {}};
var xLab=config.xLab,yLab=config.yLab,selector=config.selector,canvasWidth=config.width,canvasHeight=config.height;
if(typeof canvasWidth === 'undefined'){
canvasWidth = 500;
}
if(typeof canvasHeight === 'undefined'){
canvasHeight = 500;
}
if(typeof selector === 'undefined'){
selector = 'body';
}
var xSort = x.slice().sort(function(a,b){
return a-b;
});
var ySort = y.slice().sort(function(a,b){
return a-b;
});
var yMax = ySort[ySort.length-1];
var yMin = ySort[0];
var height = canvasHeight/1.3;
var width = canvasWidth/1.3;
if (canvasHeight - height < 75){height -= 45};
if (typeof x[0] !== 'number'){
if (typeof Date.parse(x[0]) === 'number'){
// if we're here, x[0] is a date
var xMap = d3.time.scale()
.domain([new Date(x[0]),new Date(x[x.length-1])])
.range([0,width]);
x.forEach(function(element,index){
x[index] = new Date(x[index]);
});
}
}
else{
// boundaries for numeric x
var xMax = xSort[xSort.length-1];
var xMin = xSort[0];
var xMap = d3.scale.linear()
.domain([xMin,xMax])
.range([0,width]);
}
var yMap = d3.scale.linear()
.domain([yMax,yMin])
.range([0,height]);
var objects = start(xLab,yLab,xMap,yMap,canvasWidth,canvasHeight,width,height,selector);
var canvas = objects[0];
var everything = objects[1];
for (var i=1;i<x.length;i++){
everything.append('line')
.attr('stroke-width',1)
.attr('stroke','black')
.attr('x1',xMap(x[i-1]))
.attr('x2',xMap(x[i]))
.attr('y1',yMap(y[i-1]))
.attr('y2',yMap(y[i]));
}
return canvas;
};
// START OF SCATTER FUNCTION
scatter = function(x,y,config){
if (typeof config === 'undefined'){config = {}};
var xLab=config.xLab,yLab=config.yLab,selector=config.selector,canvasWidth=config.width,canvasHeight=config.height,z=config.size,zLab=config.sizeLab;
if(typeof canvasWidth === 'undefined'){
canvasWidth = 500;
}
if(typeof canvasHeight === 'undefined'){
canvasHeight = 500;
}
if(typeof selector === 'undefined'){
selector = 'body';
}
var xSort = x.slice().sort(function(a,b){
return a-b;
});
var ySort = y.slice().sort(function(a,b){
return a-b;
});
if (typeof z !== 'undefined'){
var zSort = z.slice().sort(function(a,b){
return a-b;
});
}
var yMax = ySort[ySort.length-1];
var yMin = ySort[0];
var height = canvasHeight/1.3;
var width = canvasWidth/1.3;
if (canvasHeight - height < 75){height -= 45};
if (typeof x[0] !== 'number'){
if (typeof Date.parse(x[0]) === 'number'){
// if we're here, x[0] is a date
var xMap = d3.time.scale()
.domain([new Date(x[0]),new Date(x[x.length-1])])
.range([0,width]);
x.forEach(function(element,index){
x[index] = new Date(x[index]);
});
}
}
else{
// boundaries for numeric x
var xMax = xSort[xSort.length-1];
var xMin = xSort[0];
var xMap = d3.scale.linear()
.domain([xMin,xMax])
.range([0,width]);
}
var yMap = d3.scale.linear()
.domain([yMax,yMin])
.range([0,height]);
if (typeof zLab !== 'undefined'){yLab = yLab+' ('+zLab+')'};
var objects = start(xLab,yLab,xMap,yMap,canvasWidth,canvasHeight,width,height,selector);
var canvas = objects[0];
var everything = objects[1];
x.forEach(function(elem,index){
everything.append('circle')
.attr('r',function(){
if (typeof z === 'undefined'){
return height*width*(0.00002);
}
else{
return (height*width*0.000025 + (z[index]-zSort[0])*(height*width*(0.0001))/(zSort[zSort.length-1] - zSort[0]));
}
})
.attr('cx',xMap(x[index]))
.attr('cy',yMap(y[index]))
.attr('opacity',function(){
if (typeof z === 'undefined'){
return 1;
}
else{
return 0.3;
}
})
.attr('fill',function(){
if (typeof z === 'undefined'){
return 'none';
}
else{
return 'steelBlue';
}
})
.attr('stroke', function(){
if (typeof z === 'undefined'){return'black'};
return 'none'
});
});
return canvas;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment