svelte-plots-basic 2.4.1 → 2.5.0

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.0",
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
@@ -15,19 +15,31 @@ export function getTickLabels(ticks) {
15
15
 
16
16
  const step = Math.abs(min(diff(ticks)));
17
17
  let tickFactor = 0;
18
- if (step < 1 && Math.abs(max(ticks)) < 1) {
19
- // values between 0 and 1 (absolute)
18
+
19
+ // step is large (over 1)
20
+ if (step >= 1) {
21
+ if (step < 100) return [0, Array.from(ticks).map(v => v.toFixed(0))];
22
+
23
+ let digNum = Math.ceil(Math.log10(step));
24
+ tickFactor = digNum - 2;
25
+ return [tickFactor, Array.from(ticks).map(v => (v / Math.pow(10, tickFactor)).toFixed(0))];
26
+
27
+ }
28
+
29
+ if (Math.abs(max(ticks)) < 1) {
30
+ // tick values between 0 and 1 (absolute) and step is below 1
20
31
  let decNum = Math.ceil(-Math.log10(step));
21
32
  if (decNum <= 2) {
22
- return [0, Array.from(ticks).map(v => v.toFixed(decNum).toString())];
33
+ return [0, Array.from(ticks).map(v => v.toFixed(decNum))];
23
34
  }
24
35
  tickFactor = decNum - 2;
25
36
  decNum = 2;
26
- return [-tickFactor, Array.from(ticks).map(v => (v * Math.pow(10, tickFactor)).toFixed(decNum).toString())];
37
+ return [-tickFactor, Array.from(ticks).map(v => (v * Math.pow(10, tickFactor)).toFixed(decNum))];
27
38
  } else {
28
- let decNum = Math.ceil(Math.log10(step));
39
+ // tick values above 1 (absolute) and step is below 1
40
+ let decNum = Math.ceil(-Math.log10(step));
29
41
  if (decNum <= 2) {
30
- return [0, Array.from(ticks).map(v => v.toString())];
42
+ return [0, Array.from(ticks).map(v => v.toFixed(decNum))];
31
43
  }
32
44
  tickFactor = decNum - 2;
33
45
  decNum = 2;
@@ -132,11 +144,20 @@ export function val2p(x, y, tX, tY, axes) {
132
144
  * @param {Array} lim - vector with axis limits tickets must be computed for.
133
145
  * @param {number} maxTickNum - maximum number of ticks to compute.
134
146
  * @param {boolean} round - round or not the fractions when computing nice numbers for the ticks.
147
+ * @param {boolean} whole - should the ticks be a whole number.
135
148
  *
136
149
  * @returns {Array} an array with computed tick positions.
137
150
  *
138
151
  */
139
- export function getAxisTicks(ticks, lim, maxTickNum, round = true) {
152
+ export function getAxisTicks(ticks, lim, maxTickNum, round, whole) {
153
+
154
+ if (round === undefined || round === null) {
155
+ round = true;
156
+ }
157
+
158
+ if (whole === undefined || whole === null) {
159
+ whole = false;
160
+ }
140
161
 
141
162
  // if ticks are already provided do not recompute them
142
163
  if (ticks !== undefined) {
@@ -156,8 +177,17 @@ export function getAxisTicks(ticks, lim, maxTickNum, round = true) {
156
177
 
157
178
  // get range as a nice number and compute min, max and steps for the tick sequence
158
179
  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);
180
+ const localRange = lim[1] - lim[0] - delta;
181
+ const exponent = Math.floor(Math.log10(localRange));
182
+ const fraction = 1 / Math.pow(10, exponent - 1);
183
+ const range = Math.round(localRange * fraction) / fraction;
184
+
185
+ let tickSpacing = niceNum(range / (maxTickNum - 1), round);
186
+ if (whole) {
187
+ if (tickSpacing < 1) tickSpacing = 1;
188
+ tickSpacing = Math.round(tickSpacing);
189
+ }
190
+
161
191
  const tickMin = Math.ceil((lim[0] + delta) / tickSpacing) * tickSpacing;
162
192
  const tickMax = Math.floor((lim[1] - delta) / tickSpacing) * tickSpacing;
163
193
 
@@ -188,7 +218,7 @@ export function getAxisTicks(ticks, lim, maxTickNum, round = true) {
188
218
  * @returns {Number} the computed spacing value.
189
219
  *
190
220
  */
191
- export function niceNum( localRange, round) {
221
+ export function niceNum(localRange, round) {
192
222
 
193
223
  const exponent = Math.floor(Math.log10(localRange));
194
224
  const fraction = localRange / Math.pow(10, exponent);
@@ -236,9 +266,9 @@ export function roundCoords(x) {
236
266
  *
237
267
  */
238
268
  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";
269
+ if (height < 300.2 || width < 400.2) return "small";
270
+ if (height < 400.2 || width < 700.2) return "medium";
271
+ if (height < 650.2 || width < 850.2) return "large";
242
272
  return "xlarge";
243
273
  }
244
274