raain-ui 2.3.7 → 2.3.9

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/CHANGELOG.md CHANGED
@@ -5,51 +5,77 @@ All notable changes to the raain-ui project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
- ## [2.3.x] - Current
8
+ ## [Unreleased]
9
+
10
+ ### Changed
11
+
12
+ - Version bump to 2.3.9
13
+ - Version information export in bpInfo.ts
14
+
15
+ ## [2.3.8] - 2025-05-20
16
+
17
+ ### Changed
18
+
19
+ - Version bump to 2.3.8
20
+ - Version information export in bpInfo.ts
21
+
22
+ ## [2.3.6] - 2025-04-01
9
23
 
10
24
  ### Added
25
+
11
26
  - Cartesian earth optimization for improved performance
27
+ - DateStatusUtils for improved date handling and formatting in DateStatusElement and DynamicDateStatusElement
28
+ - Memory bank documentation for AI assistance
12
29
 
13
30
  ## [2.2.x]
14
31
 
15
32
  ### Enhanced
33
+
16
34
  - Model polar visualization improvements
17
35
 
18
36
  ## [2.1.x]
19
37
 
20
38
  ### Added
39
+
21
40
  - Support for icons in composite layers
22
41
 
23
42
  ## [2.0.x]
24
43
 
25
44
  ### Changed
45
+
26
46
  - Updated raain-model integration
27
47
 
28
48
  ## [1.11.x]
29
49
 
30
50
  ### Changed
51
+
31
52
  - Refactored Factory components
32
53
 
33
54
  ### Added
55
+
34
56
  - Performance monitoring capabilities
35
57
 
36
58
  ## [1.10.x]
37
59
 
38
60
  ### Fixed
61
+
39
62
  - Cartesian visualization issues
40
63
 
41
64
  ### Added
65
+
42
66
  - Show/hide capability for UI elements
43
67
 
44
68
  ## [1.0.x - 1.9.x]
45
69
 
46
70
  ### Added
71
+
47
72
  - Various factories for UI components:
48
- - Map integration
49
- - Compare functionality
50
- - Configuration options
73
+ - Map integration
74
+ - Compare functionality
75
+ - Configuration options
51
76
 
52
77
  ## [0.x.x]
53
78
 
54
79
  ### Added
80
+
55
81
  - Initial release with core components extracted from RAAIN project
package/README.md CHANGED
@@ -1,35 +1,86 @@
1
- # raain-ui
1
+ <div align="center">
2
2
 
3
- UI components and visualization layers for raain.io applications.
3
+ # 🌧️ raain-ui
4
4
 
5
- ## Description
5
+ [![npm version](https://img.shields.io/npm/v/raain-ui.svg)](https://www.npmjs.com/package/raain-ui)
6
+ [![Build Status](https://github.com/raainio/raain-ui/workflows/CI/badge.svg)](https://github.com/raainio/raain-ui/actions)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+ [![TypeScript](https://img.shields.io/badge/TypeScript-4.0-blue.svg)](https://www.typescriptlang.org/)
6
9
 
7
- raain-ui is a library that provides UI components and visualization layers for displaying and interacting with rainfall data. It uses Leaflet for maps, Pixi.js for rendering, and Chart.js for charting.
10
+ **Advanced UI components and visualization layers for rainfall data**
8
11
 
9
- ## Installation
12
+ </div>
13
+
14
+ <p align="center">
15
+ <b>raain-ui</b> is a library that provides specialized UI components and visualization layers for displaying and interacting with rainfall data coming from <a href="https://radartorain.com">radartorain.com</a>. Built with modern web technologies, it offers high-performance visualizations for meteorological applications.
16
+ </p>
17
+
18
+ ## 📋 Table of Contents
19
+
20
+ - [Features](#-features)
21
+ - [Screenshots](#-screenshots)
22
+ - [Installation](#-installation)
23
+ - [Usage](#-usage)
24
+ - [Documentation](#-documentation)
25
+ - [Angular Configuration](#-angular-configuration)
26
+ - [Changelog](#-changelog)
27
+ - [Contributing](#-contributing)
28
+ - [License](#-license)
29
+
30
+ ## ✨ Features
31
+
32
+ - **Interactive Maps**: Leaflet-based map visualizations for geospatial rainfall data
33
+ - **High-Performance Rendering**: Pixi.js-powered rendering for smooth visualizations
34
+ - **Data Charting**: Chart.js integration for time-series and statistical analysis
35
+ - **3D Globe Visualization**: Earth visualization for global rainfall patterns
36
+ - **Time Navigation**: Advanced date/time controls for temporal data exploration
37
+ - **Responsive Design**: Components that adapt to different screen sizes
38
+ - **Framework Agnostic**: Works with vanilla JavaScript or any framework
39
+
40
+ ## 📸 Screenshots
41
+
42
+ Here are some screenshots showcasing the raain-ui components in action:
43
+
44
+ ### Map Visualization
45
+
46
+ ![Map Visualization](./screenshots/Screenshot%202025-05-20%20at%2016.13.31.png)
47
+
48
+ ### Compare Data
49
+
50
+ ![Compare](./screenshots/Screenshot%202025-05-20%20at%2016.13.49.png)
51
+
52
+ ### Date Analysis
53
+
54
+ ![Date Analysis](./screenshots/Screenshot%202025-05-20%20at%2016.14.07.png)
55
+
56
+ ## 📦 Installation
10
57
 
11
58
  ```bash
12
59
  npm install raain-ui
13
60
  ```
14
61
 
15
- ## Usage
62
+ ## 🚀 Usage
16
63
 
17
- ### Basic Setup
64
+ raain-ui provides a set of components that can be easily integrated into your application. Here's a simple example of
65
+ how to use the MapElement component:
18
66
 
19
67
  ```javascript
20
- import { MapElement } from 'raain-ui';
68
+ import {MapElementFactory} from 'raain-ui';
21
69
 
22
70
  // Create a map element
23
- const mapElement = new MapElement({
24
- container: 'map-container',
25
- center: [51.505, -0.09],
26
- zoom: 13
71
+ const mapElement = MapElementFactory.create({
72
+ container: 'map-container',
73
+ center: [51.505, -0.09],
74
+ zoom: 13
27
75
  });
76
+
77
+ // Add a rainfall layer
78
+ mapElement.addRainfallLayer(rainfallData);
28
79
  ```
29
80
 
30
- ### Example Application
81
+ ### 🔍 Example Application
31
82
 
32
- The project includes an example application that demonstrates how to use the library:
83
+ The project includes a comprehensive example application that demonstrates how to use the library:
33
84
 
34
85
  ```bash
35
86
  # Clone the repository
@@ -45,29 +96,106 @@ cd example/
45
96
  npm start
46
97
  ```
47
98
 
48
- This will open the example application at http://localhost:1234
99
+ This will open the example application at http://localhost:1234, where you can explore the various components and
100
+ features of raain-ui.
101
+
102
+ ## 📚 Documentation
103
+
104
+ Comprehensive API documentation is available in the [specifications](./specs) directory. This includes detailed
105
+ information about all components, their properties, methods, and events.
106
+
107
+ ### 🧠 Memory Bank
49
108
 
50
- ## Development
109
+ This project uses a Memory Bank for comprehensive documentation and context retention. The Memory Bank provides in-depth
110
+ information about the project's architecture, design decisions, and development context.
111
+
112
+ <details>
113
+ <summary><b>Memory Bank Files</b> (click to expand)</summary>
114
+
115
+ The Memory Bank is located in the `.memory-bank` directory and contains the following files:
116
+
117
+ | File | Description |
118
+ |------------------------|-------------------------------------------------------------------|
119
+ | `memory-bank-rules.md` | Rules to follow and to consider in all contexts |
120
+ | `projectbrief.md` | Overview of the project, core requirements, and goals |
121
+ | `productContext.md` | Why the project exists, problems it solves, and how it works |
122
+ | `systemPatterns.md` | System architecture, key technical decisions, and design patterns |
123
+ | `techContext.md` | Technologies used, development setup, and technical constraints |
124
+ | `activeContext.md` | Current work focus, recent changes, and next steps |
125
+ | `progress.md` | What works, what's left to build, and known issues |
126
+
127
+ </details>
128
+
129
+ ### 🅰️ Angular Configuration
130
+
131
+ If you're using this library in an Angular application, you'll need to configure Angular to handle the CSS files
132
+ properly. Here are two approaches:
133
+
134
+ <details>
135
+ <summary><b>Option 1: Import CSS in angular.json</b></summary>
136
+
137
+ ```json
138
+ "styles": [
139
+ "src/styles.css",
140
+ "node_modules/raain-ui/dist/data/globe.css"
141
+ ]
142
+ ```
143
+
144
+ </details>
145
+
146
+ <details>
147
+ <summary><b>Option 2: Configure webpack for CSS imports</b></summary>
148
+
149
+ First, create a custom webpack configuration:
150
+
151
+ ```javascript
152
+ // custom-webpack.config.js
153
+ module.exports = {
154
+ module: {
155
+ rules: [
156
+ {
157
+ test: /\.css$/,
158
+ include: [/node_modules\/raain-ui/],
159
+ use: ['style-loader', 'css-loader']
160
+ }
161
+ ]
162
+ }
163
+ };
164
+ ```
165
+
166
+ Then use `@angular-builders/custom-webpack` to apply this configuration:
167
+
168
+ ```json
169
+ "architect": {
170
+ "build": {
171
+ "builder": "@angular-builders/custom-webpack:browser",
172
+ "options": {
173
+ "customWebpackConfig": {
174
+ "path": "./custom-webpack.config.js"
175
+ }
176
+ }
177
+ }
178
+ }
179
+ ```
51
180
 
52
- Please read the [Development Guidelines](./GUIDELINES.md) for detailed information about:
53
- - Build and configuration instructions
54
- - Testing information
55
- - Code style and development guidelines
56
- - Project structure
57
- - Dependencies
181
+ </details>
58
182
 
59
- ## Documentation
183
+ ## 📝 Changelog
60
184
 
61
- API documentation is available in the [specifications](./specs) directory.
185
+ See the [Changelog](./CHANGELOG.md) for a detailed list of changes in each version.
62
186
 
63
- ## Changelog
187
+ ## 👥 Contributing
64
188
 
65
- See the [Changelog](./CHANGELOG.md) for a list of changes in each version.
189
+ Contributions are welcome! If you'd like to contribute to raain-ui, please follow these steps:
66
190
 
67
- ## Release Process
191
+ 1. Fork the repository
192
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
193
+ 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
194
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
195
+ 5. Open a Pull Request
68
196
 
69
- See the [Release Process](./RELEASE_PROCESS.md) for information about how releases are managed.
197
+ Please make sure your code follows the existing style and includes appropriate tests.
70
198
 
71
- ## License
199
+ ## 📄 License
72
200
 
73
- MIT
201
+ This project is licensed under the MIT License - see the [LICENSE](./LICENSE) file for details.
package/data/globe.css ADDED
@@ -0,0 +1,167 @@
1
+ .globe {
2
+ --settingwidth: min(480px, 100vw);
3
+ --infowidth: min(480px, 50vw);
4
+ --xslide: min(480px, 50vw);
5
+ --menuheight: 100%;
6
+ --yslide: 0px;
7
+ }
8
+
9
+ @media screen and (max-width: 768px) and (orientation: portrait) {
10
+ .globe {
11
+ --infowidth: 100%;
12
+ --xslide: 0px;
13
+ --menuheight: 50vh;
14
+ --yslide: 50vh;
15
+ }
16
+ }
17
+
18
+ .globe * {
19
+ box-sizing: border-box;
20
+ }
21
+
22
+ .globe div {
23
+ transition: 0.33s;
24
+ }
25
+
26
+ .globe button {
27
+ background: transparent;
28
+ border: none;
29
+ padding: 8px;
30
+ cursor: pointer;
31
+ appearance: none;
32
+ -webkit-appearance: none;
33
+ touch-action: manipulation;
34
+ }
35
+
36
+ .globe button svg {
37
+ touch-action: manipulation;
38
+ }
39
+
40
+ .globe canvas.map {
41
+ width: 100%;
42
+ height: 100%;
43
+ display: inline-block;
44
+ position: absolute;
45
+ padding: 0;
46
+ }
47
+
48
+ .globe .sprite {
49
+ width: 0;
50
+ height: 0;
51
+ position: absolute;
52
+ visibility: hidden;
53
+ display: none;
54
+ }
55
+
56
+ .globe .settings {
57
+ position: absolute;
58
+ width: var(--settingwidth);
59
+ height: 100%;
60
+ transform: translate(calc(0px - 100%));
61
+ visibility: hidden; /* Hide from tab navigation when offscreen */
62
+ z-index: 2;
63
+ }
64
+
65
+ .globe .main {
66
+ width: 100%;
67
+ height: 100%;
68
+ position: relative;
69
+ overflow: hidden;
70
+ background-color: #404542;
71
+ }
72
+
73
+ .globe .shifted {
74
+ transform: translate(calc(0px - var(--xslide) / 2), calc(0px - var(--yslide) / 2));
75
+ }
76
+
77
+ .globe .infoslider {
78
+ position: absolute;
79
+ bottom: 0;
80
+ right: 0;
81
+ width: var(--infowidth);
82
+ height: var(--menuheight);
83
+ transform: translate(var(--xslide), var(--yslide));
84
+ visibility: hidden; /* Hide from tab navigation when offscreen */
85
+ z-index: 1;
86
+ display: flex;
87
+ flex-direction: column;
88
+ overflow: hidden;
89
+ padding: 0;
90
+ box-shadow: 0px 0px 10px 0px black;
91
+ background-color: white;
92
+ }
93
+
94
+ .globe .infoslider .infoTopBar {
95
+ display: flex;
96
+ align-items: center;
97
+ justify-content: flex-end;
98
+ gap: 20px;
99
+ box-shadow: 0px 3px 5px 0px rgba(0, 0, 0, 0.14);
100
+ font-family: 'Source Sans Pro', sans-serif;
101
+ }
102
+
103
+ .globe .infoslider .infobox {
104
+ word-wrap: break-word;
105
+ overflow-y: auto;
106
+ overflow-x: hidden;
107
+ flex: 1;
108
+ }
109
+
110
+ .globe .slid {
111
+ visibility: visible;
112
+ transform: translate(0px);
113
+ }
114
+
115
+ .globe .status {
116
+ position: absolute;
117
+ bottom: 0;
118
+ right: 0;
119
+ text-align: right;
120
+ font-family: "Lucida Console", monospace;
121
+ color: white;
122
+ background-color: rgba(34, 34, 34, 0.5);
123
+ padding: 0.2em;
124
+ z-index: 1;
125
+ }
126
+
127
+ .globe .icon {
128
+ width: 20px;
129
+ height: 20px;
130
+ }
131
+
132
+ .globe .stroke {
133
+ stroke: grey;
134
+ stroke-width: 2;
135
+ }
136
+
137
+ .globe .stroke:hover {
138
+ stroke: black;
139
+ }
140
+
141
+ .globe .close-button {
142
+ position: absolute;
143
+ top: 0;
144
+ right: 0;
145
+ }
146
+
147
+ .globe .marker {
148
+ display: inline-block;
149
+ position: absolute;
150
+ z-index: 1;
151
+ width: 30px;
152
+ height: 30px;
153
+ transform: translate(-50%, -96%);
154
+ stroke: white;
155
+ }
156
+
157
+ .globe .spot {
158
+ display: inline-block;
159
+ position: absolute;
160
+ z-index: 1;
161
+ width: 12px;
162
+ height: 12px;
163
+ transform: translate(-50%, -50%);
164
+ fill: red;
165
+ stroke: black;
166
+ stroke-width: 2px;
167
+ }
@@ -1,67 +1,67 @@
1
1
  import Chart from 'chart.js/auto';
2
2
  import { DateRange } from './Tools';
3
- export declare class DateStatusElementInput {
4
- setOfData: {
5
- label: string;
6
- style: string;
7
- values: {
8
- date: Date;
9
- value: number;
10
- }[];
3
+ export interface IDataSet {
4
+ label: string;
5
+ style: string;
6
+ values: {
7
+ date: Date;
8
+ value: number;
11
9
  }[];
10
+ }
11
+ export interface IDataPoint {
12
+ label: string;
13
+ type: string;
14
+ data: number[];
15
+ borderColor: string;
16
+ backgroundColor: string;
17
+ }
18
+ export declare class DateStatusElementInput {
19
+ setOfData: IDataSet[];
12
20
  focusDate: Date;
13
21
  focusRange: DateRange;
14
- constructor(setOfData?: {
15
- label: string;
16
- style: string;
17
- values: {
18
- date: Date;
19
- value: number;
20
- }[];
21
- }[], focusDate?: Date, focusRange?: DateRange);
22
+ chartMinValue?: number;
23
+ chartMaxValue?: number;
24
+ constructor(setOfData?: IDataSet[], focusDate?: Date, focusRange?: DateRange, chartMinValue?: number, chartMaxValue?: number);
22
25
  }
23
26
  export declare class DateStatusElement {
24
27
  protected addSomeDebugInfos: boolean;
25
28
  chart: Chart<any>;
26
- focusReset: () => void;
27
- focusPrevious: () => void;
28
- focusNext: () => void;
29
- focusClick: (e: any) => void;
29
+ chartTitle: string;
30
+ focusReset: (dataPoints?: IDataPoint[]) => Promise<void>;
31
+ focusPrevious: () => Promise<void>;
32
+ focusNext: () => Promise<void>;
33
+ focusClick: (e: any) => Promise<void>;
34
+ minDate: Date;
35
+ maxDate: Date;
36
+ focusPos: number;
37
+ focusDate: Date;
38
+ focusRange: DateRange;
39
+ chartMinValue: number | undefined;
40
+ chartMaxValue: number | undefined;
30
41
  constructor(addSomeDebugInfos?: boolean);
31
- protected static filterFocus(mapToFilter: Array<{
32
- date: Date;
33
- value: number;
34
- }>, focusDate: Date, focusRange: DateRange): Array<{
35
- date: Date;
36
- value: number;
37
- }>;
38
- protected static groupFocus(mapToFilter: Array<{
39
- date: Date;
40
- value: number;
41
- }>, focusDate: Date, focusRange: DateRange, min: Date, max: Date): any[];
42
- protected static focusLabels(focusDate: Date, focusRange: DateRange, min: Date, max: Date, data: {
43
- label: string;
44
- style: string;
45
- values: {
46
- date: Date;
47
- value: number;
48
- }[];
49
- }[]): any[];
50
- protected static getFocusDateAndTitle(oldFocusDate: Date, focusRange: DateRange, index: number, min: Date, max: Date): {
51
- newFocusDate: Date;
52
- newTitle: string;
53
- };
54
- protected static buildLabel(date: Date): string;
55
- protected static buildLabelYear(date: Date, year: number): string;
56
- protected static buildLabelMonth(date: Date, month: number): string;
57
- protected static buildLabelDay(date: Date, day: number): string;
58
- protected static buildLabelHour(date: Date, hour: number): string;
59
- protected static buildLabelMinute(date: Date, minute: number): string;
42
+ protected _setOfData: IDataSet[];
43
+ protected get setOfData(): IDataSet[];
44
+ protected set setOfData(value: IDataSet[]);
45
+ protected _originalDataPoints: number[][];
46
+ protected get originalDataPoints(): number[][];
60
47
  build(element: HTMLCanvasElement, inputs: DateStatusElementInput): void;
61
- getFocusPosRelative(event: any, chart: any): any;
48
+ getFocusPosRelative(event: any, chart_: any): any;
49
+ protected updateChartTitle(title: string): void;
50
+ protected createChartConfig(data: {
51
+ datasets: IDataPoint[];
52
+ labels: string[];
53
+ }): any;
54
+ protected initializeChart(element: HTMLCanvasElement, config: any, inputs: DateStatusElementInput): void;
55
+ protected setupFocusHandlers(inputs: DateStatusElementInput): void;
56
+ protected setupFocusClickHandler(): void;
57
+ protected setupFocusResetHandler(inputs: DateStatusElementInput): void;
58
+ protected setupFocusNavigationHandlers(): void;
59
+ protected updateChartData(): void;
60
+ protected updateChart(eFocusPos: number, eFocusDate: Date, eFocusRange?: DateRange): void;
61
+ protected buildDateTimeSeries(focusDate: Date, focusRange: DateRange): IDataPoint[];
62
62
  protected getInitialFocusPos(focusDate: Date, focusRange: DateRange, min: Date): number;
63
- protected getFocusPosAdded(chart: any, focusRange: DateRange, toAdd: number, focusDate: Date, min: Date): {
64
- pos: any;
63
+ protected getFocusPosAdded(toAdd: number, focusDate?: Date, focusRange?: DateRange): {
64
+ pos: number;
65
65
  newFocusDate: Date;
66
66
  };
67
67
  }