Skip to content

Commit

Permalink
Get started on a functional style rewrite
Browse files Browse the repository at this point in the history
  • Loading branch information
qrohlf committed Feb 11, 2015
1 parent b5778df commit bba9784
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 116 deletions.
1 change: 1 addition & 0 deletions dist/trianglify.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 4 additions & 6 deletions lib/pattern.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
// rendering methods here!
var Pattern = function(data, opts) {
function Pattern(data, opts) {
return {
data: data,
opts: opts,
svg: function() {

},

canvas: function() {

},

get_opts: function() {
return opts.slice(0);
}
};
};
}

module.exports = Pattern;
118 changes: 60 additions & 58 deletions lib/trianglify.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ var svg = Trianglify(100, 100, options).svg()
// Trianglify. Made by (and copyright) @qrohlf, licensed under the GPLv3.
var colorbrewer = require('./colorbrewer');
var Delaunay = require('delaunay-fast');
var Pattern = require('./pattern');

var defaults = {
cell_size: 50,
Expand Down Expand Up @@ -61,73 +62,74 @@ function Trianglify(width, height, opts) {
triangles.push([color, vertices]);
}
return Pattern(triangles, opts);
}


/*********************************************************
*
* Private functions
*
**********************************************************/

// generate points on a randomized grid
function _generate_points(width, height) {
// figure out how many cells we're going to have on each axis
var cells_x = Math.floor((width + 2 * opts.cell_size) / opts.cell_size);
var cells_y = Math.floor((height + 2 * opts.cell_size) / opts.cell_size);
// figure out the bleed widths to center our grid
var bleed_x = ((cells_x * opts.cell_size) - width)/2;
var bleed_y = ((cells_y * opts.cell_size) - height)/2;
// how much can out points wiggle (+/-) given the cell padding?
var variance = opts.cell_size - opts.cell_padding * 2;

var points = [];
for (var i = - bleed_x; i <= width + bleed_x; i += opts.cell_size) {
for (var j = - bleed_y; j <= height + bleed_y; j += opts.cell_size) {
var x = Math.floor(i + Math.random() * 2 * variance - variance);
var y = Math.floor(j + Math.random() * 2 * variance - variance);
points.push([x, y]);
/*********************************************************
*
* Private functions
*
**********************************************************/

// generate points on a randomized grid
function _generate_points(width, height) {
// figure out how many cells we're going to have on each axis
var cells_x = Math.floor((width + 2 * opts.cell_size) / opts.cell_size);
var cells_y = Math.floor((height + 2 * opts.cell_size) / opts.cell_size);
// figure out the bleed widths to center our grid
var bleed_x = ((cells_x * opts.cell_size) - width)/2;
var bleed_y = ((cells_y * opts.cell_size) - height)/2;
// how much can out points wiggle (+/-) given the cell padding?
var variance = opts.cell_size - opts.cell_padding * 2;

var points = [];
for (var i = - bleed_x; i <= width + bleed_x; i += opts.cell_size) {
for (var j = - bleed_y; j <= height + bleed_y; j += opts.cell_size) {
var x = Math.floor(i + Math.random() * 2 * variance - variance);
var y = Math.floor(j + Math.random() * 2 * variance - variance);
points.push([x, y]);
}
}

return points;
}

return points;
}

//triangles only!
function _centroid(d) {
return {
x: (d[0][0] + d[1][0] + d[2][0])/3,
y: (d[0][1] + d[1][1] + d[2][1])/3
};
}

// select a random palette from colorbrewer
function _random_colorbrewer() {
var keys = Object.keys(colorbrewer);
var palette = colorbrewer[keys[Math.floor(Math.random()*keys.length)]];
keys = Object.keys(palette);
var colors = palette[keys[Math.floor(Math.random()*keys.length)]];
return colors;
}

// shallow extend (sort of) for option defaults
function _merge_opts(defaults, options) {
var out = {};

// shallow-copy defaults
for (var key in defaults) {
out[key] = defaults[key];
//triangles only!
function _centroid(d) {
return {
x: (d[0][0] + d[1][0] + d[2][0])/3,
y: (d[0][1] + d[1][1] + d[2][1])/3
};
}

for (key in options) {
if (defaults.hasOwnProperty(key)) {
out[key] = options[key]; // override defaults with options
} else {
throw new Error(key+" is not a configuration option for Trianglify. Check your spelling?");
// select a random palette from colorbrewer
function _random_colorbrewer() {
var keys = Object.keys(colorbrewer);
var palette = colorbrewer[keys[Math.floor(Math.random()*keys.length)]];
keys = Object.keys(palette);
var colors = palette[keys[Math.floor(Math.random()*keys.length)]];
return colors;
}

// shallow extend (sort of) for option defaults
function _merge_opts(defaults, options) {
var out = {};

// shallow-copy defaults
for (var key in defaults) {
out[key] = defaults[key];
}

for (key in options) {
if (defaults.hasOwnProperty(key)) {
out[key] = options[key]; // override defaults with options
} else {
throw new Error(key+" is not a configuration option for Trianglify. Check your spelling?");
}
}
return out;
}
return out;
}

} //end of Trianglify function closure


Trianglify.colorbrewer = colorbrewer;
Expand Down
75 changes: 24 additions & 51 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,74 +2,47 @@ var should = require('chai').should();
var expect = require('chai').expect;
var Trianglify = require('../lib/trianglify');

var Pattern = require('../lib/pattern');

describe('Trianglify', function(){

it('should export the colorbrewer palette', function() {
Trianglify.colorbrewer.should.have.property('YlGn');
});

describe('constructor', function(){

it('should have default options', function() {
var t = Trianglify();
expect(Trianglify.defaults).to.not.be.undefined();

for (var key in Trianglify.defaults) {
t.opts.should.have.property(key);
}
});

it('should override defaults with provided options', function() {
var t = Trianglify({cell_size: 1234, cell_padding: 567});
t.opts.cell_size.should.equal(1234);
t.opts.cell_padding.should.equal(567);
t.opts.should.not.equal(Trianglify.defaults);
});
it('should throw an error on invalid options', function() {
(function() {Trianglify(100, 100, {bad_option: true});}).should.throw(Error);
});

it('should throw an error on invalid options', function() {
(function() {Trianglify({bad_option: true});}).should.throw(Error);
});
it('should throw an error on invalid dimensions', function() {
(function() {Trianglify();}).should.throw(Error);
(function() {Trianglify(-1, 100);}).should.throw(Error);
(function() {Trianglify(100, -1);}).should.throw(Error);
});

it('should give a random color from the colorbrewer palette if no colors are provided', function() {
var t = Trianglify();
t.opts.x_colors.should.have.length.within(3,11);
t.opts.y_colors.should.have.length.within(3,11);
});
it('return a Pattern given valid options', function() {
Trianglify(100, 100).should.include.keys(['opts', 'data', 'svg', 'canvas']);
});

it('should not give a random color from the colorbrewer palette if colors are provided', function() {
var whiteblack = ['#FFF', '#000'];
var blackwhite = ['#000', '#FFF'];
var t = Trianglify({
x_colors: whiteblack,
y_colors: blackwhite
});
t.opts.x_colors.should.equal(whiteblack);
t.opts.y_colors.should.equal(blackwhite);
});
it('should populate opts with defaults', function() {
var default_props = Object.keys(Trianglify.defaults);
Trianglify(100, 100).opts.should.have.keys(default_props);
});

it('should override opts with user-provided options', function() {
Trianglify(100, 100, {cell_size: 1234}).opts.cell_size.should.not.equal(Trianglify.defaults.cell_size);
});

describe('#generate', function() {
var t = Trianglify();

it('should return an array of colors & polygons', function() {
var geom = t.generate(600, 300);
geom.should.be.instanceof(Array);
var datum = geom[0];
it('should pass well-formed geometry to the Pattern', function() {
var data = Trianglify(400, 400).data;

data.should.be.instanceof(Array);
var datum = data[0];
datum.should.be.instanceof(Array);
datum[0].should.match(/^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/);
datum[1].should.be.instanceof(Array);
datum[1].should.have.length(3);
datum[1][0].should.have.length(2);
});

it('should throw an error if no dimensions are provided', function() {
(function() { t.generate(); }).should.throw(Error);
});

it("really should be returning a Pattern closure", function() {
throw new Error("wub wub wub wub");
});
});

});
Loading

0 comments on commit bba9784

Please sign in to comment.