0

I'm modifying the main dashboard of my Wagtail app to provide more useful/relevant data such as the number of open work orders, or number of customers.

I am having some trouble getting my Chart.js to display in my dashboard. I've confirmed that the resource chart.js (version 2.8.0) is loading, and my canvas element is loaded onto the page as well. Still, the chart will not display.

Here's some code. This is all in my 'dashboard' app.

wagtail_hooks.py

class WelcomePanel:
    order = 5000

    def __init__(self, request):
        self.request = request
        self.logged_in_user = request.user.username

    def render(self):
        return render_to_string('wagtailadmin/dashboard.html', {
            'logged_in_user': self.logged_in_user,
        }, request=self.request)

# simply pass the 'request' to the panel
@hooks.register('construct_homepage_panels')
def add_another_welcome_panel(request, panels):
    panels.append(WelcomePanel(request))

templates/wagtailadmin/dashboard.html

{% load static %}

<h1> This text is visible </h1>
<canvas id="pie_chart" height="604" width="1210" style="display: block; width: 605px; height: 302px;"></canvas>

<script src="{% static 'js/chart.js' %}" type="text/javascript"><script>

<script tyle="text/javascript">
var stars = [135850, 52122, 148825, 16939, 9763];
var frameworks = ["React", "Angular", "Vue", "Hyperapp", "Omi"];

document.addEventListener('DOMContentLoaded', function() {
  var ctx = document.getElementById("pie_chart").getContext('2d');
  var myChart = new Chart(ctx, {
  type: "pie",
  data: {
    labels: frameworks,
    datasets: [
      {
        label: "Github Stars",
        data: stars,
        backgroundColor: [
          "rgba(255, 99, 132, 0.2)",
          "rgba(54, 162, 235, 0.2)",
          "rgba(255, 206, 86, 0.2)",
          "rgba(75, 192, 192, 0.2)",
          "rgba(153, 102, 255, 0.2)"
        ],
        borderColor: [
          "rgba(255, 99, 132, 1)",
          "rgba(54, 162, 235, 1)",
          "rgba(255, 206, 86, 1)",
          "rgba(75, 192, 192, 1)",
          "rgba(153, 102, 255, 1)",
        ],
        borderWidth: 1
      }
    ]
  }
});
}, false);
</script>

EDIT I have tried setting async defer as well as an event listener to only execute the chart creation when the DOM is fully loaded with DOMContentLoaded.

Joe Howard
  • 307
  • 5
  • 27
  • Have you tried `var ctx = document.getElementById('pie_chart').getContext('2d');` ? (adding the getContext call to the dom element query result). https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext – LB Ben Johnston Dec 21 '20 at 01:49

1 Answers1

1

I have not run this code locally but just a quick suggestion - you may need to wait until the DOM is loaded before running the getElementById and the new Chart part.

This is because the document query will return nothing until the page is fully rendered.

<script tyle="text/javascript">
// note: you can set up your stars/frameworks and other data outside of the callback below
// the key thing is that the DOM writing and dom query (getElementById) are inside the callback

document.addEventListener('DOMContentLoaded', function() {

   var ctx = document.getElementById("pie_chart");
   var myChart = new Chart( /* ... code here */);

}, false);

</script>

You can read more about this here: https://developer.mozilla.org/en-US/docs/Web/API/Window/DOMContentLoaded_event

Here is a SO question also https://stackoverflow.com/a/11936919/8070948

LB Ben Johnston
  • 4,751
  • 13
  • 29
  • I'm a complete bonehead. Thanks for your help, LB. Note line 4 where I am importing chart.js, my closing script tag is just missing a /. Thanks again for your help. – Joe Howard Dec 21 '20 at 01:58
  • All good. You're not a bonehead, sometimes the simplest things can get anyone stuck for hours. Good on you for reaching out - better to ask for help - even if that just gives you a chance to look at your work afresh. – LB Ben Johnston Dec 21 '20 at 02:57