react-native-vroom-chart 0.6.0 → 0.8.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 +281 -33
- package/cpp/_core_include/vroom/vroom_chart.h +231 -36
- package/cpp/_core_src/bollinger.h +1 -1
- package/cpp/_core_src/candles.cpp +138 -41
- package/cpp/_core_src/candles.h +11 -1
- package/cpp/_core_src/chart.cpp +91 -40
- package/cpp/_core_src/chart.h +69 -29
- package/cpp/_core_src/chart_facade.cpp +247 -69
- package/cpp/_core_src/drawings.cpp +147 -4
- package/cpp/_core_src/drawings.h +10 -5
- package/cpp/_core_src/gradient.cpp +46 -0
- package/cpp/_core_src/gradient.h +31 -0
- package/cpp/_core_src/labels.cpp +49 -16
- package/cpp/_core_src/labels.h +33 -4
- package/cpp/_core_src/liquidity.cpp +3 -37
- package/cpp/_core_src/ma_overlay.cpp +174 -12
- package/cpp/_core_src/ma_overlay.h +55 -3
- package/cpp/_core_src/macd.cpp +13 -42
- package/cpp/_core_src/macd.h +11 -8
- package/cpp/_core_src/macd_pane.cpp +57 -27
- package/cpp/_core_src/price_line_layout.h +1 -1
- package/cpp/_core_src/rsi.cpp +4 -18
- package/cpp/_core_src/rsi.h +6 -6
- package/cpp/_core_src/rsi_pane.cpp +34 -19
- package/cpp/_core_src/series_ma.cpp +64 -0
- package/cpp/_core_src/series_ma.h +30 -0
- package/cpp/_core_src/style_inherit.h +35 -0
- package/cpp/_core_src/theme.cpp +2 -1
- package/cpp/_core_src/viewport.cpp +36 -12
- package/cpp/_core_src/viewport.h +50 -0
- package/cpp/_core_src/volume.cpp +33 -8
- package/cpp/_core_src/volume.h +12 -1
- package/cpp/_core_src/volume_anim.cpp +32 -0
- package/cpp/_core_src/volume_anim.h +41 -0
- package/lib/index.d.mts +206 -31
- package/lib/index.d.ts +206 -31
- package/lib/index.js +324 -44
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +329 -52
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/VroomChart.tsx +100 -17
- package/src/dataTransitions.ts +148 -0
- package/src/easing.ts +40 -0
- package/src/index.ts +9 -0
- package/src/jsi.d.ts +126 -19
- package/src/theme.ts +1 -0
- package/src/types.ts +3 -0
- package/src/useChartCore.ts +273 -30
|
@@ -29,7 +29,7 @@ ChartHostObject::~ChartHostObject() {
|
|
|
29
29
|
std::vector<jsi::PropNameID> ChartHostObject::getPropertyNames(
|
|
30
30
|
jsi::Runtime& rt) {
|
|
31
31
|
std::vector<jsi::PropNameID> out;
|
|
32
|
-
out.reserve(
|
|
32
|
+
out.reserve(39);
|
|
33
33
|
out.push_back(jsi::PropNameID::forAscii(rt, "setCandles"));
|
|
34
34
|
out.push_back(jsi::PropNameID::forAscii(rt, "setSize"));
|
|
35
35
|
out.push_back(jsi::PropNameID::forAscii(rt, "setColor"));
|
|
@@ -38,6 +38,13 @@ std::vector<jsi::PropNameID> ChartHostObject::getPropertyNames(
|
|
|
38
38
|
out.push_back(jsi::PropNameID::forAscii(rt, "setDefaultCandleWidth"));
|
|
39
39
|
out.push_back(jsi::PropNameID::forAscii(rt, "setChartType"));
|
|
40
40
|
out.push_back(jsi::PropNameID::forAscii(rt, "setMorph"));
|
|
41
|
+
out.push_back(jsi::PropNameID::forAscii(rt, "getVisibleRange"));
|
|
42
|
+
out.push_back(jsi::PropNameID::forAscii(rt, "resetView"));
|
|
43
|
+
out.push_back(jsi::PropNameID::forAscii(rt, "resetPriceScale"));
|
|
44
|
+
out.push_back(jsi::PropNameID::forAscii(rt, "getVisiblePriceEnvelope"));
|
|
45
|
+
out.push_back(jsi::PropNameID::forAscii(rt, "preservePriceEnvelope"));
|
|
46
|
+
out.push_back(jsi::PropNameID::forAscii(rt, "beginIntervalMorph"));
|
|
47
|
+
out.push_back(jsi::PropNameID::forAscii(rt, "setIntervalMorph"));
|
|
41
48
|
out.push_back(jsi::PropNameID::forAscii(rt, "pan"));
|
|
42
49
|
out.push_back(jsi::PropNameID::forAscii(rt, "translate"));
|
|
43
50
|
out.push_back(jsi::PropNameID::forAscii(rt, "zoom"));
|
|
@@ -54,6 +61,8 @@ std::vector<jsi::PropNameID> ChartHostObject::getPropertyNames(
|
|
|
54
61
|
out.push_back(jsi::PropNameID::forAscii(rt, "setOverlays"));
|
|
55
62
|
out.push_back(jsi::PropNameID::forAscii(rt, "setVWAP"));
|
|
56
63
|
out.push_back(jsi::PropNameID::forAscii(rt, "setBollinger"));
|
|
64
|
+
out.push_back(jsi::PropNameID::forAscii(rt, "setVolume"));
|
|
65
|
+
out.push_back(jsi::PropNameID::forAscii(rt, "setVolumeCollapse"));
|
|
57
66
|
out.push_back(jsi::PropNameID::forAscii(rt, "coordAt"));
|
|
58
67
|
out.push_back(jsi::PropNameID::forAscii(rt, "setPriceLines"));
|
|
59
68
|
out.push_back(jsi::PropNameID::forAscii(rt, "hitTestPriceLine"));
|
|
@@ -295,6 +304,129 @@ jsi::Value ChartHostObject::get(jsi::Runtime& rt,
|
|
|
295
304
|
});
|
|
296
305
|
}
|
|
297
306
|
|
|
307
|
+
if (name == "getVisibleRange") {
|
|
308
|
+
// getVisibleRange() -> { startMs, endMs }. Both 0 while uninitialized.
|
|
309
|
+
return jsi::Function::createFromHostFunction(
|
|
310
|
+
rt,
|
|
311
|
+
jsi::PropNameID::forAscii(rt, "getVisibleRange"),
|
|
312
|
+
0,
|
|
313
|
+
[this](jsi::Runtime& rt2,
|
|
314
|
+
const jsi::Value& /*thisVal*/,
|
|
315
|
+
const jsi::Value* /*args*/,
|
|
316
|
+
size_t /*count*/) -> jsi::Value {
|
|
317
|
+
int64_t s = 0, e = 0;
|
|
318
|
+
vroom_chart_get_visible_range(chart_, &s, &e);
|
|
319
|
+
jsi::Object obj(rt2);
|
|
320
|
+
obj.setProperty(rt2, "startMs", static_cast<double>(s));
|
|
321
|
+
obj.setProperty(rt2, "endMs", static_cast<double>(e));
|
|
322
|
+
return obj;
|
|
323
|
+
});
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
if (name == "resetView") {
|
|
327
|
+
// resetView() — reframe the most recent candles and re-enable y auto-fit.
|
|
328
|
+
return jsi::Function::createFromHostFunction(
|
|
329
|
+
rt,
|
|
330
|
+
jsi::PropNameID::forAscii(rt, "resetView"),
|
|
331
|
+
0,
|
|
332
|
+
[this](jsi::Runtime& /*rt2*/,
|
|
333
|
+
const jsi::Value& /*thisVal*/,
|
|
334
|
+
const jsi::Value* /*args*/,
|
|
335
|
+
size_t /*count*/) -> jsi::Value {
|
|
336
|
+
vroom_chart_reset_view(chart_);
|
|
337
|
+
return jsi::Value::undefined();
|
|
338
|
+
});
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
if (name == "resetPriceScale") {
|
|
342
|
+
// resetPriceScale() — re-enable y auto-fit, leaving the time window alone.
|
|
343
|
+
return jsi::Function::createFromHostFunction(
|
|
344
|
+
rt,
|
|
345
|
+
jsi::PropNameID::forAscii(rt, "resetPriceScale"),
|
|
346
|
+
0,
|
|
347
|
+
[this](jsi::Runtime& /*rt2*/,
|
|
348
|
+
const jsi::Value& /*thisVal*/,
|
|
349
|
+
const jsi::Value* /*args*/,
|
|
350
|
+
size_t /*count*/) -> jsi::Value {
|
|
351
|
+
vroom_chart_reset_price_scale(chart_);
|
|
352
|
+
return jsi::Value::undefined();
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
if (name == "getVisiblePriceEnvelope") {
|
|
357
|
+
// getVisiblePriceEnvelope() -> { low, high } | null. The extent the visible
|
|
358
|
+
// candles occupy, not the (wider) axis range. No rendering.
|
|
359
|
+
return jsi::Function::createFromHostFunction(
|
|
360
|
+
rt,
|
|
361
|
+
jsi::PropNameID::forAscii(rt, "getVisiblePriceEnvelope"),
|
|
362
|
+
0,
|
|
363
|
+
[this](jsi::Runtime& rt2,
|
|
364
|
+
const jsi::Value& /*thisVal*/,
|
|
365
|
+
const jsi::Value* /*args*/,
|
|
366
|
+
size_t /*count*/) -> jsi::Value {
|
|
367
|
+
double low = 0.0, high = 0.0;
|
|
368
|
+
if (!vroom_chart_get_visible_price_envelope(chart_, &low, &high)) {
|
|
369
|
+
return jsi::Value::null();
|
|
370
|
+
}
|
|
371
|
+
jsi::Object obj(rt2);
|
|
372
|
+
obj.setProperty(rt2, "low", low);
|
|
373
|
+
obj.setProperty(rt2, "high", high);
|
|
374
|
+
return obj;
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (name == "preservePriceEnvelope") {
|
|
379
|
+
// preservePriceEnvelope(prevLow, prevHigh) — scale-lock a manual price
|
|
380
|
+
// range across a timeframe switch. No-op in auto-y mode.
|
|
381
|
+
return jsi::Function::createFromHostFunction(
|
|
382
|
+
rt,
|
|
383
|
+
jsi::PropNameID::forAscii(rt, "preservePriceEnvelope"),
|
|
384
|
+
2,
|
|
385
|
+
[this](jsi::Runtime& /*rt2*/,
|
|
386
|
+
const jsi::Value& /*thisVal*/,
|
|
387
|
+
const jsi::Value* args,
|
|
388
|
+
size_t count) -> jsi::Value {
|
|
389
|
+
if (count < 2) return jsi::Value::undefined();
|
|
390
|
+
vroom_chart_preserve_price_envelope(chart_, args[0].asNumber(),
|
|
391
|
+
args[1].asNumber());
|
|
392
|
+
return jsi::Value::undefined();
|
|
393
|
+
});
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
if (name == "beginIntervalMorph") {
|
|
397
|
+
// beginIntervalMorph() — capture the visible candle geometry so the next
|
|
398
|
+
// setCandles can be animated as a reshape. Call before setCandles.
|
|
399
|
+
return jsi::Function::createFromHostFunction(
|
|
400
|
+
rt,
|
|
401
|
+
jsi::PropNameID::forAscii(rt, "beginIntervalMorph"),
|
|
402
|
+
0,
|
|
403
|
+
[this](jsi::Runtime& /*rt2*/,
|
|
404
|
+
const jsi::Value& /*thisVal*/,
|
|
405
|
+
const jsi::Value* /*args*/,
|
|
406
|
+
size_t /*count*/) -> jsi::Value {
|
|
407
|
+
vroom_chart_begin_interval_morph(chart_);
|
|
408
|
+
return jsi::Value::undefined();
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
if (name == "setIntervalMorph") {
|
|
413
|
+
// setIntervalMorph(t) — advance the capture toward the new candles. `t` is
|
|
414
|
+
// pre-eased progress: 0 = the captured frame, 1 = settled (capture freed).
|
|
415
|
+
return jsi::Function::createFromHostFunction(
|
|
416
|
+
rt,
|
|
417
|
+
jsi::PropNameID::forAscii(rt, "setIntervalMorph"),
|
|
418
|
+
1,
|
|
419
|
+
[this](jsi::Runtime& /*rt2*/,
|
|
420
|
+
const jsi::Value& /*thisVal*/,
|
|
421
|
+
const jsi::Value* args,
|
|
422
|
+
size_t count) -> jsi::Value {
|
|
423
|
+
if (count < 1) return jsi::Value::undefined();
|
|
424
|
+
vroom_chart_set_interval_morph(
|
|
425
|
+
chart_, static_cast<float>(args[0].asNumber()));
|
|
426
|
+
return jsi::Value::undefined();
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
|
|
298
430
|
if (name == "pan") {
|
|
299
431
|
// pan(dx, dy) -> JsiSkPicture
|
|
300
432
|
// Mutates the visible range and renders in one JSI call so gesture
|
|
@@ -519,46 +651,106 @@ jsi::Value ChartHostObject::get(jsi::Runtime& rt,
|
|
|
519
651
|
}
|
|
520
652
|
|
|
521
653
|
if (name == "setRSI") {
|
|
522
|
-
// setRSI(enabled, period, upperBand, lowerBand,
|
|
523
|
-
//
|
|
654
|
+
// setRSI({enabled, period, upperBand, lowerBand, maPeriod, maKind,
|
|
655
|
+
// maVisible, lineColor, lineWidth, lineVisible, maColor, maWidth,
|
|
656
|
+
// bandColor, bandsVisible}) — configures the RSI pane. No render; the next
|
|
657
|
+
// render() picks it up.
|
|
524
658
|
return jsi::Function::createFromHostFunction(
|
|
525
659
|
rt,
|
|
526
660
|
jsi::PropNameID::forAscii(rt, "setRSI"),
|
|
527
|
-
|
|
528
|
-
[this](jsi::Runtime&
|
|
661
|
+
1,
|
|
662
|
+
[this](jsi::Runtime& rt2,
|
|
529
663
|
const jsi::Value& /*thisVal*/,
|
|
530
664
|
const jsi::Value* args,
|
|
531
665
|
size_t count) -> jsi::Value {
|
|
532
|
-
if (count <
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
666
|
+
if (count < 1 || !args[0].isObject()) return jsi::Value::undefined();
|
|
667
|
+
auto s = args[0].asObject(rt2);
|
|
668
|
+
VroomRSI cfg{};
|
|
669
|
+
cfg.enabled = s.getProperty(rt2, "enabled").asBool() ? 1 : 0;
|
|
670
|
+
cfg.period = static_cast<int32_t>(
|
|
671
|
+
s.getProperty(rt2, "period").asNumber());
|
|
672
|
+
cfg.upper_band = s.getProperty(rt2, "upperBand").asNumber();
|
|
673
|
+
cfg.lower_band = s.getProperty(rt2, "lowerBand").asNumber();
|
|
674
|
+
cfg.ma_period = static_cast<int32_t>(
|
|
675
|
+
s.getProperty(rt2, "maPeriod").asNumber());
|
|
676
|
+
cfg.ma_kind = static_cast<int32_t>(
|
|
677
|
+
s.getProperty(rt2, "maKind").asNumber());
|
|
678
|
+
cfg.ma_visible = s.getProperty(rt2, "maVisible").asBool() ? 1 : 0;
|
|
679
|
+
cfg.line_color = static_cast<uint32_t>(
|
|
680
|
+
s.getProperty(rt2, "lineColor").asNumber());
|
|
681
|
+
cfg.line_width = static_cast<float>(
|
|
682
|
+
s.getProperty(rt2, "lineWidth").asNumber());
|
|
683
|
+
cfg.line_visible = s.getProperty(rt2, "lineVisible").asBool() ? 1 : 0;
|
|
684
|
+
cfg.ma_color = static_cast<uint32_t>(
|
|
685
|
+
s.getProperty(rt2, "maColor").asNumber());
|
|
686
|
+
cfg.ma_width = static_cast<float>(
|
|
687
|
+
s.getProperty(rt2, "maWidth").asNumber());
|
|
688
|
+
cfg.band_color = static_cast<uint32_t>(
|
|
689
|
+
s.getProperty(rt2, "bandColor").asNumber());
|
|
690
|
+
cfg.bands_visible =
|
|
691
|
+
s.getProperty(rt2, "bandsVisible").asBool() ? 1 : 0;
|
|
692
|
+
vroom_chart_set_rsi(chart_, &cfg);
|
|
541
693
|
return jsi::Value::undefined();
|
|
542
694
|
});
|
|
543
695
|
}
|
|
544
696
|
|
|
545
697
|
if (name == "setMACD") {
|
|
546
|
-
// setMACD(enabled, fast, slow, signal
|
|
547
|
-
//
|
|
698
|
+
// setMACD({enabled, fast, slow, signal, source, maKind, signalMaKind,
|
|
699
|
+
// lineColor, lineWidth, lineVisible, signalColor, signalWidth,
|
|
700
|
+
// signalVisible, histVisible, histUpColor, histUpFadingColor,
|
|
701
|
+
// histDownColor, histDownFadingColor, zeroColor, zeroVisible}) — configures
|
|
702
|
+
// the MACD pane. No render; the next render() picks it up.
|
|
548
703
|
return jsi::Function::createFromHostFunction(
|
|
549
704
|
rt,
|
|
550
705
|
jsi::PropNameID::forAscii(rt, "setMACD"),
|
|
551
|
-
|
|
552
|
-
[this](jsi::Runtime&
|
|
706
|
+
1,
|
|
707
|
+
[this](jsi::Runtime& rt2,
|
|
553
708
|
const jsi::Value& /*thisVal*/,
|
|
554
709
|
const jsi::Value* args,
|
|
555
710
|
size_t count) -> jsi::Value {
|
|
556
|
-
if (count <
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
711
|
+
if (count < 1 || !args[0].isObject()) return jsi::Value::undefined();
|
|
712
|
+
auto s = args[0].asObject(rt2);
|
|
713
|
+
VroomMACD cfg{};
|
|
714
|
+
cfg.enabled = s.getProperty(rt2, "enabled").asBool() ? 1 : 0;
|
|
715
|
+
cfg.fast = static_cast<int32_t>(
|
|
716
|
+
s.getProperty(rt2, "fast").asNumber());
|
|
717
|
+
cfg.slow = static_cast<int32_t>(
|
|
718
|
+
s.getProperty(rt2, "slow").asNumber());
|
|
719
|
+
cfg.signal = static_cast<int32_t>(
|
|
720
|
+
s.getProperty(rt2, "signal").asNumber());
|
|
721
|
+
cfg.source = static_cast<int32_t>(
|
|
722
|
+
s.getProperty(rt2, "source").asNumber());
|
|
723
|
+
cfg.ma_kind = static_cast<int32_t>(
|
|
724
|
+
s.getProperty(rt2, "maKind").asNumber());
|
|
725
|
+
cfg.signal_ma_kind = static_cast<int32_t>(
|
|
726
|
+
s.getProperty(rt2, "signalMaKind").asNumber());
|
|
727
|
+
cfg.line_color = static_cast<uint32_t>(
|
|
728
|
+
s.getProperty(rt2, "lineColor").asNumber());
|
|
729
|
+
cfg.line_width = static_cast<float>(
|
|
730
|
+
s.getProperty(rt2, "lineWidth").asNumber());
|
|
731
|
+
cfg.line_visible =
|
|
732
|
+
s.getProperty(rt2, "lineVisible").asBool() ? 1 : 0;
|
|
733
|
+
cfg.signal_color = static_cast<uint32_t>(
|
|
734
|
+
s.getProperty(rt2, "signalColor").asNumber());
|
|
735
|
+
cfg.signal_width = static_cast<float>(
|
|
736
|
+
s.getProperty(rt2, "signalWidth").asNumber());
|
|
737
|
+
cfg.signal_visible =
|
|
738
|
+
s.getProperty(rt2, "signalVisible").asBool() ? 1 : 0;
|
|
739
|
+
cfg.hist_visible =
|
|
740
|
+
s.getProperty(rt2, "histVisible").asBool() ? 1 : 0;
|
|
741
|
+
cfg.hist_up_color = static_cast<uint32_t>(
|
|
742
|
+
s.getProperty(rt2, "histUpColor").asNumber());
|
|
743
|
+
cfg.hist_up_fading_color = static_cast<uint32_t>(
|
|
744
|
+
s.getProperty(rt2, "histUpFadingColor").asNumber());
|
|
745
|
+
cfg.hist_down_color = static_cast<uint32_t>(
|
|
746
|
+
s.getProperty(rt2, "histDownColor").asNumber());
|
|
747
|
+
cfg.hist_down_fading_color = static_cast<uint32_t>(
|
|
748
|
+
s.getProperty(rt2, "histDownFadingColor").asNumber());
|
|
749
|
+
cfg.zero_color = static_cast<uint32_t>(
|
|
750
|
+
s.getProperty(rt2, "zeroColor").asNumber());
|
|
751
|
+
cfg.zero_visible =
|
|
752
|
+
s.getProperty(rt2, "zeroVisible").asBool() ? 1 : 0;
|
|
753
|
+
vroom_chart_set_macd(chart_, &cfg);
|
|
562
754
|
return jsi::Value::undefined();
|
|
563
755
|
});
|
|
564
756
|
}
|
|
@@ -602,21 +794,26 @@ jsi::Value ChartHostObject::get(jsi::Runtime& rt,
|
|
|
602
794
|
}
|
|
603
795
|
|
|
604
796
|
if (name == "setVWAP") {
|
|
605
|
-
// setVWAP(enabled, resetOffsetMin, color, width) — session VWAP overlay.
|
|
797
|
+
// setVWAP({enabled, resetOffsetMin, color, width}) — session VWAP overlay.
|
|
606
798
|
return jsi::Function::createFromHostFunction(
|
|
607
799
|
rt,
|
|
608
800
|
jsi::PropNameID::forAscii(rt, "setVWAP"),
|
|
609
|
-
|
|
610
|
-
[this](jsi::Runtime&
|
|
801
|
+
1,
|
|
802
|
+
[this](jsi::Runtime& rt2,
|
|
611
803
|
const jsi::Value& /*thisVal*/,
|
|
612
804
|
const jsi::Value* args,
|
|
613
805
|
size_t count) -> jsi::Value {
|
|
614
|
-
if (count <
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
806
|
+
if (count < 1 || !args[0].isObject()) return jsi::Value::undefined();
|
|
807
|
+
auto s = args[0].asObject(rt2);
|
|
808
|
+
VroomVWAP cfg{};
|
|
809
|
+
cfg.enabled = s.getProperty(rt2, "enabled").asBool() ? 1 : 0;
|
|
810
|
+
cfg.reset_offset_min = static_cast<int32_t>(
|
|
811
|
+
s.getProperty(rt2, "resetOffsetMin").asNumber());
|
|
812
|
+
cfg.color = static_cast<uint32_t>(
|
|
813
|
+
s.getProperty(rt2, "color").asNumber());
|
|
814
|
+
cfg.width = static_cast<float>(
|
|
815
|
+
s.getProperty(rt2, "width").asNumber());
|
|
816
|
+
vroom_chart_set_vwap(chart_, &cfg);
|
|
620
817
|
return jsi::Value::undefined();
|
|
621
818
|
});
|
|
622
819
|
}
|
|
@@ -667,6 +864,57 @@ jsi::Value ChartHostObject::get(jsi::Runtime& rt,
|
|
|
667
864
|
});
|
|
668
865
|
}
|
|
669
866
|
|
|
867
|
+
if (name == "setVolume") {
|
|
868
|
+
// setVolume({enabled, heightFrac, opacity, radiusPx, upColor, downColor})
|
|
869
|
+
// — the volume bars. Negative floats / zero colors inherit the theme. No
|
|
870
|
+
// render; the next render() picks it up.
|
|
871
|
+
return jsi::Function::createFromHostFunction(
|
|
872
|
+
rt,
|
|
873
|
+
jsi::PropNameID::forAscii(rt, "setVolume"),
|
|
874
|
+
1,
|
|
875
|
+
[this](jsi::Runtime& rt2,
|
|
876
|
+
const jsi::Value& /*thisVal*/,
|
|
877
|
+
const jsi::Value* args,
|
|
878
|
+
size_t count) -> jsi::Value {
|
|
879
|
+
if (count < 1 || !args[0].isObject()) return jsi::Value::undefined();
|
|
880
|
+
auto s = args[0].asObject(rt2);
|
|
881
|
+
VroomVolume cfg{};
|
|
882
|
+
cfg.enabled = s.getProperty(rt2, "enabled").asBool() ? 1 : 0;
|
|
883
|
+
cfg.height_frac = static_cast<float>(
|
|
884
|
+
s.getProperty(rt2, "heightFrac").asNumber());
|
|
885
|
+
cfg.opacity = static_cast<float>(
|
|
886
|
+
s.getProperty(rt2, "opacity").asNumber());
|
|
887
|
+
cfg.radius_px = static_cast<float>(
|
|
888
|
+
s.getProperty(rt2, "radiusPx").asNumber());
|
|
889
|
+
cfg.up_color = static_cast<uint32_t>(
|
|
890
|
+
s.getProperty(rt2, "upColor").asNumber());
|
|
891
|
+
cfg.down_color = static_cast<uint32_t>(
|
|
892
|
+
s.getProperty(rt2, "downColor").asNumber());
|
|
893
|
+
vroom_chart_set_volume(chart_, &cfg);
|
|
894
|
+
return jsi::Value::undefined();
|
|
895
|
+
});
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
if (name == "setVolumeCollapse") {
|
|
899
|
+
// setVolumeCollapse(t, easing) — staggered collapse of the volume bars. `t`
|
|
900
|
+
// is LINEAR progress; the core eases each bar over its own window.
|
|
901
|
+
return jsi::Function::createFromHostFunction(
|
|
902
|
+
rt,
|
|
903
|
+
jsi::PropNameID::forAscii(rt, "setVolumeCollapse"),
|
|
904
|
+
2,
|
|
905
|
+
[this](jsi::Runtime& /*rt2*/,
|
|
906
|
+
const jsi::Value& /*thisVal*/,
|
|
907
|
+
const jsi::Value* args,
|
|
908
|
+
size_t count) -> jsi::Value {
|
|
909
|
+
if (count < 2) return jsi::Value::undefined();
|
|
910
|
+
vroom_chart_set_volume_collapse(
|
|
911
|
+
chart_,
|
|
912
|
+
static_cast<float>(args[0].asNumber()),
|
|
913
|
+
static_cast<int32_t>(args[1].asNumber()));
|
|
914
|
+
return jsi::Value::undefined();
|
|
915
|
+
});
|
|
916
|
+
}
|
|
917
|
+
|
|
670
918
|
if (name == "coordAt") {
|
|
671
919
|
// coordAt(x, y) -> { timeMs, price } | null. The continuous data coordinate
|
|
672
920
|
// at a pixel — not snapped to a candle slot. Null when there are no candles
|