@reside-ic/skadi-chart 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +266 -0
- package/dist/skadi-chart.d.ts +290 -0
- package/dist/skadi-chart.js +8024 -0
- package/dist/skadi-chart.umd.cjs +22 -0
- package/package.json +59 -0
package/README.md
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
# Skadi Chart
|
|
2
|
+
|
|
3
|
+
This charting library provides a structured and thin wrapper around [d3](https://d3js.org)
|
|
4
|
+
to provide an fully flexible and extensible interface to plot customised graphs that
|
|
5
|
+
out-of-the-box solutions haven't prepared for.
|
|
6
|
+
|
|
7
|
+
There are many examples in [src/demo/App.vue](./src/demo/App.vue) which are used in a Vue context
|
|
8
|
+
however this library will work with TypeScript or JavaScript too. Developer facing docs are in
|
|
9
|
+
[DEV_README](./DEV_README.md).
|
|
10
|
+
|
|
11
|
+
# Installation
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
npm i @reside-ic/skadi-chart
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
# Usage
|
|
18
|
+
|
|
19
|
+
## Example
|
|
20
|
+
|
|
21
|
+
Here is a quick example of using Skadi chart:
|
|
22
|
+
|
|
23
|
+
```html
|
|
24
|
+
<div id="chart"></div>
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import {
|
|
29
|
+
Lines,
|
|
30
|
+
ScatterPoints,
|
|
31
|
+
TooltipHtmlCallback,
|
|
32
|
+
Scales,
|
|
33
|
+
OptionalLayer,
|
|
34
|
+
LayerType,
|
|
35
|
+
LayerArgs
|
|
36
|
+
} from "@reside-ic/skadi-chart";
|
|
37
|
+
|
|
38
|
+
// get element from html document
|
|
39
|
+
const chart = document.getElementById("chart") as HTMLDivElement;
|
|
40
|
+
|
|
41
|
+
// example custom metadata: define a type that you can attach to lines or scatter points
|
|
42
|
+
type Metadata = { type: "line" | "point" }
|
|
43
|
+
|
|
44
|
+
// two straight lines
|
|
45
|
+
const lines: Lines<Metadata> = [
|
|
46
|
+
{
|
|
47
|
+
points: [
|
|
48
|
+
{ x: 0, y: 0 },
|
|
49
|
+
{ x: 1, y: 1 },
|
|
50
|
+
],
|
|
51
|
+
style: { color: "black" },
|
|
52
|
+
metadata: { type: "line" }
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
points: [
|
|
56
|
+
{ x: 0, y: 0 },
|
|
57
|
+
{ x: 1, y: 2 },
|
|
58
|
+
],
|
|
59
|
+
style: { color: "red" },
|
|
60
|
+
metadata: { type: "line" }
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
// two points
|
|
65
|
+
const points: ScatterPoints<Metadata> = [
|
|
66
|
+
{
|
|
67
|
+
x: 0.5, y: 0.5,
|
|
68
|
+
style: { radius: 2 },
|
|
69
|
+
metadata: { type: "point" }
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
x: 0.5, y: 1,
|
|
73
|
+
style: { radius: 1 },
|
|
74
|
+
metadata: { type: "point" }
|
|
75
|
+
},
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
// custom tooltip with html string
|
|
79
|
+
const tooltipHtmlCallback: TooltipHtmlCallback = ({ x, y, metadata }) => {
|
|
80
|
+
return `<p>Point x=${x}, y=${y} is a ${metadata.type}</p>`
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// define x axis scale. The chart can compute y by autoscaling based on
|
|
84
|
+
// the data, or you could provide specific values for y here instead.
|
|
85
|
+
const scales: Scales = {
|
|
86
|
+
x: { start: 0, end: 1 }
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
// can extend Skadi chart with whatever functionality you'd like but it
|
|
90
|
+
// must fulfil the OptionalLayer contract
|
|
91
|
+
class CustomLayer extends OptionalLayer {
|
|
92
|
+
type = LayerType.Custom;
|
|
93
|
+
constructor() { super() };
|
|
94
|
+
|
|
95
|
+
// adds a black circle to the svg
|
|
96
|
+
draw(layerArgs: LayerArgs): void {
|
|
97
|
+
const svg = layerArgs.coreLayers[LayerType.Svg];
|
|
98
|
+
const { getHtmlId } = layerArgs;
|
|
99
|
+
svg.append("svg:circle")
|
|
100
|
+
.attr("id", `${getHtmlId(this.type)}-circle`)
|
|
101
|
+
.attr("cx", "50%")
|
|
102
|
+
.attr("cy", "50%")
|
|
103
|
+
.attr("r", "5%")
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
new Chart()
|
|
108
|
+
.addAxes()
|
|
109
|
+
.addTraces(lines)
|
|
110
|
+
.addScatterPoints(points)
|
|
111
|
+
.addGridLines()
|
|
112
|
+
.addZoom()
|
|
113
|
+
.addTooltips(tooltipHtmlCallback)
|
|
114
|
+
.addCustomLayer(new CustomLayer())
|
|
115
|
+
.addCustomLifecycleHooks({ beforeZoom() { console.log("triggering before zoom") } })
|
|
116
|
+
.makeResponsive()
|
|
117
|
+
.appendTo(chart, scales);
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
# More details
|
|
121
|
+
|
|
122
|
+
## Base chart class
|
|
123
|
+
|
|
124
|
+
All charts start with the `Chart` class that takes in `ChartOptions` (e.g. `animationDuration`
|
|
125
|
+
in ms or `logScale`, see [here](./src/Chart.ts) for source code):
|
|
126
|
+
|
|
127
|
+
```ts
|
|
128
|
+
const chart = new Chart({ animationDuration: 500 });
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## Layers
|
|
132
|
+
|
|
133
|
+
Skadi chart works in layers. Each layer "adds" something to the graph but also is completely
|
|
134
|
+
optional.
|
|
135
|
+
|
|
136
|
+
### OptionalLayer and event handling
|
|
137
|
+
|
|
138
|
+
An optional layer in Skadi chart is a layer that extends the abstract class
|
|
139
|
+
[OptionalLayer](./src/layers/Layer.ts). This abstract class will expect the layers to define
|
|
140
|
+
a `draw` function that will be used when the layer is added to the svg.
|
|
141
|
+
|
|
142
|
+
Furthermore, it defines the lifecycle hooks a layer can plug into. Lifecycle hooks are how
|
|
143
|
+
the layers react to user events. For example, the layers can each define a `zoom` method that
|
|
144
|
+
the [ZoomLayer](./src/layers/ZoomLayer.ts) will call on each of the layers when the user
|
|
145
|
+
selects an area to zoom into.
|
|
146
|
+
|
|
147
|
+
### Adding layers
|
|
148
|
+
|
|
149
|
+
To add a ready-made layer to the chart, call one of the methods below. The order of appending
|
|
150
|
+
layers does not matter however currently the multiplicity of layers does matter, i.e if you
|
|
151
|
+
add 2 [AxesLayer](./src/layers/AxesLayer.ts)s it will draw 2 of them which may be unintended.
|
|
152
|
+
These methods can also take some arguments that configure how the layers appear and examples
|
|
153
|
+
of each can be found in [src/demo/App.vue](./src/demo/App.vue). For now, this is just an
|
|
154
|
+
overview of the methods [Chart](./src/Chart.ts) class provides for adding layers:
|
|
155
|
+
|
|
156
|
+
* `addAxes` adds an [AxesLayer](./src/layers/AxesLayer.ts). This will draw axes with tick
|
|
157
|
+
marks. The axes can be autoscaled based on your data or you can provide a fixed scale in
|
|
158
|
+
the `appendTo` function below.
|
|
159
|
+
```ts
|
|
160
|
+
chart.addAxes();
|
|
161
|
+
```
|
|
162
|
+
* `addTraces` adds a [TracesLayer](./src/layers/TracesLayer.ts). This will add traces to
|
|
163
|
+
the graph. This data will also be used for autoscaling the axes if you haven't provided a
|
|
164
|
+
fixed scale.
|
|
165
|
+
```ts
|
|
166
|
+
chart.addTraces(lines);
|
|
167
|
+
```
|
|
168
|
+
* `addScatterPoints` add a [ScatterLayer](./src/layers/ScatterLayer.ts). This will add
|
|
169
|
+
scatter points to the graph. This data will also be used for autoscaling the axes if you
|
|
170
|
+
haven't provided a fixed scale.
|
|
171
|
+
```ts
|
|
172
|
+
chart.addScatterPoints(points);
|
|
173
|
+
```
|
|
174
|
+
* `addGridLines` adds a [GridLayer](./src/layers/GridLayer.ts). This will add gridlines
|
|
175
|
+
to the graph.
|
|
176
|
+
```ts
|
|
177
|
+
chart.addGridLines();
|
|
178
|
+
```
|
|
179
|
+
* `addZoom` adds a [ZoomLayer](./src/layers/ZoomLayer.ts) which will render a brush (let
|
|
180
|
+
the user draw a rectangle where they wish to zoom) and provide these extents to each layer.
|
|
181
|
+
Each layer itself defines how it zooms so this will let the user zoom on your graph.
|
|
182
|
+
```ts
|
|
183
|
+
chart.addZoom();
|
|
184
|
+
```
|
|
185
|
+
* `addTooltips` adds a [TooltipLayer](./src/layers/TooltipsLayer.ts) which adds tooltips
|
|
186
|
+
to the chart. For traces and points this means the tooltip will appear pointing to the
|
|
187
|
+
closest point in the graph to the cursor (once it is within a threshold). You must provide
|
|
188
|
+
a callback returning HTML to render the tooltip.
|
|
189
|
+
```ts
|
|
190
|
+
chart.addTooltips(tooltipHtmlCallback);
|
|
191
|
+
```
|
|
192
|
+
* `makeResponsive` is not really a layer but will make your graph responsive (redraw on change
|
|
193
|
+
to container bounds and changes to window size).
|
|
194
|
+
```ts
|
|
195
|
+
chart.makeResponsive();
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
#### Extending Skadi chart with custom layers
|
|
199
|
+
|
|
200
|
+
You can extend Skadi chart's functionality to suit your needs by defining a `CustomLayer`, as
|
|
201
|
+
long as it fulfils the contract of the class `OptionalLayer` found [here](./src/layers/Layer.ts).
|
|
202
|
+
Currently the `OptionalLayer` only requires you to define 2 things:
|
|
203
|
+
|
|
204
|
+
* the `type` of your `CustomLayer` which
|
|
205
|
+
should be `LayerType.Custom` (`LayerType` is an exported enum from the same file) in most cases.
|
|
206
|
+
* the `draw` function which will usually involve creating svg elements
|
|
207
|
+
* the `constructor` which needs to call `super`
|
|
208
|
+
|
|
209
|
+
In the example below, we define our `type` as `LayerType.Custom` and we define `draw` as adding a
|
|
210
|
+
black svg circle onto our graph using [d3.select](https://d3js.org/d3-selection/selecting).
|
|
211
|
+
|
|
212
|
+
We also declare a `beforeZoom` function to print a message before the zoom occurs. This is a
|
|
213
|
+
lifecycle hook that we can use to interact with the hook layer. For all the lifecycle hooks see
|
|
214
|
+
[here](./src/layers/Layer.ts).
|
|
215
|
+
|
|
216
|
+
```ts
|
|
217
|
+
class CustomLayer extends OptionalLayer {
|
|
218
|
+
type = LayerType.Custom;
|
|
219
|
+
constructor() { super() };
|
|
220
|
+
|
|
221
|
+
// adds a black circle to the svg
|
|
222
|
+
draw(layerArgs: LayerArgs): void {
|
|
223
|
+
const svg = layerArgs.coreLayers[LayerType.Svg];
|
|
224
|
+
const { getHtmlId } = layerArgs;
|
|
225
|
+
svg.append("svg:circle")
|
|
226
|
+
.attr("id", `${getHtmlId(this.type)}-circle`)
|
|
227
|
+
.attr("cx", "50%")
|
|
228
|
+
.attr("cy", "50%")
|
|
229
|
+
.attr("r", "5%")
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
beforeZoom() { console.log("triggering before zoom") }
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
chart.addCustomLayer(new CustomLayer());
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
If we didn't want to draw anything to the svg and instead wanted to execute some code
|
|
239
|
+
via the lifecycle hooks, the`addCustomLifecycleHooks` offers an easier interface to do
|
|
240
|
+
this. It is a convenience wrapper around `addCustomLayer`.
|
|
241
|
+
```ts
|
|
242
|
+
chart.addCustomLifecycleHooks({
|
|
243
|
+
beforeZoom() { console.log("triggering before zoom") }
|
|
244
|
+
});
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
## Drawing chart with all the layers
|
|
248
|
+
|
|
249
|
+
Once we have added all the layers, we must call `appendTo` function to draw the layers to the
|
|
250
|
+
screen. Without calling this function, nothing will be drawn to the screen. Here we can also
|
|
251
|
+
provide the scales to the graph if we want it to display a fixed scale rather than
|
|
252
|
+
automatically choosing a scale based on your data.
|
|
253
|
+
|
|
254
|
+
```ts
|
|
255
|
+
chart.appendTo(element, scales);
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
## Reactivity
|
|
259
|
+
|
|
260
|
+
There is some reactivity baked into Skadi chart via the lifecycle hooks, such as zooming. In
|
|
261
|
+
general however there is very little reactivity that Skadi chart offers, e.g. there are not
|
|
262
|
+
any functions that will remove layers after the chart is appended to the DOM.
|
|
263
|
+
|
|
264
|
+
The pattern we use for reactivity outside of the scope of lifecycle hooks is to recreate the
|
|
265
|
+
chart from scratch. The `appendTo` function will remove anything inside the chart `div` and
|
|
266
|
+
append the new `Chart` into it. To see examples of reactivity see [here](./src/demo/App.vue).
|
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
declare module "d3" {
|
|
2
|
+
import { select } from "d3-selection";
|
|
3
|
+
export { select };
|
|
4
|
+
export { type Axis, axisBottom, axisLeft } from "d3-axis";
|
|
5
|
+
export { line, type Line } from "d3-shape";
|
|
6
|
+
export { create, type BaseType, type Selection, type ClientPointEvent, pointer } from "d3-selection";
|
|
7
|
+
export { brush, type D3BrushEvent } from "d3-brush";
|
|
8
|
+
export { scaleBand, scaleLinear, scaleLog, type NumberValue, type ScaleBand, type ScaleContinuousNumeric } from "d3-scale";
|
|
9
|
+
}
|
|
10
|
+
declare module "types" {
|
|
11
|
+
import { ChartOptions } from "Chart";
|
|
12
|
+
import * as d3 from "d3";
|
|
13
|
+
import { LayerType, OptionalLayer } from "layers/Layer";
|
|
14
|
+
export type AxisType = 'x' | 'y';
|
|
15
|
+
export type XY<T> = Record<AxisType, T>;
|
|
16
|
+
export type Point = XY<number>;
|
|
17
|
+
export type PointWithMetadata<Metadata> = Point & {
|
|
18
|
+
metadata?: Metadata;
|
|
19
|
+
bands?: Partial<XY<string>>;
|
|
20
|
+
};
|
|
21
|
+
export type XYLabel = Partial<XY<string>>;
|
|
22
|
+
export type Bounds = {
|
|
23
|
+
width: number;
|
|
24
|
+
height: number;
|
|
25
|
+
margin: {
|
|
26
|
+
top: number;
|
|
27
|
+
bottom: number;
|
|
28
|
+
left: number;
|
|
29
|
+
right: number;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
export type D3Selection<Element extends d3.BaseType> = d3.Selection<Element, Point, null, undefined>;
|
|
33
|
+
export type AllOptionalLayers = OptionalLayer<any>;
|
|
34
|
+
export type ScaleNumeric = d3.ScaleContinuousNumeric<number, number, never>;
|
|
35
|
+
export type CategoricalScaleConfig = {
|
|
36
|
+
main: d3.ScaleBand<string>;
|
|
37
|
+
bands: Record<string, ScaleNumeric>;
|
|
38
|
+
};
|
|
39
|
+
export type TickConfig = {
|
|
40
|
+
count: number;
|
|
41
|
+
specifier?: string;
|
|
42
|
+
};
|
|
43
|
+
export type LayerArgs = {
|
|
44
|
+
id: string;
|
|
45
|
+
getHtmlId: (layer: LayerType) => string;
|
|
46
|
+
bounds: Bounds;
|
|
47
|
+
globals: {
|
|
48
|
+
animationDuration: number;
|
|
49
|
+
tickConfig: XY<TickConfig>;
|
|
50
|
+
};
|
|
51
|
+
scaleConfig: {
|
|
52
|
+
linearScales: XY<ScaleNumeric>;
|
|
53
|
+
scaleExtents: Scales;
|
|
54
|
+
categoricalScales: Partial<XY<CategoricalScaleConfig>>;
|
|
55
|
+
};
|
|
56
|
+
coreLayers: {
|
|
57
|
+
[LayerType.Svg]: D3Selection<SVGSVGElement>;
|
|
58
|
+
[LayerType.ClipPath]: D3Selection<SVGClipPathElement>;
|
|
59
|
+
[LayerType.BaseLayer]: D3Selection<SVGGElement>;
|
|
60
|
+
};
|
|
61
|
+
optionalLayers: AllOptionalLayers[];
|
|
62
|
+
chartOptions: ChartOptions;
|
|
63
|
+
};
|
|
64
|
+
export type ZoomExtents = XY<[number, number]>;
|
|
65
|
+
export type ZoomProperties = ZoomExtents & {
|
|
66
|
+
eventType: "brush" | "dblclick";
|
|
67
|
+
};
|
|
68
|
+
export type Scales = XY<{
|
|
69
|
+
start: number;
|
|
70
|
+
end: number;
|
|
71
|
+
}>;
|
|
72
|
+
export type PartialScales = Partial<XY<{
|
|
73
|
+
start?: number;
|
|
74
|
+
end?: number;
|
|
75
|
+
}>>;
|
|
76
|
+
export type LineStyle = {
|
|
77
|
+
color?: string;
|
|
78
|
+
opacity?: number;
|
|
79
|
+
strokeWidth?: number;
|
|
80
|
+
strokeDasharray?: string;
|
|
81
|
+
};
|
|
82
|
+
export type LineConfig<Metadata> = {
|
|
83
|
+
points: Point[];
|
|
84
|
+
style: LineStyle;
|
|
85
|
+
metadata?: Metadata;
|
|
86
|
+
bands?: Partial<XY<string>>;
|
|
87
|
+
};
|
|
88
|
+
export type Lines<Metadata> = LineConfig<Metadata>[];
|
|
89
|
+
export type ScatterPointStyle = {
|
|
90
|
+
radius?: number;
|
|
91
|
+
color?: string;
|
|
92
|
+
opacity?: number;
|
|
93
|
+
};
|
|
94
|
+
type ScatterPointConfig<Metadata> = PointWithMetadata<Metadata> & {
|
|
95
|
+
style: ScatterPointStyle;
|
|
96
|
+
};
|
|
97
|
+
export type ScatterPoints<Metadata> = ScatterPointConfig<Metadata>[];
|
|
98
|
+
}
|
|
99
|
+
declare module "layers/Layer" {
|
|
100
|
+
import { LayerArgs, ZoomExtents, ZoomProperties } from "types";
|
|
101
|
+
export enum LayerType {
|
|
102
|
+
Svg = "svg",
|
|
103
|
+
ClipPath = "clipPath",
|
|
104
|
+
BaseLayer = "baseLayer",
|
|
105
|
+
Axes = "axes",
|
|
106
|
+
Zoom = "zoom",
|
|
107
|
+
Trace = "trace",
|
|
108
|
+
Tooltip = "skadi-chart-tooltip",
|
|
109
|
+
Grid = "grid",
|
|
110
|
+
Scatter = "scatter",
|
|
111
|
+
Custom = "custom"
|
|
112
|
+
}
|
|
113
|
+
export abstract class OptionalLayer<Properties = null> {
|
|
114
|
+
abstract type: LayerType;
|
|
115
|
+
properties: Properties | null;
|
|
116
|
+
constructor();
|
|
117
|
+
abstract draw(layerArgs: LayerArgs, currentExtents: ZoomExtents): void;
|
|
118
|
+
brushStart(): void;
|
|
119
|
+
beforeZoom(_zoomProperties: ZoomProperties): void;
|
|
120
|
+
zoom(_zoomProperties: ZoomProperties): Promise<void>;
|
|
121
|
+
afterZoom(_zoomProperties: ZoomProperties | null): void;
|
|
122
|
+
}
|
|
123
|
+
export type LifecycleHooks = Omit<OptionalLayer, "type" | "properties" | "draw">;
|
|
124
|
+
}
|
|
125
|
+
declare module "layers/AxesLayer" {
|
|
126
|
+
import { LayerType, OptionalLayer } from "layers/Layer";
|
|
127
|
+
import { LayerArgs, XYLabel } from "types";
|
|
128
|
+
export class AxesLayer extends OptionalLayer {
|
|
129
|
+
labels: XYLabel;
|
|
130
|
+
type: LayerType;
|
|
131
|
+
constructor(labels: XYLabel);
|
|
132
|
+
private drawAxis;
|
|
133
|
+
draw: (layerArgs: LayerArgs) => void;
|
|
134
|
+
private drawCategoricalAxis;
|
|
135
|
+
private drawNumericalAxis;
|
|
136
|
+
private drawLinePerpendicularToAxis;
|
|
137
|
+
private axisConfig;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
declare module "helpers" {
|
|
141
|
+
import { LayerArgs, ScaleNumeric, XY } from "types";
|
|
142
|
+
export const numScales: (bands: Partial<XY<string>> | undefined, layerArgs: LayerArgs) => XY<ScaleNumeric>;
|
|
143
|
+
}
|
|
144
|
+
declare module "layers/TracesLayer" {
|
|
145
|
+
import { LayerArgs, Lines, Point, ZoomExtents } from "types";
|
|
146
|
+
import { LayerType, OptionalLayer } from "layers/Layer";
|
|
147
|
+
export type TracesOptions = {
|
|
148
|
+
RDPEpsilon: number | null;
|
|
149
|
+
};
|
|
150
|
+
export const RDPAlgorithm: (linesSC: Point[][], epsilon: number) => Point[][];
|
|
151
|
+
export class TracesLayer<Metadata> extends OptionalLayer {
|
|
152
|
+
linesDC: Lines<Metadata>;
|
|
153
|
+
options: TracesOptions;
|
|
154
|
+
type: LayerType;
|
|
155
|
+
private traces;
|
|
156
|
+
private lowResLinesSC;
|
|
157
|
+
private getNewPoint;
|
|
158
|
+
constructor(linesDC: Lines<Metadata>, options: TracesOptions);
|
|
159
|
+
private customTween;
|
|
160
|
+
private round;
|
|
161
|
+
private getNewSvgPoint;
|
|
162
|
+
private customLineGen;
|
|
163
|
+
private updateLowResLinesSC;
|
|
164
|
+
draw: (layerArgs: LayerArgs, currentExtentsDC: ZoomExtents) => void;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
declare module "layers/ZoomLayer" {
|
|
168
|
+
import { LayerType, OptionalLayer } from "layers/Layer";
|
|
169
|
+
import { D3Selection, LayerArgs } from "types";
|
|
170
|
+
export type ZoomOptions = {
|
|
171
|
+
lockAxis: "x" | "y" | null;
|
|
172
|
+
};
|
|
173
|
+
export class ZoomLayer extends OptionalLayer {
|
|
174
|
+
options: ZoomOptions;
|
|
175
|
+
type: LayerType;
|
|
176
|
+
zooming: boolean;
|
|
177
|
+
selectionMask: D3Selection<SVGRectElement> | null;
|
|
178
|
+
overlay: D3Selection<SVGRectElement> | null;
|
|
179
|
+
constructor(options: ZoomOptions);
|
|
180
|
+
private processSelection;
|
|
181
|
+
private handleZoom;
|
|
182
|
+
private handleBrushEnd;
|
|
183
|
+
private handleBrushMove;
|
|
184
|
+
draw: (layerArgs: LayerArgs) => void;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
declare module "layers/ScatterLayer" {
|
|
188
|
+
import { LayerArgs, ScatterPoints } from "types";
|
|
189
|
+
import { LayerType, OptionalLayer } from "layers/Layer";
|
|
190
|
+
export class ScatterLayer<Metadata> extends OptionalLayer {
|
|
191
|
+
points: ScatterPoints<Metadata>;
|
|
192
|
+
type: LayerType;
|
|
193
|
+
constructor(points: ScatterPoints<Metadata>);
|
|
194
|
+
draw: (layerArgs: LayerArgs) => void;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
declare module "layers/TooltipsLayer" {
|
|
198
|
+
import { LayerType, OptionalLayer } from "layers/Layer";
|
|
199
|
+
import { LayerArgs, PointWithMetadata } from "types";
|
|
200
|
+
export type TooltipHtmlCallback<Metadata> = (pointWithMetadata: PointWithMetadata<Metadata>) => string;
|
|
201
|
+
export class TooltipsLayer<Metadata> extends OptionalLayer {
|
|
202
|
+
tooltipHtmlCallback: TooltipHtmlCallback<Metadata>;
|
|
203
|
+
type: LayerType;
|
|
204
|
+
tooltipRadiusSq: number;
|
|
205
|
+
constructor(tooltipHtmlCallback: TooltipHtmlCallback<Metadata>);
|
|
206
|
+
private getDistanceSq;
|
|
207
|
+
private getDistanceSqSC;
|
|
208
|
+
private convertSCPointToCC;
|
|
209
|
+
private handleMouseMove;
|
|
210
|
+
draw: (layerArgs: LayerArgs) => void;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
declare module "layers/GridLayer" {
|
|
214
|
+
import { LayerArgs } from "types";
|
|
215
|
+
import { LayerType, OptionalLayer } from "layers/Layer";
|
|
216
|
+
export class GridLayer extends OptionalLayer {
|
|
217
|
+
type: LayerType;
|
|
218
|
+
constructor();
|
|
219
|
+
draw: (layerArgs: LayerArgs) => void;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
declare module "Chart" {
|
|
223
|
+
import { TracesOptions } from "layers/TracesLayer";
|
|
224
|
+
import { ZoomOptions } from "layers/ZoomLayer";
|
|
225
|
+
import { TooltipHtmlCallback } from "layers/TooltipsLayer";
|
|
226
|
+
import { AllOptionalLayers, Lines, PartialScales, Scales, ScatterPoints, XY, XYLabel } from "types";
|
|
227
|
+
import { LifecycleHooks, OptionalLayer } from "layers/Layer";
|
|
228
|
+
export type ChartOptions = {
|
|
229
|
+
logScale: XY<boolean>;
|
|
230
|
+
};
|
|
231
|
+
type PartialChartOptions = {
|
|
232
|
+
logScale?: Partial<XY<boolean>>;
|
|
233
|
+
animationDuration?: number;
|
|
234
|
+
};
|
|
235
|
+
type CategoricalScales = Partial<XY<string[]>>;
|
|
236
|
+
export class Chart<Metadata = any> {
|
|
237
|
+
id: string;
|
|
238
|
+
optionalLayers: AllOptionalLayers[];
|
|
239
|
+
isResponsive: boolean;
|
|
240
|
+
globals: {
|
|
241
|
+
animationDuration: number;
|
|
242
|
+
tickConfig: {
|
|
243
|
+
x: {
|
|
244
|
+
count: number;
|
|
245
|
+
};
|
|
246
|
+
y: {
|
|
247
|
+
count: number;
|
|
248
|
+
specifier: string;
|
|
249
|
+
};
|
|
250
|
+
};
|
|
251
|
+
};
|
|
252
|
+
defaultMargin: {
|
|
253
|
+
top: number;
|
|
254
|
+
bottom: number;
|
|
255
|
+
left: number;
|
|
256
|
+
right: number;
|
|
257
|
+
};
|
|
258
|
+
exportToPng: ((name?: string) => void) | null;
|
|
259
|
+
options: ChartOptions;
|
|
260
|
+
autoscaledMaxExtents: Scales;
|
|
261
|
+
constructor(options?: PartialChartOptions);
|
|
262
|
+
addAxes: (labels?: XYLabel) => this;
|
|
263
|
+
addGridLines: () => this;
|
|
264
|
+
private filterLinesForLogAxis;
|
|
265
|
+
private filterLines;
|
|
266
|
+
addTraces: (lines: Lines<Metadata>, options?: Partial<TracesOptions>) => this;
|
|
267
|
+
addZoom: (options?: ZoomOptions) => this;
|
|
268
|
+
addTooltips: (tooltipHtmlCallback: TooltipHtmlCallback<Metadata>) => this;
|
|
269
|
+
private filterScatterPointsForLogAxis;
|
|
270
|
+
private filterScatterPoints;
|
|
271
|
+
addScatterPoints: (points: ScatterPoints<Metadata>) => this;
|
|
272
|
+
addCustomLifecycleHooks: (lifecycleHooks: Partial<LifecycleHooks>) => this;
|
|
273
|
+
addCustomLayer: (customLayer: OptionalLayer) => this;
|
|
274
|
+
makeResponsive: () => this;
|
|
275
|
+
private getXYMinMax;
|
|
276
|
+
private addLinearPadding;
|
|
277
|
+
private addLogPadding;
|
|
278
|
+
private processScales;
|
|
279
|
+
private draw;
|
|
280
|
+
appendTo: (baseElement: HTMLDivElement, maxExtents?: PartialScales, initialExtents?: PartialScales, categoricalScales?: CategoricalScales) => this;
|
|
281
|
+
private createCategoricalScale;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
declare module "skadi-chart" {
|
|
285
|
+
import { Chart, ChartOptions } from "Chart";
|
|
286
|
+
import { Lines, Scales, ZoomExtents, ZoomProperties, LayerArgs, ScatterPoints, LineStyle, ScatterPointStyle, Point } from "types";
|
|
287
|
+
import { OptionalLayer, LayerType } from "layers/Layer";
|
|
288
|
+
export { Chart, OptionalLayer, LayerType };
|
|
289
|
+
export type { Lines, Scales, ZoomExtents, ZoomProperties, LayerArgs, ScatterPoints, LineStyle, ScatterPointStyle, Point, ChartOptions };
|
|
290
|
+
}
|