diff --git a/ui/app/components/line-chart.js b/ui/app/components/line-chart.js index 07e2451a0..e7410683e 100644 --- a/ui/app/components/line-chart.js +++ b/ui/app/components/line-chart.js @@ -1,6 +1,7 @@ /* eslint-disable ember/no-observers */ import Component from '@ember/component'; import { computed } from '@ember/object'; +import { assert } from '@ember/debug'; import { observes } from '@ember-decorators/object'; import { computed as overridable } from 'ember-overridable-computed'; import { guidFor } from '@ember/object/internals'; @@ -52,6 +53,7 @@ export default class LineChart extends Component.extend(WindowResizable) { onAnnotationClick() {} xProp = null; yProp = null; + curve = 'linear'; timeseries = false; chartClass = 'is-primary'; @@ -101,6 +103,16 @@ export default class LineChart extends Component.extend(WindowResizable) { return this.yFormat()(y); } + @computed('curve') + get curveMethod() { + const mappings = { + linear: 'curveLinear', + stepAfter: 'curveStepAfter', + }; + assert(`Provided curve "${this.curve}" is not an allowed curve type`, mappings[this.curve]); + return mappings[this.curve]; + } + // Overridable functions that retrurn formatter functions xFormat(timeseries) { return timeseries ? d3TimeFormat.timeFormat('%b %d, %H:%M') : d3Format.format(','); @@ -238,12 +250,13 @@ export default class LineChart extends Component.extend(WindowResizable) { return this.width - this.yAxisWidth; } - @computed('data.[]', 'xScale', 'yScale') + @computed('data.[]', 'xScale', 'yScale', 'curveMethod') get line() { - const { xScale, yScale, xProp, yProp } = this; + const { xScale, yScale, xProp, yProp, curveMethod } = this; const line = d3Shape .line() + .curve(d3Shape[curveMethod]) .defined(d => d[yProp] != null) .x(d => xScale(d[xProp])) .y(d => yScale(d[yProp])); @@ -251,12 +264,13 @@ export default class LineChart extends Component.extend(WindowResizable) { return line(this.data); } - @computed('data.[]', 'xScale', 'yScale') + @computed('data.[]', 'xScale', 'yScale', 'curveMethod') get area() { - const { xScale, yScale, xProp, yProp } = this; + const { xScale, yScale, xProp, yProp, curveMethod } = this; const area = d3Shape .area() + .curve(d3Shape[curveMethod]) .defined(d => d[yProp] != null) .x(d => xScale(d[xProp])) .y0(yScale(0)) diff --git a/ui/stories/charts/line-chart.stories.js b/ui/stories/charts/line-chart.stories.js index eea8eb550..61ae27664 100644 --- a/ui/stories/charts/line-chart.stories.js +++ b/ui/stories/charts/line-chart.stories.js @@ -210,3 +210,34 @@ export let Annotations = () => { }, }; }; + +export let StepLine = () => { + return { + template: hbs` +
Line Chart with a Step Line
+
+ {{#if this.data}} + +

{{this.activeAnnotation.info}}

+ {{/if}} +
+ `, + context: { + data: DelayedArray.create([ + { x: 1, y: 5 }, + { x: 2, y: 1 }, + { x: 3, y: 2 }, + { x: 4, y: 2 }, + { x: 5, y: 9 }, + { x: 6, y: 3 }, + { x: 7, y: 4 }, + { x: 8, y: 1 }, + { x: 9, y: 5 }, + ]), + }, + }; +};