github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/ui/app/components/gauge-chart.js (about) 1 import Component from '@ember/component'; 2 import { computed } from '@ember/object'; 3 import { assert } from '@ember/debug'; 4 import { guidFor } from '@ember/object/internals'; 5 import { once } from '@ember/runloop'; 6 import d3Shape from 'd3-shape'; 7 import WindowResizable from 'nomad-ui/mixins/window-resizable'; 8 import { classNames } from '@ember-decorators/component'; 9 import classic from 'ember-classic-decorator'; 10 11 @classic 12 @classNames('chart', 'gauge-chart') 13 export default class GaugeChart extends Component.extend(WindowResizable) { 14 value = null; 15 complement = null; 16 total = null; 17 chartClass = 'is-info'; 18 19 width = 0; 20 height = 0; 21 22 @computed('value', 'complement', 'total') 23 get percent() { 24 assert( 25 'Provide complement OR total to GaugeChart, not both.', 26 this.complement != null || this.total != null 27 ); 28 29 if (this.complement != null) { 30 return this.value / (this.value + this.complement); 31 } 32 33 return this.value / this.total; 34 } 35 36 @computed 37 get fillId() { 38 return `gauge-chart-fill-${guidFor(this)}`; 39 } 40 41 @computed 42 get maskId() { 43 return `gauge-chart-mask-${guidFor(this)}`; 44 } 45 46 @computed('width') 47 get radius() { 48 return this.width / 2; 49 } 50 51 weight = 4; 52 53 @computed('radius', 'weight') 54 get backgroundArc() { 55 const { radius, weight } = this; 56 const arc = d3Shape 57 .arc() 58 .outerRadius(radius) 59 .innerRadius(radius - weight) 60 .cornerRadius(weight) 61 .startAngle(-Math.PI / 2) 62 .endAngle(Math.PI / 2); 63 return arc(); 64 } 65 66 @computed('radius', 'weight', 'percent') 67 get valueArc() { 68 const { radius, weight, percent } = this; 69 70 const arc = d3Shape 71 .arc() 72 .outerRadius(radius) 73 .innerRadius(radius - weight) 74 .cornerRadius(weight) 75 .startAngle(-Math.PI / 2) 76 .endAngle(-Math.PI / 2 + Math.PI * percent); 77 return arc(); 78 } 79 80 didInsertElement() { 81 super.didInsertElement(...arguments); 82 this.updateDimensions(); 83 } 84 85 updateDimensions() { 86 const width = this.element.querySelector('svg').clientWidth; 87 this.setProperties({ width, height: width / 2 }); 88 } 89 90 windowResizeHandler() { 91 once(this, this.updateDimensions); 92 } 93 }