raain-ui 2.3.7 → 2.3.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/CHANGELOG.md CHANGED
@@ -5,51 +5,67 @@ 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
+ ## [Unreleased]
9
+
10
+ ### Changed
11
+
8
12
  ## [2.3.x] - Current
9
13
 
10
14
  ### Added
15
+
11
16
  - Cartesian earth optimization for improved performance
17
+ - DateStatusUtils for improved date handling and formatting in DateStatusElement and DynamicDateStatusElement
18
+ - Memory bank documentation for AI assistance
12
19
 
13
20
  ## [2.2.x]
14
21
 
15
22
  ### Enhanced
23
+
16
24
  - Model polar visualization improvements
17
25
 
18
26
  ## [2.1.x]
19
27
 
20
28
  ### Added
29
+
21
30
  - Support for icons in composite layers
22
31
 
23
32
  ## [2.0.x]
24
33
 
25
34
  ### Changed
35
+
26
36
  - Updated raain-model integration
27
37
 
28
38
  ## [1.11.x]
29
39
 
30
40
  ### Changed
41
+
31
42
  - Refactored Factory components
32
43
 
33
44
  ### Added
45
+
34
46
  - Performance monitoring capabilities
35
47
 
36
48
  ## [1.10.x]
37
49
 
38
50
  ### Fixed
51
+
39
52
  - Cartesian visualization issues
40
53
 
41
54
  ### Added
55
+
42
56
  - Show/hide capability for UI elements
43
57
 
44
58
  ## [1.0.x - 1.9.x]
45
59
 
46
60
  ### Added
61
+
47
62
  - Various factories for UI components:
48
- - Map integration
49
- - Compare functionality
50
- - Configuration options
63
+ - Map integration
64
+ - Compare functionality
65
+ - Configuration options
51
66
 
52
67
  ## [0.x.x]
53
68
 
54
69
  ### Added
70
+
55
71
  - 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,111 @@ 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
108
+
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
+ ```
49
180
 
50
- ## Development
181
+ </details>
51
182
 
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
183
+ ## 📝 Changelog
58
184
 
59
- ## Documentation
185
+ See the [Changelog](./CHANGELOG.md) for a detailed list of changes in each version. Recent highlights include:
60
186
 
61
- API documentation is available in the [specifications](./specs) directory.
187
+ - **v2.3.x**: Cartesian earth optimization, DateStatusUtils, Memory bank documentation
188
+ - **v2.2.x**: Model polar visualization improvements
189
+ - **v2.1.x**: Support for icons in composite layers
190
+ - **v2.0.x**: Updated raain-model integration
62
191
 
63
- ## Changelog
192
+ ## 👥 Contributing
64
193
 
65
- See the [Changelog](./CHANGELOG.md) for a list of changes in each version.
194
+ Contributions are welcome! If you'd like to contribute to raain-ui, please follow these steps:
66
195
 
67
- ## Release Process
196
+ 1. Fork the repository
197
+ 2. Create a feature branch (`git checkout -b feature/amazing-feature`)
198
+ 3. Commit your changes (`git commit -m 'Add some amazing feature'`)
199
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
200
+ 5. Open a Pull Request
68
201
 
69
- See the [Release Process](./RELEASE_PROCESS.md) for information about how releases are managed.
202
+ Please make sure your code follows the existing style and includes appropriate tests.
70
203
 
71
- ## License
204
+ ## 📄 License
72
205
 
73
- MIT
206
+ 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
  }