Skip to content

Instantly share code, notes, and snippets.

@djtal
Created December 16, 2015 16:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save djtal/b6f6e5c03ec747028f87 to your computer and use it in GitHub Desktop.
Save djtal/b6f6e5c03ec747028f87 to your computer and use it in GitHub Desktop.
<bc-pie-chart>
<div class="big">
<bc-pie-chart percent="85" type="donut"></bc-pie-chart>
<bc-pie-chart percent="65" type="donut"></bc-pie-chart>
<bc-pie-chart percent="35" type="donut"></bc-pie-chart>
<bc-pie-chart percent="10" type="donut"></bc-pie-chart>
<bc-pie-chart percent="15"></bc-pie-chart>
<bc-pie-chart percent="30"></bc-pie-chart>
<bc-pie-chart percent="60"></bc-pie-chart>
<bc-pie-chart percent="90"></bc-pie-chart>
</div>
<div class="little">
<bc-pie-chart percent="85" type="donut"></bc-pie-chart>
<bc-pie-chart percent="65" type="donut"></bc-pie-chart>
<bc-pie-chart percent="35" type="donut"></bc-pie-chart>
<bc-pie-chart percent="10" type="donut"></bc-pie-chart>
<bc-pie-chart percent="15"></bc-pie-chart>
<bc-pie-chart percent="30"></bc-pie-chart>
<bc-pie-chart percent="60"></bc-pie-chart>
<bc-pie-chart percent="90"></bc-pie-chart>
</div>
BC = {}
BC.registerElement = (tagName, definition = {}) ->
tagName = tagName.toLowerCase()
properties = rewriteFunctionsAsValues(definition)
defaultCSS = properties.defaultCSS ? "%t { display: block }"
delete properties.defaultCSS
installDefaultCSSForTagName(defaultCSS, tagName)
extendsTagName = properties.extendsTagName ? "div"
delete properties.extendsTagName
extendedPrototype = Object.getPrototypeOf(document.createElement(extendsTagName))
extendedPrototype.__super__ = extendedPrototype
prototype = Object.create(extendedPrototype, properties)
constructor = document.registerElement(tagName, prototype: prototype)
Object.defineProperty(prototype, "constructor", value: constructor)
constructor
installDefaultCSSForTagName = (defaultCSS, tagName) ->
styleElement = insertStyleElementForTagName(tagName)
styleElement.textContent = defaultCSS.replace(/%t/g, tagName)
insertStyleElementForTagName = (tagName) ->
element = document.createElement("style")
element.setAttribute("type", "text/css")
element.setAttribute("data-tag-name", tagName.toLowerCase())
document.head.insertBefore(element, document.head.firstChild)
element
rewriteFunctionsAsValues = (definition) ->
object = {}
for key, value of definition
object[key] = if typeof value is "function" then {value} else value
object
BC.registerElement "bc-pie-chart", do ->
DIAMETER = 64
SVG_TRANSFORM = "rotate(-90deg)"
defaultCSS: """
%t {
display: inline-block;
width: 1em;
height: 1em;
}
%t svg {
border-radius: 50%;
-webkit-transform: #{SVG_TRANSFORM};
-moz-transform: #{SVG_TRANSFORM};
-ms-transform: #{SVG_TRANSFORM};
-o-transform: #{SVG_TRANSFORM};
transform: #{SVG_TRANSFORM};
}
"""
percent:
get: ->
parseInt(@getAttribute("percent") ? 0, 10)
createdCallback: ->
@render()
attributeChangedCallback: ->
@render()
render: ->
@diameter = DIAMETER
@radius = @diameter / 2
@center = @radius
switch @getAttribute("type")
when "donut"
@strokeWidth = @radius * 0.3
@radius = @radius - @strokeWidth / 2
else
@strokeWidth = @diameter
@innerHTML = @generateHTML()
generatePieCSS: ->
"stroke-width: #{@strokeWidth};"
generateSliceCSS: ->
gap = Math.PI * 2 * @radius
length = @percent * (gap / 100)
@generatePieCSS() + "stroke-dasharray: #{length} #{gap};"
generateHTML: ->
"""
<svg viewBox="0 0 #{@diameter} #{@diameter}">
<circle class="pie" r="#{@radius}" cx="#{@center}" cy="#{@center}" style="#{@generatePieCSS()}" />
<circle class="slice" r="#{@radius}" cx="#{@center}" cy="#{@center}" style="#{@generateSliceCSS()}" />
</svg>
"""
bc-pie-chart {
circle {
&.pie {
fill: transparent;
stroke: rgba(0, 0, 0, 0.15);
}
&.slice {
fill: transparent;
stroke: #3cb371;
}
}
}
.big {
font-size: 80px;
}
.little {
font-size: 16px;
}
div {
padding: 15px;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment