svelte-plots-basic 2.5.3 → 2.5.4

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "svelte-plots-basic",
3
3
  "description": "Svelte components for creating simple plots",
4
- "version": "2.5.3",
4
+ "version": "2.5.4",
5
5
  "author": "Sergey Kucheryavskiy",
6
6
  "license": "MIT",
7
7
  "private": false,
@@ -96,7 +96,7 @@
96
96
 
97
97
  tfCoords = [
98
98
  [[], []],
99
- [[ticksX1.v[tickNum - 1]], [$yLim[1]]],
99
+ [[ticksX2.v[tickNum - 1] + dX], [$yLim[1]]],
100
100
  ];
101
101
  }
102
102
  </script>
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
- const step = Math.abs(min(diff(ticks)));
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
- if (Math.abs(max(ticks)) < 1) {
30
- // tick values between 0 and 1 (absolute) and step is below 1
31
- let decNum = -Math.log10(step);
32
-
33
- // adjust the decNum value in case if small decimals are present
34
- decNum = Math.ceil(Math.round(decNum * 100)/100);
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
- if (decNum <= 2) {
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
- // tick values above 1 (absolute) and step is below 1
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]) / 50;
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
- const tickMin = Math.ceil((lim[0] + delta) / tickSpacing) * tickSpacing;
201
- const tickMax = Math.floor((lim[1] - delta) / tickSpacing) * tickSpacing;
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);