|
|
|
@ -1,5 +1,5 @@
|
|
|
|
|
import { ChartwerkPod, VueChartwerkPodMixin, TimeFormat, CrosshairOrientation, BrushOrientation, yAxisOrientation } from '@chartwerk/core'; |
|
|
|
|
import { LineTimeSerie, LineOptions, MouseObj } from './types'; |
|
|
|
|
import { LineTimeSerie, LineOptions, MouseObj, AreaType } from './types'; |
|
|
|
|
import { Markers } from './components/markers'; |
|
|
|
|
import { Segments } from './components/segments'; |
|
|
|
|
|
|
|
|
@ -14,14 +14,9 @@ const METRIC_CIRCLE_RADIUS = 1.5;
|
|
|
|
|
const CROSSHAIR_CIRCLE_RADIUS = 3; |
|
|
|
|
const CROSSHAIR_BACKGROUND_RAIDUS = 9; |
|
|
|
|
const CROSSHAIR_BACKGROUND_OPACITY = 0.3; |
|
|
|
|
|
|
|
|
|
type Generator = d3.Line<[number, number]> | d3.Area<[number, number]>; |
|
|
|
|
|
|
|
|
|
class LinePod extends ChartwerkPod<LineTimeSerie, LineOptions> { |
|
|
|
|
lineGenerator = null; |
|
|
|
|
areaGenerator = null; |
|
|
|
|
lineGeneratorY1 = null; |
|
|
|
|
areaGeneratorY1 = null; |
|
|
|
|
|
|
|
|
|
private _markersLayer: Markers = null; |
|
|
|
|
private _segmentsLayer: Segments = null; |
|
|
|
|
|
|
|
|
@ -40,15 +35,14 @@ class LinePod extends ChartwerkPod<LineTimeSerie, LineOptions> {
|
|
|
|
|
this.clearAllMetrics(); |
|
|
|
|
|
|
|
|
|
this.updateCrosshair(); |
|
|
|
|
this.initLineGenerator(); |
|
|
|
|
this.initAreaGenerator(); |
|
|
|
|
|
|
|
|
|
if(!this.series.isSeriesAvailable) { |
|
|
|
|
this.renderNoDataPointsMessage(); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
for(const serie of this.series.visibleSeries) { |
|
|
|
|
this._renderMetric(serie); |
|
|
|
|
const generator = this.getRenderGenerator(serie.renderArea, serie.yOrientation); |
|
|
|
|
this._renderMetric(serie, generator); |
|
|
|
|
} |
|
|
|
|
if(this._markersConf !== undefined) { |
|
|
|
|
this._markersLayer = new Markers(this.d3Node, this._markersConf, this.state, this.margin); |
|
|
|
@ -65,31 +59,28 @@ class LinePod extends ChartwerkPod<LineTimeSerie, LineOptions> {
|
|
|
|
|
this._markersLayer?.clear(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
initLineGenerator(): void { |
|
|
|
|
this.lineGenerator = d3.line() |
|
|
|
|
.x(d => this.state.xScale(d[0])) |
|
|
|
|
.y(d => this.state.yScale(d[1])); |
|
|
|
|
this.lineGeneratorY1 = d3.line() |
|
|
|
|
.x(d => this.state.xScale(d[0])) |
|
|
|
|
.y(d => this.state.y1Scale(d[1])); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
initAreaGenerator(): void { |
|
|
|
|
this.areaGenerator = d3.area() |
|
|
|
|
getRenderGenerator(renderArea: AreaType, yOrientation: yAxisOrientation): Generator { |
|
|
|
|
const yScale = yOrientation === yAxisOrientation.LEFT ? this.state.yScale : this.state.y1Scale; |
|
|
|
|
switch(renderArea) { |
|
|
|
|
case AreaType.NONE: |
|
|
|
|
// return line generator
|
|
|
|
|
return d3.line() |
|
|
|
|
.x(d => this.state.xScale(d[0])) |
|
|
|
|
.y1(d => this.state.yScale(d[1])) |
|
|
|
|
.y0(d => this.height); |
|
|
|
|
this.areaGeneratorY1 = d3.area() |
|
|
|
|
.y(d => yScale(d[1])); |
|
|
|
|
case AreaType.ABOVE: |
|
|
|
|
return d3.area() |
|
|
|
|
.x(d => this.state.xScale(d[0])) |
|
|
|
|
.y1(d => this.state.y1Scale(d[1])) |
|
|
|
|
.y0(d => this.height); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
getRenderGenerator(renderArea: boolean, yOrientation: yAxisOrientation): any { |
|
|
|
|
if(renderArea) { |
|
|
|
|
return yOrientation === yAxisOrientation.LEFT ? this.areaGenerator : this.areaGeneratorY1; |
|
|
|
|
.y0(this.height) |
|
|
|
|
.y1(d => yScale(d[1])); |
|
|
|
|
case AreaType.BELOW: |
|
|
|
|
return d3.area() |
|
|
|
|
.x(d => this.state.xScale(d[0])) |
|
|
|
|
.y0(d => yScale(d[1])) |
|
|
|
|
.y1(0); |
|
|
|
|
default: |
|
|
|
|
throw new Error(`Unknown type of renderArea: ${renderArea}`); |
|
|
|
|
} |
|
|
|
|
return yOrientation === yAxisOrientation.LEFT ? this.lineGenerator : this.lineGeneratorY1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_renderDots(serie: LineTimeSerie): void { |
|
|
|
@ -105,9 +96,9 @@ class LinePod extends ChartwerkPod<LineTimeSerie, LineOptions> {
|
|
|
|
|
.attr('cy', d => this.state.getYScaleByOrientation(serie.yOrientation)(d[1])); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_renderLines(serie: LineTimeSerie): void { |
|
|
|
|
const fillColor = serie.renderArea ? serie.color : 'none'; |
|
|
|
|
const fillOpacity = serie.renderArea ? 0.5 : 'none'; |
|
|
|
|
_renderLines(serie: LineTimeSerie, generator: Generator): void { |
|
|
|
|
const fillColor = serie.renderArea !== AreaType.NONE ? serie.color : 'none'; |
|
|
|
|
const fillOpacity = serie.renderArea !== AreaType.NONE ? 0.5 : 'none'; |
|
|
|
|
|
|
|
|
|
this.metricContainer |
|
|
|
|
.append('path') |
|
|
|
@ -120,12 +111,12 @@ class LinePod extends ChartwerkPod<LineTimeSerie, LineOptions> {
|
|
|
|
|
.attr('stroke-opacity', 0.7) |
|
|
|
|
.attr('pointer-events', 'none') |
|
|
|
|
.style('stroke-dasharray', serie.dashArray) |
|
|
|
|
.attr('d', this.getRenderGenerator(serie.renderArea, serie.yOrientation)); |
|
|
|
|
.attr('d', generator); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_renderMetric(serie: LineTimeSerie): void { |
|
|
|
|
_renderMetric(serie: LineTimeSerie, generator: Generator): void { |
|
|
|
|
if(serie.renderLines === true) { |
|
|
|
|
this._renderLines(serie); |
|
|
|
|
this._renderLines(serie, generator); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if(serie.renderDots === true) { |
|
|
|
@ -490,4 +481,4 @@ export const VueChartwerkLinePod = {
|
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
export { LineTimeSerie, LineOptions, TimeFormat, LinePod }; |
|
|
|
|
export { LineTimeSerie, LineOptions, TimeFormat, LinePod, AreaType }; |
|
|
|
|