mirror of
https://github.com/kemko/nomad.git
synced 2026-01-04 01:15:43 +03:00
Test coverage for line chart annotations
This commit is contained in:
@@ -271,16 +271,21 @@ export default class LineChart extends Component.extend(WindowResizable) {
|
||||
|
||||
if (!annotations || !annotations.length) return null;
|
||||
|
||||
return annotations.map(annotation => {
|
||||
let sortedAnnotations = annotations.sortBy(xProp);
|
||||
if (timeseries) {
|
||||
sortedAnnotations = sortedAnnotations.reverse();
|
||||
}
|
||||
|
||||
return sortedAnnotations.map(annotation => {
|
||||
const x = xScale(annotation[xProp]);
|
||||
const y = 0; // TODO: prevent overlap by staggering y-offset
|
||||
const time = this.xFormat(timeseries)(annotation[xProp]);
|
||||
const formattedX = this.xFormat(timeseries)(annotation[xProp]);
|
||||
return {
|
||||
annotation,
|
||||
style: `transform:translate(${x}px,${y}px)`,
|
||||
icon: iconFor[annotation.type],
|
||||
iconClass: iconClassFor[annotation.type],
|
||||
label: `${annotation.type} event at ${time}`,
|
||||
label: `${annotation.type} event at ${formattedX}`,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
</svg>
|
||||
<div data-test-annotations class="line-chart-annotations" style={{this.chartAnnotationsStyle}}>
|
||||
{{#each this.processedAnnotations as |annotation|}}
|
||||
<div class="chart-annotation {{annotation.iconClass}}" style={{annotation.style}}>
|
||||
<div data-test-annotation class="chart-annotation {{annotation.iconClass}}" style={{annotation.style}}>
|
||||
<button
|
||||
type="button"
|
||||
class="indicator"
|
||||
|
||||
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
103
ui/tests/integration/components/line-chart-test.js
Normal file
103
ui/tests/integration/components/line-chart-test.js
Normal file
@@ -0,0 +1,103 @@
|
||||
import { findAll, click, render } from '@ember/test-helpers';
|
||||
import { module, test } from 'qunit';
|
||||
import { setupRenderingTest } from 'ember-qunit';
|
||||
import hbs from 'htmlbars-inline-precompile';
|
||||
import sinon from 'sinon';
|
||||
import moment from 'moment';
|
||||
|
||||
const REF_DATE = new Date();
|
||||
|
||||
module('Integration | Component | line chart', function(hooks) {
|
||||
setupRenderingTest(hooks);
|
||||
|
||||
test('when a chart has annotations, they are rendered in order', async function(assert) {
|
||||
const annotations = [{ x: 2, type: 'info' }, { x: 1, type: 'error' }, { x: 3, type: 'info' }];
|
||||
this.setProperties({
|
||||
annotations,
|
||||
data: [{ x: 1, y: 1 }, { x: 10, y: 10 }],
|
||||
});
|
||||
|
||||
await render(hbs`
|
||||
<LineChart
|
||||
@xProp="x"
|
||||
@yProp="y"
|
||||
@data={{this.data}}
|
||||
@annotations={{this.annotations}} />
|
||||
`);
|
||||
|
||||
const sortedAnnotations = annotations.sortBy('x');
|
||||
findAll('[data-test-annotation]').forEach((annotation, idx) => {
|
||||
const datum = sortedAnnotations[idx];
|
||||
assert.equal(
|
||||
annotation.querySelector('button').getAttribute('title'),
|
||||
`${datum.type} event at ${datum.x}`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('when a chart has annotations and is timeseries, annotations are sorted reverse-chronologically', async function(assert) {
|
||||
const annotations = [
|
||||
{
|
||||
x: moment(REF_DATE)
|
||||
.add(2, 'd')
|
||||
.toDate(),
|
||||
type: 'info',
|
||||
},
|
||||
{
|
||||
x: moment(REF_DATE)
|
||||
.add(1, 'd')
|
||||
.toDate(),
|
||||
type: 'error',
|
||||
},
|
||||
{
|
||||
x: moment(REF_DATE)
|
||||
.add(3, 'd')
|
||||
.toDate(),
|
||||
type: 'info',
|
||||
},
|
||||
];
|
||||
this.setProperties({
|
||||
annotations,
|
||||
data: [{ x: 1, y: 1 }, { x: 10, y: 10 }],
|
||||
});
|
||||
|
||||
await render(hbs`
|
||||
<LineChart
|
||||
@xProp="x"
|
||||
@yProp="y"
|
||||
@timeseries={{true}}
|
||||
@data={{this.data}}
|
||||
@annotations={{this.annotations}} />
|
||||
`);
|
||||
|
||||
const sortedAnnotations = annotations.sortBy('x').reverse();
|
||||
findAll('[data-test-annotation]').forEach((annotation, idx) => {
|
||||
const datum = sortedAnnotations[idx];
|
||||
assert.equal(
|
||||
annotation.querySelector('button').getAttribute('title'),
|
||||
`${datum.type} event at ${moment(datum.x).format('MMM DD, HH:mm')}`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
test('clicking annotations calls the onAnnotationClick action with the annotation as an argument', async function(assert) {
|
||||
const annotations = [{ x: 2, type: 'info', meta: { data: 'here' } }];
|
||||
this.setProperties({
|
||||
annotations,
|
||||
data: [{ x: 1, y: 1 }, { x: 10, y: 10 }],
|
||||
click: sinon.spy(),
|
||||
});
|
||||
|
||||
await render(hbs`
|
||||
<LineChart
|
||||
@xProp="x"
|
||||
@yProp="y"
|
||||
@data={{this.data}}
|
||||
@annotations={{this.annotations}}
|
||||
@onAnnotationClick={{this.click}} />
|
||||
`);
|
||||
|
||||
await click('[data-test-annotation] button');
|
||||
assert.ok(this.click.calledWith(annotations[0]));
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user