search

Home  >  Q&A  >  body text

Highcharts in Django: Display JSON data instead of charts on a web page

So I tried to make a candlestick chart using Highcharts in Django, but it failed to show the chart on the web page, instead it showed a JSON list of the fetched data.

I am using iexcloud’s API to obtain historical data

This is my logic: View.py file:

def candlestick_chart_data(request):
    api_key = 'my_api_key'
    stock_data = get_historical_data(
        "AAPL", start="2023-01-01", end="2023-05-05", output_format="pandas", token=api_key)
    stock_data_array = [{
        'x': date.isoformat(),
        'open': row['open'],
        'high': row['high'],
        'low': row['low'],
        'close': row['close']
    } for date, row in stock_data.iterrows()]
    return JsonResponse(stock_data_array, safe=False)

My template, namely candlestick_chart.html

{% extends 'base.html' %}

{% block content %}

{% block home_css %}
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highcharts/9.2.1/css/highcharts.css"
        integrity="sha512-bwK5pU3LlQlAocA38e/L90g86uJUZVvJEnpnT5ZyL0j3frzAKcJbhdTl0z0W4pVfTqBqftbX2y/3D2wLxbt6uQ=="
        crossorigin="anonymous" referrerpolicy="no-referrer" />
    <script src="https://code.highcharts.com/highcharts.js"></script>
    <script src="https://code.highcharts.com/modules/stock.js"></script>
    <script src="https://code.highcharts.com/modules/exporting.js"></script>
    <script src="https://code.highcharts.com/modules/export-data.js"></script>
{% endblock %}

<div id="container" style="height: 500px; width: 100%;"></div>


<script>
    

    const dataURL = '{% url "candlestick-chart" %}';

    /**
     * Load new data depending on the selected min and max
     */
    function afterSetExtremes(e) {
        const { chart } = e.target;
        chart.showLoading('Loading data from server...');
        fetch(`${dataURL}?start=${Math.round(e.min)}&end=${Math.round(e.max)}`)
            .then(res => res.ok && res.json())
            .then(data => {
                console.log(data)
                chart.series[0].setData(data);
                chart.hideLoading();
            }).catch(error => console.error(error.message));
    }

    fetch(dataURL)
        .then(res => res.ok && res.json())
        .then(data => {
            data.forEach((d) => {
                d.x = new Date(d.x);
            });
            // create the chart
            Highcharts.stockChart('container', {
                chart: {
                    type: 'candlestick',
                    zoomType: 'x'
                },

                navigator: {
                    adaptToUpdatedData: false,
                    series: {
                        data: data
                    }
                },

                scrollbar: {
                    liveRedraw: false
                },

                title: {
                    text: 'AAPL history by the minute from 1998 to 2011',
                    align: 'left'
                },

                subtitle: {
                    text: 'Displaying 1.7 million data points in Highcharts Stock by async server loading',
                    align: 'left'
                },

                rangeSelector: {
                    buttons: [{
                        type: 'hour',
                        count: 1,
                        text: '1h'
                    }, {
                        type: 'day',
                        count: 1,
                        text: '1d'
                    }, {
                        type: 'month',
                        count: 1,
                        text: '1m'
                    }, {
                        type: 'year',
                        count: 1,
                        text: '1y'
                    }, {
                        type: 'all',
                        text: 'All'
                    }],
                    inputEnabled: false, // it supports only days
                    selected: 4 // all
                },

                xAxis: {
                    events: {
                        afterSetExtremes: afterSetExtremes
                    },
                    minRange: 3600 * 1000 // one hour
                },

                yAxis: {
                    floor: 0
                },

                series: [{
                    data: data,
                    dataGrouping: {
                        enabled: false
                    }
                }]
            });
        }).catch(error => console.error(error.message));
</script>
{% endblock %}

And my url path (if needed):

path('candlestick-chart-data/', views.candlestick_chart_data, name='candlestick-chart'),

This is the output I get on the web page Localhost web image

I tried putting console.log statements into the code, tried printing the data in the terminal, everything works fine, but I can't understand why the chart doesn't appear in the webpage if everything works fine

P粉310931198P粉310931198264 days ago468

reply all(1)I'll reply

  • P粉420958692

    P粉4209586922024-04-03 00:20:33

    I would second @kikon's suggestion - it would be helpful to a) see the actual source code of the localhost page being generated, and b) look at the console output to see if any JS errors are thrown. Without seeing these, I'm afraid I can't be of much help here.

    However, One thing that might be relevant is that you are currently loading <script/> tags in your HTML <body>.

    This is somewhat of an anti-pattern, as it means that your Highcharts constructor (Highcharts.stockChart()) may be executed before the relevant Highcharts module has a chance to load, which will throw # in the console ##ReferenceError .

    A better pattern is to include the

    <script/> tag inside a <head/> block and use the defer attribute, then Trigger the Highcharts constructor on a DOM related event, such as DOMContentLoaded or similar (the exact event may depend on your specific use case/process).

    Another pattern to accomplish the same task is to use an asynchronous function that retries (catching the relevant

    ReferenceError) until the script is loaded.

    Of course, these are just guesses - it's hard to determine exactly what's going on here without looking at the HTML output and console output.

    By the way, if you're trying to integrate Highcharts into Django, you might also want to check out the

    Highcharts for Python toolkit has just been released as a paid plugin for Highcharts (full disclosure, I'm a fan of the Highcharts for Python toolkit package creator), which can simplify some of your Django view integrations. In the meantime, I hope this answer helps you diagnose/solve the problem, and if you share more details, I'll be happy to revise this answer with a more accurate diagnosis/suggestion.

    reply
    0
  • Cancelreply