rte-utils 1.2.1 → 1.2.3
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/README.md +121 -13
- package/dist/components/Histogram.d.ts +10 -0
- package/dist/index.css +1 -1
- package/dist/index.esm.css +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -84,6 +84,106 @@ function EnergyDashboard() {
|
|
|
84
84
|
}
|
|
85
85
|
```
|
|
86
86
|
|
|
87
|
+
### Horizontal Orientation Example
|
|
88
|
+
|
|
89
|
+
```tsx
|
|
90
|
+
import React from 'react';
|
|
91
|
+
import { Histogram } from 'rte-utils';
|
|
92
|
+
import 'rte-utils/dist/index.css';
|
|
93
|
+
|
|
94
|
+
function HorizontalChart() {
|
|
95
|
+
return (
|
|
96
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '1rem' }}>
|
|
97
|
+
<Histogram
|
|
98
|
+
max={{ value: 100, color: "#D3D64E" }}
|
|
99
|
+
relative={{ value: 75, color: "#C0C402" }}
|
|
100
|
+
barWidth={200} // This becomes height in horizontal mode
|
|
101
|
+
barHeight={24} // This becomes width in horizontal mode
|
|
102
|
+
orientation="horizontal"
|
|
103
|
+
>
|
|
104
|
+
<div className="histogram-value-container">
|
|
105
|
+
<p className="histogram-value">75</p>
|
|
106
|
+
<p className="histogram-unit">%</p>
|
|
107
|
+
</div>
|
|
108
|
+
<div>
|
|
109
|
+
<p className="histogram-label">Progress</p>
|
|
110
|
+
</div>
|
|
111
|
+
</Histogram>
|
|
112
|
+
</div>
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### Custom Corner Radius Example
|
|
118
|
+
|
|
119
|
+
```tsx
|
|
120
|
+
import React from 'react';
|
|
121
|
+
import { Histogram } from 'rte-utils';
|
|
122
|
+
import 'rte-utils/dist/index.css';
|
|
123
|
+
|
|
124
|
+
function CustomCornerChart() {
|
|
125
|
+
return (
|
|
126
|
+
<div style={{ display: 'flex', gap: '1rem' }}>
|
|
127
|
+
{/* Rounded top corners only */}
|
|
128
|
+
<Histogram
|
|
129
|
+
max={{ value: 100, color: "#E0E0E0" }}
|
|
130
|
+
relative={{ value: 60, color: "#4CAF50" }}
|
|
131
|
+
barWidth={32}
|
|
132
|
+
barHeight={120}
|
|
133
|
+
cornerRadius={{ topLeft: 16, topRight: 16, bottomLeft: 0, bottomRight: 0 }}
|
|
134
|
+
/>
|
|
135
|
+
|
|
136
|
+
{/* Fully rounded corners */}
|
|
137
|
+
<Histogram
|
|
138
|
+
max={{ value: 100, color: "#F0F0F0", opacity: 0.5 }}
|
|
139
|
+
relative={{ value: 80, color: "#2196F3" }}
|
|
140
|
+
barWidth={32}
|
|
141
|
+
barHeight={120}
|
|
142
|
+
cornerRadius={{ topLeft: 16, topRight: 16, bottomLeft: 16, bottomRight: 16 }}
|
|
143
|
+
/>
|
|
144
|
+
|
|
145
|
+
{/* Asymmetric corners */}
|
|
146
|
+
<Histogram
|
|
147
|
+
max={{ value: 100, color: "#FFECB3" }}
|
|
148
|
+
relative={{ value: 45, color: "#FF9800" }}
|
|
149
|
+
barWidth={32}
|
|
150
|
+
barHeight={120}
|
|
151
|
+
cornerRadius={{ topLeft: 20, topRight: 4, bottomLeft: 4, bottomRight: 20 }}
|
|
152
|
+
/>
|
|
153
|
+
</div>
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### Opacity and Advanced Styling Example
|
|
159
|
+
|
|
160
|
+
```tsx
|
|
161
|
+
import React from 'react';
|
|
162
|
+
import { Histogram } from 'rte-utils';
|
|
163
|
+
import 'rte-utils/dist/index.css';
|
|
164
|
+
|
|
165
|
+
function AdvancedStylingChart() {
|
|
166
|
+
return (
|
|
167
|
+
<Histogram
|
|
168
|
+
max={{ value: 100, color: "#000000", opacity: 0.1 }}
|
|
169
|
+
relative={{ value: 65, color: "#E91E63" }}
|
|
170
|
+
barWidth={40}
|
|
171
|
+
barHeight={150}
|
|
172
|
+
orientation="vertical"
|
|
173
|
+
cornerRadius={{ topLeft: 8, topRight: 8, bottomLeft: 4, bottomRight: 4 }}
|
|
174
|
+
>
|
|
175
|
+
<div className="histogram-value-container">
|
|
176
|
+
<p className="histogram-value">65</p>
|
|
177
|
+
<p className="histogram-unit">kW</p>
|
|
178
|
+
</div>
|
|
179
|
+
<div>
|
|
180
|
+
<p className="histogram-label">Power Usage</p>
|
|
181
|
+
</div>
|
|
182
|
+
</Histogram>
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
```
|
|
186
|
+
|
|
87
187
|
## Components
|
|
88
188
|
|
|
89
189
|
### Histogram
|
|
@@ -94,20 +194,25 @@ A histogram component with smooth animations for energy data visualization.
|
|
|
94
194
|
|
|
95
195
|
| Prop | Type | Required | Default | Description |
|
|
96
196
|
|------|------|----------|---------|-------------|
|
|
97
|
-
| `max` | `{ value: number; color: string }` | ✅ | - | Maximum value configuration with value and
|
|
197
|
+
| `max` | `{ value: number; color: string; opacity?: number }` | ✅ | - | Maximum value configuration with value, color, and optional opacity |
|
|
98
198
|
| `relative` | `{ value: number; color: string }` | ✅ | - | Relative/current value configuration with value and color |
|
|
99
199
|
| `barHeight` | `number` | ❌ | `103` | Height of the histogram bar in pixels |
|
|
100
200
|
| `barWidth` | `number` | ❌ | `32` | Width of the histogram bar in pixels |
|
|
201
|
+
| `orientation` | `'vertical' \| 'horizontal'` | ❌ | `'vertical'` | Orientation of the histogram bars |
|
|
202
|
+
| `cornerRadius` | `{ topLeft?: number; topRight?: number; bottomLeft?: number; bottomRight?: number }` | ❌ | `{ topLeft: 2, topRight: 2, bottomLeft: 2, bottomRight: 2 }` | Individual corner radius configuration |
|
|
101
203
|
| `children` | `React.ReactNode` | ❌ | - | Child components (typically text content) |
|
|
102
204
|
|
|
103
205
|
#### Features
|
|
104
206
|
|
|
105
|
-
- **Smooth animations**:
|
|
106
|
-
- **
|
|
207
|
+
- **Smooth animations**: 1-second Chart.js-style transitions with easeOutQuart easing
|
|
208
|
+
- **Multiple orientations**: Support for both vertical and horizontal layouts
|
|
209
|
+
- **Individual corner control**: Customize each corner radius independently
|
|
107
210
|
- **Dynamic two-color visualization**:
|
|
108
211
|
- Background bar color defined by `max.color` represents the maximum value
|
|
109
212
|
- Foreground bar color defined by `relative.color` represents the relative value
|
|
110
|
-
- **
|
|
213
|
+
- **Opacity control**: Optional opacity setting for background bars
|
|
214
|
+
- **Smart corner rendering**: Foreground bars intelligently apply corner radii based on fill level
|
|
215
|
+
- **Customizable**: Colors, dimensions, orientations, and styling options
|
|
111
216
|
- **TypeScript support**: Full type definitions included
|
|
112
217
|
|
|
113
218
|
## Styling
|
|
@@ -120,15 +225,18 @@ import 'rte-utils/dist/index.css';
|
|
|
120
225
|
|
|
121
226
|
You can override the default styles by targeting the CSS classes:
|
|
122
227
|
|
|
123
|
-
- `.histogram-container`
|
|
124
|
-
- `.histogram-
|
|
125
|
-
- `.histogram-
|
|
126
|
-
- `.histogram-
|
|
127
|
-
- `.histogram-
|
|
128
|
-
- `.histogram-
|
|
129
|
-
- `.histogram-
|
|
130
|
-
- `.histogram-
|
|
131
|
-
- `.histogram-
|
|
228
|
+
- `.histogram-container` - Main container
|
|
229
|
+
- `.histogram-container--horizontal` - Horizontal layout modifier
|
|
230
|
+
- `.histogram-content` - Content wrapper
|
|
231
|
+
- `.histogram-content--horizontal` - Horizontal content modifier
|
|
232
|
+
- `.histogram-bar` - Bar container
|
|
233
|
+
- `.histogram-svg` - SVG element
|
|
234
|
+
- `.histogram-text-container` - Text content container
|
|
235
|
+
- `.histogram-text-container--horizontal` - Horizontal text layout modifier
|
|
236
|
+
- `.histogram-value-container` - Value display wrapper
|
|
237
|
+
- `.histogram-value` - Main value text
|
|
238
|
+
- `.histogram-unit` - Unit text
|
|
239
|
+
- `.histogram-label` - Label text
|
|
132
240
|
|
|
133
241
|
## License
|
|
134
242
|
|
|
@@ -5,6 +5,7 @@ interface HistogramProps {
|
|
|
5
5
|
max: {
|
|
6
6
|
value: number;
|
|
7
7
|
color: string;
|
|
8
|
+
opacity?: number;
|
|
8
9
|
};
|
|
9
10
|
/** Relative/current value configuration with value and color */
|
|
10
11
|
relative: {
|
|
@@ -15,6 +16,15 @@ interface HistogramProps {
|
|
|
15
16
|
barHeight?: number;
|
|
16
17
|
/** Width of the histogram bar in pixels */
|
|
17
18
|
barWidth?: number;
|
|
19
|
+
/** Orientation of the histogram - 'vertical' or 'horizontal' */
|
|
20
|
+
orientation?: 'vertical' | 'horizontal';
|
|
21
|
+
/** Corner radius configuration for individual corners */
|
|
22
|
+
cornerRadius?: {
|
|
23
|
+
topLeft?: number;
|
|
24
|
+
topRight?: number;
|
|
25
|
+
bottomLeft?: number;
|
|
26
|
+
bottomRight?: number;
|
|
27
|
+
};
|
|
18
28
|
/** Child components (typically text content) */
|
|
19
29
|
children?: React.ReactNode;
|
|
20
30
|
}
|
package/dist/index.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600&display=swap");*{font-family:Open Sans,sans-serif}.histogram-container{
|
|
1
|
+
@import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600&display=swap");*{font-family:Open Sans,sans-serif}.histogram-container{height:auto;max-width:54px;position:relative}.histogram-container--horizontal{max-width:none;width:auto}.histogram-content{align-items:center;display:flex;flex-direction:column;gap:8px;width:100%}.histogram-content--horizontal{align-items:center;flex-direction:row;height:100%}.histogram-bar{position:relative}.histogram-svg{display:block}.histogram-text-container{align-items:center;display:flex;flex-direction:column;gap:0;width:100%}.histogram-text-container--horizontal{align-items:flex-start;margin-left:8px}.histogram-value-container{text-align:center;width:40px}.histogram-value{font-size:16px;line-height:14px}.histogram-unit,.histogram-value{color:#000;display:block;font-weight:600;margin:0}.histogram-unit{font-size:12px}.histogram-label{color:#6f6f6f;font-size:12px;font-style:normal;font-weight:400;line-height:18px;margin:0;text-align:left;white-space:nowrap}
|
package/dist/index.esm.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
@import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600&display=swap");*{font-family:Open Sans,sans-serif}.histogram-container{
|
|
1
|
+
@import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;600&display=swap");*{font-family:Open Sans,sans-serif}.histogram-container{height:auto;max-width:54px;position:relative}.histogram-container--horizontal{max-width:none;width:auto}.histogram-content{align-items:center;display:flex;flex-direction:column;gap:8px;width:100%}.histogram-content--horizontal{align-items:center;flex-direction:row;height:100%}.histogram-bar{position:relative}.histogram-svg{display:block}.histogram-text-container{align-items:center;display:flex;flex-direction:column;gap:0;width:100%}.histogram-text-container--horizontal{align-items:flex-start;margin-left:8px}.histogram-value-container{text-align:center;width:40px}.histogram-value{font-size:16px;line-height:14px}.histogram-unit,.histogram-value{color:#000;display:block;font-weight:600;margin:0}.histogram-unit{font-size:12px}.histogram-label{color:#6f6f6f;font-size:12px;font-style:normal;font-weight:400;line-height:18px;margin:0;text-align:left;white-space:nowrap}
|
package/dist/index.esm.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsx as
|
|
1
|
+
import{jsx as t,jsxs as o}from"react/jsx-runtime";import{useState as a,useEffect as n}from"react";var c=function(c){var i,e,r,h,l=c.max,m=c.relative,g=c.barHeight,p=void 0===g?103:g,f=c.barWidth,v=void 0===f?32:f,s=c.orientation,d=void 0===s?"vertical":s,L=c.cornerRadius,b=c.children,R=a(0),u=R[0],z=R[1],x=a(0),w=x[0],M=x[1],N=Math.min(m.value/l.value*100,100)/100*p,Q=Math.min(m.value/l.value*100,100)/100*v;n(function(){z(0),M(0);var t=Date.now(),o=function(){var a=Date.now()-t,n=Math.min(a/1e3,1),c=1-Math.pow(1-n,4);z(N*c),M(Q*c),n<1&&requestAnimationFrame(o)};requestAnimationFrame(o)},[N,Q]);var y="horizontal"===d?p:v,q="horizontal"===d?v:p,A="horizontal"===d?p:v,D="horizontal"===d?v:p,F=function(t,o,a,n,c){var i=c.topLeft,e=c.topRight,r=c.bottomLeft,h=c.bottomRight;return"\n M ".concat(t+i," ").concat(o,"\n L ").concat(t+a-e," ").concat(o,"\n Q ").concat(t+a," ").concat(o," ").concat(t+a," ").concat(o+e,"\n L ").concat(t+a," ").concat(o+n-h,"\n Q ").concat(t+a," ").concat(o+n," ").concat(t+a-h," ").concat(o+n,"\n L ").concat(t+r," ").concat(o+n,"\n Q ").concat(t," ").concat(o+n," ").concat(t," ").concat(o+n-r,"\n L ").concat(t," ").concat(o+i,"\n Q ").concat(t," ").concat(o," ").concat(t+i," ").concat(o,"\n Z\n ").trim().replace(/\s+/g," ")},j={topLeft:2,topRight:2,bottomLeft:2,bottomRight:2},B=L?{topLeft:null!==(i=L.topLeft)&&void 0!==i?i:j.topLeft,topRight:null!==(e=L.topRight)&&void 0!==e?e:j.topRight,bottomLeft:null!==(r=L.bottomLeft)&&void 0!==r?r:j.bottomLeft,bottomRight:null!==(h=L.bottomRight)&&void 0!==h?h:j.bottomRight}:j;return t("div",{className:"histogram-container ".concat("horizontal"===d?"histogram-container--horizontal":""),children:o("div",{className:"histogram-content ".concat("horizontal"===d?"histogram-content--horizontal":""),children:[t("div",{className:"histogram-bar",style:{height:"".concat(q,"px"),width:"".concat(y,"px")},children:o("svg",{width:A,height:D,viewBox:"0 0 ".concat(A," ").concat(D),className:"histogram-svg",children:[t("path",{d:F(0,0,A,D,B),fill:l.color,fillOpacity:l.opacity||1}),t("path","vertical"===d?{d:F(0,D-u,A,u,{topLeft:u>=D?B.topLeft:0,topRight:u>=D?B.topRight:0,bottomLeft:B.bottomLeft,bottomRight:B.bottomRight}),fill:m.color}:{d:F(0,0,w,D,{topLeft:B.topLeft,topRight:w>=A?B.topRight:0,bottomLeft:B.bottomLeft,bottomRight:w>=A?B.bottomRight:0}),fill:m.color})]})}),b&&t("div",{className:"histogram-text-container ".concat("horizontal"===d?"histogram-text-container--horizontal":""),children:b})]})})};export{c as Histogram};
|
|
2
2
|
//# sourceMappingURL=index.esm.js.map
|
package/dist/index.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.esm.js","sources":["../src/components/Histogram.tsx"],"sourcesContent":["import React, { useEffect, useState
|
|
1
|
+
{"version":3,"file":"index.esm.js","sources":["../src/components/Histogram.tsx"],"sourcesContent":["import React, { useEffect, useState } from \"react\";\nimport \"./Histogram.css\";\n\ninterface HistogramProps {\n /** Maximum value configuration with value and color */\n max: {\n value: number;\n color: string;\n opacity?: number;\n };\n /** Relative/current value configuration with value and color */\n relative: {\n value: number;\n color: string;\n };\n /** Height of the histogram bar in pixels */\n barHeight?: number;\n /** Width of the histogram bar in pixels */\n barWidth?: number;\n /** Orientation of the histogram - 'vertical' or 'horizontal' */\n orientation?: 'vertical' | 'horizontal';\n /** Corner radius configuration for individual corners */\n cornerRadius?: {\n topLeft?: number;\n topRight?: number;\n bottomLeft?: number;\n bottomRight?: number;\n };\n /** Child components (typically text content) */\n children?: React.ReactNode;\n}\n\nexport const Histogram: React.FC<HistogramProps> = ({\n max,\n relative,\n barHeight = 103,\n barWidth = 32,\n orientation = 'vertical',\n cornerRadius,\n children,\n}) => {\n const [animatedHeight, setAnimatedHeight] = useState(0);\n const [animatedWidth, setAnimatedWidth] = useState(0);\n\n // Calculate target dimensions based on orientation\n const targetHeight = (Math.min((relative.value / max.value) * 100, 100) / 100) * barHeight;\n const targetWidth = (Math.min((relative.value / max.value) * 100, 100) / 100) * barWidth;\n\n // Simple Chart.js-like animation: always animate from 0 to target\n useEffect(() => {\n setAnimatedHeight(0);\n setAnimatedWidth(0);\n \n const startTime = Date.now();\n const duration = 1000;\n\n const animate = () => {\n const elapsed = Date.now() - startTime;\n const progress = Math.min(elapsed / duration, 1);\n\n // Chart.js-like easing (easeOutQuart)\n const easeOutQuart = 1 - Math.pow(1 - progress, 4);\n \n setAnimatedHeight(targetHeight * easeOutQuart);\n setAnimatedWidth(targetWidth * easeOutQuart);\n\n if (progress < 1) {\n requestAnimationFrame(animate);\n }\n };\n\n requestAnimationFrame(animate);\n }, [targetHeight, targetWidth]);\n\n const displayWidth = orientation === 'horizontal' ? barHeight : barWidth;\n const displayHeight = orientation === 'horizontal' ? barWidth : barHeight;\n const svgWidth = orientation === 'horizontal' ? barHeight : barWidth;\n const svgHeight = orientation === 'horizontal' ? barWidth : barHeight;\n\n // Helper function to create rounded rectangle path\n const createRoundedRectPath = (\n x: number,\n y: number,\n width: number,\n height: number,\n radii: { topLeft: number; topRight: number; bottomLeft: number; bottomRight: number }\n ) => {\n const { topLeft, topRight, bottomLeft, bottomRight } = radii;\n \n return `\n M ${x + topLeft} ${y}\n L ${x + width - topRight} ${y}\n Q ${x + width} ${y} ${x + width} ${y + topRight}\n L ${x + width} ${y + height - bottomRight}\n Q ${x + width} ${y + height} ${x + width - bottomRight} ${y + height}\n L ${x + bottomLeft} ${y + height}\n Q ${x} ${y + height} ${x} ${y + height - bottomLeft}\n L ${x} ${y + topLeft}\n Q ${x} ${y} ${x + topLeft} ${y}\n Z\n `.trim().replace(/\\s+/g, ' ');\n };\n\n // Default corner radius values\n const defaultCornerRadius = { topLeft: 2, topRight: 2, bottomLeft: 2, bottomRight: 2 };\n const corners = cornerRadius ? {\n topLeft: cornerRadius.topLeft ?? defaultCornerRadius.topLeft,\n topRight: cornerRadius.topRight ?? defaultCornerRadius.topRight,\n bottomLeft: cornerRadius.bottomLeft ?? defaultCornerRadius.bottomLeft,\n bottomRight: cornerRadius.bottomRight ?? defaultCornerRadius.bottomRight,\n } : defaultCornerRadius;\n\n return (\n <div className={`histogram-container ${orientation === 'horizontal' ? 'histogram-container--horizontal' : ''}`}>\n <div className={`histogram-content ${orientation === 'horizontal' ? 'histogram-content--horizontal' : ''}`}>\n <div \n className=\"histogram-bar\"\n style={{\n height: `${displayHeight}px`,\n width: `${displayWidth}px`\n }}\n >\n <svg\n width={svgWidth}\n height={svgHeight}\n viewBox={`0 0 ${svgWidth} ${svgHeight}`}\n className=\"histogram-svg\"\n >\n {/* Background bar (max value) */}\n <path\n d={createRoundedRectPath(0, 0, svgWidth, svgHeight, corners)}\n fill={max.color}\n fillOpacity={max.opacity || 1}\n />\n {/* Foreground bar (relative value) with animation */}\n {orientation === 'vertical' ? (\n <path\n d={createRoundedRectPath(\n 0,\n svgHeight - animatedHeight,\n svgWidth,\n animatedHeight,\n {\n topLeft: animatedHeight >= svgHeight ? corners.topLeft : 0,\n topRight: animatedHeight >= svgHeight ? corners.topRight : 0,\n bottomLeft: corners.bottomLeft,\n bottomRight: corners.bottomRight,\n }\n )}\n fill={relative.color}\n />\n ) : (\n <path\n d={createRoundedRectPath(\n 0,\n 0,\n animatedWidth,\n svgHeight,\n {\n topLeft: corners.topLeft,\n topRight: animatedWidth >= svgWidth ? corners.topRight : 0,\n bottomLeft: corners.bottomLeft,\n bottomRight: animatedWidth >= svgWidth ? corners.bottomRight : 0,\n }\n )}\n fill={relative.color}\n />\n )}\n </svg>\n </div>\n {children && (\n <div className={`histogram-text-container ${orientation === 'horizontal' ? 'histogram-text-container--horizontal' : ''}`}>\n {children}\n </div>\n )}\n </div>\n </div>\n );\n};\n"],"names":["Histogram","_a","max","relative","_f","barHeight","_g","barWidth","_h","orientation","cornerRadius","children","_j","useState","animatedHeight","setAnimatedHeight","_k","animatedWidth","setAnimatedWidth","targetHeight","Math","min","value","targetWidth","useEffect","startTime","Date","now","animate","elapsed","progress","easeOutQuart","pow","requestAnimationFrame","displayWidth","displayHeight","svgWidth","svgHeight","createRoundedRectPath","x","y","width","height","radii","topLeft","topRight","bottomLeft","bottomRight","concat","trim","replace","defaultCornerRadius","corners","_b","_c","_d","_e","_jsx","className","_jsxs","style","viewBox","d","fill","color","fillOpacity","opacity"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var t=require("react/jsx-runtime"),o=require("react");exports.Histogram=function(a){var c,n,i,e,r=a.max,h=a.relative,l=a.barHeight,s=void 0===l?103:l,m=a.barWidth,g=void 0===m?32:m,f=a.orientation,p=void 0===f?"vertical":f,v=a.cornerRadius,d=a.children,u=o.useState(0),L=u[0],b=u[1],R=o.useState(0),x=R[0],z=R[1],j=Math.min(h.value/r.value*100,100)/100*s,w=Math.min(h.value/r.value*100,100)/100*g;o.useEffect(function(){b(0),z(0);var t=Date.now(),o=function(){var a=Date.now()-t,c=Math.min(a/1e3,1),n=1-Math.pow(1-c,4);b(j*n),z(w*n),c<1&&requestAnimationFrame(o)};requestAnimationFrame(o)},[j,w]);var M="horizontal"===p?s:g,N="horizontal"===p?g:s,q="horizontal"===p?s:g,Q="horizontal"===p?g:s,y=function(t,o,a,c,n){var i=n.topLeft,e=n.topRight,r=n.bottomLeft,h=n.bottomRight;return"\n M ".concat(t+i," ").concat(o,"\n L ").concat(t+a-e," ").concat(o,"\n Q ").concat(t+a," ").concat(o," ").concat(t+a," ").concat(o+e,"\n L ").concat(t+a," ").concat(o+c-h,"\n Q ").concat(t+a," ").concat(o+c," ").concat(t+a-h," ").concat(o+c,"\n L ").concat(t+r," ").concat(o+c,"\n Q ").concat(t," ").concat(o+c," ").concat(t," ").concat(o+c-r,"\n L ").concat(t," ").concat(o+i,"\n Q ").concat(t," ").concat(o," ").concat(t+i," ").concat(o,"\n Z\n ").trim().replace(/\s+/g," ")},A={topLeft:2,topRight:2,bottomLeft:2,bottomRight:2},D=v?{topLeft:null!==(c=v.topLeft)&&void 0!==c?c:A.topLeft,topRight:null!==(n=v.topRight)&&void 0!==n?n:A.topRight,bottomLeft:null!==(i=v.bottomLeft)&&void 0!==i?i:A.bottomLeft,bottomRight:null!==(e=v.bottomRight)&&void 0!==e?e:A.bottomRight}:A;return t.jsx("div",{className:"histogram-container ".concat("horizontal"===p?"histogram-container--horizontal":""),children:t.jsxs("div",{className:"histogram-content ".concat("horizontal"===p?"histogram-content--horizontal":""),children:[t.jsx("div",{className:"histogram-bar",style:{height:"".concat(N,"px"),width:"".concat(M,"px")},children:t.jsxs("svg",{width:q,height:Q,viewBox:"0 0 ".concat(q," ").concat(Q),className:"histogram-svg",children:[t.jsx("path",{d:y(0,0,q,Q,D),fill:r.color,fillOpacity:r.opacity||1}),"vertical"===p?t.jsx("path",{d:y(0,Q-L,q,L,{topLeft:L>=Q?D.topLeft:0,topRight:L>=Q?D.topRight:0,bottomLeft:D.bottomLeft,bottomRight:D.bottomRight}),fill:h.color}):t.jsx("path",{d:y(0,0,x,Q,{topLeft:D.topLeft,topRight:x>=q?D.topRight:0,bottomLeft:D.bottomLeft,bottomRight:x>=q?D.bottomRight:0}),fill:h.color})]})}),d&&t.jsx("div",{className:"histogram-text-container ".concat("horizontal"===p?"histogram-text-container--horizontal":""),children:d})]})})};
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/components/Histogram.tsx"],"sourcesContent":["import React, { useEffect, useState
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/components/Histogram.tsx"],"sourcesContent":["import React, { useEffect, useState } from \"react\";\nimport \"./Histogram.css\";\n\ninterface HistogramProps {\n /** Maximum value configuration with value and color */\n max: {\n value: number;\n color: string;\n opacity?: number;\n };\n /** Relative/current value configuration with value and color */\n relative: {\n value: number;\n color: string;\n };\n /** Height of the histogram bar in pixels */\n barHeight?: number;\n /** Width of the histogram bar in pixels */\n barWidth?: number;\n /** Orientation of the histogram - 'vertical' or 'horizontal' */\n orientation?: 'vertical' | 'horizontal';\n /** Corner radius configuration for individual corners */\n cornerRadius?: {\n topLeft?: number;\n topRight?: number;\n bottomLeft?: number;\n bottomRight?: number;\n };\n /** Child components (typically text content) */\n children?: React.ReactNode;\n}\n\nexport const Histogram: React.FC<HistogramProps> = ({\n max,\n relative,\n barHeight = 103,\n barWidth = 32,\n orientation = 'vertical',\n cornerRadius,\n children,\n}) => {\n const [animatedHeight, setAnimatedHeight] = useState(0);\n const [animatedWidth, setAnimatedWidth] = useState(0);\n\n // Calculate target dimensions based on orientation\n const targetHeight = (Math.min((relative.value / max.value) * 100, 100) / 100) * barHeight;\n const targetWidth = (Math.min((relative.value / max.value) * 100, 100) / 100) * barWidth;\n\n // Simple Chart.js-like animation: always animate from 0 to target\n useEffect(() => {\n setAnimatedHeight(0);\n setAnimatedWidth(0);\n \n const startTime = Date.now();\n const duration = 1000;\n\n const animate = () => {\n const elapsed = Date.now() - startTime;\n const progress = Math.min(elapsed / duration, 1);\n\n // Chart.js-like easing (easeOutQuart)\n const easeOutQuart = 1 - Math.pow(1 - progress, 4);\n \n setAnimatedHeight(targetHeight * easeOutQuart);\n setAnimatedWidth(targetWidth * easeOutQuart);\n\n if (progress < 1) {\n requestAnimationFrame(animate);\n }\n };\n\n requestAnimationFrame(animate);\n }, [targetHeight, targetWidth]);\n\n const displayWidth = orientation === 'horizontal' ? barHeight : barWidth;\n const displayHeight = orientation === 'horizontal' ? barWidth : barHeight;\n const svgWidth = orientation === 'horizontal' ? barHeight : barWidth;\n const svgHeight = orientation === 'horizontal' ? barWidth : barHeight;\n\n // Helper function to create rounded rectangle path\n const createRoundedRectPath = (\n x: number,\n y: number,\n width: number,\n height: number,\n radii: { topLeft: number; topRight: number; bottomLeft: number; bottomRight: number }\n ) => {\n const { topLeft, topRight, bottomLeft, bottomRight } = radii;\n \n return `\n M ${x + topLeft} ${y}\n L ${x + width - topRight} ${y}\n Q ${x + width} ${y} ${x + width} ${y + topRight}\n L ${x + width} ${y + height - bottomRight}\n Q ${x + width} ${y + height} ${x + width - bottomRight} ${y + height}\n L ${x + bottomLeft} ${y + height}\n Q ${x} ${y + height} ${x} ${y + height - bottomLeft}\n L ${x} ${y + topLeft}\n Q ${x} ${y} ${x + topLeft} ${y}\n Z\n `.trim().replace(/\\s+/g, ' ');\n };\n\n // Default corner radius values\n const defaultCornerRadius = { topLeft: 2, topRight: 2, bottomLeft: 2, bottomRight: 2 };\n const corners = cornerRadius ? {\n topLeft: cornerRadius.topLeft ?? defaultCornerRadius.topLeft,\n topRight: cornerRadius.topRight ?? defaultCornerRadius.topRight,\n bottomLeft: cornerRadius.bottomLeft ?? defaultCornerRadius.bottomLeft,\n bottomRight: cornerRadius.bottomRight ?? defaultCornerRadius.bottomRight,\n } : defaultCornerRadius;\n\n return (\n <div className={`histogram-container ${orientation === 'horizontal' ? 'histogram-container--horizontal' : ''}`}>\n <div className={`histogram-content ${orientation === 'horizontal' ? 'histogram-content--horizontal' : ''}`}>\n <div \n className=\"histogram-bar\"\n style={{\n height: `${displayHeight}px`,\n width: `${displayWidth}px`\n }}\n >\n <svg\n width={svgWidth}\n height={svgHeight}\n viewBox={`0 0 ${svgWidth} ${svgHeight}`}\n className=\"histogram-svg\"\n >\n {/* Background bar (max value) */}\n <path\n d={createRoundedRectPath(0, 0, svgWidth, svgHeight, corners)}\n fill={max.color}\n fillOpacity={max.opacity || 1}\n />\n {/* Foreground bar (relative value) with animation */}\n {orientation === 'vertical' ? (\n <path\n d={createRoundedRectPath(\n 0,\n svgHeight - animatedHeight,\n svgWidth,\n animatedHeight,\n {\n topLeft: animatedHeight >= svgHeight ? corners.topLeft : 0,\n topRight: animatedHeight >= svgHeight ? corners.topRight : 0,\n bottomLeft: corners.bottomLeft,\n bottomRight: corners.bottomRight,\n }\n )}\n fill={relative.color}\n />\n ) : (\n <path\n d={createRoundedRectPath(\n 0,\n 0,\n animatedWidth,\n svgHeight,\n {\n topLeft: corners.topLeft,\n topRight: animatedWidth >= svgWidth ? corners.topRight : 0,\n bottomLeft: corners.bottomLeft,\n bottomRight: animatedWidth >= svgWidth ? corners.bottomRight : 0,\n }\n )}\n fill={relative.color}\n />\n )}\n </svg>\n </div>\n {children && (\n <div className={`histogram-text-container ${orientation === 'horizontal' ? 'histogram-text-container--horizontal' : ''}`}>\n {children}\n </div>\n )}\n </div>\n </div>\n );\n};\n"],"names":["_a","max","relative","_f","barHeight","_g","barWidth","_h","orientation","cornerRadius","children","_j","useState","animatedHeight","setAnimatedHeight","_k","animatedWidth","setAnimatedWidth","targetHeight","Math","min","value","targetWidth","useEffect","startTime","Date","now","animate","elapsed","progress","easeOutQuart","pow","requestAnimationFrame","displayWidth","displayHeight","svgWidth","svgHeight","createRoundedRectPath","x","y","width","height","radii","topLeft","topRight","bottomLeft","bottomRight","concat","trim","replace","defaultCornerRadius","corners","_b","_c","_d","_e","_jsx","jsx","className","_jsxs","style","viewBox","d","fill","color","fillOpacity","opacity"],"mappings":"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"}
|