open-nomad/ui/app/components/gauge-chart.js

94 lines
2.1 KiB
JavaScript
Raw Normal View History

2020-05-09 00:26:18 +00:00
import Component from '@ember/component';
import { computed } from '@ember/object';
import { assert } from '@ember/debug';
import { guidFor } from '@ember/object/internals';
import { run } from '@ember/runloop';
import d3Shape from 'd3-shape';
import WindowResizable from 'nomad-ui/mixins/window-resizable';
import { classNames } from '@ember-decorators/component';
import classic from 'ember-classic-decorator';
@classic
@classNames('chart', 'gauge-chart')
export default class GaugeChart extends Component.extend(WindowResizable) {
value = null;
complement = null;
total = null;
chartClass = 'is-info';
width = 0;
height = 0;
@computed('value', 'complement', 'total')
get percent() {
2020-05-09 00:26:18 +00:00
assert(
'Provide complement OR total to GaugeChart, not both.',
this.complement != null || this.total != null
);
if (this.complement != null) {
return this.value / (this.value + this.complement);
}
return this.value / this.total;
}
2020-05-09 00:26:18 +00:00
@computed
get fillId() {
2020-05-09 00:26:18 +00:00
return `gauge-chart-fill-${guidFor(this)}`;
}
2020-05-09 00:26:18 +00:00
@computed
get maskId() {
2020-05-09 00:26:18 +00:00
return `gauge-chart-mask-${guidFor(this)}`;
}
2020-05-09 00:26:18 +00:00
@computed('width')
get radius() {
2020-05-09 00:26:18 +00:00
return this.width / 2;
}
2020-05-09 00:26:18 +00:00
weight = 4;
2020-05-09 00:26:18 +00:00
@computed('radius', 'weight')
get backgroundArc() {
2020-05-09 00:26:18 +00:00
const { radius, weight } = this;
const arc = d3Shape
.arc()
.outerRadius(radius)
.innerRadius(radius - weight)
.cornerRadius(weight)
.startAngle(-Math.PI / 2)
.endAngle(Math.PI / 2);
return arc();
}
2020-05-09 00:26:18 +00:00
@computed('radius', 'weight', 'percent')
get valueArc() {
2020-05-09 00:26:18 +00:00
const { radius, weight, percent } = this;
const arc = d3Shape
.arc()
.outerRadius(radius)
.innerRadius(radius - weight)
.cornerRadius(weight)
.startAngle(-Math.PI / 2)
.endAngle(-Math.PI / 2 + Math.PI * percent);
return arc();
}
2020-05-09 00:26:18 +00:00
didInsertElement() {
2021-12-28 14:45:20 +00:00
super.didInsertElement(...arguments);
2020-05-09 00:26:18 +00:00
this.updateDimensions();
}
2020-05-09 00:26:18 +00:00
updateDimensions() {
2020-05-26 21:13:29 +00:00
const width = this.element.querySelector('svg').clientWidth;
2020-05-09 00:26:18 +00:00
this.setProperties({ width, height: width / 2 });
}
2020-05-09 00:26:18 +00:00
windowResizeHandler() {
run.once(this, this.updateDimensions);
}
}