class MaterialRaingular.d3.Directives.MrD3StackedBar extends AngularDirectiveModel
@inject('$parse','$element') initialize: -> @parent = @$element.parent().controller('mrD3BarChart') @direction = if @parent then 'vertical' else 'horizontal' @parent ?= @$element.parent().controller('mrD3HorizontalBarChart') @bar = d3.select(@$element[0]) @label = @$parse @$element.attr('mr-d3-label') @stacked = @$parse @$element.attr('mr-d3-stacked') @texts = [] @$scope.$watch @label.bind(@), @adjustBars.bind(@) @$scope.$watch @size.bind(@), @adjustBars.bind(@) @$scope.$watch @stacked.bind(@), @adjustBars.bind(@) @$scope.$on '$destroy', @removeText.bind(@) @adjustBars() bars: -> @bar.selectAll('rect') size: -> if @direction == 'vertical' then @bar.attr('height') else @bar.attr('width') rawSize: -> (@bars().nodes().map (rect) => d3.select(rect).attr('raw-size')).sum() removeText: -> text.remove() for text in @texts @adjustBars() adjustBars: -> @bar.attr('raw-size',@rawSize() || 0) @bar.attr('label', @label(@$scope)) @parent.adjustBars() width = @bar.attr('width') height = @bar.attr('height') x = @bar.attr('x') y = @bar.attr('y') usedSpace = 0 key = @bar.node().$$hashKey?.replace(':','_') #TODO: Not Dependable fill = null fillRegex = /.*\(([0-9]+\, [0-9]+\, [0-9]+).*\)/ @parent.holder.selectAll("text.bar.#{key}").remove() length = @bars().nodes().length nonzero = 0 for rect,i in @bars().nodes() nonzero += 1 if d3.select(rect).attr('raw-size') > 0 for rect,i in @bars().nodes() bar = d3.select(rect) bar.attr('class',"#{i} bar") fill = fill || bar.attr('fill')?.match(fillRegex)?[1] || '0,0,0' bar.attr('fill',"rgba(#{fill},#{1 - i/length})") parentLabel = rect.parentNode.attributes['label'].value.slice(-2) bar.on('mouseover', @_mouseOver.bind(null,rect,i,parentLabel)) .on('mouseout', @_mouseOut.bind(null,rect,i,parentLabel)) .on('mousemove', @_mouseMove.bind(null,rect,i,parentLabel)) text = @parent.holder.append('text') .style("text-anchor","middle") .style("fill", "#FFF") .attr('class',"#{i} bar text #{key}") .text(bar.attr('label')) @texts.push(text) if @direction == 'vertical' ratio = height / @bar.attr('raw-size') barHeight = ratio * bar.attr('raw-size') bar.attr('height',barHeight || 0) if @stacked(@$scope) usedSpace += barHeight || 0 bar.attr('x',x) bar.attr('width',width || 0) bar.attr('y',@parent.height() - usedSpace) else barWidth = width / nonzero bar.attr('width', barWidth) bar.attr('x', parseFloat(x) + usedSpace) bar.attr('y', @parent.height() - barHeight) usedSpace += barWidth if barHeight > 0 text.attr('x', -parseFloat(bar.attr('y')) - parseFloat(bar.attr('height'))/2) .attr('y',parseFloat(bar.attr('x')) + parseFloat(bar.attr('width'))/2 + 5) .attr('transform','rotate(-90)') bbox = text.node().getBBox() if (bbox.width > barHeight) || (bbox.height > width || barWidth) text.style('display','none') else text.style('pointer-events', 'none').style('display', 'block') else ratio = width / @bar.attr('raw-size') barWidth = ratio * bar.attr('raw-size') bar.attr('width',barWidth || 0) if @stacked(@$scope) bar.attr('y',y) bar.attr('height',height || 0) bar.attr('x',usedSpace) usedSpace += barWidth || 0 else barHeight = height / nonzero bar.attr('y',parseFloat(y) + usedSpace) bar.attr('height',barHeight) bar.attr('x',0) usedSpace += barHeight if barWidth > 0 text.attr('x', parseFloat(bar.attr('width' || 0))/2 + parseFloat(bar.attr('x'))) .attr('y',parseFloat(bar.attr('y')) + parseFloat(bar.attr('height'))/2 + 5) bbox = text.node().getBBox() if bbox.width > barWidth || (bbox.height > height || barHeight) text.style('display', 'none') else text.style('pointer-events', 'none').style('display', 'block') _mouseOver: (d,i,parentLabel) -> d3.select("#tip-table-" + parentLabel) .classed('hidden', false) .style('left', (d3.event.pageX + 10) + 'px') .style('top', (d3.event.pageY + 10) + 'px') .select("#tip-" + i).classed('hidden', false) _mouseMove: (d,i,parentLabel) -> d3.select("#tip-table-" + parentLabel) .style('left', (d3.event.pageX + 10) + 'px') .style('top', (d3.event.pageY + 10) + 'px') _mouseOut: (d,i,parentLabel) -> d3.select("#tip-table-" + parentLabel) .classed('hidden', true) .select("#tip-" + i).classed('hidden', true)