Chart.js on wix site

HI,

I want to make a chart on my wix site (upgraded). I searched online and I found some tutorials for making charts using chart.js and I think I can manage to make one with those tutorials. But, the problem is there is no a single tutorials I could find to integrate this chart with the wix website. Some links on the Wix itself is broken links and only working link on wix I could find is the following but that doesn’t seem to work.
https://support.wix.com/en/article/corvid-working-with-the-html-element#messaging-1
Can somebody tell me if this is working for you so that I can recheck once again if I was wrong.
By the way, it works one way, that is, I can send message to the HTML element but I can’t sent from it.

Googling didn’t help on this.

Can you help me make one in detail please?

Thanks in advance.

Look in the examples for this Corvid Forum and you will find…
https://www.wix.com/corvid/examples

https://www.wix.com/corvid/example/chart.js-custom-element
https://www.wix.com/corvid/example/create-a-custom-chart

How do I send data between my page and an HTML Component?
You can send and receive messages between your page and an HTML Component using the postMessage() and onMessage() functions.

https://support.wix.com/en/article/corvid-working-with-the-html-element
https://www.wix.com/corvid/reference/$w.HtmlComponent.html

Thanks for your quick response.
I have already gone through the links you have provided. One of the links you have provided is already included in my question and that doesn’t seems to work. Could you please check if there is anything wrong in it (Wix Help Center).

Another link you have provided is to Chart.js Custom Element, I opened the same page in the editor it was not working as the page needs to be upgraded to premium and hence I recreated everything on my website which is an upgraded one (but not connected to the domain), I created Chart JS page, under Public I have the following files as in the below screenshot and I created a database with the same values as in the example and I added Custom Element on to the Chart JS page and pasted all the codes to the relevant pages and published (I think this is all what I have to do). But chart did not shown on the page. I do not know what went wrong.

Another link was to Create a Custom Chart, it works as is. Can you tell me how the above chart and this chart are different? Can I use this chart and use data from my database using corvid and dataset and make different charts such as Pie, Doughnut, Line,etc.

There are tutorials on Chart.js but there is no help available online on integrating it to the wix website.

Could you please help on this as I need it for one of my projects.

Thanks.

Hey maybe this example can help you. I’m really bad explaining things so I’ll do my best hehe… with this code you can :

1- query a collection after a drop-down selection which change the data (chart) dynamically based on selection.
2-The background color of Bar Chart change after drop-down selection.
3-Populate a repeater after a ‘Click’ in a single bar to show a picture and a text element to get the data (string) of that bar clicked, will be: Namefield + " is " + Agefield + " years old"

Scenario:
-Collection Name: “my collection”
-3 Field: Name, Age, Picture

Elements on page:
1- html component (to show the chart)
2-dropdown (to filter the “Age” field)
3-text element (…just for text…) (collapsed on load)
4-repeater (to show a picture) (collapsed on load)
5-dataset for “my collection” and connected to a image element in repeater

Page Code:

import wixData from 'wix-data';

$w.onReady(() => {
    filter("All");    // Filter your data on page load.
$w('#dropdown').onChange(() => { 
let chartdata = $w('#dropdown').value;
    filter(chartdata);
});

function filter(chartdata) { 

wixData.query("mycollection")
.contains("age",chartdata)
.find()
.then((res) => {
 let name = new Array() 
 let age = new Array()
 for (let i = 0; i < res.length; i++) { 

        name[i] = res.items[i].name;
        age[i] = res.items[i].age;
 
    }
 let data = [[age],[name],[chartdata]];
 
    $w('#html1').postMessage(data);
    console.log(data)
    $w('#html1').onMessage(async(event) => { 

 if (event.data.type === 'ready') { 
            $w('#html1').postMessage(data);
        }
 if (event.data.type === 'click') {
 
            $w("#text").text = event.data.label  + " is " + event.data.value + " years old.";
 let torepeater = `${event.data.label}`;
 await $w('#datasetmycollection').setFilter(wixData.filter().eq("name",torepeater))
                       $w("#repeater").expand();
                      $w("#text").expand();
        }
    });
})
.catch((err) => {
 let errorMsg = err;
});
}
});

HTML Code:
Be aware that you can customize the chart, in this case I change the bg color of bar, a tool-tip when hover over a bar and others smalls changes, anyway this is not relate to wix just read the documentation on Chartjs.

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
 <title></title>
 <script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.bundle.min.js"></script>
 </head>

 <body onLoad="ready()">

 <canvas id="myChart" width="980" height="1650"></canvas>
 <script>
 
     var ctx = document.getElementById("myChart");
       var myChart = new Chart(ctx, {
           type: 'horizontalBar',
               data: {
                     labels: [],
                           datasets: [{
                                   label: '',
                                      data: [],//start empty
                      backgroundColor: 'rgba(255, 119, 0, 0.6)',        borderColor: 'rgba(65, 65, 65, 1)',
                      borderWidth: 1}]
                          },
        options: { maintainAspectRatio: false,
              legend: {display: false}, 
              tooltips: {callbacks: {
              label: function(tooltipItem, data) {
              return tooltipItem.xLabel.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","); }, }, },
                    scales: {
                        xAxes: [{
                             ticks: {
                                 beginAtZero: true,            callback: function(value, index, values) {                    return value.toLocaleString();
                                 }
                                  }
                                   }],
                                      },
                                        onClick: handleClick
                                           }
                                             });
////everything above this is just pure chart customization////////// 

///Now 'what' the charts do with the data it receives////

 window.onmessage = function(event){
     if (event.data && Array.isArray(event.data)) {
           myChart.data.datasets[0].data = event.data[0][0];
           myChart.data.labels = event.data[1][0];
           myChart.data.datasets[0].label = event.data[2][0];
           myChart.update();
           } 
           else { console.log("HTML Code Element received a generic message:");
            console.log(event.data);
            }
            
   ////change bar bgcolor based on age selection in dropdown////         

 if (event.data[2][0] <= 20) { myChart.data.datasets[0].backgroundColor = "SlateBlue";  myChart.update();
  } 
  else if (event.data[2][0] >= 50) {    myChart.data.datasets[0].backgroundColor = "LightYellow";  myChart.update();
    } 
  else { myChart.data.datasets[0].backgroundColor = 'rgba(255, 119, 0, 0.6)';
   myChart.update();
         console.log("HTML Code Element received a generic message:");
               console.log(event.data[2][0]);
                     }
                       };
                       
//// function to handles the Click event over the bar///
                       
function handleClick(e){
    var activeBars = myChart.getElementAtEvent(e);
    var value = myChart.config.data.datasets[activeBars[0]._datasetIndex].data[activeBars[0]._index].toLocaleString();
    var label = activeBars[0]._model.label;
////Send the data back to page to do something, in this case 
////'ready' and 'click', if 'click' the text element get the //// label (Name) and the value (Age) and 'ready' to show the ///chart.
 window.parent.postMessage({
      "type":"click",
         "label":label,
            "value":value
              } , "*");
                }
 function ready(){
    window.parent.postMessage({"type":"ready"}, "*");
      }
</script>
</body>
</html>

That is, Hopefully somebody else could explain the code better than me hehehe

Good luck!

First of all thanks for your quick and wonderful explanation. But, being a dumb I couldn’t make it work. I think, I did everything as you explained.

This is how the preview looks like

First I used Number as the format for age and then changed to text to see if that will fix the issue.

Can you tell me where I went wrong.
I copy paste the Page cod as is and added the elements with the same IDs as in the code.

I added the code in HTML element as it is and changed height and width only, nothing else changed in the HTML code.

Created a database as shown above.

Where did I go wrong!!!? :frowning:

mmmmm well, I made two mistakes sorry for that
One:

////this part///

filter("All");// Filter your data on page load.

//could be omitted, what this call those its to filter data on page load so the chart is not empty, for example if you want the data of 30 years on page load, you do this:///

filter(30); 

Two

//this part//

wixData.query("mycollection")
.contains("age",chartdata)

//changed it to///

wixData.query("mycollection")
.eq("age",chartdata)

Beside this two changes I don’t see nothing wrong with the code. Try it again and let me know.

Also change the “Age” type field to number again. Remember that the Chart code have a few customization that you may not need, like a tool-tip and “,” to add a thousand separator so instead this output 1000 you get 1,000.

I did a test site a few moths back with the chart you can check it, here

Hi Liu SG,

After making those changes I thought it’s working but there’s again some issue. On loading the page chart showed for the age given in the

 onReady()
 filter(40);

. but when I change dropdown value nothing happened. Even though I do not know, I tried to make changes like, taking the entire code out of

onReady()

except

 filter(40);

and replaced

 $w('#dropdown').onChange(() => { 
let chartdata = $w('#dropdown').value;
    filter(chartdata);
});

with

export function dropdown_change(event) {
let chartdata = $w('#dropdown').value;
console.log(chartdata)
    filter(chartdata);
}

after this, when I change dropdown value chart changes it’s current values but nothing new was shown.
I don’t think I can do anything more than this. ;).

Thanks for your time.

hey man don’t give up, just check what you missed and its working. If the page load and the chart shows the data, that means that the code part is working.

Now if you change you the selection in dropdown two thing can happen:

1-the chart does not update its data.
2-the chart updated but with empty values.

If the first happen, probably means that there is not ‘connection’ between the dropdown and chart, you make sure to use the correct ID, by default the dropdown is ( $w ( ‘#dropdown1’ ). value) but you have in code ($w ( ‘#dropdown’ ). value).

If the second, means a ‘miss match’ between the dropdown and the filter code, so make sure that the value from dropdown match the data type for the field (for data types check here) “Age” . So lets say that you want to filter all data with the 30 of field named 'Age", you will need:
-a Label, could by anything, I use “30’s”
-a value, I use 30 as a value to the label “30’s”.

Now if the field “Age” data type is number the code page for filter is:
.eq(“age”, 30)
if it is data type text:
.eq(“age”, “30”)

You can check to what type of data field input elements connect to. ( here )

After checking this things out let me know. If you still struggling with this. I’ll post (code and the picture) from the test page, you can see it works flawlessly.

good luck :slight_smile:

hurray!!!

It took me only a second to fix the issue even though I did know that it was a mistake but I just tried to check if that was an issue. And, that thought came to mind after reading your line " value from dropdown match the data type for the field".
I thought if the value in a dropdown is a number then it would take it as a number by default, hence I didn’t use any type conversion. All I did this time is

change

let chartdata = $w('#dropdown').value;

to

let chartdata = Number($w('#dropdown').value);

and it worked when I change the dropdown selection.

By the way, I forgot to tell you in my last post that I checked you website and it’s working good.
Also, my repeater was and is not working. But the text label changes as we change selection.

Could you check only this line of code, I tried changing as much as I could but to no avail.

let torepeater = `${event.data.label}`;
 await $w('#datasetmycollection').setFilter(wixData.filter().eq("name",torepeater))

I think, If we could make the repeater work then we are done with this code.

Yes, I have a dataset with this name datasetmycollection

I must say that you are more than a so-called human to write all these lines of codes and spend time for this.

hahah almost done with it… Good.

First thing is to check that all elements are connected to repeater, so:

1-connect mycollection to a dataset element.
2-connect the dataset element to repeater.
3-connect the text element inside the repeater to the field named “Name”
4 -connect the image element inside the repeater to the field named “Picture”

this line of code activated when you click in a single bar:

let torepeater = `${event.data.label}`;
 await $w('#datasetmycollection').setFilter(wixData.filter().eq("name",torepeater))

If you click the bar assigned to “Sample1” , the code becomes:

let torepeater = "Sample1";
await $w('#datasetmycollection').setFilter(wixData.filter().eq("name",torepeater))

Doble check this things and let me know how goes. Btw datasetmycollection is the ID of the dataset not the name, of course the Name and ID can share the same name but just to point this out.

Oh gosh!!! I’ve never seen such a dumb like me… lol.

I knew that repeater elements need to be connected to dataset and I have created many repeaters like this in last week, needless to mention all these I learned with the help of people like you, but you are exceptional though.

I even thought about connecting it once and then I thought you have done it programmatically and no need to connect it like this. Mainly because I did not understand that for loop and Array () part.

Anyway, it’s working now perfectly and as expected.

Only change I made to your code is

filter("All"); 

as this is not working
to

filter(); 

and

let chartdata = $w('#dropdown').value;

to

let chartdata = Number($w('#dropdown').value);

Many people will definitely view and take advantage of this post as there are few help available online on Charts on Wix

This was only a test chart for me, I now need to tweak this to suit my requirement.

My coffee is getting cold but I know I should give priority to reply you than to my coffee, hehe.

Thank you so much.
You are awesome.

Hi,

I am back again. We were making a sample chart then and now I want to make a chart with my original data.
What exactly I want is a chart of items that was purchased between two dates and its amount.
Before I make many changes to your code to get what I want, I only tried the following but that did not work as I expected. I was planning to tweak your code gradually if I could successfully do following. Now I know I can’t.

Instead of ‘age’ and ‘name’ what I want to filter the database is with date and item name. I changed dropdown id to the datePicker, name with itemName , age with date .

Something is working, a positive signal…
With the above changes on load chart shows an item with its amount. When I change the date the current item from the chart is gone and no new item is appeared in the chart. Default date of the date picker is set as Today’s date and there is no data in the database with that date and I do know know how that item came into the chart. and when I change the date back to today that does not shown in the chart. It’s only showing on page load.

Also, please check if this is how value from a date picker is stored in a variable.

import wixData from 'wix-data';

 $w.onReady(() => {

filter(); // Filter your data on page load.
    $w('#startDate').onChange(() => {
 let chartdata = Number($w('#startDate').value);
        filter(chartdata);
    });

 function filter(chartdata) {

        wixData.query("ListOfItems")
            .eq("PurchaseDate", chartdata)
            .find()
            .then((res) => {
 let item = new Array()
 let date = new Array()
 for (let j = 0; j < res.length; j++) {
                    item[i] = res.items[i].itemName;
                    date[i] = res.items[i].purDate;
                }
 let data2 = [
                    [item],
                    [date],
                    [chartdata]
                ];

                $w('#html2').postMessage(data2);
                console.log(data2)
                $w('#html2').onMessage(async (event) => {

 if (event.data2.type === 'ready') {
                        $w('#html2').postMessage(data2);
                    }

                });
            })
            .catch((err) => {
 let errorMsg = err;
            });
    }
});

This is the sample of dates in the database.

I tried date format of date picker to the following but nothing worked

MM/DD/YYYY
DD/MM/YYYY

Can you tell me how to do this, purchase items and amount between two dates

Thank you.

Did you get an example working my friend? I really need to see how to do this and that other example is really not working

Is Chart.js still compatible with Wix? Can not get code to work, any tutorials that may be recommended would be helpful
Cannot find module ‘chart.js’ in 'public/pages/mu2e2.js