krivaten
5/25/2017 - 4:31 PM

Coin Chart

Coin Chart

{
  "version": "0.12.1",
  "EmberENV": {
    "FEATURES": {}
  },
  "options": {
    "use_pods": false,
    "enable-testing": false
  },
  "dependencies": {
    "jquery": "https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.3/jquery.js",
    "ember": "2.12.0",
    "ember-template-compiler": "2.12.0",
    "ember-testing": "2.12.0"
  },
  "addons": {
    "ember-data": "2.12.1"
  }
}
<defs>
  <pattern id="tile-icon-image" x="0" y="0" height="100%" width="100%" patternUnits="userSpaceOnUse" viewBox="0 0 800 800">
    <image xlink:href="https://unsplash.it/800?image=890"></image>
  </pattern>
  
  <linearGradient id="fadeGrad" y2="1" x2="0">
    <stop offset="0" stop-color="#9966CC" stop-opacity="0"/>
    <stop offset="1" stop-color="#9966CC" stop-opacity="0.75"/>
  </linearGradient>
</defs>

<circle cx="50" cy="50" r="39" fill="url(#tile-icon-image)"></circle>
<circle cx="50" cy="50" r="39" fill="url(#fadeGrad)"></circle>
<svg width="400px" height="400px" viewBox="0 0 100 100" class="coin-chart">
  {{yield}}
	<g class="coin-chart-fill" transform="rotate(90 50 50)">
    <circle cx="50" cy="50" r="{{radius}}" stroke-width="{{stroke}}" fill="transparent" stroke="#f2f2f2" class="coin-chart-background"></circle>
    <circle cx="50" cy="50" r="{{radius}}" stroke-width="{{stroke}}" fill="transparent" stroke="{{percentColor}}" class="coin-chart-segment" stroke-dasharray="{{percentCompleteStroke}}"></circle>
  </g>

  <g class="coin-chart-indicator" transform="rotate({{expectedPercentRotation}} 50 50)">
    <circle cx="50" cy="50" r="50" fill="transparent" stroke="transparent" class="coin-chart-rail"></circle>
    <polygon points="50 91 54 99 46 99" fill="#000000" stroke-width="0.5" class="coin-chart-tick"></polygon>
  </g>
</svg>
<h1>A Generic Tile Coin</h1>

{{input value=percentComplete placeholder="Percent Complete" type="number"}}
{{input value=expectedPercent placeholder="Expected Percent" type="number"}}

{{#tile-coin
  type="donut"
	percentComplete=percentComplete
  expectedPercent=expectedPercent}}
  {{tile-icon-content text=textContent}}
{{/tile-coin}}

{{tile-coin
  type="pie"
	percentComplete=percentComplete
  expectedPercent=expectedPercent}}
.coin-chart-segment {
  transition: stroke-dasharray 0.75s ease;
}
.coin-chart-indicator {
  transition: transform 0.75s ease;
}

.tile-icon {
  position: relative;
}

.tile-icon-content-text {
  font-family: -apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen-Sans,Ubuntu,Cantarell,"Helvetica Neue",sans-serif;
  color: white;
  font-weight: 800;
  text-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
}

.svg-big,
.svg-small {
  margin: 0;
  padding: 0;
}

.svg-big {
  font-size: 40px;
}
.svg-small {
  font-size: 14px;
}
import Ember from 'ember';

export default Ember.Controller.extend({
  percentComplete: 60,
  expectedPercent: 65
});
import Ember from 'ember';

export default Ember.Component.extend({
  tagName: 'g'
});
import Ember from 'ember';

const {
  get,
  computed
} = Ember;

export default Ember.Component.extend({
  class: ['tile-icon'],
  percentComplete: 100,
  expectedPercent: 40,
  
  type: '2',
  
  percentColor: computed('percentComplete', function() {
    const percentComplete = get(this, 'percentComplete');
    let color;
    
		if (percentComplete > 50) {
      color = '#99CC00';
    } else if (percentComplete > 25) {
      color = '#FFCC00';
    } else {
      color = '#CC3300';
    }
    
    return color;
  }),
  
  radius: computed('type', function() {
    const type = get(this, 'type');
    let radius;
    
    switch (type) {
      case 'donut':
      	radius = 45;
        break;
      case 'pie':
        radius = 25;
        break;
    }
        
    return radius;
  }),
  
  stroke: computed('type', function() {
    const type = get(this, 'type');
    let stroke;
    
    switch (type) {
      case 'donut':
      	stroke = 10;
        break;
      case 'pie':
        stroke = 50;
        break;
    }
        
    return stroke;
  }),
  
  percentCompleteStroke: computed('percentComplete', function() {
    let percent = get(this, 'percentComplete') || 0;
    let radius = get(this, 'radius');
    let length = (2 * Math.PI) * radius;
  
    if (percent > 100) percent = 100;
    
    let result = (percent / 100) * length;    

    return result + ' ' + length;
  }),
  
  expectedPercentRotation: computed('expectedPercent', function() {
    let expectedPercent = get(this, 'expectedPercent');
    
    if (expectedPercent > 100) expectedPercent = 0;
    
    return 360 * (expectedPercent * 0.01);
  })
});