Jelajahi Sumber

introducing traffic chart with page views and session count

Rodja Trappe 2 tahun lalu
induk
melakukan
ea09f02cd3
2 mengubah file dengan 70 tambahan dan 19 penghapusan
  1. 26 19
      main.py
  2. 44 0
      traffic_tracking.py

+ 26 - 19
main.py

@@ -7,6 +7,7 @@ from typing import Callable, Union
 
 
 import docutils.core
 import docutils.core
 
 
+import traffic_tracking
 from nicegui import ui
 from nicegui import ui
 
 
 # add docutils css to webpage
 # add docutils css to webpage
@@ -86,25 +87,31 @@ with ui.row().classes('flex w-full'):
         content = re.sub(r'(?m)^\<img.*\n?', '', content)
         content = re.sub(r'(?m)^\<img.*\n?', '', content)
         ui.markdown(content).classes('w-6/12')
         ui.markdown(content).classes('w-6/12')
 
 
-    with ui.card().classes('mx-auto mt-24'):
-        with ui.row():
-            with ui.column():
-                ui.button('Click me!', on_click=lambda: output.set_text('Click'))
-                ui.checkbox('Check me!', on_change=lambda e: output.set_text('Checked' if e.value else 'Unchecked'))
-                ui.switch('Switch me!', on_change=lambda e: output.set_text('Switched' if e.value else 'Unswitched'))
-                ui.input('Text', value='abc', on_change=lambda e: output.set_text(e.value))
-                ui.number('Number', value=3.1415927, format='%.2f', on_change=lambda e: output.set_text(e.value))
-
-            with ui.column():
-                ui.slider(min=0, max=100, value=50, step=0.1, on_change=lambda e: output.set_text(e.value))
-                ui.radio(['A', 'B', 'C'], value='A', on_change=lambda e: output.set_text(e.value)).props('inline')
-                ui.toggle(['1', '2', '3'], value='1', on_change=lambda e: output.set_text(e.value)).classes('mx-auto')
-                ui.select({1: 'One', 2: 'Two', 3: 'Three'}, value=1,
-                          on_change=lambda e: output.set_text(e.value)).classes('mx-auto')
-
-            with ui.column().classes('w-24'):
-                ui.label('Output:')
-                output = ui.label('').classes('text-bold')
+    with ui.row().classes('w-5/12 flex-center'):
+        width = 450
+
+        with ui.card():
+            with ui.row().style(f'width:{width}px'):
+                with ui.column():
+                    ui.button('Click me!', on_click=lambda: output.set_text('Click'))
+                    ui.checkbox('Check me!', on_change=lambda e: output.set_text('Checked' if e.value else 'Unchecked'))
+                    ui.switch('Switch me!', on_change=lambda e: output.set_text(
+                        'Switched' if e.value else 'Unswitched'))
+                    ui.input('Text', value='abc', on_change=lambda e: output.set_text(e.value))
+                    ui.number('Number', value=3.1415927, format='%.2f', on_change=lambda e: output.set_text(e.value))
+
+                with ui.column():
+                    ui.slider(min=0, max=100, value=50, step=0.1, on_change=lambda e: output.set_text(e.value))
+                    ui.radio(['A', 'B', 'C'], value='A', on_change=lambda e: output.set_text(e.value)).props('inline')
+                    ui.toggle(['1', '2', '3'], value='1', on_change=lambda e: output.set_text(e.value)).classes('mx-auto')
+                    ui.select({1: 'One', 2: 'Two', 3: 'Three'}, value=1,
+                              on_change=lambda e: output.set_text(e.value)).classes('mx-auto')
+
+                with ui.column().classes('w-24'):
+                    ui.label('Output:')
+                    output = ui.label('').classes('text-bold')
+        with ui.card():
+            traffic_tracking.add().style(f'width:{width}px;height:250px')
 
 
 ui.markdown('## API Documentation and Examples')
 ui.markdown('## API Documentation and Examples')
 
 

+ 44 - 0
traffic_tracking.py

@@ -0,0 +1,44 @@
+import os
+import time
+
+from starlette.requests import Request
+
+from nicegui import ui
+
+
+def add() -> ui.chart:
+    page_visits: dict[int, int] = {}
+    page_sessions: dict[int, set[str]] = {}
+
+    def handle_connection(request: Request):
+        factor = 60 * 24
+        today = int(time.time() / factor)
+        page_visits[today] = page_visits.get(today, 0) + 1
+        traffic_chart.options.series[0].data[:] = [[day * factor * 1000, count]
+                                                   for day, count in page_visits.items()]
+        if not today in page_sessions:
+            page_sessions[today] = set()
+        page_sessions[today].add(request.session_id)
+        traffic_chart.options.series[1].data[:] = [
+            [day * factor * 1000, len(s)] for day, s in page_sessions.items()]
+        traffic_chart.update()
+
+    ui.on_connect(handle_connection)
+
+    traffic_chart = ui.chart({
+        'title': {'text': 'Traffic'},
+        'navigation': {'buttonOptions': {'enabled': False}},
+        'chart': {'type': 'line'},
+        'yAxis': {'title': False},
+        'xAxis': {
+            'type': 'datetime',
+            'labels': {'format': '{value:%e. %b}', },
+        },
+        'series': [
+            {'name': 'Views', 'data': []},
+            {'name': 'Sessions', 'data': []},
+        ],
+    })
+
+    traffic_chart.visible = os.environ.get('SHOW_TRAFFIC')
+    return traffic_chart