diff options
author | Marvin Borner | 2018-07-13 19:06:45 +0200 |
---|---|---|
committer | Marvin Borner | 2018-07-13 19:06:45 +0200 |
commit | 6fcfb7c04d32e1c8b26a312295bf7ac3ec2d2ad7 (patch) | |
tree | dbc87ef16fa01d5d99116de283592b8fe5e02944 /public/bower_components/morris.js/lib/morris.donut.coffee | |
parent | dfd839f27146df0ad0494e11734fc7d310c70ebf (diff) |
Fixed many permissions and began admin interface
Diffstat (limited to 'public/bower_components/morris.js/lib/morris.donut.coffee')
-rw-r--r-- | public/bower_components/morris.js/lib/morris.donut.coffee | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/public/bower_components/morris.js/lib/morris.donut.coffee b/public/bower_components/morris.js/lib/morris.donut.coffee new file mode 100644 index 0000000..e40314d --- /dev/null +++ b/public/bower_components/morris.js/lib/morris.donut.coffee @@ -0,0 +1,213 @@ +# Donut charts. +# +# @example +# Morris.Donut({ +# el: $('#donut-container'), +# data: [ +# { label: 'yin', value: 50 }, +# { label: 'yang', value: 50 } +# ] +# }); +class Morris.Donut extends Morris.EventEmitter + defaults: + colors: [ + '#0B62A4' + '#3980B5' + '#679DC6' + '#95BBD7' + '#B0CCE1' + '#095791' + '#095085' + '#083E67' + '#052C48' + '#042135' + ], + backgroundColor: '#FFFFFF', + labelColor: '#000000', + formatter: Morris.commas + resize: false + + # Create and render a donut chart. + # + constructor: (options) -> + return new Morris.Donut(options) unless (@ instanceof Morris.Donut) + @options = $.extend {}, @defaults, options + + if typeof options.element is 'string' + @el = $ document.getElementById(options.element) + else + @el = $ options.element + + if @el == null || @el.length == 0 + throw new Error("Graph placeholder not found.") + + # bail if there's no data + if options.data is undefined or options.data.length is 0 + return + + @raphael = new Raphael(@el[0]) + + if @options.resize + $(window).bind 'resize', (evt) => + if @timeoutId? + window.clearTimeout @timeoutId + @timeoutId = window.setTimeout @resizeHandler, 100 + + @setData options.data + + # Clear and redraw the chart. + redraw: -> + @raphael.clear() + + cx = @el.width() / 2 + cy = @el.height() / 2 + w = (Math.min(cx, cy) - 10) / 3 + + total = 0 + total += value for value in @values + + min = 5 / (2 * w) + C = 1.9999 * Math.PI - min * @data.length + + last = 0 + idx = 0 + @segments = [] + for value, i in @values + next = last + min + C * (value / total) + seg = new Morris.DonutSegment( + cx, cy, w*2, w, last, next, + @data[i].color || @options.colors[idx % @options.colors.length], + @options.backgroundColor, idx, @raphael) + seg.render() + @segments.push seg + seg.on 'hover', @select + seg.on 'click', @click + last = next + idx += 1 + + @text1 = @drawEmptyDonutLabel(cx, cy - 10, @options.labelColor, 15, 800) + @text2 = @drawEmptyDonutLabel(cx, cy + 10, @options.labelColor, 14) + + max_value = Math.max @values... + idx = 0 + for value in @values + if value == max_value + @select idx + break + idx += 1 + + setData: (data) -> + @data = data + @values = (parseFloat(row.value) for row in @data) + @redraw() + + # @private + click: (idx) => + @fire 'click', idx, @data[idx] + + # Select the segment at the given index. + select: (idx) => + s.deselect() for s in @segments + segment = @segments[idx] + segment.select() + row = @data[idx] + @setLabels(row.label, @options.formatter(row.value, row)) + + + + # @private + setLabels: (label1, label2) -> + inner = (Math.min(@el.width() / 2, @el.height() / 2) - 10) * 2 / 3 + maxWidth = 1.8 * inner + maxHeightTop = inner / 2 + maxHeightBottom = inner / 3 + @text1.attr(text: label1, transform: '') + text1bbox = @text1.getBBox() + text1scale = Math.min(maxWidth / text1bbox.width, maxHeightTop / text1bbox.height) + @text1.attr(transform: "S#{text1scale},#{text1scale},#{text1bbox.x + text1bbox.width / 2},#{text1bbox.y + text1bbox.height}") + @text2.attr(text: label2, transform: '') + text2bbox = @text2.getBBox() + text2scale = Math.min(maxWidth / text2bbox.width, maxHeightBottom / text2bbox.height) + @text2.attr(transform: "S#{text2scale},#{text2scale},#{text2bbox.x + text2bbox.width / 2},#{text2bbox.y}") + + drawEmptyDonutLabel: (xPos, yPos, color, fontSize, fontWeight) -> + text = @raphael.text(xPos, yPos, '') + .attr('font-size', fontSize) + .attr('fill', color) + text.attr('font-weight', fontWeight) if fontWeight? + return text + + resizeHandler: => + @timeoutId = null + @raphael.setSize @el.width(), @el.height() + @redraw() + + +# A segment within a donut chart. +# +# @private +class Morris.DonutSegment extends Morris.EventEmitter + constructor: (@cx, @cy, @inner, @outer, p0, p1, @color, @backgroundColor, @index, @raphael) -> + @sin_p0 = Math.sin(p0) + @cos_p0 = Math.cos(p0) + @sin_p1 = Math.sin(p1) + @cos_p1 = Math.cos(p1) + @is_long = if (p1 - p0) > Math.PI then 1 else 0 + @path = @calcSegment(@inner + 3, @inner + @outer - 5) + @selectedPath = @calcSegment(@inner + 3, @inner + @outer) + @hilight = @calcArc(@inner) + + calcArcPoints: (r) -> + return [ + @cx + r * @sin_p0, + @cy + r * @cos_p0, + @cx + r * @sin_p1, + @cy + r * @cos_p1] + + calcSegment: (r1, r2) -> + [ix0, iy0, ix1, iy1] = @calcArcPoints(r1) + [ox0, oy0, ox1, oy1] = @calcArcPoints(r2) + return ( + "M#{ix0},#{iy0}" + + "A#{r1},#{r1},0,#{@is_long},0,#{ix1},#{iy1}" + + "L#{ox1},#{oy1}" + + "A#{r2},#{r2},0,#{@is_long},1,#{ox0},#{oy0}" + + "Z") + + calcArc: (r) -> + [ix0, iy0, ix1, iy1] = @calcArcPoints(r) + return ( + "M#{ix0},#{iy0}" + + "A#{r},#{r},0,#{@is_long},0,#{ix1},#{iy1}") + + render: -> + @arc = @drawDonutArc(@hilight, @color) + @seg = @drawDonutSegment( + @path, + @color, + @backgroundColor, + => @fire('hover', @index), + => @fire('click', @index) + ) + + drawDonutArc: (path, color) -> + @raphael.path(path) + .attr(stroke: color, 'stroke-width': 2, opacity: 0) + + drawDonutSegment: (path, fillColor, strokeColor, hoverFunction, clickFunction) -> + @raphael.path(path) + .attr(fill: fillColor, stroke: strokeColor, 'stroke-width': 3) + .hover(hoverFunction) + .click(clickFunction) + + select: => + unless @selected + @seg.animate(path: @selectedPath, 150, '<>') + @arc.animate(opacity: 1, 150, '<>') + @selected = true + + deselect: => + if @selected + @seg.animate(path: @path, 150, '<>') + @arc.animate(opacity: 0, 150, '<>') + @selected = false |