|
|
@ -1,7 +1,9 @@ |
|
|
|
import VueChartwerkPodMixin from './VueChartwerkPodMixin'; |
|
|
|
import VueChartwerkPodMixin from './VueChartwerkPodMixin'; |
|
|
|
import { PodState } from './state'; |
|
|
|
import { PodState } from './state'; |
|
|
|
import { Grid } from './components/grid'; |
|
|
|
import { Grid } from './components/grid'; |
|
|
|
|
|
|
|
|
|
|
|
import { CoreSeries } from 'models/series'; |
|
|
|
import { CoreSeries } from 'models/series'; |
|
|
|
|
|
|
|
import { CoreOptions } from 'models/options'; |
|
|
|
|
|
|
|
|
|
|
|
import styles from './css/style.css'; |
|
|
|
import styles from './css/style.css'; |
|
|
|
|
|
|
|
|
|
|
@ -9,7 +11,6 @@ import { |
|
|
|
Margin, |
|
|
|
Margin, |
|
|
|
CoreSerie, |
|
|
|
CoreSerie, |
|
|
|
Options, |
|
|
|
Options, |
|
|
|
TickOrientation, |
|
|
|
|
|
|
|
TimeFormat, |
|
|
|
TimeFormat, |
|
|
|
BrushOrientation, |
|
|
|
BrushOrientation, |
|
|
|
AxisFormat, |
|
|
|
AxisFormat, |
|
|
@ -21,6 +22,7 @@ import { |
|
|
|
ScrollPanOrientation, |
|
|
|
ScrollPanOrientation, |
|
|
|
ScrollPanDirection, |
|
|
|
ScrollPanDirection, |
|
|
|
AxisOption, |
|
|
|
AxisOption, |
|
|
|
|
|
|
|
AxesOptions, |
|
|
|
} from './types'; |
|
|
|
} from './types'; |
|
|
|
import { uid } from './utils'; |
|
|
|
import { uid } from './utils'; |
|
|
|
import { palette } from './colors'; |
|
|
|
import { palette } from './colors'; |
|
|
@ -43,77 +45,11 @@ const DEFAULT_MARGIN: Margin = { top: 30, right: 20, bottom: 20, left: 30 }; |
|
|
|
const DEFAULT_TICK_COUNT = 4; |
|
|
|
const DEFAULT_TICK_COUNT = 4; |
|
|
|
const DEFAULT_TICK_SIZE = 2; |
|
|
|
const DEFAULT_TICK_SIZE = 2; |
|
|
|
const MILISECONDS_IN_MINUTE = 60 * 1000; |
|
|
|
const MILISECONDS_IN_MINUTE = 60 * 1000; |
|
|
|
const DEFAULT_SCROLL_PAN_STEP = 50; |
|
|
|
|
|
|
|
const DEFAULT_OPTIONS: Options = { |
|
|
|
|
|
|
|
confidence: 0, |
|
|
|
|
|
|
|
timeInterval: { |
|
|
|
|
|
|
|
timeFormat: TimeFormat.MINUTE |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
tickFormat: { |
|
|
|
|
|
|
|
xAxis: '%H:%M', |
|
|
|
|
|
|
|
xTickOrientation: TickOrientation.HORIZONTAL |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
zoomEvents: { |
|
|
|
|
|
|
|
mouse: { |
|
|
|
|
|
|
|
zoom: { |
|
|
|
|
|
|
|
isActive: true, |
|
|
|
|
|
|
|
keyEvent: KeyEvent.MAIN, |
|
|
|
|
|
|
|
orientation: BrushOrientation.HORIZONTAL |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
pan: { |
|
|
|
|
|
|
|
isActive: true, |
|
|
|
|
|
|
|
keyEvent: KeyEvent.SHIFT, |
|
|
|
|
|
|
|
orientation: PanOrientation.HORIZONTAL |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
doubleClick: { |
|
|
|
|
|
|
|
isActive: true, |
|
|
|
|
|
|
|
keyEvent: KeyEvent.MAIN, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
scroll: { |
|
|
|
|
|
|
|
zoom: { |
|
|
|
|
|
|
|
isActive: true, |
|
|
|
|
|
|
|
keyEvent: KeyEvent.MAIN, |
|
|
|
|
|
|
|
orientation: PanOrientation.BOTH, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
pan: { |
|
|
|
|
|
|
|
isActive: false, |
|
|
|
|
|
|
|
keyEvent: KeyEvent.SHIFT, |
|
|
|
|
|
|
|
panStep: DEFAULT_SCROLL_PAN_STEP, |
|
|
|
|
|
|
|
orientation: ScrollPanOrientation.HORIZONTAL, |
|
|
|
|
|
|
|
direction: ScrollPanDirection.BOTH, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
axis: { |
|
|
|
|
|
|
|
x: { |
|
|
|
|
|
|
|
isActive: true, |
|
|
|
|
|
|
|
ticksCount: DEFAULT_TICK_COUNT, |
|
|
|
|
|
|
|
format: AxisFormat.TIME |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
y: { |
|
|
|
|
|
|
|
isActive: true, |
|
|
|
|
|
|
|
ticksCount: DEFAULT_TICK_COUNT, |
|
|
|
|
|
|
|
format: AxisFormat.NUMERIC |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
y1: { |
|
|
|
|
|
|
|
isActive: false, |
|
|
|
|
|
|
|
ticksCount: DEFAULT_TICK_COUNT, |
|
|
|
|
|
|
|
format: AxisFormat.NUMERIC |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
crosshair: { |
|
|
|
|
|
|
|
orientation: CrosshairOrientation.VERTICAL, |
|
|
|
|
|
|
|
color: 'red' |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
renderTicksfromTimestamps: false, |
|
|
|
|
|
|
|
renderLegend: true, |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
abstract class ChartwerkPod<T extends CoreSerie, O extends Options> { |
|
|
|
abstract class ChartwerkPod<T extends CoreSerie, O extends Options> { |
|
|
|
|
|
|
|
|
|
|
|
protected coreSeries: CoreSeries<T>; |
|
|
|
protected coreSeries: CoreSeries<T>; |
|
|
|
protected options: O; |
|
|
|
protected coreOptions: CoreOptions<O>; |
|
|
|
|
|
|
|
|
|
|
|
protected d3Node?: d3.Selection<HTMLElement, unknown, null, undefined>; |
|
|
|
protected d3Node?: d3.Selection<HTMLElement, unknown, null, undefined>; |
|
|
|
protected customOverlay?: d3.Selection<SVGRectElement, unknown, null, undefined>; |
|
|
|
protected customOverlay?: d3.Selection<SVGRectElement, unknown, null, undefined>; |
|
|
@ -155,10 +91,7 @@ abstract class ChartwerkPod<T extends CoreSerie, O extends Options> { |
|
|
|
// TODO: test if it's necessary
|
|
|
|
// TODO: test if it's necessary
|
|
|
|
styles.use(); |
|
|
|
styles.use(); |
|
|
|
|
|
|
|
|
|
|
|
let options = cloneDeep(_options); |
|
|
|
this.coreOptions = new CoreOptions(_options); |
|
|
|
defaultsDeep(options, DEFAULT_OPTIONS); |
|
|
|
|
|
|
|
this.options = options; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.coreSeries = new CoreSeries(_series); |
|
|
|
this.coreSeries = new CoreSeries(_series); |
|
|
|
|
|
|
|
|
|
|
|
this.d3Node = d3.select(this.el); |
|
|
|
this.d3Node = d3.select(this.el); |
|
|
@ -178,9 +111,7 @@ abstract class ChartwerkPod<T extends CoreSerie, O extends Options> { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public render(): void { |
|
|
|
public render(): void { |
|
|
|
if(has(this.options.eventsCallbacks, 'renderStart')) { |
|
|
|
this.coreOptions.callbackRenderStart(); |
|
|
|
this.options.eventsCallbacks.renderStart(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.renderClipPath(); |
|
|
|
this.renderClipPath(); |
|
|
|
this.addEvents(); |
|
|
|
this.addEvents(); |
|
|
@ -196,9 +127,7 @@ abstract class ChartwerkPod<T extends CoreSerie, O extends Options> { |
|
|
|
this.renderYLabel(); |
|
|
|
this.renderYLabel(); |
|
|
|
this.renderXLabel(); |
|
|
|
this.renderXLabel(); |
|
|
|
|
|
|
|
|
|
|
|
if(has(this.options.eventsCallbacks, 'renderEnd')) { |
|
|
|
this.coreOptions.callbackRenderEnd(); |
|
|
|
this.options.eventsCallbacks.renderEnd(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public updateData(series?: T[], options?: O, shouldRerender = true): void { |
|
|
|
public updateData(series?: T[], options?: O, shouldRerender = true): void { |
|
|
@ -222,10 +151,7 @@ abstract class ChartwerkPod<T extends CoreSerie, O extends Options> { |
|
|
|
if(newOptions === undefined) { |
|
|
|
if(newOptions === undefined) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
let options = cloneDeep(newOptions); |
|
|
|
this.coreOptions.updateOptions(newOptions); |
|
|
|
defaultsDeep(options, DEFAULT_OPTIONS); |
|
|
|
|
|
|
|
this.options = options; |
|
|
|
|
|
|
|
// TODO: update state if axis ranges were changed
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected updateSeries(newSeries: T[]): void { |
|
|
|
protected updateSeries(newSeries: T[]): void { |
|
|
@ -247,7 +173,7 @@ abstract class ChartwerkPod<T extends CoreSerie, O extends Options> { |
|
|
|
height: this.height, |
|
|
|
height: this.height, |
|
|
|
width: this.width, |
|
|
|
width: this.width, |
|
|
|
} |
|
|
|
} |
|
|
|
this.state = new PodState(boxPararms, this.coreSeries.visibleSeries, this.options); |
|
|
|
this.state = new PodState(boxPararms, this.coreSeries.visibleSeries, this.coreOptions.allOptions); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected initComponents(): void { |
|
|
|
protected initComponents(): void { |
|
|
@ -260,7 +186,7 @@ abstract class ChartwerkPod<T extends CoreSerie, O extends Options> { |
|
|
|
yScale: this.state.yScale, |
|
|
|
yScale: this.state.yScale, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.grid = new Grid(this.chartContainer, svgElParams, this.options.grid); |
|
|
|
this.grid = new Grid(this.chartContainer, svgElParams, this.coreOptions.grid); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected renderMetricsContainer(): void { |
|
|
|
protected renderMetricsContainer(): void { |
|
|
@ -303,7 +229,7 @@ abstract class ChartwerkPod<T extends CoreSerie, O extends Options> { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected renderXAxis(): void { |
|
|
|
protected renderXAxis(): void { |
|
|
|
if(this.options.axis.x.isActive === false) { |
|
|
|
if(this.coreOptions.axis.x.isActive === false) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
this.chartContainer.select('#x-axis-container').remove(); |
|
|
|
this.chartContainer.select('#x-axis-container').remove(); |
|
|
@ -314,16 +240,14 @@ abstract class ChartwerkPod<T extends CoreSerie, O extends Options> { |
|
|
|
.style('pointer-events', 'none') |
|
|
|
.style('pointer-events', 'none') |
|
|
|
.call( |
|
|
|
.call( |
|
|
|
d3.axisBottom(this.xScale) |
|
|
|
d3.axisBottom(this.xScale) |
|
|
|
.ticks(this.options.axis.x.ticksCount) |
|
|
|
.ticks(this.coreOptions.axis.x.ticksCount) |
|
|
|
.tickSize(DEFAULT_TICK_SIZE) |
|
|
|
.tickSize(DEFAULT_TICK_SIZE) |
|
|
|
.tickFormat(this.getAxisTicksFormatter(this.options.axis.x)) |
|
|
|
.tickFormat(this.getAxisTicksFormatter(this.coreOptions.axis.x)) |
|
|
|
); |
|
|
|
); |
|
|
|
this.chartContainer.select('#x-axis-container').selectAll('.tick').selectAll('text') |
|
|
|
|
|
|
|
.style('transform', this.xTickTransform); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected renderYAxis(): void { |
|
|
|
protected renderYAxis(): void { |
|
|
|
if(this.options.axis.y.isActive === false) { |
|
|
|
if(this.coreOptions.axis.y.isActive === false) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
this.chartContainer.select('#y-axis-container').remove(); |
|
|
|
this.chartContainer.select('#y-axis-container').remove(); |
|
|
@ -335,9 +259,9 @@ abstract class ChartwerkPod<T extends CoreSerie, O extends Options> { |
|
|
|
// TODO: number of ticks shouldn't be hardcoded
|
|
|
|
// TODO: number of ticks shouldn't be hardcoded
|
|
|
|
.call( |
|
|
|
.call( |
|
|
|
d3.axisLeft(this.yScale) |
|
|
|
d3.axisLeft(this.yScale) |
|
|
|
.ticks(this.options.axis.y.ticksCount) |
|
|
|
.ticks(this.coreOptions.axis.y.ticksCount) |
|
|
|
.tickSize(DEFAULT_TICK_SIZE) |
|
|
|
.tickSize(DEFAULT_TICK_SIZE) |
|
|
|
.tickFormat(this.getAxisTicksFormatter(this.options.axis.y)) |
|
|
|
.tickFormat(this.getAxisTicksFormatter(this.coreOptions.axis.y)) |
|
|
|
); |
|
|
|
); |
|
|
|
const ticks = this.yAxisElement.selectAll(`.tick`).select('text').nodes(); |
|
|
|
const ticks = this.yAxisElement.selectAll(`.tick`).select('text').nodes(); |
|
|
|
this.yAxisTicksColors.map((color, index) => { |
|
|
|
this.yAxisTicksColors.map((color, index) => { |
|
|
@ -349,7 +273,7 @@ abstract class ChartwerkPod<T extends CoreSerie, O extends Options> { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected renderY1Axis(): void { |
|
|
|
protected renderY1Axis(): void { |
|
|
|
if(this.options.axis.y1.isActive === false) { |
|
|
|
if(this.coreOptions.axis.y1.isActive === false) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
this.chartContainer.select('#y1-axis-container').remove(); |
|
|
|
this.chartContainer.select('#y1-axis-container').remove(); |
|
|
@ -363,7 +287,7 @@ abstract class ChartwerkPod<T extends CoreSerie, O extends Options> { |
|
|
|
d3.axisRight(this.y1Scale) |
|
|
|
d3.axisRight(this.y1Scale) |
|
|
|
.ticks(DEFAULT_TICK_COUNT) |
|
|
|
.ticks(DEFAULT_TICK_COUNT) |
|
|
|
.tickSize(DEFAULT_TICK_SIZE) |
|
|
|
.tickSize(DEFAULT_TICK_SIZE) |
|
|
|
.tickFormat(this.getAxisTicksFormatter(this.options.axis.y1)) |
|
|
|
.tickFormat(this.getAxisTicksFormatter(this.coreOptions.axis.y1)) |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -375,28 +299,28 @@ abstract class ChartwerkPod<T extends CoreSerie, O extends Options> { |
|
|
|
.style('display', 'none'); |
|
|
|
.style('display', 'none'); |
|
|
|
|
|
|
|
|
|
|
|
if( |
|
|
|
if( |
|
|
|
this.options.crosshair.orientation === CrosshairOrientation.VERTICAL || |
|
|
|
this.coreOptions.crosshair.orientation === CrosshairOrientation.VERTICAL || |
|
|
|
this.options.crosshair.orientation === CrosshairOrientation.BOTH |
|
|
|
this.coreOptions.crosshair.orientation === CrosshairOrientation.BOTH |
|
|
|
) { |
|
|
|
) { |
|
|
|
this.crosshair.append('line') |
|
|
|
this.crosshair.append('line') |
|
|
|
.attr('class', 'crosshair-line') |
|
|
|
.attr('class', 'crosshair-line') |
|
|
|
.attr('id', 'crosshair-line-x') |
|
|
|
.attr('id', 'crosshair-line-x') |
|
|
|
.attr('fill', this.options.crosshair.color) |
|
|
|
.attr('fill', this.coreOptions.crosshair.color) |
|
|
|
.attr('stroke', this.options.crosshair.color) |
|
|
|
.attr('stroke', this.coreOptions.crosshair.color) |
|
|
|
.attr('stroke-width', '1px') |
|
|
|
.attr('stroke-width', '1px') |
|
|
|
.attr('y1', 0) |
|
|
|
.attr('y1', 0) |
|
|
|
.attr('y2', this.height) |
|
|
|
.attr('y2', this.height) |
|
|
|
.style('pointer-events', 'none'); |
|
|
|
.style('pointer-events', 'none'); |
|
|
|
} |
|
|
|
} |
|
|
|
if( |
|
|
|
if( |
|
|
|
this.options.crosshair.orientation === CrosshairOrientation.HORIZONTAL || |
|
|
|
this.coreOptions.crosshair.orientation === CrosshairOrientation.HORIZONTAL || |
|
|
|
this.options.crosshair.orientation === CrosshairOrientation.BOTH |
|
|
|
this.coreOptions.crosshair.orientation === CrosshairOrientation.BOTH |
|
|
|
) { |
|
|
|
) { |
|
|
|
this.crosshair.append('line') |
|
|
|
this.crosshair.append('line') |
|
|
|
.attr('class', 'crosshair-line') |
|
|
|
.attr('class', 'crosshair-line') |
|
|
|
.attr('id', 'crosshair-line-y') |
|
|
|
.attr('id', 'crosshair-line-y') |
|
|
|
.attr('fill', this.options.crosshair.color) |
|
|
|
.attr('fill', this.coreOptions.crosshair.color) |
|
|
|
.attr('stroke', this.options.crosshair.color) |
|
|
|
.attr('stroke', this.coreOptions.crosshair.color) |
|
|
|
.attr('stroke-width', '1px') |
|
|
|
.attr('stroke-width', '1px') |
|
|
|
.attr('x1', 0) |
|
|
|
.attr('x1', 0) |
|
|
|
.attr('x2', this.width) |
|
|
|
.attr('x2', this.width) |
|
|
@ -501,7 +425,7 @@ abstract class ChartwerkPod<T extends CoreSerie, O extends Options> { |
|
|
|
|
|
|
|
|
|
|
|
this.initScaleX = this.xScale.copy(); |
|
|
|
this.initScaleX = this.xScale.copy(); |
|
|
|
this.initScaleY = this.yScale.copy(); |
|
|
|
this.initScaleY = this.yScale.copy(); |
|
|
|
if(this.options.axis.y1.isActive === true) { |
|
|
|
if(this.coreOptions.axis.y1.isActive) { |
|
|
|
this.initScaleY1 = this.y1Scale.copy(); |
|
|
|
this.initScaleY1 = this.y1Scale.copy(); |
|
|
|
} |
|
|
|
} |
|
|
|
this.pan = d3.zoom() |
|
|
|
this.pan = d3.zoom() |
|
|
@ -533,9 +457,6 @@ abstract class ChartwerkPod<T extends CoreSerie, O extends Options> { |
|
|
|
.attr('class', 'legend-row'); |
|
|
|
.attr('class', 'legend-row'); |
|
|
|
const series = this.coreSeries.allSeries;
|
|
|
|
const series = this.coreSeries.allSeries;
|
|
|
|
for(let idx = 0; idx < series.length; idx++) { |
|
|
|
for(let idx = 0; idx < series.length; idx++) { |
|
|
|
if(includes(this.seriesTargetsWithBounds, series[idx].target)) { |
|
|
|
|
|
|
|
continue; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
let node = legendRow.selectAll('text').node(); |
|
|
|
let node = legendRow.selectAll('text').node(); |
|
|
|
let rowWidth = 0; |
|
|
|
let rowWidth = 0; |
|
|
|
if(node !== null) { |
|
|
|
if(node !== null) { |
|
|
@ -549,11 +470,7 @@ abstract class ChartwerkPod<T extends CoreSerie, O extends Options> { |
|
|
|
.attr('width', 13) |
|
|
|
.attr('width', 13) |
|
|
|
.attr('height', 15) |
|
|
|
.attr('height', 15) |
|
|
|
.html(`<form><input type=checkbox ${isChecked? 'checked' : ''} /></form>`) |
|
|
|
.html(`<form><input type=checkbox ${isChecked? 'checked' : ''} /></form>`) |
|
|
|
.on('click', () => { |
|
|
|
.on('click', () => this.coreOptions.callbackLegendClick(idx)); |
|
|
|
if(this.options.eventsCallbacks !== undefined && this.options.eventsCallbacks.onLegendClick !== undefined) { |
|
|
|
|
|
|
|
this.options.eventsCallbacks.onLegendClick(idx); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
legendRow.append('text') |
|
|
|
legendRow.append('text') |
|
|
|
.attr('x', rowWidth + 20) |
|
|
|
.attr('x', rowWidth + 20) |
|
|
@ -562,16 +479,12 @@ abstract class ChartwerkPod<T extends CoreSerie, O extends Options> { |
|
|
|
.style('font-size', '12px') |
|
|
|
.style('font-size', '12px') |
|
|
|
.style('fill', series[idx].color) |
|
|
|
.style('fill', series[idx].color) |
|
|
|
.text(series[idx].target) |
|
|
|
.text(series[idx].target) |
|
|
|
.on('click', () => { |
|
|
|
.on('click', () => this.coreOptions.callbackLegendLabelClick(idx)); |
|
|
|
if(this.options.eventsCallbacks !== undefined && this.options.eventsCallbacks.onLegendLabelClick !== undefined) { |
|
|
|
|
|
|
|
this.options.eventsCallbacks.onLegendLabelClick(idx); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected renderYLabel(): void { |
|
|
|
protected renderYLabel(): void { |
|
|
|
if(this.options.labelFormat === undefined || this.options.labelFormat.yAxis === undefined) { |
|
|
|
if(this.coreOptions.axis.y.label === undefined) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
this.chartContainer.append('text') |
|
|
|
this.chartContainer.append('text') |
|
|
@ -583,11 +496,11 @@ abstract class ChartwerkPod<T extends CoreSerie, O extends Options> { |
|
|
|
.style('text-anchor', 'middle') |
|
|
|
.style('text-anchor', 'middle') |
|
|
|
.style('font-size', '14px') |
|
|
|
.style('font-size', '14px') |
|
|
|
.style('fill', 'currentColor') |
|
|
|
.style('fill', 'currentColor') |
|
|
|
.text(this.options.labelFormat.yAxis); |
|
|
|
.text(this.coreOptions.axis.y.label); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected renderXLabel(): void { |
|
|
|
protected renderXLabel(): void { |
|
|
|
if(this.options.labelFormat === undefined || this.options.labelFormat.xAxis === undefined) { |
|
|
|
if(this.coreOptions.axis.x.label === undefined) { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
let yPosition = this.height + this.margin.top + this.margin.bottom - 35; |
|
|
|
let yPosition = this.height + this.margin.top + this.margin.bottom - 35; |
|
|
@ -601,7 +514,7 @@ abstract class ChartwerkPod<T extends CoreSerie, O extends Options> { |
|
|
|
.style('text-anchor', 'middle') |
|
|
|
.style('text-anchor', 'middle') |
|
|
|
.style('font-size', '14px') |
|
|
|
.style('font-size', '14px') |
|
|
|
.style('fill', 'currentColor') |
|
|
|
.style('fill', 'currentColor') |
|
|
|
.text(this.options.labelFormat.xAxis); |
|
|
|
.text(this.coreOptions.axis.x.label); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected renderNoDataPointsMessage(): void { |
|
|
|
protected renderNoDataPointsMessage(): void { |
|
|
@ -883,9 +796,6 @@ abstract class ChartwerkPod<T extends CoreSerie, O extends Options> { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected zoomOut(): void { |
|
|
|
protected zoomOut(): void { |
|
|
|
if(this.isOutOfChart() === true) { |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
let xAxisMiddleValue: number = this.xScale.invert(this.width / 2); |
|
|
|
let xAxisMiddleValue: number = this.xScale.invert(this.width / 2); |
|
|
|
let yAxisMiddleValue: number = this.yScale.invert(this.height / 2); |
|
|
|
let yAxisMiddleValue: number = this.yScale.invert(this.height / 2); |
|
|
|
const centers = { |
|
|
|
const centers = { |
|
|
@ -999,52 +909,6 @@ abstract class ChartwerkPod<T extends CoreSerie, O extends Options> { |
|
|
|
return MILISECONDS_IN_MINUTE; |
|
|
|
return MILISECONDS_IN_MINUTE; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
get xTickTransform(): string { |
|
|
|
|
|
|
|
if(this.options.tickFormat === undefined || this.options.tickFormat.xTickOrientation === undefined) { |
|
|
|
|
|
|
|
return ''; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
switch (this.options.tickFormat.xTickOrientation) { |
|
|
|
|
|
|
|
case TickOrientation.VERTICAL: |
|
|
|
|
|
|
|
return 'translate(-10px, 50px) rotate(-90deg)'; |
|
|
|
|
|
|
|
case TickOrientation.HORIZONTAL: |
|
|
|
|
|
|
|
return ''; |
|
|
|
|
|
|
|
case TickOrientation.DIAGONAL: |
|
|
|
|
|
|
|
return 'translate(-30px, 30px) rotate(-45deg)'; |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
return ''; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get extraMargin(): Margin { |
|
|
|
|
|
|
|
let optionalMargin = { top: 0, right: 0, bottom: 0, left: 0 }; |
|
|
|
|
|
|
|
if(this.options.tickFormat !== undefined && this.options.tickFormat.xTickOrientation !== undefined) { |
|
|
|
|
|
|
|
switch (this.options.tickFormat.xTickOrientation) { |
|
|
|
|
|
|
|
case TickOrientation.VERTICAL: |
|
|
|
|
|
|
|
optionalMargin.bottom += 80; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case TickOrientation.HORIZONTAL: |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case TickOrientation.DIAGONAL: |
|
|
|
|
|
|
|
optionalMargin.left += 15; |
|
|
|
|
|
|
|
optionalMargin.bottom += 50; |
|
|
|
|
|
|
|
optionalMargin.right += 10; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(this.options.labelFormat !== undefined) { |
|
|
|
|
|
|
|
if(this.options.labelFormat.xAxis !== undefined && this.options.labelFormat.xAxis.length > 0) { |
|
|
|
|
|
|
|
optionalMargin.bottom += 20; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(this.options.labelFormat.yAxis !== undefined && this.options.labelFormat.yAxis.length > 0) { |
|
|
|
|
|
|
|
optionalMargin.left += 20; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if(this.coreSeries.isSeriesAvailable) { |
|
|
|
|
|
|
|
optionalMargin.bottom += 25; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return optionalMargin; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get width(): number { |
|
|
|
get width(): number { |
|
|
|
return this.d3Node.node().clientWidth - this.margin.left - this.margin.right; |
|
|
|
return this.d3Node.node().clientWidth - this.margin.left - this.margin.right; |
|
|
|
} |
|
|
|
} |
|
|
@ -1058,61 +922,25 @@ abstract class ChartwerkPod<T extends CoreSerie, O extends Options> { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
get margin(): Margin { |
|
|
|
get margin(): Margin { |
|
|
|
if(this.options.margin !== undefined) { |
|
|
|
return this.coreOptions.margin; |
|
|
|
return this.options.margin; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return mergeWith({}, DEFAULT_MARGIN, this.extraMargin, add); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
formattedBound(alias: string, target: string): string { |
|
|
|
|
|
|
|
const confidenceMetric = replace(alias, '$__metric_name', target); |
|
|
|
|
|
|
|
return confidenceMetric; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected clearState(): void { |
|
|
|
protected clearState(): void { |
|
|
|
this.state.clearState(); |
|
|
|
this.state.clearState(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
protected get seriesTargetsWithBounds(): any[] { |
|
|
|
|
|
|
|
if( |
|
|
|
|
|
|
|
this.options.bounds === undefined || |
|
|
|
|
|
|
|
this.options.bounds.upper === undefined || |
|
|
|
|
|
|
|
this.options.bounds.lower === undefined |
|
|
|
|
|
|
|
) { |
|
|
|
|
|
|
|
return []; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
let series = []; |
|
|
|
|
|
|
|
this.coreSeries.allSeries.forEach(serie => { |
|
|
|
|
|
|
|
series.push(this.formattedBound(this.options.bounds.upper, serie.target)); |
|
|
|
|
|
|
|
series.push(this.formattedBound(this.options.bounds.lower, serie.target)); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
return series; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
protected get rectClipId(): string { |
|
|
|
protected get rectClipId(): string { |
|
|
|
if(this._clipPathUID.length === 0) { |
|
|
|
if(this._clipPathUID.length === 0) { |
|
|
|
this._clipPathUID = uid(); |
|
|
|
this._clipPathUID = uid(); |
|
|
|
} |
|
|
|
} |
|
|
|
return this._clipPathUID; |
|
|
|
return this._clipPathUID; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
isOutOfChart(): boolean { |
|
|
|
|
|
|
|
const event = d3.mouse(this.chartContainer.node()); |
|
|
|
|
|
|
|
const eventX = event[0]; |
|
|
|
|
|
|
|
const eventY = event[1]; |
|
|
|
|
|
|
|
if( |
|
|
|
|
|
|
|
eventY > this.height + 1 || eventY < -1 || |
|
|
|
|
|
|
|
eventX > this.width || eventX < 0 |
|
|
|
|
|
|
|
) { |
|
|
|
|
|
|
|
return true; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
return false; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
export { |
|
|
|
export { |
|
|
|
ChartwerkPod, VueChartwerkPodMixin, |
|
|
|
ChartwerkPod, VueChartwerkPodMixin, |
|
|
|
Margin, CoreSerie, Options, TickOrientation, TimeFormat, BrushOrientation, PanOrientation, |
|
|
|
Margin, CoreSerie, Options, TimeFormat, BrushOrientation, PanOrientation, |
|
|
|
|
|
|
|
AxesOptions, AxisOption, |
|
|
|
AxisFormat, yAxisOrientation, CrosshairOrientation, ScrollPanOrientation, ScrollPanDirection, KeyEvent, |
|
|
|
AxisFormat, yAxisOrientation, CrosshairOrientation, ScrollPanOrientation, ScrollPanDirection, KeyEvent, |
|
|
|
palette |
|
|
|
palette |
|
|
|
}; |
|
|
|
}; |
|
|
|