# cPy - show dynamic data in oscilloscope like window
# Copyright by Anthony Vogelaar, Perth Scotland
# rev 0.10  2024-10-03  initial release

import  time
from    collections         import  deque
import  matplotlib.pyplot   as  plt

# ============================== Oascilloscope =================================

# data oscilloscope Thinkpad2 = 35 fps, Legion = 50 fps
class Oscilloscope:

    def __init__(self, x_width, y_range):
        plt.ion()                               # enable interactive mode = redraw on change
        self.isRunning = True
        self.data = deque([], x_width)
        self.fig, ax   = plt.subplots()
        ax.set_facecolor('0')
        ax.grid(True, linestyle='-.', color='green')
        ax.tick_params(labelcolor='r', labelsize='medium')
        ax.set_xlim(0, x_width)
        ax.set_ylim(*y_range)
        self.line = ax.plot([],[], color='red')[0]    # plot returns list of Line2D
        self.fig.canvas.mpl_connect('close_event', self._onClose)


    def append(self, y):
        self.data.append(y)
        x_data = [i for i in range(len(self.data))]
        y_data = [y for y in self.data]
        self.line.set_data(x_data, y_data)
        self.fig.canvas.draw()
        self.fig.canvas.flush_events()


    def _onClose(self, ev):
        self.isRunning = False

# =============================== Test =======================================

if __name__ == '__main__':

    import  os;     os.system('clear')
    import  time
    import  math

    # run at 20 fps = 50 mS, horiz = 10 seconds
    def test():
        t    = 0
        osc  = Oscilloscope(200, (-1, +1))
        while osc.isRunning:                        # 50 mS loop
            t += 1
            t1 = time.time()                    
            osc.append(math.sin(0.05*t))            
            dly = 0.05 - (time.time() - t1)         # x speed is 200 * 0.05 = 10 sec / screen 
            if dly > 0: time.sleep(dly)


    test()

# ================================ End ==================================
