How to add other charts in Report Charts, For ex. Line Chart, Bubble Chart, Gauge chart, Funnel Chart etc.

I have a working example with both a chart and a table (also rendered by Google), also from the same data, so it should be the same as your case. After setting all the properties on the graphs this is how it ends:

        // Instantiate and draw our chart, passing in some options.
        var chart = new google.visualization.Sankey(document.getElementById('chart_div'));
        chart.draw(data, options);

        var table = new google.visualization.Table(document.getElementById('table_div'));

        table.draw(data, {showRowNumber: true, width: '100%', height: '100%'});


<div style="zoom: 1.0; -moz-transform: scale(1.0); transform-origin: 0 0; -moz-transform-origin: 0 0">
    <!--Table and divs that hold the charts-->
    <table class="columns" align="center">
        <td><div id="chart_div" style="border: 1px solid #ccc;"></div></td>
      <td><div id="table_div" style="border: 1px solid #ccc;"></div></td>

Thank you very much for your reply.

I apologize for the confusion. I basically followed your instructions posted on “5 Oct 2018 12:48” and created 2 different charts. So I repeated your steps 1 to 5 twice. Meaning, I created two entry points, two different google chart files, 2 different dashlets and maybe because of this, I get Javascript conflict (Dashboard keeps reloading and not working).

I am trying to have 3 google charts,

  1. All leads by Status - Column Chart
  2. All Open Tasks by assigned users - Pie Chart
  3. All Converted leads by month - line Chart.

Kindly, let m know if I can achieve what I want by following your steps and repeating them 3 times? and how do I solve the Javascript conflict?

I don’t know, I never tried it, but…

Are you giving different names to the Javascript variables, and to the divs?

What errors do you see in your browser’s Javascript console?

I see this error. and not sure how to rename the variables or the divs.
Any idea what is this error is?

You’re messing up your Javascript. ArrayToDataTable is a static method, a helper function, not an object that you can instantiate with new

It would be easier to help you if you shared your entire code.

Hi @pgr so sorry for the late response. Here is what I have done.

So I have followed your instructions above and created 2 different entry point:
File 1: custom/Extension/application/Ext/EntryPointRegistry/googleCharts1.php
File 2: custom/Extension/application/Ext/EntryPointRegistry/googleCharts2.php
(I actually need to create multiple charts using Google chart but the data will have to be different)

and then I created the following chart files in (/custom/charts):

Sorry couldn’t copy the code here as it wont let me.

Thanks a lot for your help with this.

Focus on the name chart_div. You can’t repeat that for both charts, if they’re showing in the same page.

The id of the div you specify in the HTML part:
<td><div id="chart_div" style="border: 1px solid #ccc;"></div></td>

… must match what you tell the Google visualization object to use:

var chart = new google.visualization.ColumnChart(document.getElementById("chart_div"));

Then, for the second chart, change both of those: a new div id in the HTML, and that same id is passed to the visualization object.

You can paste code here by enclosing it in triple-backtick tags, like this:


Using custom Entrypoint and Adding Web URL Dashlets, it produces amazing results.


That’s really :cool:, yes!

I love your typo: instead of Sankey graph, you called it a Snakey graph… which actually describes it a lot better :stuck_out_tongue:


I wanted to ask a little extra help with database queries to get the following charts:

  1. Active Leads by Status (excluding dead/close/converted leads) - column chart
  2. Active Product by Status (I created a custom dropdown called Status for the product module, so want to show all products excluding dead/close products) - bar chart
  3. Ready products by month/year (custom dropdown “status = Ready, Final, Delivering” and group them by two custom fields Month and years. I created one dropdown with all months and one dropdown with year from 2019 to 2025. Is it possible to group the results to Jan 2020, Feb 2020)? - Column Chart
  4. Best Converted Source - Pie Chart
  5. Active Leads by Quality - Leads status=non equal to dead, converted. Group the results by a custom dropdown called Quality (includes Good, Bad, Very Good) - Pie Chart
  6. Open Tasks by Assigned Users = Pie Chart
  7. Open Meetings by Assigned Users = Pie Chart

I am not very familiar with DB queries so would really appreciate your help.

Also wanted to ask your opinion on:
I can get the reports with build in reports and chart and apply necessary filters but can’t figure out the DB queries to build google charts. Is there an easy way find what DB queries is being used after I create an report?

I’m glad you got it working.

I don’t have much time to look at your questions right now, but this should be enough: put your log level at DEBUG in Admin / System settings, then every query should be in the logs. You can run the reports and get the queries.

This might also help if you want to understand things better:

Hey All, I know this is an old thread, but hoping someone who’s tried this can chime in. First THANK YOU to all in this thread, I tried this out and it works great. So easy!

However, I have an installation for a client that I keep getting: "Incorrect website location is specified
" in the dashlet. It works in the browser OK, just not the dashlet. I’ve done this in other installs and it works fine. I inspected the display() function that drives the URL check and it looks to me like it only checks it’s in the format https:// or http:// (which it is), it shouldn’t even matter if it resolves. I’m kind of stumped, anyone have any ideas?

hmm, I found this in: modules/Home/Dashlets/iFrameDashlet.php

It prevents this from working! It’s not in my install but happens to be in the latest code on Github too.

If you are pasting in an internal URL like to a entryPoint it will always return true and then blank out the URL and the dashlet won’t work. Not sure why this was added?

 if (isSelfRequest($this->url)) {
            $this->url = '';

Anyone know why this was added? Going to ad a bug on github. I can’t see why this is necessary or what it’s purpose is?

I’d say it’s a security measure. I’m just guessing, but there’s probably a way to hijack SuiteCRM from within dashlets if you bring in malicious web content, and this helps prevent it.

Probably the security measure can be improved. One way to do it would be to use the entryPoint registry as a white-list.

@pgr that’s what I was thinking (that’ s the only logical explanation I could come to!). I’ll have a look at the “isSelfRequest” function and see if I can add an exception for URL contains “entryPoint=” or something like that.

That could be a good solution for you, but won’t be good enough as a generic solution, because it would be easy to just insert that string to get past the security check.

If the $entry_point_registry variable is available, we could check for those entries at the beginning of the URL, after the site_url part.

I’m wondering if we can check that the entry point is a valid entry point and get a list of entry points that exist. Something like that. Who knows, maybe this was instituted to prevent iframe of entry points? Not sure what the exact security issue was as it’s not public. Maybe the dev who did this on Github will comment on my issue there.

I guess I could create a custom dashlet too that displays the iframe, but maybe that would be subject to the same constraint, not sure until I try.

I think the threat is that if you configure a Dashlet with some external content, that content can just come in and start making requests into the same web server (thus the check being called isSelfRequest) as if it is logged in.

:point_up: this is exactly what I meant regarding the $entry_point_registry variable, see here

Then the custom entry-points are added to that.

The enhanced check should make sure that any requests inside the dashlets are going only to known entry-points that require authorization. This would guarantee that they have all the safeguards in place.

Hey @pgr I didn’t have much luck trying to get the list of entry points from entry_point_registry.php, so instead I went to the custom file that gets created when new entry points are added and searched through there for valid entry point. Then added an exception to the getCustomEntryPoints where the URL matches a valid custom entry point. I added on github so hopefully the original author of this check will chime in.

1 Like

@pstevens : Thanks for this solution and sharing the detailed code, I am using your solution in /include/utils.php.

1 Like