#Integrating a charting library into Remix

1 messages · Page 1 of 1 (latest)

tender valve
#

I have tried and failed to integrate two different chart libraries into Remix, just looking for some help around what I'm doing wrong here. I saw about splitting out the chart code into a separate file with .client and using <ClientOnly> from remix-utils so it's only rendered on the client side.

I'm using react-apexcharts and have a split between two files:

// ~/components/BarChart.client.js

export const BarChart = (input) => {
  const options = {
    labels: input.labels,
    // .......
  }
  const series = [{ name: 'total', data: input.data }]
  return <ReactApexChart type="bar" series={series} options={options} height={364} />
}

// ~/routes/analytics.js

export const loader = async ({ request }) => {
  await getUser(request)
  const data = {
    labels: ['2022-01-01', '2022-02-01', '2022-03-01'],
    data: [100, 200, 300],
  }
  return json({ data })
}
export default function Analytics() {
  const { data } = useLoaderData()
  return (
    <div className="divider-vertical m-2 p-2">
      <ClientOnly fallback={<p>Cannot load chart</p>}>
        {() => <BarChart input={data} />}
      </ClientOnly>
    </div>
  )
}

I'm getting an error in ApexCharts:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'length')
    at t2.value (apexcharts.common.js:6:137588)
    at t2.value (apexcharts.common.js:6:141311)
    at t2.value (apexcharts.common.js:14:38129)
    at t2.create (apexcharts.common.js:6:4483)
    at apexcharts.common.js:14:37129
    at new Promise (<anonymous>)
    at t2.value (apexcharts.common.js:14:21643)
    at r.value (react-apexcharts.min.js:1:2762)
    at commitLifeCycles (react-dom.development.js:20663:24)
    at commitLayoutEffects (react-dom.development.js:23426:7)

It looks like an issue with ApexCharts, but I have verified this works in a plain old Create React App setup, it seems to be only in Remix that it has this issue

formal lava
#

Is it not an issue with your loader? Looks like you are returning input but I don't see this defined. Should it not be return json({ data }) rather than return json({ input })?

tender valve
formal lava
#

Did that fix the issue?

tender valve
#

Nope, still the same error

formal lava
#

ClientOnly implementation looks ok. We implemented the same pattern earlier this week for plotly charting library without issue. Does the input prop inside your BarChart look as you would expect if you debug or console log it? Should you not be destructuring props to extract input?

tender valve
#

It does indeed and that's how I checked that it worked in a plain Create React App setup. Could you please share a code snippet of your chart component that I could copy to see if it's something else I've set up wrong?

formal lava
#

Maybe you could create a reproducible repo somewhere and we can take a look and try to run it.

#

Our chart is identical to your implementation but rather than <ReactApexChart> we call some React Plotly component.

narrow wedge
#

const chartRef = React.useRef<HTMLDivElement>(null);

React.useEffect(() => {
if (chartRef.current && typeof document !== "undefined") {
const { createChart } = require("lightweight-charts");

  // do your stuff here
}

}, [chartRef, data]);

#

Hi Alex, I've done something like this and got rid of that error with a different charting library

potent cedar
rain lava
#

@formal lava I'm struggling to get Plotly working with Remix, even within a ".client.tsx" component file and <ClientOnly wrapper. Did you use react-plotly.js?

broken drum
broken drum
broken drum