-
Notifications
You must be signed in to change notification settings - Fork 2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #10069 from hashicorp/f-ui/line-chart-decomposed
UI: Line chart decomposed
- Loading branch information
Showing
20 changed files
with
470 additions
and
415 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<defs> | ||
<linearGradient x1="0" x2="0" y1="0" y2="1" class="{{this.colorClass}}" id="{{this.fillId}}"> | ||
<stop class="start" offset="0%" /> | ||
<stop class="end" offset="100%" /> | ||
</linearGradient> | ||
<clipPath id="{{this.maskId}}"> | ||
<path class="fill" d="{{this.area}}" /> | ||
</clipPath> | ||
</defs> | ||
<g class="area {{this.colorClass}}" ...attributes> | ||
<path class="line" d="{{this.line}}" /> | ||
<rect class="fill" x="0" y="0" width="{{@width}}" height="{{@height}}" fill="url(#{{this.fillId}})" clip-path="url(#{{this.maskId}})" /> | ||
</g> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import Component from '@glimmer/component'; | ||
import { default as d3Shape, area, line } from 'd3-shape'; | ||
import uniquely from 'nomad-ui/utils/properties/uniquely'; | ||
|
||
export default class ChartPrimitiveArea extends Component { | ||
get colorClass() { | ||
return this.args.colorClass || `${this.args.colorScale}-${this.args.index}`; | ||
} | ||
|
||
@uniquely('area-mask') maskId; | ||
@uniquely('area-fill') fillId; | ||
|
||
get line() { | ||
const { xScale, yScale, xProp, yProp, curveMethod } = this.args; | ||
|
||
const builder = line() | ||
.curve(d3Shape[curveMethod]) | ||
.defined(d => d[yProp] != null) | ||
.x(d => xScale(d[xProp])) | ||
.y(d => yScale(d[yProp])); | ||
|
||
return builder(this.args.data); | ||
} | ||
|
||
get area() { | ||
const { xScale, yScale, xProp, yProp, curveMethod } = this.args; | ||
|
||
const builder = area() | ||
.curve(d3Shape[curveMethod]) | ||
.defined(d => d[yProp] != null) | ||
.x(d => xScale(d[xProp])) | ||
.y0(yScale(0)) | ||
.y1(d => yScale(d[yProp])); | ||
|
||
return builder(this.args.data); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
<div data-test-annotations class="line-chart-annotations" style={{this.chartAnnotationsStyle}} ...attributes> | ||
{{#each this.processed key=@key as |annotation|}} | ||
<div data-test-annotation class="chart-annotation {{annotation.iconClass}} {{annotation.staggerClass}}" style={{annotation.style}}> | ||
<button | ||
type="button" | ||
title={{annotation.label}} | ||
class="indicator {{if (or | ||
(and @key (eq-by @key annotation.annotation this.activeAnnotation)) | ||
(and (not @key) (eq annotation.annotation this.activeAnnotation)) | ||
) "is-active"}}" | ||
{{on "click" (fn this.selectAnnotation annotation.annotation)}}> | ||
{{x-icon annotation.icon}} | ||
</button> | ||
<div class="line" /> | ||
</div> | ||
{{/each}} | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
import Component from '@glimmer/component'; | ||
import { htmlSafe } from '@ember/template'; | ||
import { action } from '@ember/object'; | ||
import styleString from 'nomad-ui/utils/properties/glimmer-style-string'; | ||
|
||
const iconFor = { | ||
error: 'cancel-circle-fill', | ||
info: 'info-circle-fill', | ||
}; | ||
|
||
const iconClassFor = { | ||
error: 'is-danger', | ||
info: '', | ||
}; | ||
|
||
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); | ||
} | ||
} |
Oops, something went wrong.