|
|
|
@ -1,4 +1,3 @@
|
|
|
|
|
import { AxisRange } from './types'; |
|
|
|
|
import VueChartwerkPodMixin from './VueChartwerkPodMixin'; |
|
|
|
|
import { Grid } from './components/grid'; |
|
|
|
|
|
|
|
|
@ -31,13 +30,15 @@ import { palette } from './colors';
|
|
|
|
|
|
|
|
|
|
import * as d3 from 'd3'; |
|
|
|
|
|
|
|
|
|
import first from 'lodash/first'; |
|
|
|
|
import last from 'lodash/last'; |
|
|
|
|
import debounce from 'lodash/debounce'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const DEFAULT_TICK_SIZE = 2; |
|
|
|
|
const MILISECONDS_IN_MINUTE = 60 * 1000; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ChartwerkPod<T extends Serie, O extends Options> { |
|
|
|
|
abstract class ChartwerkPod<T extends Serie, O extends Options> { |
|
|
|
|
|
|
|
|
|
protected series: CoreSeries<T>; |
|
|
|
|
protected options: CoreOptions<O>; |
|
|
|
@ -79,8 +80,7 @@ class ChartwerkPod<T extends Serie, O extends Options> {
|
|
|
|
|
_series: T[] = [], |
|
|
|
|
_options: O |
|
|
|
|
) { |
|
|
|
|
// need to call explicitly because option lazyStyleTag
|
|
|
|
|
// in webpack style-loader
|
|
|
|
|
// TODO: test if it's necessary
|
|
|
|
|
styles.use(); |
|
|
|
|
|
|
|
|
|
this.options = new CoreOptions(_options); |
|
|
|
@ -116,7 +116,6 @@ class ChartwerkPod<T extends Serie, O extends Options> {
|
|
|
|
|
|
|
|
|
|
this.renderLegend(); |
|
|
|
|
this.renderYLabel(); |
|
|
|
|
this.renderY1Label(); |
|
|
|
|
this.renderXLabel(); |
|
|
|
|
|
|
|
|
|
this.options.callbackRenderEnd(); |
|
|
|
@ -153,13 +152,12 @@ class ChartwerkPod<T extends Serie, O extends Options> {
|
|
|
|
|
this.series.updateSeries(newSeries); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected renderMetrics(): void {} |
|
|
|
|
protected onMouseOver(): void {} |
|
|
|
|
protected onMouseOut(): void {} |
|
|
|
|
protected onMouseMove(): void {} |
|
|
|
|
protected onMouseClick(): void {} |
|
|
|
|
public renderSharedCrosshair(values: { x?: number, y?: number }): void {} |
|
|
|
|
public hideSharedCrosshair(): void {} |
|
|
|
|
protected abstract renderMetrics(): void; |
|
|
|
|
protected abstract onMouseOver(): void; |
|
|
|
|
protected abstract onMouseOut(): void; |
|
|
|
|
protected abstract onMouseMove(): void; |
|
|
|
|
public abstract renderSharedCrosshair(values: { x?: number, y?: number }): void; |
|
|
|
|
public abstract hideSharedCrosshair(): void; |
|
|
|
|
|
|
|
|
|
protected initPodState(): void { |
|
|
|
|
const boxPararms = { |
|
|
|
@ -329,21 +327,12 @@ class ChartwerkPod<T extends Serie, O extends Options> {
|
|
|
|
|
// TODO: refactor for a new mouse/scroll events
|
|
|
|
|
const panKeyEvent = this.options.mousePanEvent.keyEvent; |
|
|
|
|
const isPanActive = this.options.mousePanEvent.isActive; |
|
|
|
|
const isBrushActive = this.options.mouseZoomEvent.isActive; |
|
|
|
|
if(panKeyEvent === KeyEvent.MAIN) { |
|
|
|
|
if(isPanActive) { |
|
|
|
|
this.initPan(); |
|
|
|
|
} |
|
|
|
|
if(isBrushActive) { |
|
|
|
|
this.initBrush(); |
|
|
|
|
} |
|
|
|
|
if(isPanActive === true && panKeyEvent === KeyEvent.MAIN) { |
|
|
|
|
this.initPan(); |
|
|
|
|
this.initBrush(); |
|
|
|
|
} else { |
|
|
|
|
if(isBrushActive) { |
|
|
|
|
this.initBrush(); |
|
|
|
|
} |
|
|
|
|
if(isPanActive) { |
|
|
|
|
this.initPan(); |
|
|
|
|
} |
|
|
|
|
this.initBrush(); |
|
|
|
|
this.initPan(); |
|
|
|
|
} |
|
|
|
|
this.ensureOverlayExisting(); |
|
|
|
|
|
|
|
|
@ -352,7 +341,6 @@ class ChartwerkPod<T extends Serie, O extends Options> {
|
|
|
|
|
.on('mouseover', this.onMouseOver.bind(this)) |
|
|
|
|
.on('mouseout', this.onMouseOut.bind(this)) |
|
|
|
|
.on('mousemove', this.onMouseMove.bind(this)) |
|
|
|
|
.on('click', this.onMouseClick.bind(this)) |
|
|
|
|
.on('dblclick', () => { |
|
|
|
|
d3.event.stopPropagation(); |
|
|
|
|
// TODO: add the same check as we have in line-pod
|
|
|
|
@ -384,6 +372,10 @@ class ChartwerkPod<T extends Serie, O extends Options> {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected initBrush(): void { |
|
|
|
|
const isBrushActive = this.options.mouseZoomEvent.isActive; |
|
|
|
|
if(isBrushActive === false) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
switch(this.options.mouseZoomEvent.orientation) { |
|
|
|
|
case BrushOrientation.VERTICAL: |
|
|
|
|
this.brush = d3.brushY(); |
|
|
|
@ -417,9 +409,9 @@ class ChartwerkPod<T extends Serie, O extends Options> {
|
|
|
|
|
// TODO: refactor
|
|
|
|
|
switch(key) { |
|
|
|
|
case KeyEvent.MAIN: |
|
|
|
|
return () => !d3.event.shiftKey && !d3.event.button; |
|
|
|
|
return () => !d3.event.shiftKey; |
|
|
|
|
case KeyEvent.SHIFT: |
|
|
|
|
return () => d3.event.shiftKey && !d3.event.button; |
|
|
|
|
return () => d3.event.shiftKey; |
|
|
|
|
default: |
|
|
|
|
throw new Error(`Unknown type of KeyEvent: ${key}`); |
|
|
|
|
} |
|
|
|
@ -510,8 +502,8 @@ class ChartwerkPod<T extends Serie, O extends Options> {
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
this.chartContainer.append('text') |
|
|
|
|
.attr('y', -this.margin.left) |
|
|
|
|
.attr('x', -(this.height / 2)) |
|
|
|
|
.attr('y', 0 - this.margin.left) |
|
|
|
|
.attr('x', 0 - (this.height / 2)) |
|
|
|
|
.attr('dy', '1em') |
|
|
|
|
.attr('class', 'y-axis-label') |
|
|
|
|
.attr('transform', 'rotate(-90)') |
|
|
|
@ -521,22 +513,6 @@ class ChartwerkPod<T extends Serie, O extends Options> {
|
|
|
|
|
.text(this.options.axis.y.label); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected renderY1Label(): void { |
|
|
|
|
if(this.options.axis.y1?.label === undefined) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
this.chartContainer.append('text') |
|
|
|
|
.attr('y', -this.width - this.margin.right) |
|
|
|
|
.attr('x', (this.height / 2)) |
|
|
|
|
.attr('dy', '1em') |
|
|
|
|
.attr('class', 'y-axis-label') |
|
|
|
|
.attr('transform', 'rotate(90)') |
|
|
|
|
.style('text-anchor', 'middle') |
|
|
|
|
.style('font-size', '14px') |
|
|
|
|
.style('fill', 'currentColor') |
|
|
|
|
.text(this.options.axis.y1.label); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected renderXLabel(): void { |
|
|
|
|
if(this.options.axis.x.label === undefined) { |
|
|
|
|
return; |
|
|
|
@ -817,7 +793,8 @@ class ChartwerkPod<T extends Serie, O extends Options> {
|
|
|
|
|
this.state.yValueRange = yRange; |
|
|
|
|
this.brushStartSelection = null; |
|
|
|
|
} |
|
|
|
|
this.zoomIn([xRange, yRange]); |
|
|
|
|
|
|
|
|
|
this.options.callbackZoomIn([xRange, yRange]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected zoomOut(): void { |
|
|
|
@ -830,10 +807,6 @@ class ChartwerkPod<T extends Serie, O extends Options> {
|
|
|
|
|
this.options.callbackZoomOut(centers); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected zoomIn(ranges: AxisRange[]): void { |
|
|
|
|
this.options.callbackZoomIn(ranges); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
getAxisTicksFormatter(axisOptions: AxisOption): (d: any, i: number) => any { |
|
|
|
|
// TODO: ticksCount === 0 -> suspicious option
|
|
|
|
|
if(axisOptions.ticksCount === 0) { |
|
|
|
|