• Djangoing

    Ole Andreas Utstumo05/14/2019 at 18:13 0 comments

    Using some simple jQuery Ajax the Highcharts graphs now retrieves data from a Django view on my server at will. Which means events like loading the page or clicking any buttons can call my view to get fresh weather data. Thanks to Vitor for the crystal clear, cut to the chase examples on how to do this at SimpleIsBetterThanComplex. Keep in mind that I'm a total newbie on web programming, so don't take me for an authority on the subject ;-) I just piece together stuff that work using a combination of a) tutorials and examples, b) the official documentation, c) stackoverflow.com and d) assumptions from past programming experience.

    Taking one of the templates from geetbootstrap.com I've mashed together this:

    If only you could add 240 m/s wind gusts to your customer orders...

    The basic structure around this is (and this is inspired heavily by Vitor's article):

    A HTML container in my template with the special parameter "data-url":

    <div id="container" data-url="{% url 'chart_data' %}">
        <div id="plot1"></div>
        <div id="plot2"></div>
    </div>

     A jQuery script in the same template which will trigger when he container element loads and query the Django site for the URL named "chart_data":

    $.ajax({
        dataType: 'json',
        url: $("#container").attr("data-url"),
        success: function (data){
            console.log("Fekk tak på dataen");
            renderPlot(data);
        },
        error: function (error){
            console.log("Feil...");
            console.log(error);
        }
    });

     The "chart_data" URL will be routed through the urls.py file to the view called by the same name:

    urlpatterns = [
        path('', views.about),
        path('data/', views.chart_data, name='chart_data'),
    ]

     And the view will respond with a JSON object in the following matter:

    def chart_data(request):
    
    
        dataset = weatherHour.objects.all().order_by('timestamp').filter(timestamp__range=[datetime.now()-timedelta(days=filter_days), datetime.now()])
        temperature_out_list = []
        temperature_in_list = []
        pressure_list = []
        wind_av_list = [] #needs to be a dict for highcharts wind barbs
        wind_gust_list = []
        humidity_list = []
        rain_list = []
        for d in dataset:
            temperature_out_list.append([int(d.timestamp.strftime("%s")) * 1000, d.temperature_out])
            rain_list.append([int(d.timestamp.strftime("%s")) * 1000, d.rain])
            temperature_in_list.append([int(d.timestamp.strftime("%s")) * 1000, d.temperature_in])
            pressure_list.append([int(d.timestamp.strftime("%s")) * 1000, d.pressure])
            wind_av_list.append([int(d.timestamp.strftime("%s")) * 1000, d.wind_av_ms, d.wind_deg])
            wind_gust_list.append([int(d.timestamp.strftime("%s")) * 1000, d.wind_gust_ms, d.wind_deg])
            humidity_list.append([int(d.timestamp.strftime("%s")) * 1000, d.humidity])
        chart = {'temperature_out': temperature_out_list,
            'rain': rain_list, 
            'temperature_in': temperature_in_list, 
            'pressure': pressure_list, 
            'wind_av': wind_av_list,
            'wind_gust': wind_gust_list,
            'humidity': humidity_list
            }
        return JsonResponse(chart, safe=False)
     (The weatherHour object which is part of the starting Django query is a database model where hourly weather data is stored, alongside a weatherDay model for daily aggregates for the weather. Think max, min and mean for temperature, wind, humidity, etc.)

    Finally, in our template, our data is received and our renderPlot(data) function is called:
    function renderPlot(weatherData){
        console.log((weatherData));
        
        Highcharts.chart('plot1', {
            plotOptions: {
            series: {
                marker: {
                    enabled: false
                }
            }
        },
        chart: {
            zoomType: 'x',
        },
        title: {
            text: null,
        },
        tooltip: {
                valueDecimals:1,
                shared: true,
                useHTML: true,
                headerFormat:
                    '<small>{point.x:%A, %b %e, %H:%M} - {point.point.to:%H:%M}</small><br>' +
                    '<b>{point.point.symbolName}</b><br>'
    
            },
        xAxis: [{
            type:'datetime',
            crosshair: true,
            },
            { // Top X axis
            linkedTo: 0,
            type: 'datetime',
            tickInterval: 24 * 3600 * 1000,
            labels: {
                format: '{value:<span style="font-size: 12px; font-weight: bold">%a</span> %e. %b}',
                align: 'left',
                x: 3,
                y: -5
            },
            opposite...
    Read more »

  • Setting up the charts

    Ole Andreas Utstumo05/07/2019 at 19:31 0 comments

    Took me a while to "get" Highcharts, but the pieces are starting to fall in place. Luckily, there's a wealth of live examples and demos in the documentation to lend inspiration from...
    It's all test data for now, generated by two python scripts and stored in my Django web app's database.