Reputation: 636
I have an SVG element and am drawing rectangles of set size. I calculate max columns max_cols
and required rows min_rows
to match dataset. When I reach the end of the SVG canvas I start a new row, however my algorhytm to calculate the y
coordinate uses magic numbers. How can I get rid of it?
Below are the relevant blocks of my (D3.js) code:
var rw = 17; // rect width
var rh = 17; // rect height
var rm = 2; // rect margin
var min_rows = Math.ceil(c * (rw + rm) / w );
var max_cols = ( Math.ceil(w / (rh + rm)) ) - 2;
...
.attr('x', function(d, i) {
var rem = i % max_cols;
if (i < max_cols){
return i * (rw + rm);
} else {
return rem * (rw + rm);
}
})
.attr('y', function(d, i) {
if (i < max_cols){
return rh + rm;
} else if (i < max_cols * 2) {
return 2 * (rh + rm);
} else if (i < max_cols * 3){
return 3 * (rh + rm);
} else {
return 4 * (rh + rm);
}
})
...
and in case this helps, here's the visual outcome:
Upvotes: 0
Views: 110
Reputation: 1976
I'd do it something like this:
var width = 323,
height = 400,
rw = 17,
rh = 17,
rm = 2,
num_cols = parseInt(width / (rw + rm)),
data = [
"#800", "#800", "#800", "#800", "#800", "#800", "#800",
"#800", "#800", "#800", "#800", "#800", "#800", "#800",
"#800", "#800", "#800", "#800", "#800", "#800", "#800",
"#800", "#800", "#800", "#800", "#800", "#800", "#800",
"#800", "#800", "#800", "#008", "#008", "#008", "#008",
"#008", "#008", "#008", "#008", "#008", "#008", "#008",
"#008", "#008", "#008", "#008", "#008", "#008", "#008",
"#008", "#008", "#008", "#008", "#880", "#880", "#880",
"#800", "#800", "#800", "#800", "#800", "#800", "#800",
"#800", "#800", "#800", "#008", "#008", "#008", "#008",
"#800", "#800", "#800", "#800", "#800", "#800", "#800",
"#800", "#800", "#800", "#008", "#008", "#008", "#008",
"#008", "#008", "#008", "#008", "#008", "#008", "#008",
"#008", "#008", "#008", "#008", "#008", "#008", "#008",
"#008", "#008", "#008", "#008", "#880", "#880", "#880",
"#800", "#800", "#800", "#800", "#800", "#800", "#800",
"#800", "#800", "#800", "#008", "#008", "#008", "#008",
"#008", "#008", "#008", "#008", "#008", "#008", "#008",
"#008", "#008", "#008", "#008", "#008", "#008", "#008",
"#008", "#008", "#008", "#008", "#880", "#880", "#880",
"#888", "#888", "#080", "#880", "#880", "#880", "#880",
"#880", "#880", "#880", "#880", "#880",
];
var svg = d3.select("#vis").append("svg")
.attr("width", width)
.attr("height", height);
var rects = d3.select("svg").selectAll("rect")
.data(data)
.enter().append("rect")
.attr("width", rw)
.attr("height", rh)
.attr("x", function(d, i) {
return (i % num_cols) * (rw + rm);
}).attr("y", function(d, i) {
return parseInt(i / num_cols) * (rh + rm);
}).style("fill", function(d) {
return d;
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="vis"></div>
Basically, the y
position, is just parseInt(i * (rh + rm) / num_cols)
and the x
position is just (i % num_cols) * (rw + rm)
;
Upvotes: 3