open-nomad/ui/app/components/chart-primitives/v-annotations.js

86 lines
2.2 KiB
JavaScript
Raw Normal View History

import Component from '@glimmer/component';
import { htmlSafe } from '@ember/template';
import { action } from '@ember/object';
const iconFor = {
error: 'cancel-circle-fill',
info: 'info-circle-fill',
};
const iconClassFor = {
error: 'is-danger',
info: '',
};
// TODO: This is what styleStringProperty looks like in the pure decorator world
function styleString(target, name, descriptor) {
if (!descriptor.get) throw new Error('styleString only works on getters');
const orig = descriptor.get;
descriptor.get = function() {
const styles = orig.apply(this);
let str = '';
if (styles) {
str = Object.keys(styles)
.reduce(function(arr, key) {
const val = styles[key];
arr.push(key + ':' + (typeof val === 'number' ? val.toFixed(2) + 'px' : val));
return arr;
}, [])
.join(';');
}
return htmlSafe(str);
};
return descriptor;
}
export default class ChartPrimitiveVAnnotations extends Component {
@styleString
get chartAnnotationsStyle() {
return {
height: this.args.height,
};
}
get processed() {
const { scale, prop, annotations, timeseries, format } = this.args;
if (!annotations || !annotations.length) return null;
let sortedAnnotations = annotations.sortBy(prop);
if (timeseries) {
sortedAnnotations = sortedAnnotations.reverse();
}
let prevX = 0;
let prevHigh = false;
return sortedAnnotations.map(annotation => {
const x = scale(annotation[prop]);
if (prevX && !prevHigh && Math.abs(x - prevX) < 30) {
prevHigh = true;
} else if (prevHigh) {
prevHigh = false;
}
const y = prevHigh ? -15 : 0;
const formattedX = format(timeseries)(annotation[prop]);
prevX = x;
return {
annotation,
style: htmlSafe(`transform:translate(${x}px,${y}px)`),
icon: iconFor[annotation.type],
iconClass: iconClassFor[annotation.type],
staggerClass: prevHigh ? 'is-staggered' : '',
label: `${annotation.type} event at ${formattedX}`,
};
});
}
@action
selectAnnotation(annotation) {
if (this.args.annotationClick) this.args.annotationClick(annotation);
}
}