raain-ui 2.3.6 → 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 ADDED
@@ -0,0 +1,71 @@
1
+ # Changelog
2
+
3
+ All notable changes to the raain-ui project will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Changed
11
+
12
+ ## [2.3.x] - Current
13
+
14
+ ### Added
15
+
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
19
+
20
+ ## [2.2.x]
21
+
22
+ ### Enhanced
23
+
24
+ - Model polar visualization improvements
25
+
26
+ ## [2.1.x]
27
+
28
+ ### Added
29
+
30
+ - Support for icons in composite layers
31
+
32
+ ## [2.0.x]
33
+
34
+ ### Changed
35
+
36
+ - Updated raain-model integration
37
+
38
+ ## [1.11.x]
39
+
40
+ ### Changed
41
+
42
+ - Refactored Factory components
43
+
44
+ ### Added
45
+
46
+ - Performance monitoring capabilities
47
+
48
+ ## [1.10.x]
49
+
50
+ ### Fixed
51
+
52
+ - Cartesian visualization issues
53
+
54
+ ### Added
55
+
56
+ - Show/hide capability for UI elements
57
+
58
+ ## [1.0.x - 1.9.x]
59
+
60
+ ### Added
61
+
62
+ - Various factories for UI components:
63
+ - Map integration
64
+ - Compare functionality
65
+ - Configuration options
66
+
67
+ ## [0.x.x]
68
+
69
+ ### Added
70
+
71
+ - Initial release with core components extracted from RAAIN project
package/README.md CHANGED
@@ -1,19 +1,206 @@
1
- # raain-ui
1
+ <div align="center">
2
2
 
3
- Please read the [specifications](./specs).
3
+ # 🌧️ raain-ui
4
+
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/)
9
+
10
+ **Advanced UI components and visualization layers for rainfall data**
11
+
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
4
57
 
5
- or try the [example](./example) :
6
58
  ```bash
7
- npm i
59
+ npm install raain-ui
60
+ ```
61
+
62
+ ## 🚀 Usage
63
+
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:
66
+
67
+ ```javascript
68
+ import {MapElementFactory} from 'raain-ui';
69
+
70
+ // Create a map element
71
+ const mapElement = MapElementFactory.create({
72
+ container: 'map-container',
73
+ center: [51.505, -0.09],
74
+ zoom: 13
75
+ });
76
+
77
+ // Add a rainfall layer
78
+ mapElement.addRainfallLayer(rainfallData);
79
+ ```
80
+
81
+ ### 🔍 Example Application
82
+
83
+ The project includes a comprehensive example application that demonstrates how to use the library:
84
+
85
+ ```bash
86
+ # Clone the repository
87
+ git clone https://github.com/raainio/raain-ui.git
88
+ cd raain-ui
89
+
90
+ # Install dependencies and build the library
91
+ npm install
8
92
  npm run build
93
+
94
+ # Run the example
9
95
  cd example/
10
- npm start
96
+ npm start
11
97
  ```
12
- => http://localhost:1234
13
98
 
14
- ## History
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
+ ```
180
+
181
+ </details>
182
+
183
+ ## 📝 Changelog
184
+
185
+ See the [Changelog](./CHANGELOG.md) for a detailed list of changes in each version. Recent highlights include:
186
+
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
191
+
192
+ ## 👥 Contributing
193
+
194
+ Contributions are welcome! If you'd like to contribute to raain-ui, please follow these steps:
195
+
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
201
+
202
+ Please make sure your code follows the existing style and includes appropriate tests.
15
203
 
16
- See [Release notes](./RELEASE.md).
204
+ ## 📄 License
17
205
 
18
- ## License
19
- 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
  }