@fc-plot/ts-graph 0.16.3 → 0.17.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/dist/BundleReport.html +2 -2
- package/dist/index.js +1 -1
- package/examples/index.js +39 -23
- package/package.json +1 -1
- package/src/getNearestPoints.ts +36 -17
- package/src/index.ts +294 -168
- package/src/interface.ts +164 -160
- package/src/line.ts +51 -26
- package/src/tooltip.ts +125 -63
- package/src/yAxis.ts +35 -19
package/src/interface.ts
CHANGED
|
@@ -1,148 +1,150 @@
|
|
|
1
1
|
export type TsGraphType = {
|
|
2
|
-
[index: string]: any
|
|
3
|
-
}
|
|
2
|
+
[index: string]: any;
|
|
3
|
+
};
|
|
4
4
|
|
|
5
|
-
export type Timestamp =
|
|
5
|
+
export type Timestamp = "x" | "X";
|
|
6
6
|
|
|
7
7
|
export type BaseOptions = {
|
|
8
|
-
xkey: number | string
|
|
9
|
-
ykey: number | string
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
xkey: number | string;
|
|
9
|
+
ykey: number | string;
|
|
10
|
+
ykey2?: number | string;
|
|
11
|
+
ykeyFormatter?: (value: number | string) => number;
|
|
12
|
+
oykey: string;
|
|
13
|
+
timestamp: Timestamp;
|
|
14
|
+
};
|
|
14
15
|
|
|
15
16
|
export type Chart = {
|
|
16
|
-
id: string
|
|
17
|
-
scope?: string
|
|
18
|
-
colors: string[]
|
|
19
|
-
width: number
|
|
20
|
-
height: number
|
|
21
|
-
marginTop: number
|
|
22
|
-
marginRight: number
|
|
23
|
-
marginBottom: number
|
|
24
|
-
marginLeft: number
|
|
25
|
-
renderTo: HTMLElement
|
|
26
|
-
containerWidth: number
|
|
27
|
-
containerHeight: number
|
|
28
|
-
}
|
|
17
|
+
id: string;
|
|
18
|
+
scope?: string;
|
|
19
|
+
colors: string[];
|
|
20
|
+
width: number;
|
|
21
|
+
height: number;
|
|
22
|
+
marginTop: number;
|
|
23
|
+
marginRight: number;
|
|
24
|
+
marginBottom: number;
|
|
25
|
+
marginLeft: number;
|
|
26
|
+
renderTo: HTMLElement;
|
|
27
|
+
containerWidth: number;
|
|
28
|
+
containerHeight: number;
|
|
29
|
+
};
|
|
29
30
|
|
|
30
31
|
export type PlotLine = {
|
|
31
|
-
value: number
|
|
32
|
-
color: string
|
|
33
|
-
}
|
|
32
|
+
value: number;
|
|
33
|
+
color: string;
|
|
34
|
+
};
|
|
34
35
|
|
|
35
36
|
export type XAxis = {
|
|
36
|
-
visible: boolean
|
|
37
|
-
lineColor: string
|
|
38
|
-
lineWidth: number
|
|
39
|
-
tickLength: number
|
|
40
|
-
tickpadding: number
|
|
41
|
-
tickColor: string
|
|
37
|
+
visible: boolean;
|
|
38
|
+
lineColor: string;
|
|
39
|
+
lineWidth: number;
|
|
40
|
+
tickLength: number;
|
|
41
|
+
tickpadding: number;
|
|
42
|
+
tickColor: string;
|
|
42
43
|
labels: {
|
|
43
|
-
color: string
|
|
44
|
-
fontSize: number
|
|
45
|
-
timeFormat?: string
|
|
46
|
-
}
|
|
47
|
-
plotLines: PlotLine[]
|
|
48
|
-
ticks?: Date[]
|
|
49
|
-
}
|
|
44
|
+
color: string;
|
|
45
|
+
fontSize: number;
|
|
46
|
+
timeFormat?: string; // %Y:%m:%d %H:%M:%S
|
|
47
|
+
};
|
|
48
|
+
plotLines: PlotLine[];
|
|
49
|
+
ticks?: Date[];
|
|
50
|
+
};
|
|
50
51
|
|
|
51
52
|
export type YAxis = {
|
|
52
|
-
visible: boolean
|
|
53
|
-
min: number
|
|
54
|
-
max: number
|
|
55
|
-
lineColor: string
|
|
56
|
-
lineWidth: number
|
|
57
|
-
tickLength: number
|
|
58
|
-
tickpadding: number
|
|
59
|
-
tickColor: string
|
|
60
|
-
gridLineColor: string
|
|
53
|
+
visible: boolean;
|
|
54
|
+
min: number;
|
|
55
|
+
max: number;
|
|
56
|
+
lineColor: string;
|
|
57
|
+
lineWidth: number;
|
|
58
|
+
tickLength: number;
|
|
59
|
+
tickpadding: number;
|
|
60
|
+
tickColor: string;
|
|
61
|
+
gridLineColor: string;
|
|
61
62
|
labels: {
|
|
62
|
-
color: string
|
|
63
|
-
shadowColor: string
|
|
64
|
-
fontSize: number
|
|
63
|
+
color: string;
|
|
64
|
+
shadowColor: string;
|
|
65
|
+
fontSize: number;
|
|
65
66
|
style: {
|
|
66
|
-
fontSize: number
|
|
67
|
-
color: string
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
plotLines: PlotLine[]
|
|
71
|
-
tickValueFormatter?: (value: number) => string
|
|
72
|
-
}
|
|
67
|
+
fontSize: number;
|
|
68
|
+
color: string;
|
|
69
|
+
};
|
|
70
|
+
};
|
|
71
|
+
plotLines: PlotLine[];
|
|
72
|
+
tickValueFormatter?: (value: number) => string;
|
|
73
|
+
};
|
|
73
74
|
|
|
74
75
|
export type SerieDataItemMarker = {
|
|
75
|
-
enabled: boolean
|
|
76
|
-
radius: number
|
|
77
|
-
}
|
|
76
|
+
enabled: boolean;
|
|
77
|
+
radius: number;
|
|
78
|
+
};
|
|
78
79
|
|
|
79
80
|
export type SerieDataItem = {
|
|
80
|
-
[index: string]: any
|
|
81
|
-
marker?: SerieDataItemMarker
|
|
82
|
-
timestamp?: number
|
|
83
|
-
value?: number
|
|
84
|
-
}
|
|
81
|
+
[index: string]: any;
|
|
82
|
+
marker?: SerieDataItemMarker;
|
|
83
|
+
timestamp?: number;
|
|
84
|
+
value?: number;
|
|
85
|
+
};
|
|
85
86
|
|
|
86
87
|
export interface Serie {
|
|
87
|
-
name: string
|
|
88
|
-
color: string
|
|
89
|
-
visible: boolean
|
|
90
|
-
data: SerieDataItem[]
|
|
91
|
-
lineDash?: number[]
|
|
92
|
-
zIndex?: number
|
|
88
|
+
name: string;
|
|
89
|
+
color: string;
|
|
90
|
+
visible: boolean;
|
|
91
|
+
data: SerieDataItem[];
|
|
92
|
+
lineDash?: number[];
|
|
93
|
+
zIndex?: number;
|
|
94
|
+
opacity?: number;
|
|
93
95
|
}
|
|
94
96
|
|
|
95
|
-
export type Series = Serie[]
|
|
97
|
+
export type Series = Serie[];
|
|
96
98
|
|
|
97
99
|
export type Point = {
|
|
98
|
-
name: string
|
|
99
|
-
color: string
|
|
100
|
-
x: number
|
|
101
|
-
y: number
|
|
102
|
-
timestamp: number
|
|
103
|
-
value: number
|
|
104
|
-
origin: number
|
|
105
|
-
serieIndex: number
|
|
106
|
-
filledNull?: number
|
|
107
|
-
serieOptions: Serie
|
|
108
|
-
}
|
|
100
|
+
name: string;
|
|
101
|
+
color: string;
|
|
102
|
+
x: number;
|
|
103
|
+
y: number;
|
|
104
|
+
timestamp: number;
|
|
105
|
+
value: number;
|
|
106
|
+
origin: number;
|
|
107
|
+
serieIndex: number;
|
|
108
|
+
filledNull?: number;
|
|
109
|
+
serieOptions: Serie;
|
|
110
|
+
};
|
|
109
111
|
|
|
110
112
|
export type Tooltip = {
|
|
111
|
-
precision: number |
|
|
112
|
-
shared: boolean
|
|
113
|
-
sharedSortDirection:
|
|
114
|
-
formatter: (points: Point[], originalPoints: Point[]) => string
|
|
115
|
-
cascade: boolean
|
|
116
|
-
cascadeScope?: string
|
|
117
|
-
timeFormat: string
|
|
113
|
+
precision: number | "origin" | "short";
|
|
114
|
+
shared: boolean;
|
|
115
|
+
sharedSortDirection: "asc" | "desc";
|
|
116
|
+
formatter: (points: Point[], originalPoints: Point[]) => string;
|
|
117
|
+
cascade: boolean;
|
|
118
|
+
cascadeScope?: string;
|
|
119
|
+
timeFormat: string;
|
|
118
120
|
pointValueformatter?: (value: number) => string;
|
|
119
|
-
}
|
|
121
|
+
};
|
|
120
122
|
|
|
121
123
|
export type Legend = {
|
|
122
|
-
align: string
|
|
123
|
-
verticalAlign: string
|
|
124
|
-
enabled: boolean
|
|
125
|
-
}
|
|
124
|
+
align: string;
|
|
125
|
+
verticalAlign: string;
|
|
126
|
+
enabled: boolean;
|
|
127
|
+
};
|
|
126
128
|
|
|
127
129
|
export type Time = {
|
|
128
|
-
timezoneOffset: number
|
|
129
|
-
}
|
|
130
|
+
timezoneOffset: number;
|
|
131
|
+
};
|
|
130
132
|
|
|
131
133
|
export type NearestPoint = {
|
|
132
|
-
name: string
|
|
133
|
-
color: string
|
|
134
|
-
timestamp: number
|
|
135
|
-
value: number
|
|
136
|
-
origin: number
|
|
137
|
-
serieIndex: number
|
|
138
|
-
filledNull?: number
|
|
139
|
-
serieOptions: Serie
|
|
140
|
-
}
|
|
134
|
+
name: string;
|
|
135
|
+
color: string;
|
|
136
|
+
timestamp: number;
|
|
137
|
+
value: number;
|
|
138
|
+
origin: number;
|
|
139
|
+
serieIndex: number;
|
|
140
|
+
filledNull?: number;
|
|
141
|
+
serieOptions: Serie;
|
|
142
|
+
};
|
|
141
143
|
|
|
142
144
|
export interface GetNearestPointsFnParam extends BaseOptions {
|
|
143
|
-
series: Series
|
|
144
|
-
x: Date
|
|
145
|
-
fillNull: undefined | number
|
|
145
|
+
series: Series;
|
|
146
|
+
x: Date;
|
|
147
|
+
fillNull: undefined | number;
|
|
146
148
|
}
|
|
147
149
|
|
|
148
150
|
export interface Shape {
|
|
@@ -155,41 +157,41 @@ export interface Shape {
|
|
|
155
157
|
}
|
|
156
158
|
|
|
157
159
|
export interface Options extends BaseOptions {
|
|
158
|
-
ratio: number
|
|
159
|
-
chart: Chart
|
|
160
|
-
xAxis: XAxis
|
|
161
|
-
yAxis: YAxis
|
|
162
|
-
tooltip: Tooltip
|
|
163
|
-
type:
|
|
160
|
+
ratio: number;
|
|
161
|
+
chart: Chart;
|
|
162
|
+
xAxis: XAxis;
|
|
163
|
+
yAxis: YAxis;
|
|
164
|
+
tooltip: Tooltip;
|
|
165
|
+
type: "line" | "bar";
|
|
164
166
|
line: {
|
|
165
|
-
width: number
|
|
166
|
-
}
|
|
167
|
+
width: number;
|
|
168
|
+
};
|
|
167
169
|
area: {
|
|
168
|
-
opacity: number
|
|
169
|
-
}
|
|
170
|
+
opacity: number;
|
|
171
|
+
};
|
|
170
172
|
stack: {
|
|
171
|
-
enabled: boolean
|
|
172
|
-
}
|
|
173
|
+
enabled: boolean;
|
|
174
|
+
};
|
|
173
175
|
curve: {
|
|
174
|
-
enabled: boolean
|
|
175
|
-
mode:
|
|
176
|
-
}
|
|
177
|
-
series: Serie[]
|
|
178
|
-
notDisplayedSeries: string[]
|
|
179
|
-
legend: Legend
|
|
180
|
-
time: Time
|
|
181
|
-
fillNull: undefined | number
|
|
182
|
-
xmin: number
|
|
183
|
-
xmax: number
|
|
184
|
-
ymin: number
|
|
185
|
-
ymax: number
|
|
186
|
-
shapes: any[]
|
|
187
|
-
onClick: (d3Event: any, date: Date, value: number) => any
|
|
188
|
-
onRightClick: (d3Event: any, date: Date, value: number) => any
|
|
189
|
-
onZoom: (getZoomedSeries: () => Series) => any
|
|
190
|
-
onZoomWithoutDefult?: (times?: Date[]) => any
|
|
191
|
-
onShapeMouseOver: (event: any, shape: Shape) => any
|
|
192
|
-
onShapeClick: (event: any, shape: Shape) => any
|
|
176
|
+
enabled: boolean;
|
|
177
|
+
mode: "smooth"; // 'step' | 'stepAfter' | 'stepBefore'
|
|
178
|
+
};
|
|
179
|
+
series: Serie[];
|
|
180
|
+
notDisplayedSeries: string[];
|
|
181
|
+
legend: Legend;
|
|
182
|
+
time: Time;
|
|
183
|
+
fillNull: undefined | number;
|
|
184
|
+
xmin: number;
|
|
185
|
+
xmax: number;
|
|
186
|
+
ymin: number;
|
|
187
|
+
ymax: number;
|
|
188
|
+
shapes: any[];
|
|
189
|
+
onClick: (d3Event: any, date: Date, value: number) => any;
|
|
190
|
+
onRightClick: (d3Event: any, date: Date, value: number) => any;
|
|
191
|
+
onZoom: (getZoomedSeries: () => Series) => any;
|
|
192
|
+
onZoomWithoutDefult?: (times?: Date[]) => any;
|
|
193
|
+
onShapeMouseOver: (event: any, shape: Shape) => any;
|
|
194
|
+
onShapeClick: (event: any, shape: Shape) => any;
|
|
193
195
|
}
|
|
194
196
|
|
|
195
197
|
export type EventPosition = {
|
|
@@ -199,33 +201,35 @@ export type EventPosition = {
|
|
|
199
201
|
offsetY: number;
|
|
200
202
|
layerX: number;
|
|
201
203
|
layerY: number;
|
|
202
|
-
}
|
|
204
|
+
};
|
|
203
205
|
|
|
204
|
-
export type Transform =
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
206
|
+
export type Transform =
|
|
207
|
+
| {
|
|
208
|
+
rescaleX: (xScales: any) => any;
|
|
209
|
+
k: number;
|
|
210
|
+
x: number;
|
|
211
|
+
y: number;
|
|
212
|
+
}
|
|
213
|
+
| undefined;
|
|
210
214
|
|
|
211
215
|
export interface WorkerPostMessage extends BaseOptions {
|
|
212
|
-
id?: string
|
|
213
|
-
str?: string
|
|
214
|
-
flag?: boolean
|
|
215
|
-
x: Date
|
|
216
|
-
fillNull: undefined | number
|
|
216
|
+
id?: string;
|
|
217
|
+
str?: string;
|
|
218
|
+
flag?: boolean;
|
|
219
|
+
x: Date;
|
|
220
|
+
fillNull: undefined | number;
|
|
217
221
|
}
|
|
218
222
|
|
|
219
223
|
export interface XScales {
|
|
220
|
-
(a: number | Date): number
|
|
221
|
-
invert(value: number | { valueOf(): number }): Date
|
|
222
|
-
ticks(value: number): Date[]
|
|
224
|
+
(a: number | Date): number;
|
|
225
|
+
invert(value: number | { valueOf(): number }): Date;
|
|
226
|
+
ticks(value: number): Date[];
|
|
223
227
|
}
|
|
224
228
|
|
|
225
229
|
export interface YScales {
|
|
226
|
-
(a: number): number
|
|
227
|
-
domain(value: number[]): any
|
|
228
|
-
nice(value: number): any
|
|
229
|
-
ticks(value: number): number[]
|
|
230
|
-
invert(value: number | { valueOf(): number }): number
|
|
230
|
+
(a: number): number;
|
|
231
|
+
domain(value: number[]): any;
|
|
232
|
+
nice(value: number): any;
|
|
233
|
+
ticks(value: number): number[];
|
|
234
|
+
invert(value: number | { valueOf(): number }): number;
|
|
231
235
|
}
|
package/src/line.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import * as d3 from
|
|
2
|
-
import { sortBy } from
|
|
3
|
-
import { getColor } from
|
|
4
|
-
import { Options, Serie, SerieDataItem, XScales, YScales } from
|
|
1
|
+
import * as d3 from "d3";
|
|
2
|
+
import { sortBy } from "lodash";
|
|
3
|
+
import { getColor } from "./utils";
|
|
4
|
+
import { Options, Serie, SerieDataItem, XScales, YScales } from "./interface";
|
|
5
5
|
|
|
6
6
|
export default class Line {
|
|
7
7
|
options: Options;
|
|
@@ -12,31 +12,42 @@ export default class Line {
|
|
|
12
12
|
}
|
|
13
13
|
|
|
14
14
|
draw(xScales: XScales, yScales: YScales) {
|
|
15
|
-
const {
|
|
15
|
+
const {
|
|
16
|
+
series,
|
|
17
|
+
chart: { colors, height },
|
|
18
|
+
xAxis,
|
|
19
|
+
xkey,
|
|
20
|
+
ykey,
|
|
21
|
+
ykey2,
|
|
22
|
+
timestamp,
|
|
23
|
+
fillNull,
|
|
24
|
+
notDisplayedSeries,
|
|
25
|
+
curve,
|
|
26
|
+
} = this.options;
|
|
16
27
|
const { width: lineWidth } = this.options.line;
|
|
17
28
|
const { opacity: areaOpacity } = this.options.area;
|
|
18
29
|
const { ctx } = this;
|
|
19
30
|
|
|
20
31
|
const xAccessor = (d: SerieDataItem) => {
|
|
21
|
-
const xVal = timestamp ===
|
|
32
|
+
const xVal = timestamp === "X" ? d[xkey] * 1000 : d[xkey];
|
|
22
33
|
const x = xScales(new Date(xVal));
|
|
23
34
|
return x;
|
|
24
35
|
};
|
|
25
|
-
const yAccessor = (d: SerieDataItem) => {
|
|
36
|
+
const yAccessor = (d: SerieDataItem, ykey: any) => {
|
|
26
37
|
const val = d[ykey];
|
|
27
|
-
if (typeof val ===
|
|
38
|
+
if (typeof val === "number" && !isNaN(val)) {
|
|
28
39
|
return yScales(val);
|
|
29
|
-
} else if (typeof fillNull ===
|
|
40
|
+
} else if (typeof fillNull === "number") {
|
|
30
41
|
return yScales(fillNull);
|
|
31
42
|
}
|
|
32
43
|
return undefined;
|
|
33
44
|
};
|
|
34
45
|
const definedAccessor = (d: SerieDataItem) => {
|
|
35
46
|
const val = d[ykey];
|
|
36
|
-
return typeof val ===
|
|
47
|
+
return typeof val === "number" || typeof fillNull === "number";
|
|
37
48
|
};
|
|
38
49
|
|
|
39
|
-
sortBy(series,
|
|
50
|
+
sortBy(series, "zIndex").forEach((serie: Serie, i: number) => {
|
|
40
51
|
if (serie.visible === false) return;
|
|
41
52
|
if (notDisplayedSeries.indexOf(serie.name) > -1) return;
|
|
42
53
|
|
|
@@ -44,40 +55,54 @@ export default class Line {
|
|
|
44
55
|
|
|
45
56
|
serie.color = color;
|
|
46
57
|
|
|
47
|
-
if (areaOpacity > 0) {
|
|
58
|
+
if (areaOpacity > 0 || serie.opacity) {
|
|
48
59
|
ctx.beginPath();
|
|
49
|
-
const area = d3
|
|
60
|
+
const area = d3
|
|
61
|
+
.area()
|
|
50
62
|
.x(xAccessor)
|
|
51
|
-
.y0(
|
|
52
|
-
|
|
63
|
+
.y0((d: SerieDataItem) => {
|
|
64
|
+
if (ykey2 && ykey2 in d) {
|
|
65
|
+
return yAccessor(d, ykey);
|
|
66
|
+
}
|
|
67
|
+
return height - xAxis.tickpadding - xAxis.labels.fontSize - 5;
|
|
68
|
+
})
|
|
69
|
+
.y1((d: SerieDataItem) => {
|
|
70
|
+
if (ykey2 && ykey2 in d) {
|
|
71
|
+
return yAccessor(d, ykey2);
|
|
72
|
+
}
|
|
73
|
+
return yAccessor(d, ykey);
|
|
74
|
+
})
|
|
53
75
|
.defined(definedAccessor)
|
|
54
76
|
.context(ctx);
|
|
55
77
|
|
|
56
78
|
if (curve.enabled) {
|
|
57
|
-
if (curve.mode ===
|
|
58
|
-
area.curve(d3.curveMonotoneX)
|
|
79
|
+
if (curve.mode === "smooth") {
|
|
80
|
+
area.curve(d3.curveMonotoneX);
|
|
59
81
|
}
|
|
60
82
|
}
|
|
61
83
|
|
|
62
|
-
area(serie.data || [])
|
|
84
|
+
area(serie.data || []);
|
|
63
85
|
|
|
64
86
|
ctx.fillStyle = color;
|
|
65
|
-
ctx.globalAlpha = areaOpacity;
|
|
87
|
+
ctx.globalAlpha = areaOpacity || (serie.opacity ? serie.opacity : 0.5);
|
|
66
88
|
ctx.fill();
|
|
67
89
|
ctx.closePath();
|
|
68
90
|
}
|
|
69
91
|
|
|
70
|
-
if (lineWidth > 0) {
|
|
92
|
+
if (lineWidth > 0 && serie.opacity === undefined) {
|
|
71
93
|
ctx.beginPath();
|
|
72
|
-
const line = d3
|
|
94
|
+
const line = d3
|
|
95
|
+
.line()
|
|
73
96
|
.x(xAccessor)
|
|
74
|
-
.y(
|
|
97
|
+
.y((d: SerieDataItem) => {
|
|
98
|
+
return yAccessor(d, ykey);
|
|
99
|
+
})
|
|
75
100
|
.defined(definedAccessor)
|
|
76
101
|
.context(ctx);
|
|
77
102
|
|
|
78
103
|
if (curve.enabled) {
|
|
79
|
-
if (curve.mode ===
|
|
80
|
-
line.curve(d3.curveMonotoneX)
|
|
104
|
+
if (curve.mode === "smooth") {
|
|
105
|
+
line.curve(d3.curveMonotoneX);
|
|
81
106
|
}
|
|
82
107
|
}
|
|
83
108
|
|
|
@@ -85,10 +110,10 @@ export default class Line {
|
|
|
85
110
|
|
|
86
111
|
line(serie.data || []);
|
|
87
112
|
|
|
88
|
-
ctx.lineJoin =
|
|
113
|
+
ctx.lineJoin = "round";
|
|
89
114
|
ctx.lineWidth = lineWidth;
|
|
90
115
|
ctx.strokeStyle = color;
|
|
91
|
-
ctx.lineCap =
|
|
116
|
+
ctx.lineCap = "round";
|
|
92
117
|
ctx.globalAlpha = 1;
|
|
93
118
|
ctx.setLineDash(serie.lineDash || []);
|
|
94
119
|
ctx.stroke();
|