mirror of
https://github.com/Relintai/pandemonium_engine_easy_charts.git
synced 2024-11-20 10:47:22 +01:00
+ LineChart, (up) chart
This commit is contained in:
parent
f7864e4755
commit
bc4c066c02
20
addons/easy_charts/control_charts/LineChart/line_chart.gd
Normal file
20
addons/easy_charts/control_charts/LineChart/line_chart.gd
Normal file
@ -0,0 +1,20 @@
|
||||
extends ScatterChart
|
||||
class_name LineChart
|
||||
|
||||
func _draw_line(from: Point, to: Point, function_index: int) -> void:
|
||||
draw_line(
|
||||
from.position,
|
||||
to.position,
|
||||
chart_properties.get_function_color(function_index),
|
||||
chart_properties.line_width,
|
||||
true
|
||||
)
|
||||
|
||||
func _draw_lines() -> void:
|
||||
for function in function_points.size():
|
||||
for i in range(1, function_points[function].size()):
|
||||
_draw_line(function_points[function][i], function_points[function][i - 1], function)
|
||||
|
||||
func _draw() -> void:
|
||||
if chart_properties.lines:
|
||||
_draw_lines()
|
@ -0,0 +1,7 @@
|
||||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://addons/easy_charts/control_charts/LineChart/line_chart.gd" type="Script" id=1]
|
||||
[ext_resource path="res://addons/easy_charts/control_charts/chart.tscn" type="PackedScene" id=2]
|
||||
|
||||
[node name="LineChart" instance=ExtResource( 2 )]
|
||||
script = ExtResource( 1 )
|
@ -3,46 +3,37 @@ class_name ScatterChart
|
||||
|
||||
signal point_entered(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.
|
||||
func _ready():
|
||||
pass
|
||||
|
||||
func plot(x: Array, y: Array, properties: ChartProperties = self.chart_properties) -> void:
|
||||
self.x = x
|
||||
self.y = y
|
||||
|
||||
if properties != null:
|
||||
self.chart_properties = properties
|
||||
|
||||
update()
|
||||
var points: Array = []
|
||||
var function_points: Array = []
|
||||
var focused_point: Point = null
|
||||
|
||||
func _clear_points() -> void:
|
||||
points = []
|
||||
points.clear()
|
||||
function_points.clear()
|
||||
|
||||
func _clear() -> void:
|
||||
_clear_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))
|
||||
$Tooltip.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)
|
||||
$Tooltip.show()
|
||||
$Tooltip.set_text(text)
|
||||
$Tooltip.set_size(Vector2.ZERO)
|
||||
|
||||
func _hide_tooltip() -> void:
|
||||
$Label.hide()
|
||||
$Label.set_text("")
|
||||
$Label.set_size(Vector2.ZERO)
|
||||
$Tooltip.hide()
|
||||
$Tooltip.set_text("")
|
||||
$Tooltip.set_size(Vector2.ZERO)
|
||||
|
||||
func _input(event: InputEvent):
|
||||
func _input(event: InputEvent) -> void:
|
||||
if event is InputEventMouse:
|
||||
for point in points:
|
||||
if _get_point_box(point, _point_box_rad).abs().has_point(event.position):
|
||||
@ -59,8 +50,6 @@ func _input(event: InputEvent):
|
||||
_hide_tooltip()
|
||||
|
||||
func _draw_point(point: Point, function_index: int) -> void:
|
||||
points.append(point)
|
||||
|
||||
match chart_properties.get_point_shape(function_index):
|
||||
Point.Shape.CIRCLE:
|
||||
draw_circle(point.position, chart_properties.point_radius, chart_properties.get_function_color(function_index))
|
||||
@ -94,6 +83,11 @@ func _draw_point(point: Point, function_index: int) -> void:
|
||||
# )
|
||||
|
||||
func _draw_points() -> void:
|
||||
for function in function_points.size():
|
||||
for point in function_points[function]:
|
||||
_draw_point(point, function)
|
||||
|
||||
func _calculate_points() -> void:
|
||||
var validation: int = _validate_sampled_axis(x_sampled, y_sampled)
|
||||
if not validation == OK:
|
||||
printerr("Cannot plot points for invalid dataset! Error: %s" % validation)
|
||||
@ -101,14 +95,24 @@ func _draw_points() -> void:
|
||||
|
||||
if y_sampled.values[0] is Array:
|
||||
for yxi in y_sampled.values.size():
|
||||
var _function_points: Array = []
|
||||
for i in y_sampled.values[yxi].size():
|
||||
var real_point_val: Pair = Pair.new(x[i], y[yxi][i])
|
||||
var sampled_point_pos: Vector2 = Vector2(x_sampled.values[i], y_sampled.values[yxi][i])
|
||||
var point: Point = Point.new(sampled_point_pos, real_point_val)
|
||||
_draw_point(point, yxi)
|
||||
_function_points.append(point)
|
||||
points.append(point)
|
||||
function_points.append(_function_points)
|
||||
else:
|
||||
for i in y_sampled.values.size():
|
||||
var real_point_val: Pair = Pair.new(x[i], y[i])
|
||||
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)
|
||||
points.append(point)
|
||||
function_points.append(points)
|
||||
|
||||
func _draw() -> void:
|
||||
_calculate_points()
|
||||
|
||||
if chart_properties.points:
|
||||
_draw_points()
|
||||
|
@ -1,25 +1,7 @@
|
||||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://addons/easy_charts/control_charts/ScatterChart/scatter_chart.gd" type="Script" id=1]
|
||||
[ext_resource path="res://addons/easy_charts/control_charts/chart.tscn" type="PackedScene" id=2]
|
||||
|
||||
[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
|
||||
[node name="ScatterChart" instance=ExtResource( 2 )]
|
||||
script = ExtResource( 1 )
|
||||
__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 )
|
||||
|
@ -4,8 +4,10 @@ class_name Chart
|
||||
var x: Array
|
||||
var y: Array
|
||||
|
||||
var x_min_max: Pair = Pair.new()
|
||||
var y_min_max: Pair = Pair.new()
|
||||
var x_min_max: Pair = Pair.new() # Min and Max values of @x
|
||||
var x_domain: Pair = Pair.new() # Rounded domain of values of @x
|
||||
var y_min_max: Pair = Pair.new() # Min and Max values of @y
|
||||
var y_domain: Pair = Pair.new() # Rounded domain of values of @x
|
||||
|
||||
var x_sampled: SampledAxis = SampledAxis.new()
|
||||
var y_sampled: SampledAxis = SampledAxis.new()
|
||||
@ -45,8 +47,20 @@ var _x_ticklabel_offset: int = 5 # offset only on the X axis
|
||||
var _x_tick_size: int = 7
|
||||
|
||||
###########
|
||||
func _ready() -> void:
|
||||
set_process_input(false)
|
||||
set_process(false)
|
||||
|
||||
func plot(x: Array, y: Array, properties: ChartProperties = self.chart_properties) -> void:
|
||||
pass
|
||||
self.x = x
|
||||
self.y = y
|
||||
|
||||
if properties != null:
|
||||
self.chart_properties = properties
|
||||
|
||||
set_process_input(chart_properties.interactive)
|
||||
|
||||
update()
|
||||
|
||||
func _map_pair(val: float, rel: Pair, ref: Pair) -> float:
|
||||
return range_lerp(val, rel.left, rel.right, ref.left, ref.right)
|
||||
@ -99,8 +113,6 @@ func _sample_values(values: Array, rel_values: Pair, ref_values: Pair) -> Sample
|
||||
return SampledAxis.new()
|
||||
|
||||
var temp: Array = values.duplicate(true)
|
||||
var _min: float
|
||||
var _max: float
|
||||
|
||||
var rels: Array = []
|
||||
if temp[0] is Array:
|
||||
@ -116,8 +128,13 @@ func _sample_values(values: Array, rel_values: Pair, ref_values: Pair) -> Sample
|
||||
|
||||
return SampledAxis.new(rels, rel_values)
|
||||
|
||||
func _round_min(val: float) -> float:
|
||||
return round(val) if abs(val) < 10 else floor(val / 10.0) * 10.0
|
||||
|
||||
func _pre_process_drawings() -> void:
|
||||
func _round_max(val: float) -> float:
|
||||
return round(val) if abs(val) < 10 else ceil(val / 10.0) * 10.0
|
||||
|
||||
func _pre_process() -> void:
|
||||
var t_gr: Rect2 = get_global_rect()
|
||||
|
||||
#### @node_box size, which is the whole "frame"
|
||||
@ -125,7 +142,9 @@ func _pre_process_drawings() -> void:
|
||||
|
||||
#### drawing size for defining @bounding_box
|
||||
x_min_max = _find_min_max(x)
|
||||
x_domain = Pair.new(_round_min(x_min_max.left), _round_max(x_min_max.right))
|
||||
y_min_max = _find_min_max(y)
|
||||
y_domain = Pair.new(_round_min(y_min_max.left), _round_max(y_min_max.right))
|
||||
|
||||
#### calculating offset from the @node_box for the @bounding_box.
|
||||
var offset: Vector2 = _padding_offset
|
||||
@ -142,7 +161,7 @@ func _pre_process_drawings() -> void:
|
||||
x_has_decimals = _has_decimals(x)
|
||||
# calculate the string length of the largest value on the Y axis.
|
||||
# remember that "-" sign adds additional pixels, and it is relative only to negative numbers!
|
||||
var x_max_formatted: String = ("%.2f" if x_has_decimals else "%s") % x_min_max.right
|
||||
var x_max_formatted: String = ("%.2f" if x_has_decimals else "%s") % x_domain.right
|
||||
_x_ticklabel_size = chart_properties.font.get_string_size(x_max_formatted)
|
||||
|
||||
offset.y += _x_label_offset + _x_label_size.y + _x_ticklabel_offset + _x_ticklabel_size.y
|
||||
@ -151,10 +170,10 @@ func _pre_process_drawings() -> void:
|
||||
y_has_decimals = _has_decimals(y)
|
||||
# calculate the string length of the largest value on the Y axis.
|
||||
# remember that "-" sign adds additional pixels, and it is relative only to negative numbers!
|
||||
var y_max_formatted: String = ("%.2f" if y_has_decimals else "%s") % y_min_max.right
|
||||
if y_min_max.left < 0:
|
||||
var y_max_formatted: String = ("%.2f" if y_has_decimals else "%s") % y_domain.right
|
||||
if y_domain.left < 0:
|
||||
# negative number
|
||||
var y_min_formatted: String = ("%.2f" if y_has_decimals else "%s") % y_min_max.left
|
||||
var y_min_formatted: String = ("%.2f" if y_has_decimals else "%s") % y_domain.left
|
||||
if y_min_formatted.length() >= y_max_formatted.length():
|
||||
_y_ticklabel_size = chart_properties.font.get_string_size(y_min_formatted)
|
||||
else:
|
||||
@ -183,21 +202,10 @@ func _pre_process_drawings() -> void:
|
||||
Vector2(x_sampled_domain.left, y_sampled_domain.left),
|
||||
Vector2(x_sampled_domain.right, y_sampled_domain.right)
|
||||
)
|
||||
|
||||
func _pre_process_sampling() -> void:
|
||||
|
||||
# samples
|
||||
x_sampled = _sample_values(x, x_min_max, x_sampled_domain)
|
||||
y_sampled = _sample_values(y, y_min_max, y_sampled_domain)
|
||||
|
||||
func _pre_process() -> void:
|
||||
_pre_process_drawings()
|
||||
_pre_process_sampling()
|
||||
|
||||
|
||||
|
||||
func _draw_points() -> void:
|
||||
pass
|
||||
y_sampled = _sample_values(y, y_domain, y_sampled_domain)
|
||||
|
||||
func _draw_borders() -> void:
|
||||
draw_rect(node_box, Color.red, false, 1, true)
|
||||
@ -212,7 +220,7 @@ func _draw_bounding_box() -> void:
|
||||
|
||||
func _draw_origin() -> void:
|
||||
var xorigin: float = _map_pair(0.0, x_min_max, x_sampled_domain)
|
||||
var yorigin: float = _map_pair(0.0, y_min_max, y_sampled_domain)
|
||||
var yorigin: float = _map_pair(0.0, y_domain, y_sampled_domain)
|
||||
draw_line(Vector2(xorigin, bounding_box.position.y), Vector2(xorigin, bounding_box.position.y + bounding_box.size.y), Color.black, 1, 0)
|
||||
draw_line(Vector2(bounding_box.position.x, yorigin), Vector2(bounding_box.position.x + bounding_box.size.x, yorigin), Color.black, 1, 0)
|
||||
draw_string(chart_properties.font, Vector2(xorigin, yorigin) - Vector2(15, -15), "O", chart_properties.colors.bounding_box)
|
||||
@ -232,10 +240,15 @@ func _draw_grid() -> void:
|
||||
return
|
||||
|
||||
# draw vertical lines
|
||||
var v_lines: float = (x_sampled.min_max.right - x_sampled.min_max.left) / (chart_properties.x_scale - 1)
|
||||
var x_labels_spacing: float = x_labels.size() / (chart_properties.x_scale - 1)
|
||||
for _x in chart_properties.x_scale:
|
||||
var x_val: float = _x * v_lines + x_sampled.min_max.left
|
||||
|
||||
# 1. the amount of lines is equals to the X_scale: it identifies in how many sectors the x domain
|
||||
# should be devided
|
||||
# 2. calculate the spacing between each line in pixel. It is equals to x_sampled_domain / x_scale
|
||||
# 3. calculate the offset in the real x domain, which is x_domain / x_scale.
|
||||
var x_pixel_dist: float = (x_sampled.min_max.right - x_sampled.min_max.left) / (chart_properties.x_scale)
|
||||
var x_lbl_val: float = (x_min_max.right - x_min_max.left) / (chart_properties.x_scale)
|
||||
for _x in chart_properties.x_scale + 1:
|
||||
var x_val: float = _x * x_pixel_dist + x_sampled.min_max.left
|
||||
var p1: Vector2 = Vector2(
|
||||
range_lerp(x_val, x_sampled.min_max.left, x_sampled.min_max.right, x_sampled_domain.left, x_sampled_domain.right),
|
||||
bounding_box.position.y
|
||||
@ -249,9 +262,9 @@ func _draw_grid() -> void:
|
||||
if chart_properties.labels:
|
||||
var tick_lbl: String = ""
|
||||
if x_labels.empty():
|
||||
tick_lbl = ("%.2f" if x_has_decimals else "%s") % x_val
|
||||
tick_lbl = ("%.2f" if x_has_decimals else "%s") % [x_min_max.left + (_x * x_lbl_val)]
|
||||
else:
|
||||
tick_lbl = x_labels[clamp(x_labels_spacing * _x, 0, x_labels.size() - 1)]
|
||||
tick_lbl = x_labels[clamp(x_lbl_val * _x, 0, x_labels.size() - 1)]
|
||||
|
||||
draw_string(
|
||||
chart_properties.font,
|
||||
@ -272,10 +285,15 @@ func _draw_grid() -> void:
|
||||
draw_line(p1, p2, chart_properties.colors.grid, 1, true)
|
||||
|
||||
# draw horizontal lines
|
||||
var h_lines: float = (y_sampled.min_max.right - y_sampled.min_max.left) / (chart_properties.y_scale - 1)
|
||||
var y_labels_spacing: float = y_labels.size() / (chart_properties.y_scale - 1)
|
||||
for _y in chart_properties.y_scale:
|
||||
var y_val: float = _y * h_lines + y_sampled.min_max.left
|
||||
|
||||
# 1. the amount of lines is equals to the y_scale: it identifies in how many sectors the y domain
|
||||
# should be devided
|
||||
# 2. calculate the spacing between each line in pixel. It is equals to y_sampled_domain / y_scale
|
||||
# 3. calculate the offset in the real y domain, which is y_domain / y_scale.
|
||||
var y_pixel_dist: float = (y_sampled.min_max.right - y_sampled.min_max.left) / (chart_properties.y_scale)
|
||||
var y_lbl_val: float = (y_domain.right - y_domain.left) / (chart_properties.y_scale)
|
||||
for _y in chart_properties.y_scale + 1:
|
||||
var y_val: float = (_y * y_pixel_dist) + y_sampled.min_max.left
|
||||
var p1: Vector2 = Vector2(
|
||||
bounding_box.position.x,
|
||||
range_lerp(y_val, y_sampled.min_max.left, y_sampled.min_max.right, y_sampled_domain.left, y_sampled_domain.right)
|
||||
@ -289,7 +307,7 @@ func _draw_grid() -> void:
|
||||
if chart_properties.labels:
|
||||
var tick_lbl: String = ""
|
||||
if y_labels.empty():
|
||||
tick_lbl = ("%.2f" if y_has_decimals else "%s") % y_val
|
||||
tick_lbl = ("%.2f" if y_has_decimals else "%s") % [y_domain.left + (_y * y_lbl_val)]
|
||||
else:
|
||||
tick_lbl = y_labels[clamp(y_labels * _y, 0, y_labels.size() - 1)]
|
||||
|
||||
@ -321,15 +339,23 @@ func _create_canvas_label(text: String, position: Vector2, rotation: float = 0.0
|
||||
lbl.rect_position = position
|
||||
return lbl
|
||||
|
||||
func _update_canvas_label(canvas_label: Label, text: String, position: Vector2, rotation: float = 0.0) -> void:
|
||||
canvas_label.set_text(text)
|
||||
canvas_label.modulate = chart_properties.colors.bounding_box
|
||||
canvas_label.rect_rotation = rotation
|
||||
canvas_label.rect_position = position
|
||||
|
||||
func _draw_yaxis_label() -> void:
|
||||
_create_canvas_label(
|
||||
_update_canvas_label(
|
||||
$Canvas/YLabel,
|
||||
chart_properties.y_label,
|
||||
Vector2(_padding_offset.x, (node_box.size.y / 2) + (_y_label_size.x / 2)),
|
||||
-90
|
||||
)
|
||||
|
||||
func _draw_xaxis_label() -> void:
|
||||
_create_canvas_label(
|
||||
_update_canvas_label(
|
||||
$Canvas/XLabel,
|
||||
chart_properties.x_label,
|
||||
Vector2(
|
||||
node_box.size.x/2 - (_x_label_size.x / 2),
|
||||
@ -338,24 +364,24 @@ func _draw_xaxis_label() -> void:
|
||||
)
|
||||
|
||||
func _draw_title() -> void:
|
||||
_create_canvas_label(
|
||||
_update_canvas_label(
|
||||
$Canvas/Title,
|
||||
chart_properties.title,
|
||||
Vector2(node_box.size.x / 2, _padding_offset.y*2) - (chart_properties.font.get_string_size(chart_properties.title) / 2)
|
||||
)
|
||||
|
||||
func _clear_points() -> void:
|
||||
pass
|
||||
# for point in $Points.get_children():
|
||||
# point.queue_free()
|
||||
|
||||
func _clear_canvas_labels() -> void:
|
||||
for label in $Canvas.get_children():
|
||||
label.queue_free()
|
||||
|
||||
func _clear() -> void:
|
||||
_clear_points()
|
||||
_clear_canvas_labels()
|
||||
|
||||
# Draw Loop:
|
||||
# the drow loop gives order to what thigs will be drawn
|
||||
# each chart specifies its own draw loop that inherits from this one.
|
||||
# The draw loop also contains the "processing loop" which is where
|
||||
# everything is calculated in a separated function.
|
||||
func _draw():
|
||||
_clear()
|
||||
_pre_process()
|
||||
@ -366,11 +392,6 @@ func _draw():
|
||||
if chart_properties.borders:
|
||||
_draw_borders()
|
||||
|
||||
if chart_properties.labels:
|
||||
_draw_xaxis_label()
|
||||
_draw_yaxis_label()
|
||||
_draw_title()
|
||||
|
||||
if chart_properties.grid or chart_properties.ticks or chart_properties.labels:
|
||||
_draw_grid()
|
||||
|
||||
@ -380,8 +401,10 @@ func _draw():
|
||||
if chart_properties.origin:
|
||||
_draw_origin()
|
||||
|
||||
if chart_properties.points:
|
||||
_draw_points()
|
||||
if chart_properties.labels:
|
||||
_draw_xaxis_label()
|
||||
_draw_yaxis_label()
|
||||
_draw_title()
|
||||
|
||||
func _validate_sampled_axis(x_data: SampledAxis, y_data: SampledAxis) -> int:
|
||||
var error: int = 0 # OK
|
||||
|
34
addons/easy_charts/control_charts/chart.tscn
Normal file
34
addons/easy_charts/control_charts/chart.tscn
Normal file
@ -0,0 +1,34 @@
|
||||
[gd_scene load_steps=3 format=2]
|
||||
|
||||
[ext_resource path="res://addons/easy_charts/control_charts/chart.gd" type="Script" id=1]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id=1]
|
||||
bg_color = Color( 1, 1, 1, 1 )
|
||||
|
||||
[node name="Chart" type="Control"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
script = ExtResource( 1 )
|
||||
|
||||
[node name="Canvas" type="Control" parent="."]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
|
||||
[node name="Title" type="Label" parent="Canvas"]
|
||||
margin_right = 40.0
|
||||
margin_bottom = 14.0
|
||||
|
||||
[node name="XLabel" type="Label" parent="Canvas"]
|
||||
margin_right = 40.0
|
||||
margin_bottom = 14.0
|
||||
|
||||
[node name="YLabel" type="Label" parent="Canvas"]
|
||||
margin_right = 40.0
|
||||
margin_bottom = 14.0
|
||||
|
||||
[node name="Tooltip" 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 )
|
53
addons/easy_charts/examples/line_chart/Control.gd
Normal file
53
addons/easy_charts/examples/line_chart/Control.gd
Normal file
@ -0,0 +1,53 @@
|
||||
extends Control
|
||||
|
||||
func _ready():
|
||||
# Let's create our @x values
|
||||
var x: Array = ArrayOperations.multiply_float(range(-2*PI, +2*PI, 1), 0.5)
|
||||
# And our y values. It can be an n-size array of arrays.
|
||||
# NOTE: `x.size() == y.size()` or `x.size() == y[n].size()`
|
||||
var y: Array = [
|
||||
ArrayOperations.multiply_float(ArrayOperations.cos(x), 1.0),
|
||||
ArrayOperations.add_float(ArrayOperations.multiply_int(ArrayOperations.sin(x), 1), 0)
|
||||
]
|
||||
print(y)
|
||||
# Add some labels for the x axis, we don't want to use our x values array
|
||||
# they will be printed on the chart ticks instead of the value of the x axis.
|
||||
var x_labels: Array = ArrayOperations.suffix(x, "s")
|
||||
|
||||
# Let's customize the chart properties, which specify how the chart
|
||||
# should look, plus some additional elements like labels, the scale, etc...
|
||||
var cp: ChartProperties = ChartProperties.new()
|
||||
cp.grid = false
|
||||
cp.origin = true
|
||||
cp.title = "Air Quality Monitoring"
|
||||
cp.x_label = ("Time")
|
||||
cp.x_scale = 10
|
||||
cp.y_label = ("Sensor values")
|
||||
cp.y_scale = 10
|
||||
cp.points = false
|
||||
cp.line_width = 2.0
|
||||
cp.interactive = false # false by default, it allows the chart to create a tooltip to show point values
|
||||
# and interecept clicks on the plot
|
||||
|
||||
# Set the x_labels
|
||||
# $LineChart.x_labels = x_labels
|
||||
|
||||
# Plot our data
|
||||
$LineChart.plot(x, y, cp)
|
||||
|
||||
# Uncommenting this line will show how real time data plotting works
|
||||
set_process(false)
|
||||
|
||||
func _process(delta: float):
|
||||
# This function updates the values of chart x, y, and x_labels array
|
||||
# and updaptes the plot
|
||||
var new_val: float = $LineChart.x.back() + 1
|
||||
$LineChart.x.append(new_val)
|
||||
$LineChart.y[0].append(cos(new_val) * 20)
|
||||
$LineChart.y[1].append(20 + sin(new_val) * 20)
|
||||
$LineChart.x_labels.append(str(new_val) + "s")
|
||||
$LineChart.update()
|
||||
|
||||
|
||||
func _on_CheckButton_pressed():
|
||||
set_process(not is_processing())
|
49
addons/easy_charts/examples/line_chart/Control.tscn
Normal file
49
addons/easy_charts/examples/line_chart/Control.tscn
Normal file
@ -0,0 +1,49 @@
|
||||
[gd_scene load_steps=4 format=2]
|
||||
|
||||
[ext_resource path="res://addons/easy_charts/control_charts/LineChart/line_chart.tscn" type="PackedScene" id=1]
|
||||
[ext_resource path="res://addons/easy_charts/examples/line_chart/Control.gd" type="Script" id=2]
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id=1]
|
||||
content_margin_right = 5.0
|
||||
content_margin_bottom = 5.0
|
||||
draw_center = false
|
||||
border_width_right = 2
|
||||
border_width_bottom = 2
|
||||
border_color = Color( 0, 0, 0, 1 )
|
||||
|
||||
[node name="Control" type="Control"]
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
script = ExtResource( 2 )
|
||||
__meta__ = {
|
||||
"_edit_use_anchors_": true
|
||||
}
|
||||
|
||||
[node name="LineChart" parent="." instance=ExtResource( 1 )]
|
||||
|
||||
[node name="CheckButton" type="CheckButton" parent="."]
|
||||
margin_right = 223.0
|
||||
margin_bottom = 40.0
|
||||
custom_colors/font_color_disabled = Color( 0, 0, 0, 1 )
|
||||
custom_colors/font_color_focus = Color( 0, 0, 0, 1 )
|
||||
custom_colors/font_color_hover_pressed = Color( 0, 0, 0, 1 )
|
||||
custom_colors/font_color = Color( 0, 0, 0, 1 )
|
||||
custom_colors/font_color_hover = Color( 0, 0, 0, 1 )
|
||||
custom_colors/font_color_pressed = Color( 0, 0, 0, 1 )
|
||||
text = "Start Relatime Plotting"
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
anchor_left = 1.0
|
||||
anchor_top = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
margin_left = -159.0
|
||||
margin_top = -19.0
|
||||
custom_colors/font_color = Color( 0, 0, 0, 1 )
|
||||
custom_styles/normal = SubResource( 1 )
|
||||
text = "Try to scale the window!"
|
||||
__meta__ = {
|
||||
"_edit_lock_": true
|
||||
}
|
||||
|
||||
[connection signal="pressed" from="CheckButton" to="." method="_on_CheckButton_pressed"]
|
@ -9,7 +9,6 @@ func _ready():
|
||||
ArrayOperations.multiply_int(ArrayOperations.cos(x), 20),
|
||||
ArrayOperations.add_float(ArrayOperations.multiply_int(ArrayOperations.sin(x), 20), 20)
|
||||
]
|
||||
|
||||
# Add some labels for the x axis, we don't want to use our x values array
|
||||
# they will be printed on the chart ticks instead of the value of the x axis.
|
||||
var x_labels: Array = ArrayOperations.suffix(x, "s")
|
||||
@ -23,10 +22,12 @@ func _ready():
|
||||
cp.x_label = ("Time")
|
||||
cp.x_scale = 10
|
||||
cp.y_label = ("Sensor values")
|
||||
cp.y_scale = 10
|
||||
cp.y_scale = 30
|
||||
cp.interactive = true # false by default, it allows the chart to create a tooltip to show point values
|
||||
# and interecept clicks on the plot
|
||||
|
||||
# Set the x_labels
|
||||
$ScatterChart.x_labels = x_labels
|
||||
# $ScatterChart.x_labels = x_labels
|
||||
|
||||
# Plot our data
|
||||
$ScatterChart.plot(x, y, cp)
|
||||
|
@ -8,14 +8,20 @@ var y_label: String
|
||||
var x_scale: float = 5.0
|
||||
var y_scale: float = 2.0
|
||||
|
||||
var points: bool = true
|
||||
var grid: bool = false
|
||||
var bounding_box: bool = true
|
||||
var background: bool = true
|
||||
# Scale type, 0 = linear | 1 = logarithmic
|
||||
var x_scale_type: int = 0
|
||||
var y_scale_type: int = 0
|
||||
|
||||
var borders: bool = false
|
||||
var background: bool = true
|
||||
var bounding_box: bool = true
|
||||
var grid: bool = false
|
||||
var ticks: bool = true
|
||||
var labels: bool = true
|
||||
var origin: bool = true
|
||||
var points: bool = true
|
||||
var lines: bool = true
|
||||
var interactive: bool = false
|
||||
|
||||
var colors: Dictionary = {
|
||||
bounding_box = Color.black,
|
||||
@ -23,8 +29,9 @@ var colors: Dictionary = {
|
||||
functions = [Color.red, Color.green, Color.blue, Color.black]
|
||||
}
|
||||
|
||||
var shapes: Array = [Point.Shape.CIRCLE, Point.Shape.SQUARE, Point.Shape.TRIANGLE, Point.Shape.CROSS]
|
||||
var point_radius: float = 3.0
|
||||
var line_width: float = 1.0
|
||||
var shapes: Array = [Point.Shape.CIRCLE, Point.Shape.SQUARE, Point.Shape.TRIANGLE, Point.Shape.CROSS]
|
||||
var font: BitmapFont = Label.new().get_font("")
|
||||
|
||||
func get_function_color(function_index: int) -> Color:
|
||||
|
@ -15,4 +15,4 @@ func _init(left: float = 0.0, right: float = 0.0) -> void:
|
||||
self.right = right
|
||||
|
||||
func _to_string() -> String:
|
||||
return "[%s, %s]" % [self.left, self.right]
|
||||
return "[%.2f, %.2f]" % [self.left, self.right]
|
||||
|
Loading…
Reference in New Issue
Block a user