Grid layout demo.
forked from herrstucki's block: Grid layout
forked from anonymous's block: Grid layout
| license: mit |
Grid layout demo.
forked from herrstucki's block: Grid layout
forked from anonymous's block: Grid layout
| (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) { | |
| x.domain(d3.range(_cols))//.bandwidth([0, size[0]], padding[0], 0); | |
| y.domain(d3.range(_rows))//.bandwidth([0, size[1]], padding[1], 0); | |
| actualSize[0] = x.bandwidth(); | |
| actualSize[1] = y.bandwidth(); | |
| } 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; | |
| }; | |
| })(); |
| <!DOCTYPE html> | |
| <meta charset="utf-8"> | |
| <style> | |
| </style> | |
| <body> | |
| <script src="http://d3js.org/d3.v4.min.js"></script> | |
| <script src="d3-grid.js"></script> | |
| <script> | |
| var con = [], | |
| lab = []; | |
| var width = 960, | |
| height = 500; | |
| //var color = d3.scale.category10(); | |
| var pointGrid = d3.grid() | |
| .points() | |
| .size([100, 100]); | |
| var svg = d3.select("body").append("svg") | |
| .attr('width', width) | |
| .attr('height', height) | |
| .append("g") | |
| .attr("transform", "translate(70,70)"); | |
| var concontainer = svg.append('g') | |
| .attr("transform", "translate(70,70)") | |
| .style('background-color', 'lightblue'); | |
| var labcontainer = svg.append('g') | |
| .attr("transform", "translate(370,70)") | |
| .style('background-color', 'lightcoral'); | |
| var tick = setInterval(push, 500); | |
| function update(){ | |
| var condots = concontainer.selectAll(".point") | |
| .data(pointGrid(con)); | |
| condots.enter().append("circle") | |
| .attr("class", "point") | |
| .attr("r", 1e-6) | |
| .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); | |
| condots.transition() | |
| .attr("r", 10) | |
| .attr('fill', 'orange') | |
| .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); | |
| condots.exit().transition() | |
| .attr("r", 1e-6) | |
| .remove(); | |
| var labdots = labcontainer.selectAll(".point") | |
| .data(pointGrid(lab)); | |
| labdots.enter().append("circle") | |
| .attr("class", "point") | |
| .attr("r", 1e-6) | |
| .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); | |
| labdots.transition() | |
| .attr("r", 10) | |
| .attr('fill', 'steelblue') | |
| .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; }); | |
| labdots.exit().transition() | |
| .attr("r", 1e-6) | |
| .remove(); | |
| } | |
| function push() { | |
| var i = Math.floor(Math.random() * (5 - 1 + 1)) + 1; | |
| while(i>1) { | |
| con.push({}); | |
| i--; | |
| } | |
| var y = Math.floor(Math.random() * (7 - 1 + 1)) + 1; | |
| while(y>1) { | |
| lab.push({}); | |
| y--; | |
| } | |
| lab.push({}); | |
| update(); | |
| if (con.length > 10) { | |
| clearInterval(tick); | |
| tick = setInterval(pop, 500); | |
| } | |
| } | |
| function pop() { | |
| con.pop(); | |
| lab.pop(); | |
| update(); | |
| if (con.length < 2) { | |
| clearInterval(tick); | |
| tick = setInterval(push, 500); | |
| } | |
| } | |
| </script> |