the react-financial-charts library is written in TS. I am trying to use it in my (React+Js) project because it has active contributions. But the documentation is non-existant and the Q&A on Github is not helpful at all. It mainly discusses TS based solutions and I do not know TypeScript. My question is basic,
- Firstly is it possible to use a npm library written in TS in a React+JS project?
- If yes, then how?
What I've tried so far:
- I checked that I have the
tslib
package in thenode_modules
directory - I searched through the Github Q&A section for some guidance on how to implement in React+JS
- I parsed though the npm package for
react-financial-charts
and@react-financial-charts
to make named imports of some of the modules to see if I can import the chart ponents, didn't work it gave the module not found error
Module not found: Can't resolve '@react-financial-charts' in '/Users/****/***/***/***/root-app-folder/src/pages'
- I tried to import and use the tsx,tsv and ts files and as per a discussion on their github page one should be able to
the react-financial-charts library is written in TS. I am trying to use it in my (React+Js) project because it has active contributions. But the documentation is non-existant and the Q&A on Github is not helpful at all. It mainly discusses TS based solutions and I do not know TypeScript. My question is basic,
- Firstly is it possible to use a npm library written in TS in a React+JS project?
- If yes, then how?
What I've tried so far:
- I checked that I have the
tslib
package in thenode_modules
directory - I searched through the Github Q&A section for some guidance on how to implement in React+JS
- I parsed though the npm package for
react-financial-charts
and@react-financial-charts
to make named imports of some of the modules to see if I can import the chart ponents, didn't work it gave the module not found error
Module not found: Can't resolve '@react-financial-charts' in '/Users/****/***/***/***/root-app-folder/src/pages'
- I tried to import and use the tsx,tsv and ts files and as per a discussion on their github page one should be able to
2 Answers
Reset to default 5As I was typing out the question I found the solution, it was a shared sandbox by 'cerchio-pixel' that I implemented and it worked in my project.
Link to the codesandbox
Here is the React ponent for implementing the Financial Chart below for quick reference:
import React from "react";
import { format } from "d3-format";
import { timeFormat } from "d3-time-format";
import {
elderRay,
ema,
discontinuousTimeScaleProviderBuilder,
Chart,
ChartCanvas,
CurrentCoordinate,
BarSeries,
CandlestickSeries,
ElderRaySeries,
LineSeries,
MovingAverageTooltip,
OHLCTooltip,
SingleValueTooltip,
lastVisibleItemBasedZoomAnchor,
XAxis,
YAxis,
CrossHairCursor,
EdgeIndicator,
MouseCoordinateX,
MouseCoordinateY,
ZoomButtons,
withDeviceRatio,
withSize,
} from "react-financial-charts";
import { initialData } from "./data/data";
const Stonk = () => {
const ScaleProvider =
discontinuousTimeScaleProviderBuilder().inputDateAccessor(
(d) => new Date(d.date)
);
const height = 700;
const width = 900;
const margin = { left: 0, right: 48, top: 0, bottom: 24 };
const ema12 = ema()
.id(1)
.options({ windowSize: 12 })
.merge((d, c) => {
d.ema12 = c;
})
.accessor((d) => d.ema12);
const ema26 = ema()
.id(2)
.options({ windowSize: 26 })
.merge((d, c) => {
d.ema26 = c;
})
.accessor((d) => d.ema26);
const elder = elderRay();
const calculatedData = elder(ema26(ema12(initialData)));
const { data, xScale, xAccessor, displayXAccessor } =
ScaleProvider(initialData);
const pricesDisplayFormat = format(".2f");
const max = xAccessor(data[data.length - 1]);
const min = xAccessor(data[Math.max(0, data.length - 100)]);
const xExtents = [min, max + 5];
const gridHeight = height - margin.top - margin.bottom;
const elderRayHeight = 100;
const elderRayOrigin = (_, h) => [0, h - elderRayHeight];
const barChartHeight = gridHeight / 4;
const barChartOrigin = (_, h) => [0, h - barChartHeight - elderRayHeight];
const chartHeight = gridHeight - elderRayHeight;
const yExtents = (data) => {
return [data.high, data.low];
};
const dateTimeFormat = "%d %b";
const timeDisplayFormat = timeFormat(dateTimeFormat);
const barChartExtents = (data) => {
return data.volume;
};
const candleChartExtents = (data) => {
return [data.high, data.low];
};
const yEdgeIndicator = (data) => {
return data.close;
};
const volumeColor = (data) => {
return data.close > data.open
? "rgba(38, 166, 154, 0.3)"
: "rgba(239, 83, 80, 0.3)";
};
const volumeSeries = (data) => {
return data.volume;
};
const openCloseColor = (data) => {
return data.close > data.open ? "#26a69a" : "#ef5350";
};
return (
<ChartCanvas
height={height}
ratio={3}
width={width}
margin={margin}
data={data}
displayXAccessor={displayXAccessor}
seriesName="Data"
xScale={xScale}
xAccessor={xAccessor}
xExtents={xExtents}
zoomAnchor={lastVisibleItemBasedZoomAnchor}
>
<Chart
id={2}
height={barChartHeight}
origin={barChartOrigin}
yExtents={barChartExtents}
>
<BarSeries fillStyle={volumeColor} yAccessor={volumeSeries} />
</Chart>
<Chart id={3} height={chartHeight} yExtents={candleChartExtents}>
<XAxis showGridLines showTickLabel={false} />
<YAxis showGridLines tickFormat={pricesDisplayFormat} />
<CandlestickSeries />
<LineSeries yAccessor={ema26.accessor()} strokeStyle={ema26.stroke()} />
<CurrentCoordinate
yAccessor={ema26.accessor()}
fillStyle={ema26.stroke()}
/>
<LineSeries yAccessor={ema12.accessor()} strokeStyle={ema12.stroke()} />
<CurrentCoordinate
yAccessor={ema12.accessor()}
fillStyle={ema12.stroke()}
/>
<MouseCoordinateY
rectWidth={margin.right}
displayFormat={pricesDisplayFormat}
/>
<EdgeIndicator
itemType="last"
rectWidth={margin.right}
fill={openCloseColor}
lineStroke={openCloseColor}
displayFormat={pricesDisplayFormat}
yAccessor={yEdgeIndicator}
/>
<MovingAverageTooltip
origin={[8, 24]}
options={[
{
yAccessor: ema26.accessor(),
type: "EMA",
stroke: ema26.stroke(),
windowSize: ema26.options().windowSize,
},
{
yAccessor: ema12.accessor(),
type: "EMA",
stroke: ema12.stroke(),
windowSize: ema12.options().windowSize,
},
]}
/>
<ZoomButtons />
<OHLCTooltip origin={[8, 16]} />
</Chart>
<Chart
id={4}
height={elderRayHeight}
yExtents={[0, elder.accessor()]}
origin={elderRayOrigin}
padding={{ top: 8, bottom: 8 }}
>
<XAxis showGridLines gridLinesStrokeStyle="#e0e3eb" />
<YAxis ticks={4} tickFormat={pricesDisplayFormat} />
<MouseCoordinateX displayFormat={timeDisplayFormat} />
<MouseCoordinateY
rectWidth={margin.right}
displayFormat={pricesDisplayFormat}
/>
<ElderRaySeries yAccessor={elder.accessor()} />
<SingleValueTooltip
yAccessor={elder.accessor()}
yLabel="Elder Ray"
yDisplayFormat={(d) =>
`${pricesDisplayFormat(d.bullPower)}, ${pricesDisplayFormat(
d.bearPower
)}`
}
origin={[8, 16]}
/>
</Chart>
<CrossHairCursor />
</ChartCanvas>
);
};
export default Stonk;
where the data.js
file is as follows:
export let initialData = [
{
date: "2021-02-02 16:00:00",
open: 134.9307,
low: 134.9105,
high: 135.4215,
close: 135.0087,
volume: 73591581
},
{
date: "2021-02-02 15:45:00",
open: 134.9707,
low: 134.9307,
high: 134.9707,
close: 134.9307,
volume: 67639193
},
{
date: "2021-02-02 15:30:00",
open: 134.6608,
low: 134.6608,
high: 134.975,
close: 134.975,
volume: 64815258
},
{
date: "2021-02-02 15:15:00",
open: 134.8585,
low: 134.6237,
high: 134.9716,
close: 134.6608,
volume: 62892896
},
{
date: "2021-02-02 15:00:00",
open: 134.985,
low: 134.78,
high: 135.0,
close: 134.8585,
volume: 60880828
},
]
I added the files above and imported the ponent elsewhere in my project and it worked just as expected. I may have been missing something very obvious and/or didn't have enough documentation to read on how to implement the library but hopefully this helps someone else who could not find enough resources on how to implement it and was searching the Q&A, now they'll have a StackOverflow search result. Happy Hacking!
This repo is a fork of react-stockcharts, renamed, converted to typescript and bug fixes applied due to the original project being unmaintained. Here is the link to origin documentation