1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | !function(SVGElement, document, bindings) {
|
7 | var ns = "http://www.w3.org/2000/svg"
|
8 | , xlinkNs = "http://www.w3.org/1999/xlink"
|
9 | , svg = document.createElementNS && document.createElementNS(ns, "svg").createSVGRect
|
10 | , proto = SVGElement && SVGElement.prototype
|
11 |
|
12 | if (!svg || !proto) {
|
13 | return
|
14 | }
|
15 |
|
16 | ;(
|
17 | "svg defs pattern g symbol use clipPath textPath marker mask stop linearGradient radialGradient " +
|
18 | "circle ellipse image line mesh path polygon polyline rect text tspan " +
|
19 | "filter feBlend feColorMatrix feComponentTransfer feComposite feConvolveMatrix feDiffuseLighting feDisplacementMap feDropShadow feFlood eFuncA feFuncB feFuncG feFuncR eGaussianBlur feImage feMerge feMergeNode feMorphology feOffset feSpecularLighting feTile feTurbulence"
|
20 | ).replace(/\w+/g, populateSvgElements)
|
21 |
|
22 |
|
23 | function polarToCartesian(centerX, centerY, radius, angleInDegrees) {
|
24 | var angleInRadians = (angleInDegrees - 90) * Math.PI / 180.0
|
25 | return {
|
26 | x: centerX + (radius * Math.cos(angleInRadians)),
|
27 | y: centerY + (radius * Math.sin(angleInRadians))
|
28 | }
|
29 | }
|
30 | function describeArc(x, y, radius, startAngle, endAngle) {
|
31 | var start = polarToCartesian(x, y, radius, endAngle)
|
32 | , end = polarToCartesian(x, y, radius, startAngle)
|
33 | , arcSweep = endAngle - startAngle <= 180 ? "0" : "1"
|
34 | , d = [
|
35 | "M", start.x, start.y,
|
36 | "A", radius, radius, 0, arcSweep, 0, end.x, end.y
|
37 | ].join(" ")
|
38 | return d
|
39 | }
|
40 | bindings.arc = function(el, startAngle, endAngle, radius, x, y) {
|
41 | var center = (y && x && radius) || el.viewportElement.viewBox.baseVal.width >> 1
|
42 |
|
43 | el.setAttribute("d", describeArc(
|
44 | x || center,
|
45 | y || center,
|
46 | radius || center,
|
47 | 3.6 * startAngle,
|
48 | 3.6 * endAngle
|
49 | ))
|
50 | }
|
51 | bindings.xlink = function(el, href) {
|
52 |
|
53 | el.setAttributeNS(xlinkNs, "xlink:href", href)
|
54 | }
|
55 | bindings.xlink.once=1
|
56 |
|
57 | function drawLine(node) {
|
58 | var length = node.getTotalLength()
|
59 | node.style.transition = node.style.WebkitTransition = "none"
|
60 | node.style.strokeDasharray = length + " " + length
|
61 | node.style.strokeDashoffset = length
|
62 |
|
63 |
|
64 | node.getBoundingClientRect()
|
65 | node.style.transition = node.style.WebkitTransition = "stroke-dashoffset 5s ease .5s"
|
66 | node.style.strokeDashoffset = "0"
|
67 | }
|
68 | var arch1 = "a? ? 0 1 0 ? -?".split("?")
|
69 | , arch2 = "a? ? 0 1 0 ? ?".split("?")
|
70 | bindings.svgLine = function(el, points, opts) {
|
71 | opts = opts || {}
|
72 | var i = 0
|
73 | , dataPoints = []
|
74 | , radius = opts.radius || 0
|
75 | , d = ["M" + (100 - radius), points[0]]
|
76 | if (radius) {
|
77 | d.push(arch1.join(radius), arch2.join(radius))
|
78 | }
|
79 |
|
80 | for (; ++i < points.length; ) {
|
81 | if (opts.smooth) {
|
82 | d.push("C" + (i * 100 + 50 - radius), points[i-1] + "," + (i * 100 + 50 + radius), points[i] + "," + (i * 100 + 100 - radius), points[i])
|
83 | } else {
|
84 | d.push("L" + (i * 100 + 100 - radius), points[i])
|
85 | }
|
86 | if (radius) {
|
87 | d.push(arch1.join(radius), arch2.join(radius))
|
88 | }
|
89 |
|
90 | }
|
91 | el.setAttribute("d", d.join(" "))
|
92 | drawLine(el)
|
93 | el.parentNode.append(dataPoints)
|
94 | }
|
95 | var svgToLastActive
|
96 | bindings.initChart = function(el) {
|
97 | El.on(el, "mouseout", function(e) {
|
98 | if (svgToLastActive && e.target == el) {
|
99 | El.cls(svgToLastActive, "is-active", svgToLastActive = null)
|
100 | }
|
101 | })
|
102 | }
|
103 |
|
104 | bindings.svgToLast = function(el) {
|
105 | El.on(el, "mouseover", function() {
|
106 | if (!svgToLastActive || el != el.parentNode.lastChild) {
|
107 | El.cls(svgToLastActive, "line-active", 0)
|
108 | El.append(el.parentNode, el)
|
109 | El.cls(el, "is-active", svgToLastActive = el)
|
110 | }
|
111 | })
|
112 | }
|
113 | bindings.svgToLast.once =
|
114 | bindings.initChart.once = 1
|
115 | function populateSvgElements(name) {
|
116 | El.cache[name] = document.createElementNS(ns, name)
|
117 | }
|
118 | }(this.SVGElement, document, El.bindings)
|
119 |
|