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

标签 javascript reactjs typescript npm

react-financial-charts 库是用 TS 编写的。我正在尝试在我的 (React+Js) 项目中使用它,因为它有积极的贡献。但是文档不存在并且 Q&A on Github一点帮助都没有。它主要讨论基于 TS 的解决方案,我不知道 TypeScript。我的问题很基本,

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

到目前为止我尝试了什么:

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

未找到模块:无法在“/Users/****/***/***/***/root-app-folder/”中解析“@react-financial-charts”源/页面'

  • 我尝试导入和使用 tsx、tsv 和 ts 文件,并按照 discussion在他们的 github 页面上应该能够

最佳答案

当我输入问题时,我找到了解决方案,这是我实现的“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;

其中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
  },
]

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

关于javascript - 如何(我可以)在 React+JS 中使用 react-financial-charts 库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68483822/

相关文章:

javascript - 如何在使用固定结构时在 ngFor 中将索引值增加和更新 2

javascript - 如何在 jQuery 插件中启用全局设置更改

javascript - Kendo UI 的加载指示器?

javascript - Mouseup 事件未使用函数内部代码触发

reactjs - react native 0.31 : Could not get BatchedBridge Error

typescript 泛型 : checking a unique property on a generic type object in if condition doesn't determine the object's type

html - 模式背景元素的正确 HTML 角色和其他相关属性 (TypeScript React)

javascript - 如何检查是否按下了shift+tab?

javascript - 是否可以将 Proptypes 用于复杂对象的关联数组

javascript - 使用 mapStateToProps 连接到 redux 存储的确认模式给出错误