svelte-plots-basic 3.4.0 → 4.1.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/NEWS.md +76 -0
- package/README.md +39 -49
- package/package.json +13 -12
- package/src/2d/Area.svelte +8 -7
- package/src/2d/Axes.svelte +10 -8
- package/src/2d/AxisLines.svelte +4 -6
- package/src/2d/AxisTickLabels.svelte +1 -3
- package/src/2d/Bars.svelte +30 -9
- package/src/2d/Heatmap.svelte +15 -6
- package/src/2d/Legend.svelte +74 -30
- package/src/2d/Lines.svelte +6 -5
- package/src/2d/Multilines.svelte +9 -8
- package/src/2d/Points.svelte +9 -9
- package/src/2d/Rectangles.svelte +47 -18
- package/src/2d/Segments.svelte +3 -3
- package/src/2d/TextLabels.svelte +12 -10
- package/src/2d/TextLegend.svelte +49 -11
- package/src/2d/YAxis.svelte +1 -1
- package/src/3d/Axes.svelte +5 -7
- package/src/3d/AxisLines.svelte +3 -4
- package/src/3d/AxisTickLabels.svelte +2 -2
- package/src/3d/Lines.svelte +8 -8
- package/src/3d/Mesh.svelte +15 -13
- package/src/3d/Points.svelte +8 -9
- package/src/3d/Segments.svelte +11 -13
- package/src/3d/TextLabels.svelte +27 -14
- package/src/3d/XAxis.svelte +2 -4
- package/src/3d/YAxis.svelte +4 -6
- package/src/3d/ZAxis.svelte +4 -6
- package/src/ExportDialog.svelte +236 -66
- package/src/methods.js +241 -127
package/NEWS.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Release notes
|
|
2
|
+
|
|
3
|
+
This file contains the full release history of `svelte-plots-basic`. The [README](README.md) shows only the most recent releases.
|
|
4
|
+
|
|
5
|
+
## 4.1.0
|
|
6
|
+
|
|
7
|
+
* Added a `svelte` export condition to every entry point, so bundlers recognize the package as a Svelte library. This matters when `prebundleSvelteLibraries` is disabled, where the components must be excluded from dependency pre-bundling.
|
|
8
|
+
* Added `./package.json` to the exported paths, so tools that read the package manifest can resolve it.
|
|
9
|
+
|
|
10
|
+
## 4.0.0
|
|
11
|
+
|
|
12
|
+
* Added horizontal legend layout and improved legend sizing and alignment.
|
|
13
|
+
* Improved PNG/SVG export reliability, export-dialog accessibility, and clipboard handling.
|
|
14
|
+
* Strengthened validation, automatic axis ticks, marker rendering, and component cleanup.
|
|
15
|
+
* Made subscripts, superscripts, and tick-factor labels consistent across modern browsers.
|
|
16
|
+
* Updated to `mdatools ^1.5.0`, now declared as a peer dependency to prevent incompatible duplicate instances.
|
|
17
|
+
|
|
18
|
+
## 3.4.0
|
|
19
|
+
|
|
20
|
+
* Added the `plotActions` property to `Axes` for adding custom buttons to the download panel.
|
|
21
|
+
* Added advanced validation for axis limits, text-label positions, heatmap breaks, and custom plot actions.
|
|
22
|
+
* Fixed text-label positioning and rotation when individual positions are provided.
|
|
23
|
+
* Fixed heatmaps with automatic, custom, or constant-value breaks.
|
|
24
|
+
* Added support for rectangular and constant-height 3D meshes.
|
|
25
|
+
* Improved PNG, SVG, and clipboard export by serializing a clone instead of modifying the visible plot.
|
|
26
|
+
* Fixed the advanced PNG export dialog so a default resolution is always selected, falling back to 300 dpi when necessary.
|
|
27
|
+
* Prevented plot controls from submitting an enclosing HTML form.
|
|
28
|
+
* Added package validation before publishing and synchronized Svelte 5 peer-dependency metadata.
|
|
29
|
+
* Fixed conditionally rendered axes, boxes, and legends so their parent state is cleared when they are removed.
|
|
30
|
+
* Improved heatmap interval processing and added automatically generated colormaps with more than 16 colors.
|
|
31
|
+
* Fixed `TextLegend` positioning at zero and strengthened finite-range validation for 3D axes.
|
|
32
|
+
* Reduced reactive and repeated allocation overhead for axis configuration, text measurement, PNG export, and colormap generation.
|
|
33
|
+
* Added dependency-free regression tests and made them run automatically before packaging.
|
|
34
|
+
* Documented the trust requirements for labels rendered as SVG/HTML markup.
|
|
35
|
+
|
|
36
|
+
## 3.3.0
|
|
37
|
+
|
|
38
|
+
* Added advanced "save as PNG" option where user can select size and resolution of the image as well as change the filename.
|
|
39
|
+
* several small improvements and bug fixes.
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
## 3.2.1
|
|
43
|
+
|
|
44
|
+
* Added mouse click handler option for `Heatmap.svelte` component (returns row and column index of the element).
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
## 3.1.1-3.1.6
|
|
48
|
+
|
|
49
|
+
* Fixed bug which sometimes caused an error when manual text tick labels provided.
|
|
50
|
+
* Added `markerSize` specification to legend items.
|
|
51
|
+
* Small improvements and bug fixes.
|
|
52
|
+
|
|
53
|
+
## 3.1.0
|
|
54
|
+
|
|
55
|
+
* Added possibility to reverse the axis, just swap the limit values.
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
## 3.0.0
|
|
59
|
+
|
|
60
|
+
New major release (v. 3.0.0, released 20/01/2025) introduces many breaking changes as the library has been re-written using Svelte 5. If you use previous versions of `svelte-plots-basic` in your projects, and do not want to change anything, stick to the latest 2.x.x version.
|
|
61
|
+
|
|
62
|
+
In addition to Svelte 5 syntax and functionality, this release also introduces a lot of improvements, such as better handling of axis ticks, new syntax for axis elements, etc. See examples below for inspiration. Here is a short list what has been changed from 2.x.x:
|
|
63
|
+
|
|
64
|
+
* **No more slots** — components `<Box>`, `<XAxis>`, `<YAxis>`, and `<ZAxis>` (for 3D) do not require attribute `slot` anymore. Moreover, you have to remove this attribute from all your old code in order to use the new version.
|
|
65
|
+
|
|
66
|
+
* **Axis labels** — in version 2.x.x. labels for x- and y-axis were a part of `<Axes>` component. From 3.x.x. they are part of corresponding axis components, for example:<br> `<XAxis label="x-axis label"/>`.
|
|
67
|
+
|
|
68
|
+
* **Support for subscripts and superscripts** — you can now use simple syntax for subscripts (`_`) and superscripts (`^`) in axis labels, tick labels, legend labels and plot title. For example, such labels as `'x^2'`, `x^-1` or `x_(34)` — will be correctly transformed to corresponding SVG text elements in order to visualize them correctly. You can also use HTML symbols, such as `α`.
|
|
69
|
+
|
|
70
|
+
* **Mouse events** — previosly, handling mouse events was done through a coplex system of manual events dispatched by `<Axes>` component. From 3.x.x this is much easier, almost every 2D series component (`<Rectangles>`, `<Bars>`, `<Points>`, `<Segments>`, `<Lines>`, `<Areas>`) can handle its own `onclick` event. You just need to provide a callback — a function that will be run if this event is fired. The callback should have one argument — id (position) of an element the click was made on. For example `<Points ... onclick={(id) => console.log(id)}>`. Because of this modification, the property `title` has been removed from all components. 2D component `<Axes>` also supports `onclick` event, it provides coordinates of the clicked point as arguments for the callback function. 3D plots do not support mouse events.
|
|
71
|
+
|
|
72
|
+
* **Save and copy 3D plots** — from 3.x.x you can also save and copy to clipboard 3D plots (same way as for 2D).
|
|
73
|
+
|
|
74
|
+
* **Doc strings** — every component has a corresponding doc string with description of its properties and a simple code example. It should be available when you move your mouse over the component tag in your editor/IDE if it supports this option (works in VSCode).
|
|
75
|
+
|
|
76
|
+
* **Properites** — from 3.x.x the naming of the properties is more consistent. For example, before the library used properties `borderColor` and `borderWidth` for areas, rectangels, bars and markers, while for lines, segments and multilines the similar properties were named as `lineColor` and `lineWidth`. Now they all have prefix `line*` if it is something about lines or segments and `face*` if it is somthing inside a closed contour. So no more `border*` properties.
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
`svelte-plots-basic` is a [Svelte](https://svelte.dev) component library for making simple responsive 2D and 3D plots/charts. The plots are created by generating [SVG](https://en.wikipedia.org/wiki/Scalable_Vector_Graphics) inside HTML document.
|
|
4
4
|
|
|
5
|
-
One can think of this library as "Lego" bricks for plots. It has two groups of components: for 2D and for 3D plots. The 2D components are more developed while 3D components remain quite basic. In addition to `svelte`, the package
|
|
5
|
+
One can think of this library as "Lego" bricks for plots. It has two groups of components: for 2D and for 3D plots. The 2D components are more developed while 3D components remain quite basic. In addition to `svelte`, the package requires the [mdatools-js](https://github.com/svkucheryavski/mdatools-js) library as a peer dependency. It is used for vector/matrix operations, statistics, and other manipulations with data values.
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
## Showcase
|
|
@@ -15,6 +15,19 @@ These websites and web-applications use `svelte-plots-basic` library:
|
|
|
15
15
|
|
|
16
16
|
## News
|
|
17
17
|
|
|
18
|
+
### 4.1.0
|
|
19
|
+
|
|
20
|
+
* Added a `svelte` export condition to every entry point, so bundlers recognize the package as a Svelte library. This matters when `prebundleSvelteLibraries` is disabled, where the components must be excluded from dependency pre-bundling.
|
|
21
|
+
* Added `./package.json` to the exported paths, so tools that read the package manifest can resolve it.
|
|
22
|
+
|
|
23
|
+
### 4.0.0
|
|
24
|
+
|
|
25
|
+
* Added horizontal legend layout and improved legend sizing and alignment.
|
|
26
|
+
* Improved PNG/SVG export reliability, export-dialog accessibility, and clipboard handling.
|
|
27
|
+
* Strengthened validation, automatic axis ticks, marker rendering, and component cleanup.
|
|
28
|
+
* Made subscripts, superscripts, and tick-factor labels consistent across modern browsers.
|
|
29
|
+
* Updated to `mdatools ^1.5.0`, now declared as a peer dependency to prevent incompatible duplicate instances.
|
|
30
|
+
|
|
18
31
|
### 3.4.0
|
|
19
32
|
|
|
20
33
|
* Added the `plotActions` property to `Axes` for adding custom buttons to the download panel.
|
|
@@ -39,41 +52,7 @@ These websites and web-applications use `svelte-plots-basic` library:
|
|
|
39
52
|
* several small improvements and bug fixes.
|
|
40
53
|
|
|
41
54
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
* Added mouse click handler option for `Heatmap.svelte` component (returns row and column index of the element).
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
### 3.1.1-3.1.6
|
|
48
|
-
|
|
49
|
-
* Fixed bug which sometimes caused an error when manual text tick labels provided.
|
|
50
|
-
* Added `markerSize` specification to legend items.
|
|
51
|
-
* Small improvements and bug fixes.
|
|
52
|
-
|
|
53
|
-
### 3.1.0
|
|
54
|
-
|
|
55
|
-
* Added possibility to reverse the axis, just swap the limit values.
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
### 3.0.0
|
|
59
|
-
|
|
60
|
-
New major release (v. 3.0.0, released 20/01/2025) introduces many breaking changes as the library has been re-written using Svelte 5. If you use previous versions of `svelte-plots-basic` in your projects, and do not want to change anything, stick to the latest 2.x.x version.
|
|
61
|
-
|
|
62
|
-
In addition to Svelte 5 syntax and functionality, this release also introduces a lot of improvements, such as better handling of axis ticks, new syntax for axis elements, etc. See examples below for inspiration. Here is a short list what has been changed from 2.x.x:
|
|
63
|
-
|
|
64
|
-
* **No more slots** — components `<Box>`, `<XAxis>`, `<YAxis>`, and `<ZAxis>` (for 3D) do not require attribute `slot` anymore. Moreover, you have to remove this attribute from all your old code in order to use the new version.
|
|
65
|
-
|
|
66
|
-
* **Axis labels** — in version 2.x.x. labels for x- and y-axis were a part of `<Axes>` component. From 3.x.x. they are part of corresponding axis components, for example:<br> `<XAxis label="x-axis label"/>`.
|
|
67
|
-
|
|
68
|
-
* **Support for subscripts and superscripts** — you can now use simple syntax for subscripts (`_`) and superscripts (`^`) in axis labels, tick labels, legend labels and plot title. For example, such labels as `'x^2'`, `x^-1` or `x_(34)` — will be correctly transformed to corresponding SVG text elements in order to visualize them correctly. You can also use HTML symbols, such as `α`.
|
|
69
|
-
|
|
70
|
-
* **Mouse events** — previosly, handling mouse events was done through a coplex system of manual events dispatched by `<Axes>` component. From 3.x.x this is much easier, almost every 2D series component (`<Rectangles>`, `<Bars>`, `<Points>`, `<Segments>`, `<Lines>`, `<Areas>`) can handle its own `onclick` event. You just need to provide a callback — a function that will be run if this event is fired. The callback should have one argument — id (position) of an element the click was made on. For example `<Points ... onclick={(id) => console.log(id)}>`. Because of this modification, the property `title` has been removed from all components. 2D component `<Axes>` also supports `onclick` event, it provides coordinates of the clicked point as arguments for the callback function. 3D plots do not support mouse events.
|
|
71
|
-
|
|
72
|
-
* **Save and copy 3D plots** — from 3.x.x you can also save and copy to clipboard 3D plots (same way as for 2D).
|
|
73
|
-
|
|
74
|
-
* **Doc strings** — every component has a corresponding doc string with description of its properties and a simple code example. It should be available when you move your mouse over the component tag in your editor/IDE if it supports this option (works in VSCode).
|
|
75
|
-
|
|
76
|
-
* **Properites** — from 3.x.x the naming of the properties is more consistent. For example, before the library used properties `borderColor` and `borderWidth` for areas, rectangels, bars and markers, while for lines, segments and multilines the similar properties were named as `lineColor` and `lineWidth`. Now they all have prefix `line*` if it is something about lines or segments and `face*` if it is somthing inside a closed contour. So no more `border*` properties.
|
|
55
|
+
Notes for earlier releases, including the list of breaking changes introduced in 3.0.0 when the library was re-written using Svelte 5, are available in the [full release notes](https://github.com/svkucheryavski/svelte-plots-basic/blob/main/NEWS.md).
|
|
77
56
|
|
|
78
57
|
|
|
79
58
|
## Security and label markup
|
|
@@ -96,6 +75,8 @@ or, to install it with yarn:
|
|
|
96
75
|
yarn add svelte-plots-basic
|
|
97
76
|
```
|
|
98
77
|
|
|
78
|
+
The components are always imported from the `svelte-plots-basic/2d` and `svelte-plots-basic/3d` subpaths, and the helper functions from `svelte-plots-basic/utils` and `svelte-plots-basic/constants`. There is no root import — the 2D and 3D groups deliberately share component names, such as `Axes` and `Points`, so importing from `svelte-plots-basic` directly is not supported and will fail to resolve.
|
|
79
|
+
|
|
99
80
|
|
|
100
81
|
## User tutorial (2D plots)
|
|
101
82
|
|
|
@@ -220,7 +201,7 @@ You can also define tick positions and corresponding labels manually. Tick posit
|
|
|
220
201
|
|
|
221
202
|
```svelte
|
|
222
203
|
<Axes limX={[2019, 2026]} limY={[0, 60000]}>
|
|
223
|
-
<
|
|
204
|
+
<XAxis ticks={[2023, 2024, 2025]} tickLabels={['Past', 'Present', 'Future']} />
|
|
224
205
|
</Axes>
|
|
225
206
|
```
|
|
226
207
|
|
|
@@ -620,7 +601,7 @@ Here is an example:
|
|
|
620
601
|
|
|
621
602
|
```svelte
|
|
622
603
|
<script>
|
|
623
|
-
import { Axes,
|
|
604
|
+
import { Axes, XAxis, YAxis, Box, Area } from 'svelte-plots-basic/2d';
|
|
624
605
|
|
|
625
606
|
const xValues = [3, 2, 2.5, 4, 5.5, 6, 5];
|
|
626
607
|
const yValues = [1, 3, 4, 5, 4, 3, 1];
|
|
@@ -677,7 +658,7 @@ Here is an example:
|
|
|
677
658
|
|
|
678
659
|
```svelte
|
|
679
660
|
<script>
|
|
680
|
-
import { Axes,
|
|
661
|
+
import { Axes, XAxis, YAxis, Box, Heatmap } from 'svelte-plots-basic/2d';
|
|
681
662
|
import { Matrix } from 'mdatools/arrays';
|
|
682
663
|
|
|
683
664
|
// create 5 x 10 matrix filled with normally distributed random values
|
|
@@ -729,7 +710,7 @@ Colormap legend can be used together with `<Heatmap>` or any other color groupin
|
|
|
729
710
|
|
|
730
711
|
```svelte
|
|
731
712
|
<script>
|
|
732
|
-
import { Axes,
|
|
713
|
+
import { Axes, XAxis, YAxis, Box, Heatmap, ColormapLegend } from 'svelte-plots-basic/2d';
|
|
733
714
|
import { Matrix } from 'mdatools/arrays';
|
|
734
715
|
|
|
735
716
|
// create 5 x 10 matrix filled with normally distributed random values
|
|
@@ -789,16 +770,16 @@ Here is an example:
|
|
|
789
770
|
const y3 = x.apply(v => Math.pow(v, 4));
|
|
790
771
|
|
|
791
772
|
// define properties of each series
|
|
792
|
-
line1Props = {lineType: 3, lineColor: 'red'};
|
|
793
|
-
line2Props = {lineColor: 'blue', lineType: 1};
|
|
794
|
-
point2Props = {lineColor: 'blue', faceColor: 'white'};
|
|
795
|
-
point3Props = {marker: 5, lineColor: 'green', faceColor: 'yellow'};
|
|
773
|
+
const line1Props = {lineType: 3, lineColor: 'red'};
|
|
774
|
+
const line2Props = {lineColor: 'blue', lineType: 1};
|
|
775
|
+
const point2Props = {lineColor: 'blue', faceColor: 'white'};
|
|
776
|
+
const point3Props = {marker: 5, lineColor: 'green', faceColor: 'yellow'};
|
|
796
777
|
|
|
797
778
|
// legend items
|
|
798
|
-
items = [
|
|
799
|
-
{label: 'y=x^2', line:
|
|
800
|
-
{label: "y=x^3", line:
|
|
801
|
-
{label: "y=x^4", point:
|
|
779
|
+
const items = [
|
|
780
|
+
{label: 'y=x^2', line: line1Props },
|
|
781
|
+
{label: "y=x^3", line: line2Props, point: point2Props },
|
|
782
|
+
{label: "y=x^4", point: point3Props },
|
|
802
783
|
];
|
|
803
784
|
</script>
|
|
804
785
|
|
|
@@ -812,7 +793,7 @@ Here is an example:
|
|
|
812
793
|
<Points xValues={x} yValues={y2} {...point2Props} />
|
|
813
794
|
|
|
814
795
|
<!-- series 3: markers in form of diamonds with green stroke and yellow fill -->
|
|
815
|
-
<Points xValues={x} yValues={y3} {...
|
|
796
|
+
<Points xValues={x} yValues={y3} {...point3Props} />
|
|
816
797
|
|
|
817
798
|
<!-- legend with one JSON for each series -->
|
|
818
799
|
<Legend position="right" {items} />
|
|
@@ -826,12 +807,21 @@ Check this example in Svelte REPL: [plots-legend](https://svelte.dev/playground/
|
|
|
826
807
|
|
|
827
808
|
The `position` parameter can be one of the follows: `'topleft'`, `'top'`, `'topright'`, `'right'`, `'bottomright'` and so on.
|
|
828
809
|
|
|
810
|
+
By default, legend items are arranged vertically. Set `orientation="horizontal"` to arrange them in a single row, which is especially useful with the `top` and `bottom` positions:
|
|
811
|
+
|
|
812
|
+
```svelte
|
|
813
|
+
<Legend position="top" orientation="horizontal" {items} />
|
|
814
|
+
```
|
|
815
|
+
|
|
816
|
+
The horizontal layout does not wrap items onto additional rows, so a large number of items or long labels may require more plot width.
|
|
817
|
+
|
|
829
818
|
The component has also properties which changes it apearance, here is the full list:
|
|
830
819
|
|
|
831
820
|
Property name | Default value | Description
|
|
832
821
|
--|--|--
|
|
833
822
|
`items` | | array with JSON properties of legend items
|
|
834
823
|
`position` | `'topleft'` | position of the legend element inside plotting area
|
|
824
|
+
`orientation` | `'vertical'` | arrangement of legend items: `'vertical'` or `'horizontal'`
|
|
835
825
|
`lineColor` | `'#303030'` | color of the legend box line
|
|
836
826
|
`lineWidth` | `1` | width (thickness) of the legend box line
|
|
837
827
|
`faceColor` | `'#fff'` | background color of the legend box
|
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": "
|
|
4
|
+
"version": "4.1.0",
|
|
5
5
|
"author": "Sergey Kucheryavskiy",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"private": false,
|
|
@@ -12,22 +12,22 @@
|
|
|
12
12
|
"prepack": "npm run check && npm test"
|
|
13
13
|
},
|
|
14
14
|
"exports": {
|
|
15
|
-
"./constants":
|
|
16
|
-
"./utils":
|
|
17
|
-
"./2d":
|
|
18
|
-
"./2d/*.svelte": "./src/2d/*.svelte",
|
|
19
|
-
"./3d":
|
|
20
|
-
"./3d/*.svelte": "./src/3d/*.svelte"
|
|
15
|
+
"./constants": { "svelte": "./src/constants.js", "default": "./src/constants.js" },
|
|
16
|
+
"./utils": { "svelte": "./src/methods.js", "default": "./src/methods.js" },
|
|
17
|
+
"./2d": { "svelte": "./src/2d/index.js", "default": "./src/2d/index.js" },
|
|
18
|
+
"./2d/*.svelte": { "svelte": "./src/2d/*.svelte", "default": "./src/2d/*.svelte" },
|
|
19
|
+
"./3d": { "svelte": "./src/3d/index.js", "default": "./src/3d/index.js" },
|
|
20
|
+
"./3d/*.svelte": { "svelte": "./src/3d/*.svelte", "default": "./src/3d/*.svelte" },
|
|
21
|
+
"./package.json": "./package.json"
|
|
21
22
|
},
|
|
22
23
|
"devDependencies": {
|
|
23
|
-
"
|
|
24
|
+
"mdatools": "^1.5.0",
|
|
25
|
+
"svelte": "^5.56.8"
|
|
24
26
|
},
|
|
25
27
|
"peerDependencies": {
|
|
28
|
+
"mdatools": "^1.5.0",
|
|
26
29
|
"svelte": "^5.0.0"
|
|
27
30
|
},
|
|
28
|
-
"dependencies": {
|
|
29
|
-
"mdatools": "^1.x.x"
|
|
30
|
-
},
|
|
31
31
|
"keywords": [
|
|
32
32
|
"svelte",
|
|
33
33
|
"plots",
|
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
"svelte plots"
|
|
36
36
|
],
|
|
37
37
|
"files": [
|
|
38
|
-
"src"
|
|
38
|
+
"src",
|
|
39
|
+
"NEWS.md"
|
|
39
40
|
],
|
|
40
41
|
"repository": {
|
|
41
42
|
"type": "git",
|
package/src/2d/Area.svelte
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
@component Adds a closed polygon (area).
|
|
3
3
|
|
|
4
4
|
Main properties:
|
|
5
|
-
- `xValues` - array
|
|
6
|
-
- `yValues` - array
|
|
7
|
-
- `lineWidth` - width (thickness) of the polygon's line in pixels,
|
|
5
|
+
- `xValues` - array or vector with x-coordinates of the polygon's points.
|
|
6
|
+
- `yValues` - array or vector with y-coordinates of the polygon's points.
|
|
7
|
+
- `lineWidth` - width (thickness) of the polygon's line in pixels, default: `1`.
|
|
8
8
|
- `lineColor` - line color, default: `Colors.PRIMARY`.
|
|
9
9
|
- `lineType` - type of line (`1` - solid, `2` - dashed, `3` - dotted, `4` - dashdot).
|
|
10
|
-
- `
|
|
10
|
+
- `faceColor` - face (fill) color of the polygon, default: `'transparent'`.
|
|
11
11
|
- `opacity` - opacity of the face color, default: `1`.
|
|
12
12
|
- `onclick` - function (callback) to be called when user clicks on a polygon.
|
|
13
13
|
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
<script>
|
|
30
30
|
import { getContext } from 'svelte';
|
|
31
31
|
import { Colors } from '../constants';
|
|
32
|
-
import { val2p, checkCoords, handleClick, transformCoords } from '../methods';
|
|
32
|
+
import { val2p, checkCoords, handleClick, transformCoords, normalizeLineType } from '../methods';
|
|
33
33
|
import { LINE_STYLES } from '../constants';
|
|
34
34
|
|
|
35
35
|
let {
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
lineColor = Colors.PRIMARY, // color of segment lines
|
|
39
39
|
lineType = 1, // type of segment lines (1 - solid, 2 - dashed, 3 - dotted, 4 - dashdot)
|
|
40
40
|
lineWidth = 1, // width (thickness) of segment lines
|
|
41
|
-
faceColor = 'transparent', // color of
|
|
41
|
+
faceColor = 'transparent', // face (fill) color of the polygon
|
|
42
42
|
opacity = 1, // opacity of the area color
|
|
43
43
|
onclick, // function to be called if onclick event fires
|
|
44
44
|
} = $props();
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
// check user provided coordinates
|
|
47
47
|
const xv = $derived(checkCoords(xValues, 'Area'));
|
|
48
48
|
const yv = $derived(xv ? checkCoords(yValues, 'Area', xv.length) : null);
|
|
49
|
+
const validLineType = $derived(normalizeLineType(lineType, 'Area'));
|
|
49
50
|
|
|
50
51
|
// get axes context and compute coordinates of polyline
|
|
51
52
|
const axes = getContext('axes');
|
|
@@ -55,7 +56,7 @@
|
|
|
55
56
|
const xs = $derived(xv ? transformCoords(xv.subset(1), axes.tX()) : null);
|
|
56
57
|
const pa = $derived(p && xs && ys ? xs + ',' + ys + ' ' + p + ' ' + xs + ',' + ys : null);
|
|
57
58
|
|
|
58
|
-
const areaStyleStr = $derived(`opacity:${opacity};fill:${faceColor};stroke:${lineColor};stroke-width: ${lineWidth}px;stroke-dasharray:${LINE_STYLES[axes.scales().plot][
|
|
59
|
+
const areaStyleStr = $derived(`opacity:${opacity};fill:${faceColor};stroke:${lineColor};stroke-width: ${lineWidth}px;stroke-dasharray:${LINE_STYLES[axes.scales().plot][validLineType - 1]}`);
|
|
59
60
|
</script>
|
|
60
61
|
|
|
61
62
|
{#if pa}
|
package/src/2d/Axes.svelte
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
- `limX` - array with limits for x-axis (in plot units), default: `[0, 1]`.
|
|
6
6
|
- `limY` - array with limits for y-axis (in plot units), default: `[0, 1]`.
|
|
7
7
|
- `title` - title of the plot (string).
|
|
8
|
-
- `margins` - array with relative margins (bottom, left, top, right), default `[1.0,
|
|
8
|
+
- `margins` - array with relative margins (bottom, left, top, right), default `[1.0, 1.1, 0.55, 0.60]`.
|
|
9
9
|
|
|
10
10
|
Properties for downloading the plot as PNG or SVG file or copying it to clipboard:
|
|
11
11
|
- `downloadLinks` - how to show download links panel (`'none'` - default, `'hover'`, `'fixed'`).
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
- `pngWidth` - width of PNG image in cm, default `8`
|
|
14
14
|
- `pngHeight` - height of PNG image in cm, default `8`.
|
|
15
15
|
- `pngRes` - resolution of PNG image (pixels per inch), default `300`.
|
|
16
|
-
- `clipboardWidth` - width of plot image to copy to clipboard in pixels
|
|
17
|
-
- `clipboardHeight` - height of plot image to copy to clipboard in pixels
|
|
16
|
+
- `clipboardWidth` - width of plot image to copy to clipboard in pixels, default `1200`.
|
|
17
|
+
- `clipboardHeight` - height of plot image to copy to clipboard in pixels, default `800`.
|
|
18
18
|
|
|
19
19
|
Example:
|
|
20
20
|
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
import {Axes} from 'svelte-plots-basic/2d';
|
|
24
24
|
</script>
|
|
25
25
|
|
|
26
|
-
<Axes limX={[2000, 2050]} limY={[0, 100]} title="GDP of
|
|
26
|
+
<Axes limX={[2000, 2050]} limY={[0, 100]} title="GDP of countries" >
|
|
27
27
|
</Axes>
|
|
28
28
|
```
|
|
29
29
|
-->
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
|
|
102
102
|
/* handler for mouse events */
|
|
103
103
|
function handleMouse(e, f) {
|
|
104
|
-
if (f && e.target.id
|
|
104
|
+
if (f && e.target.id === "axes-box") {
|
|
105
105
|
const x = invTransformCoords([e.offsetX - left], tX)[0];
|
|
106
106
|
const y = invTransformCoords([e.offsetY - top], tY)[0];
|
|
107
107
|
f(x, y);
|
|
@@ -307,7 +307,7 @@
|
|
|
307
307
|
<text {x} y={coords.ltop} dx="1.2em" dy="-0.25em" dominant-baseline="hanging"
|
|
308
308
|
fill={params.labelColor}
|
|
309
309
|
font-size="{params.fontSize}em"
|
|
310
|
-
text-anchor="
|
|
310
|
+
text-anchor="start"
|
|
311
311
|
>{@html getTickFactorLabel(params.labelsFactor)}</text>
|
|
312
312
|
{/if}
|
|
313
313
|
{/snippet}
|
|
@@ -316,14 +316,16 @@
|
|
|
316
316
|
{#snippet glgSnippet(params, coords)}
|
|
317
317
|
{@const elw = coords.elw + 2 * coords.elp}
|
|
318
318
|
{@const elp = coords.elp}
|
|
319
|
+
{@const elx = coords.elx}
|
|
319
320
|
{@const elh = coords.elh}
|
|
320
321
|
{@const ely = coords.ely}
|
|
322
|
+
{@const eliw = coords.eliw}
|
|
321
323
|
|
|
322
324
|
<svg x={coords.lgl} y={coords.lgt} height={coords.lgh} width={coords.lgw}>
|
|
323
325
|
<rect height="100%" width="100%" fill={params.faceColor} stroke={params.lineColor} stroke-width={params.lineWidth} />
|
|
324
326
|
|
|
325
327
|
{#each params.items as item, i}
|
|
326
|
-
<svg x={
|
|
328
|
+
<svg x={elx[i]} y={ely[i]} width={eliw[i]} height={elh[i]}>
|
|
327
329
|
|
|
328
330
|
<!-- line -->
|
|
329
331
|
{#if item.line}
|
|
@@ -532,7 +534,7 @@
|
|
|
532
534
|
</p>
|
|
533
535
|
{:else}
|
|
534
536
|
<div class="download-links">
|
|
535
|
-
<button type="button" onclick={handleClickSVG}>↓
|
|
537
|
+
<button type="button" onclick={handleClickSVG}>↓ svg</button>
|
|
536
538
|
<button type="button" onclick={handleClickPNG}>↓ png</button>
|
|
537
539
|
<button type="button" onclick={handleClickPNGAdvanced}>↓ png+</button>
|
|
538
540
|
<button type="button" onclick={handleClickCopy}>⧉ copy</button>
|
package/src/2d/AxisLines.svelte
CHANGED
|
@@ -3,21 +3,19 @@
|
|
|
3
3
|
|
|
4
4
|
Main properties:
|
|
5
5
|
- `lineCoords` - coordinates of the line segments as 2D array.
|
|
6
|
-
- `lineColor` - color of the
|
|
7
|
-
- `lineWidth` - width of
|
|
6
|
+
- `lineColor` - color of the line segments, default: `Colors.DARKGRAY`.
|
|
7
|
+
- `lineWidth` - width of the line segments in pixels, default: `1`.
|
|
8
8
|
- `lineType` - line type (`1` - solid (default), `2` - dashed, `3` - dotted, `4` - dashdot).
|
|
9
9
|
- `className` - string with classname to be added to `<g></g>` tag wrapping the lines.
|
|
10
10
|
|
|
11
11
|
**Description:**
|
|
12
12
|
|
|
13
|
-
The coordinates
|
|
13
|
+
The coordinates must be provided in form of nested arrays. Each element of this array contains
|
|
14
14
|
`Vector` or `Array` with the coordinates in world (not screen) coordinate system:
|
|
15
15
|
- `lineCoords[0][0]` - x-coordinates of start points of segments.
|
|
16
16
|
- `lineCoords[1][0]` - x-coordinates of end points of segments.
|
|
17
17
|
- `lineCoords[0][1]` - y-coordinates of start points of segments.
|
|
18
18
|
- `lineCoords[1][1]` - y-coordinates of end points of segments.
|
|
19
|
-
|
|
20
|
-
```
|
|
21
19
|
-->
|
|
22
20
|
<script>
|
|
23
21
|
import { getContext } from 'svelte';
|
|
@@ -33,7 +31,7 @@
|
|
|
33
31
|
className = '' // CSS class name for the component
|
|
34
32
|
} = $props();
|
|
35
33
|
|
|
36
|
-
// get axes context
|
|
34
|
+
// get axes context for coordinate transforms
|
|
37
35
|
const axes = getContext('axes');
|
|
38
36
|
|
|
39
37
|
// reactive variables for coordinates of axis lines
|
|
@@ -16,8 +16,6 @@
|
|
|
16
16
|
- `tickCoords[1][0]` - x-coordinates of end points of tick segments.
|
|
17
17
|
- `tickCoords[0][1]` - y-coordinates of start points of tick segments.
|
|
18
18
|
- `tickCoords[1][1]` - y-coordinates of end points of tick segments.
|
|
19
|
-
|
|
20
|
-
```
|
|
21
19
|
-->
|
|
22
20
|
<script>
|
|
23
21
|
|
|
@@ -57,7 +55,7 @@
|
|
|
57
55
|
{/each}
|
|
58
56
|
{:else if las === 2 && pos === 1}
|
|
59
57
|
{#each x as v, i}
|
|
60
|
-
<text data-id={i} x={x[i]} y={y[i]} dx={-dy/2} dy={0} transform={`rotate(-90, ${x[i]}, ${y[i]})`} text-anchor=
|
|
58
|
+
<text data-id={i} x={x[i]} y={y[i]} dx={-dy/2} dy={0} transform={`rotate(-90, ${x[i]}, ${y[i]})`} text-anchor="end">{@html tickLabels[i]}</text>
|
|
61
59
|
{/each}
|
|
62
60
|
{:else}
|
|
63
61
|
{#each x as v, i}
|
package/src/2d/Bars.svelte
CHANGED
|
@@ -45,25 +45,46 @@
|
|
|
45
45
|
onclick
|
|
46
46
|
} = $props();
|
|
47
47
|
|
|
48
|
+
function toNumber(value) {
|
|
49
|
+
const canConvert =
|
|
50
|
+
typeof value === 'number' ||
|
|
51
|
+
(typeof value === 'string' && value.trim() !== '');
|
|
52
|
+
|
|
53
|
+
return canConvert ? Number(value) : NaN;
|
|
54
|
+
}
|
|
55
|
+
|
|
48
56
|
const bw = $derived.by(() => {
|
|
49
|
-
|
|
50
|
-
|
|
57
|
+
const value = toNumber(barWidth);
|
|
58
|
+
if (!Number.isFinite(value) || value <= 0 || value > 1) {
|
|
59
|
+
console.error('Bars: parameter "barWidth" must be a finite number greater than 0 and no greater than 1.');
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
return value;
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
const exactWidth = $derived.by(() => {
|
|
66
|
+
if (barWidthExact == null) return {provided: false, value: null};
|
|
67
|
+
|
|
68
|
+
const value = toNumber(barWidthExact);
|
|
69
|
+
if (!Number.isFinite(value) || value <= 0) {
|
|
70
|
+
console.error('Bars: parameter "barWidthExact" must be a finite positive number.');
|
|
51
71
|
return null;
|
|
52
72
|
}
|
|
53
|
-
|
|
73
|
+
|
|
74
|
+
return {provided: true, value};
|
|
54
75
|
});
|
|
55
76
|
|
|
56
77
|
const x = $derived.by(() => {
|
|
57
|
-
if (
|
|
78
|
+
if (bw === null || exactWidth === null) return null;
|
|
58
79
|
const xv = checkCoords(xValues, 'BarSeries');
|
|
59
80
|
if (!xv) return null;
|
|
60
81
|
const n = xv.length;
|
|
61
82
|
if (n < 1) return null;
|
|
62
83
|
|
|
63
84
|
let w;
|
|
64
|
-
if (
|
|
65
|
-
w =
|
|
66
|
-
} else if (n
|
|
85
|
+
if (exactWidth.provided) {
|
|
86
|
+
w = exactWidth.value;
|
|
87
|
+
} else if (n === 1) {
|
|
67
88
|
console.error('Bars: if only one bar must be shown, value for property "barWidthExact" should be provided.');
|
|
68
89
|
return null;
|
|
69
90
|
} else {
|
|
@@ -74,7 +95,7 @@
|
|
|
74
95
|
}
|
|
75
96
|
}
|
|
76
97
|
|
|
77
|
-
w = w *
|
|
98
|
+
w = w * bw;
|
|
78
99
|
const whalf = w / 2;
|
|
79
100
|
const left = Vector.zeros(n);
|
|
80
101
|
const width = Vector.zeros(n);
|
|
@@ -113,6 +134,6 @@
|
|
|
113
134
|
</script>
|
|
114
135
|
|
|
115
136
|
{#if isOk}
|
|
116
|
-
<Rectangles className="series
|
|
137
|
+
<Rectangles className="series-bar" left={x.left} width={x.width} top={y.top} height={y.height}
|
|
117
138
|
lineWidth={lineWidth} {lineColor} {faceColor} {onclick} />
|
|
118
139
|
{/if}
|
package/src/2d/Heatmap.svelte
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<!--
|
|
2
|
-
@component Adds a heatmap
|
|
2
|
+
@component Adds a heatmap visualizing values of a matrix.
|
|
3
3
|
|
|
4
4
|
Main properties:
|
|
5
5
|
- `values` - matrix (object of class `Matrix` from `mdatools` package) with values to visualize.
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
import { Matrix } from 'mdatools/arrays';
|
|
14
14
|
import { Axes, Heatmap } from 'svelte-plots-basic/2d';
|
|
15
15
|
|
|
16
|
-
// create matrix with 5 rows and 10 columns filled with
|
|
16
|
+
// create matrix with 5 rows and 10 columns filled with random values.
|
|
17
17
|
const x = Matrix.rand(5, 10);
|
|
18
18
|
</script>
|
|
19
19
|
|
|
@@ -91,7 +91,14 @@
|
|
|
91
91
|
|
|
92
92
|
|
|
93
93
|
// check that values are provided as a matrix
|
|
94
|
-
|
|
94
|
+
const v = $derived.by(() => {
|
|
95
|
+
if (!ismatrix(values) || values.nrows < 1 || values.ncols < 1) {
|
|
96
|
+
console.error('Heatmap: parameter "values" must be a non-empty Matrix.');
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return values;
|
|
101
|
+
});
|
|
95
102
|
|
|
96
103
|
// check and process left values for breaks
|
|
97
104
|
let lb = $derived.by(() => {
|
|
@@ -121,9 +128,11 @@
|
|
|
121
128
|
let lc = $derived.by(() => {
|
|
122
129
|
if (!lb) return null;
|
|
123
130
|
|
|
124
|
-
if (colmap) {
|
|
125
|
-
if (!Array.isArray(colmap)
|
|
126
|
-
|
|
131
|
+
if (colmap !== null && colmap !== undefined) {
|
|
132
|
+
if (!Array.isArray(colmap) || colmap.some(color =>
|
|
133
|
+
typeof color !== 'string' || color.trim() === ''
|
|
134
|
+
)) {
|
|
135
|
+
console.error('Heatmap: parameter "colmap" must be an array of non-empty color strings.');
|
|
127
136
|
return null;
|
|
128
137
|
}
|
|
129
138
|
if (colmap.length !== lb.length - 1) {
|