react-native-vroom-chart 0.12.0 → 0.13.1
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/android/CMakeLists.txt +8 -0
- package/android/README.md +11 -10
- package/cpp/VroomChartHostObject.cpp +140 -47
- package/cpp/VroomChartHostObject.h +1 -1
- package/cpp/VroomJsiInstaller.cpp +1 -1
- package/cpp/_core_src/price_format.cpp +55 -4
- package/cpp/_core_src/price_format.h +32 -5
- package/lib/index.js +62 -32
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +71 -34
- package/lib/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/VroomChart.tsx +92 -43
- package/src/jsi.d.ts +12 -9
- package/src/useChartCore.ts +4 -5
package/lib/index.js
CHANGED
|
@@ -514,6 +514,9 @@ function useChartCore(candles, size, visibleRange, defaultCandleWidth, chartType
|
|
|
514
514
|
}
|
|
515
515
|
|
|
516
516
|
// src/VroomChart.tsx
|
|
517
|
+
function isSkImage(frame) {
|
|
518
|
+
return typeof frame.getImageInfo === "function";
|
|
519
|
+
}
|
|
517
520
|
function VroomChart(props) {
|
|
518
521
|
const {
|
|
519
522
|
candles,
|
|
@@ -565,17 +568,38 @@ function VroomChart(props) {
|
|
|
565
568
|
rec.beginRecording(import_react_native_skia.Skia.XYWHRect(0, 0, 1, 1));
|
|
566
569
|
return rec.finishRecordingAsPicture();
|
|
567
570
|
}, []);
|
|
571
|
+
const emptyImage = (0, import_react2.useMemo)(() => {
|
|
572
|
+
const data = import_react_native_skia.Skia.Data.fromBytes(new Uint8Array(4));
|
|
573
|
+
return import_react_native_skia.Skia.Image.MakeImage(
|
|
574
|
+
{
|
|
575
|
+
width: 1,
|
|
576
|
+
height: 1,
|
|
577
|
+
colorType: import_react_native_skia.ColorType.RGBA_8888,
|
|
578
|
+
alphaType: import_react_native_skia.AlphaType.Premul
|
|
579
|
+
},
|
|
580
|
+
data,
|
|
581
|
+
4
|
|
582
|
+
);
|
|
583
|
+
}, []);
|
|
568
584
|
const pictureSV = (0, import_react_native_reanimated.useSharedValue)(emptyPicture);
|
|
585
|
+
const imageSV = (0, import_react_native_reanimated.useSharedValue)(emptyImage);
|
|
586
|
+
const applyFrame = (0, import_react2.useCallback)(
|
|
587
|
+
(frame) => {
|
|
588
|
+
if (isSkImage(frame)) imageSV.value = frame;
|
|
589
|
+
else pictureSV.value = frame;
|
|
590
|
+
},
|
|
591
|
+
[imageSV, pictureSV]
|
|
592
|
+
);
|
|
569
593
|
const reduceMotion = (0, import_react_native_reanimated.useReducedMotion)();
|
|
570
594
|
const onFrame = (0, import_react2.useCallback)(
|
|
571
595
|
(p) => {
|
|
572
|
-
|
|
596
|
+
applyFrame(p);
|
|
573
597
|
},
|
|
574
|
-
[
|
|
598
|
+
[applyFrame]
|
|
575
599
|
);
|
|
576
600
|
const { handle, picture, volumeCollapseRef } = useChartCore(
|
|
577
601
|
candles,
|
|
578
|
-
{ width, height },
|
|
602
|
+
{ width, height, pxRatio: import_react_native2.PixelRatio.get() },
|
|
579
603
|
visibleRange,
|
|
580
604
|
defaultCandleWidth,
|
|
581
605
|
chartType,
|
|
@@ -604,11 +628,11 @@ function VroomChart(props) {
|
|
|
604
628
|
animRaf.current = null;
|
|
605
629
|
if (!handle) return;
|
|
606
630
|
const next = handle.render();
|
|
607
|
-
if (next)
|
|
631
|
+
if (next) applyFrame(next);
|
|
608
632
|
if (handle.isAnimating()) {
|
|
609
633
|
animRaf.current = requestAnimationFrame(animTick);
|
|
610
634
|
}
|
|
611
|
-
}, [handle,
|
|
635
|
+
}, [handle, applyFrame]);
|
|
612
636
|
const maybeStartAnim = (0, import_react2.useCallback)(() => {
|
|
613
637
|
if (animRaf.current != null) return;
|
|
614
638
|
if (!handle?.isAnimating()) return;
|
|
@@ -623,9 +647,9 @@ function VroomChart(props) {
|
|
|
623
647
|
};
|
|
624
648
|
}, []);
|
|
625
649
|
(0, import_react2.useEffect)(() => {
|
|
626
|
-
if (picture)
|
|
650
|
+
if (picture) applyFrame(picture);
|
|
627
651
|
maybeStartAnim();
|
|
628
|
-
}, [picture,
|
|
652
|
+
}, [picture, applyFrame, maybeStartAnim]);
|
|
629
653
|
const morphRaf = (0, import_react2.useRef)(null);
|
|
630
654
|
const morphFade = (0, import_react2.useRef)(null);
|
|
631
655
|
const morphHandle = (0, import_react2.useRef)(null);
|
|
@@ -639,7 +663,7 @@ function VroomChart(props) {
|
|
|
639
663
|
morphFade.current = target;
|
|
640
664
|
handle.setChartType(target);
|
|
641
665
|
const p = handle.render();
|
|
642
|
-
if (p)
|
|
666
|
+
if (p) applyFrame(p);
|
|
643
667
|
maybeStartAnim();
|
|
644
668
|
return void 0;
|
|
645
669
|
}
|
|
@@ -656,7 +680,7 @@ function VroomChart(props) {
|
|
|
656
680
|
morphFade.current = target;
|
|
657
681
|
handle.setChartType(target);
|
|
658
682
|
const p = handle.render();
|
|
659
|
-
if (p)
|
|
683
|
+
if (p) applyFrame(p);
|
|
660
684
|
maybeStartAnim();
|
|
661
685
|
return void 0;
|
|
662
686
|
}
|
|
@@ -669,7 +693,7 @@ function VroomChart(props) {
|
|
|
669
693
|
morphFade.current = fade;
|
|
670
694
|
handle.setMorph(reduceMotion ? 0 : fade, fade);
|
|
671
695
|
const p = handle.render();
|
|
672
|
-
if (p)
|
|
696
|
+
if (p) applyFrame(p);
|
|
673
697
|
if (prog < 1) {
|
|
674
698
|
morphRaf.current = requestAnimationFrame(step);
|
|
675
699
|
} else {
|
|
@@ -677,7 +701,7 @@ function VroomChart(props) {
|
|
|
677
701
|
morphFade.current = target;
|
|
678
702
|
handle.setChartType(target);
|
|
679
703
|
const q = handle.render();
|
|
680
|
-
if (q)
|
|
704
|
+
if (q) applyFrame(q);
|
|
681
705
|
maybeStartAnim();
|
|
682
706
|
}
|
|
683
707
|
};
|
|
@@ -688,7 +712,7 @@ function VroomChart(props) {
|
|
|
688
712
|
morphRaf.current = null;
|
|
689
713
|
}
|
|
690
714
|
};
|
|
691
|
-
}, [handle, chartType, transitionMs, reduceMotion,
|
|
715
|
+
}, [handle, chartType, transitionMs, reduceMotion, applyFrame, maybeStartAnim]);
|
|
692
716
|
const volumeRaf = (0, import_react2.useRef)(null);
|
|
693
717
|
const volumeHandle = (0, import_react2.useRef)(null);
|
|
694
718
|
(0, import_react2.useEffect)(() => {
|
|
@@ -714,7 +738,7 @@ function VroomChart(props) {
|
|
|
714
738
|
volumeCollapseRef.current = { t: target, easing };
|
|
715
739
|
handle.setVolumeCollapse(target, easing);
|
|
716
740
|
const p = handle.render();
|
|
717
|
-
if (p)
|
|
741
|
+
if (p) applyFrame(p);
|
|
718
742
|
maybeStartAnim();
|
|
719
743
|
return void 0;
|
|
720
744
|
}
|
|
@@ -728,7 +752,7 @@ function VroomChart(props) {
|
|
|
728
752
|
volumeCollapseRef.current = { t, easing: kind };
|
|
729
753
|
handle.setVolumeCollapse(t, kind);
|
|
730
754
|
const p = handle.render();
|
|
731
|
-
if (p)
|
|
755
|
+
if (p) applyFrame(p);
|
|
732
756
|
if (prog < 1) {
|
|
733
757
|
volumeRaf.current = requestAnimationFrame(step);
|
|
734
758
|
} else {
|
|
@@ -748,7 +772,7 @@ function VroomChart(props) {
|
|
|
748
772
|
volume?.enabled,
|
|
749
773
|
transitionMs,
|
|
750
774
|
reduceMotion,
|
|
751
|
-
|
|
775
|
+
applyFrame,
|
|
752
776
|
volumeCollapseRef,
|
|
753
777
|
maybeStartAnim
|
|
754
778
|
]);
|
|
@@ -766,7 +790,7 @@ function VroomChart(props) {
|
|
|
766
790
|
axisCollapse.current = { y: targetY, x: targetX };
|
|
767
791
|
handle.setAxisCollapse(targetY, targetX);
|
|
768
792
|
const p = handle.render();
|
|
769
|
-
if (p)
|
|
793
|
+
if (p) applyFrame(p);
|
|
770
794
|
maybeStartAnim();
|
|
771
795
|
return void 0;
|
|
772
796
|
}
|
|
@@ -785,7 +809,7 @@ function VroomChart(props) {
|
|
|
785
809
|
axisCollapse.current = { y: targetY, x: targetX };
|
|
786
810
|
handle.setAxisCollapse(targetY, targetX);
|
|
787
811
|
const p = handle.render();
|
|
788
|
-
if (p)
|
|
812
|
+
if (p) applyFrame(p);
|
|
789
813
|
maybeStartAnim();
|
|
790
814
|
return void 0;
|
|
791
815
|
}
|
|
@@ -799,7 +823,7 @@ function VroomChart(props) {
|
|
|
799
823
|
axisCollapse.current = { y, x };
|
|
800
824
|
handle.setAxisCollapse(y, x);
|
|
801
825
|
const p = handle.render();
|
|
802
|
-
if (p)
|
|
826
|
+
if (p) applyFrame(p);
|
|
803
827
|
if (prog < 1) {
|
|
804
828
|
axisRaf.current = requestAnimationFrame(step);
|
|
805
829
|
} else {
|
|
@@ -820,7 +844,7 @@ function VroomChart(props) {
|
|
|
820
844
|
showXAxis,
|
|
821
845
|
transitionMs,
|
|
822
846
|
reduceMotion,
|
|
823
|
-
|
|
847
|
+
applyFrame,
|
|
824
848
|
maybeStartAnim
|
|
825
849
|
]);
|
|
826
850
|
const hitAxis = (0, import_react2.useCallback)(
|
|
@@ -860,7 +884,7 @@ function VroomChart(props) {
|
|
|
860
884
|
priceDrag.current = { index: pl.index, id: pl.line.id, price: pl.line.price };
|
|
861
885
|
handle.setPriceLineDrag(pl.index, pl.line.price);
|
|
862
886
|
const p = handle.render();
|
|
863
|
-
if (p)
|
|
887
|
+
if (p) applyFrame(p);
|
|
864
888
|
}
|
|
865
889
|
}
|
|
866
890
|
}).onChange((e) => {
|
|
@@ -883,7 +907,7 @@ function VroomChart(props) {
|
|
|
883
907
|
next = handle.render();
|
|
884
908
|
} else if (crosshairActive.current) {
|
|
885
909
|
const ch = handle.setCrosshair(e.x, e.y - crosshairOffset);
|
|
886
|
-
if (ch)
|
|
910
|
+
if (ch) applyFrame(ch);
|
|
887
911
|
const info = handle.getCrosshairInfo();
|
|
888
912
|
const t = info?.timeMs ?? null;
|
|
889
913
|
if (t !== lastCrosshairTime.current) {
|
|
@@ -894,7 +918,7 @@ function VroomChart(props) {
|
|
|
894
918
|
} else {
|
|
895
919
|
next = handle.translate(e.changeX, e.changeY);
|
|
896
920
|
}
|
|
897
|
-
if (next)
|
|
921
|
+
if (next) applyFrame(next);
|
|
898
922
|
maybeStartAnim();
|
|
899
923
|
}).onEnd((e) => {
|
|
900
924
|
if (!handle) return;
|
|
@@ -903,7 +927,7 @@ function VroomChart(props) {
|
|
|
903
927
|
priceDrag.current = null;
|
|
904
928
|
handle.setPriceLineDrag(-1, 0);
|
|
905
929
|
const p = handle.render();
|
|
906
|
-
if (p)
|
|
930
|
+
if (p) applyFrame(p);
|
|
907
931
|
if (g) onPriceLineDragEnd?.(g.id, g.price);
|
|
908
932
|
return;
|
|
909
933
|
}
|
|
@@ -923,7 +947,7 @@ function VroomChart(props) {
|
|
|
923
947
|
velocity *= Math.pow(0.5, dt / HALF_LIFE_S);
|
|
924
948
|
const dx = velocity * dt;
|
|
925
949
|
const next = handle.pan(dx, 0);
|
|
926
|
-
if (next)
|
|
950
|
+
if (next) applyFrame(next);
|
|
927
951
|
maybeStartAnim();
|
|
928
952
|
if (Math.abs(velocity) > MIN_STOP) {
|
|
929
953
|
decayRaf.current = requestAnimationFrame(tick);
|
|
@@ -977,7 +1001,7 @@ function VroomChart(props) {
|
|
|
977
1001
|
}
|
|
978
1002
|
if (frameX === 1 && frameY === 1) return;
|
|
979
1003
|
const next = handle.zoom(frameX, frameY, focalX, focalY);
|
|
980
|
-
if (next)
|
|
1004
|
+
if (next) applyFrame(next);
|
|
981
1005
|
maybeStartAnim();
|
|
982
1006
|
});
|
|
983
1007
|
const longPress = import_react_native_gesture_handler.Gesture.LongPress().runOnJS(true).onStart((e) => {
|
|
@@ -987,7 +1011,7 @@ function VroomChart(props) {
|
|
|
987
1011
|
cancelDecay();
|
|
988
1012
|
crosshairActive.current = true;
|
|
989
1013
|
const ch = handle.setCrosshair(e.x, e.y - crosshairOffset);
|
|
990
|
-
if (ch)
|
|
1014
|
+
if (ch) applyFrame(ch);
|
|
991
1015
|
const info = handle.getCrosshairInfo();
|
|
992
1016
|
lastCrosshairTime.current = info?.timeMs ?? null;
|
|
993
1017
|
onCrosshair?.({
|
|
@@ -1010,7 +1034,7 @@ function VroomChart(props) {
|
|
|
1010
1034
|
if (hitAxis(e.x, e.y) !== "chart") return;
|
|
1011
1035
|
crosshairActive.current = false;
|
|
1012
1036
|
const ch = handle.clearCrosshair();
|
|
1013
|
-
if (ch)
|
|
1037
|
+
if (ch) applyFrame(ch);
|
|
1014
1038
|
lastCrosshairTime.current = null;
|
|
1015
1039
|
onCrosshair?.({ active: false, candle: null, timeMs: null, price: null, reason: "hide" });
|
|
1016
1040
|
});
|
|
@@ -1025,11 +1049,17 @@ function VroomChart(props) {
|
|
|
1025
1049
|
style
|
|
1026
1050
|
]
|
|
1027
1051
|
},
|
|
1028
|
-
/* @__PURE__ */ import_react2.default.createElement(import_react_native_gesture_handler.GestureDetector, { gesture }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: { flex: 1 } }, /* @__PURE__ */ import_react2.default.createElement(import_react_native_skia.Canvas, { style: { flex: 1 } }, width > 0 && height > 0 ? (
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1052
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native_gesture_handler.GestureDetector, { gesture }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: { flex: 1 } }, /* @__PURE__ */ import_react2.default.createElement(import_react_native_skia.Canvas, { style: { flex: 1 } }, width > 0 && height > 0 ? /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement(import_react_native_skia.Picture, { picture: pictureSV }), /* @__PURE__ */ import_react2.default.createElement(
|
|
1053
|
+
import_react_native_skia.Image,
|
|
1054
|
+
{
|
|
1055
|
+
image: imageSV,
|
|
1056
|
+
x: 0,
|
|
1057
|
+
y: 0,
|
|
1058
|
+
width,
|
|
1059
|
+
height,
|
|
1060
|
+
fit: "fill"
|
|
1061
|
+
}
|
|
1062
|
+
)) : null)))
|
|
1033
1063
|
);
|
|
1034
1064
|
}
|
|
1035
1065
|
// Annotate the CommonJS export names for ESM import in node:
|