Chart.js and Plumsail: not a good mariage

Hi,

On a SharePoint 2019 page, I want to embed a chart, based on Chart.js framework (https://www.chartjs.org/)

However
On a blanc SharePoint page, I can use the framework, simply by adding the following script tag:

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.3.0/chart.umd.js" integrity="sha512-CMF3tQtjOoOJoOKlsS7/2loJlkyctwzSoDK/S40iAB+MqWSaf50uObGQSk5Ny/gfRhRCjNLvoxuCvdnERU4WGg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>

On the same page, if I add a basic Plumsail forms webpart:

  • the plumsail form does not show up
  • on my console, I get following error:
Uncaught Error: Multiple anonymous defines in module https://component-id.invalid/5571c98c-07f8-4738-b0dc-a58895d89c90_1.0.8/UserFormWebPartStrings
    at l.eval [as reduceRegister_] (eval at <anonymous> (sp-classic-page-assembly.js?uniqueId=GFcOm:691:66376), <anonymous>:5:14395)
    at HTMLScriptElement.m (eval at <anonymous> (sp-classic-page-assembly.js?uniqueId=GFcOm:691:66376), <anonymous>:5:72)
eval @ VM16934:5
m @ VM16934:5

So my question is:
How can I use the Chart.js framework together with Plumsail forms on the same SharePoint 2019 web page

kind regards,
Bart Plessers

FYI
If I place following code on a Script Editor webpart on a SharePoint page, I can use the "Chart" function

<script>
    console.log("loading Chart.js");
    var imported = document.createElement('script');
    imported.setAttribute("src","https://icts.groupware.kuleuven.be/sites/zandbak_2023-04-28_PublishingPortal_uk/app/SiteAssets/ICTS.Plumsail/chart.umd.js");
    imported.setAttribute("integrity", "sha512-CMF3tQtjOoOJoOKlsS7/2loJlkyctwzSoDK/S40iAB+MqWSaf50uObGQSk5Ny/gfRhRCjNLvoxuCvdnERU4WGg==" );
    imported.setAttribute("crossorigin", "anonymous");
    imported.setAttribute("referrerpolicy", "no-referrer");
    document.head.appendChild(imported);
    console.log("loading Chart.js: loaded!");    
</script>

If I do exactly the same on a Plumsail form:

fd.spRendered(function(){
    console.log("loading Chart.js");
    var imported = document.createElement('script');
    imported.setAttribute("src","https://icts.groupware.kuleuven.be/sites/zandbak_2023-04-28_PublishingPortal_uk/app/SiteAssets/ICTS.Plumsail/chart.umd.js");
    imported.setAttribute("integrity", "sha512-CMF3tQtjOoOJoOKlsS7/2loJlkyctwzSoDK/S40iAB+MqWSaf50uObGQSk5Ny/gfRhRCjNLvoxuCvdnERU4WGg==" );
    imported.setAttribute("crossorigin", "anonymous");
    imported.setAttribute("referrerpolicy", "no-referrer");
    document.head.appendChild(imported);
    console.log("loading Chart.js: loaded!");    
}) 

than the "Chart" function is NOT defined and I got following error

Uncaught TypeError: Unexpected anonymous AMD define.
    at l.eval [as reduceRegister_] (eval at <anonymous> (sp-classic-page-assembly.js?uniqueId=GFcOm:691:66376), <anonymous>:5:14313)
    at l.eval [as pushRegister_] (eval at <anonymous> (sp-classic-page-assembly.js?uniqueId=GFcOm:691:66376), <anonymous>:4:31764)
    at a (eval at <anonymous> (sp-classic-page-assembly.js?uniqueId=GFcOm:691:66376), <anonymous>:5:13777)
    at chart.umd.js:7:126
    at chart.umd.js:7:200

Hello @bartplessers,

First, you need to add an HTML-control into the form where the chart should be rendered with the content:

<canvas id="myChart"></canvas>

Next, add the code below to the JS editor. Note that the path in the require config must be without .js.

fd.spRendered(function(){
    requirejs.config({
        paths: {
            chart: 'https://cdn.jsdelivr.net/npm/chart'
        }
    });
    
    require(['chart'], function(Chart) {
        const ctx = document.getElementById('myChart');

        new Chart(ctx, {
        type: 'bar',
        data: {
          labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
          datasets: [{
            label: '# of Votes',
            data: [12, 19, 3, 5, 2, 3],
            borderWidth: 1
          }]
        },
        options: {
          scales: {
            y: {
              beginAtZero: true
            }
          }
        }
        }); 
    })
})

Hi @mnikitina ,

Thanx for response.

However, I still get an error

If I use

    requirejs.config({
        paths: {
            chart: 'https://cdn.jsdelivr.net/npm/chart'
        }
    });

I get following error:


indicating that the module was not (correctly) loaded

If I use

    requirejs.config({
        paths: {
            chart: 'https://cdn.jsdelivr.net/npm/chart.js@4.3.0/dist/'
        }
    });


indicating that there is some other error...

Did you test your code and did that work?
Is there some other reference that I'm missing?

kind regards,
Bart Plessers

Hello @bartplessers,

There is a bug in SystemJS library that is used in SharePoint on-premises, that is why the code doesn't work in a full screen mode. Please try this code, it should work in both panel and full screen:

fd.spRendered(function () {
    var defineOrig = window.define;
    window.define = null;

    $.getScript('https://cdn.jsdelivr.net/npm/chart.js', function () {
        window.define = defineOrig;

        var Chart = window.Chart;
        const ctx = document.getElementById('myChart');

        new Chart(ctx, {
            type: 'bar',
            data: {
                labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
                datasets: [
                    {
                        label: '# of Votes',
                        data: [12, 19, 3, 5, 2, 3],
                        borderWidth: 1,
                    },
                ],
            },
            options: {
                scales: {
                    y: {
                        beginAtZero: true,
                    },
                },
            },
        });
    });
});
2 Likes

@mnikitina
YESSSSZZZZZZZZZZZZ!!!! This works!

thanx for your help.
B

Maybe another question
I have a page with a Content Editor webpart (1) and a Plumsail Forms webpart (2)
The CEWP points to a html-file, containing code that loads the chart.js and displays a chart.
The PFWP shows an out-of-the box Plumsail display form of a list item. No code/css added

If I only place (1) on my page --> chart.js works

From the moment that I place (2) on the same page --> (1) stops working

It seems to me that there is some interference between Plumsail code injection and CEWP code injection.

Can this be avoided too?

kind regards,
Bart

PS
here is my html-file

<script>
console.log("loading: " + "https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.3.0/chart.umd.js");
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.3.0/chart.umd.js" integrity="sha512-CMF3tQtjOoOJoOKlsS7/2loJlkyctwzSoDK/S40iAB+MqWSaf50uObGQSk5Ny/gfRhRCjNLvoxuCvdnERU4WGg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<p>

<br>This Content Editor Webpart 
<br>https://icts.groupware.kuleuven.be/sites/zandbak_2023-04-28_PublishingPortal_uk/app/SiteAssets/ICTS.Plumsail/loadChart.js.html
<br>has a script tag that loads
<br>https://cdnjs.cloudflare.com/ajax/libs/Chart.js/4.3.0/chart.umd.js
</p>

<canvas id="myChart"></canvas>

<script>

	const myChart = document.getElementById('myChart');

	new Chart(myChart, {
	type: 'bar',
	data: {
	  labels: ['Red', 'Blue', 'Yellow', 'Green', 'Purple', 'Orange'],
	  datasets: [{
		label: '# of Votes',
		data: [12, 19, 3, 5, 2, 3],
		borderWidth: 1
	  }]
	},
	options: {
	  scales: {
		y: {
		  beginAtZero: true
		}
	  }
	}
	}); 


</script>

@bartplessers,

You can download the script through the designer using the code I've shared. And add this line to the content editor instead of the form:

<canvas id="myChart"></canvas>

Hi @mnikitina ,

Thanx for your answer.

In fact, this is another use case.

The main idea was:

  1. I have an existing Sharepoint page with Chart.js loaded
  2. I want to add a Plumsail Form webpart on the same page. The form has nothing to do with the chart displayed.

Just by adding (2) to (1), my webpage is broken and the chart is not loaded anymore.
I can load the Chart.js framework via Plumsail form, but that is not desirable here.

You where mentioning that "There is a bug in SystemJS library that is used in SharePoint on-premises", but for me it feels that there is maybe a bug in Plumsail in that way that it interferes with out-of-the box Chart.js and/or SharePoint pages.

But maybe I should log another ticket for this use case?

Anyway, any help is welcome!

kind regards,
Bart

Hello @bartplessers,

RequireJS module is built into Plumsail Forms. ChartJS is designed as a module and cannot be imported this way when a page contains SystemJS/requires. So, the only workaround is to load the script via the form.

Also, we don't recommend using Plumsail Forms on classic pages, as it is designed specifically for modern pages. For classic pages, you can try Forms Designer.