cx 26.4.4 → 26.5.1
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/build/charts/axis/Axis.d.ts +8 -0
- package/build/charts/axis/Axis.d.ts.map +1 -1
- package/build/charts/axis/Axis.js +18 -1
- package/build/charts/axis/TimeAxis.js +1 -0
- package/build/ui/Format.d.ts.map +1 -1
- package/build/ui/Format.js +26 -2
- package/build/util/Format.d.ts.map +1 -1
- package/build/util/Format.js +6 -0
- package/build/util/date/dateQuarter.d.ts +7 -0
- package/build/util/date/dateQuarter.d.ts.map +1 -0
- package/build/util/date/dateQuarter.js +8 -0
- package/build/util/date/dayBefore.d.ts +12 -0
- package/build/util/date/dayBefore.d.ts.map +1 -0
- package/build/util/date/dayBefore.js +15 -0
- package/build/util/date/index.d.ts +2 -0
- package/build/util/date/index.d.ts.map +1 -1
- package/build/util/date/index.js +2 -0
- package/build/widgets/form/DateTimePicker.d.ts.map +1 -1
- package/build/widgets/form/DateTimePicker.js +53 -31
- package/build/widgets/form/Field.d.ts.map +1 -1
- package/build/widgets/form/Field.js +2 -1
- package/build/widgets/form/Wheel.d.ts +8 -0
- package/build/widgets/form/Wheel.d.ts.map +1 -1
- package/build/widgets/form/Wheel.js +30 -7
- package/build/widgets/grid/Grid.d.ts +1 -1
- package/build/widgets/grid/Grid.d.ts.map +1 -1
- package/dist/charts.css +6 -0
- package/dist/charts.js +18 -1
- package/dist/manifest.js +787 -778
- package/dist/ui.js +33 -1
- package/dist/util.js +32 -0
- package/dist/widgets.js +225 -173
- package/package.json +1 -1
- package/src/charts/BarGraph.scss +31 -31
- package/src/charts/Legend.scss +57 -57
- package/src/charts/LegendEntry.scss +35 -35
- package/src/charts/LineGraph.scss +28 -28
- package/src/charts/RangeMarker.scss +3 -0
- package/src/charts/axis/Axis.tsx +31 -1
- package/src/charts/axis/TimeAxis.tsx +1 -0
- package/src/charts/helpers/SnapPointFinder.ts +136 -136
- package/src/charts/helpers/ValueAtFinder.ts +72 -72
- package/src/charts/index.scss +1 -0
- package/src/data/AugmentedViewBase.ts +89 -89
- package/src/data/View.ts +301 -301
- package/src/data/createAccessorModelProxy.ts +66 -66
- package/src/ui/Format.spec.ts +32 -0
- package/src/ui/Format.ts +27 -2
- package/src/ui/Repeater.spec.tsx +181 -181
- package/src/util/Format.spec.ts +11 -0
- package/src/util/Format.ts +7 -0
- package/src/util/date/dateQuarter.ts +8 -0
- package/src/util/date/dayBefore.ts +15 -0
- package/src/util/date/index.ts +2 -0
- package/src/util/scss/include.scss +69 -69
- package/src/widgets/Button.maps.scss +103 -103
- package/src/widgets/form/Calendar.tsx +772 -772
- package/src/widgets/form/DateTimePicker.tsx +453 -392
- package/src/widgets/form/Field.tsx +2 -1
- package/src/widgets/form/ValidationGroup.spec.tsx +30 -1
- package/src/widgets/form/Wheel.tsx +36 -7
- package/src/widgets/grid/Grid.scss +657 -657
- package/src/widgets/grid/Grid.tsx +1 -1
- package/src/widgets/grid/variables.scss +47 -47
- package/src/widgets/index.ts +63 -63
- package/src/widgets/nav/MenuItem.scss +150 -150
- package/src/widgets/nav/Tab.ts +122 -122
- package/src/widgets/overlay/Overlay.tsx +1029 -1029
- package/src/widgets/variables.scss +61 -61
package/src/charts/BarGraph.scss
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
@use "sass:math";
|
|
2
|
-
@use "sass:map";
|
|
3
|
-
@use "../util/scss/besm.scss" as *;
|
|
4
|
-
@use "../util/scss/include.scss" as *;
|
|
5
|
-
@use "../util/scss/add-rules.scss" as *;
|
|
6
|
-
@use "../util/scss/clockwise.scss" as *;
|
|
7
|
-
@use "./variables" as *;
|
|
8
|
-
|
|
9
|
-
@mixin cx-bargraph($name: "bargraph", $besm: $cx-besm) {
|
|
10
|
-
$block: map.get($besm, block);
|
|
11
|
-
$element: map.get($besm, element);
|
|
12
|
-
$state: map.get($besm, state);
|
|
13
|
-
|
|
14
|
-
.#{$element}#{$name}-bar {
|
|
15
|
-
stroke-width: $cx-default-chart-shape-stroke-width;
|
|
16
|
-
fill: $cx-default-chart-shape-fill-color;
|
|
17
|
-
stroke: $cx-default-chart-shape-stroke-color;
|
|
18
|
-
|
|
19
|
-
&.#{$state}selectable {
|
|
20
|
-
cursor: pointer;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
&.#{$state}selected {
|
|
24
|
-
stroke-width: $cx-default-chart-selected-stroke-width;
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
@if (cx-should-include("cx/charts/BarGraph")) {
|
|
30
|
-
@include cx-bargraph();
|
|
31
|
-
}
|
|
1
|
+
@use "sass:math";
|
|
2
|
+
@use "sass:map";
|
|
3
|
+
@use "../util/scss/besm.scss" as *;
|
|
4
|
+
@use "../util/scss/include.scss" as *;
|
|
5
|
+
@use "../util/scss/add-rules.scss" as *;
|
|
6
|
+
@use "../util/scss/clockwise.scss" as *;
|
|
7
|
+
@use "./variables" as *;
|
|
8
|
+
|
|
9
|
+
@mixin cx-bargraph($name: "bargraph", $besm: $cx-besm) {
|
|
10
|
+
$block: map.get($besm, block);
|
|
11
|
+
$element: map.get($besm, element);
|
|
12
|
+
$state: map.get($besm, state);
|
|
13
|
+
|
|
14
|
+
.#{$element}#{$name}-bar {
|
|
15
|
+
stroke-width: $cx-default-chart-shape-stroke-width;
|
|
16
|
+
fill: $cx-default-chart-shape-fill-color;
|
|
17
|
+
stroke: $cx-default-chart-shape-stroke-color;
|
|
18
|
+
|
|
19
|
+
&.#{$state}selectable {
|
|
20
|
+
cursor: pointer;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
&.#{$state}selected {
|
|
24
|
+
stroke-width: $cx-default-chart-selected-stroke-width;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@if (cx-should-include("cx/charts/BarGraph")) {
|
|
30
|
+
@include cx-bargraph();
|
|
31
|
+
}
|
package/src/charts/Legend.scss
CHANGED
|
@@ -1,57 +1,57 @@
|
|
|
1
|
-
@use "sass:math";
|
|
2
|
-
@use "sass:map";
|
|
3
|
-
@use "../util/scss/besm.scss" as *;
|
|
4
|
-
@use "../util/scss/include.scss" as *;
|
|
5
|
-
@use "../util/scss/add-rules.scss" as *;
|
|
6
|
-
@use "../util/scss/clockwise.scss" as *;
|
|
7
|
-
@use "./variables" as *;
|
|
8
|
-
|
|
9
|
-
@mixin cx-legend($name: "legend", $besm: $cx-besm) {
|
|
10
|
-
$block: map.get($besm, block);
|
|
11
|
-
$element: map.get($besm, element);
|
|
12
|
-
$state: map.get($besm, state);
|
|
13
|
-
|
|
14
|
-
.#{$block}#{$name} {
|
|
15
|
-
display: flex;
|
|
16
|
-
justify-content: center;
|
|
17
|
-
align-items: flex-start;
|
|
18
|
-
flex-wrap: wrap;
|
|
19
|
-
gap: $cx-default-chart-legend-gap;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
.#{$block}#{$name}.#{$state}vertical {
|
|
23
|
-
flex-direction: column;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
.#{$element}#{$name}-entry {
|
|
27
|
-
display: flex;
|
|
28
|
-
align-items: center;
|
|
29
|
-
padding: $cx-default-chart-legend-padding;
|
|
30
|
-
gap: $cx-default-chart-legend-entry-gap;
|
|
31
|
-
font-size: $cx-default-chart-legend-font-size;
|
|
32
|
-
position: relative;
|
|
33
|
-
box-sizing: border-box;
|
|
34
|
-
cursor: pointer;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
.#{$element}#{$name}-svg {
|
|
38
|
-
flex-shrink: 0;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
.#{$element}#{$name}-shape {
|
|
42
|
-
fill: $cx-default-chart-legend-shape-color;
|
|
43
|
-
stroke-width: $cx-default-chart-legend-shape-stroke-width;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
.#{$element}#{$name}-value {
|
|
47
|
-
order: 3;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
.#{$element}#{$name}-entry-text {
|
|
51
|
-
order: 2;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
@if (cx-should-include("cx/charts/Legend")) {
|
|
56
|
-
@include cx-legend();
|
|
57
|
-
}
|
|
1
|
+
@use "sass:math";
|
|
2
|
+
@use "sass:map";
|
|
3
|
+
@use "../util/scss/besm.scss" as *;
|
|
4
|
+
@use "../util/scss/include.scss" as *;
|
|
5
|
+
@use "../util/scss/add-rules.scss" as *;
|
|
6
|
+
@use "../util/scss/clockwise.scss" as *;
|
|
7
|
+
@use "./variables" as *;
|
|
8
|
+
|
|
9
|
+
@mixin cx-legend($name: "legend", $besm: $cx-besm) {
|
|
10
|
+
$block: map.get($besm, block);
|
|
11
|
+
$element: map.get($besm, element);
|
|
12
|
+
$state: map.get($besm, state);
|
|
13
|
+
|
|
14
|
+
.#{$block}#{$name} {
|
|
15
|
+
display: flex;
|
|
16
|
+
justify-content: center;
|
|
17
|
+
align-items: flex-start;
|
|
18
|
+
flex-wrap: wrap;
|
|
19
|
+
gap: $cx-default-chart-legend-gap;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.#{$block}#{$name}.#{$state}vertical {
|
|
23
|
+
flex-direction: column;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.#{$element}#{$name}-entry {
|
|
27
|
+
display: flex;
|
|
28
|
+
align-items: center;
|
|
29
|
+
padding: $cx-default-chart-legend-padding;
|
|
30
|
+
gap: $cx-default-chart-legend-entry-gap;
|
|
31
|
+
font-size: $cx-default-chart-legend-font-size;
|
|
32
|
+
position: relative;
|
|
33
|
+
box-sizing: border-box;
|
|
34
|
+
cursor: pointer;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.#{$element}#{$name}-svg {
|
|
38
|
+
flex-shrink: 0;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.#{$element}#{$name}-shape {
|
|
42
|
+
fill: $cx-default-chart-legend-shape-color;
|
|
43
|
+
stroke-width: $cx-default-chart-legend-shape-stroke-width;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.#{$element}#{$name}-value {
|
|
47
|
+
order: 3;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.#{$element}#{$name}-entry-text {
|
|
51
|
+
order: 2;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
@if (cx-should-include("cx/charts/Legend")) {
|
|
56
|
+
@include cx-legend();
|
|
57
|
+
}
|
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
@use "sass:math";
|
|
2
|
-
@use "sass:map";
|
|
3
|
-
@use "../util/scss/besm.scss" as *;
|
|
4
|
-
@use "../util/scss/include.scss" as *;
|
|
5
|
-
@use "../util/scss/add-rules.scss" as *;
|
|
6
|
-
@use "../util/scss/clockwise.scss" as *;
|
|
7
|
-
@use "./variables" as *;
|
|
8
|
-
|
|
9
|
-
@mixin cx-legendentry($name: "legendentry", $besm: $cx-besm) {
|
|
10
|
-
$block: map.get($besm, block);
|
|
11
|
-
$element: map.get($besm, element);
|
|
12
|
-
$state: map.get($besm, state);
|
|
13
|
-
|
|
14
|
-
.#{$block}#{$name} {
|
|
15
|
-
display: inline-flex;
|
|
16
|
-
align-items: center;
|
|
17
|
-
padding: $cx-default-chart-legend-padding;
|
|
18
|
-
gap: $cx-default-chart-legend-entry-gap;
|
|
19
|
-
position: relative;
|
|
20
|
-
box-sizing: border-box;
|
|
21
|
-
cursor: pointer;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
.#{$element}#{$name}-svg {
|
|
25
|
-
flex-shrink: 0;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
.#{$element}#{$name}-shape {
|
|
29
|
-
fill: $cx-default-chart-shape-fill-color;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
@if (cx-should-include("cx/charts/LegendEntry")) {
|
|
34
|
-
@include cx-legendentry();
|
|
35
|
-
}
|
|
1
|
+
@use "sass:math";
|
|
2
|
+
@use "sass:map";
|
|
3
|
+
@use "../util/scss/besm.scss" as *;
|
|
4
|
+
@use "../util/scss/include.scss" as *;
|
|
5
|
+
@use "../util/scss/add-rules.scss" as *;
|
|
6
|
+
@use "../util/scss/clockwise.scss" as *;
|
|
7
|
+
@use "./variables" as *;
|
|
8
|
+
|
|
9
|
+
@mixin cx-legendentry($name: "legendentry", $besm: $cx-besm) {
|
|
10
|
+
$block: map.get($besm, block);
|
|
11
|
+
$element: map.get($besm, element);
|
|
12
|
+
$state: map.get($besm, state);
|
|
13
|
+
|
|
14
|
+
.#{$block}#{$name} {
|
|
15
|
+
display: inline-flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
padding: $cx-default-chart-legend-padding;
|
|
18
|
+
gap: $cx-default-chart-legend-entry-gap;
|
|
19
|
+
position: relative;
|
|
20
|
+
box-sizing: border-box;
|
|
21
|
+
cursor: pointer;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.#{$element}#{$name}-svg {
|
|
25
|
+
flex-shrink: 0;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.#{$element}#{$name}-shape {
|
|
29
|
+
fill: $cx-default-chart-shape-fill-color;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
@if (cx-should-include("cx/charts/LegendEntry")) {
|
|
34
|
+
@include cx-legendentry();
|
|
35
|
+
}
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
@use "sass:math";
|
|
2
|
-
@use "sass:map";
|
|
3
|
-
@use "../util/scss/besm.scss" as *;
|
|
4
|
-
@use "../util/scss/include.scss" as *;
|
|
5
|
-
@use "../util/scss/add-rules.scss" as *;
|
|
6
|
-
@use "../util/scss/clockwise.scss" as *;
|
|
7
|
-
@use "./variables" as *;
|
|
8
|
-
|
|
9
|
-
@mixin cx-linegraph($name: "linegraph", $besm: $cx-besm) {
|
|
10
|
-
$block: map.get($besm, block);
|
|
11
|
-
$element: map.get($besm, element);
|
|
12
|
-
$state: map.get($besm, state);
|
|
13
|
-
|
|
14
|
-
.#{$element}#{$name}-line {
|
|
15
|
-
stroke: $cx-default-chart-line-stroke-color;
|
|
16
|
-
stroke-width: $cx-default-chart-line-stroke-width;
|
|
17
|
-
fill: none !important;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
.#{$element}#{$name}-area {
|
|
21
|
-
stroke-width: 0;
|
|
22
|
-
opacity: $cx-default-chart-area-opacity;
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
@if (cx-should-include("cx/charts/LineGraph")) {
|
|
27
|
-
@include cx-linegraph();
|
|
28
|
-
}
|
|
1
|
+
@use "sass:math";
|
|
2
|
+
@use "sass:map";
|
|
3
|
+
@use "../util/scss/besm.scss" as *;
|
|
4
|
+
@use "../util/scss/include.scss" as *;
|
|
5
|
+
@use "../util/scss/add-rules.scss" as *;
|
|
6
|
+
@use "../util/scss/clockwise.scss" as *;
|
|
7
|
+
@use "./variables" as *;
|
|
8
|
+
|
|
9
|
+
@mixin cx-linegraph($name: "linegraph", $besm: $cx-besm) {
|
|
10
|
+
$block: map.get($besm, block);
|
|
11
|
+
$element: map.get($besm, element);
|
|
12
|
+
$state: map.get($besm, state);
|
|
13
|
+
|
|
14
|
+
.#{$element}#{$name}-line {
|
|
15
|
+
stroke: $cx-default-chart-line-stroke-color;
|
|
16
|
+
stroke-width: $cx-default-chart-line-stroke-width;
|
|
17
|
+
fill: none !important;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.#{$element}#{$name}-area {
|
|
21
|
+
stroke-width: 0;
|
|
22
|
+
opacity: $cx-default-chart-area-opacity;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
@if (cx-should-include("cx/charts/LineGraph")) {
|
|
27
|
+
@include cx-linegraph();
|
|
28
|
+
}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
@use "sass:map";
|
|
2
|
+
@use "../util/scss/besm.scss" as *;
|
|
3
|
+
@use "../util/scss/include.scss" as *;
|
|
4
|
+
@use "./variables" as *;
|
|
2
5
|
|
|
3
6
|
@mixin cx-rangemarker($name: "rangemarker", $besm: $cx-besm, $range-marker-color: $cx-default-range-marker-color) {
|
|
4
7
|
$block: map.get($besm, block);
|
package/src/charts/axis/Axis.tsx
CHANGED
|
@@ -74,6 +74,14 @@ export interface AxisConfig extends BoundedObjectConfig {
|
|
|
74
74
|
/** Set to true to hide the axis labels. */
|
|
75
75
|
hideLabels?: boolean;
|
|
76
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Set to `true` to drop a boundary (first/last) label, together with its tick,
|
|
79
|
+
* when the label would not fit within the chart and get clipped at the edge.
|
|
80
|
+
* Minor ticks are unaffected. Only affects horizontal axes. Defaults to `false`,
|
|
81
|
+
* except on `TimeAxis` where it defaults to `true`.
|
|
82
|
+
*/
|
|
83
|
+
hideClippedLabels?: boolean;
|
|
84
|
+
|
|
77
85
|
/** Set to true to hide the axis line. */
|
|
78
86
|
hideLine?: boolean;
|
|
79
87
|
|
|
@@ -131,6 +139,7 @@ export class Axis extends BoundedObject<AxisConfig, AxisInstance> {
|
|
|
131
139
|
declare inverted: boolean;
|
|
132
140
|
declare hidden: boolean;
|
|
133
141
|
declare hideLabels: boolean;
|
|
142
|
+
declare hideClippedLabels: boolean;
|
|
134
143
|
declare hideTicks: boolean;
|
|
135
144
|
declare hideLine: boolean;
|
|
136
145
|
declare tickSize: number;
|
|
@@ -185,6 +194,7 @@ export class Axis extends BoundedObject<AxisConfig, AxisInstance> {
|
|
|
185
194
|
{
|
|
186
195
|
anchors: undefined,
|
|
187
196
|
hideLabels: undefined,
|
|
197
|
+
hideClippedLabels: undefined,
|
|
188
198
|
hideLine: undefined,
|
|
189
199
|
hideTicks: undefined,
|
|
190
200
|
labelRotation: undefined,
|
|
@@ -259,10 +269,27 @@ export class Axis extends BoundedObject<AxisConfig, AxisInstance> {
|
|
|
259
269
|
var t: string[] = [];
|
|
260
270
|
if (!!size && !data.hideLabels) {
|
|
261
271
|
var ticks = calculator.getTicks([size]);
|
|
272
|
+
|
|
273
|
+
// A boundary label is dropped when it would be clipped at the chart edge.
|
|
274
|
+
// How far a label reaches toward an edge depends only on its text anchor
|
|
275
|
+
// and minLabelDistance, so it is resolved once here rather than per tick.
|
|
276
|
+
// Chart bounds (parentRect) are used rather than axis bounds, since an
|
|
277
|
+
// axis can be inset within its chart and one Svg may host several charts.
|
|
278
|
+
let chartBounds = instance.parentRect;
|
|
279
|
+
let clipBoundaryLabels = !this.vertical && !!data.hideClippedLabels && !!chartBounds;
|
|
280
|
+
let reach = minLabelDistance * 0.8;
|
|
281
|
+
let leftReach = data.labelAnchor == "end" ? reach : data.labelAnchor == "middle" ? reach / 2 : 0;
|
|
282
|
+
let rightReach = data.labelAnchor == "start" ? reach : data.labelAnchor == "middle" ? reach / 2 : 0;
|
|
283
|
+
|
|
262
284
|
ticks.forEach((serie: any[], si: number) => {
|
|
263
285
|
serie.forEach((v: any, i: number) => {
|
|
264
286
|
var s = calculator.map(v);
|
|
265
287
|
|
|
288
|
+
// Drop this boundary label (and its major tick) if it would be
|
|
289
|
+
// clipped at the chart edge; minor ticks render separately and stay.
|
|
290
|
+
let clipped =
|
|
291
|
+
clipBoundaryLabels && (s + rightReach > chartBounds.r || s - leftReach < chartBounds.l);
|
|
292
|
+
|
|
266
293
|
if (this.secondary) {
|
|
267
294
|
x1 = this.vertical ? bounds.r + tickOffset : s;
|
|
268
295
|
y1 = this.vertical ? s : bounds.t - tickOffset;
|
|
@@ -275,7 +302,9 @@ export class Axis extends BoundedObject<AxisConfig, AxisInstance> {
|
|
|
275
302
|
y2 = this.vertical ? s : bounds.b + tickOffset + tickSize;
|
|
276
303
|
}
|
|
277
304
|
|
|
278
|
-
if (!this.useGridlineTicks) t.push(`M ${x1} ${y1} L ${x2} ${y2}`);
|
|
305
|
+
if (!this.useGridlineTicks && !clipped) t.push(`M ${x1} ${y1} L ${x2} ${y2}`);
|
|
306
|
+
|
|
307
|
+
if (clipped) return;
|
|
279
308
|
|
|
280
309
|
var x, y;
|
|
281
310
|
let labelOffset =
|
|
@@ -422,6 +451,7 @@ Axis.prototype.secondary = false;
|
|
|
422
451
|
Axis.prototype.inverted = false;
|
|
423
452
|
Axis.prototype.hidden = false;
|
|
424
453
|
Axis.prototype.hideLabels = false;
|
|
454
|
+
Axis.prototype.hideClippedLabels = false;
|
|
425
455
|
Axis.prototype.hideTicks = false;
|
|
426
456
|
Axis.prototype.hideLine = false;
|
|
427
457
|
|
|
@@ -212,6 +212,7 @@ TimeAxis.prototype.minLabelDistance = 60;
|
|
|
212
212
|
TimeAxis.prototype.minTickDistance = 60;
|
|
213
213
|
TimeAxis.prototype.minTickUnit = "second";
|
|
214
214
|
TimeAxis.prototype.useLabelDistanceFormatOverrides = false;
|
|
215
|
+
TimeAxis.prototype.hideClippedLabels = true;
|
|
215
216
|
TimeAxis.prototype.minLabelDistanceFormatOverrideDefaults = {
|
|
216
217
|
[TimeFormats.fullDateAndTime]: 150,
|
|
217
218
|
[TimeFormats.shortMonthDate]: 90,
|
|
@@ -1,136 +1,136 @@
|
|
|
1
|
-
import { PointReducer, PointReducerConfig, PointReducerInstance, PointReducerAccumulator } from "./PointReducer";
|
|
2
|
-
import { RenderingContext } from "../../ui/RenderingContext";
|
|
3
|
-
import { NumberProp, Bind, Prop, DataRecord } from "../../ui/Prop";
|
|
4
|
-
import { AccessorChain } from "../../data/createAccessorModelProxy";
|
|
5
|
-
|
|
6
|
-
export interface SnapAccumulator extends PointReducerAccumulator {
|
|
7
|
-
cursor: {
|
|
8
|
-
x: number | null;
|
|
9
|
-
y: number | null;
|
|
10
|
-
mapped: boolean;
|
|
11
|
-
mappedX?: number | null;
|
|
12
|
-
mappedY?: number | null;
|
|
13
|
-
};
|
|
14
|
-
dist: number;
|
|
15
|
-
snapX: any;
|
|
16
|
-
snapY: any;
|
|
17
|
-
snapRecord?: any;
|
|
18
|
-
xAxis: any;
|
|
19
|
-
yAxis: any;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export interface SnapPointFinderInstance extends PointReducerInstance<SnapAccumulator> {
|
|
23
|
-
xAxis?: any;
|
|
24
|
-
yAxis?: any;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface SnapPointFinderConfig extends PointReducerConfig {
|
|
28
|
-
/** Cursor X value. */
|
|
29
|
-
cursorX?: NumberProp;
|
|
30
|
-
|
|
31
|
-
/** Cursor Y value */
|
|
32
|
-
cursorY?: NumberProp;
|
|
33
|
-
|
|
34
|
-
/** A binding used to receive the x value of the nearest point.*/
|
|
35
|
-
snapX?: Bind | AccessorChain<number | null | undefined> | AccessorChain<string | null | undefined>;
|
|
36
|
-
|
|
37
|
-
/** A binding used to receive the y value of the nearest point. */
|
|
38
|
-
snapY?: Bind | AccessorChain<number | null | undefined> | AccessorChain<string | null | undefined>;
|
|
39
|
-
|
|
40
|
-
/** A binding used to receive the record prop */
|
|
41
|
-
snapRecord?: Prop<DataRecord>;
|
|
42
|
-
|
|
43
|
-
/** Maximum distance between cursor and the snap point. Default value is 50. Adjust accordingly for large distances, e.g. set to Infinity when using TimeAxis */
|
|
44
|
-
maxDistance?: number;
|
|
45
|
-
|
|
46
|
-
/** A function used to convert x values into numeric format. Commonly used with dates. */
|
|
47
|
-
convertX?: (value: number | string) => number;
|
|
48
|
-
|
|
49
|
-
/** A function used to convert y values into numeric format. Commonly used with dates. */
|
|
50
|
-
convertY?: (value: number | string) => number;
|
|
51
|
-
|
|
52
|
-
/** Name of the x-axis. Default is 'x'. */
|
|
53
|
-
xAxis?: string;
|
|
54
|
-
|
|
55
|
-
/** Name of the y-axis. Default is 'y'. */
|
|
56
|
-
yAxis?: string;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export class SnapPointFinder extends PointReducer<SnapAccumulator> {
|
|
60
|
-
declare maxDistance: number;
|
|
61
|
-
declare convertX: (value: any) => number;
|
|
62
|
-
declare convertY: (value: any) => number;
|
|
63
|
-
declare xAxis: string;
|
|
64
|
-
declare yAxis: string;
|
|
65
|
-
|
|
66
|
-
constructor(config?: SnapPointFinderConfig) {
|
|
67
|
-
super(config);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
declareData(...args: any[]) {
|
|
71
|
-
super.declareData(...args, {
|
|
72
|
-
cursorX: undefined,
|
|
73
|
-
cursorY: undefined,
|
|
74
|
-
snapX: undefined,
|
|
75
|
-
snapY: undefined,
|
|
76
|
-
snapRecord: undefined,
|
|
77
|
-
maxDistance: undefined,
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
explore(context: RenderingContext, instance: SnapPointFinderInstance) {
|
|
82
|
-
instance.xAxis = (context.axes as any)?.[this.xAxis];
|
|
83
|
-
instance.yAxis = (context.axes as any)?.[this.yAxis];
|
|
84
|
-
super.explore(context, instance);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
onInitAccumulator = (acc: SnapAccumulator, { data, xAxis, yAxis }: SnapPointFinderInstance) => {
|
|
88
|
-
const d = data as any;
|
|
89
|
-
acc.cursor = {
|
|
90
|
-
x: d.cursorX,
|
|
91
|
-
y: d.cursorY,
|
|
92
|
-
mapped: false,
|
|
93
|
-
};
|
|
94
|
-
acc.dist = d.maxDistance > 0 ? Math.pow(d.maxDistance, 2) : Number.POSITIVE_INFINITY;
|
|
95
|
-
acc.snapX = null;
|
|
96
|
-
acc.snapY = null;
|
|
97
|
-
acc.xAxis = xAxis;
|
|
98
|
-
acc.yAxis = yAxis;
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
onMap = (acc: SnapAccumulator, x: any, y: any, name: string, p: any) => {
|
|
102
|
-
let { xAxis, yAxis, cursor } = acc;
|
|
103
|
-
|
|
104
|
-
if (!cursor.mapped) {
|
|
105
|
-
cursor.mappedX = cursor.x != null ? xAxis?.map(this.convertX(cursor.x)) : null;
|
|
106
|
-
cursor.mappedY = cursor.y != null ? yAxis?.map(this.convertY(cursor.y)) : null;
|
|
107
|
-
cursor.mapped = true;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
let d: number | null = null;
|
|
111
|
-
let cx = x != null ? xAxis?.map(this.convertX(x)) : null;
|
|
112
|
-
let cy = y != null ? yAxis?.map(this.convertY(y)) : null;
|
|
113
|
-
|
|
114
|
-
if (cursor.mappedX != null && cx != null) d = (d || 0) + Math.pow(Math.abs(cx - cursor.mappedX), 2);
|
|
115
|
-
if (cursor.mappedY != null && cy != null) d = (d || 0) + Math.pow(Math.abs(cy - cursor.mappedY), 2);
|
|
116
|
-
|
|
117
|
-
if (d != null && d < acc.dist) {
|
|
118
|
-
acc.dist = d;
|
|
119
|
-
acc.snapX = x;
|
|
120
|
-
acc.snapY = y;
|
|
121
|
-
acc.snapRecord = p;
|
|
122
|
-
}
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
onReduce = (acc: SnapAccumulator, instance: PointReducerInstance<SnapAccumulator>) => {
|
|
126
|
-
instance.set("snapX", acc.snapX);
|
|
127
|
-
instance.set("snapY", acc.snapY);
|
|
128
|
-
instance.set("snapRecord", acc.snapRecord);
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
SnapPointFinder.prototype.maxDistance = 50;
|
|
133
|
-
SnapPointFinder.prototype.convertX = (x) => x;
|
|
134
|
-
SnapPointFinder.prototype.convertY = (y) => y;
|
|
135
|
-
SnapPointFinder.prototype.xAxis = "x";
|
|
136
|
-
SnapPointFinder.prototype.yAxis = "y";
|
|
1
|
+
import { PointReducer, PointReducerConfig, PointReducerInstance, PointReducerAccumulator } from "./PointReducer";
|
|
2
|
+
import { RenderingContext } from "../../ui/RenderingContext";
|
|
3
|
+
import { NumberProp, Bind, Prop, DataRecord } from "../../ui/Prop";
|
|
4
|
+
import { AccessorChain } from "../../data/createAccessorModelProxy";
|
|
5
|
+
|
|
6
|
+
export interface SnapAccumulator extends PointReducerAccumulator {
|
|
7
|
+
cursor: {
|
|
8
|
+
x: number | null;
|
|
9
|
+
y: number | null;
|
|
10
|
+
mapped: boolean;
|
|
11
|
+
mappedX?: number | null;
|
|
12
|
+
mappedY?: number | null;
|
|
13
|
+
};
|
|
14
|
+
dist: number;
|
|
15
|
+
snapX: any;
|
|
16
|
+
snapY: any;
|
|
17
|
+
snapRecord?: any;
|
|
18
|
+
xAxis: any;
|
|
19
|
+
yAxis: any;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface SnapPointFinderInstance extends PointReducerInstance<SnapAccumulator> {
|
|
23
|
+
xAxis?: any;
|
|
24
|
+
yAxis?: any;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export interface SnapPointFinderConfig extends PointReducerConfig {
|
|
28
|
+
/** Cursor X value. */
|
|
29
|
+
cursorX?: NumberProp;
|
|
30
|
+
|
|
31
|
+
/** Cursor Y value */
|
|
32
|
+
cursorY?: NumberProp;
|
|
33
|
+
|
|
34
|
+
/** A binding used to receive the x value of the nearest point.*/
|
|
35
|
+
snapX?: Bind | AccessorChain<number | null | undefined> | AccessorChain<string | null | undefined>;
|
|
36
|
+
|
|
37
|
+
/** A binding used to receive the y value of the nearest point. */
|
|
38
|
+
snapY?: Bind | AccessorChain<number | null | undefined> | AccessorChain<string | null | undefined>;
|
|
39
|
+
|
|
40
|
+
/** A binding used to receive the record prop */
|
|
41
|
+
snapRecord?: Prop<DataRecord>;
|
|
42
|
+
|
|
43
|
+
/** Maximum distance between cursor and the snap point. Default value is 50. Adjust accordingly for large distances, e.g. set to Infinity when using TimeAxis */
|
|
44
|
+
maxDistance?: number;
|
|
45
|
+
|
|
46
|
+
/** A function used to convert x values into numeric format. Commonly used with dates. */
|
|
47
|
+
convertX?: (value: number | string) => number;
|
|
48
|
+
|
|
49
|
+
/** A function used to convert y values into numeric format. Commonly used with dates. */
|
|
50
|
+
convertY?: (value: number | string) => number;
|
|
51
|
+
|
|
52
|
+
/** Name of the x-axis. Default is 'x'. */
|
|
53
|
+
xAxis?: string;
|
|
54
|
+
|
|
55
|
+
/** Name of the y-axis. Default is 'y'. */
|
|
56
|
+
yAxis?: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export class SnapPointFinder extends PointReducer<SnapAccumulator> {
|
|
60
|
+
declare maxDistance: number;
|
|
61
|
+
declare convertX: (value: any) => number;
|
|
62
|
+
declare convertY: (value: any) => number;
|
|
63
|
+
declare xAxis: string;
|
|
64
|
+
declare yAxis: string;
|
|
65
|
+
|
|
66
|
+
constructor(config?: SnapPointFinderConfig) {
|
|
67
|
+
super(config);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
declareData(...args: any[]) {
|
|
71
|
+
super.declareData(...args, {
|
|
72
|
+
cursorX: undefined,
|
|
73
|
+
cursorY: undefined,
|
|
74
|
+
snapX: undefined,
|
|
75
|
+
snapY: undefined,
|
|
76
|
+
snapRecord: undefined,
|
|
77
|
+
maxDistance: undefined,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
explore(context: RenderingContext, instance: SnapPointFinderInstance) {
|
|
82
|
+
instance.xAxis = (context.axes as any)?.[this.xAxis];
|
|
83
|
+
instance.yAxis = (context.axes as any)?.[this.yAxis];
|
|
84
|
+
super.explore(context, instance);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
onInitAccumulator = (acc: SnapAccumulator, { data, xAxis, yAxis }: SnapPointFinderInstance) => {
|
|
88
|
+
const d = data as any;
|
|
89
|
+
acc.cursor = {
|
|
90
|
+
x: d.cursorX,
|
|
91
|
+
y: d.cursorY,
|
|
92
|
+
mapped: false,
|
|
93
|
+
};
|
|
94
|
+
acc.dist = d.maxDistance > 0 ? Math.pow(d.maxDistance, 2) : Number.POSITIVE_INFINITY;
|
|
95
|
+
acc.snapX = null;
|
|
96
|
+
acc.snapY = null;
|
|
97
|
+
acc.xAxis = xAxis;
|
|
98
|
+
acc.yAxis = yAxis;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
onMap = (acc: SnapAccumulator, x: any, y: any, name: string, p: any) => {
|
|
102
|
+
let { xAxis, yAxis, cursor } = acc;
|
|
103
|
+
|
|
104
|
+
if (!cursor.mapped) {
|
|
105
|
+
cursor.mappedX = cursor.x != null ? xAxis?.map(this.convertX(cursor.x)) : null;
|
|
106
|
+
cursor.mappedY = cursor.y != null ? yAxis?.map(this.convertY(cursor.y)) : null;
|
|
107
|
+
cursor.mapped = true;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
let d: number | null = null;
|
|
111
|
+
let cx = x != null ? xAxis?.map(this.convertX(x)) : null;
|
|
112
|
+
let cy = y != null ? yAxis?.map(this.convertY(y)) : null;
|
|
113
|
+
|
|
114
|
+
if (cursor.mappedX != null && cx != null) d = (d || 0) + Math.pow(Math.abs(cx - cursor.mappedX), 2);
|
|
115
|
+
if (cursor.mappedY != null && cy != null) d = (d || 0) + Math.pow(Math.abs(cy - cursor.mappedY), 2);
|
|
116
|
+
|
|
117
|
+
if (d != null && d < acc.dist) {
|
|
118
|
+
acc.dist = d;
|
|
119
|
+
acc.snapX = x;
|
|
120
|
+
acc.snapY = y;
|
|
121
|
+
acc.snapRecord = p;
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
onReduce = (acc: SnapAccumulator, instance: PointReducerInstance<SnapAccumulator>) => {
|
|
126
|
+
instance.set("snapX", acc.snapX);
|
|
127
|
+
instance.set("snapY", acc.snapY);
|
|
128
|
+
instance.set("snapRecord", acc.snapRecord);
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
SnapPointFinder.prototype.maxDistance = 50;
|
|
133
|
+
SnapPointFinder.prototype.convertX = (x) => x;
|
|
134
|
+
SnapPointFinder.prototype.convertY = (y) => y;
|
|
135
|
+
SnapPointFinder.prototype.xAxis = "x";
|
|
136
|
+
SnapPointFinder.prototype.yAxis = "y";
|