|
|
|
@ -1,5 +1,5 @@
|
|
|
|
|
import { ChartwerkPod, VueChartwerkPodMixin, TickOrientation, TimeFormat, yAxisOrientation, CrosshairOrientation } from '@chartwerk/core'; |
|
|
|
|
import { ScatterData, ScatterOptions, PointType, LineType } from './types'; |
|
|
|
|
import { ScatterData, ScatterOptions, PointType, LineType, Datapoint } from './types'; |
|
|
|
|
|
|
|
|
|
import { DelaunayDiagram } from './delaunay'; |
|
|
|
|
|
|
|
|
@ -150,12 +150,12 @@ export class ChartwerkScatterPod extends ChartwerkPod<ScatterData, ScatterOption
|
|
|
|
|
.attr('height', (d: number[]) => this.series[_.last(d)].pointSize || DEFAULT_POINT_SIZE); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
getSeriesColorFromDataRow(values: number[], rowIdx: number): string { |
|
|
|
|
const seriesIdx = _.last(values); |
|
|
|
|
if(this.series[seriesIdx].colorFormatter) { |
|
|
|
|
return this.series[seriesIdx].colorFormatter(values, rowIdx); |
|
|
|
|
getSeriesColorFromDataRow(datapoint: Datapoint): string { |
|
|
|
|
const serieIdx = datapoint.serieIdx; |
|
|
|
|
if(this.series[serieIdx].colorFormatter) { |
|
|
|
|
return this.series[serieIdx].colorFormatter(datapoint); |
|
|
|
|
} |
|
|
|
|
return this.getSerieColor(seriesIdx); |
|
|
|
|
return this.getSerieColor(serieIdx); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
onPanningEnd(): void { |
|
|
|
@ -173,23 +173,18 @@ export class ChartwerkScatterPod extends ChartwerkPod<ScatterData, ScatterOption
|
|
|
|
|
this.crosshair.selectAll('.crosshair-point').style('display', 'none'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
highlight(pointIdx: number): void { |
|
|
|
|
highlight(datapoint: Datapoint): void { |
|
|
|
|
this.unhighlight(); |
|
|
|
|
|
|
|
|
|
const datapoint = this._delaunayDiagram.getDataRowByIndex(pointIdx); |
|
|
|
|
if(datapoint === undefined || datapoint === null) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const serieIdx = _.last(datapoint); |
|
|
|
|
const serieIdx = datapoint.serieIdx; |
|
|
|
|
const serieOrientation = this.series[serieIdx].yOrientation; |
|
|
|
|
const size = this.getCrosshairCircleBackgroundSize(serieIdx); |
|
|
|
|
this.crosshair.selectAll(`.crosshair-point-${serieIdx}`) |
|
|
|
|
.attr('cx', this.xScale(datapoint[0])) |
|
|
|
|
.attr('cy', this.getYScale(serieOrientation)(datapoint[1])) |
|
|
|
|
.attr('x', this.xScale(datapoint[0]) - size / 2) |
|
|
|
|
.attr('y', this.getYScale(serieOrientation)(datapoint[1]) - size / 2) |
|
|
|
|
.attr('fill', this.getSeriesColorFromDataRow(datapoint, pointIdx)) |
|
|
|
|
.attr('cx', this.xScale(datapoint.x)) |
|
|
|
|
.attr('cy', this.getYScale(serieOrientation)(datapoint.y)) |
|
|
|
|
.attr('x', this.xScale(datapoint.x - size / 2)) |
|
|
|
|
.attr('y', this.getYScale(serieOrientation)(datapoint.y) - size / 2) |
|
|
|
|
.attr('fill', this.getSeriesColorFromDataRow(datapoint)) |
|
|
|
|
.style('display', null); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -208,7 +203,7 @@ export class ChartwerkScatterPod extends ChartwerkPod<ScatterData, ScatterOption
|
|
|
|
|
const eventX = this.xScale(values.x); |
|
|
|
|
const eventY = this.yScale(values.y); |
|
|
|
|
this.moveCrosshairLine(eventX, eventY); |
|
|
|
|
const datapoints = this.findAndHighlightDatapoints(values.x, values.y); |
|
|
|
|
const datapoints = this.findDatapoint(values.x, values.y); |
|
|
|
|
|
|
|
|
|
if(this.options.eventsCallbacks === undefined || this.options.eventsCallbacks.sharedCrosshairMove === undefined) { |
|
|
|
|
console.log('Shared crosshair move, but there is no callback'); |
|
|
|
@ -246,21 +241,36 @@ export class ChartwerkScatterPod extends ChartwerkPod<ScatterData, ScatterOption
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
findAndHighlightDatapoints(eventX: number, eventY: number): { values: any[], pointIdx: number } | null { |
|
|
|
|
highlightDatapoint(datapoint?: Datapoint): void { |
|
|
|
|
if(_.isNil(datapoint)) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
this.highlight(datapoint);
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
findDatapoint(eventX: number, eventY: number): Datapoint | null { |
|
|
|
|
if(this.series === undefined || this.series.length === 0) { |
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const pointIndex = this._delaunayDiagram.findPointIndex(eventX, eventY); |
|
|
|
|
if(pointIndex === undefined) { |
|
|
|
|
this.unhighlight(); |
|
|
|
|
const datapoint = this._delaunayDiagram.getDataRowByIndex(pointIndex); |
|
|
|
|
if(_.isNil(datapoint)) { |
|
|
|
|
// TODO: maybe throw an error?
|
|
|
|
|
return null; |
|
|
|
|
} |
|
|
|
|
this.highlight(pointIndex); |
|
|
|
|
const serieIdx = _.last(datapoint); |
|
|
|
|
let seriePointIdx = pointIndex |
|
|
|
|
for(let i = 0; i < serieIdx; i++) { |
|
|
|
|
seriePointIdx -= this.series[serieIdx].datapoints.length; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return { |
|
|
|
|
values: this._delaunayDiagram.data[pointIndex], |
|
|
|
|
pointIdx: pointIndex, |
|
|
|
|
x: datapoint[0], |
|
|
|
|
y: datapoint[1], |
|
|
|
|
rawValues: datapoint, |
|
|
|
|
serieIdx, |
|
|
|
|
pointIdx: seriePointIdx, |
|
|
|
|
}; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -282,7 +292,8 @@ export class ChartwerkScatterPod extends ChartwerkPod<ScatterData, ScatterOption
|
|
|
|
|
this.crosshair.style('display', 'none'); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
onMouseMove(): void { |
|
|
|
|
// @ts-ignore
|
|
|
|
|
onMouseMove(d: any): void { |
|
|
|
|
const mousePosition = d3.mouse(this.chartContainer.node()); |
|
|
|
|
const eventX = mousePosition[0]; |
|
|
|
|
const eventY = mousePosition[1]; |
|
|
|
@ -298,7 +309,8 @@ export class ChartwerkScatterPod extends ChartwerkPod<ScatterData, ScatterOption
|
|
|
|
|
this.moveCrosshairLine(eventX, eventY); |
|
|
|
|
|
|
|
|
|
// TOOD: it should be two different methods
|
|
|
|
|
const highlighted = this.findAndHighlightDatapoints(eventX, eventY); |
|
|
|
|
const datapoint = this.findDatapoint(eventX, eventY); |
|
|
|
|
this.highlightDatapoint(datapoint); |
|
|
|
|
if(this.options.eventsCallbacks === undefined || this.options.eventsCallbacks.mouseMove === undefined) { |
|
|
|
|
console.log('Mouse move, but there is no callback'); |
|
|
|
|
return; |
|
|
|
@ -309,7 +321,7 @@ export class ChartwerkScatterPod extends ChartwerkPod<ScatterData, ScatterOption
|
|
|
|
|
y: d3.event.clientY, |
|
|
|
|
xval: this.xScale.invert(eventX), |
|
|
|
|
yval: this.xScale.invert(eventY), |
|
|
|
|
highlighted, |
|
|
|
|
highlighted: datapoint, |
|
|
|
|
chartX: eventX, |
|
|
|
|
chartWidth: this.width |
|
|
|
|
}); |
|
|
|
|