D3を書くときの小さいTips
marginの扱いがダルい
div > svg > g
としてその中にいろいろ追加していく、というのがベストだと思っていますが、marginの取り扱いが割とだるい。よくあるのが
d3.select('div').appned('svg') .attr('width', width + margin * 2) .attr('height', height + margin * 2) .append('g') .attr('width', width).attr('height', height) .attr('transform', 'translate('+margin+','+margin+')')
とかだと思うけど、この時点で割とイライラしているのでMargin
作った
class Margin constructor: (args...)-> @top = 0 @right = 0 @bottom = 0 @right = 0 @width = 0 @height = 0 if args.length is 1 @top = @right = @bottom = @left = args[0] else if args.length is 2 @top = @bottom = args[0] @right = @left = args[1] else if args.length is 3 @top = args[0] @bottom = args[2] @right = @left = args[1] else if args.length is 4 [@top, @right, @bottom, @left] = args @width = @right + @left @height = @top + @bottom toString: ()-> return [@top, @right, @bottom, @left].map((d)-> "#{d}px").join(" ")
これを使うとCSSと同じようにmarginを指定できます。
var margin = new Margin(100, 50, 30); // 上100、下30、左右50 d3.select('div').appned('svg') .attr('width', width + margin.width) .attr('height', height + margin.height) .append('g') .attr('width', width).attr('height', height) .attr('transform', 'translate('+margin.left+','+margin.top+')');
attrを無限に書くのがダルい
よくあるのが
circle = svg.append('circle') .attr('cx', 10) .attr('cy', 10) .attr('r', 5) .attr('fill', 'grey') .attr('stroke', 'blue') .attr('stroke-width', 3);
これにstyleも同じようにするのがうんざりする
なので、attrs
を作った
attrs = (obj)-> ()-> for k, v of obj this.attr(k, v) this
これを使うと
circle = svg.append('circle').call(attrs({ cx: 10, cy: 10, r: 5, fill: 'grey', stroke: 'blue', 'stroke-width': 3 }))
オブジェクトで定義できるので楽です。(.attr()
って無限に書かなくても済むし、なにより、この設定を変数化してもっておける!わーい