Skip to content

Commit 0629fd5

Browse files
committed
added linear guage
1 parent 1cb915c commit 0629fd5

11 files changed

Lines changed: 1584 additions & 11 deletions

File tree

CMakeLists.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,19 @@ if(WIN32)
3030
target_link_libraries(raylib_gauges winmm)
3131
endif()
3232

33+
# Build the linear gauge demo
34+
add_executable(raylib_lineargauge
35+
${CMAKE_CURRENT_SOURCE_DIR}/src/examples/lineargauge.cpp
36+
${CMAKE_CURRENT_SOURCE_DIR}/src/charts/RLLinearGauge.cpp
37+
)
38+
target_link_libraries(raylib_lineargauge
39+
raylib
40+
Threads::Threads
41+
)
42+
if(WIN32)
43+
target_link_libraries(raylib_lineargauge winmm)
44+
endif()
45+
3346
# Build the bubble chart demo
3447
add_executable(raylib_bubble
3548
${CMAKE_CURRENT_SOURCE_DIR}/src/examples/bubble.cpp
@@ -239,6 +252,7 @@ add_executable(raylib_all_charts
239252
${CMAKE_CURRENT_SOURCE_DIR}/src/charts/RLGauge.cpp
240253
${CMAKE_CURRENT_SOURCE_DIR}/src/charts/RLHeatMap.cpp
241254
${CMAKE_CURRENT_SOURCE_DIR}/src/charts/RLHeatMap3D.cpp
255+
${CMAKE_CURRENT_SOURCE_DIR}/src/charts/RLLinearGauge.cpp
242256
${CMAKE_CURRENT_SOURCE_DIR}/src/charts/RLOrderBookVis.cpp
243257
${CMAKE_CURRENT_SOURCE_DIR}/src/charts/RLPieChart.cpp
244258
${CMAKE_CURRENT_SOURCE_DIR}/src/charts/RLScatterPlot.cpp

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ Let's face it: there is no really simple C++ library for great-looking graphs. M
3030
- 🫧 **Bubble Charts** - Multi-dimensional data visualization
3131
- 🕯️ **Candlestick Charts** - Financial data visualization (OHLC)
3232
- 🌡️ **Gauges** - Circular and semi-circular gauge displays
33+
- 📏 **Linear Gauges** - Horizontal/vertical progress gauges with range bands and pointer styles
3334
- 🗺️ **Heat Maps** - Matrix data visualization with color gradients
3435
- 🏔️ **3D Heat Maps** - 3D surface visualization with palette-based coloring and smooth transitions
3536
- 📉 **Log-Log Plots** - Real-time streaming time series with Allan variance-style analysis and dynamic confidence intervals
@@ -76,6 +77,7 @@ For comprehensive documentation on each chart type, including full API reference
7677
| 🌡️ Gauge | Circular gauge displays | [RLGauge.md](docs/RLGauge.md) |
7778
| 🗺️ Heat Map | Matrix color visualization | [RLHeatMap.md](docs/RLHeatMap.md) |
7879
| 🏔️ 3D Heat Map | 3D surface visualization | [RLHeatMap3D.md](docs/RLHeatMap3D.md) |
80+
| 📏 Linear Gauge | Horizontal/vertical progress gauges | [RLLinearGauge.md](docs/RLLinearGauge.md) |
7981
| 📉 Log-Log Plot | Allan variance analysis | [RLLogPlot.md](docs/RLLogPlot.md) |
8082
| 📊 Order Book | DOM depth heatmap (2D/3D) | [RLOrderBookVis.md](docs/RLOrderBookVis.md) |
8183
| 🥧 Pie Chart | Pie and donut charts | [RLPieChart.md](docs/RLPieChart.md) |

docs/RLLinearGauge.md

Lines changed: 313 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,313 @@
1+
# RLLinearGauge
2+
3+
A horizontal or vertical linear gauge display for raylib with smooth animations.
4+
5+
## Features
6+
7+
- Horizontal and vertical orientations
8+
- Multiple pointer/indicator styles (fill bar, triangle, line marker)
9+
- Colored range bands (e.g., green/yellow/red zones)
10+
- Major and minor tick marks with labels
11+
- Target/goal marker line
12+
- Smooth animation to target values
13+
- Title and unit display
14+
- Customizable styling
15+
16+
## Constructor
17+
18+
```cpp
19+
RLLinearGauge(Rectangle aBounds, float aMinValue, float aMaxValue,
20+
RLLinearGaugeOrientation aOrientation = RLLinearGaugeOrientation::HORIZONTAL,
21+
const RLLinearGaugeStyle &aStyle = {});
22+
```
23+
24+
**Parameters:**
25+
- `aBounds` - The rectangle defining the gauge's position and size
26+
- `aMinValue` - Minimum value on the gauge scale
27+
- `aMaxValue` - Maximum value on the gauge scale
28+
- `aOrientation` - HORIZONTAL or VERTICAL orientation
29+
- `aStyle` - Optional style configuration
30+
31+
## Orientation
32+
33+
```cpp
34+
enum class RLLinearGaugeOrientation {
35+
HORIZONTAL, // Left-to-right gauge
36+
VERTICAL // Bottom-to-top gauge
37+
};
38+
```
39+
40+
## Pointer Styles
41+
42+
```cpp
43+
enum class RLLinearGaugePointerStyle {
44+
FILL_BAR, // Filled bar from min to current value (default)
45+
TRIANGLE, // Triangle pointer at current value
46+
LINE_MARKER // Line marker at current value
47+
};
48+
```
49+
50+
## Range Bands
51+
52+
```cpp
53+
struct RLLinearGaugeRangeBand {
54+
float mMin{0.0f}; // Start of the range
55+
float mMax{100.0f}; // End of the range
56+
Color mColor{GREEN}; // Color for this range
57+
};
58+
```
59+
60+
## Style Configuration
61+
62+
```cpp
63+
struct RLLinearGaugeStyle {
64+
// Track appearance
65+
Color mTrackColor{60, 60, 70, 255};
66+
Color mTrackBorderColor{80, 80, 90, 255};
67+
float mTrackThickness{24.0f};
68+
float mTrackBorderThickness{1.0f};
69+
float mCornerRadius{4.0f};
70+
71+
// Fill/indicator appearance
72+
Color mFillColor{0, 180, 255, 255};
73+
Color mPointerColor{255, 74, 74, 255};
74+
float mPointerSize{12.0f};
75+
76+
// Target marker appearance
77+
Color mTargetMarkerColor{255, 220, 80, 255};
78+
float mTargetMarkerThickness{3.0f};
79+
float mTargetMarkerLength{8.0f};
80+
81+
// Tick marks
82+
int mMajorTickCount{5};
83+
int mMinorTicksPerMajor{4};
84+
Color mMajorTickColor{220, 220, 230, 255};
85+
Color mMinorTickColor{150, 150, 160, 255};
86+
float mMajorTickLength{12.0f};
87+
float mMinorTickLength{6.0f};
88+
float mMajorTickThickness{2.0f};
89+
float mMinorTickThickness{1.0f};
90+
91+
// Labels
92+
Color mLabelColor{220, 220, 230, 255};
93+
Color mTitleColor{180, 190, 210, 255};
94+
Color mValueColor{255, 255, 255, 255};
95+
float mLabelFontSize{12.0f};
96+
float mTitleFontSize{16.0f};
97+
float mValueFontSize{18.0f};
98+
Font mLabelFont{};
99+
100+
// Layout padding
101+
float mPadding{10.0f};
102+
float mTickLabelGap{4.0f};
103+
104+
// Animation
105+
bool mSmoothAnimate{true};
106+
float mAnimateSpeed{10.0f};
107+
108+
// Display options
109+
bool mShowTicks{true};
110+
bool mShowTickLabels{true};
111+
bool mShowTitle{true};
112+
bool mShowValueText{true};
113+
bool mShowRangeBands{true};
114+
bool mShowTargetMarker{false};
115+
int mValueDecimals{1};
116+
117+
// Background
118+
Color mBackgroundColor{30, 30, 36, 255};
119+
bool mShowBackground{true};
120+
};
121+
```
122+
123+
## Methods
124+
125+
### Value Control
126+
127+
| Method | Description |
128+
|--------|-------------|
129+
| `setValue(float aValue)` | Set value immediately (no animation) |
130+
| `setTargetValue(float aValue)` | Set target value (animates to new value) |
131+
| `getValue() const` | Get current displayed value |
132+
| `getTargetValue() const` | Get target value |
133+
134+
### Configuration
135+
136+
| Method | Description |
137+
|--------|-------------|
138+
| `setRange(float aMinValue, float aMaxValue)` | Set the value range |
139+
| `setBounds(Rectangle aBounds)` | Set the gauge bounds |
140+
| `setOrientation(RLLinearGaugeOrientation aOrientation)` | Set horizontal/vertical orientation |
141+
| `setStyle(const RLLinearGaugeStyle &aStyle)` | Apply a style configuration |
142+
| `setPointerStyle(RLLinearGaugePointerStyle aStyle)` | Set pointer/indicator style |
143+
| `setAnimationEnabled(bool aEnabled)` | Enable/disable smooth animation |
144+
145+
### Tick Marks
146+
147+
| Method | Description |
148+
|--------|-------------|
149+
| `setTicks(int aMajorCount, int aMinorPerMajor)` | Configure tick mark counts |
150+
151+
### Labels
152+
153+
| Method | Description |
154+
|--------|-------------|
155+
| `setLabel(const std::string &aTitle)` | Set the gauge title |
156+
| `setUnit(const std::string &aUnit)` | Set the unit suffix (e.g., "°C", "%") |
157+
158+
### Range Bands
159+
160+
| Method | Description |
161+
|--------|-------------|
162+
| `setRanges(const std::vector<RLLinearGaugeRangeBand> &aRanges)` | Set colored range bands |
163+
| `clearRanges()` | Remove all range bands |
164+
165+
### Target Marker
166+
167+
| Method | Description |
168+
|--------|-------------|
169+
| `setTargetMarker(float aValue)` | Show target/goal marker at value |
170+
| `hideTargetMarker()` | Hide the target marker |
171+
172+
### Rendering
173+
174+
| Method | Description |
175+
|--------|-------------|
176+
| `update(float aDt)` | Update animations (call each frame with delta time) |
177+
| `draw() const` | Draw the gauge |
178+
179+
## Complete Example
180+
181+
```cpp
182+
#include "raylib.h"
183+
#include "RLLinearGauge.h"
184+
185+
int main() {
186+
InitWindow(800, 400, "Linear Gauge Example");
187+
SetTargetFPS(60);
188+
189+
// Create horizontal gauge
190+
Rectangle lHorizBounds = {50, 50, 300, 80};
191+
RLLinearGaugeStyle lStyle;
192+
lStyle.mBackgroundColor = Color{30, 30, 36, 255};
193+
lStyle.mTrackColor = Color{50, 55, 65, 255};
194+
lStyle.mFillColor = Color{80, 200, 120, 255};
195+
lStyle.mMajorTickCount = 10;
196+
lStyle.mMinorTicksPerMajor = 1;
197+
lStyle.mSmoothAnimate = true;
198+
199+
RLLinearGauge lHorizGauge(lHorizBounds, 0.0f, 100.0f,
200+
RLLinearGaugeOrientation::HORIZONTAL, lStyle);
201+
lHorizGauge.setLabel("Temperature");
202+
lHorizGauge.setUnit("°C");
203+
204+
// Add colored range bands
205+
std::vector<RLLinearGaugeRangeBand> lRanges = {
206+
{0.0f, 60.0f, Color{80, 200, 120, 255}}, // Green: Safe
207+
{60.0f, 80.0f, Color{255, 200, 80, 255}}, // Yellow: Warning
208+
{80.0f, 100.0f, Color{255, 80, 80, 255}} // Red: Danger
209+
};
210+
lHorizGauge.setRanges(lRanges);
211+
lHorizGauge.setTargetMarker(75.0f);
212+
lHorizGauge.setValue(45.0f);
213+
214+
// Create vertical gauge
215+
Rectangle lVertBounds = {450, 50, 100, 300};
216+
RLLinearGauge lVertGauge(lVertBounds, 0.0f, 100.0f,
217+
RLLinearGaugeOrientation::VERTICAL, lStyle);
218+
lVertGauge.setPointerStyle(RLLinearGaugePointerStyle::TRIANGLE);
219+
lVertGauge.setLabel("Level");
220+
lVertGauge.setUnit("%");
221+
lVertGauge.setValue(70.0f);
222+
223+
float lTimer = 0.0f;
224+
225+
while (!WindowShouldClose()) {
226+
float lDt = GetFrameTime();
227+
lTimer += lDt;
228+
229+
// Animate to random value every 2 seconds
230+
if (lTimer > 2.0f) {
231+
lTimer = 0.0f;
232+
lHorizGauge.setTargetValue((float)(rand() % 100));
233+
lVertGauge.setTargetValue((float)(rand() % 100));
234+
}
235+
236+
// Update animations
237+
lHorizGauge.update(lDt);
238+
lVertGauge.update(lDt);
239+
240+
BeginDrawing();
241+
ClearBackground(Color{20, 22, 28, 255});
242+
243+
lHorizGauge.draw();
244+
lVertGauge.draw();
245+
246+
EndDrawing();
247+
}
248+
249+
CloseWindow();
250+
return 0;
251+
}
252+
```
253+
254+
## Customizing Appearance
255+
256+
### Horizontal Progress Bar
257+
258+
```cpp
259+
RLLinearGaugeStyle lStyle;
260+
lStyle.mTrackThickness = 20.0f;
261+
lStyle.mCornerRadius = 10.0f; // Rounded ends
262+
lStyle.mShowTicks = false;
263+
lStyle.mShowTickLabels = false;
264+
lStyle.mFillColor = Color{100, 180, 255, 255};
265+
266+
RLLinearGauge lGauge(lBounds, 0.0f, 100.0f,
267+
RLLinearGaugeOrientation::HORIZONTAL, lStyle);
268+
```
269+
270+
### Vertical Thermometer Style
271+
272+
```cpp
273+
RLLinearGaugeStyle lStyle;
274+
lStyle.mTrackThickness = 16.0f;
275+
lStyle.mMajorTickCount = 10;
276+
lStyle.mMinorTicksPerMajor = 4;
277+
lStyle.mShowValueText = true;
278+
lStyle.mValueDecimals = 1;
279+
280+
RLLinearGauge lGauge(lBounds, -20.0f, 50.0f,
281+
RLLinearGaugeOrientation::VERTICAL, lStyle);
282+
lGauge.setLabel("Temperature");
283+
lGauge.setUnit("°C");
284+
```
285+
286+
### Dashboard Gauge with Zones
287+
288+
```cpp
289+
RLLinearGaugeStyle lStyle;
290+
lStyle.mTrackThickness = 24.0f;
291+
lStyle.mMajorTickCount = 5;
292+
lStyle.mMinorTicksPerMajor = 3;
293+
294+
RLLinearGauge lGauge(lBounds, 0.0f, 100.0f,
295+
RLLinearGaugeOrientation::HORIZONTAL, lStyle);
296+
lGauge.setPointerStyle(RLLinearGaugePointerStyle::TRIANGLE);
297+
298+
std::vector<RLLinearGaugeRangeBand> lRanges = {
299+
{0.0f, 50.0f, Color{80, 180, 255, 255}}, // Blue
300+
{50.0f, 80.0f, Color{255, 180, 80, 255}}, // Orange
301+
{80.0f, 100.0f, Color{255, 80, 100, 255}} // Red
302+
};
303+
lGauge.setRanges(lRanges);
304+
lGauge.setTargetMarker(75.0f); // Goal line
305+
```
306+
307+
## Performance Notes
308+
309+
- Tick positions are precomputed when geometry changes (bounds, range, or tick count)
310+
- Minimal per-frame allocations
311+
- Efficient raylib primitive drawing
312+
- Suitable for multiple gauges on screen simultaneously
313+

0 commit comments

Comments
 (0)