Search code examples
djangopostgresqlhighchartspie-chartdataformat

pie chart highcharts from django query


I am running a query in views.py in a django environment. All is currently running local with the idea to push it finally into a heroku environment. I use PostgreSQL.

def test(request):
    click_results = clickstats.objects.filter(user=request.user.username, urlid=pk_int)
    data = parse_data_browser(request, click_results)
    template = get_template('index.html')
    context = {
    'data': data,
    }
    return HttpResponse(template.render(context,request))

def parse_data_browser(request,click_results):

    browsers = click_results.values('browser').annotate(browser_qty=Count('browser')).order_by()
    print("browsers")
    print(browsers)
    return browsers

the printed output by parse_data_browser looks like this:

<QuerySet [{'browser': 'Chrome Mobile', 'browser_qty': 4}, {'browser': 'Chrome', 'browser_qty': 9}]>

the challenge is to get it in this shape:

data = [{name: 'Chrome Mobile', y: 4}, {name: 'Chrome', y: 9}]

then passing it on to my index.html using following scripts:

<script>
    var chart_id = {{ chartID|safe }}
    var chart = {{ chart|safe }}
    var title = {{ title|safe }}
    var yAxis = {{ yAxis|safe }}
    var data = {{ data|safe }}
</script>

and finally create the chart with this script:

<script>
$(function () { 
    var myChart = Highcharts.chart('chartID', {
        chart: {
            plotBackgroundColor: null,
            plotBorderWidth: null,
            plotShadow: false,
            type: 'pie'
        },
        series: [{
            name: 'Brands',
            colorByPoint: true,
            data: [{name: 'Chrome Mobile', y: 4}, {name: 'Chrome', y: 9}]
        }]
    });
});
</script>

I tried multiple things with dict and append functions, but nothing does give the right output.

What is the best approach. I would rather not start stacking output-json files on my environment as that seems one way to go.

thanks for the help


Solution

  • you can iterate on the query and build a list:

    data = [{'name': item['browser'], 'y': item['browser_qty'] }
             for item in parse_data_browser_result.all() ]
    

    This is called a list comprehension.

    Or you can still pass the queryset to the template and build the data like this:

    data: [
        {% for item in data.all() %}
            {% if total > 0 %}
                { name: "{{ item['browser'] }}", y: {{ item['browser_qty'] }} },
            {% endif %}
        {% endfor %}
    ]
    

    inside the <script>.