svelte-plots-basic 2.5.3 → 2.5.5
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/package.json +2 -1
- package/src/2d/YAxis.svelte +1 -1
- package/src/Utils.js +38 -30
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte-plots-basic",
|
|
3
3
|
"description": "Svelte components for creating simple plots",
|
|
4
|
-
"version": "2.5.
|
|
4
|
+
"version": "2.5.5",
|
|
5
5
|
"author": "Sergey Kucheryavskiy",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"private": false,
|
|
8
8
|
"exports": {
|
|
9
|
+
"./utils": "./src/Utils.js",
|
|
9
10
|
"./2d": "./src/2d/index.js",
|
|
10
11
|
"./2d/*.svelte": "./src/2d/*.svelte",
|
|
11
12
|
"./3d": "./src/3d/index.js",
|
package/src/2d/YAxis.svelte
CHANGED
package/src/Utils.js
CHANGED
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
import { cbind, vector, isvector, Vector } from 'mdatools/arrays';
|
|
2
2
|
import { min, max, diff } from 'mdatools/stat';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Trim number leaving only significant decimals.
|
|
6
|
+
* @param {number} num
|
|
7
|
+
* @returns trimmed number
|
|
8
|
+
*/
|
|
9
|
+
function trimNum(num) {
|
|
10
|
+
|
|
11
|
+
// check if number is whole — return as is
|
|
12
|
+
if (num === Math.round(num)) return num;
|
|
13
|
+
|
|
14
|
+
// Convert to string with precision to maintain significant digits
|
|
15
|
+
let str = num.toPrecision(12);
|
|
16
|
+
|
|
17
|
+
// Remove trailing zeros
|
|
18
|
+
str = str.replace(/\.?0+$/, '');
|
|
19
|
+
|
|
20
|
+
// Convert back to number
|
|
21
|
+
return parseFloat(str);
|
|
22
|
+
}
|
|
4
23
|
|
|
5
24
|
/**
|
|
6
25
|
* Generate vector with axis tick labels and tick factor based on numeric tick values.
|
|
@@ -14,44 +33,29 @@ export function getTickLabels(ticks) {
|
|
|
14
33
|
if (ticks === undefined) return undefined;
|
|
15
34
|
if (ticks.length === 1) return [0, [ticks[0].toString()]];
|
|
16
35
|
|
|
17
|
-
|
|
36
|
+
// compute and correct step between ticks
|
|
37
|
+
let step = trimNum(Math.abs(min(diff(ticks))));
|
|
18
38
|
let tickFactor = 0;
|
|
19
39
|
|
|
20
40
|
// step is large (over 1)
|
|
21
41
|
if (step >= 1 && ticks.length > 1) {
|
|
22
42
|
if (step < 100) return [0, Array.from(ticks).map(v => v.toFixed(0))];
|
|
23
|
-
|
|
24
|
-
let digNum = Math.ceil(Math.log10(step));
|
|
43
|
+
let digNum = Math.ceil(trimNum(Math.log10(step)));
|
|
25
44
|
tickFactor = digNum - 2;
|
|
26
45
|
return [tickFactor, Array.from(ticks).map(v => (v / Math.pow(10, tickFactor)).toFixed(0))];
|
|
27
46
|
}
|
|
28
47
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
48
|
+
let decNum = Math.ceil(-trimNum(Math.log10(step)));
|
|
49
|
+
if (decNum <= 2) {
|
|
50
|
+
return [0, Array.from(ticks).map(v => v.toFixed(decNum))];
|
|
51
|
+
}
|
|
52
|
+
tickFactor = decNum - 2;
|
|
53
|
+
decNum = 2;
|
|
35
54
|
|
|
36
|
-
|
|
37
|
-
return [0, Array.from(ticks).map(v => v.toFixed(decNum))];
|
|
38
|
-
}
|
|
39
|
-
tickFactor = decNum - 2;
|
|
40
|
-
decNum = 2;
|
|
55
|
+
if (trimNum(Math.abs(max(ticks))) <= 10) {
|
|
41
56
|
return [-tickFactor, Array.from(ticks).map(v => (v * Math.pow(10, tickFactor)).toFixed(decNum))];
|
|
42
57
|
} else {
|
|
43
|
-
|
|
44
|
-
let decNum = -Math.log10(step);
|
|
45
|
-
|
|
46
|
-
// adjust the decNum value in case if small decimals are present
|
|
47
|
-
decNum = Math.ceil(Math.round(decNum * 100)/100);
|
|
48
|
-
|
|
49
|
-
if (decNum <= 2) {
|
|
50
|
-
return [0, Array.from(ticks).map(v => v.toFixed(decNum))];
|
|
51
|
-
}
|
|
52
|
-
tickFactor = decNum - 2;
|
|
53
|
-
decNum = 2;
|
|
54
|
-
return [tickFactor, Array.from(ticks).map(v => (v / Math.pow(10, tickFactor)).toString())];
|
|
58
|
+
return [-tickFactor, Array.from(ticks).map(v => (v / Math.pow(10, tickFactor)).toString())];
|
|
55
59
|
}
|
|
56
60
|
}
|
|
57
61
|
|
|
@@ -184,7 +188,7 @@ export function getAxisTicks(ticks, lim, maxTickNum, round, whole) {
|
|
|
184
188
|
if (typeof(lim) !== "object" || lim[0] === undefined || lim[1] === undefined) return undefined;
|
|
185
189
|
|
|
186
190
|
// get range as a nice number and compute min, max and steps for the tick sequence
|
|
187
|
-
const delta = (lim[1] - lim[0]) /
|
|
191
|
+
const delta = (lim[1] - lim[0]) / 100;
|
|
188
192
|
const localRange = lim[1] - lim[0] - delta;
|
|
189
193
|
const exponent = Math.floor(Math.log10(localRange));
|
|
190
194
|
const fraction = 1 / Math.pow(10, exponent - 1);
|
|
@@ -197,11 +201,15 @@ export function getAxisTicks(ticks, lim, maxTickNum, round, whole) {
|
|
|
197
201
|
}
|
|
198
202
|
|
|
199
203
|
// compute smallest and largest tick rounded to tickSpacing
|
|
200
|
-
|
|
201
|
-
|
|
204
|
+
let tickMin = Math.ceil((lim[0] + delta ) / tickSpacing) * tickSpacing;
|
|
205
|
+
let tickMax = Math.floor((lim[1] - delta) / tickSpacing) * tickSpacing;
|
|
206
|
+
|
|
207
|
+
// adjust largest tick if it is too close to axis limit and tick spacing
|
|
208
|
+
// is small (so tick factor may appear)
|
|
209
|
+
if (tickSpacing < 0.1 && (lim[1] - tickMax) < (tickSpacing / 2)) tickMax = tickMax - tickSpacing;
|
|
202
210
|
|
|
203
211
|
// recompute maxTickNum
|
|
204
|
-
maxTickNum = Math.ceil((tickMax - tickMin) / tickSpacing) + 1;
|
|
212
|
+
maxTickNum = (Math.ceil(trimNum((tickMax - tickMin) / tickSpacing)) + 1);
|
|
205
213
|
|
|
206
214
|
// create a sequence of ticks
|
|
207
215
|
ticks = Vector.zeros(maxTickNum);
|