From 274c32f15e292d05a1037dfd7e76efeec0b8650e Mon Sep 17 00:00:00 2001 From: fenix-hub Date: Wed, 11 Jan 2023 23:09:45 +0100 Subject: [PATCH] scatter chart feature complete --- .../ScatterChart/scatter_chart.gd | 90 +++++++++++++++---- .../ScatterChart/scatter_chart.tscn | 19 ++-- addons/easy_charts/control_charts/chart.gd | 9 +- .../classes/plotting/drawing_options.gd | 4 +- .../utilities/classes/plotting/point.gd | 7 ++ .../point_container/point_container.gd | 81 ----------------- .../point_container/point_container.tscn | 13 --- 7 files changed, 97 insertions(+), 126 deletions(-) delete mode 100644 addons/easy_charts/utilities/containers/point_container/point_container.gd delete mode 100644 addons/easy_charts/utilities/containers/point_container/point_container.tscn diff --git a/addons/easy_charts/control_charts/ScatterChart/scatter_chart.gd b/addons/easy_charts/control_charts/ScatterChart/scatter_chart.gd index d311a87..0cd40fd 100644 --- a/addons/easy_charts/control_charts/ScatterChart/scatter_chart.gd +++ b/addons/easy_charts/control_charts/ScatterChart/scatter_chart.gd @@ -2,7 +2,11 @@ extends Chart class_name ScatterChart signal point_entered(point) -signal point_exited(point) + +var focused_point: Point = null + +var points: Array = [] +var _point_box_rad: int = 10 # Called when the node enters the scene tree for the first time. @@ -20,16 +24,76 @@ func plot(x: Array, y: Array, drawing_options: DrawingOptions = null, chart_prop update() +func _clear_points() -> void: + points = [] + +func _get_point_box(point: Point, rad: int) -> Rect2: + return Rect2(point.position - (Vector2.ONE * rad), (Vector2.ONE * rad * 2)) + +func _move_tooltip(position: Vector2) -> void: + $Label.set_position(position + (Vector2.ONE * 15)) + +func _show_tooltip(position: Vector2, text: String) -> void: + _move_tooltip(position) + $Label.show() + $Label.set_text(text) + $Label.set_size(Vector2.ZERO) + +func _hide_tooltip() -> void: + $Label.hide() + $Label.set_text("") + $Label.set_size(Vector2.ZERO) + +func _input(event: InputEvent): + if event is InputEventMouse: + for point in points: + if _get_point_box(point, _point_box_rad).abs().has_point(event.position): + if focused_point == point: + _move_tooltip(event.position) + return + else: + focused_point = point + _show_tooltip(event.position, str(focused_point.value)) + emit_signal("point_entered", point) + return + # Mouse is not in any point's box + focused_point = null + _hide_tooltip() + func _draw_point(point: Point, function_index: int) -> void: - var point_container: PointContainer = point_container_scene.instance() - $Points.add_child(point_container) - point_container.set_point( - point, - drawing_options.get_function_color(function_index), - drawing_options.get_point_shape(function_index) - ) - point_container.connect("point_entered", self, "_on_point_entered") - point_container.connect("point_exited", self, "_on_point_exited") + points.append(point) + + match drawing_options.get_point_shape(function_index): + Point.Shape.CIRCLE: + draw_circle(point.position, drawing_options.point_radius, drawing_options.get_function_color(function_index)) + Point.Shape.SQUARE: + draw_rect(_get_point_box(point, drawing_options.point_radius), drawing_options.get_function_color(function_index), true, 1.0, false) + Point.Shape.TRIANGLE: + draw_colored_polygon( + PoolVector2Array([ + point.position + (Vector2.UP * drawing_options.point_radius * 1.3), + point.position + (Vector2.ONE * drawing_options.point_radius * 1.3), + point.position - (Vector2(1, -1) * drawing_options.point_radius * 1.3) + ]), drawing_options.get_function_color(function_index), [], null, null, false + ) + Point.Shape.CROSS: + draw_line( + point.position - (Vector2.ONE * drawing_options.point_radius), + point.position + (Vector2.ONE * drawing_options.point_radius), + drawing_options.get_function_color(function_index), drawing_options.point_radius, true + ) + draw_line( + point.position + (Vector2(1, -1) * drawing_options.point_radius), + point.position + (Vector2(-1, 1) * drawing_options.point_radius), + drawing_options.get_function_color(function_index), drawing_options.point_radius / 2, true + ) + +# # (debug) +# draw_rect( +# _get_point_box(point, _point_box_rad), +# Color.red, +# false, 1, true +# ) func _draw_points() -> void: var validation: int = _validate_sampled_axis(x_sampled, y_sampled) @@ -50,9 +114,3 @@ func _draw_points() -> void: var sampled_point_pos: Vector2 = Vector2(x_sampled.values[i], y_sampled.values[i]) var point: Point = Point.news(sampled_point_pos, real_point_val) _draw_point(point, i) - -func _on_point_entered(point: Point) -> void: - emit_signal("point_entered", point) - -func _on_point_exited(point: Point) -> void: - emit_signal("point_exited", point) diff --git a/addons/easy_charts/control_charts/ScatterChart/scatter_chart.tscn b/addons/easy_charts/control_charts/ScatterChart/scatter_chart.tscn index d547b30..e7b9d0b 100644 --- a/addons/easy_charts/control_charts/ScatterChart/scatter_chart.tscn +++ b/addons/easy_charts/control_charts/ScatterChart/scatter_chart.tscn @@ -1,7 +1,10 @@ -[gd_scene load_steps=2 format=2] +[gd_scene load_steps=3 format=2] [ext_resource path="res://addons/easy_charts/control_charts/ScatterChart/scatter_chart.gd" type="Script" id=1] +[sub_resource type="StyleBoxFlat" id=1] +bg_color = Color( 1, 1, 1, 1 ) + [node name="ScatterChart" type="Control"] anchor_right = 1.0 anchor_bottom = 1.0 @@ -10,13 +13,13 @@ __meta__ = { "_edit_use_anchors_": true } -[node name="Points" type="Control" parent="."] -anchor_right = 1.0 -anchor_bottom = 1.0 -__meta__ = { -"_edit_use_anchors_": true -} - [node name="Canvas" type="Control" parent="."] anchor_right = 1.0 anchor_bottom = 1.0 + +[node name="Label" type="Label" parent="."] +visible = false +margin_right = 40.0 +margin_bottom = 14.0 +custom_colors/font_color = Color( 0, 0, 0, 1 ) +custom_styles/normal = SubResource( 1 ) diff --git a/addons/easy_charts/control_charts/chart.gd b/addons/easy_charts/control_charts/chart.gd index ee6af5f..ac144a0 100644 --- a/addons/easy_charts/control_charts/chart.gd +++ b/addons/easy_charts/control_charts/chart.gd @@ -47,10 +47,6 @@ var _x_ticklabel_size: Vector2 # offset only on the X axis var _x_ticklabel_offset: int = 5 # offset only on the X axis var _x_tick_size: int = 7 - -var point_container_scene: PackedScene = preload("res://addons/easy_charts/utilities/containers/point_container/point_container.tscn") - - ########### func plot(x: Array, y: Array, drawing_options: DrawingOptions = DrawingOptions.new(), chart_properties: ChartProperties = ChartProperties.new()) -> void: pass @@ -342,8 +338,9 @@ func _draw_title() -> void: ) func _clear_points() -> void: - for point in $Points.get_children(): - point.queue_free() + pass +# for point in $Points.get_children(): +# point.queue_free() func _clear_canvas_labels() -> void: for label in $Canvas.get_children(): diff --git a/addons/easy_charts/utilities/classes/plotting/drawing_options.gd b/addons/easy_charts/utilities/classes/plotting/drawing_options.gd index aa353b4..d7ebbce 100644 --- a/addons/easy_charts/utilities/classes/plotting/drawing_options.gd +++ b/addons/easy_charts/utilities/classes/plotting/drawing_options.gd @@ -16,7 +16,7 @@ var colors: Dictionary = { functions = [Color.red, Color.green, Color.blue, Color.black] } -var shapes: Array = [PointContainer.PointShape.CIRCLE, PointContainer.PointShape.SQUARE, PointContainer.PointShape.TRIANGLE, PointContainer.PointShape.CROSS] +var shapes: Array = [Point.Shape.CIRCLE, Point.Shape.SQUARE, Point.Shape.TRIANGLE, Point.Shape.CROSS] var point_radius: float = 3.0 var font: BitmapFont = Label.new().get_font("") @@ -24,4 +24,4 @@ func get_function_color(function_index: int) -> Color: return colors.functions[function_index] if function_index < colors.functions.size() else Color.black func get_point_shape(function_index: int) -> int: - return shapes[function_index] if function_index < shapes.size() else PointContainer.PointShape.CIRCLE + return shapes[function_index] if function_index < shapes.size() else Point.Shape.CIRCLE diff --git a/addons/easy_charts/utilities/classes/plotting/point.gd b/addons/easy_charts/utilities/classes/plotting/point.gd index ba480bf..f47e6b3 100644 --- a/addons/easy_charts/utilities/classes/plotting/point.gd +++ b/addons/easy_charts/utilities/classes/plotting/point.gd @@ -2,6 +2,13 @@ tool extends Reference class_name Point +enum Shape { + CIRCLE, + TRIANGLE, + SQUARE, + CROSS +} + var position: Vector2 var value: Pair diff --git a/addons/easy_charts/utilities/containers/point_container/point_container.gd b/addons/easy_charts/utilities/containers/point_container/point_container.gd deleted file mode 100644 index df38a69..0000000 --- a/addons/easy_charts/utilities/containers/point_container/point_container.gd +++ /dev/null @@ -1,81 +0,0 @@ -extends Control -class_name PointContainer - -signal point_entered(point) -signal point_exited(point) - -enum PointShape { - CIRCLE, - TRIANGLE, - SQUARE, - CROSS -} - -var point: Point -var color: Color -var radius: float -var shape: int -var label: String - -func _ready(): - pass - -func set_point(point: Point, color: Color = Color.black, shape: int = PointShape.CIRCLE, radius: float = 3.0) -> void: - self.point = point - self.color = color - self.shape = shape - self.radius = radius - - auto_pos(self.point.position) - -func auto_pos(pos: Vector2) -> void: - self.rect_position += pos - -func _draw_bounding_box() -> void: - var t_gr: Rect2 = get_global_rect() - draw_rect(Rect2(Vector2.ZERO, get_rect().size), Color.black, false, 1, true) - -func _draw_label() -> void: - var lbl: Label = Label.new() - add_child(lbl) - lbl.rect_position += self.rect_size - lbl.text = str(label) - -func _draw_point() -> void: - var point_rel_pos: Vector2 = self.rect_size * 0.5 - - match self.shape: - PointShape.CIRCLE: - draw_circle(point_rel_pos, self.radius, self.color) - PointShape.SQUARE: - draw_rect(Rect2(point_rel_pos * 0.5, point_rel_pos), self.color, true, 1.0, false) - PointShape.TRIANGLE: - draw_colored_polygon( - PoolVector2Array([ - point_rel_pos + (Vector2.UP * self.radius * 1.5), - point_rel_pos + (Vector2.ONE * self.radius * 1.5), - point_rel_pos - (Vector2(1, -1) * self.radius * 1.5) - ]), self.color, [], null, null, false - ) - PointShape.CROSS: - draw_line( - point_rel_pos - (Vector2.ONE * self.radius), - point_rel_pos + (Vector2.ONE * self.radius), - self.color, self.radius, true - ) - draw_line( - point_rel_pos + (Vector2(1, -1) * self.radius), - point_rel_pos + (Vector2(-1, 1) * self.radius), - self.color, self.radius / 2, true - ) - -func _draw(): -# _draw_bounding_box() - _draw_point() -# _draw_label() - -func _on_PointContainer_mouse_entered(): - emit_signal("point_entered", self.point) - -func _on_PointContainer_mouse_exited(): - emit_signal("point_exited", self.point) diff --git a/addons/easy_charts/utilities/containers/point_container/point_container.tscn b/addons/easy_charts/utilities/containers/point_container/point_container.tscn deleted file mode 100644 index 63eaae6..0000000 --- a/addons/easy_charts/utilities/containers/point_container/point_container.tscn +++ /dev/null @@ -1,13 +0,0 @@ -[gd_scene load_steps=2 format=2] - -[ext_resource path="res://addons/easy_charts/utilities/containers/point_container/point_container.gd" type="Script" id=1] - -[node name="PointContainer" type="Control"] -margin_left = -8.0 -margin_top = -8.0 -margin_right = 8.0 -margin_bottom = 8.0 -script = ExtResource( 1 ) - -[connection signal="mouse_entered" from="." to="." method="_on_PointContainer_mouse_entered"] -[connection signal="mouse_exited" from="." to="." method="_on_PointContainer_mouse_exited"]