# Path: thingflow/base.py
# class Filter(OutputThing, InputThing):
#     """A filter has a default input port and a default output port. It is
#     used for data transformations. The default implementations of on_next(),
#     on_completed(), and on_error() just pass the event on to the downstream
#     connection.
#     """
#     def __init__(self, previous_in_chain):
#         super().__init__()
#         # connect to the previous filter
#         self.disconnect_from_upstream = previous_in_chain.connect(self)
# 
#     def on_next(self, x):
#         self._dispatch_next(x)
# 
#     def on_error(self, e):
#         self._dispatch_error(e)
# 
#     def on_completed(self):
#         self._dispatch_completed()
# 
#     def __str__(self):
#         return self.__class__.__name__ + '()'


import logging
import functools
import threading, queue
from math import pi
from bokeh.plotting import figure, curdoc
from bokeh.layouts import column # to show two or more plots arranged in a column
from bokeh.models import ColumnDataSource
from bokeh.client import push_session
from thingflow.base import Filter
        p.yaxis.axis_label = plot_specs.y_axis_label 

        p.x_range.follow = "end"
        p.x_range.follow_interval = 10
        p.x_range.range_padding = 0 
        # p.xaxis.formatter=DatetimeTickFormatter(dict(seconds=["%S"],minutes=["%M"],hours=["%d %B %Y"],days=["%d %B %Y"],months=["%d %B %Y"],years=["%d %B %Y"]))
        p.xaxis.major_label_orientation = pi/4
        p.line(x=plot_specs.x_axis_label, y=plot_specs.y_axis_label, color="blue", source=plot_specs.source)
        p.circle(x=plot_specs.x_axis_label, y=plot_specs.y_axis_label, color="red", source=plot_specs.source)
        curdoc().add_periodic_callback(functools.partial(self.update, name=plot_specs.name), plot_specs.update_period) #period in ms
        return p

    def run(self):
        print("In thread.run")
        self.figs = [self.make_fig(self.plotters[name]) for name in self.plotters]
        self.session = push_session(curdoc())
        self.session.show(column(self.figs)) 
        curdoc().title = 'AntEvent Streams' 
        self.session.loop_until_closed()



class BokehPlot(object):
    def __init__(self, name, y_axis_label="", x_axis_label="timestamp", update_period_in_ms=500):
        self.name = name
        self.x_axis_label = x_axis_label
        self.y_axis_label = y_axis_label
        self.update_period = update_period_in_ms
        self.source = ColumnDataSource(dict({ self.x_axis_label: [], self.y_axis_label: []} ))


# Path: thingflow/base.py
# class Filter(OutputThing, InputThing):
#     """A filter has a default input port and a default output port. It is
#     used for data transformations. The default implementations of on_next(),
#     on_completed(), and on_error() just pass the event on to the downstream
#     connection.
#     """
#     def __init__(self, previous_in_chain):
#         super().__init__()
#         # connect to the previous filter
#         self.disconnect_from_upstream = previous_in_chain.connect(self)
# 
#     def on_next(self, x):
#         self._dispatch_next(x)
# 
#     def on_error(self, e):
#         self._dispatch_error(e)
# 
#     def on_completed(self):
#         self._dispatch_completed()
# 
#     def __str__(self):
#         return self.__class__.__name__ + '()'


# Path: thingflow/adapters/bokeh.py
import logging
import functools
import threading, queue
from math import pi
from bokeh.plotting import figure, curdoc
from bokeh.layouts import column # to show two or more plots arranged in a column
from bokeh.models import ColumnDataSource
from bokeh.client import push_session
from thingflow.base import Filter

        p.yaxis.axis_label = plot_specs.y_axis_label 

        p.x_range.follow = "end"
        p.x_range.follow_interval = 10
        p.x_range.range_padding = 0 
        # p.xaxis.formatter=DatetimeTickFormatter(dict(seconds=["%S"],minutes=["%M"],hours=["%d %B %Y"],days=["%d %B %Y"],months=["%d %B %Y"],years=["%d %B %Y"]))
        p.xaxis.major_label_orientation = pi/4
        p.line(x=plot_specs.x_axis_label, y=plot_specs.y_axis_label, color="blue", source=plot_specs.source)
        p.circle(x=plot_specs.x_axis_label, y=plot_specs.y_axis_label, color="red", source=plot_specs.source)
        curdoc().add_periodic_callback(functools.partial(self.update, name=plot_specs.name), plot_specs.update_period) #period in ms
        return p

    def run(self):
        print("In thread.run")
        self.figs = [self.make_fig(self.plotters[name]) for name in self.plotters]
        self.session = push_session(curdoc())
        self.session.show(column(self.figs)) 
        curdoc().title = 'AntEvent Streams' 
        self.session.loop_until_closed()



class BokehPlot(object):
    def __init__(self, name, y_axis_label="", x_axis_label="timestamp", update_period_in_ms=500):
        self.name = name
        self.x_axis_label = x_axis_label
        self.y_axis_label = y_axis_label
        self.update_period = update_period_in_ms
        self.source = ColumnDataSource(dict({ self.x_axis_label: [], self.y_axis_label: []} ))


class BokehPlotManager(Filter):