Files
d3-progress-meter/d3-progress-meter.html
Ronny Roeller e449889795 Add Polymer doc
2015-12-30 22:55:49 +01:00

190 lines
4.0 KiB
HTML

<link rel="import" href="../polymer/polymer.html">
<script src="../d3/d3.min.js"></script>
<!--
An animated chart that shows the progress as a meter
### Example
```html
<d3-progress-meter radius="100" percentage="0.35" current-text="70" goal-text="Goal: 200" type-text="transactions"></d3-progress-meter>
```
@demo demo/index.html
-->
<dom-module id="d3-progress-meter">
<template>
<style>
:host {
display: inline-block;
}
#background {
/* var(--paper-grey-300) */
fill: #e0e0e0;
}
#progress.low {
/* var(--paper-red-500) */
fill: #f44336;
}
#progress.medium {
/* var(--paper-yellow-500) */
fill: #ffeb3b;
}
#progress.high {
/* var(--paper-green-500) */
fill: #4caf50;
}
#current,#goal,#type {
font-family: Arial, sans-serif;
}
#current {
font-weight: bold;
}
#type {
margin-top: 5px;
text-align: center;
text-transform: uppercase;
white-space: nowrap;
overflow-x: hidden;
text-overflow: ellipsis;
}
</style>
<svg width$=[[diameter]] height$=[[diameter]]>
<g transform$=[[transform]]>
<g>
<path id="background"></path>
<path id="progress" class$=[[_progressLevel]]></path>
<text id="current" dy="-.2em" text-anchor="middle">[[currentText]]</text>
<text id="goal" dy="1.5em" text-anchor="middle">[[goalText]]</text>
</g>
</g>
</svg>
<div id="type">[[typeText]]</div>
</template>
</dom-module>
<script>
(function() {
Polymer({
is: 'd3-progress-meter',
properties: {
/**
* Amount of progress made (absolute number)
*/
progress: {
type: Number,
value: 0
},
/**
* Radius of the meter. The element will have twice the size of the radius
*/
radius: {
type: Number,
value: 100,
observer: '_radiusChanged'
},
/**
* Progress in percent
*/
percentage: {
type: Number,
observer: '_percentageChanged'
},
/**
* Large number showing current progress
*/
currentText: String,
/**
* Small text indicating when progress will be 100%
*/
goalText: String,
/**
* Bottom text describing for what progress is measured
*/
typeText: String,
diameter: {
type: Number,
computed: '_computeDiameter(radius)'
},
transform: {
type: String,
computed: '_computeTransform(radius)'
},
_progressLevel: {
type: Number,
computed: '_computeProgressLevel(percentage)'
}
},
_computeDiameter: function(radius) {
return 2 * radius;
},
_computeTransform: function(radius) {
return "translate(" + radius + ", " + radius + ")";
},
_computeProgressLevel: function(percentage) {
if (percentage <= .33) {
return 'low';
}
if (percentage <= .66) {
return 'medium';
}
return 'high';
},
_radiusChanged: function(oldVal, newVal) {
this._onRadiusChanged();
this._onPercentageChanged();
},
_percentageChanged: function(oldVal, newVal) {
this._onPercentageChanged();
},
_onRadiusChanged: function() {
this.progressArc = d3.svg.arc()
.startAngle(0)
.innerRadius(9/10 * this.radius)
.outerRadius(this.radius);
this.backgroundArc = d3.svg.arc()
.startAngle(0)
.innerRadius(0.825 * this.radius)
.outerRadius(0.85 * this.radius);
this.$.current.style.fontSize = this.radius/2 + 'px';
this.$.goal.style.fontSize = this.radius/5 + 'px';
this.$.type.style.fontSize = this.radius/4 + 'px';
this.$.type.style.width = 2 * this.radius + 'px';
this.$.background.setAttribute('d', this.backgroundArc.endAngle(2 * Math.PI)());
},
_onPercentageChanged: function() {
if (typeof this.percentage == 'undefined') {
return;
}
this.percentage = Math.min(1, Math.max(0, this.percentage));
var i = d3.interpolate(this.progress, this.percentage);
d3.select(this).transition().tween(this.$.progress, function() {
return function(t) {
this.progress = i(t);
this.$.progress.setAttribute('d', this.progressArc.endAngle(2 * Math.PI * this.progress)());
}.bind(this);
}.bind(this));
}
});
})();
</script>