Browse Source

Merge branch 'click-on-metric' into 'main'

metric options: callback on click

See merge request chartwerk/scatter-pod!7
pull/2/head
Alexander Velikiy 2 years ago
parent
commit
e217ebc042
  1. 1
      examples/demo.html
  2. 2
      package.json
  3. 36
      src/index.ts
  4. 8
      src/models/delaunay.ts
  5. 7
      src/models/scatter_series.ts
  6. 12
      src/types.ts
  7. 6
      yarn.lock

1
examples/demo.html

@ -28,6 +28,7 @@
lineType: 'dashed',
pointType: 'circle',
colorFormatter: (values, idx) => datapoints1[idx][2] === 0 ? 'blue' : 'green',
clickCallback: (metricData, pointData) => { console.log('click', metricData, pointData) }
},
{
target: 'test2',

2
package.json

@ -1,6 +1,6 @@
{
"name": "@chartwerk/scatter-pod",
"version": "0.6.5",
"version": "0.6.6",
"description": "Chartwerk scatter pod",
"main": "dist/index.js",
"scripts": {

36
src/index.ts

@ -1,7 +1,7 @@
import { ChartwerkPod, VueChartwerkPodMixin, TimeFormat, yAxisOrientation, CrosshairOrientation } from '@chartwerk/core';
import { ScatterData, ScatterOptions, PointType, LineType, HighlightedData, MouseMoveEvent } from './types';
import { ScatterData, ScatterOptions, PointType, LineType, HighlightedData, MouseMoveEvent, DelaunayDataRow } from './types';
import { DelaunayDiagram, DelaunayDataRow } from './models/delaunay';
import { DelaunayDiagram } from './models/delaunay';
import { ScatterSeries } from './models/scatter_series';
import * as d3 from 'd3';
@ -103,13 +103,15 @@ export class ChartwerkScatterPod extends ChartwerkPod<ScatterData, ScatterOption
.append('path')
.datum(serie.datapoints)
.attr('class', 'metric-path')
.attr('d', lineGenerator)
.attr('fill', 'none')
.style('pointer-events', 'none')
.attr('stroke', serie.color)
.attr('stroke-width', 1)
.attr('stroke-opacity', 0.7)
.attr('stroke-dasharray', strokeDasharray)
.attr('d', lineGenerator);
.style('pointer-events', serie.clickCallback ? 'auto' : 'none')
.style('cursor', serie.clickCallback ? 'pointer' : 'crosshair')
.on('click', () => { serie.clickCallback({ target: serie.target, class: serie.class, alias: serie.alias }) });
}
protected renderPoints(): void {
@ -123,10 +125,17 @@ export class ChartwerkScatterPod extends ChartwerkPod<ScatterData, ScatterOption
.filter((d: DelaunayDataRow) => this.series.getSerieByTarget(d[4])?.pointType !== PointType.RECTANGLE)
.attr('class', (d, i: number) => `metric-element metric-circle point-${i}`)
.attr('r', (d: DelaunayDataRow) => this.series.getSerieByTarget(d[4])?.pointSize)
.style('fill', (d: DelaunayDataRow, i: number) => this.getSeriesColorFromDataRow(d, i))
.style('pointer-events', 'none')
.attr('cx', (d: DelaunayDataRow) => this.state.xScale(d[0]))
.attr('cy', (d: DelaunayDataRow) => this.getYScale(this.series.getSerieByTarget(d[4])?.yOrientation)(d[1]));
.attr('cy', (d: DelaunayDataRow) => this.getYScale(this.series.getSerieByTarget(d[4])?.yOrientation)(d[1]))
.style('fill', (d: DelaunayDataRow, i: number) => this.getSeriesColorFromDataRow(d, i))
.style('pointer-events', (d: DelaunayDataRow) => this.series.getSerieByTarget(d[4])?.clickCallback ? 'auto' : 'none')
.style('cursor', (d: DelaunayDataRow) => this.series.getSerieByTarget(d[4])?.clickCallback ? 'pointer' : 'crosshair')
.on('click', (d: DelaunayDataRow) => {
d3.event.stopPropagation();
const serie = this.series.getSerieByTarget(d[4]);
const serieData = { target: serie?.target, class: serie?.class, alias: serie?.alias };
serie?.clickCallback(serieData, d);
});
this.metricContainer.selectAll(null)
.data(this._delaunayDiagram.data)
@ -135,12 +144,19 @@ export class ChartwerkScatterPod extends ChartwerkPod<ScatterData, ScatterOption
.filter((d: DelaunayDataRow) => this.series.getSerieByTarget(d[4])?.pointType === PointType.RECTANGLE)
.attr('class', (d, i: number) => `metric-element metric-circle point-${i}`)
.attr('r', (d: DelaunayDataRow) => this.series.getSerieByTarget(d[4])?.pointSize)
.style('fill', (d: DelaunayDataRow) => this.series.getSerieByTarget(d[4])?.color)
.style('pointer-events', 'none')
.attr('x', (d: DelaunayDataRow) => this.state.xScale(d[0]) - this.series.getSerieByTarget(d[4])?.pointSize / 2)
.attr('y', (d: DelaunayDataRow) => this.getYScale(this.series.getSerieByTarget(d[4])?.yOrientation)(d[1]) - this.series.getSerieByTarget(d[4])?.pointSize / 2)
.attr('width', (d: DelaunayDataRow) => this.series.getSerieByTarget(d[4])?.pointSize)
.attr('height', (d: DelaunayDataRow) => this.series.getSerieByTarget(d[4])?.pointSize);
.attr('height', (d: DelaunayDataRow) => this.series.getSerieByTarget(d[4])?.pointSize)
.style('fill', (d: DelaunayDataRow) => this.series.getSerieByTarget(d[4])?.color)
.style('pointer-events', (d: DelaunayDataRow) => this.series.getSerieByTarget(d[4])?.clickCallback ? 'auto' : 'none')
.style('cursor', (d: DelaunayDataRow) => this.series.getSerieByTarget(d[4])?.clickCallback ? 'pointer' : 'crosshair')
.on('click', (d: DelaunayDataRow) => {
d3.event.stopPropagation();
const serie = this.series.getSerieByTarget(d[4]);
const serieData = { target: serie?.target, class: serie?.class, alias: serie?.alias };
serie?.clickCallback(serieData, d);
});
}
getSeriesColorFromDataRow(values: DelaunayDataRow, rowIdx: number): string {

8
src/models/delaunay.ts

@ -1,4 +1,4 @@
import { ScatterData, PointType } from '../types';
import { ScatterData, PointType, DelaunayDataRow } from '../types';
import { ScatterSeries } from './scatter_series';
import { Delaunay } from 'd3-delaunay';
@ -6,12 +6,6 @@ import { Delaunay } from 'd3-delaunay';
import * as _ from 'lodash';
import * as d3 from 'd3'; // only types
// return type row: [ 0:x, 1:y, 2:(custom value | null), 3:pointIdx, 4:serie.target ]
type Value = number;
type PointIdx = number;
type Target = string;
export type DelaunayDataRow = [Value, Value, Value | null, PointIdx, Target];
export class DelaunayDiagram {
private _delaunayData: DelaunayDataRow[];
private _delaunayDiagram: any;

7
src/models/scatter_series.ts

@ -1,15 +1,16 @@
import { CoreSeries } from '@chartwerk/core';
import { ScatterData, PointType, LineType } from '../types';
import { ScatterData, PointType, LineType, ScatterDataParams } from '../types';
import * as _ from 'lodash';
const DEFAULT_POINT_SIZE = 4;
const SCATTER_DATA_DEFAULTS = {
const SCATTER_DATA_DEFAULTS: ScatterDataParams = {
pointType: PointType.CIRCLE,
lineType: LineType.NONE,
pointSize: DEFAULT_POINT_SIZE,
colorFormatter: undefined
colorFormatter: undefined,
clickCallback: undefined,
};
export class ScatterSeries extends CoreSeries<ScatterData> {

12
src/types.ts

@ -1,11 +1,12 @@
import { Serie, Options } from '@chartwerk/core';
type ScatterDataParams = {
export type ScatterDataParams = {
pointType: PointType;
lineType: LineType;
pointSize: number;
colorFormatter?: ColorFormatter
colorFormatter?: ColorFormatter;
clickCallback?: ( metricData: { target: Target, class: string, alias: string }, pointData?: DelaunayDataRow) => void;
}
type ScatterOptionsParams = {
// TODO: this options is not used anywhere, let's remove it
@ -49,3 +50,10 @@ export type HighlightedData = {
pointIdx: number, totalPointIdx: number,
serieInfo: { target: string, alias?: string, class?: string, idx?: number }
}
type Value = number;
type PointIdx = number;
type Target = string;
// type row: [ 0:x, 1:y, 2:(custom value | null), 3:pointIdx, 4:serie.target ]
export type DelaunayDataRow = [Value, Value, Value | null, PointIdx, Target];

6
yarn.lock

@ -6,12 +6,12 @@ __metadata:
cacheKey: 8
"@chartwerk/core@npm:latest":
version: 0.6.6
resolution: "@chartwerk/core@npm:0.6.6"
version: 0.6.10
resolution: "@chartwerk/core@npm:0.6.10"
dependencies:
d3: ^5.7.2
lodash: ^4.14.149
checksum: 2f07c389c7af34dfb79a47a2e47c6c19540df6a85bad21606e28297eaaad6849b2fd1f62710882729274b38448578d2cc2985a3ec01159bb600dfcf2818fe71d
checksum: 6a7f187b77878f20ba696a2bbd843bb57d8891efd69e578c946f56f501f679531efa42a33aa243b7fb5e52f6ca06a49a357fb37bcf99d8c32c1c46e4d27fcb2d
languageName: node
linkType: hard

Loading…
Cancel
Save