246 lines
7.8 KiB
JavaScript
246 lines
7.8 KiB
JavaScript
var fs = require('fs');
|
|
var d3 = require('./d3');
|
|
var D3Node = require('./d3-node');
|
|
function log(msg) {
|
|
console.log('[PLOT] '+msg);
|
|
}
|
|
|
|
|
|
/**
|
|
* generic options = {margin, padding}
|
|
*/
|
|
|
|
var Plot = function(options) {
|
|
var self=this;
|
|
// auto-new instance, so we always have 'this'
|
|
if (!(this instanceof Plot)) {
|
|
return new Plot(options)
|
|
}
|
|
|
|
this.options=options;
|
|
if (this.options.margin==undefined) this,options.margin=0;
|
|
if (this.options.padding==undefined) this,options.padding=0;
|
|
|
|
switch (options.type) {
|
|
case 'matrix':
|
|
if (!this.options.fontsize) this.options.fontsize=12;
|
|
case 'circle':
|
|
/* Circle 2D Scatter Plot
|
|
** Text 2D Matrix Plot
|
|
**
|
|
** type options = {
|
|
** x:number of circles/entries,y:number of circles/entries,
|
|
** size:number of circle/element size,
|
|
** color:string of circle fill color/text color,
|
|
** min:number of smallest data value, max: number of biggest data value
|
|
** grid:boolean for grid drawing,
|
|
** map: function (d,i,j) is a data set mapping functions
|
|
**
|
|
**/
|
|
if (!this.options.color) this.options.color='green';
|
|
this.d3n = new D3Node({d3Module:d3});
|
|
this.width = 2*this.options.margin+
|
|
2*this.options.padding+
|
|
this.options.size*(this.options.x+2);
|
|
this.height = 2*this.options.margin+
|
|
2*this.options.padding+
|
|
this.options.size*(this.options.y+2);
|
|
log('Size of diagram: width='+this.width+', height='+this.height+' px');
|
|
this.svg = this.d3n.createSVG()
|
|
.attr("width", this.width)
|
|
.attr("height", this.height);
|
|
break;
|
|
default:
|
|
throw Error ('[PLOT] Unknown plot diagram tyoe '+options.type);
|
|
}
|
|
}
|
|
|
|
Plot.prototype.plot = function (dataset) {
|
|
var self=this,
|
|
i,j,g,d;
|
|
|
|
if (!this.options.min) this.options.min=0;
|
|
if (!this.options.max) {
|
|
this.options.max=0;
|
|
for (j=0; j < dataset.length; j++)
|
|
for(i=0; i < dataset[j].length; i++) {
|
|
d=dataset[j][i];
|
|
if (this.options.map) d=this.options.map(d,i,j);
|
|
if (d> this.options.max) this.options.max= d;
|
|
}
|
|
}
|
|
|
|
log('Data set has min='+this.options.min+', max='+this.options.max);
|
|
switch (this.options.type) {
|
|
case 'circle':
|
|
d3.select(this.d3n.document.body)
|
|
|
|
if (this.options.grid) {
|
|
g=this.svg.append("g")
|
|
.selectAll("g")
|
|
.data(dataset)
|
|
.enter()
|
|
.append("g") //removing
|
|
.selectAll("text") // these
|
|
.data( function(d,i,j) { return d; } ) //lines
|
|
.enter()
|
|
g.append('rect')
|
|
.attr("x", function(d,i,j) {
|
|
return self.options.padding+
|
|
self.options.margin+
|
|
(i * self.options.size) + self.options.size/2;
|
|
})
|
|
.attr("y", function(d,i,j) {
|
|
return self.options.padding+
|
|
self.options.margin+
|
|
(j * self.options.size) + self.options.size/2;
|
|
})
|
|
.attr("width", function(d,i,j) {
|
|
return self.options.size
|
|
})
|
|
.attr("height", function(d,i,j) {
|
|
return self.options.size
|
|
})
|
|
.attr("stroke", function(d,i,j) {
|
|
return '#AAAAAA'
|
|
})
|
|
.attr("fill", function(d,i,j) {
|
|
return 'white'
|
|
});
|
|
}
|
|
|
|
g=this.svg.append("g")
|
|
.selectAll("g")
|
|
.data(dataset)
|
|
.enter()
|
|
.append("g") //removing
|
|
.selectAll("text") // these
|
|
.data( function(d,i,j) { return d; } ) //lines
|
|
.enter() // circle displays normally
|
|
g=g.append("circle")
|
|
.attr("cx", function(d,i,j) {
|
|
return self.options.padding+
|
|
self.options.margin+
|
|
(i * self.options.size) + self.options.size;
|
|
})
|
|
.attr("cy", function(d,i,j) {
|
|
return self.options.padding+
|
|
self.options.margin+(j * self.options.size) + self.options.size;
|
|
})
|
|
.attr("r", function(d,i,j) {
|
|
if (self.options.map) d=self.options.map(d,i,j);
|
|
return (
|
|
self.options.size/2*(
|
|
(d-self.options.min)/
|
|
(self.options.max-self.options.min))
|
|
);
|
|
})
|
|
.attr("fill", function(d,i,j) {
|
|
return self.options.color
|
|
});
|
|
|
|
break;
|
|
|
|
case 'matrix':
|
|
d3.select(this.d3n.document.body)
|
|
if (this.options.grid) {
|
|
g=this.svg.append("g")
|
|
.selectAll("g")
|
|
.data(dataset)
|
|
.enter()
|
|
.append("g") //removing
|
|
.selectAll("text") // these
|
|
.data( function(d,i,j) { return d; } ) //lines
|
|
.enter();
|
|
g.append('rect')
|
|
.attr("x", function(d,i,j) {
|
|
return self.options.padding+
|
|
self.options.margin+
|
|
(i * self.options.size) + self.options.size/2;
|
|
})
|
|
.attr("y", function(d,i,j) {
|
|
return self.options.padding+
|
|
self.options.margin+
|
|
(j * self.options.size) + self.options.size/2;
|
|
})
|
|
.attr("width", function(d,i,j) {
|
|
return self.options.size
|
|
})
|
|
.attr("height", function(d,i,j) {
|
|
return self.options.size
|
|
})
|
|
.attr("stroke", function(d,i,j) {
|
|
return '#AAAAAA'
|
|
})
|
|
.attr("fill", function(d,i,j) {
|
|
return 'white'
|
|
});
|
|
}
|
|
|
|
|
|
for(var index=0;index<(self.options.cell?self.options.cell.rows:1);index++) {
|
|
g=this.svg.append("g")
|
|
.selectAll("g")
|
|
.data(dataset)
|
|
.enter()
|
|
.append("g") //removing
|
|
.selectAll("text") // these
|
|
.data( function(d,i,j) { return d; } ) //lines
|
|
.enter(); // circle displays normal
|
|
|
|
g=g.append("text")
|
|
.attr("x", function(d,i,j) {
|
|
if (self.options.map) d=self.options.map(d,i,j);
|
|
if (self.options.cell && self.options.cell.rows) d=d[index];
|
|
return (self.options.padding+
|
|
self.options.margin-
|
|
(d.length*self.options.fontsize/3)+
|
|
(i * self.options.size) + self.options.size);
|
|
})
|
|
.attr("y", function(d,i,j) {
|
|
var off;
|
|
if (self.options.cell && self.options.cell.rows) {
|
|
switch (index) {
|
|
case 0: off=-self.options.fontsize; break;
|
|
case 1: off=self.options.fontsize; break;
|
|
default: off=0;
|
|
}
|
|
} else
|
|
off=self.options.fontsize/3;
|
|
|
|
return (self.options.padding+
|
|
off+
|
|
self.options.margin+(j * self.options.size) + self.options.size);
|
|
})
|
|
.attr("font-size", self.options.fontsize+'px')
|
|
.attr("color", function(d,i,j) {
|
|
return self.options.color
|
|
})
|
|
.attr("fill", function(d,i,j) {
|
|
return self.options.color
|
|
})
|
|
.text(function (d,i,j) {
|
|
var lines='';
|
|
if (self.options.map) d=self.options.map(d,i,j);
|
|
if (self.options.cell && self.options.cell.rows) d=d[index];
|
|
return d
|
|
});
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
Plot.prototype.output = function (outputName) {
|
|
fs.writeFile(outputName+'.html', this.d3n.html(), function () {
|
|
log(outputName+'.html created.');
|
|
});
|
|
var svgBuffer = new Buffer(this.d3n.svgString(), 'utf-8');
|
|
fs.writeFile(outputName+'.svg', svgBuffer, function () {
|
|
log(outputName+'.svg created');
|
|
})
|
|
};
|
|
|
|
module.exports = {
|
|
Plot:Plot
|
|
}
|