react-native-vroom-chart 0.15.0 → 0.17.0
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/cpp/VroomChartHostObject.cpp +252 -1
- package/cpp/_core_include/vroom/vroom_chart.h +178 -4
- package/cpp/_core_src/atr.cpp +67 -0
- package/cpp/_core_src/atr.h +44 -0
- package/cpp/_core_src/atr_pane.cpp +162 -0
- package/cpp/_core_src/atr_pane.h +48 -0
- package/cpp/_core_src/candles.cpp +15 -14
- package/cpp/_core_src/chart.cpp +758 -200
- package/cpp/_core_src/chart.h +221 -3
- package/cpp/_core_src/chart_facade.cpp +236 -23
- package/cpp/_core_src/color_lerp.h +28 -0
- package/cpp/_core_src/fair_value_gaps.cpp +76 -0
- package/cpp/_core_src/fair_value_gaps.h +54 -0
- package/cpp/_core_src/fvg_overlay.cpp +262 -0
- package/cpp/_core_src/fvg_overlay.h +43 -0
- package/cpp/_core_src/ichimoku.cpp +65 -0
- package/cpp/_core_src/ichimoku.h +45 -0
- package/cpp/_core_src/labels.cpp +3 -0
- package/cpp/_core_src/line_morph.h +159 -0
- package/cpp/_core_src/loading_line.cpp +183 -0
- package/cpp/_core_src/loading_line.h +38 -0
- package/cpp/_core_src/loading_wave.h +140 -0
- package/cpp/_core_src/ma_overlay.cpp +273 -45
- package/cpp/_core_src/ma_overlay.h +64 -2
- package/cpp/_core_src/macd.cpp +24 -1
- package/cpp/_core_src/macd.h +16 -0
- package/cpp/_core_src/macd_pane.cpp +71 -62
- package/cpp/_core_src/macd_pane.h +13 -1
- package/cpp/_core_src/pane_series.h +169 -0
- package/cpp/_core_src/price_indicator.cpp +21 -7
- package/cpp/_core_src/price_indicator.h +11 -1
- package/cpp/_core_src/price_indicator_anim.h +81 -0
- package/cpp/_core_src/rsi.cpp +4 -0
- package/cpp/_core_src/rsi.h +7 -0
- package/cpp/_core_src/rsi_pane.cpp +85 -29
- package/cpp/_core_src/rsi_pane.h +11 -1
- package/cpp/_core_src/theme.cpp +5 -0
- package/cpp/_core_src/tip_geometry.h +55 -0
- package/cpp/_core_src/viewport.h +68 -0
- package/lib/index.d.mts +281 -3
- package/lib/index.d.ts +281 -3
- package/lib/index.js +292 -14
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +292 -14
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/VroomChart.tsx +33 -3
- package/src/dataTransitions.ts +47 -0
- package/src/index.ts +5 -0
- package/src/jsi.d.ts +139 -1
- package/src/theme.ts +1 -0
- package/src/types.ts +5 -0
- package/src/useChartCore.ts +402 -8
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
#include "atr_pane.h"
|
|
2
|
+
|
|
3
|
+
#pragma clang diagnostic push
|
|
4
|
+
#pragma clang diagnostic ignored "-Wdocumentation"
|
|
5
|
+
#include "include/core/SkCanvas.h"
|
|
6
|
+
#include "include/core/SkColor.h"
|
|
7
|
+
#include "include/core/SkFont.h"
|
|
8
|
+
#include "include/core/SkFontTypes.h"
|
|
9
|
+
#include "include/core/SkPaint.h"
|
|
10
|
+
#include "include/core/SkPathBuilder.h"
|
|
11
|
+
#include "include/core/SkRect.h"
|
|
12
|
+
#include "include/core/SkTypeface.h"
|
|
13
|
+
#pragma clang diagnostic pop
|
|
14
|
+
|
|
15
|
+
#include <algorithm>
|
|
16
|
+
#include <cmath>
|
|
17
|
+
#include <cstdio>
|
|
18
|
+
#include <cstring>
|
|
19
|
+
|
|
20
|
+
#include "atr.h"
|
|
21
|
+
#include "chart.h"
|
|
22
|
+
#include "fonts.h"
|
|
23
|
+
#include "line_morph.h"
|
|
24
|
+
#include "pane_series.h"
|
|
25
|
+
#include "price_format.h"
|
|
26
|
+
#include "style_inherit.h"
|
|
27
|
+
#include "theme.h"
|
|
28
|
+
#include "viewport.h"
|
|
29
|
+
|
|
30
|
+
namespace vroom::atr_pane {
|
|
31
|
+
|
|
32
|
+
namespace {
|
|
33
|
+
using vroom::style::color_or;
|
|
34
|
+
using vroom::style::width_or;
|
|
35
|
+
|
|
36
|
+
constexpr SkColor kAtrLine = 0xff26a69a; // teal
|
|
37
|
+
constexpr SkColor kDivider = 0xff21262d; // pane separator
|
|
38
|
+
constexpr float kLineWidth = 1.5f;
|
|
39
|
+
} // namespace
|
|
40
|
+
|
|
41
|
+
void draw(SkCanvas* canvas,
|
|
42
|
+
const VroomChart& chart,
|
|
43
|
+
const Layout& lay,
|
|
44
|
+
const ::VroomCandle* visible,
|
|
45
|
+
std::size_t n,
|
|
46
|
+
const double* atr_visible,
|
|
47
|
+
int64_t window_ms,
|
|
48
|
+
int64_t visible_start_ms,
|
|
49
|
+
int64_t candle_duration_ms,
|
|
50
|
+
float candle_right,
|
|
51
|
+
float pane_top,
|
|
52
|
+
float pane_bottom,
|
|
53
|
+
const vroom::LineMorph* from,
|
|
54
|
+
float morph_t) {
|
|
55
|
+
if (!canvas || candle_right <= 0.f) return;
|
|
56
|
+
const float band_h = pane_bottom - pane_top;
|
|
57
|
+
if (band_h <= 0.f) return;
|
|
58
|
+
morph_t = std::clamp(morph_t, 0.f, 1.f);
|
|
59
|
+
// A fade's outgoing half has no new data at all, so the capture is the whole
|
|
60
|
+
// frame. Nothing on either side means nothing to paint, shell included.
|
|
61
|
+
if (n == 0 && vroom::morph_line_count(from, morph_t) == 0) return;
|
|
62
|
+
|
|
63
|
+
const VroomATR& cfg = chart.atr;
|
|
64
|
+
|
|
65
|
+
// ATR is strictly positive, so the domain runs 0..peak off the bottom edge.
|
|
66
|
+
// User y-zoom stretches it from there; 1.0 is the default fit.
|
|
67
|
+
const double scale = vroom::atr::autoscale(atr_visible, n);
|
|
68
|
+
auto y_for = [&](double v) -> float {
|
|
69
|
+
return pane_bottom -
|
|
70
|
+
static_cast<float>(
|
|
71
|
+
vroom::atr::band_fraction(v, scale, chart.atr_y_scale)) *
|
|
72
|
+
band_h;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
// The peak the label reports. Mid-morph it eases out of the fit the capture
|
|
76
|
+
// was taken against, so the number tracks the curve instead of jumping to
|
|
77
|
+
// the new resolution's peak on the first frame.
|
|
78
|
+
const double label_scale =
|
|
79
|
+
(from && morph_t < 1.f)
|
|
80
|
+
? from->scale + (scale - from->scale) * static_cast<double>(morph_t)
|
|
81
|
+
: scale;
|
|
82
|
+
|
|
83
|
+
// Mask the band (candles can overflow below the shortened price pane).
|
|
84
|
+
SkPaint bg;
|
|
85
|
+
bg.setColor(chart.theme.colors[VROOM_COLOR_BACKGROUND]);
|
|
86
|
+
canvas->drawRect(SkRect::MakeLTRB(0.f, pane_top, candle_right, pane_bottom),
|
|
87
|
+
bg);
|
|
88
|
+
|
|
89
|
+
// Pane separator (top edge).
|
|
90
|
+
SkPaint divider;
|
|
91
|
+
divider.setColor(kDivider);
|
|
92
|
+
divider.setStrokeWidth(1.f);
|
|
93
|
+
canvas->drawLine(0.f, pane_top, candle_right, pane_top, divider);
|
|
94
|
+
|
|
95
|
+
canvas->save();
|
|
96
|
+
canvas->clipRect(SkRect::MakeLTRB(0.f, pane_top, candle_right, pane_bottom));
|
|
97
|
+
|
|
98
|
+
if (atr_visible || from) {
|
|
99
|
+
SkPaint line;
|
|
100
|
+
line.setAntiAlias(true);
|
|
101
|
+
line.setColor(color_or(cfg.line_color, kAtrLine));
|
|
102
|
+
line.setStyle(SkPaint::kStroke_Style);
|
|
103
|
+
line.setStrokeWidth(width_or(cfg.line_width, kLineWidth));
|
|
104
|
+
canvas->drawPath(
|
|
105
|
+
vroom::pane_series::build_path(
|
|
106
|
+
lay, visible, n, atr_visible, window_ms, visible_start_ms,
|
|
107
|
+
candle_duration_ms, pane_top, pane_bottom, from, morph_t, y_for),
|
|
108
|
+
line);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Caption, top-left of the pane.
|
|
112
|
+
auto tf = vroom::axis_typeface();
|
|
113
|
+
if (tf) {
|
|
114
|
+
SkFont font(tf, chart.theme.floats[VROOM_FLOAT_AXIS_FONT_SIZE_PX]);
|
|
115
|
+
font.setSubpixel(true);
|
|
116
|
+
font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
|
|
117
|
+
char caption[24];
|
|
118
|
+
std::snprintf(caption, sizeof(caption), "ATR %d", cfg.period);
|
|
119
|
+
SkRect cb;
|
|
120
|
+
font.measureText(caption, std::strlen(caption), SkTextEncoding::kUTF8,
|
|
121
|
+
&cb);
|
|
122
|
+
SkPaint cap_paint;
|
|
123
|
+
cap_paint.setAntiAlias(true);
|
|
124
|
+
cap_paint.setColor(chart.theme.colors[VROOM_COLOR_AXIS_TEXT]);
|
|
125
|
+
canvas->drawString(caption, 6.f, pane_top + 4.f - cb.fTop, font,
|
|
126
|
+
cap_paint);
|
|
127
|
+
}
|
|
128
|
+
canvas->restore();
|
|
129
|
+
|
|
130
|
+
// Peak label in the y-axis strip — ATR is in price units, so it shares the
|
|
131
|
+
// price axis's formatting. Hidden with that strip.
|
|
132
|
+
if (tf && label_scale > 0.0 && lay.y_axis_opacity > 0.f) {
|
|
133
|
+
SkFont font(tf, chart.theme.floats[VROOM_FLOAT_AXIS_FONT_SIZE_PX]);
|
|
134
|
+
font.setSubpixel(true);
|
|
135
|
+
font.setEdging(SkFont::Edging::kSubpixelAntiAlias);
|
|
136
|
+
SkPaint text_paint;
|
|
137
|
+
text_paint.setAntiAlias(true);
|
|
138
|
+
text_paint.setColor(chart.theme.colors[VROOM_COLOR_AXIS_TEXT]);
|
|
139
|
+
text_paint.setAlphaf(text_paint.getAlphaf() * lay.y_axis_opacity);
|
|
140
|
+
char label[48];
|
|
141
|
+
vroom::format_price(label, sizeof(label), label_scale, chart.price_fmt);
|
|
142
|
+
SkRect tb;
|
|
143
|
+
const float tw = font.measureText(label, std::strlen(label),
|
|
144
|
+
SkTextEncoding::kUTF8, &tb);
|
|
145
|
+
const float axis_center_x = lay.width_px - lay.y_axis_width_px * 0.5f;
|
|
146
|
+
const float text_x = axis_center_x - tw * 0.5f;
|
|
147
|
+
// A series' own peak lands at the top of the padded band whatever the
|
|
148
|
+
// fit is, so the label's height doesn't move as the morph re-scales —
|
|
149
|
+
// only the number it reports does. Clamped into the band so a zoomed-in
|
|
150
|
+
// peak doesn't label another pane.
|
|
151
|
+
const float half_text = (tb.fBottom - tb.fTop) * 0.5f;
|
|
152
|
+
const float peak_y = std::clamp(
|
|
153
|
+
pane_bottom - static_cast<float>(vroom::atr::band_fraction(
|
|
154
|
+
label_scale, label_scale, chart.atr_y_scale)) *
|
|
155
|
+
band_h,
|
|
156
|
+
pane_top + half_text, pane_bottom - half_text);
|
|
157
|
+
const float baseline_y = peak_y - (tb.fTop + tb.fBottom) * 0.5f;
|
|
158
|
+
canvas->drawString(label, text_x, baseline_y, font, text_paint);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
} // namespace vroom::atr_pane
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// ATR indicator pane — draws the Average True Range line, its caption, and a
|
|
2
|
+
// peak label in the band below the candles. Its own module alongside
|
|
3
|
+
// rsi_pane / macd_pane so the chart orchestrator stays thin.
|
|
4
|
+
|
|
5
|
+
#pragma once
|
|
6
|
+
|
|
7
|
+
#include <cstddef>
|
|
8
|
+
#include <cstdint>
|
|
9
|
+
|
|
10
|
+
#include "vroom/vroom_chart.h" // ::VroomCandle
|
|
11
|
+
|
|
12
|
+
class SkCanvas;
|
|
13
|
+
|
|
14
|
+
namespace vroom {
|
|
15
|
+
struct Layout;
|
|
16
|
+
struct LineMorph;
|
|
17
|
+
} // namespace vroom
|
|
18
|
+
|
|
19
|
+
struct VroomChart;
|
|
20
|
+
|
|
21
|
+
namespace vroom::atr_pane {
|
|
22
|
+
|
|
23
|
+
// Draws the ATR pane spanning vertically [pane_top, pane_bottom]. `atr_visible`
|
|
24
|
+
// is the cached ATR series aligned with `visible` (NaN where undefined). ATR is
|
|
25
|
+
// strictly positive and unbounded, so the pane fits 0..peak anchored at its
|
|
26
|
+
// bottom edge rather than centering on a reference level.
|
|
27
|
+
//
|
|
28
|
+
// `from` / `morph_t` are the interval morph: the capture holds the curve's
|
|
29
|
+
// outgoing shape indexed from the right (slot 0 = newest), in fractions of the
|
|
30
|
+
// band, so the pane is free to re-fit across the switch without the shape
|
|
31
|
+
// moving. The peak label eases between the two fits. A fade's outgoing half
|
|
32
|
+
// passes n = 0 with morph_t = 0, which paints the capture alone.
|
|
33
|
+
void draw(SkCanvas* canvas,
|
|
34
|
+
const VroomChart& chart,
|
|
35
|
+
const Layout& lay,
|
|
36
|
+
const ::VroomCandle* visible,
|
|
37
|
+
std::size_t n,
|
|
38
|
+
const double* atr_visible,
|
|
39
|
+
int64_t window_ms,
|
|
40
|
+
int64_t visible_start_ms,
|
|
41
|
+
int64_t candle_duration_ms,
|
|
42
|
+
float candle_right,
|
|
43
|
+
float pane_top,
|
|
44
|
+
float pane_bottom,
|
|
45
|
+
const LineMorph* from = nullptr,
|
|
46
|
+
float morph_t = 1.f);
|
|
47
|
+
|
|
48
|
+
} // namespace vroom::atr_pane
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
#include <algorithm>
|
|
11
11
|
|
|
12
|
+
#include "color_lerp.h"
|
|
12
13
|
#include "theme.h"
|
|
13
14
|
#include "viewport.h"
|
|
14
15
|
|
|
@@ -21,18 +22,6 @@ inline uint32_t resolve_color(uint32_t color, uint32_t fill) {
|
|
|
21
22
|
return (color >> 24) == 0 ? fill : color;
|
|
22
23
|
}
|
|
23
24
|
|
|
24
|
-
// Channel-wise ARGB blend, for a candle that changes direction mid-morph.
|
|
25
|
-
inline uint32_t lerp_argb(uint32_t a, uint32_t b, float t) {
|
|
26
|
-
uint32_t out = 0;
|
|
27
|
-
for (int shift = 0; shift < 32; shift += 8) {
|
|
28
|
-
const float ca = static_cast<float>((a >> shift) & 0xFFu);
|
|
29
|
-
const float cb = static_cast<float>((b >> shift) & 0xFFu);
|
|
30
|
-
const auto v = static_cast<uint32_t>(ca + (cb - ca) * t + 0.5f);
|
|
31
|
-
out |= v << shift;
|
|
32
|
-
}
|
|
33
|
-
return out;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
25
|
inline uint32_t scale_alpha(uint32_t argb, float a) {
|
|
37
26
|
const auto alpha =
|
|
38
27
|
static_cast<uint32_t>(static_cast<float>((argb >> 24) & 0xFFu) * a + 0.5f);
|
|
@@ -90,6 +79,7 @@ void draw(SkCanvas* canvas,
|
|
|
90
79
|
|
|
91
80
|
const uint32_t fill_bull = theme.colors[VROOM_COLOR_BULL];
|
|
92
81
|
const uint32_t fill_bear = theme.colors[VROOM_COLOR_BEAR];
|
|
82
|
+
const uint32_t skeleton_color = theme.colors[VROOM_COLOR_SKELETON];
|
|
93
83
|
|
|
94
84
|
const float body_r = theme.floats[VROOM_FLOAT_CANDLE_RADIUS_PX];
|
|
95
85
|
const bool wick_round = theme.floats[VROOM_FLOAT_WICK_ROUND_CAP] > 0.5f;
|
|
@@ -207,10 +197,21 @@ void draw(SkCanvas* canvas,
|
|
|
207
197
|
bool draw_border = bull ? draw_border_bull : draw_border_bear;
|
|
208
198
|
|
|
209
199
|
const bool flip = frm && to && frm->bull != bull;
|
|
210
|
-
|
|
200
|
+
// A slot handed over from the loading skeleton starts grey, whatever its
|
|
201
|
+
// direction — so it takes the per-slot path from a different origin
|
|
202
|
+
// color than a flip does, and overrides it when both apply.
|
|
203
|
+
const bool from_skeleton = frm && to && frm->skeleton;
|
|
204
|
+
if (flip || from_skeleton || alpha < 0.999f) {
|
|
211
205
|
const auto blend = [&](uint32_t c_bull, uint32_t c_bear) {
|
|
212
206
|
uint32_t c = bull ? c_bull : c_bear;
|
|
213
|
-
if (
|
|
207
|
+
if (from_skeleton) {
|
|
208
|
+
// lerp_argb covers the alpha channel too, so the bar's
|
|
209
|
+
// opacity rides in on the same blend as its color.
|
|
210
|
+
c = lerp_argb(scale_alpha(skeleton_color, frm->skeleton_alpha),
|
|
211
|
+
c, morph_t);
|
|
212
|
+
} else if (flip) {
|
|
213
|
+
c = lerp_argb(bull ? c_bear : c_bull, c, morph_t);
|
|
214
|
+
}
|
|
214
215
|
return scale_alpha(c, alpha);
|
|
215
216
|
};
|
|
216
217
|
slot_wick = *wick_p;
|