cx 25.6.0 → 25.6.2
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/charts.js +99 -8
- package/dist/manifest.js +709 -709
- package/package.json +2 -2
- package/src/charts/LineGraph.d.ts +9 -0
- package/src/charts/LineGraph.js +77 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cx",
|
|
3
|
-
"version": "25.6.
|
|
3
|
+
"version": "25.6.2",
|
|
4
4
|
"description": "Advanced JavaScript UI framework for admin and dashboard applications with ready to use grid, form and chart components.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"jsnext:main": "src/index.js",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
},
|
|
15
15
|
"homepage": "https://cxjs.io",
|
|
16
16
|
"dependencies": {
|
|
17
|
-
"intl-io": "^0.4.
|
|
17
|
+
"intl-io": "^0.4.4",
|
|
18
18
|
"route-parser": "^0.0.5"
|
|
19
19
|
},
|
|
20
20
|
"peerDependencies": {
|
|
@@ -87,6 +87,15 @@ interface LineGraphProps extends Cx.WidgetProps {
|
|
|
87
87
|
|
|
88
88
|
/** Set to true to avoid forcing the vertical axis to accommodate y0 values. */
|
|
89
89
|
hiddenBase?: boolean;
|
|
90
|
+
|
|
91
|
+
/** Set to `true` to draw smoothed lines between data points using cubic Bézier curve.
|
|
92
|
+
* When enabled, the graph uses control points calculated from neighboring values to create smooth transitions between data points. */
|
|
93
|
+
smooth?: boolean;
|
|
94
|
+
|
|
95
|
+
/** Controls the intensity of the smoothing effect applied to Bézier curves when `smooth` is enabled.
|
|
96
|
+
* Accepts a number between `0` (straight lines) and `0.4` (maximum smoothing).
|
|
97
|
+
* Values outside this range are automatically clamped. Default value is `0.05`. */
|
|
98
|
+
smoothingRatio?: number;
|
|
90
99
|
}
|
|
91
100
|
|
|
92
101
|
export class LineGraph extends Cx.Widget<LineGraphProps> {}
|
package/src/charts/LineGraph.js
CHANGED
|
@@ -27,6 +27,8 @@ export class LineGraph extends Widget {
|
|
|
27
27
|
active: true,
|
|
28
28
|
stack: undefined,
|
|
29
29
|
stacked: undefined,
|
|
30
|
+
smooth: undefined,
|
|
31
|
+
smoothingRatio: undefined,
|
|
30
32
|
});
|
|
31
33
|
}
|
|
32
34
|
|
|
@@ -35,6 +37,11 @@ export class LineGraph extends Widget {
|
|
|
35
37
|
|
|
36
38
|
if (data.name && !data.colorName) data.colorName = data.name;
|
|
37
39
|
|
|
40
|
+
if (data.smooth && data.smoothingRatio != null) {
|
|
41
|
+
if (data.smoothingRatio < 0) data.smoothingRatio = 0;
|
|
42
|
+
if (data.smoothingRatio > 0.4) data.smoothingRatio = 0.4;
|
|
43
|
+
}
|
|
44
|
+
|
|
38
45
|
super.prepareData(context, instance);
|
|
39
46
|
}
|
|
40
47
|
|
|
@@ -161,13 +168,18 @@ export class LineGraph extends Widget {
|
|
|
161
168
|
};
|
|
162
169
|
|
|
163
170
|
let line, area;
|
|
171
|
+
const r = data.smoothingRatio;
|
|
164
172
|
|
|
173
|
+
let linePath = "";
|
|
165
174
|
if (data.line) {
|
|
166
|
-
let linePath = "";
|
|
167
175
|
lineSpans.forEach((span) => {
|
|
168
176
|
span.forEach((p, i) => {
|
|
169
|
-
linePath +=
|
|
170
|
-
|
|
177
|
+
linePath +=
|
|
178
|
+
i == 0
|
|
179
|
+
? `M ${p.x} ${p.y}`
|
|
180
|
+
: !data.smooth || span.length < 2
|
|
181
|
+
? `L ${p.x} ${p.y}`
|
|
182
|
+
: this.getCurvedPathSegment(p, span, i - 1, i - 2, i - 1, i + 1, r);
|
|
171
183
|
});
|
|
172
184
|
});
|
|
173
185
|
|
|
@@ -185,13 +197,35 @@ export class LineGraph extends Widget {
|
|
|
185
197
|
lineSpans.forEach((span) => {
|
|
186
198
|
let closePath = "";
|
|
187
199
|
span.forEach((p, i) => {
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
200
|
+
let segment = "";
|
|
201
|
+
if (i == 0) {
|
|
202
|
+
segment = `M ${p.x} ${p.y}`;
|
|
203
|
+
|
|
204
|
+
// closing point
|
|
205
|
+
closePath =
|
|
206
|
+
!data.smooth || span.length < 2
|
|
207
|
+
? `L ${p.x} ${p.y0}`
|
|
208
|
+
: this.getCurvedPathSegment(p, span, i + 1, i + 2, i + 1, i - 1, r, "y0");
|
|
209
|
+
} else {
|
|
210
|
+
if (!data.smooth) {
|
|
211
|
+
segment = `L ${p.x} ${p.y}`;
|
|
212
|
+
closePath = `L ${p.x} ${p.y0}` + closePath;
|
|
213
|
+
} else {
|
|
214
|
+
segment = this.getCurvedPathSegment(p, span, i - 1, i - 2, i - 1, i + 1, r, "y");
|
|
215
|
+
|
|
216
|
+
// closing point
|
|
217
|
+
if (i < span.length - 1)
|
|
218
|
+
closePath = this.getCurvedPathSegment(p, span, i + 1, i + 2, i + 1, i - 1, r, "y0") + closePath;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
areaPath += segment;
|
|
191
222
|
});
|
|
223
|
+
|
|
224
|
+
areaPath += `L ${span[span.length - 1].x} ${span[span.length - 1].y0}`;
|
|
192
225
|
areaPath += closePath;
|
|
193
|
-
areaPath +=
|
|
226
|
+
areaPath += "Z";
|
|
194
227
|
});
|
|
228
|
+
|
|
195
229
|
area = (
|
|
196
230
|
<path
|
|
197
231
|
className={this.CSS.element(this.baseClass, "area", stateMods)}
|
|
@@ -208,6 +242,39 @@ export class LineGraph extends Widget {
|
|
|
208
242
|
</g>
|
|
209
243
|
);
|
|
210
244
|
}
|
|
245
|
+
|
|
246
|
+
getCurvedPathSegment(p, points, i1, i2, j1, j2, r, yField = "y") {
|
|
247
|
+
const [sx, sy] = this.getControlPoint({ cp: points[i1], pp: points[i2], r, np: p, yField });
|
|
248
|
+
const [ex, ey] = this.getControlPoint({ cp: p, pp: points[j1], np: points[j2], r, reverse: true, yField });
|
|
249
|
+
|
|
250
|
+
return `C ${sx} ${sy}, ${ex} ${ey}, ${p.x} ${p[yField]}`;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
getControlPoint({ cp, pp, np, r, reverse, yField = "y" }) {
|
|
254
|
+
// When 'current' is the first or last point of the array 'previous' or 'next' don't exist. Replace with 'current'.
|
|
255
|
+
const p = pp || cp;
|
|
256
|
+
const n = np || cp;
|
|
257
|
+
|
|
258
|
+
// Properties of the opposed-line
|
|
259
|
+
let { angle, length } = this.getLineInfo(p.x, p[yField], n.x, n[yField]);
|
|
260
|
+
// If it is end-control-point, add PI to the angle to go backward
|
|
261
|
+
angle = angle + (reverse ? Math.PI : 0);
|
|
262
|
+
length = length * r;
|
|
263
|
+
// The control point position is relative to the current point
|
|
264
|
+
const x = cp.x + Math.cos(angle) * length;
|
|
265
|
+
const y = cp[yField] + Math.sin(angle) * length;
|
|
266
|
+
return [x, y];
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
getLineInfo(p1x, p1y, p2x, p2y) {
|
|
270
|
+
const lengthX = p2x - p1x;
|
|
271
|
+
const lengthY = p2y - p1y;
|
|
272
|
+
|
|
273
|
+
return {
|
|
274
|
+
length: Math.sqrt(Math.pow(lengthX, 2) + Math.pow(lengthY, 2)),
|
|
275
|
+
angle: Math.atan2(lengthY, lengthX),
|
|
276
|
+
};
|
|
277
|
+
}
|
|
211
278
|
}
|
|
212
279
|
|
|
213
280
|
LineGraph.prototype.xAxis = "x";
|
|
@@ -227,4 +294,7 @@ LineGraph.prototype.legendShape = "rect";
|
|
|
227
294
|
LineGraph.prototype.stack = "stack";
|
|
228
295
|
LineGraph.prototype.hiddenBase = false;
|
|
229
296
|
|
|
297
|
+
LineGraph.prototype.smooth = false;
|
|
298
|
+
LineGraph.prototype.smoothingRatio = 0.05;
|
|
299
|
+
|
|
230
300
|
Widget.alias("line-graph", LineGraph);
|