from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Line, Color, Ellipse
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.popup import Popup
from kivy.uix.label import Label
class InteractiveLineChart(Widget):
def __init__(self, **kwargs):
super(InteractiveLineChart, self).__init__(**kwargs)
self.data = [10, 20, 15, 30, 25, 35, 20]
self.points = []
self.draw_line()
def draw_line(self):
with self.canvas:
Color(0.8, 0.3, 0.3, 1) # Line color
self.line = Line(points=self.get_line_points(), width=2)
Color(0, 0, 0, 1) # Point color
for point in self.points:
Ellipse(pos=point, size=(10, 10))
def get_line_points(self):
width, height = self.size
padding = 50
max_value = max(self.data)
points = []
self.points = []
for index, value in enumerate(self.data):
x = padding + index * ((width - 2 * padding) / (len(self.data) - 1))
y = padding + (value / max_value) * (height - 2 * padding)
points.extend([x, y])
self.points.append((x - 5, y - 5))
return points
def on_touch_down(self, touch):
for index, point in enumerate(self.points):
x, y = point
if x <= touch.x <= x + 10 and y <= touch.y <= y + 10:
self.show_popup(index)
return True
return super(InteractiveLineChart, self).on_touch_down(touch)
def show_popup(self, index):
popup = Popup(title=f'Data Point {index + 1}',
content=Label(text=f'Value: {self.data[index]}'),
size_hint=(None, None), size=(200, 200))
popup.open()
def on_size(self, *args):
self.canvas.clear()
self.draw_line()
class LineChartApp(App):
def build(self):
layout = BoxLayout()
chart = InteractiveLineChart()
layout.add_widget(chart)
return layout
if __name__ == '__main__':
LineChartApp().run()