Linked Questions

Popular Questions

I am doing a project which uses flask, flask-socketio from python, html and javascript. It draws a chart on html server with the input taken from client side. However, I am trying to do a chart with the Google visualization and using ChartRangeFilter. I can't figure out why the chart is not drawn on the html.

Below is the js code that I wrote to draw the chart

// load google charts library
google.load("visualization", "1.1", {packages:['corechart', 'controls']});

// for percentage data
var dashboard, data, chart, options;

var i = 0;

google.setOnLoadCallback(drawChart);

/* initialize chart1 - rest, walk, fast_walk data */
function drawChart() {
    var dashboard = new google.visualization.Dashboard(
      document.getElementById('dashboard'));

    var control = new google.visualization.ControlWrapper({
        'controlType': 'ChartRangeFilter',
        'containerId': 'control',
        'options': {
        // Filter by the date axis.
        'filterColumnIndex': 0,
        'ui': {
          'chartType': 'LineChart',
          'chartOptions': {
            'chartArea': {'width': '90%'},
            'hAxis': {'baselineColor': 'none'}
          }
        }
        }
        // Initial range: 2012-02-09 to 2012-03-20.
        'state': {'range': {'start': 0 'end': 10}}
        });

    var chart = new google.visualization.ChartWrapper({
        'chartType': 'CandlestickChart',
        'containerId': 'chart',
        'options': {
        // Use the same chart area width as the control for axis alignment.
            'chartArea': {'height': '80%', 'width': '90%'},
            'hAxis': {'slantedText': false},
            'vAxis': {'viewWindow': {'min': 0, 'max': 100}},
            'legend': {'position': 'none'}
        },
    });

    var data = new google.visualization.DataTable();
    data.addColumn('count', 'Count');
    data.addColumn('percent', 'Percentage');
    data.addRow([
        '0',
        0
    ]);

    // var chart = new google.visualization.LineChart(document.getElementById('data-container'));
    // chart.draw(data, options);
    dashboard.bind(control, chart);
    dashboard.draw(data);
    // return(dashboard);
}

/* update the chart1 - percentage data */
function updateChart(percentage) {
    i = (i + 1);

    data.addRow([
        ""+i,
        percentage
    ]);

    chart.draw(data, options);
}

$(function() {
    chart = drawChart();
});


/* reset charts */
function reset(){
    i = 0;

    data = google.visualization.arrayToDataTable([
        ['Time', 'percentage'],
        ['0', 0],
    ]);

    chart = drawChart(data);
}

Also I will have my html display below

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Live Graph Service</title>

    <!-- Bootstrap and libraries -->
    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/1.7.3/socket.io.js"></script>
    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    <script type="text/javascript" src="https://www.google.com/jsapi"></script>
    <!-- websocket code -->
    <script src="/static/js/charts.js"></script>
    <script type="text/javascript">
      $(document).ready(function(){
        var sock = io.connect('http://localhost:8000');

        sock.on('draw', function(data){
          if($('#changeButton').html() == 'stop'){
            // get data
            percentage = data['percentage'];

            // updating chart (live)
            updateChart(percentage);
          }
        });

        // change mode
        $('#changeButton').on('click', function(){
          // change mode: stop -> start
          if($('#changeButton').html() == 'start'){
            $('#changeButton').html('stop');
            sock.emit('change mode', {'mode': 'start'});
          }
          // change mode: start -> stop
          else{
            $('#changeButton').html('start');
            sock.emit('change mode', {'mode': 'stop'});
          }
        });
      });
    </script>
  </head>
  <body>
    <div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
      <div class="container-fluid">
        <div class="navbar-header">
          <a class="navbar-brand" href="/" style="color: white">Live Graph Service</a>
        </div>
        <!-- Collect the nav links, forms, and other content for toggling -->
      </div>
    </div>

    <!-- padding -->
    <div style="height: 90px"></div>

    <!-- buttons -->
    <div class="btn-group" role="group" style="padding-left: 15px">
      <button class="btn btn-default btn-lg" id="changeButton">start</button>
      <button class="btn btn-default btn-lg" id="resetButton" onclick="reset()">reset</button>
    </div>
        <!-- chart - percentage -->
    <div class="container-fluid" id="dashboard">
      <div id="chart" style='width: 915px; height: 300px;'></div>
      <div id="control" style='width: 915px; height: 50px;'></div>
    </div>
  </body>
</html>

The server code is provided below

from flask import Flask, jsonify, render_template, request
from subprocess import call
from flask_socketio import SocketIO, send, emit

app = Flask(__name__)
app.secret_key = 'mysecret'

socket_io = SocketIO(app)

# _mode = 'start' or 'stop'
_mode = 'stop'

@app.route('/')
def draw():
    return render_template('main.html')

# Changing Mode
@socket_io.on('change mode')
def changer(data):
    global _mode
    if data['mode'] == 'start':
        _mode = 'start'
    else:
        _mode = 'stop'

# Receiving Messages
@socket_io.on('my event')
def drawer(data):
    print("draw")
    global _mode
    if _mode == 'stop':
        pass
    else:
        print('input data: ' + str(data))
        # send to webpage
        emit('draw', data, broadcast=True)

if __name__ == '__main__':
    socket_io.run(app, debug=True, host='localhost', port=8000)
    #socket_io.run(app, debug=True, host='0.0.0.0', port=80)

The client code is provided below

import time
import random as r
from socketIO_client import SocketIO, LoggingNamespace

'''
sending data format:
    data= {
        'percentage': value
    }
'''

while True:
    with SocketIO('localhost', 8000, LoggingNamespace) as socketIO:
        # test data set

        send_data = {
            'percentage': r.random(),
        }

        # sending data set
        socketIO.emit('my event', send_data)
        time.sleep(1)

Related Questions