Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Charts: Explicit import of chart.js dependency doesn't allow for single pages with inline scripting #3059

Closed
tailg8nj opened this issue Jul 13, 2022 · 10 comments · Fixed by #3061 or #3068
Assignees
Labels
Type: Enhancement Issue contains an enhancement related to a specific component. Additional functionality has been add
Milestone

Comments

@tailg8nj
Copy link

Unless I'm misunderstanding something here, I believe the following line that imports chart.js/auto, means that in order to use the PrimeReact Graph components, you must be using a node-based installation. I have not found a way to successfully leverage them via script tags.

import('chart.js/auto').then((module) => {

Example code that fails:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Chart Example</title>

    <!-- PrimeReact -->
    <link rel="stylesheet" href="https://unpkg.com/primeicons/primeicons.css" />
    <link rel="stylesheet" href="https://unpkg.com/primereact/resources/themes/lara-light-indigo/theme.css" />
    <link rel="stylesheet" href="https://unpkg.com/primereact/resources/primereact.min.css" />
    <link rel="stylesheet" href="https://unpkg.com/primeflex@2.0.0/primeflex.min.css" />

    <!-- Dependencies -->
    <script src="https://unpkg.com/react/umd/react.production.min.js"></script>
    <script src="https://unpkg.com/react-dom/umd/react-dom.production.min.js"></script>
    <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
    <script src="https://unpkg.com/react-transition-group@4.4.2/dist/react-transition-group.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/3.8.0/chart.min.js" crossorigin="anonymous"></script>

    <!-- Demo -->
    <script src="https://unpkg.com/primereact/core/core.min.js"></script>
    <script src="https://unpkg.com/primereact/chart/chart.min.js" crossorigin="anonymous"></script>
</head>
<body>
    <div id="root"></div>

    <script type="text/babel">

        const { useEffect, useState } = React;
        const { Chart } = primereact.chart;

        const data = {
        labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
            datasets: [
                {
                    label: 'First Dataset',
                    data: [65, 59, 80, 81, 56, 55, 40],
                    fill: false,
                    borderColor: '#4bc0c0'
                }
            ]
        };

        const ChartDemo = () => {
            return (
                <div className="chart-demo">
                    <div className="card">
                        <Chart type="line" data={data} />
                    </div>
                </div>
            );
        }

        const rootElement = document.getElementById("root");
        ReactDOM.render(<ChartDemo />, rootElement);

    </script>
</body>
</html>

Stack:

Uncaught (in promise) TypeError: Failed to resolve module specifier 'chart.js/auto'
    at chart.min.js:1:1012
    at Id (react-dom.production.min.js:165:137)
    at Xb (react-dom.production.min.js:200:284)
    at react-dom.production.min.js:197:106
    at S (react.production.min.js:17:25)
    at MessagePort.U (react.production.min.js:21:60)

Opening this issue to confirm and any suggested work-arounds. I have a fairly simple form that needs to query a rest server and display the chart. I'd love to use the charting available here instead of say, plotly or returning svg/png data.

@melloware
Copy link
Member

Thanks for reporting. I think that you might be correct that this won't work. I just recently fixed this: #2999

I think we have to try and make another fix to load it if its loaded via script.

@melloware melloware added the Type: Enhancement Issue contains an enhancement related to a specific component. Additional functionality has been add label Jul 13, 2022
@melloware
Copy link
Member

Looks like this: https://www.chartjs.org/docs/latest/getting-started/integration.html Just need to figure out how.

melloware added a commit to melloware/primereact that referenced this issue Jul 13, 2022
@melloware
Copy link
Member

Currently this doesn't look possible because the name of the React component Chart is colliding with ChartsJS new Chart

@melloware melloware added Status: Discussion Issue or pull request needs to be discussed by Core Team and removed Type: Enhancement Issue contains an enhancement related to a specific component. Additional functionality has been add labels Jul 13, 2022
@melloware melloware changed the title Explicit import of chart.js dependency doesn't allow for single pages with inline scripting Charts: Explicit import of chart.js dependency doesn't allow for single pages with inline scripting Jul 14, 2022
@tailg8nj
Copy link
Author

tailg8nj commented Jul 14, 2022

Currently this doesn't look possible because the name of the React component Chart is colliding with ChartsJS new Chart

I looked at your commit / attempt. Would we be able to leverage the export as syntax here with a temporary name for the React Chart? e.g.:

import * as React from 'react';
import { useUnmountEffect } from '../hooks/Hooks';
import { classNames, ObjectUtils } from '../utils/Utils';

const ChartJS = function() {
    try {
        return Chart;
    } catch {
        return undefined;
    }    
}();

const PrimeReactChart = React.memo(React.forwardRef((props, ref) => {

    const chartRef = React.useRef(null);
    const canvasRef = React.useRef(null);

    const initChart = () => {

        // lines omitted 

        if (ChartJS) {
            // GitHub #3059 loaded by script only
            chartRef.current = new ChartJS(canvasRef.current, configuration);
        }
        else {
            import('chart.js/auto').then((module) => {
                if (module) {
                    if (module.default) {
                        // WebPack
                        chartRef.current = new module.default(canvasRef.current, configuration);
                    } else {
                        // ParcelJs
                        chartRef.current = new module(canvasRef.current, configuration);
                    }
                }
            });
        }
    }

    // lines omitted

    return (
        <div id={props.id} style={style} className={className} {...otherProps}>
            <canvas ref={canvasRef} width={props.width} height={props.height}></canvas>
        </div>
    );
}), (prevProps, nextProps) => prevProps.data === nextProps.data && prevProps.options === nextProps.options && prevProps.type === nextProps.type);

PrimeReactChart.displayName = 'Chart';
PrimeReactChart.defaultProps = {
    __TYPE: 'Chart',
    id: null,
    type: null,
    data: null,
    options: null,
    plugins: null,
    width: null,
    height: null,
    style: null,
    className: null
}

export { PrimeReactChart as Chart };

I was able to get it working with a change similar to this to the dist version of chart.js.

@melloware
Copy link
Member

Yes let me try this that looks really promising!

@tailg8nj
Copy link
Author

I just edited the example above with some try/catch behavior to take into account the other use cases where we actually need to import the module.

melloware added a commit to melloware/primereact that referenced this issue Jul 14, 2022
melloware added a commit to melloware/primereact that referenced this issue Jul 14, 2022
@melloware melloware assigned melloware and tailg8nj and unassigned melloware Jul 14, 2022
@melloware melloware added this to the 9.0.0 milestone Jul 14, 2022
@melloware
Copy link
Member

OK PR submitted! Tested and its still working fine in NextJS/CRA.

@melloware melloware added Type: Enhancement Issue contains an enhancement related to a specific component. Additional functionality has been add and removed Status: Discussion Issue or pull request needs to be discussed by Core Team labels Jul 14, 2022
melloware added a commit to melloware/primereact that referenced this issue Jul 14, 2022
melloware added a commit to melloware/primereact that referenced this issue Jul 15, 2022
@mertsincan mertsincan modified the milestones: 9.0.0, 8.3.0 Jul 18, 2022
@melloware
Copy link
Member

8.3.0 is release @tailg8nj if you want to give it a try now?

@tailg8nj
Copy link
Author

tailg8nj commented Jul 18, 2022

Confirmed working as expected. Thanks for the quick turnaround!

@mertsincan
Copy link
Member

Ohh no! I did not expect such a quick effect :) You are very fast :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Enhancement Issue contains an enhancement related to a specific component. Additional functionality has been add
Projects
None yet
3 participants