2017-07-25 1 views
0

Un objet Bokeh est une figure qui montre 3 lignes indépendantes.Bokeh + Flask: appels multiples AjaxDataSource

Les données sont diffusées. Un appel AjaxDataSource met à jour les données toutes les 5 secondes en lisant les dernières d'une base de données.

Ceci est la classe dépouillée:

class Graph: 
    def __init__(self): 

     data_source = AjaxDataSource(data=dict(date_time=[], 
               value_1=[], 
               value_2=[], 
               value_3=[]), 
               data_url="/data", 
               polling_interval=5000) 

     line1 = self.figure.line(x="date_time", y="value_1", source=data_source) 
     line2 = self.figure.line(x="date_time", y="value_2", source=data_source) 
     line3 = self.figure.line(x="date_time", y="value_3", source=data_source) 

     app.add_url_rule("/data", "/data", self.serve, methods=['GET', 'OPTIONS', 'POST']) 

    def serve(self): 

     # load data from db and return JSON 
     ... 
     return jsonify(
      date_time= da.df["Date_Time"].tolist(), 
      value_1=da.df["Value1"].tolist(), 
      value_2=da.df["Value2"].tolist(), 
      value_3=da.df["Value3"].tolist() 
     ) 

date_time est commun axe x, value_1 est pour la ligne 1, value_2 ligne 2, value_3 pour la ligne 3.

Le problème

Pourquoi est AjaxDataSource appelé 3 fois (ils sont à quelques millisecondes d'intervalle, puis la lecture triple est faite à nouveau après 5 secondes) au lieu d'une seule fois toutes les 5 secondes? Je croyais que AjaxDataSource remplissait dynamiquement data_source.data toutes les 5 secondes, puis, après qu'ils ont été lus, les 3 lignes lisent ces données "maintenant statiques".

Solution de contournement?

Y at-il un moyen de lire les données en utilisant AjaxDataSource, transférer automatiquement les données dans un ColumnDataSource et l'utiliser comme une source de données "statique"?

Ou est-ce qu'il me manque quelque chose d'important ici?

Répondre

1

Le problème est que chaque glyphe auquel est associée une source de données distante tente d'initialiser la source de données. Dans le cas de AjaxDataSource, il ne vérifie pas les initialisations précédentes.

J'ai ouvert un problème pour elle: https://github.com/bokeh/bokeh/issues/6736

Une solution temporaire que vous pouvez essayer:

Bokeh.require('models/sources/ajax_data_source').AjaxDataSource.prototype.setup = function() { 
    this.get_data(this.mode); 
    if (this.polling_interval && this.interval == null) { 
     return this.interval = setInterval(this.get_data, this.polling_interval, this.mode, this.max_size, this.if_modified); 
    } 
} 

Assurez-vous que ce code est exécuté juste après Bokeh est inclus dans votre page, mais avant d'initialiser ses documents. Comment le faire dépend de la façon dont vous intégrez Bokeh.

+0

La solution de contournement fonctionne parfaitement! Merci Eugene. –