如何(我可以)在React+JS中使用react-financial-charts库

Jus*_*gin 2 javascript npm typescript reactjs

React-Financial-Charts 库是用 TS 编写的。我正在尝试在我的(React+Js)项目中使用它,因为它有积极的贡献。但文档不存在,Github 上的问答根本没有帮助。主要讨论基于TS的解决方案,我不懂TypeScript。我的问题很基本,

  1. 首先,是否可以在 React+JS 项目中使用 TS 编写的 npm 库?
  2. 如果是,那么如何?

到目前为止我尝试过的:

  • 我检查了目录tslib中是否有该包node_modules
  • 我在 Github Q&A 部分搜索了一些关于如何在 React+JS 中实现的指导
  • 我解析了 npm 包react-financial-charts@react-financial-charts进行了某些模块的命名导入,以查看是否可以导入图表组件,但没有成功,它给出了模块未找到错误

Module not found: Can't resolve '@react-financial-charts' in '/Users/****/***/***/***/root-app-folder/src/pages'

  • 我尝试导入并使用 tsx、tsv 和 ts 文件,根据他们的 github 页面上的讨论,应该能够

Jus*_*gin 5

当我输入问题时,我找到了解决方案,它是我实现的“cerchio-pixel”共享沙箱,并且它在我的项目中有效。

链接到codesandbox

以下是用于实现下面财务图表的 React 组件,以供快速参考:

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;
Run Code Online (Sandbox Code Playgroud)

其中data.js文件如下:

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
  },
]
Run Code Online (Sandbox Code Playgroud)

我添加了上面的文件,并将该组件导入到我的项目中的其他位置,它按预期工作。我可能遗漏了一些非常明显的东西和/或没有足够的文档来阅读如何实现该库,但希望这可以帮助其他无法找到足够的资源来实现它并正在搜索问答的人,现在他们将会有一个 StackOverflow 搜索结果。黑客快乐!

  • 这使得反应财务图表更加平易近人。很棒的发现,谢谢。我给codesandbox点了个赞。他是如何想出如何使用它的,我们可能永远不知道:) (3认同)