svelte-plots-basic 1.1.3 → 2.0.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.
Files changed (50) hide show
  1. package/README.md +54 -69
  2. package/package.json +28 -33
  3. package/src/2d/Area.svelte +61 -0
  4. package/src/2d/Axes.svelte +500 -0
  5. package/src/2d/Axis.svelte +50 -0
  6. package/src/2d/AxisLines.svelte +54 -0
  7. package/src/2d/AxisTickLabels.svelte +82 -0
  8. package/src/2d/Bars.svelte +65 -0
  9. package/src/2d/Box.svelte +50 -0
  10. package/src/2d/ColorLegend.svelte +36 -0
  11. package/src/2d/Legend.svelte +148 -0
  12. package/src/2d/Lines.svelte +49 -0
  13. package/src/2d/Multilines.svelte +67 -0
  14. package/src/2d/Points.svelte +79 -0
  15. package/src/2d/Rectangles.svelte +74 -0
  16. package/src/2d/Segments.svelte +65 -0
  17. package/src/2d/TextLabels.svelte +107 -0
  18. package/src/2d/TextLegend.svelte +53 -0
  19. package/src/2d/XAxis.svelte +99 -0
  20. package/src/2d/YAxis.svelte +99 -0
  21. package/src/{index.js → 2d/index.js} +10 -6
  22. package/src/3d/Axes.svelte +445 -0
  23. package/src/3d/Axis.svelte +64 -0
  24. package/src/3d/AxisLines.svelte +50 -0
  25. package/src/3d/AxisTickLabels.svelte +54 -0
  26. package/src/3d/Lines.svelte +49 -0
  27. package/src/3d/Mesh.svelte +188 -0
  28. package/src/3d/Points.svelte +61 -0
  29. package/src/3d/Segments.svelte +69 -0
  30. package/src/3d/TextLabels.svelte +79 -0
  31. package/src/3d/XAxis.svelte +123 -0
  32. package/src/3d/YAxis.svelte +123 -0
  33. package/src/3d/ZAxis.svelte +123 -0
  34. package/src/3d/index.js +13 -0
  35. package/src/Colors.js +36 -1
  36. package/src/Utils.js +205 -0
  37. package/dist/index.js +0 -4209
  38. package/dist/index.mjs +0 -4187
  39. package/src/AreaSeries.svelte +0 -53
  40. package/src/Axes.svelte +0 -538
  41. package/src/BarSeries.svelte +0 -78
  42. package/src/Box.svelte +0 -35
  43. package/src/LineSeries.svelte +0 -50
  44. package/src/Rectangles.svelte +0 -64
  45. package/src/ScatterSeries.svelte +0 -85
  46. package/src/Segments.svelte +0 -48
  47. package/src/TextLabels.svelte +0 -78
  48. package/src/TextLegend.svelte +0 -38
  49. package/src/XAxis.svelte +0 -69
  50. package/src/YAxis.svelte +0 -72
@@ -1,53 +0,0 @@
1
- <script>
2
-
3
- import { getContext } from 'svelte';
4
- import { mrange } from 'mdatools/stat';
5
- import { Colors } from './Colors';
6
-
7
- // input parameters
8
- export let xValues;
9
- export let yValues;
10
- export let title = "";
11
- export let lineWidth = 1;
12
- export let lineColor = Colors.PRIMARY;
13
- export let fillColor = Colors.PRIMARY;
14
- export let opacity = 1;
15
- export let lineType = 1;
16
-
17
- /* sanity check of input parameters */
18
- if (!Array.isArray(xValues) || !Array.isArray(yValues) || xValues.length != yValues.length) {
19
- throw("AreaSeries: parameters 'xValues' and 'yValues' must be numeric vectors of the same length.");
20
- }
21
-
22
- // compute ranges for x and y values
23
- const xValuesRange = mrange(xValues, 0.05);
24
- const yValuesRange = mrange(yValues, 0.05);
25
-
26
- // get axes context and adjust axes limits
27
- const axes = getContext('axes');
28
- axes.adjustXAxisLimits(xValuesRange);
29
- axes.adjustYAxisLimits(yValuesRange);
30
-
31
- // get reactive variables needed to compute coordinates
32
- const xLim = axes.xLim;
33
- const yLim = axes.yLim;
34
- const axesWidth = axes.width;
35
- const axesHeight = axes.height;
36
- const scale = axes.scale;
37
-
38
- // reactive variables for coordinates of data points in pixels
39
- $: y0 = axes.scaleY([0], $yLim, $axesHeight);
40
- $: x = axes.scaleX(xValues, $xLim, $axesWidth);
41
- $: y = axes.scaleY(yValues, $yLim, $axesHeight);
42
- $: p = x !== undefined && y !== undefined ? x.map((v, i) => `${v},${y[i]}`).join(' ') : undefined;
43
- $: areaStyleStr = `opacity:${opacity};fill:${fillColor};stroke:${lineColor};stroke-width: ${lineWidth}px;stroke-dasharray:${axes.LINE_STYLES[$scale][lineType - 1]}`;
44
- </script>
45
-
46
- {#if p !== undefined}
47
- <g class="series lineseries" style="{areaStyleStr}" title="{title}">
48
- <polygon points="{x[0] + "," + y0 + " " + p + " " + x[x.length - 1] + "," + y0[0]}"/>
49
- </g>
50
- {/if}
51
-
52
- <style>
53
- </style>
package/src/Axes.svelte DELETED
@@ -1,538 +0,0 @@
1
- <script>
2
- import { setContext, createEventDispatcher, onMount, onDestroy } from 'svelte';
3
- import { writable } from 'svelte/store';
4
-
5
- /* input parameters */
6
- export let limX = [undefined, undefined]; // limits for x-axis (in plot units) [min, max]
7
- export let limY = [undefined, undefined]; // limits for y-axis (in plot units) [min, max]
8
- export let title = ""; // title of the plot
9
- export let xLabel = ""; // label for x-axis
10
- export let yLabel = ""; // label for y-axis
11
- export let multiSeries = true; // is the plot for one series or for many
12
-
13
- // event dispatcher
14
- const dispatch = createEventDispatcher();
15
-
16
- // how big are margins (number of pixels in unit margin value) between axis and plot area if axis are shown
17
- const AXES_MARGIN_FACTORS = {
18
- "small": 30,
19
- "medium": 40,
20
- "large": 50
21
- }
22
-
23
- // number of ticks along each axis
24
- const TICK_NUM = {
25
- "small": 5,
26
- "medium": 8,
27
- "large": 12
28
- };
29
-
30
- // margin between plot series elements and data labels
31
- const LABELS_MARGIN = {
32
- "small": 10,
33
- "medium": 15,
34
- "large": 20
35
- };
36
-
37
-
38
- // line styles for different scales and types
39
- const LINE_STYLES = {
40
- small: ["0", "3,3", "1,1", "3,1"],
41
- medium: ["0", "5,5", "2,2", "5,2"],
42
- large: ["0", "7,7", "3,3", "7,3"],
43
- }
44
-
45
- // constant to make clip path ID unique
46
- const clipPathID = "plottingArea" + Math.round(Math.random() * 10000);
47
-
48
- /* parameters for internal use inside the component */
49
- let plotElement;
50
- let axesElement;
51
- let axesMargins = [0.034, 0.034, 0.034, 0.034]; // initial margins (will be multiplied to FACTORS)
52
-
53
- /* reactive parameters to be shared with children via context */
54
- const width = writable(100); // actual width of plotting area in pixels
55
- const height = writable(100); // actual height of plotting area in pixels
56
- const xLim = writable([undefined, undefined]); // actual limits for x-axis in plot units
57
- const yLim = writable([undefined, undefined]); // actual limits for y-axis in plot units
58
- const scale = writable("medium"); // scale factor (how big the shown plot is)
59
- const isOk = writable(false); // are axes ready for drawing
60
-
61
- /** Adds margins for x-axis (e.g. when x-axis must be shown) */
62
- const addXAxisMargins = function() {
63
- axesMargins[0] = 1;
64
- axesMargins[2] = 0.5;
65
- axesMargins[1] = axesMargins[1] > 0.5 ? axesMargins[1] : 0.5;
66
- axesMargins[3] = axesMargins[3] > 0.5 ? axesMargins[3] : 0.5;
67
- }
68
-
69
- /** Adds margins for y-axis (e.g. when y-axis must be shown) */
70
- const addYAxisMargins = function() {
71
- axesMargins[1] = 1;
72
- axesMargins[3] = 0.5;
73
- axesMargins[0] = axesMargins[0] > 0.5 ? axesMargins[0] : 0.5;
74
- axesMargins[2] = axesMargins[2] > 0.5 ? axesMargins[2] : 0.5;
75
- }
76
-
77
- /** Adjusts limits for x-axis (e.g. when new series is added)
78
- * @param {Array} newLim - vector with new limits (two values)
79
- */
80
- const adjustXAxisLimits = function(newLim) {
81
- if (!limX.some(v => v === undefined)) return;
82
- xLim.update(lim => adjustAxisLimits(lim, newLim));
83
- }
84
-
85
- /** Adjusts limits for y-axis (e.g. when new series is added)
86
- * @param {Array} newLim - vector with new limits (two values)
87
- */
88
- const adjustYAxisLimits = function(newLim) {
89
- if (!limY.some(v => v === undefined)) return;
90
- yLim.update(lim => adjustAxisLimits(lim, newLim));
91
- }
92
-
93
- /** Adjusts x- or y- axis limits (e.g. when new elements are added)
94
- * @param {Array} lim - vector with limits for current axis (two values)
95
- * @param {Array} newLim - vector with new limits (two values)
96
- * @returns {Array} vector with rescaled values
97
- *
98
- * The new limits are set separately for min and max. Either if current value is undefined or
99
- * if new value is outside the current limits (smaller than min or larger than max).
100
- */
101
- const adjustAxisLimits = function(lim, newLim) {
102
-
103
- let adjustedLim = [
104
- (lim[0] !== undefined && multiSeries === true && lim[0] < newLim[0]) ? lim[0] : newLim[0],
105
- (lim[1] !== undefined && multiSeries === true && lim[1] > newLim[1]) ? lim[1] : newLim[1]
106
- ];
107
-
108
- // special case when both limits are zero
109
- if (adjustedLim[0] === 0 && adjustedLim[1] === 0) {
110
- adjustedLim = [-0.1, 0.1];
111
- }
112
-
113
- // special case when limits are equal (add ±5%)
114
- if (adjustedLim[0] === adjustedLim[1]) {
115
- adjustedLim = [adjustedLim[0] * 0.95, adjustedLim[0] * 1.05];
116
- }
117
-
118
- return adjustedLim;
119
- }
120
-
121
- /** Rescales x-values from plot coordinates to screen (SVG) coordinates
122
- * @param {Array} x - vector with coordinates (or objects size) in original plot coordinates
123
- * @param {Array} xLim - vector with current limits for x-axis in original plot coordinates
124
- * @param {number} width - width of coordinate system in pixels
125
- * @param {boolean} doSizeScreen - scale size of objects (true) or coordinates
126
- * @returns {Array} vector with rescaled values
127
- */
128
- const scaleX = function(x, xLim, width, doSizeScale = false) {
129
- if (!$isOk || x === undefined || !Array.isArray(x)) return undefined;
130
-
131
- if (doSizeScale) {
132
- // scale size of objects instead of coordinates
133
- return x.map(v => v / (xLim[1] - xLim[0]) * (width - margins[1] - margins[3]));
134
- }
135
-
136
- return x.map(v => (v - xLim[0]) / (xLim[1] - xLim[0]) * (width - margins[1] - margins[3]) + margins[1]);
137
- }
138
-
139
- /** Rescales x-values from plot coordinates to screen (SVG) coordinates
140
- * @param {Array} x - vector with coordinates (or objects size) in original plot coordinates
141
- * @param {Array} xLim - vector with current limits for x-axis in original plot coordinates
142
- * @param {number} width - width of coordinate system in pixels
143
- * @param {boolean} doSizeScreen - scale size of objects (true) or coordinates
144
- * @returns {Array} vector with rescaled values
145
- */
146
- const scaleY = function(y, yLim, height, doSizeScale = false) {
147
- if (!$isOk || y === undefined || !Array.isArray(y)) return undefined;
148
-
149
- if (doSizeScale) {
150
- // scale size of objects instead of coordinates
151
- return y.map(v => v / (yLim[1] - yLim[0]) * (height - margins[0] - margins[2]));
152
- }
153
-
154
- // for coordinates we also need to invert (flip) the y-axis
155
- return y.map(v => (yLim[1] - v) / (yLim[1] - yLim[0]) * (height - margins[0] - margins[2]) + margins[2]);
156
- }
157
-
158
- /** Computes nice tick values for axis
159
- * @param {Array} ticks - vector with ticks if alredy available (if not, new will be computed)
160
- * @param {Array} lim - vector with axis limits tickets must be computed for
161
- * @param {number} maxTickNum - maximum number of ticks to compute
162
- * @param {boolean} round - round or not the fractions when computing nice numbers for the ticks
163
- * @returns {Array} a vector with computed tick positions
164
- */
165
- const getAxisTicks = function(ticks, lim, maxTickNum, round = true) {
166
-
167
- // if ticks are already provided do not recompute them
168
- if (ticks !== undefined) return ticks;
169
-
170
- // check if limits are ok
171
- if (!Array.isArray(lim) || lim[0] === undefined || lim[1] === undefined) return undefined;
172
-
173
- // get range as a nice number and compute min, max and steps for the tick sequence
174
- const range = niceNum(lim[1] - lim[0], round);
175
- const tickSpacing = niceNum(range / (maxTickNum - 1), round);
176
- const tickMin = Math.ceil(lim[0] / tickSpacing) * tickSpacing;
177
- const tickMax = Math.floor(lim[1] / tickSpacing) * tickSpacing;
178
-
179
- // recompute maxTickNum
180
- maxTickNum = Math.round((tickMax - tickMin + 1) / tickSpacing) + 1;
181
-
182
- // create a sequence and return
183
- ticks = [...Array(maxTickNum)].map((x, i) => tickMin + i * tickSpacing);
184
-
185
- // if step is smaller than 1 round values to remove small decimals accidentiall added by JS
186
- if (Math.abs(tickSpacing) < 1) {
187
- const r = Math.pow(10, 1 + Math.round(-Math.log10(tickSpacing)));
188
- ticks = ticks.map(v => Math.round((v + Number.EPSILON) * r) / r)
189
- }
190
-
191
- // make sure the ticks are not aligned with axes limits
192
- return ticks.filter(x => x >= lim[0] & x <= lim[1]);
193
- }
194
-
195
- /** Computes a nice spacing value for a given range
196
- * @param {numeric} localRange - a range (max - min)
197
- * @param {boolean} round - round or not the fractions when computing the number
198
- * @returns {numeric} the computed spacing value
199
- */
200
- function niceNum( localRange, round) {
201
-
202
- const exponent = Math.floor(Math.log10(localRange));
203
- const fraction = localRange / Math.pow(10, exponent);
204
- let niceFraction;
205
-
206
- if (round) {
207
- if (fraction < 1.5)
208
- niceFraction = 1;
209
- else if (fraction < 3)
210
- niceFraction = 2;
211
- else if (fraction < 7)
212
- niceFraction = 5;
213
- else
214
- niceFraction = 10;
215
- } else {
216
- if (fraction <= 1)
217
- niceFraction = 1;
218
- else if (fraction <= 2)
219
- niceFraction = 2;
220
- else if (fraction <= 5)
221
- niceFraction = 5;
222
- else
223
- niceFraction = 10;
224
- }
225
-
226
- return niceFraction * Math.pow(10, exponent);
227
- }
228
-
229
- /** Computes a scale level
230
- * @param {numeric} width - width of plotting area in pixels
231
- * @param {numeric} height - height of plotting area in pixels
232
- * @returns {text} the scale level ("small", "medium" or "large")
233
- */
234
- function getScale(width, height) {
235
- if (height < 300.2 || width < 300.2) return "small";
236
- if (height < 600.2 || width < 600.2) return "medium";
237
- return "large";
238
- }
239
-
240
- /* context with Axes constants, properties and methods to share with children */
241
- let context = {
242
-
243
- // methods
244
- addXAxisMargins: addXAxisMargins,
245
- addYAxisMargins: addYAxisMargins,
246
- adjustXAxisLimits: adjustXAxisLimits,
247
- adjustYAxisLimits: adjustYAxisLimits,
248
- getAxisTicks: getAxisTicks,
249
- scaleX: scaleX,
250
- scaleY: scaleY,
251
-
252
- // variables
253
- isOk: isOk,
254
- scale: scale,
255
- width: width,
256
- height: height,
257
- xLim: xLim,
258
- yLim: yLim,
259
-
260
- // constants
261
- LINE_STYLES: LINE_STYLES,
262
- LABELS_MARGIN: LABELS_MARGIN,
263
- TICK_NUM: TICK_NUM,
264
- }
265
-
266
- setContext('axes', context);
267
-
268
- // handle click on plot elements and dispatch manual events
269
- function dispatchClickEvent(eventName, el) {
270
- dispatch(eventName, {seriesTitle: el.parentNode.getAttribute('title'), elementID: el.dataset.id});
271
- }
272
-
273
- function handleClick(e) {
274
-
275
- // scatter plot markers
276
- if (e.target.tagName === "text" && e.target.parentNode.classList.contains("series_scatter")) {
277
- dispatchClickEvent("markerclick", e.target);
278
- return;
279
- }
280
-
281
- // bar plot bars
282
- if (e.target.tagName === "rect" && e.target.parentNode.classList.contains("series_bar")) {
283
- dispatchClickEvent("barclick", e.target);
284
- return;
285
- }
286
-
287
- // outside any plot element
288
- dispatch("axesclick")
289
- }
290
-
291
-
292
- // this is reactive in case if limX and limY are interactively changed by parent script
293
- $: if (!limX.some(v => v === undefined)) xLim.update(v => limX);
294
- $: if (!limY.some(v => v === undefined)) yLim.update(v => limY);
295
-
296
- // computes real margins in pixels based on current scale
297
- $: margins = axesMargins.map(v => v * AXES_MARGIN_FACTORS[$scale]);
298
-
299
- // computes status which tells that axes limits look fine and it is safe to draw
300
- // the status is based on the axis limits validity
301
- $: isOk.update(v =>
302
- Array.isArray($yLim) &&
303
- Array.isArray($xLim) &&
304
- $xLim.length === 2 &&
305
- $yLim.length === 2 &&
306
- !$yLim.some(v => v === undefined) &&
307
- !$xLim.some(v => v === undefined) &&
308
- !$yLim.some(v => isNaN(v)) &&
309
- !$xLim.some(v => isNaN(v)) &&
310
- $xLim[1] !== $xLim[0] &&
311
- $yLim[1] !== $yLim[0] &&
312
- $width > (margins[1] + margins[3]) &&
313
- $height > (margins[0] + margins[2])
314
- )
315
-
316
- // computes coordinates for clip path box
317
- $: cpx = $isOk ? scaleX($xLim, $xLim, $width) : [0, 1];
318
- $: cpy = $isOk ? scaleY($yLim, $yLim, $height) : [1, 0];
319
-
320
- /* observer for the axes area size - to update size of axes */
321
- const ro2 = new ResizeObserver(entries => {
322
- for (let entry of entries) {
323
- const acr = axesElement.getBoundingClientRect();
324
- width.update(x => acr.width);
325
- height.update(x => acr.height);
326
- }
327
- });
328
-
329
- /* observer for the plot area size — to update scale */
330
- const ro1 = new ResizeObserver(entries => {
331
- for (let entry of entries) {
332
- const pcr = plotElement.getBoundingClientRect();
333
- scale.update(x => getScale(pcr.width, pcr.height));
334
- }
335
- });
336
-
337
- onMount(() => {
338
- ro1.observe(plotElement);
339
- ro2.observe(axesElement);
340
- });
341
-
342
- onDestroy(() => {
343
- ro1.unobserve(plotElement);
344
- ro2.unobserve(axesElement);
345
- })
346
- </script>
347
-
348
-
349
- <div class="plot {'plot_' + $scale}" bind:this={plotElement} class:plot_error="{!$isOk}">
350
-
351
- <!-- plot title and axis labels -->
352
- {#if title !== ""}<div class="axes__title">{@html title}</div>{/if}
353
- {#if yLabel !== ""}<div class="axes__ylabel"><span>{@html yLabel}</span></div>{/if}
354
- {#if xLabel !== ""}<div class="axes__xlabel"><span>{@html xLabel}</span></div>{/if}
355
-
356
- <!-- axes (coordinate system) -->
357
- <div class="axes-wrapper" bind:this={axesElement} >
358
- <svg on:click={handleClick} preserveAspectRatio="none" class="axes">
359
-
360
- <!-- define clipping path -->
361
- <defs>
362
- <clipPath id="{clipPathID}">
363
- <rect style="pointer-events:none" x="{cpx[0]}" y="{cpy[1]}" width = "{cpx[1] - cpx[0]}" height="{cpy[0] - cpy[1]}"></rect>
364
- </clipPath>
365
- </defs>
366
-
367
- <!-- axis and box -->
368
- <slot name="xaxis"></slot>
369
- <slot name="yaxis"></slot>
370
-
371
- <!-- main plot content -->
372
- <g class="axes-content" clip-path="url(#{clipPathID})">
373
- <slot></slot>
374
- </g>
375
-
376
- <!-- axis and box -->
377
- <slot name="box"></slot>
378
-
379
- </svg>
380
- </div>
381
-
382
- {#if !$isOk}
383
- <p class="message_error">
384
- Axes component was not properly initialized. <br />
385
- Add plot series (check that coordinates are numeric) or define axes limits manually.
386
- </p>
387
- {/if}
388
-
389
- </div>
390
-
391
- <style>
392
-
393
- /* Plot (main container) */
394
- :global(.plot) {
395
- font-family: Arial, Helvetica, sans-serif;
396
-
397
- display: grid;
398
- grid-template-columns: min-content auto;
399
- grid-template-rows: min-content auto min-content;
400
- grid-template-areas:
401
- ". title"
402
- "ylab axes"
403
- ". xlab";
404
-
405
- box-sizing: border-box;
406
- background: #fefefe;
407
- min-width: 100px;
408
- min-height: 50px;
409
- width: 100%;
410
- height: 100%;
411
- padding: 0;
412
- margin: 0;
413
- }
414
-
415
- :global(.plot_small) {
416
- font-size: 11px;
417
- }
418
-
419
- :global(.plot_medium) {
420
- font-size: 13px;
421
- }
422
-
423
- :global(.plot_large) {
424
- font-size: 16px;
425
- }
426
-
427
- :global(.plot_error) {
428
- display: flex;
429
- }
430
-
431
- :global(.plot_error > .axes-wrapper) {
432
- display: none;
433
- }
434
-
435
- :global(.message_error) {
436
- font-size: 1.2em;
437
- color: crimson;
438
- padding: 20px;
439
- text-align: center;
440
- }
441
-
442
- /* Axes (coordinate system) */
443
- .axes-wrapper {
444
- grid-area: axes;
445
- position:relative;
446
- box-sizing: border-box;
447
- display: flex;
448
- width: 100%;
449
- height: 100%;
450
- padding: 0;
451
- margin: 0;
452
- }
453
-
454
- :global(.axes) {
455
- display: block;
456
- box-sizing: border-box;
457
- position:absolute;
458
-
459
- padding: 0;
460
- margin: 0;
461
- height: 100%;
462
- width: 100%;
463
- max-height: 100%;
464
- max-width: 100%;
465
- min-height: 100%;
466
- min-width: 100%;
467
- }
468
-
469
- :global(.axes-content) {
470
- padding: 0;
471
- margin: 0;
472
- height: 100%;
473
- width: 100%;
474
- max-height: 100%;
475
- max-width: 100%;
476
- min-height: 100%;
477
- min-width: 100%;
478
-
479
- }
480
-
481
- :global(.axes__xlabel) {
482
- grid-area: xlab;
483
- font-size: 1.0em;
484
- font-weight: 600;
485
- padding: 0.25em;
486
- text-align: center;
487
- }
488
-
489
-
490
- :global(.axes__ylabel) {
491
- grid-area: ylab;
492
- font-size: 1.0em;
493
- font-weight: 600;
494
- padding: 0.25em;
495
- text-align: center;
496
- vertical-align: middle;
497
- display: flex;
498
- }
499
-
500
- :global(.axes__ylabel > span) {
501
- width: 1.5em;
502
- line-height: 1.5em;
503
- display: inline-block;
504
- writing-mode: vertical-rl;
505
- transform: rotate(180deg);
506
- }
507
-
508
-
509
- :global(.axes__title) {
510
- background: transparent;
511
- grid-area: title;
512
-
513
- font-size: 1.3em;
514
- font-weight: bold;
515
- line-height: 1.2em;
516
- padding: 0.5em 0;
517
- text-align: center;
518
- }
519
-
520
- /* Axis */
521
- :global(.axis-labels) {
522
- fill: #303030;
523
- font-size: 0.95em;
524
- }
525
-
526
- /* Data labels */
527
- :global(.labels) {
528
- fill: #606060;
529
- font-size: 0.90em;
530
- }
531
-
532
- :global(.labels) {
533
- visibility: hidden;
534
- transition:visibility 0.25s linear, opacity 0.25s linear;
535
- opacity: 0;
536
- }
537
-
538
- </style>
@@ -1,78 +0,0 @@
1
- <script>
2
- import { getContext } from 'svelte';
3
- import { Colors } from './Colors';
4
- import { max, mrange, diff } from 'mdatools/stat';
5
- import Rectangles from './Rectangles.svelte';
6
-
7
- /* input parameters */
8
- export let xValues;
9
- export let yValues;
10
- export let barWidth = 0.8;
11
- export let title = "";
12
- export let faceColor = Colors.PRIMARY;
13
- export let borderColor = Colors.PRIMARY;
14
- export let showLabels = "no"; // can be "no", "hover", "always"
15
-
16
- // TODO: implemented later
17
- //export let labels = yValues;
18
-
19
- /* internal parameters */
20
- let width;
21
- let left;
22
- let top;
23
- let height;
24
-
25
- // to access shared parameters and methods from Axes
26
- const axes = getContext('axes');
27
-
28
- /* reactive actions related to x-values, fires when there are changes in:
29
- * - xValues
30
- * - barWidth
31
- */
32
- $: {
33
-
34
- if (!Array.isArray(xValues)) {
35
- throw("BarSeries: parameter 'xValues' must be a numeric vector.");
36
- }
37
-
38
- if (barWidth <= 0 || barWidth > 1) {
39
- throw("BarSeries: parameters 'barWidth' should be between 0 and 1.");
40
- }
41
-
42
- const xValuesRange = mrange(xValues, 0.1);
43
- xValuesRange[0] = xValuesRange[0] - barWidth * diff(xValuesRange) / xValues.length * 0.5
44
- xValuesRange[1] = xValuesRange[1] + barWidth * diff(xValuesRange) / xValues.length * 0.5
45
- axes.adjustXAxisLimits(xValuesRange);
46
-
47
- width = Array(xValues.length).fill(max(diff(xValues)) * barWidth);
48
- left = xValues.map((v, i) => v - width[i]/2);
49
- }
50
-
51
- /* reactive actions related to y-values, fires when there are changes in:
52
- * - yValues
53
- */
54
- $: {
55
-
56
- if (!Array.isArray(yValues) || xValues.length != yValues.length) {
57
- throw("BarSeries: parameter 'yValues' must be a numeric vector of the same length as 'xValues'.");
58
- }
59
-
60
- const yValuesRange = mrange(yValues, showLabels === "no" ? 0.05 : 0.20);
61
- axes.adjustYAxisLimits(yValuesRange);
62
-
63
- top = yValues.map(v => v > 0 ? v : 0);
64
- height = yValues.map(v => Math.abs(v));
65
- }
66
- </script>
67
-
68
- <Rectangles style="series_bar" {left} {top} {width} {height} {borderColor} {faceColor} {title} />
69
-
70
- <style>
71
- :global(.series_bar > rect){
72
- stroke-width: 1px;
73
- }
74
-
75
- :global(.series_bar > rect:hover){
76
- opacity: 90%;
77
- }
78
- </style>
package/src/Box.svelte DELETED
@@ -1,35 +0,0 @@
1
- <script>
2
- import { getContext } from 'svelte';
3
- import { Colors } from './Colors';
4
- import Rectangles from './Rectangles.svelte';
5
-
6
- /* input parameters */
7
- export let slot;
8
-
9
- // check that the box is located in a correct slot
10
- if (slot !== "box") {
11
- throw("Component Box must have \"slot='box'\" attribute.")
12
- }
13
-
14
- // get axes context and reactive variables needed to compute coordinates
15
- const axes = getContext('axes');
16
- const xLim = axes.xLim;
17
- const yLim = axes.yLim;
18
- const isOk = axes.isOk;
19
-
20
- // reactive variables for coordinates of box points in pixels
21
- $: left = [$xLim[0]];
22
- $: top = [$yLim[1]];
23
- $: width = [$xLim[1] - $xLim[0]];
24
- $: height = [$yLim[1] - $yLim[0]];
25
-
26
- </script>
27
-
28
- {#if $isOk}
29
- <g style="pointer-events:none" class="mdaplot__axes-box">
30
- <Rectangles {left} {top} {width} {height} borderColor="{Colors.DARKGRAY}" faceColor="transparent"></Rectangles>
31
- </g>
32
- {/if}
33
-
34
- <style>
35
- </style>