svelte-plots-basic 1.0.1 → 1.0.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/dist/index.js +332 -243
- package/dist/index.mjs +332 -243
- package/package.json +1 -1
- package/src/Axes.svelte +27 -8
- package/src/BarSeries.svelte +1 -3
- package/src/Box.svelte +1 -1
- package/src/LineSeries.svelte +4 -4
- package/src/Rectangles.svelte +5 -1
- package/src/ScatterSeries.svelte +10 -6
- package/src/TextLabels.svelte +22 -7
- package/src/TextLegend.svelte +1 -1
package/package.json
CHANGED
package/src/Axes.svelte
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
import { onMount, setContext } from 'svelte';
|
|
2
|
+
import { onMount, setContext, createEventDispatcher } from 'svelte';
|
|
3
3
|
import { writable } from 'svelte/store';
|
|
4
4
|
|
|
5
5
|
/* input parameters */
|
|
@@ -10,7 +10,8 @@
|
|
|
10
10
|
export let yLabel = ""; // label for y-axis
|
|
11
11
|
export let multiSeries = true; // is the plot for one series or for many
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
// event dispatcher
|
|
14
|
+
const dispatch = createEventDispatcher();
|
|
14
15
|
|
|
15
16
|
// how big are margins (number of pixels in unit margin value) between axis and plot area if axis are shown
|
|
16
17
|
const AXES_MARGIN_FACTORS = {
|
|
@@ -276,6 +277,22 @@
|
|
|
276
277
|
ro.observe(axesWrapper);
|
|
277
278
|
});
|
|
278
279
|
|
|
280
|
+
// handle click on plot elements and dispatch manual events
|
|
281
|
+
function handleClick(e) {
|
|
282
|
+
|
|
283
|
+
if (e.target.tagName === "text" && e.target.parentNode.classList.contains("series_scatter")) {
|
|
284
|
+
dispatch("markerclick", {markerid: e.target.dataset.id})
|
|
285
|
+
return;
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
if (e.target.tagName === "rect" && e.target.parentNode.classList.contains("series_bar")) {
|
|
289
|
+
dispatch("barclick", {markerid: e.target.dataset.id})
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
dispatch("axesclick")
|
|
294
|
+
}
|
|
295
|
+
|
|
279
296
|
|
|
280
297
|
// this is reactive in case if limX and limY are interactively changed by parent script
|
|
281
298
|
$: if (!limX.some(v => v === undefined)) xLim.update(v => limX);
|
|
@@ -297,8 +314,8 @@
|
|
|
297
314
|
!$xLim.some(v => isNaN(v)) &&
|
|
298
315
|
$xLim[1] !== $xLim[0] &&
|
|
299
316
|
$yLim[1] !== $yLim[0] &&
|
|
300
|
-
|
|
301
|
-
|
|
317
|
+
$width > (margins[1] + margins[3]) &&
|
|
318
|
+
$height > (margins[0] + margins[2])
|
|
302
319
|
)
|
|
303
320
|
|
|
304
321
|
// computes coordinates for clip path box
|
|
@@ -315,13 +332,13 @@
|
|
|
315
332
|
{#if xLabel !== ""}<div class="axes__xlabel"><span>{@html xLabel}</span></div>{/if}
|
|
316
333
|
|
|
317
334
|
<!-- axes (coordinate system) -->
|
|
318
|
-
<div class="axes-wrapper" bind:this=
|
|
319
|
-
<svg preserveAspectRatio="none" class="axes">
|
|
335
|
+
<div class="axes-wrapper" bind:this={axesWrapper} >
|
|
336
|
+
<svg on:click={handleClick} preserveAspectRatio="none" class="axes">
|
|
320
337
|
|
|
321
338
|
<!-- define clipping path -->
|
|
322
339
|
<defs>
|
|
323
340
|
<clipPath id="{clipPathID}">
|
|
324
|
-
<rect x="{cpx[0]}" y="{cpy[1]}" width = "{cpx[1] - cpx[0]}" height="{cpy[0] - cpy[1]}"></rect>
|
|
341
|
+
<rect style="pointer-events:none" x="{cpx[0]}" y="{cpy[1]}" width = "{cpx[1] - cpx[0]}" height="{cpy[0] - cpy[1]}"></rect>
|
|
325
342
|
</clipPath>
|
|
326
343
|
</defs>
|
|
327
344
|
|
|
@@ -401,11 +418,13 @@
|
|
|
401
418
|
}
|
|
402
419
|
|
|
403
420
|
/* Axes (coordinate system) */
|
|
404
|
-
|
|
421
|
+
.axes-wrapper {
|
|
405
422
|
grid-area: axes;
|
|
406
423
|
position:relative;
|
|
407
424
|
box-sizing: border-box;
|
|
408
425
|
display: flex;
|
|
426
|
+
width: 100%;
|
|
427
|
+
height: 100%;
|
|
409
428
|
padding: 0;
|
|
410
429
|
margin: 0;
|
|
411
430
|
}
|
package/src/BarSeries.svelte
CHANGED
|
@@ -65,9 +65,7 @@
|
|
|
65
65
|
}
|
|
66
66
|
</script>
|
|
67
67
|
|
|
68
|
-
<
|
|
69
|
-
<Rectangles {left} {top} {width} {height} {borderColor} {faceColor} />
|
|
70
|
-
</g>
|
|
68
|
+
<Rectangles style="series_bar" {left} {top} {width} {height} {borderColor} {faceColor} {title} />
|
|
71
69
|
|
|
72
70
|
<style>
|
|
73
71
|
:global(.series_bar > rect){
|
package/src/Box.svelte
CHANGED
package/src/LineSeries.svelte
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
<script>
|
|
2
|
-
|
|
3
2
|
import { getContext } from 'svelte';
|
|
4
3
|
import { mrange } from 'mdatools/stat';
|
|
5
4
|
import { Colors } from './Colors';
|
|
@@ -37,12 +36,13 @@
|
|
|
37
36
|
$: x = axes.scaleX(xValues, $xLim, $axesWidth);
|
|
38
37
|
$: y = axes.scaleY(yValues, $yLim, $axesHeight);
|
|
39
38
|
$: p = x !== undefined && y !== undefined ? x.map((v, i) => `${v},${y[i]}`).join(' ') : undefined;
|
|
40
|
-
$: lineStyleStr = `fill:transparent;stroke:${lineColor};stroke-width: ${lineWidth}px;
|
|
39
|
+
$: lineStyleStr = `fill:transparent;stroke:${lineColor};stroke-width: ${lineWidth}px;
|
|
40
|
+
stroke-dasharray:${axes.LINE_STYLES[$scale][lineType - 1]}`;
|
|
41
41
|
</script>
|
|
42
42
|
|
|
43
43
|
{#if p !== undefined}
|
|
44
|
-
<g class="series
|
|
45
|
-
|
|
44
|
+
<g class="series series_line" style={lineStyleStr} title={title}>
|
|
45
|
+
<polyline class="line" points={p}/>
|
|
46
46
|
</g>
|
|
47
47
|
{/if}
|
|
48
48
|
|
package/src/Rectangles.svelte
CHANGED
|
@@ -11,6 +11,8 @@
|
|
|
11
11
|
export let faceColor = Colors.PRIMARY;
|
|
12
12
|
export let borderColor = faceColor;
|
|
13
13
|
export let lineWidth = 1;
|
|
14
|
+
export let title = "";
|
|
15
|
+
export let style = "series_rect";
|
|
14
16
|
|
|
15
17
|
// styles for bars and labels
|
|
16
18
|
const barsStyleStr = `fill:${faceColor};stroke:${borderColor};stroke-width: ${lineWidth}px;`;
|
|
@@ -49,9 +51,11 @@
|
|
|
49
51
|
</script>
|
|
50
52
|
|
|
51
53
|
{#if rx !== undefined && ry !== undefined}
|
|
54
|
+
<g class="series {style}" title={title} style={barsStyleStr}>
|
|
52
55
|
{#each left as v, i}
|
|
53
|
-
<rect x=
|
|
56
|
+
<rect x={rx[i]} y={ry[i]} width={rw[i]} height={rh[i]} />
|
|
54
57
|
{/each}
|
|
58
|
+
</g>
|
|
55
59
|
{/if}
|
|
56
60
|
|
|
57
61
|
<style>
|
package/src/ScatterSeries.svelte
CHANGED
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
//export let labels = yValues;
|
|
20
20
|
//export let showLabels = "no"; // can be "no", "hover", "always"
|
|
21
21
|
|
|
22
|
+
/* constants for internal use */
|
|
22
23
|
const markers = ["●", "◼", "▲", "▼", "⬥", "+", "*", "⨯"];
|
|
23
24
|
let markerSymbol;
|
|
24
25
|
|
|
@@ -57,20 +58,23 @@
|
|
|
57
58
|
const yValuesRange = mrange(yValues, 0.05);
|
|
58
59
|
axes.adjustYAxisLimits(yValuesRange);
|
|
59
60
|
}
|
|
60
|
-
|
|
61
61
|
</script>
|
|
62
62
|
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
63
|
+
<TextLabels
|
|
64
|
+
{xValues} {yValues} {faceColor} {borderColor} {borderWidth} {title}
|
|
65
|
+
style="series_scatter"
|
|
66
|
+
labels={markerSymbol}
|
|
67
|
+
textSize={markerSize}
|
|
68
|
+
/>
|
|
66
69
|
|
|
67
70
|
<style>
|
|
68
|
-
|
|
71
|
+
|
|
72
|
+
:global(.series_scatter > text) {
|
|
69
73
|
font-size: 1em;
|
|
70
74
|
cursor: default;
|
|
71
75
|
}
|
|
72
76
|
|
|
73
|
-
:global(.
|
|
77
|
+
:global(.series_scatter > text:hover) {
|
|
74
78
|
opacity: 90%;
|
|
75
79
|
}
|
|
76
80
|
|
package/src/TextLabels.svelte
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
<script>
|
|
2
|
+
/****************************************************
|
|
3
|
+
* TextLabels component *
|
|
4
|
+
* -------------------- *
|
|
5
|
+
* shows a series of text labels on the plot *
|
|
6
|
+
* can be used as basis for marker plot *
|
|
7
|
+
*****************************************************/
|
|
8
|
+
|
|
2
9
|
import { getContext } from 'svelte';
|
|
3
10
|
import { Colors } from './Colors';
|
|
4
11
|
|
|
5
|
-
|
|
12
|
+
// input parameters
|
|
6
13
|
export let xValues;
|
|
7
14
|
export let yValues;
|
|
8
15
|
export let labels;
|
|
@@ -11,16 +18,18 @@
|
|
|
11
18
|
export let borderColor = "transparent";
|
|
12
19
|
export let borderWidth = 0;
|
|
13
20
|
export let textSize = 1;
|
|
21
|
+
export let style = "";
|
|
22
|
+
export let title = "series_text";
|
|
14
23
|
|
|
15
24
|
// text-anchor values depending on position
|
|
16
25
|
const textAnchors = ["middle", "middle", "start", "middle", "end"];
|
|
17
26
|
|
|
18
|
-
|
|
27
|
+
// sanity check for input parameters
|
|
19
28
|
if (!Array.isArray(xValues) || !Array.isArray(yValues) || xValues.length !== yValues.length) {
|
|
20
29
|
throw("TextLabels: parameters 'xValues' and 'yValues' must be vectors of the same length.")
|
|
21
30
|
}
|
|
22
31
|
|
|
23
|
-
// multiply
|
|
32
|
+
// multiply label values if needed
|
|
24
33
|
$: {
|
|
25
34
|
const n = xValues.length;
|
|
26
35
|
if (!Array.isArray(labels)) labels = Array(n).fill(labels);
|
|
@@ -49,15 +58,21 @@
|
|
|
49
58
|
$: dx = [0, 0, 1, 0, -1][pos] * axes.LABELS_MARGIN[$scale];
|
|
50
59
|
$: dy = [0, 1, 0, -1, 0][pos] * axes.LABELS_MARGIN[$scale];
|
|
51
60
|
|
|
52
|
-
// styles for
|
|
53
|
-
$: textStyleStr = `fill:${faceColor};stroke-width:${borderWidth}px;stroke:${borderColor};
|
|
61
|
+
// styles for the elements
|
|
62
|
+
$: textStyleStr = `fill:${faceColor};stroke-width:${borderWidth}px;stroke:${borderColor};
|
|
63
|
+
font-size:${textSize}em; text-anchor:${textAnchors[pos]};`;
|
|
54
64
|
</script>
|
|
55
65
|
|
|
56
66
|
{#if x !== undefined && y !== undefined}
|
|
67
|
+
<g class="series {style}" title={title} style={textStyleStr} >
|
|
57
68
|
{#each x as v, i}
|
|
58
|
-
<text
|
|
69
|
+
<text data-id={i} x={x[i]} y={y[i]} dx={dx} dy={dy}>{@html labels[i]}</text>
|
|
59
70
|
{/each}
|
|
71
|
+
</g>
|
|
60
72
|
{/if}
|
|
61
73
|
|
|
62
74
|
<style>
|
|
63
|
-
|
|
75
|
+
text {
|
|
76
|
+
dominant-baseline: middle;
|
|
77
|
+
}
|
|
78
|
+
</style>
|
package/src/TextLegend.svelte
CHANGED
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
{#if x !== undefined && y !== undefined && elements.length > 0}
|
|
33
33
|
<text style={textStyleStr} x={x} y={y} dx={dx} dy={dy} dominant-baseline="middle" text-anchor="start">
|
|
34
34
|
{#each elements as el, i}
|
|
35
|
-
<tspan
|
|
35
|
+
<tspan {x} {dx} dy={i === 0 ? 0 : dy}>{@html el}</tspan>
|
|
36
36
|
{/each}
|
|
37
37
|
</text>
|
|
38
38
|
{/if}
|