1

UPDATE:

I've been trying to replicate the method used in this solution thread to display a Highcharts graph via Django, but in vain. I'm passing data from a python script to my views.py file, but the graph doesn't show up.

Below is what I get when I check view source in my browser. What am I missing in this html doc? The graph is not showing up.

<!DOCTYPE html>
<html lang="en">

<head>
    <title>Head title here</title>
    <meta charset="utf-8" />

    <link rel="stylesheet" href="/static/css/bootstrap.min.css" type = "text/css"/>
    <meta name="viewport" content = "width=device-width, initial-scale=1.0">

    <style type="text/css">
        html,
        body {
          height:100%
        }
    </style>
</head>

<body class="body" style="background-color:#f6f6f6">
    <div class="container-fluid" style="min-height:95%; ">
        <div class="row">
              <div class="col-sm-2">
                  <br>
                  <center>
                    <img src="/static/img/profile.jpg" class="responsive-img" style='max-height:100px;' alt="face">
                  </center>
              </div>
              <div class="col-sm-10">
                  <br>
                  <center>
                  <h3>Some stuff goes here</h3>
                  </center>
              </div>
        </div><hr>

        <div class="row">
          <div class="col-sm-2">
          <br>

          <br>
            <!-- Great, til you resize. -->
            <!--<div class="well bs-sidebar affix" id="sidebar" style="background-color:#fff">-->
            <div class="well bs-sidebar" id="sidebar" style="background-color:#fff">
              <ul class="nav nav-pills nav-stacked">
                <li><a href='/'>Home</a></li>
                <li><a href='/blog/'>Blog</a></li>
                <li><a href='/contact/'>Contact</a></li>
              </ul>
            </div> <!--well bs-sidebar affix-->
          </div> <!--col-sm-2-->
          <div class="col-sm-10">

            <div class='container-fluid'>
            <br><br>

<body>
    <div id="chart_ID" class="chart" style="height:100px; width:100%"></div>
</body>

            </div>
          </div>
        </div>
    </div>
</body>

</html>

Original post:

my my-app/views.py file

from __future__ import unicode_literals
import datetime
from django.shortcuts import render
from . import python_script

def plot(request, chartID = 'chart_ID', chart_type = 'bar', chart_height = 500):

    data = python_script.chart_function()
    categories = python_script.chart_categories()
    chart = {"renderTo": chartID, "type": chart_type, "height": chart_height,}
    title = {"text": 'my title here'}
    xAxis = {"title": {"text": 'axis title here'}, "categories": categories}
    yAxis = {"title": {"text": 'axis title here'}}
    series = [
        {"name": 'Asia Pacific', "data": data['Asia Pacific']},
        {"name": 'CIS', "data": data['Commonwealth of Independent States']},
        {"name": 'Europe', "data": data['Europe']},
        {"name": 'Latin America', "data": data['Latin America']},
        {"name": 'MENA', "data": data['Middle East and North Africa']},
        {"name": 'Northern America', "data": data['Northern America']},
        {"name": 'SSA', "data": data['Sub-Saharan Africa']}
    ]

    return render(request, 'my-app/chart.html', {'chartID': chartID, 'chart': chart,
                                                'series': series, 'title': title,
                                                'xAxis': xAxis, 'yAxis': yAxis})

In my views.py file:

  • the format of data is a dictionary: {'Asia Pacific':[1,2,3,4],'Europe':[1,2,3...], ...}
  • the format of categories is a list of strings: ['A', 'B', ...]

my my-app/chart.html file

{% load compress %}
{% compress js %}
<script src="{{ STATIC_URL }}jquery-3.2.1.js"></script>
<script src="{{ STATIC_URL }}jquery-3.2.1.min.js"></script>
<script src="{{ STATIC_URL }}Highcharts-5.0.14/code/js/highcharts.js"></script>
<script src="{{ STATIC_URL }}Highcharts-5.0.14/code/js/modules/exporting.js"></script>
{% endcompress %}

{% block heading %}
    <h1 align="center">Analysis</h1>
{% endblock %}

{% block content %}
    <div id={{ chartID|safe }} class="chart" style="height:100px; width:100%"></div>
{% endblock %}

{% block overwrite %}
<!-- Overwrite the base.html jQuery load and put in head for Highcharts to work -->
{% endblock %}

{% block extrajs %}
<!-- Maps the Python template context variables from views.py to the Highchart js variables -->
<script>
    var chart_id = {{ chartID|safe }}
    var chart = {{ chart|safe }}
    var title = {{ title|safe }}
    var xAxis = {{ xAxis|safe }}
    var yAxis = {{ yAxis|safe }}
    var series = {{ series|safe }}
</script>

<!-- Highchart js. Variable map shown above -->
<script>
$(document).ready(function() {
    $(chart_id).highcharts({
        chart: chart,
        title: title,
        xAxis: xAxis,
        yAxis: yAxis,
        series: series
    });
});
</script>
{% endblock %}

my my-app/urls.py file

from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^$',views.index, name='index'),
    url(r'^graph/', views.plot, name = 'plot'),
]

my settings.py file

INSTALLED_APPS = [
    'my-app',
    'highcharts',
    'jquery',
    'compressor',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
...
STATIC_ROOT = 'static'
STATIC_URL = '/static/'
MEDIA_ROOT = 'media'
MEDIA_URL = '/media/'

I have ran the command python manage.py collectstatic already.

Joss
  • 197
  • 1
  • 5
  • 18

1 Answers1

1

Directly rendering Python data structures like lists and dictionaries in your template to use them in JavaScript can work, but it is unreliable. Instead, convert them to JSON in your view:

import json
...
return render(request, 'my-app/chart.html',
              {'chartID': json.dumps(chartID), 'chart': json.dumps(chart),
               'series': json.dumps(series), 'title': json.dumps(title),
               'xAxis': json.dumps(xAxis), 'yAxis': json.dumps(yAxis)})

In you template, use the JSON like this:

var chartID = JSON.parse("{{ chartID|escapejs }}")

If that doesn't solve the issue, check the JavaScript console of your browser for error messages.

Daniel Hepper
  • 28,981
  • 10
  • 72
  • 75
  • Thanks Daniel - it didn't solve it, but I checked the JavaScript console and it does show 4 alerts for each static file I'm loading, the alerts say: Uncaught SyntaxError: Unexpected token – Joss Sep 05 '17 at 12:27
  • Apparently your static files do not contain valid JavaScript, that sounds to me like the files cannot be loaded correctly. Check the URL in page source and see what it returns. – Daniel Hepper Sep 05 '17 at 12:51
  • BTW, it is a good idea to update your original question with these findings so others can easier follow along and chime in. – Daniel Hepper Sep 05 '17 at 12:51
  • Thanks Daniel - you're correct, in view source, the page displays exactly the code as it's written in the chart.html file above. The first line says . It doesn't seem to be interpreting the page as – Joss Sep 05 '17 at 13:50
  • I just realized that your template probably extends another template, but misses an `{% extends ... %}` tag in the first. – Daniel Hepper Sep 05 '17 at 13:54
  • @DanielHepper you should include in your snippet how to use the json, e.g., `` – Jiaaro Sep 05 '17 at 15:52
  • thanks @Jiaaro, I've tried your approach without success. How would you recommend implementing? Also, I wonder if I'm missing something in my *chart.html* file in the {block overwrite} section ... could that be? – Joss Sep 05 '17 at 17:04