svelte-plots-basic 2.4.1 → 2.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/README.md CHANGED
@@ -11,6 +11,12 @@ These websites and web-applications use `svelte-plots-basic` library:
11
11
 
12
12
  ## News
13
13
 
14
+ ### 2.5.0
15
+
16
+ * improvements to axis ticks and tick labels estimation.
17
+ * `<XAxis>` and `<YAxis>` got a new logical parameter `whole` to force using whole numbers as ticks.
18
+
19
+
14
20
  ### 2.4.0
15
21
 
16
22
  * added possibility to copy a plot to clipboard.
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.4.1",
4
+ "version": "2.5.1",
5
5
  "author": "Sergey Kucheryavskiy",
6
6
  "license": "MIT",
7
7
  "private": false,
@@ -21,6 +21,7 @@
21
21
  export let tickLabels = undefined; // vector with labels for each tick (by default tick values will be used)
22
22
  export let showGrid = false; // logical, show or not grid lines
23
23
  export let las = 1; // orientation of tick labels (1 - horizontal, 2 - vertical)
24
+ export let whole = false; // should the ticks be a whole number or not
24
25
 
25
26
  export let lineColor = Colors.DARKGRAY; // color of axis and tick lines
26
27
  export let gridColor = Colors.MIDDLEGRAY; // color og grid lines
@@ -57,7 +58,7 @@
57
58
  $: if ($isOk) {
58
59
 
59
60
  // compute x-coordinates of the ticks or take the ones manually specified by user
60
- const ticksX = getAxisTicks(ticks, $xLim, axes.TICK_NUM[$scale], true);
61
+ const ticksX = getAxisTicks(ticks, $xLim, axes.TICK_NUM[$scale], true, whole);
61
62
  const tickNum = ticksX.length;
62
63
 
63
64
  // compute tick y-coordinates (up and bottom)
@@ -21,6 +21,7 @@
21
21
  export let tickLabels = undefined; // vector with labels for each tick (by default tick values will be used)
22
22
  export let showGrid = false; // logical, show or not grid lines
23
23
  export let las = 1; // orientation of tick labels (1 - horizontal, 2 - vertical)
24
+ export let whole = false; // should the ticks be a whole number or not
24
25
 
25
26
  export let lineColor = Colors.DARKGRAY; // color of axis and tick lines
26
27
  export let gridColor = Colors.MIDDLEGRAY; // color og grid lines
@@ -57,7 +58,7 @@
57
58
  $: if ($isOk) {
58
59
 
59
60
  // compute x-coordinates of the ticks or take the ones manually specified by user
60
- const ticksY = getAxisTicks(ticks, $yLim, axes.TICK_NUM[$scale], true);
61
+ const ticksY = getAxisTicks(ticks, $yLim, axes.TICK_NUM[$scale], true, whole);
61
62
  const tickNum = ticksY.length;
62
63
 
63
64
  // compute tick y-coordinates (up and bottom)
package/src/Utils.js CHANGED
@@ -13,21 +13,35 @@ export function getTickLabels(ticks) {
13
13
 
14
14
  if (ticks === undefined) return undefined;
15
15
 
16
+ if (ticks.length === 1) return [0, [ticks[0].toString()]];
17
+
16
18
  const step = Math.abs(min(diff(ticks)));
17
19
  let tickFactor = 0;
18
- if (step < 1 && Math.abs(max(ticks)) < 1) {
19
- // values between 0 and 1 (absolute)
20
+
21
+ // step is large (over 1)
22
+ if (step >= 1 && ticks.length > 1) {
23
+ if (step < 100) return [0, Array.from(ticks).map(v => v.toFixed(0))];
24
+
25
+ let digNum = Math.ceil(Math.log10(step));
26
+ tickFactor = digNum - 2;
27
+ return [tickFactor, Array.from(ticks).map(v => (v / Math.pow(10, tickFactor)).toFixed(0))];
28
+
29
+ }
30
+
31
+ if (Math.abs(max(ticks)) < 1) {
32
+ // tick values between 0 and 1 (absolute) and step is below 1
20
33
  let decNum = Math.ceil(-Math.log10(step));
21
34
  if (decNum <= 2) {
22
- return [0, Array.from(ticks).map(v => v.toFixed(decNum).toString())];
35
+ return [0, Array.from(ticks).map(v => v.toFixed(decNum))];
23
36
  }
24
37
  tickFactor = decNum - 2;
25
38
  decNum = 2;
26
- return [-tickFactor, Array.from(ticks).map(v => (v * Math.pow(10, tickFactor)).toFixed(decNum).toString())];
39
+ return [-tickFactor, Array.from(ticks).map(v => (v * Math.pow(10, tickFactor)).toFixed(decNum))];
27
40
  } else {
28
- let decNum = Math.ceil(Math.log10(step));
41
+ // tick values above 1 (absolute) and step is below 1
42
+ let decNum = Math.ceil(-Math.log10(step));
29
43
  if (decNum <= 2) {
30
- return [0, Array.from(ticks).map(v => v.toString())];
44
+ return [0, Array.from(ticks).map(v => v.toFixed(decNum))];
31
45
  }
32
46
  tickFactor = decNum - 2;
33
47
  decNum = 2;
@@ -132,11 +146,20 @@ export function val2p(x, y, tX, tY, axes) {
132
146
  * @param {Array} lim - vector with axis limits tickets must be computed for.
133
147
  * @param {number} maxTickNum - maximum number of ticks to compute.
134
148
  * @param {boolean} round - round or not the fractions when computing nice numbers for the ticks.
149
+ * @param {boolean} whole - should the ticks be a whole number.
135
150
  *
136
151
  * @returns {Array} an array with computed tick positions.
137
152
  *
138
153
  */
139
- export function getAxisTicks(ticks, lim, maxTickNum, round = true) {
154
+ export function getAxisTicks(ticks, lim, maxTickNum, round, whole) {
155
+
156
+ if (round === undefined || round === null) {
157
+ round = true;
158
+ }
159
+
160
+ if (whole === undefined || whole === null) {
161
+ whole = false;
162
+ }
140
163
 
141
164
  // if ticks are already provided do not recompute them
142
165
  if (ticks !== undefined) {
@@ -156,8 +179,17 @@ export function getAxisTicks(ticks, lim, maxTickNum, round = true) {
156
179
 
157
180
  // get range as a nice number and compute min, max and steps for the tick sequence
158
181
  const delta = (lim[1] - lim[0]) / 50;
159
- const range = niceNum(lim[1] - lim[0] - 1 * delta, round);
160
- const tickSpacing = niceNum(range / (maxTickNum - 1), round);
182
+ const localRange = lim[1] - lim[0] - delta;
183
+ const exponent = Math.floor(Math.log10(localRange));
184
+ const fraction = 1 / Math.pow(10, exponent - 1);
185
+ const range = Math.round(localRange * fraction) / fraction;
186
+
187
+ let tickSpacing = niceNum(range / (maxTickNum - 1), round);
188
+ if (whole) {
189
+ if (tickSpacing < 1) tickSpacing = 1;
190
+ tickSpacing = Math.round(tickSpacing);
191
+ }
192
+
161
193
  const tickMin = Math.ceil((lim[0] + delta) / tickSpacing) * tickSpacing;
162
194
  const tickMax = Math.floor((lim[1] - delta) / tickSpacing) * tickSpacing;
163
195
 
@@ -188,7 +220,7 @@ export function getAxisTicks(ticks, lim, maxTickNum, round = true) {
188
220
  * @returns {Number} the computed spacing value.
189
221
  *
190
222
  */
191
- export function niceNum( localRange, round) {
223
+ export function niceNum(localRange, round) {
192
224
 
193
225
  const exponent = Math.floor(Math.log10(localRange));
194
226
  const fraction = localRange / Math.pow(10, exponent);
@@ -236,9 +268,9 @@ export function roundCoords(x) {
236
268
  *
237
269
  */
238
270
  export function getScale(width, height) {
239
- if (height < 300.2 || width < 300.2) return "small";
240
- if (height < 600.2 || width < 600.2) return "medium";
241
- if (height < 850.2 || width < 850.2) return "large";
271
+ if (height < 300.2 || width < 400.2) return "small";
272
+ if (height < 400.2 || width < 700.2) return "medium";
273
+ if (height < 650.2 || width < 850.2) return "large";
242
274
  return "xlarge";
243
275
  }
244
276