svelte-plots-basic 2.5.6 → 2.5.8

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.6",
4
+ "version": "2.5.8",
5
5
  "author": "Sergey Kucheryavskiy",
6
6
  "license": "MIT",
7
7
  "private": false,
@@ -8,7 +8,7 @@
8
8
  import { setContext, createEventDispatcher, onMount, onDestroy } from 'svelte';
9
9
  import { writable } from 'svelte/store';
10
10
  import { isvector, vector, Vector } from 'mdatools/arrays';
11
- import { roundCoords, getScale, downloadSVG, downloadPNG, createPngBlob } from '../Utils.js';
11
+ import { roundCoords, getScale, downloadSVG, downloadPNG, createPngBlob, getAxisScale } from '../Utils.js';
12
12
 
13
13
 
14
14
  /*****************************************/
@@ -50,14 +50,22 @@
50
50
  'xlarge': 60
51
51
  }
52
52
 
53
- // number of ticks along each axis
54
- const TICK_NUM = {
53
+ // number of x-ticks along each axis
54
+ const XTICK_NUM = {
55
55
  'small': 5,
56
56
  'medium': 8,
57
57
  'large': 12,
58
58
  'xlarge': 15
59
59
  };
60
60
 
61
+ // number of y-ticks along each axis
62
+ const YTICK_NUM = {
63
+ 'small': 6,
64
+ 'medium': 10,
65
+ 'large': 14,
66
+ 'xlarge': 18
67
+ };
68
+
61
69
  // size of ticks
62
70
  const TICK_SIZE = {
63
71
  'small': 4,
@@ -246,6 +254,8 @@
246
254
  /* Storage to share with children */
247
255
  /*****************************************/
248
256
 
257
+ const xscale = writable('medium'); // scale factor for x-axis (influences number of ticks)
258
+ const yscale = writable('medium'); // scale factor for y-axis (influences number of ticks)
249
259
  const scale = writable('medium'); // scale factor (how big the shown plot is)
250
260
  const isOk = writable(false); // are axes ready for drawing
251
261
  const xLim = writable(limX); // validated values for x-axis limits
@@ -266,6 +276,8 @@
266
276
 
267
277
  // variables
268
278
  scale: scale,
279
+ xscale: xscale,
280
+ yscale: yscale,
269
281
  isOk: isOk,
270
282
  xLim: xLim,
271
283
  yLim: yLim,
@@ -277,7 +289,8 @@
277
289
  // constants
278
290
  LINE_STYLES: LINE_STYLES,
279
291
  LABELS_MARGIN: LABELS_MARGIN,
280
- TICK_NUM: TICK_NUM,
292
+ XTICK_NUM: XTICK_NUM,
293
+ YTICK_NUM: YTICK_NUM,
281
294
  TICK_SIZE: TICK_SIZE,
282
295
  MARKER_SYMBOLS: MARKER_SYMBOLS,
283
296
  LEGEND_FONT_SIZE: LEGEND_FONT_SIZE
@@ -347,7 +360,11 @@
347
360
  for (let entry of entries) {
348
361
  const pcr = plotElement.getBoundingClientRect();
349
362
  const scl = getScale(pcr.width, pcr.height);
363
+ const xscl = getAxisScale(pcr.width);
364
+ const yscl = getAxisScale(pcr.height);
350
365
  scale.update(x => scl);
366
+ xscale.update(x => xscl);
367
+ yscale.update(x => yscl);
351
368
 
352
369
  const m = PLOT_FONT_SIZE[scl] * 1.5;
353
370
  left = xLabel && xLabel !== '' ? m : 0;
@@ -7,10 +7,11 @@
7
7
  *****************************************************/
8
8
 
9
9
  import { Colors } from '../Colors.js';
10
+ import { getTickFactorLabel } from '../Utils.js';
11
+
10
12
  import AxisLines from './AxisLines.svelte';
11
13
  import AxisTickLabels from './AxisTickLabels.svelte';
12
14
 
13
-
14
15
  /*****************************************/
15
16
  /* Input parameters */
16
17
  /*****************************************/
@@ -32,14 +33,6 @@
32
33
  export let textColor = Colors.DARKGRAY; // color of tick labels
33
34
 
34
35
  // generate text for tick factor label
35
- function getTickFactorLabel(tf) {
36
- if (tf === 0) return '';
37
- if (tf < 0) {
38
- return `&times;10<tspan dy="-0.5em">${(tf).toString()}</tspan>`;
39
- } else {
40
- return `&times;10<tspan dy="-0.5em">${(tf).toString()}</tspan>`;
41
- }
42
- }
43
36
  </script>
44
37
 
45
38
  <g class="mdaplot__axis {className}">
@@ -6,7 +6,7 @@
6
6
  **********************************************************/
7
7
 
8
8
  import { getContext } from 'svelte';
9
- import { checkCoords } from '../Utils';
9
+ import { checkCoords, getTickLabels, getTickFactorLabel } from '../Utils';
10
10
  import { Vector, isvector } from 'mdatools/arrays';
11
11
 
12
12
 
@@ -44,17 +44,21 @@
44
44
 
45
45
  // check colormap values
46
46
  $: if (!colmap || !(colmap.length === breaks.length - 1 || colmap.length === breaks.length )) {
47
- console.log(colmap)
48
- console.log(breaks)
49
- console.log(labels)
50
47
  throw new Error('ColormapLegend: number of color values in colormap does not match number of intervals defined by breaks.');
51
48
  }
52
49
 
53
50
  // define local variables for breaks and prepare breaks labels
54
51
  $: lBreaks = isvector(breaks) ? breaks.v : breaks;
55
- $: lLabels = labels && labels.length === lBreaks.length ?
56
- labels :
57
- Array.from(lBreaks).map(v => v.toFixed(decNum).toString());
52
+
53
+ let breakFactor, breakLabels;
54
+ $: if (lBreaks) {
55
+ [breakFactor, breakLabels] = getTickLabels(lBreaks);
56
+ } else {
57
+ breakFactor = null;
58
+ breakLabels = null;
59
+ }
60
+
61
+ $: lLabels = labels && labels.length === lBreaks.length ? labels : breakLabels;
58
62
 
59
63
  // get axes context and reactive variables needed to compute coordinates
60
64
  const axes = getContext('axes');
@@ -80,7 +84,7 @@
80
84
  const height = axesHeight * HEIGHT_RATIO;
81
85
 
82
86
  // compute elements size and position
83
- const elWidth = width / n;
87
+ const elWidth = width / (n + (breakFactor !== 0));
84
88
  const left = $xLim[0] + axesWidth * (1 - WIDTH_RATIO) * 0.5 ;
85
89
  const elTop = $yLim[1] - height * TOP_MARGIN;
86
90
 
@@ -103,7 +107,14 @@
103
107
  {#if !isCentered}
104
108
  <text x={rx[n]} y={ry} dx={0} dy={rh * 1.25} dominant-baseline="hanging" fill={labelColor} font-size="{fontSize}em" text-anchor="middle">{@html lLabels[n]}</text>
105
109
  {/if}
110
+
111
+ {#if breakFactor !== 0}
112
+ <text x={rx[n] + rw[0] * 0.85} y={ry[0] + rh * 2.2} dx={0} dy={0} dominant-baseline="hanging" fill={labelColor} font-size="{fontSize}em" text-anchor="middle">{@html getTickFactorLabel(breakFactor)}</text>
113
+ {/if}
114
+
106
115
  </g>
116
+
117
+
107
118
  {/if}
108
119
 
109
120
 
@@ -1,9 +1,9 @@
1
1
  <script>
2
- /****************************************************
3
- * X-Axis *
4
- * -------------------- *
5
- * shows x-axis and its elements (ticks, grid, etc.) *
6
- *****************************************************/
2
+ /*****************************************************/
3
+ /* X-Axis */
4
+ /* -------------------- */
5
+ /* shows x-axis and its elements (ticks, grid, etc.) */
6
+ /*****************************************************/
7
7
 
8
8
  import { getContext } from 'svelte';
9
9
  import { Vector, vector } from 'mdatools/arrays';
@@ -44,6 +44,7 @@
44
44
  const xLim = axes.xLim;
45
45
  const yLim = axes.yLim;
46
46
  const scale = axes.scale;
47
+ const xscale = axes.xscale;
47
48
  const isOk = axes.isOk;
48
49
  const tY = axes.tY;
49
50
 
@@ -58,7 +59,7 @@
58
59
  $: if ($isOk) {
59
60
 
60
61
  // compute x-coordinates of the ticks or take the ones manually specified by user
61
- const ticksX = getAxisTicks(ticks, $xLim, axes.TICK_NUM[$scale], true, whole);
62
+ const ticksX = getAxisTicks(ticks, $xLim, axes.XTICK_NUM[$xscale], true, whole);
62
63
  const tickNum = ticksX.length;
63
64
 
64
65
  // compute tick y-coordinates (up and bottom)
@@ -44,6 +44,7 @@
44
44
  const xLim = axes.xLim;
45
45
  const yLim = axes.yLim;
46
46
  const scale = axes.scale;
47
+ const yscale = axes.yscale;
47
48
  const isOk = axes.isOk;
48
49
  const tX = axes.tX;
49
50
 
@@ -58,7 +59,7 @@
58
59
  $: if ($isOk) {
59
60
 
60
61
  // compute x-coordinates of the ticks or take the ones manually specified by user
61
- const ticksY = getAxisTicks(ticks, $yLim, axes.TICK_NUM[$scale], true, whole);
62
+ const ticksY = getAxisTicks(ticks, $yLim, axes.YTICK_NUM[$yscale], true, whole);
62
63
  const tickNum = ticksY.length;
63
64
 
64
65
  // compute tick y-coordinates (up and bottom)
package/src/Utils.js CHANGED
@@ -1,12 +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
+ /**
6
+ * Creates label for a tick factor.
7
+ *
8
+ * @param {Number} tf - tick factor value (negative or positive)
9
+ * @returns
10
+ */
11
+ export function getTickFactorLabel(tf) {
12
+ if (tf === 0) return '';
13
+ return `<tspan>&times;10</tspan><tspan baseline-shift="super">${(tf).toString()}</tspan>`;
14
+ }
15
+
16
+
4
17
  /**
5
18
  * Trim number leaving only significant decimals.
6
19
  * @param {number} num
7
20
  * @returns trimmed number
8
21
  */
9
- function trimNum(num) {
22
+ export function trimNum(num) {
10
23
 
11
24
  // check if number is whole — return as is
12
25
  if (num === Math.round(num)) return num;
@@ -193,13 +206,13 @@ export function getAxisTicks(ticks, lim, maxTickNum, round, whole, deltaFactor)
193
206
  if (typeof(lim) !== "object" || lim[0] === undefined || lim[1] === undefined) return undefined;
194
207
 
195
208
  // get range as a nice number and compute min, max and steps for the tick sequence
196
- const delta = (lim[1] - lim[0]) * deltaFactor;
197
- const localRange = lim[1] - lim[0] - delta;
209
+ const delta = Math.abs((lim[1] - lim[0])) * deltaFactor;
210
+ const localRange = lim[1] - lim[0] - 2 * delta;
198
211
  const exponent = Math.floor(Math.log10(localRange));
199
212
  const fraction = 1 / Math.pow(10, exponent - 1);
200
213
  const range = Math.round(localRange * fraction) / fraction;
201
214
 
202
- let tickSpacing = niceNum(range / (maxTickNum - 1), round);
215
+ let tickSpacing = niceNum(range / maxTickNum, false);
203
216
  if (whole) {
204
217
  if (tickSpacing < 1) tickSpacing = 1;
205
218
  tickSpacing = Math.round(tickSpacing);
@@ -297,6 +310,19 @@ export function getScale(width, height) {
297
310
  return "xlarge";
298
311
  }
299
312
 
313
+ /**
314
+ * Computes a scale level for single axis.
315
+ *
316
+ * @param {numeric} size - width or height of plotting area in pixels.
317
+ * @returns {text} the scale level ("small", "medium" or "large").
318
+ *
319
+ */
320
+ export function getAxisScale(width, size) {
321
+ if (width < 400.2) return "small";
322
+ if (width < 700.2) return "medium";
323
+ if (width < 900.2) return "large";
324
+ return "xlarge";
325
+ }
300
326
 
301
327
  /*************************************************************/
302
328
  /* Functions needed to adjust DPI of resulting PNG image */