From 499b691a5efe6d22b3d0bc7124c518e1352d9994 Mon Sep 17 00:00:00 2001 From: basilesimon Date: Mon, 22 May 2017 11:40:26 +0100 Subject: [PATCH 01/10] Changes to README and package to up version Update README --- README.md | 24 +++++++++++++++--------- package.json | 15 +++++++++------ 2 files changed, 24 insertions(+), 15 deletions(-) diff --git a/README.md b/README.md index 1f76573..98976d7 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,12 @@ -# d3.layout.grid +# d3-grid -A grid layout for [D3](http://d3js.org). The grid layout takes a one-dimensional array of data and arranges it on a two-dimensional grid. +A grid layout for [D3](http://d3js.org)v4. + +The grid layout takes a one-dimensional array of data and arranges it on a two-dimensional grid. ## API -# d3.layout.grid() +# d3.grid() Constructs a new grid layout. @@ -17,20 +19,21 @@ Computes the layout for nodes. Per default, the layout tries to keep the # grid.points() -Configure the grid to treat nodes as points, cf. [d3.scale.ordinal().rangePoints()](https://github.com/mbostock/d3/wiki/Ordinal-Scales#wiki-ordinal_rangePoints). +Configure the grid to treat nodes as points, cf. [d3.scalePoints().range()](https://github.com/d3/d3-scale#point-scales). + # grid.bands() -Configure the grid to treat nodes as bands, cf. [d3.scale.ordinal().rangeBands()](https://github.com/mbostock/d3/wiki/Ordinal-Scales#wiki-ordinal_rangeBands) +Configure the grid to treat nodes as bands, cf. [d3.scaleBand().range()](https://github.com/d3/d3-scale#band-scales). # grid.padding([padding]) -Specify the padding between the node bands as [x, y]. x and y are relative to the band width/height, similar to the padding parameter of [d3.scale.ordinal().rangeBands()](https://github.com/mbostock/d3/wiki/Ordinal-Scales#wiki-ordinal_rangeBands). +Specify the padding between the node bands as [x, y]. x and y are relative to the band width/height, similar to the padding parameter of [d3.scaleBand().range()](https://github.com/mbostock/d3/wiki/Ordinal-Scales#wiki-ordinal_rangeBands). If [nodeSize](#nodeSize) is set, padding is absolute. For example, to configure a grid layout for nodes with 100×100px size, and 20px horizontal and vertical padding, use: ```javascript -var grid = d3.layout.grid() +var grid = d3.grid() .nodeSize([100, 100]) .padding([20, 20]); ``` @@ -59,15 +62,18 @@ If nodeSize is set, returns the current nodeSize. If instead [size](#size) is set, returns the actual size of a node after [grid](#grid) has been called. - ## Examples -* [Grid layout demo](http://bl.ocks.org/herrstucki/5684816) +* [Grid layout demo](http://bl.ocks.org/basilesimon/dbb876d063f2b0475824dbd6b16c251f) ## Author Jeremy Stucki, [Interactive Things](http://interactivethings.com) +## Contributors + +Basile Simon, [@basilesimon](https://twitter.com/basilesimon) + ## License BSD, see LICENSE.txt diff --git a/package.json b/package.json index a5eb5c2..3b066b7 100644 --- a/package.json +++ b/package.json @@ -1,24 +1,27 @@ { "name": "d3-grid", - "version": "0.1.1", - "description": "Grid layout for D3", + "version": "0.2", + "description": "Grid layout for D3v4", "main": "d3-grid.js", "scripts": { "test": "node_modules/.bin/vows --spec" }, - "repository": "https://github.com/interactivethings/d3-grid.git", + "repository": "https://github.com/basilesimon/d3-grid.git", "keywords": [ "d3", "layout", "grid" ], - "author": { + "author": [{ "name": "Jeremy Stucki", "url": "http://interactivethings.com" - }, + }, { + "name": "Basile Simon", + "url": "https://twitter.com/basilesimon" + }], "license": "BSD", "dependencies": { - "d3": "~3.1.5" + "d3": "~4.9" }, "devDependencies": { "vows": "~0.7.0" From e2714ad8159afff6e73590b30d8623a67d6623b3 Mon Sep 17 00:00:00 2001 From: basilesimon Date: Mon, 22 May 2017 11:43:48 +0100 Subject: [PATCH 02/10] Upgrade layout to d3v4 --- d3-grid.js | 100 +++++++++++++++++++++++++---------------------------- 1 file changed, 47 insertions(+), 53 deletions(-) diff --git a/d3-grid.js b/d3-grid.js index 88f7d04..533be73 100644 --- a/d3-grid.js +++ b/d3-grid.js @@ -1,64 +1,68 @@ (function() { - var DEBUG = false; - - d3.layout.grid = function() { - var mode = "equal", - layout = _distributeEqually, - x = d3.scale.ordinal(), - y = d3.scale.ordinal(), - size = [1, 1], - actualSize = [0, 0], - nodeSize = false, - bands = false, - padding = [0, 0], - cols, rows; + d3.grid = function() { + var mode = 'equal', + layout = _distributeEqually, + x = d3.scaleOrdinal(), + y = d3.scaleOrdinal(), + size = [1, 1], + actualSize = [0, 0], + nodeSize = false, + bands = false, + padding = [0, 0], + cols, + rows; function grid(nodes) { return layout(nodes); } function _distributeEqually(nodes) { - var i = -1, - n = nodes.length, - _cols = cols ? cols : 0, - _rows = rows ? rows : 0, - col, row; - - // FIXME: make explicit rows/cols exclusive? Or find a smart way to deal with overflows (repeat?) - // FIXME: when rows are set, fill top-to-bottom (make test with 5 data points and 4 rows) + var i = -1, + n = nodes.length, + _cols = cols ? cols : 0, + _rows = rows ? rows : 0, + col, + row; if (_rows && !_cols) { - _cols = Math.ceil(n / _rows) + _cols = Math.ceil(n / _rows); } else { _cols || (_cols = Math.ceil(Math.sqrt(n))); _rows || (_rows = Math.ceil(n / _cols)); } if (nodeSize) { - x.domain(d3.range(_cols)).range(d3.range(0, (size[0] + padding[0]) * _cols, size[0] + padding[0])); - y.domain(d3.range(_rows)).range(d3.range(0, (size[1] + padding[1]) * _rows, size[1] + padding[1])); + x + .domain(d3.range(_cols)) + .range( + d3.range(0, (size[0] + padding[0]) * _cols, size[0] + padding[0]) + ); + y + .domain(d3.range(_rows)) + .range( + d3.range(0, (size[1] + padding[1]) * _rows, size[1] + padding[1]) + ); actualSize[0] = bands ? x(_cols - 1) + size[0] : x(_cols - 1); actualSize[1] = bands ? y(_rows - 1) + size[1] : y(_rows - 1); } else if (bands) { - x.domain(d3.range(_cols)).rangeBands([0, size[0]], padding[0], 0); - y.domain(d3.range(_rows)).rangeBands([0, size[1]], padding[1], 0); - actualSize[0] = x.rangeBand(); - actualSize[1] = y.rangeBand(); + var x = d3.scaleBand(); + var y = d3.scaleBand(); + x.domain(d3.range(_cols)).range([0, size[0]], padding[0], 0); + y.domain(d3.range(_rows)).range([0, size[1]], padding[1], 0); + actualSize[0] = x.bandwidth() - 10; + actualSize[1] = y.bandwidth() - 10; } else { - x.domain(d3.range(_cols)).rangePoints([0, size[0]]); - y.domain(d3.range(_rows)).rangePoints([0, size[1]]); + var x = d3.scalePoint(); + var y = d3.scalePoint(); + x.domain(d3.range(_cols)).range([0, size[0]]); + y.domain(d3.range(_rows)).range([0, size[1]]); actualSize[0] = x(1); actualSize[1] = y(1); } - if (DEBUG) console.log('cols/rows', _cols, _rows); - while (++i < n) { col = i % _cols; row = Math.floor(i / _cols); - - if (DEBUG) console.log(i, col, row); - nodes[i].x = x(col); nodes[i].y = y(row); } @@ -66,58 +70,48 @@ return nodes; } - // grid.mode = function(value) { - // if (!arguments.length) return mode; - // switch(mode = value) { - // case "equal": - // layout = _distributeEqually; - // break; - // } - // return grid; - // } - grid.size = function(value) { if (!arguments.length) return nodeSize ? actualSize : size; actualSize = [0, 0]; nodeSize = (size = value) == null; return grid; - } + }; grid.nodeSize = function(value) { if (!arguments.length) return nodeSize ? size : actualSize; actualSize = [0, 0]; nodeSize = (size = value) != null; return grid; - } + }; grid.rows = function(value) { if (!arguments.length) return rows; rows = value; return grid; - } + }; grid.cols = function(value) { if (!arguments.length) return cols; cols = value; return grid; - } + }; grid.bands = function() { bands = true; return grid; - } + }; grid.points = function() { bands = false; return grid; - } + }; grid.padding = function(value) { if (!arguments.length) return padding; padding = value; return grid; - } + }; return grid; }; -})(); \ No newline at end of file +})(); From f3015dd3dcb235c6710e94027c5359164f4d77b7 Mon Sep 17 00:00:00 2001 From: basilesimon Date: Mon, 22 May 2017 12:54:43 +0100 Subject: [PATCH 03/10] Match plugin folder structure --- d3-grid.js | 117 ---------- index.js | 1 + src/d3-grid.js | 115 +++++++++ test/d3-grid-test.js | 546 ++++++++++++++++++++++--------------------- 4 files changed, 397 insertions(+), 382 deletions(-) delete mode 100644 d3-grid.js create mode 100644 index.js create mode 100644 src/d3-grid.js diff --git a/d3-grid.js b/d3-grid.js deleted file mode 100644 index 533be73..0000000 --- a/d3-grid.js +++ /dev/null @@ -1,117 +0,0 @@ -(function() { - d3.grid = function() { - var mode = 'equal', - layout = _distributeEqually, - x = d3.scaleOrdinal(), - y = d3.scaleOrdinal(), - size = [1, 1], - actualSize = [0, 0], - nodeSize = false, - bands = false, - padding = [0, 0], - cols, - rows; - - function grid(nodes) { - return layout(nodes); - } - - function _distributeEqually(nodes) { - var i = -1, - n = nodes.length, - _cols = cols ? cols : 0, - _rows = rows ? rows : 0, - col, - row; - - if (_rows && !_cols) { - _cols = Math.ceil(n / _rows); - } else { - _cols || (_cols = Math.ceil(Math.sqrt(n))); - _rows || (_rows = Math.ceil(n / _cols)); - } - - if (nodeSize) { - x - .domain(d3.range(_cols)) - .range( - d3.range(0, (size[0] + padding[0]) * _cols, size[0] + padding[0]) - ); - y - .domain(d3.range(_rows)) - .range( - d3.range(0, (size[1] + padding[1]) * _rows, size[1] + padding[1]) - ); - actualSize[0] = bands ? x(_cols - 1) + size[0] : x(_cols - 1); - actualSize[1] = bands ? y(_rows - 1) + size[1] : y(_rows - 1); - } else if (bands) { - var x = d3.scaleBand(); - var y = d3.scaleBand(); - x.domain(d3.range(_cols)).range([0, size[0]], padding[0], 0); - y.domain(d3.range(_rows)).range([0, size[1]], padding[1], 0); - actualSize[0] = x.bandwidth() - 10; - actualSize[1] = y.bandwidth() - 10; - } else { - var x = d3.scalePoint(); - var y = d3.scalePoint(); - x.domain(d3.range(_cols)).range([0, size[0]]); - y.domain(d3.range(_rows)).range([0, size[1]]); - actualSize[0] = x(1); - actualSize[1] = y(1); - } - - while (++i < n) { - col = i % _cols; - row = Math.floor(i / _cols); - nodes[i].x = x(col); - nodes[i].y = y(row); - } - - return nodes; - } - - grid.size = function(value) { - if (!arguments.length) return nodeSize ? actualSize : size; - actualSize = [0, 0]; - nodeSize = (size = value) == null; - return grid; - }; - - grid.nodeSize = function(value) { - if (!arguments.length) return nodeSize ? size : actualSize; - actualSize = [0, 0]; - nodeSize = (size = value) != null; - return grid; - }; - - grid.rows = function(value) { - if (!arguments.length) return rows; - rows = value; - return grid; - }; - - grid.cols = function(value) { - if (!arguments.length) return cols; - cols = value; - return grid; - }; - - grid.bands = function() { - bands = true; - return grid; - }; - - grid.points = function() { - bands = false; - return grid; - }; - - grid.padding = function(value) { - if (!arguments.length) return padding; - padding = value; - return grid; - }; - - return grid; - }; -})(); diff --git a/index.js b/index.js new file mode 100644 index 0000000..bc6f0f8 --- /dev/null +++ b/index.js @@ -0,0 +1 @@ +export { default as grid } from './src/d3-grid'; diff --git a/src/d3-grid.js b/src/d3-grid.js new file mode 100644 index 0000000..d5f0588 --- /dev/null +++ b/src/d3-grid.js @@ -0,0 +1,115 @@ +export default function() { + var mode = 'equal', + layout = _distributeEqually, + x = d3.scaleOrdinal(), + y = d3.scaleOrdinal(), + size = [1, 1], + actualSize = [0, 0], + nodeSize = false, + bands = false, + padding = [0, 0], + cols, + rows; + + function grid(nodes) { + return layout(nodes); + } + + function _distributeEqually(nodes) { + var i = -1, + n = nodes.length, + _cols = cols ? cols : 0, + _rows = rows ? rows : 0, + col, + row; + + if (_rows && !_cols) { + _cols = Math.ceil(n / _rows); + } else { + _cols || (_cols = Math.ceil(Math.sqrt(n))); + _rows || (_rows = Math.ceil(n / _cols)); + } + + if (nodeSize) { + x + .domain(d3.range(_cols)) + .range( + d3.range(0, (size[0] + padding[0]) * _cols, size[0] + padding[0]) + ); + y + .domain(d3.range(_rows)) + .range( + d3.range(0, (size[1] + padding[1]) * _rows, size[1] + padding[1]) + ); + actualSize[0] = bands ? x(_cols - 1) + size[0] : x(_cols - 1); + actualSize[1] = bands ? y(_rows - 1) + size[1] : y(_rows - 1); + } else if (bands) { + var x = d3.scaleBand(); + var y = d3.scaleBand(); + x.domain(d3.range(_cols)).range([0, size[0]], padding[0], 0); + y.domain(d3.range(_rows)).range([0, size[1]], padding[1], 0); + actualSize[0] = x.bandwidth() - 10; + actualSize[1] = y.bandwidth() - 10; + } else { + var x = d3.scalePoint(); + var y = d3.scalePoint(); + x.domain(d3.range(_cols)).range([0, size[0]]); + y.domain(d3.range(_rows)).range([0, size[1]]); + actualSize[0] = x(1); + actualSize[1] = y(1); + } + + while (++i < n) { + col = i % _cols; + row = Math.floor(i / _cols); + nodes[i].x = x(col); + nodes[i].y = y(row); + } + + return nodes; + } + + grid.size = function(value) { + if (!arguments.length) return nodeSize ? actualSize : size; + actualSize = [0, 0]; + nodeSize = (size = value) == null; + return grid; + }; + + grid.nodeSize = function(value) { + if (!arguments.length) return nodeSize ? size : actualSize; + actualSize = [0, 0]; + nodeSize = (size = value) != null; + return grid; + }; + + grid.rows = function(value) { + if (!arguments.length) return rows; + rows = value; + return grid; + }; + + grid.cols = function(value) { + if (!arguments.length) return cols; + cols = value; + return grid; + }; + + grid.bands = function() { + bands = true; + return grid; + }; + + grid.points = function() { + bands = false; + return grid; + }; + + grid.padding = function(value) { + if (!arguments.length) return padding; + padding = value; + return grid; + }; + + return grid; +} diff --git a/test/d3-grid-test.js b/test/d3-grid-test.js index cf9c4fa..1583d63 100644 --- a/test/d3-grid-test.js +++ b/test/d3-grid-test.js @@ -1,274 +1,290 @@ -var vows = require('vows'), - assert = require('assert'); +var vows = require('vows'), assert = require('assert'); d3 = require('d3'); -var grid = require("../d3-grid.js"); - -vows.describe('d3.layout.grid').addBatch({ - 'Grid layout' : { - topic: function() { return d3.layout.grid; }, - 'equally distributes 4 nodes within a 1x1 space, left to right, top to bottom': function(grid) { - var l = grid().points(); - var nodes = [{}, {}, {}, {}]; - - assert.deepEqual(l(nodes).map(layout), [ - {x: 0, y: 0}, - {x: 1, y: 0}, - {x: 0, y: 1}, - {x: 1, y: 1} - ]); +var grid = require('../d3-grid.js'); + +vows + .describe('d3.grid') + .addBatch({ + 'Grid layout': { + topic: function() { + return d3.layout.grid; + }, + 'equally distributes 4 nodes within a 1x1 space, left to right, top to bottom': function( + grid + ) { + var l = grid().points(); + var nodes = [{}, {}, {}, {}]; + + assert.deepEqual(l(nodes).map(layout), [ + { x: 0, y: 0 }, + { x: 1, y: 0 }, + { x: 0, y: 1 }, + { x: 1, y: 1 }, + ]); + }, + '1 data point is in the center (is this good or should it be at [0,0]?)': function( + grid + ) { + var l = grid().points(); + var nodes = [{}]; + + assert.deepEqual(l(nodes).map(layout), [{ x: 0.5, y: 0.5 }]); + }, + 'equally distributes 5 nodes within a 1x1 space': function(grid) { + var l = grid().points(); + var nodes = [{}, {}, {}, {}, {}]; + + assert.deepEqual(l(nodes).map(layout), [ + { x: 0, y: 0 }, + { x: 0.5, y: 0 }, + { x: 1, y: 0 }, + { x: 0, y: 1 }, + { x: 0.5, y: 1 }, + ]); + }, + 'equally distributes 5 nodes within a 300x500 space': function(grid) { + var l = grid().points().size([300, 500]); + var nodes = [{}, {}, {}, {}, {}]; + + assert.deepEqual(l(nodes).map(layout), [ + { x: 0, y: 0 }, + { x: 150, y: 0 }, + { x: 300, y: 0 }, + { x: 0, y: 500 }, + { x: 150, y: 500 }, + ]); + }, + 'fixed amount of cols': function(grid) { + var l = grid().points().cols(2); + var nodes = [{}, {}, {}, {}, {}]; + + assert.deepEqual(l(nodes).map(layout), [ + { x: 0, y: 0 }, + { x: 1, y: 0 }, + { x: 0, y: 0.5 }, + { x: 1, y: 0.5 }, + { x: 0, y: 1 }, + ]); + }, + 'fixed amount of rows': function(grid) { + var l = grid().points().rows(3); + var nodes = [{}, {}, {}, {}, {}]; + + assert.deepEqual(l(nodes).map(layout), [ + { x: 0, y: 0 }, + { x: 1, y: 0 }, + { x: 0, y: 0.5 }, + { x: 1, y: 0.5 }, + { x: 0, y: 1 }, + ]); + }, + 'fixed amount of cols and rows': function(grid) { + var l = grid().points().cols(2).rows(5); + var nodes = [{}, {}, {}, {}, {}]; + + assert.deepEqual(l(nodes).map(layout), [ + { x: 0, y: 0 }, + { x: 1, y: 0 }, + { x: 0, y: 0.25 }, + { x: 1, y: 0.25 }, + { x: 0, y: 0.5 }, + ]); + }, + '1 row': function(grid) { + var l = grid().points().rows(1); + var nodes = [{}, {}, {}, {}, {}]; + + assert.deepEqual(l(nodes).map(layout), [ + { x: 0, y: 0.5 }, + { x: 0.25, y: 0.5 }, + { x: 0.5, y: 0.5 }, + { x: 0.75, y: 0.5 }, + { x: 1, y: 0.5 }, + ]); + }, + // TODO: This needs some more thought ... + // '4 rows, 5 data points': function(grid) { + // var l = grid().points().rows(4); + // var nodes = [{}, {}, {}, {}, {}]; + + // assert.deepEqual(l(nodes).map(layout), [ + // {x: 0, y: 0}, + // {x: 0, y: 1/3}, + // {x: 0, y: 2/3}, + // {x: 0, y: 1}, + // {x: 1, y: 0} + // ]); + // }, + 'fixed node sizes': function(grid) { + var l = grid().points().nodeSize([1, 1]); + var nodes = [{}, {}, {}, {}, {}]; + + assert.deepEqual(l(nodes).map(layout), [ + { x: 0, y: 0 }, + { x: 1, y: 0 }, + { x: 2, y: 0 }, + { x: 0, y: 1 }, + { x: 1, y: 1 }, + ]); + }, + 'reset rows/cols after each call': function(grid) { + var l = grid().points(); + var nodes = [{}, {}, {}, {}, {}]; + + assert.deepEqual(l(nodes).map(layout), [ + { x: 0, y: 0 }, + { x: 0.5, y: 0 }, + { x: 1, y: 0 }, + { x: 0, y: 1 }, + { x: 0.5, y: 1 }, + ]); + + nodes = [{}, {}, {}, {}]; + + assert.deepEqual(l(nodes).map(layout), [ + { x: 0, y: 0 }, + { x: 1, y: 0 }, + { x: 0, y: 1 }, + { x: 1, y: 1 }, + ]); + }, + 'fixed amount of cols stays the same': function(grid) { + var l = grid().points().cols(2); + var nodes = [{}, {}, {}, {}, {}]; + + assert.deepEqual(l(nodes).map(layout), [ + { x: 0, y: 0 }, + { x: 1, y: 0 }, + { x: 0, y: 0.5 }, + { x: 1, y: 0.5 }, + { x: 0, y: 1 }, + ]); + + nodes = [{}, {}, {}, {}, {}, {}, {}]; + + assert.deepEqual(l(nodes).map(layout), [ + { x: 0, y: 0 }, + { x: 1, y: 0 }, + { x: 0, y: 1 / 3 }, + { x: 1, y: 1 / 3 }, + { x: 0, y: 2 / 3 }, + { x: 1, y: 2 / 3 }, + { x: 0, y: 1 }, + ]); + }, + bands: function(grid) { + var l = grid().bands(); + var nodes = [{}, {}, {}, {}, {}]; + + assert.deepEqual(l(nodes).map(layout), [ + { x: 0, y: 0 }, + { x: 1 / 3, y: 0 }, + { x: 2 / 3, y: 0 }, + { x: 0, y: 0.5 }, + { x: 1 / 3, y: 0.5 }, + ]); + + l.cols(2); + + assert.deepEqual(l(nodes).map(layout), [ + { x: 0, y: 0 }, + { x: 0.5, y: 0 }, + { x: 0, y: 1 / 3 }, + { x: 0.5, y: 1 / 3 }, + { x: 0, y: 2 / 3 }, + ]); + }, + 'bands with padding': function(grid) { + var l = grid().bands().padding([0.5, 0.5]); + var nodes = [{}, {}, {}, {}, {}]; + + assert.deepEqual(l(nodes).map(layout), [ + { x: 0, y: 0 }, + { x: 0.4, y: 0 }, + { x: 0.8, y: 0 }, + { x: 0, y: 2 / 3 }, + { x: 0.4, y: 2 / 3 }, + ]); + + l.cols(2); + + assert.deepEqual(l(nodes).map(layout), [ + { x: 0, y: 0 }, + { x: 2 / 3, y: 0 }, + { x: 0, y: 0.4 }, + { x: 2 / 3, y: 0.4 }, + { x: 0, y: 0.8 }, + ]); + }, + 'initial sizes': function(grid) { + var l = grid(); + assert.deepEqual(l.size(), [1, 1]); + assert.deepEqual(l.nodeSize(), [0, 0]); + assert.deepEqual(l.nodeSize([1, 1]).size(), [0, 0]); + }, + '.size() reports actual size when .points().nodeSize() is set': function( + grid + ) { + var l = grid().points().nodeSize([1, 1]); + var nodes = [{}, {}, {}, {}, {}]; + + l(nodes); + assert.deepEqual(l.size(), [2, 1]); + }, + '.size() reports actual size when .points().nodeSize() is set': function( + grid + ) { + var l = grid().points().nodeSize([1, 1]); + var nodes = [{}, {}, {}, {}, {}]; + + l(nodes); + assert.deepEqual(l.size(), [2, 1]); + }, + '.size() reports actual size when .bands().nodeSize() is set': function( + grid + ) { + var l = grid().bands().nodeSize([1, 1]); + var nodes = [{}, {}, {}, {}, {}]; + + l(nodes); + assert.deepEqual(l.size(), [3, 2]); + }, + '.nodeSize() reports actual spacing between points when .points().size() is set': function( + grid + ) { + var l = grid().points().size([1, 1]); + var nodes = [{}, {}, {}, {}, {}]; + + l(nodes); + assert.deepEqual(l.nodeSize(), [0.5, 1]); + }, + '.nodeSize() reports actual size when .bands().size() is set': function( + grid + ) { + var l = grid().bands().size([1, 1]); + var nodes = [{}, {}, {}, {}, {}]; + + l(nodes); + assert.deepEqual(l.nodeSize(), [1 / 3, 0.5]); + }, + '.nodeSize() reports actual size when .bands().size().padding() is set': function( + grid + ) { + var l = grid().bands().padding([0.5, 0.5]).size([1, 1]); + var nodes = [{}, {}, {}, {}, {}]; + + l(nodes); + assert.deepEqual(l.nodeSize(), [1 / 5, 1 / 3]); + }, }, - '1 data point is in the center (is this good or should it be at [0,0]?)': function(grid) { - var l = grid().points(); - var nodes = [{}]; - - assert.deepEqual(l(nodes).map(layout), [ - {x: 0.5, y: 0.5} - ]); - }, - 'equally distributes 5 nodes within a 1x1 space': function(grid) { - var l = grid().points(); - var nodes = [{}, {}, {}, {}, {}]; - - assert.deepEqual(l(nodes).map(layout), [ - {x: 0, y: 0}, - {x: 0.5, y: 0}, - {x: 1, y: 0}, - {x: 0, y: 1}, - {x: 0.5, y: 1} - ]); - }, - 'equally distributes 5 nodes within a 300x500 space': function(grid) { - var l = grid().points() - .size([300, 500]); - var nodes = [{}, {}, {}, {}, {}]; - - assert.deepEqual(l(nodes).map(layout), [ - {x: 0, y: 0}, - {x: 150, y: 0}, - {x: 300, y: 0}, - {x: 0, y: 500}, - {x: 150, y: 500} - ]); - }, - 'fixed amount of cols': function(grid) { - var l = grid().points().cols(2); - var nodes = [{}, {}, {}, {}, {}]; - - assert.deepEqual(l(nodes).map(layout), [ - {x: 0, y: 0}, - {x: 1, y: 0}, - {x: 0, y: 0.5}, - {x: 1, y: 0.5}, - {x: 0, y: 1} - ]); - }, - 'fixed amount of rows': function(grid) { - var l = grid().points().rows(3); - var nodes = [{}, {}, {}, {}, {}]; - - assert.deepEqual(l(nodes).map(layout), [ - {x: 0, y: 0}, - {x: 1, y: 0}, - {x: 0, y: 0.5}, - {x: 1, y: 0.5}, - {x: 0, y: 1} - ]); - }, - 'fixed amount of cols and rows': function(grid) { - var l = grid().points().cols(2).rows(5); - var nodes = [{}, {}, {}, {}, {}]; - - assert.deepEqual(l(nodes).map(layout), [ - {x: 0, y: 0}, - {x: 1, y: 0}, - {x: 0, y: 0.25}, - {x: 1, y: 0.25}, - {x: 0, y: 0.5} - ]); - }, - '1 row': function(grid) { - var l = grid().points().rows(1); - var nodes = [{}, {}, {}, {}, {}]; - - assert.deepEqual(l(nodes).map(layout), [ - {x: 0, y: 0.5}, - {x: 0.25, y: 0.5}, - {x: 0.5, y: 0.5}, - {x: 0.75, y: 0.5}, - {x: 1, y: 0.5} - ]); - }, - // TODO: This needs some more thought ... - // '4 rows, 5 data points': function(grid) { - // var l = grid().points().rows(4); - // var nodes = [{}, {}, {}, {}, {}]; - - // assert.deepEqual(l(nodes).map(layout), [ - // {x: 0, y: 0}, - // {x: 0, y: 1/3}, - // {x: 0, y: 2/3}, - // {x: 0, y: 1}, - // {x: 1, y: 0} - // ]); - // }, - 'fixed node sizes': function(grid) { - var l = grid().points().nodeSize([1, 1]); - var nodes = [{}, {}, {}, {}, {}]; - - assert.deepEqual(l(nodes).map(layout), [ - {x: 0, y: 0}, - {x: 1, y: 0}, - {x: 2, y: 0}, - {x: 0, y: 1}, - {x: 1, y: 1} - ]); - }, - 'reset rows/cols after each call': function(grid) { - var l = grid().points(); - var nodes = [{}, {}, {}, {}, {}]; - - assert.deepEqual(l(nodes).map(layout), [ - {x: 0, y: 0}, - {x: 0.5, y: 0}, - {x: 1, y: 0}, - {x: 0, y: 1}, - {x: 0.5, y: 1} - ]); - - nodes = [{}, {}, {}, {}]; - - assert.deepEqual(l(nodes).map(layout), [ - {x: 0, y: 0}, - {x: 1, y: 0}, - {x: 0, y: 1}, - {x: 1, y: 1} - ]); - }, - 'fixed amount of cols stays the same': function(grid) { - var l = grid().points().cols(2); - var nodes = [{}, {}, {}, {}, {}]; - - assert.deepEqual(l(nodes).map(layout), [ - {x: 0, y: 0}, - {x: 1, y: 0}, - {x: 0, y: 0.5}, - {x: 1, y: 0.5}, - {x: 0, y: 1} - ]); - - nodes = [{}, {}, {}, {}, {}, {}, {}]; - - assert.deepEqual(l(nodes).map(layout), [ - {x: 0, y: 0}, - {x: 1, y: 0}, - {x: 0, y: 1/3}, - {x: 1, y: 1/3}, - {x: 0, y: 2/3}, - {x: 1, y: 2/3}, - {x: 0, y: 1}, - - ]); - }, - 'bands': function(grid) { - var l = grid().bands(); - var nodes = [{}, {}, {}, {}, {}]; - - assert.deepEqual(l(nodes).map(layout), [ - {x: 0, y: 0}, - {x: 1/3, y: 0}, - {x: 2/3, y: 0}, - {x: 0, y: 0.5}, - {x: 1/3, y: 0.5} - ]); - - l.cols(2); - - assert.deepEqual(l(nodes).map(layout), [ - {x: 0, y: 0}, - {x: 0.5, y: 0}, - {x: 0, y: 1/3}, - {x: 0.5, y: 1/3}, - {x: 0, y: 2/3} - ]); - }, - 'bands with padding': function(grid) { - var l = grid().bands().padding([0.5, 0.5]); - var nodes = [{}, {}, {}, {}, {}]; - - assert.deepEqual(l(nodes).map(layout), [ - {x: 0, y: 0}, - {x: 0.4, y: 0}, - {x: 0.8, y: 0}, - {x: 0, y: 2/3}, - {x: 0.4, y: 2/3} - ]); - - l.cols(2); - - assert.deepEqual(l(nodes).map(layout), [ - {x: 0, y: 0}, - {x: 2/3, y: 0}, - {x: 0, y: 0.4}, - {x: 2/3, y: 0.4}, - {x: 0, y: 0.8} - ]); - }, - 'initial sizes': function(grid) { - var l = grid(); - assert.deepEqual(l.size(), [1, 1]); - assert.deepEqual(l.nodeSize(), [0, 0]); - assert.deepEqual(l.nodeSize([1, 1]).size(), [0, 0]); - }, - '.size() reports actual size when .points().nodeSize() is set': function(grid) { - var l = grid().points().nodeSize([1, 1]); - var nodes = [{}, {}, {}, {}, {}]; - - l(nodes); - assert.deepEqual(l.size(), [2, 1]); - }, - '.size() reports actual size when .points().nodeSize() is set': function(grid) { - var l = grid().points().nodeSize([1, 1]); - var nodes = [{}, {}, {}, {}, {}]; - - l(nodes); - assert.deepEqual(l.size(), [2, 1]); - }, - '.size() reports actual size when .bands().nodeSize() is set': function(grid) { - var l = grid().bands().nodeSize([1, 1]); - var nodes = [{}, {}, {}, {}, {}]; - - l(nodes); - assert.deepEqual(l.size(), [3, 2]); - }, - '.nodeSize() reports actual spacing between points when .points().size() is set': function(grid) { - var l = grid().points().size([1, 1]); - var nodes = [{}, {}, {}, {}, {}]; - - l(nodes); - assert.deepEqual(l.nodeSize(), [0.5, 1]); - }, - '.nodeSize() reports actual size when .bands().size() is set': function(grid) { - var l = grid().bands().size([1, 1]); - var nodes = [{}, {}, {}, {}, {}]; - - l(nodes); - assert.deepEqual(l.nodeSize(), [1/3, 0.5]); - }, - '.nodeSize() reports actual size when .bands().size().padding() is set': function(grid) { - var l = grid().bands().padding([0.5, 0.5]).size([1, 1]); - var nodes = [{}, {}, {}, {}, {}]; - - l(nodes); - assert.deepEqual(l.nodeSize(), [1/5, 1/3]); - }, - } -}).export(module); + }) + .export(module); function layout(node) { return { x: node.x, - y: node.y + y: node.y, }; -} \ No newline at end of file +} From 838c964bd2ac3ba9b804c13c3a21ef3b36dc30d7 Mon Sep 17 00:00:00 2001 From: basilesimon Date: Mon, 22 May 2017 13:04:22 +0100 Subject: [PATCH 04/10] Trim down d3 dependencies - fix #7 --- .gitignore | 1 + package.json | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2658d7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +node_modules/ diff --git a/package.json b/package.json index 3b066b7..d6c05ee 100644 --- a/package.json +++ b/package.json @@ -12,16 +12,17 @@ "layout", "grid" ], - "author": [{ + "author": { "name": "Jeremy Stucki", "url": "http://interactivethings.com" - }, { + }, + "constributors": [{ "name": "Basile Simon", "url": "https://twitter.com/basilesimon" }], "license": "BSD", "dependencies": { - "d3": "~4.9" + "d3-scale": "^1.0.6" }, "devDependencies": { "vows": "~0.7.0" From 7bdde0bd5bb3174c1af297428c4ce5c8a47dc8ae Mon Sep 17 00:00:00 2001 From: basilesimon Date: Wed, 12 Jul 2017 13:09:26 +0100 Subject: [PATCH 05/10] Changes to stick to the build process --- package.json | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index d6c05ee..ad0cdf8 100644 --- a/package.json +++ b/package.json @@ -3,10 +3,12 @@ "version": "0.2", "description": "Grid layout for D3v4", "main": "d3-grid.js", + "module": "index", + "jsnext:main": "index", "scripts": { "test": "node_modules/.bin/vows --spec" }, - "repository": "https://github.com/basilesimon/d3-grid.git", + "repository": "https://github.com/interactivethings/d3-grid.git", "keywords": [ "d3", "layout", @@ -21,6 +23,9 @@ "url": "https://twitter.com/basilesimon" }], "license": "BSD", + "scripts": { + "pretest": "rm -rf build && mkdir build && rollup --banner \"$(preamble)\" -f umd -n d3 -o build/d3-grid.js -- index.js", + }, "dependencies": { "d3-scale": "^1.0.6" }, From 1cb7272c03b86d3484eb36c00258dced1c09732d Mon Sep 17 00:00:00 2001 From: Jeremy Stucki Date: Wed, 12 Jul 2017 14:39:57 +0200 Subject: [PATCH 06/10] Fix package.json --- package.json | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index ad0cdf8..ed62f74 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,12 @@ { "name": "d3-grid", - "version": "0.2", + "version": "0.2.0", "description": "Grid layout for D3v4", "main": "d3-grid.js", "module": "index", "jsnext:main": "index", "scripts": { - "test": "node_modules/.bin/vows --spec" + "pretest": "rm -rf build && mkdir build && rollup --banner \"$(preamble)\" -f umd -n d3 -o build/d3-grid.js -- index.js" }, "repository": "https://github.com/interactivethings/d3-grid.git", "keywords": [ @@ -18,14 +18,13 @@ "name": "Jeremy Stucki", "url": "http://interactivethings.com" }, - "constributors": [{ - "name": "Basile Simon", - "url": "https://twitter.com/basilesimon" - }], - "license": "BSD", - "scripts": { - "pretest": "rm -rf build && mkdir build && rollup --banner \"$(preamble)\" -f umd -n d3 -o build/d3-grid.js -- index.js", - }, + "constributors": [ + { + "name": "Basile Simon", + "url": "https://twitter.com/basilesimon" + } + ], + "license": "BSD-3-Clause", "dependencies": { "d3-scale": "^1.0.6" }, From 6ced216f21d0b9224cd77bcbfdbe33b6d99cb178 Mon Sep 17 00:00:00 2001 From: Jeremy Stucki Date: Wed, 12 Jul 2017 14:40:06 +0200 Subject: [PATCH 07/10] Add .travis.yml --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..e0cc348 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - '8' + - '6' From 8484f79f292a12806cd8d78632f81dc0f1645ecd Mon Sep 17 00:00:00 2001 From: Jeremy Stucki Date: Wed, 12 Jul 2017 14:40:06 +0200 Subject: [PATCH 08/10] Add .travis.yml --- package.json | 6 +++++- src/d3-grid.js | 2 +- test/d3-grid-test.js | 4 ++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index ed62f74..7398efd 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ "module": "index", "jsnext:main": "index", "scripts": { - "pretest": "rm -rf build && mkdir build && rollup --banner \"$(preamble)\" -f umd -n d3 -o build/d3-grid.js -- index.js" + "pretest": "rm -rf build && mkdir build && rollup --banner \"$(preamble)\" -f umd -n d3 -o build/d3-grid.js -- index.js", + "test": "vows test/*" }, "repository": "https://github.com/interactivethings/d3-grid.git", "keywords": [ @@ -29,6 +30,9 @@ "d3-scale": "^1.0.6" }, "devDependencies": { + "d3": "^4", + "package-preamble": "0.0", + "rollup": "0.41", "vows": "~0.7.0" } } diff --git a/src/d3-grid.js b/src/d3-grid.js index d5f0588..4d47dd8 100644 --- a/src/d3-grid.js +++ b/src/d3-grid.js @@ -1,4 +1,4 @@ -export default function() { +module.exports = function() { var mode = 'equal', layout = _distributeEqually, x = d3.scaleOrdinal(), diff --git a/test/d3-grid-test.js b/test/d3-grid-test.js index 1583d63..7357c5e 100644 --- a/test/d3-grid-test.js +++ b/test/d3-grid-test.js @@ -2,14 +2,14 @@ var vows = require('vows'), assert = require('assert'); d3 = require('d3'); -var grid = require('../d3-grid.js'); +var grid = require('../src/d3-grid.js'); vows .describe('d3.grid') .addBatch({ 'Grid layout': { topic: function() { - return d3.layout.grid; + return d3.grid; }, 'equally distributes 4 nodes within a 1x1 space, left to right, top to bottom': function( grid From b966eb65979c447775a55a890ece9361bcd7d0dd Mon Sep 17 00:00:00 2001 From: Chris Hutchinson Date: Wed, 12 Jul 2017 22:34:59 +0100 Subject: [PATCH 09/10] Get test suite up and running --- src/d3-grid.js | 2 +- test/d3-grid-test.js | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/d3-grid.js b/src/d3-grid.js index 4d47dd8..d5f0588 100644 --- a/src/d3-grid.js +++ b/src/d3-grid.js @@ -1,4 +1,4 @@ -module.exports = function() { +export default function() { var mode = 'equal', layout = _distributeEqually, x = d3.scaleOrdinal(), diff --git a/test/d3-grid-test.js b/test/d3-grid-test.js index 7357c5e..b595db0 100644 --- a/test/d3-grid-test.js +++ b/test/d3-grid-test.js @@ -1,14 +1,16 @@ -var vows = require('vows'), assert = require('assert'); +const vows = require('vows'); +const assert = require('assert'); d3 = require('d3'); -var grid = require('../src/d3-grid.js'); +const { grid } = require('../build/d3-grid.js'); vows .describe('d3.grid') .addBatch({ 'Grid layout': { topic: function() { + d3.grid = grid; return d3.grid; }, 'equally distributes 4 nodes within a 1x1 space, left to right, top to bottom': function( From e946675bda4970a3f969f48e85c90b84ceb18200 Mon Sep 17 00:00:00 2001 From: basilesimon Date: Thu, 13 Jul 2017 11:39:38 +0100 Subject: [PATCH 10/10] x/y scales declarations in `_distributeEqually` --- src/d3-grid.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/d3-grid.js b/src/d3-grid.js index d5f0588..250b212 100644 --- a/src/d3-grid.js +++ b/src/d3-grid.js @@ -31,6 +31,8 @@ export default function() { } if (nodeSize) { + x = d3.scaleOrdinal(); + y = d3.scaleOrdinal(); x .domain(d3.range(_cols)) .range(