summaryrefslogtreecommitdiff
path: root/lib/lvgl/examples/widgets/chart
diff options
context:
space:
mode:
authorjacqueline <me@jacqueline.id.au>2023-06-01 15:41:47 +1000
committerjacqueline <me@jacqueline.id.au>2023-06-01 15:41:47 +1000
commitdd27c3530432ea0b09f01e604bf577f31d8ef841 (patch)
treebbf86cf81a78f0ff0b07f31f1c390db473f26fd3 /lib/lvgl/examples/widgets/chart
parent6fd588e970470b15936187980829916d0dbe77bb (diff)
downloadtangara-fw-dd27c3530432ea0b09f01e604bf577f31d8ef841.tar.gz
convert lvgl from submodule to a plain old directory
Diffstat (limited to 'lib/lvgl/examples/widgets/chart')
m---------lib/lvgl0
-rw-r--r--lib/lvgl/examples/widgets/chart/index.rst49
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_1.c44
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_1.py26
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_2.c130
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_2.py76
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_3.c76
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_3.py52
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_4.c86
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_4.py73
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_5.c99
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_5.py89
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_6.c87
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_6.py88
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_7.c66
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_7.py77
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_8.c131
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_8.py124
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_9.c46
-rw-r--r--lib/lvgl/examples/widgets/chart/lv_example_chart_9.py31
20 files changed, 1450 insertions, 0 deletions
diff --git a/lib/lvgl b/lib/lvgl
deleted file mode 160000
-Subproject 0732400e7b564dd0e7dc4a924619d8e19c5b23a
diff --git a/lib/lvgl/examples/widgets/chart/index.rst b/lib/lvgl/examples/widgets/chart/index.rst
new file mode 100644
index 00000000..d07f0969
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/index.rst
@@ -0,0 +1,49 @@
+
+Line Chart
+""""""""""
+
+.. lv_example:: widgets/chart/lv_example_chart_1
+ :language: c
+
+
+Faded area line chart with custom division lines
+"""""""""""""""""""""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/chart/lv_example_chart_2
+ :language: c
+
+Axis ticks and labels with scrolling
+""""""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/chart/lv_example_chart_3
+ :language: c
+
+Show the value of the pressed points
+""""""""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/chart/lv_example_chart_4
+ :language: c
+
+Display 1000 data points with zooming and scrolling
+""""""""""""""""""""""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/chart/lv_example_chart_5
+ :language: c
+
+Show cursor on the clicked point
+"""""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/chart/lv_example_chart_6
+ :language: c
+
+Scatter chart
+"""""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/chart/lv_example_chart_7
+ :language: c
+
+Stacked area chart
+"""""""""""""""""""""""""""""""""""
+
+.. lv_example:: widgets/chart/lv_example_chart_8
+ :language:
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_1.c b/lib/lvgl/examples/widgets/chart/lv_example_chart_1.c
new file mode 100644
index 00000000..a946e188
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_1.c
@@ -0,0 +1,44 @@
+#include "../../lv_examples.h"
+#if LV_USE_CHART && LV_BUILD_EXAMPLES
+
+void lv_example_chart_1(void)
+{
+ /*Create a chart*/
+ lv_obj_t * chart;
+ chart = lv_chart_create(lv_scr_act());
+ lv_obj_set_size(chart, 200, 150);
+ lv_obj_center(chart);
+ lv_chart_set_type(chart, LV_CHART_TYPE_LINE); /*Show lines and points too*/
+
+ /*Add two data series*/
+ lv_chart_series_t * ser1 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
+ lv_chart_series_t * ser2 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_GREEN), LV_CHART_AXIS_SECONDARY_Y);
+
+ /*Set the next points on 'ser1'*/
+ lv_chart_set_next_value(chart, ser1, 10);
+ lv_chart_set_next_value(chart, ser1, 10);
+ lv_chart_set_next_value(chart, ser1, 10);
+ lv_chart_set_next_value(chart, ser1, 10);
+ lv_chart_set_next_value(chart, ser1, 10);
+ lv_chart_set_next_value(chart, ser1, 10);
+ lv_chart_set_next_value(chart, ser1, 10);
+ lv_chart_set_next_value(chart, ser1, 30);
+ lv_chart_set_next_value(chart, ser1, 70);
+ lv_chart_set_next_value(chart, ser1, 90);
+
+ /*Directly set points on 'ser2'*/
+ ser2->y_points[0] = 90;
+ ser2->y_points[1] = 70;
+ ser2->y_points[2] = 65;
+ ser2->y_points[3] = 65;
+ ser2->y_points[4] = 65;
+ ser2->y_points[5] = 65;
+ ser2->y_points[6] = 65;
+ ser2->y_points[7] = 65;
+ ser2->y_points[8] = 65;
+ ser2->y_points[9] = 65;
+
+ lv_chart_refresh(chart); /*Required after direct set*/
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_1.py b/lib/lvgl/examples/widgets/chart/lv_example_chart_1.py
new file mode 100644
index 00000000..ec7afc34
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_1.py
@@ -0,0 +1,26 @@
+# Create a chart
+chart = lv.chart(lv.scr_act())
+chart.set_size(200, 150)
+chart.center()
+chart.set_type(lv.chart.TYPE.LINE) # Show lines and points too
+
+# Add two data series
+ser1 = chart.add_series(lv.palette_main(lv.PALETTE.RED), lv.chart.AXIS.PRIMARY_Y)
+ser2 = chart.add_series(lv.palette_main(lv.PALETTE.GREEN), lv.chart.AXIS.SECONDARY_Y)
+print(ser2)
+# Set next points on ser1
+chart.set_next_value(ser1,10)
+chart.set_next_value(ser1,10)
+chart.set_next_value(ser1,10)
+chart.set_next_value(ser1,10)
+chart.set_next_value(ser1,10)
+chart.set_next_value(ser1,10)
+chart.set_next_value(ser1,10)
+chart.set_next_value(ser1,30)
+chart.set_next_value(ser1,70)
+chart.set_next_value(ser1,90)
+
+# Directly set points on 'ser2'
+ser2.y_points = [90, 70, 65, 65, 65, 65, 65, 65, 65, 65]
+chart.refresh() # Required after direct set
+
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_2.c b/lib/lvgl/examples/widgets/chart/lv_example_chart_2.c
new file mode 100644
index 00000000..a10f6f9e
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_2.c
@@ -0,0 +1,130 @@
+#include "../../lv_examples.h"
+#if LV_USE_CHART && LV_DRAW_COMPLEX && LV_BUILD_EXAMPLES
+
+static lv_obj_t * chart1;
+static lv_chart_series_t * ser1;
+static lv_chart_series_t * ser2;
+
+static void draw_event_cb(lv_event_t * e)
+{
+ lv_obj_t * obj = lv_event_get_target(e);
+
+ /*Add the faded area before the lines are drawn*/
+ lv_obj_draw_part_dsc_t * dsc = lv_event_get_draw_part_dsc(e);
+ if(dsc->part == LV_PART_ITEMS) {
+ if(!dsc->p1 || !dsc->p2) return;
+
+ /*Add a line mask that keeps the area below the line*/
+ lv_draw_mask_line_param_t line_mask_param;
+ lv_draw_mask_line_points_init(&line_mask_param, dsc->p1->x, dsc->p1->y, dsc->p2->x, dsc->p2->y,
+ LV_DRAW_MASK_LINE_SIDE_BOTTOM);
+ int16_t line_mask_id = lv_draw_mask_add(&line_mask_param, NULL);
+
+ /*Add a fade effect: transparent bottom covering top*/
+ lv_coord_t h = lv_obj_get_height(obj);
+ lv_draw_mask_fade_param_t fade_mask_param;
+ lv_draw_mask_fade_init(&fade_mask_param, &obj->coords, LV_OPA_COVER, obj->coords.y1 + h / 8, LV_OPA_TRANSP,
+ obj->coords.y2);
+ int16_t fade_mask_id = lv_draw_mask_add(&fade_mask_param, NULL);
+
+ /*Draw a rectangle that will be affected by the mask*/
+ lv_draw_rect_dsc_t draw_rect_dsc;
+ lv_draw_rect_dsc_init(&draw_rect_dsc);
+ draw_rect_dsc.bg_opa = LV_OPA_20;
+ draw_rect_dsc.bg_color = dsc->line_dsc->color;
+
+ lv_area_t a;
+ a.x1 = dsc->p1->x;
+ a.x2 = dsc->p2->x - 1;
+ a.y1 = LV_MIN(dsc->p1->y, dsc->p2->y);
+ a.y2 = obj->coords.y2;
+ lv_draw_rect(dsc->draw_ctx, &draw_rect_dsc, &a);
+
+ /*Remove the masks*/
+ lv_draw_mask_free_param(&line_mask_param);
+ lv_draw_mask_free_param(&fade_mask_param);
+ lv_draw_mask_remove_id(line_mask_id);
+ lv_draw_mask_remove_id(fade_mask_id);
+ }
+ /*Hook the division lines too*/
+ else if(dsc->part == LV_PART_MAIN) {
+ if(dsc->line_dsc == NULL || dsc->p1 == NULL || dsc->p2 == NULL) return;
+
+ /*Vertical line*/
+ if(dsc->p1->x == dsc->p2->x) {
+ dsc->line_dsc->color = lv_palette_lighten(LV_PALETTE_GREY, 1);
+ if(dsc->id == 3) {
+ dsc->line_dsc->width = 2;
+ dsc->line_dsc->dash_gap = 0;
+ dsc->line_dsc->dash_width = 0;
+ }
+ else {
+ dsc->line_dsc->width = 1;
+ dsc->line_dsc->dash_gap = 6;
+ dsc->line_dsc->dash_width = 6;
+ }
+ }
+ /*Horizontal line*/
+ else {
+ if(dsc->id == 2) {
+ dsc->line_dsc->width = 2;
+ dsc->line_dsc->dash_gap = 0;
+ dsc->line_dsc->dash_width = 0;
+ }
+ else {
+ dsc->line_dsc->width = 2;
+ dsc->line_dsc->dash_gap = 6;
+ dsc->line_dsc->dash_width = 6;
+ }
+
+ if(dsc->id == 1 || dsc->id == 3) {
+ dsc->line_dsc->color = lv_palette_main(LV_PALETTE_GREEN);
+ }
+ else {
+ dsc->line_dsc->color = lv_palette_lighten(LV_PALETTE_GREY, 1);
+ }
+ }
+ }
+}
+
+static void add_data(lv_timer_t * timer)
+{
+ LV_UNUSED(timer);
+ static uint32_t cnt = 0;
+ lv_chart_set_next_value(chart1, ser1, lv_rand(20, 90));
+
+ if(cnt % 4 == 0) lv_chart_set_next_value(chart1, ser2, lv_rand(40, 60));
+
+ cnt++;
+}
+
+/**
+ * Add a faded area effect to the line chart and make some division lines ticker
+ */
+void lv_example_chart_2(void)
+{
+ /*Create a chart1*/
+ chart1 = lv_chart_create(lv_scr_act());
+ lv_obj_set_size(chart1, 200, 150);
+ lv_obj_center(chart1);
+ lv_chart_set_type(chart1, LV_CHART_TYPE_LINE); /*Show lines and points too*/
+
+ lv_chart_set_div_line_count(chart1, 5, 7);
+
+ lv_obj_add_event_cb(chart1, draw_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);
+ lv_chart_set_update_mode(chart1, LV_CHART_UPDATE_MODE_CIRCULAR);
+
+ /*Add two data series*/
+ ser1 = lv_chart_add_series(chart1, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
+ ser2 = lv_chart_add_series(chart1, lv_palette_main(LV_PALETTE_BLUE), LV_CHART_AXIS_SECONDARY_Y);
+
+ uint32_t i;
+ for(i = 0; i < 10; i++) {
+ lv_chart_set_next_value(chart1, ser1, lv_rand(20, 90));
+ lv_chart_set_next_value(chart1, ser2, lv_rand(30, 70));
+ }
+
+ lv_timer_create(add_data, 200, NULL);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_2.py b/lib/lvgl/examples/widgets/chart/lv_example_chart_2.py
new file mode 100644
index 00000000..ad2c8794
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_2.py
@@ -0,0 +1,76 @@
+def draw_event_cb(e):
+
+ obj = e.get_target()
+
+ # Add the faded area before the lines are drawn
+ dsc = lv.obj_draw_part_dsc_t.__cast__(e.get_param())
+ if dsc.part != lv.PART.ITEMS:
+ return
+ if not dsc.p1 or not dsc.p2:
+ return
+
+ # Add a line mask that keeps the area below the line
+ line_mask_param = lv.draw_mask_line_param_t()
+ line_mask_param.points_init(dsc.p1.x, dsc.p1.y, dsc.p2.x, dsc.p2.y, lv.DRAW_MASK_LINE_SIDE.BOTTOM)
+ # line_mask_id = line_mask_param.draw_mask_add(None)
+ line_mask_id = lv.draw_mask_add(line_mask_param, None)
+ # Add a fade effect: transparent bottom covering top
+ h = obj.get_height()
+ fade_mask_param = lv.draw_mask_fade_param_t()
+ coords = lv.area_t()
+ obj.get_coords(coords)
+ fade_mask_param.init(coords, lv.OPA.COVER, coords.y1 + h // 8, lv.OPA.TRANSP,coords.y2)
+ fade_mask_id = lv.draw_mask_add(fade_mask_param,None)
+
+ # Draw a rectangle that will be affected by the mask
+ draw_rect_dsc = lv.draw_rect_dsc_t()
+ draw_rect_dsc.init()
+ draw_rect_dsc.bg_opa = lv.OPA._20
+ draw_rect_dsc.bg_color = dsc.line_dsc.color
+
+ a = lv.area_t()
+ a.x1 = dsc.p1.x
+ a.x2 = dsc.p2.x - 1
+ a.y1 = min(dsc.p1.y, dsc.p2.y)
+ coords = lv.area_t()
+ obj.get_coords(coords)
+ a.y2 = coords.y2
+ dsc.draw_ctx.rect(draw_rect_dsc, a)
+
+ # Remove the masks
+ lv.draw_mask_remove_id(line_mask_id)
+ lv.draw_mask_remove_id(fade_mask_id)
+
+
+def add_data(timer):
+ # LV_UNUSED(timer);
+ cnt = 0
+ chart1.set_next_value(ser1, lv.rand(20, 90))
+
+ if cnt % 4 == 0:
+ chart1.set_next_value(ser2, lv.rand(40, 60))
+
+ cnt +=1
+
+#
+# Add a faded area effect to the line chart
+#
+
+# Create a chart1
+chart1 = lv.chart(lv.scr_act())
+chart1.set_size(200, 150)
+chart1.center()
+chart1.set_type(lv.chart.TYPE.LINE) # Show lines and points too
+
+chart1.add_event_cb(draw_event_cb, lv.EVENT.DRAW_PART_BEGIN, None)
+chart1.set_update_mode(lv.chart.UPDATE_MODE.CIRCULAR)
+
+# Add two data series
+ser1 = chart1.add_series(lv.palette_main(lv.PALETTE.RED), lv.chart.AXIS.PRIMARY_Y)
+ser2 = chart1.add_series(lv.palette_main(lv.PALETTE.BLUE), lv.chart.AXIS.SECONDARY_Y)
+
+for i in range(10):
+ chart1.set_next_value(ser1, lv.rand(20, 90))
+ chart1.set_next_value(ser2, lv.rand(30, 70))
+
+timer = lv.timer_create(add_data, 200, None)
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_3.c b/lib/lvgl/examples/widgets/chart/lv_example_chart_3.c
new file mode 100644
index 00000000..b5111502
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_3.c
@@ -0,0 +1,76 @@
+#include "../../lv_examples.h"
+#if LV_USE_CHART && LV_BUILD_EXAMPLES
+
+static void draw_event_cb(lv_event_t * e)
+{
+ lv_obj_draw_part_dsc_t * dsc = lv_event_get_draw_part_dsc(e);
+ if(!lv_obj_draw_part_check_type(dsc, &lv_chart_class, LV_CHART_DRAW_PART_TICK_LABEL)) return;
+
+ if(dsc->id == LV_CHART_AXIS_PRIMARY_X && dsc->text) {
+ const char * month[] = {"Jan", "Febr", "March", "Apr", "May", "Jun", "July", "Aug", "Sept", "Oct", "Nov", "Dec"};
+ lv_snprintf(dsc->text, dsc->text_length, "%s", month[dsc->value]);
+ }
+}
+
+/**
+ * Add ticks and labels to the axis and demonstrate scrolling
+ */
+void lv_example_chart_3(void)
+{
+ /*Create a chart*/
+ lv_obj_t * chart;
+ chart = lv_chart_create(lv_scr_act());
+ lv_obj_set_size(chart, 200, 150);
+ lv_obj_center(chart);
+ lv_chart_set_type(chart, LV_CHART_TYPE_BAR);
+ lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, 0, 100);
+ lv_chart_set_range(chart, LV_CHART_AXIS_SECONDARY_Y, 0, 400);
+ lv_chart_set_point_count(chart, 12);
+ lv_obj_add_event_cb(chart, draw_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);
+
+ /*Add ticks and label to every axis*/
+ lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_X, 10, 5, 12, 3, true, 40);
+ lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_Y, 10, 5, 6, 2, true, 50);
+ lv_chart_set_axis_tick(chart, LV_CHART_AXIS_SECONDARY_Y, 10, 5, 3, 4, true, 50);
+
+ /*Zoom in a little in X*/
+ lv_chart_set_zoom_x(chart, 800);
+
+ /*Add two data series*/
+ lv_chart_series_t * ser1 = lv_chart_add_series(chart, lv_palette_lighten(LV_PALETTE_GREEN, 2), LV_CHART_AXIS_PRIMARY_Y);
+ lv_chart_series_t * ser2 = lv_chart_add_series(chart, lv_palette_darken(LV_PALETTE_GREEN, 2),
+ LV_CHART_AXIS_SECONDARY_Y);
+
+ /*Set the next points on 'ser1'*/
+ lv_chart_set_next_value(chart, ser1, 31);
+ lv_chart_set_next_value(chart, ser1, 66);
+ lv_chart_set_next_value(chart, ser1, 10);
+ lv_chart_set_next_value(chart, ser1, 89);
+ lv_chart_set_next_value(chart, ser1, 63);
+ lv_chart_set_next_value(chart, ser1, 56);
+ lv_chart_set_next_value(chart, ser1, 32);
+ lv_chart_set_next_value(chart, ser1, 35);
+ lv_chart_set_next_value(chart, ser1, 57);
+ lv_chart_set_next_value(chart, ser1, 85);
+ lv_chart_set_next_value(chart, ser1, 22);
+ lv_chart_set_next_value(chart, ser1, 58);
+
+ lv_coord_t * ser2_array = lv_chart_get_y_array(chart, ser2);
+ /*Directly set points on 'ser2'*/
+ ser2_array[0] = 92;
+ ser2_array[1] = 71;
+ ser2_array[2] = 61;
+ ser2_array[3] = 15;
+ ser2_array[4] = 21;
+ ser2_array[5] = 35;
+ ser2_array[6] = 35;
+ ser2_array[7] = 58;
+ ser2_array[8] = 31;
+ ser2_array[9] = 53;
+ ser2_array[10] = 33;
+ ser2_array[11] = 73;
+
+ lv_chart_refresh(chart); /*Required after direct set*/
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_3.py b/lib/lvgl/examples/widgets/chart/lv_example_chart_3.py
new file mode 100644
index 00000000..0afe6fe1
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_3.py
@@ -0,0 +1,52 @@
+def draw_event_cb(e):
+
+ dsc = lv.obj_draw_part_dsc_t.__cast__(e.get_param())
+ if dsc.part == lv.PART.TICKS and dsc.id == lv.chart.AXIS.PRIMARY_X:
+ month = ["Jan", "Febr", "March", "Apr", "May", "Jun", "July", "Aug", "Sept", "Oct", "Nov", "Dec"]
+ # dsc.text is defined char text[16], I must therefore convert the Python string to a byte_array
+ dsc.text = bytes(month[dsc.value],"ascii")
+#
+# Add ticks and labels to the axis and demonstrate scrolling
+#
+
+# Create a chart
+chart = lv.chart(lv.scr_act())
+chart.set_size(200, 150)
+chart.center()
+chart.set_type(lv.chart.TYPE.BAR)
+chart.set_range(lv.chart.AXIS.PRIMARY_Y, 0, 100)
+chart.set_range(lv.chart.AXIS.SECONDARY_Y, 0, 400)
+chart.set_point_count(12)
+chart.add_event_cb(draw_event_cb, lv.EVENT.DRAW_PART_BEGIN, None)
+
+# Add ticks and label to every axis
+chart.set_axis_tick(lv.chart.AXIS.PRIMARY_X, 10, 5, 12, 3, True, 40)
+chart.set_axis_tick(lv.chart.AXIS.PRIMARY_Y, 10, 5, 6, 2, True, 50)
+chart.set_axis_tick(lv.chart.AXIS.SECONDARY_Y, 10, 5, 3, 4,True, 50)
+
+# Zoom in a little in X
+chart.set_zoom_x(800)
+
+# Add two data series
+ser1 = lv.chart.add_series(chart, lv.palette_lighten(lv.PALETTE.GREEN, 2), lv.chart.AXIS.PRIMARY_Y)
+ser2 = lv.chart.add_series(chart, lv.palette_darken(lv.PALETTE.GREEN, 2), lv.chart.AXIS.SECONDARY_Y)
+
+# Set the next points on 'ser1'
+chart.set_next_value(ser1, 31)
+chart.set_next_value(ser1, 66)
+chart.set_next_value(ser1, 10)
+chart.set_next_value(ser1, 89)
+chart.set_next_value(ser1, 63)
+chart.set_next_value(ser1, 56)
+chart.set_next_value(ser1, 32)
+chart.set_next_value(ser1, 35)
+chart.set_next_value(ser1, 57)
+chart.set_next_value(ser1, 85)
+chart.set_next_value(ser1, 22)
+chart.set_next_value(ser1, 58)
+
+# Directly set points on 'ser2'
+ser2.y_points = [92,71,61,15,21,35,35,58,31,53,33,73]
+
+chart.refresh() # Required after direct set
+
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_4.c b/lib/lvgl/examples/widgets/chart/lv_example_chart_4.c
new file mode 100644
index 00000000..8508ef18
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_4.c
@@ -0,0 +1,86 @@
+#include "../../lv_examples.h"
+#if LV_USE_CHART && LV_BUILD_EXAMPLES
+
+
+static void event_cb(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+ lv_obj_t * chart = lv_event_get_target(e);
+
+ if(code == LV_EVENT_VALUE_CHANGED) {
+ lv_obj_invalidate(chart);
+ }
+ if(code == LV_EVENT_REFR_EXT_DRAW_SIZE) {
+ lv_coord_t * s = lv_event_get_param(e);
+ *s = LV_MAX(*s, 20);
+ }
+ else if(code == LV_EVENT_DRAW_POST_END) {
+ int32_t id = lv_chart_get_pressed_point(chart);
+ if(id == LV_CHART_POINT_NONE) return;
+
+ LV_LOG_USER("Selected point %d", (int)id);
+
+ lv_chart_series_t * ser = lv_chart_get_series_next(chart, NULL);
+ while(ser) {
+ lv_point_t p;
+ lv_chart_get_point_pos_by_id(chart, ser, id, &p);
+
+ lv_coord_t * y_array = lv_chart_get_y_array(chart, ser);
+ lv_coord_t value = y_array[id];
+
+ char buf[16];
+ lv_snprintf(buf, sizeof(buf), LV_SYMBOL_DUMMY"$%d", value);
+
+ lv_draw_rect_dsc_t draw_rect_dsc;
+ lv_draw_rect_dsc_init(&draw_rect_dsc);
+ draw_rect_dsc.bg_color = lv_color_black();
+ draw_rect_dsc.bg_opa = LV_OPA_50;
+ draw_rect_dsc.radius = 3;
+ draw_rect_dsc.bg_img_src = buf;
+ draw_rect_dsc.bg_img_recolor = lv_color_white();
+
+ lv_area_t a;
+ a.x1 = chart->coords.x1 + p.x - 20;
+ a.x2 = chart->coords.x1 + p.x + 20;
+ a.y1 = chart->coords.y1 + p.y - 30;
+ a.y2 = chart->coords.y1 + p.y - 10;
+
+ lv_draw_ctx_t * draw_ctx = lv_event_get_draw_ctx(e);
+ lv_draw_rect(draw_ctx, &draw_rect_dsc, &a);
+
+ ser = lv_chart_get_series_next(chart, ser);
+ }
+ }
+ else if(code == LV_EVENT_RELEASED) {
+ lv_obj_invalidate(chart);
+ }
+}
+
+/**
+ * Show the value of the pressed points
+ */
+void lv_example_chart_4(void)
+{
+ /*Create a chart*/
+ lv_obj_t * chart;
+ chart = lv_chart_create(lv_scr_act());
+ lv_obj_set_size(chart, 200, 150);
+ lv_obj_center(chart);
+
+ lv_obj_add_event_cb(chart, event_cb, LV_EVENT_ALL, NULL);
+ lv_obj_refresh_ext_draw_size(chart);
+
+ /*Zoom in a little in X*/
+ lv_chart_set_zoom_x(chart, 800);
+
+ /*Add two data series*/
+ lv_chart_series_t * ser1 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
+ lv_chart_series_t * ser2 = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_GREEN), LV_CHART_AXIS_PRIMARY_Y);
+ uint32_t i;
+ for(i = 0; i < 10; i++) {
+ lv_chart_set_next_value(chart, ser1, lv_rand(60, 90));
+ lv_chart_set_next_value(chart, ser2, lv_rand(10, 40));
+ }
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_4.py b/lib/lvgl/examples/widgets/chart/lv_example_chart_4.py
new file mode 100644
index 00000000..3b8d0633
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_4.py
@@ -0,0 +1,73 @@
+def event_cb(e):
+ code = e.get_code()
+ chart = e.get_target()
+
+ if code == lv.EVENT.VALUE_CHANGED:
+ chart.invalidate()
+
+ if code == lv.EVENT.REFR_EXT_DRAW_SIZE:
+ e.set_ext_draw_size(20)
+
+ elif code == lv.EVENT.DRAW_POST_END:
+ id = lv.chart.get_pressed_point(chart)
+ if id == lv.CHART_POINT.NONE:
+ return
+ # print("Selected point ", id)
+ for i in range(len(series)):
+ p = lv.point_t()
+ chart.get_point_pos_by_id(series[i], id, p)
+ value = series_points[i][id]
+ buf = lv.SYMBOL.DUMMY + "$" + str(value)
+
+ draw_rect_dsc = lv.draw_rect_dsc_t()
+ draw_rect_dsc.init()
+ draw_rect_dsc.bg_color = lv.color_black()
+ draw_rect_dsc.bg_opa = lv.OPA._50
+ draw_rect_dsc.radius = 3
+ draw_rect_dsc.bg_img_src = buf
+ draw_rect_dsc.bg_img_recolor = lv.color_white()
+
+ a = lv.area_t()
+ coords = lv.area_t()
+ chart.get_coords(coords)
+ a.x1 = coords.x1 + p.x - 20
+ a.x2 = coords.x1 + p.x + 20
+ a.y1 = coords.y1 + p.y - 30
+ a.y2 = coords.y1 + p.y - 10
+
+ clip_area = lv.area_t.__cast__(e.get_param())
+ lv.draw_rect(a, clip_area, draw_rect_dsc)
+
+ elif code == lv.EVENT.RELEASED:
+ chart.invalidate()
+
+#
+# Add ticks and labels to the axis and demonstrate scrolling
+#
+
+# Create a chart
+chart = lv.chart(lv.scr_act())
+chart.set_size(200, 150)
+chart.center()
+
+chart.add_event_cb(event_cb, lv.EVENT.ALL, None)
+chart.refresh_ext_draw_size()
+
+# Zoom in a little in X
+chart.set_zoom_x(800)
+
+# Add two data series
+ser1 = chart.add_series(lv.palette_main(lv.PALETTE.RED), lv.chart.AXIS.PRIMARY_Y)
+ser2 = chart.add_series(lv.palette_main(lv.PALETTE.GREEN), lv.chart.AXIS.PRIMARY_Y)
+
+ser1_p = []
+ser2_p = []
+for i in range(10):
+ ser1_p.append(lv.rand(60,90))
+ ser2_p.append(lv.rand(10,40))
+ser1.y_points = ser1_p
+ser2.y_points = ser2_p
+
+series = [ser1,ser2]
+series_points=[ser1_p,ser2_p]
+
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_5.c b/lib/lvgl/examples/widgets/chart/lv_example_chart_5.c
new file mode 100644
index 00000000..c175e37c
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_5.c
@@ -0,0 +1,99 @@
+#include "../../lv_examples.h"
+#if LV_USE_CHART && LV_USE_SLIDER && LV_BUILD_EXAMPLES
+
+static lv_obj_t * chart;
+/* Source: https://github.com/ankur219/ECG-Arrhythmia-classification/blob/642230149583adfae1e4bd26c6f0e1fd8af2be0e/sample.csv*/
+static const lv_coord_t ecg_sample[] = {
+ -2, 2, 0, -15, -39, -63, -71, -68, -67, -69, -84, -95, -104, -107, -108, -107, -107, -107, -107, -114, -118, -117,
+ -112, -100, -89, -83, -71, -64, -58, -58, -62, -62, -58, -51, -46, -39, -27, -10, 4, 7, 1, -3, 0, 14, 24, 30, 25, 19,
+ 13, 7, 12, 15, 18, 21, 13, 6, 9, 8, 17, 19, 13, 11, 11, 11, 23, 30, 37, 34, 25, 14, 15, 19, 28, 31, 26, 23, 25, 31,
+ 39, 37, 37, 34, 30, 32, 22, 29, 31, 33, 37, 23, 13, 7, 2, 4, -2, 2, 11, 22, 33, 19, -1, -27, -55, -67, -72, -71, -63,
+ -49, -18, 35, 113, 230, 369, 525, 651, 722, 730, 667, 563, 454, 357, 305, 288, 274, 255, 212, 173, 143, 117, 82, 39,
+ -13, -53, -78, -91, -101, -113, -124, -131, -131, -131, -129, -128, -129, -125, -123, -123, -129, -139, -148, -153,
+ -159, -166, -183, -205, -227, -243, -248, -246, -254, -280, -327, -381, -429, -473, -517, -556, -592, -612, -620,
+ -620, -614, -604, -591, -574, -540, -497, -441, -389, -358, -336, -313, -284, -222, -167, -114, -70, -47, -28, -4, 12,
+ 38, 52, 58, 56, 56, 57, 68, 77, 86, 86, 80, 69, 67, 70, 82, 85, 89, 90, 89, 89, 88, 91, 96, 97, 91, 83, 78, 82, 88, 95,
+ 96, 105, 106, 110, 102, 100, 96, 98, 97, 101, 98, 99, 100, 107, 113, 119, 115, 110, 96, 85, 73, 64, 69, 76, 79,
+ 78, 75, 85, 100, 114, 113, 105, 96, 84, 74, 66, 60, 75, 85, 89, 83, 67, 61, 67, 73, 79, 74, 63, 57, 56, 58, 61, 55,
+ 48, 45, 46, 55, 62, 55, 49, 43, 50, 59, 63, 57, 40, 31, 23, 25, 27, 31, 35, 34, 30, 36, 34, 42, 38, 36, 40, 46, 50,
+ 47, 32, 30, 32, 52, 67, 73, 71, 63, 54, 53, 45, 41, 28, 13, 3, 1, 4, 4, -8, -23, -32, -31, -19, -5, 3, 9, 13, 19,
+ 24, 27, 29, 25, 22, 26, 32, 42, 51, 56, 60, 57, 55, 53, 53, 54, 59, 54, 49, 26, -3, -11, -20, -47, -100, -194, -236,
+ -212, -123, 8, 103, 142, 147, 120, 105, 98, 93, 81, 61, 40, 26, 28, 30, 30, 27, 19, 17, 21, 20, 19, 19, 22, 36, 40,
+ 35, 20, 7, 1, 10, 18, 27, 22, 6, -4, -2, 3, 6, -2, -13, -14, -10, -2, 3, 2, -1, -5, -10, -19, -32, -42, -55, -60,
+ -68, -77, -86, -101, -110, -117, -115, -104, -92, -84, -85, -84, -73, -65, -52, -50, -45, -35, -20, -3, 12, 20, 25,
+ 26, 28, 28, 30, 28, 25, 28, 33, 42, 42, 36, 23, 9, 0, 1, -4, 1, -4, -4, 1, 5, 9, 9, -3, -1, -18, -50, -108, -190,
+ -272, -340, -408, -446, -537, -643, -777, -894, -920, -853, -697, -461, -251, -60, 58, 103, 129, 139, 155, 170, 173,
+ 178, 185, 190, 193, 200, 208, 215, 225, 224, 232, 234, 240, 240, 236, 229, 226, 224, 232, 233, 232, 224, 219, 219,
+ 223, 231, 226, 223, 219, 218, 223, 223, 223, 233, 245, 268, 286, 296, 295, 283, 271, 263, 252, 243, 226, 210, 197,
+ 186, 171, 152, 133, 117, 114, 110, 107, 96, 80, 63, 48, 40, 38, 34, 28, 15, 2, -7, -11, -14, -18, -29, -37, -44, -50,
+ -58, -63, -61, -52, -50, -48, -61, -59, -58, -54, -47, -52, -62, -61, -64, -54, -52, -59, -69, -76, -76, -69, -67,
+ -74, -78, -81, -80, -73, -65, -57, -53, -51, -47, -35, -27, -22, -22, -24, -21, -17, -13, -10, -11, -13, -20, -20,
+ -12, -2, 7, -1, -12, -16, -13, -2, 2, -4, -5, -2, 9, 19, 19, 14, 11, 13, 19, 21, 20, 18, 19, 19, 19, 16, 15, 13, 14,
+ 9, 3, -5, -9, -5, -3, -2, -3, -3, 2, 8, 9, 9, 5, 6, 8, 8, 7, 4, 3, 4, 5, 3, 5, 5, 13, 13, 12, 10, 10, 15, 22, 17,
+ 14, 7, 10, 15, 16, 11, 12, 10, 13, 9, -2, -4, -2, 7, 16, 16, 17, 16, 7, -1, -16, -18, -16, -9, -4, -5, -10, -9, -8,
+ -3, -4, -10, -19, -20, -16, -9, -9, -23, -40, -48, -43, -33, -19, -21, -26, -31, -33, -19, 0, 17, 24, 9, -17, -47,
+ -63, -67, -59, -52, -51, -50, -49, -42, -26, -21, -15, -20, -23, -22, -19, -12, -8, 5, 18, 27, 32, 26, 25, 26, 22,
+ 23, 17, 14, 17, 21, 25, 2, -45, -121, -196, -226, -200, -118, -9, 73, 126, 131, 114, 87, 60, 42, 29, 26, 34, 35, 34,
+ 25, 12, 9, 7, 3, 2, -8, -11, 2, 23, 38, 41, 23, 9, 10, 13, 16, 8, -8, -17, -23, -26, -25, -21, -15, -10, -13, -13,
+ -19, -22, -29, -40, -48, -48, -54, -55, -66, -82, -85, -90, -92, -98, -114, -119, -124, -129, -132, -146, -146, -138,
+ -124, -99, -85, -72, -65, -65, -65, -66, -63, -64, -64, -58, -46, -26, -9, 2, 2, 4, 0, 1, 4, 3, 10, 11, 10, 2, -4,
+ 0, 10, 18, 20, 6, 2, -9, -7, -3, -3, -2, -7, -12, -5, 5, 24, 36, 31, 25, 6, 3, 7, 12, 17, 11, 0, -6, -9, -8, -7, -5,
+ -6, -2, -2, -6, -2, 2, 14, 24, 22, 15, 8, 4, 6, 7, 12, 16, 25, 20, 7, -16, -41, -60, -67, -65, -54, -35, -11, 30,
+ 84, 175, 302, 455, 603, 707, 743, 714, 625, 519, 414, 337, 300, 281, 263, 239, 197, 163, 136, 109, 77, 34, -18, -50,
+ -66, -74, -79, -92, -107, -117, -127, -129, -135, -139, -141, -155, -159, -167, -171, -169, -174, -175, -178, -191,
+ -202, -223, -235, -243, -237, -240, -256, -298, -345, -393, -432, -475, -518, -565, -596, -619, -623, -623, -614,
+ -599, -583, -559, -524, -477, -425, -383, -357, -331, -301, -252, -198, -143, -96, -57, -29, -8, 10, 31, 45, 60, 65,
+ 70, 74, 76, 79, 82, 79, 75, 62,
+ };
+
+static void slider_x_event_cb(lv_event_t * e)
+{
+ lv_obj_t * obj = lv_event_get_target(e);
+ int32_t v = lv_slider_get_value(obj);
+ lv_chart_set_zoom_x(chart, v);
+}
+
+static void slider_y_event_cb(lv_event_t * e)
+{
+ lv_obj_t * obj = lv_event_get_target(e);
+ int32_t v = lv_slider_get_value(obj);
+ lv_chart_set_zoom_y(chart, v);
+}
+
+/**
+ * Display 1000 data points with zooming and scrolling.
+ * See how the chart changes drawing mode (draw only vertical lines) when
+ * the points get too crowded.
+ */
+void lv_example_chart_5(void)
+{
+ /*Create a chart*/
+ chart = lv_chart_create(lv_scr_act());
+ lv_obj_set_size(chart, 200, 150);
+ lv_obj_align(chart, LV_ALIGN_CENTER, -30, -30);
+ lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, -1000, 1000);
+
+ /*Do not display points on the data*/
+ lv_obj_set_style_size(chart, 0, LV_PART_INDICATOR);
+
+ lv_chart_series_t * ser = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
+
+ uint32_t pcnt = sizeof(ecg_sample) / sizeof(ecg_sample[0]);
+ lv_chart_set_point_count(chart, pcnt);
+ lv_chart_set_ext_y_array(chart, ser, (lv_coord_t *)ecg_sample);
+
+ lv_obj_t * slider;
+ slider = lv_slider_create(lv_scr_act());
+ lv_slider_set_range(slider, LV_IMG_ZOOM_NONE, LV_IMG_ZOOM_NONE * 10);
+ lv_obj_add_event_cb(slider, slider_x_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
+ lv_obj_set_size(slider, 200, 10);
+ lv_obj_align_to(slider, chart, LV_ALIGN_OUT_BOTTOM_MID, 0, 20);
+
+ slider = lv_slider_create(lv_scr_act());
+ lv_slider_set_range(slider, LV_IMG_ZOOM_NONE, LV_IMG_ZOOM_NONE * 10);
+ lv_obj_add_event_cb(slider, slider_y_event_cb, LV_EVENT_VALUE_CHANGED, NULL);
+ lv_obj_set_size(slider, 10, 150);
+ lv_obj_align_to(slider, chart, LV_ALIGN_OUT_RIGHT_MID, 20, 0);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_5.py b/lib/lvgl/examples/widgets/chart/lv_example_chart_5.py
new file mode 100644
index 00000000..f0d58323
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_5.py
@@ -0,0 +1,89 @@
+# Source: https://github.com/ankur219/ECG-Arrhythmia-classification/blob/642230149583adfae1e4bd26c6f0e1fd8af2be0e/sample.csv
+ecg_sample = [
+ -2, 2, 0, -15, -39, -63, -71, -68, -67, -69, -84, -95, -104, -107, -108, -107, -107, -107, -107, -114, -118, -117,
+ -112, -100, -89, -83, -71, -64, -58, -58, -62, -62, -58, -51, -46, -39, -27, -10, 4, 7, 1, -3, 0, 14, 24, 30, 25, 19,
+ 13, 7, 12, 15, 18, 21, 13, 6, 9, 8, 17, 19, 13, 11, 11, 11, 23, 30, 37, 34, 25, 14, 15, 19, 28, 31, 26, 23, 25, 31,
+ 39, 37, 37, 34, 30, 32, 22, 29, 31, 33, 37, 23, 13, 7, 2, 4, -2, 2, 11, 22, 33, 19, -1, -27, -55, -67, -72, -71, -63,
+ -49, -18, 35, 113, 230, 369, 525, 651, 722, 730, 667, 563, 454, 357, 305, 288, 274, 255, 212, 173, 143, 117, 82, 39,
+ -13, -53, -78, -91, -101, -113, -124, -131, -131, -131, -129, -128, -129, -125, -123, -123, -129, -139, -148, -153,
+ -159, -166, -183, -205, -227, -243, -248, -246, -254, -280, -327, -381, -429, -473, -517, -556, -592, -612, -620,
+ -620, -614, -604, -591, -574, -540, -497, -441, -389, -358, -336, -313, -284, -222, -167, -114, -70, -47, -28, -4, 12,
+ 38, 52, 58, 56, 56, 57, 68, 77, 86, 86, 80, 69, 67, 70, 82, 85, 89, 90, 89, 89, 88, 91, 96, 97, 91, 83, 78, 82, 88, 95,
+ 96, 105, 106, 110, 102, 100, 96, 98, 97, 101, 98, 99, 100, 107, 113, 119, 115, 110, 96, 85, 73, 64, 69, 76, 79,
+ 78, 75, 85, 100, 114, 113, 105, 96, 84, 74, 66, 60, 75, 85, 89, 83, 67, 61, 67, 73, 79, 74, 63, 57, 56, 58, 61, 55,
+ 48, 45, 46, 55, 62, 55, 49, 43, 50, 59, 63, 57, 40, 31, 23, 25, 27, 31, 35, 34, 30, 36, 34, 42, 38, 36, 40, 46, 50,
+ 47, 32, 30, 32, 52, 67, 73, 71, 63, 54, 53, 45, 41, 28, 13, 3, 1, 4, 4, -8, -23, -32, -31, -19, -5, 3, 9, 13, 19,
+ 24, 27, 29, 25, 22, 26, 32, 42, 51, 56, 60, 57, 55, 53, 53, 54, 59, 54, 49, 26, -3, -11, -20, -47, -100, -194, -236,
+ -212, -123, 8, 103, 142, 147, 120, 105, 98, 93, 81, 61, 40, 26, 28, 30, 30, 27, 19, 17, 21, 20, 19, 19, 22, 36, 40,
+ 35, 20, 7, 1, 10, 18, 27, 22, 6, -4, -2, 3, 6, -2, -13, -14, -10, -2, 3, 2, -1, -5, -10, -19, -32, -42, -55, -60,
+ -68, -77, -86, -101, -110, -117, -115, -104, -92, -84, -85, -84, -73, -65, -52, -50, -45, -35, -20, -3, 12, 20, 25,
+ 26, 28, 28, 30, 28, 25, 28, 33, 42, 42, 36, 23, 9, 0, 1, -4, 1, -4, -4, 1, 5, 9, 9, -3, -1, -18, -50, -108, -190,
+ -272, -340, -408, -446, -537, -643, -777, -894, -920, -853, -697, -461, -251, -60, 58, 103, 129, 139, 155, 170, 173,
+ 178, 185, 190, 193, 200, 208, 215, 225, 224, 232, 234, 240, 240, 236, 229, 226, 224, 232, 233, 232, 224, 219, 219,
+ 223, 231, 226, 223, 219, 218, 223, 223, 223, 233, 245, 268, 286, 296, 295, 283, 271, 263, 252, 243, 226, 210, 197,
+ 186, 171, 152, 133, 117, 114, 110, 107, 96, 80, 63, 48, 40, 38, 34, 28, 15, 2, -7, -11, -14, -18, -29, -37, -44, -50,
+ -58, -63, -61, -52, -50, -48, -61, -59, -58, -54, -47, -52, -62, -61, -64, -54, -52, -59, -69, -76, -76, -69, -67,
+ -74, -78, -81, -80, -73, -65, -57, -53, -51, -47, -35, -27, -22, -22, -24, -21, -17, -13, -10, -11, -13, -20, -20,
+ -12, -2, 7, -1, -12, -16, -13, -2, 2, -4, -5, -2, 9, 19, 19, 14, 11, 13, 19, 21, 20, 18, 19, 19, 19, 16, 15, 13, 14,
+ 9, 3, -5, -9, -5, -3, -2, -3, -3, 2, 8, 9, 9, 5, 6, 8, 8, 7, 4, 3, 4, 5, 3, 5, 5, 13, 13, 12, 10, 10, 15, 22, 17,
+ 14, 7, 10, 15, 16, 11, 12, 10, 13, 9, -2, -4, -2, 7, 16, 16, 17, 16, 7, -1, -16, -18, -16, -9, -4, -5, -10, -9, -8,
+ -3, -4, -10, -19, -20, -16, -9, -9, -23, -40, -48, -43, -33, -19, -21, -26, -31, -33, -19, 0, 17, 24, 9, -17, -47,
+ -63, -67, -59, -52, -51, -50, -49, -42, -26, -21, -15, -20, -23, -22, -19, -12, -8, 5, 18, 27, 32, 26, 25, 26, 22,
+ 23, 17, 14, 17, 21, 25, 2, -45, -121, -196, -226, -200, -118, -9, 73, 126, 131, 114, 87, 60, 42, 29, 26, 34, 35, 34,
+ 25, 12, 9, 7, 3, 2, -8, -11, 2, 23, 38, 41, 23, 9, 10, 13, 16, 8, -8, -17, -23, -26, -25, -21, -15, -10, -13, -13,
+ -19, -22, -29, -40, -48, -48, -54, -55, -66, -82, -85, -90, -92, -98, -114, -119, -124, -129, -132, -146, -146, -138,
+ -124, -99, -85, -72, -65, -65, -65, -66, -63, -64, -64, -58, -46, -26, -9, 2, 2, 4, 0, 1, 4, 3, 10, 11, 10, 2, -4,
+ 0, 10, 18, 20, 6, 2, -9, -7, -3, -3, -2, -7, -12, -5, 5, 24, 36, 31, 25, 6, 3, 7, 12, 17, 11, 0, -6, -9, -8, -7, -5,
+ -6, -2, -2, -6, -2, 2, 14, 24, 22, 15, 8, 4, 6, 7, 12, 16, 25, 20, 7, -16, -41, -60, -67, -65, -54, -35, -11, 30,
+ 84, 175, 302, 455, 603, 707, 743, 714, 625, 519, 414, 337, 300, 281, 263, 239, 197, 163, 136, 109, 77, 34, -18, -50,
+ -66, -74, -79, -92, -107, -117, -127, -129, -135, -139, -141, -155, -159, -167, -171, -169, -174, -175, -178, -191,
+ -202, -223, -235, -243, -237, -240, -256, -298, -345, -393, -432, -475, -518, -565, -596, -619, -623, -623, -614,
+ -599, -583, -559, -524, -477, -425, -383, -357, -331, -301, -252, -198, -143, -96, -57, -29, -8, 10, 31, 45, 60, 65,
+ 70, 74, 76, 79, 82, 79, 75, 62,
+]
+
+def slider_x_event_cb(e):
+
+ slider = e.get_target()
+ v = slider.get_value()
+ chart.set_zoom_x(v)
+
+def slider_y_event_cb(e):
+
+ slider = e.get_target()
+ v = slider.get_value()
+ chart.set_zoom_y(v)
+
+
+#
+# Display 1000 data points with zooming and scrolling.
+# See how the chart changes drawing mode (draw only vertical lines) when
+# the points get too crowded.
+
+# Create a chart
+chart = lv.chart(lv.scr_act())
+chart.set_size(200, 150)
+chart.align(lv.ALIGN.CENTER, -30, -30)
+chart.set_range(lv.chart.AXIS.PRIMARY_Y, -1000, 1000)
+
+# Do not display points on the data
+chart.set_style_size(0, lv.PART.INDICATOR)
+
+ser = chart.add_series(lv.palette_main(lv.PALETTE.RED), lv.chart.AXIS.PRIMARY_Y)
+
+pcnt = len(ecg_sample)
+chart.set_point_count(pcnt)
+chart.set_ext_y_array(ser, ecg_sample)
+
+slider = lv.slider(lv.scr_act())
+slider.set_range(lv.IMG_ZOOM.NONE, lv.IMG_ZOOM.NONE * 10)
+slider.add_event_cb(slider_x_event_cb, lv.EVENT.VALUE_CHANGED, None)
+slider.set_size(200,10)
+slider.align_to(chart, lv.ALIGN.OUT_BOTTOM_MID, 0, 20)
+
+slider = lv.slider(lv.scr_act())
+slider.set_range(lv.IMG_ZOOM.NONE, lv.IMG_ZOOM.NONE * 10)
+slider.add_event_cb(slider_y_event_cb, lv.EVENT.VALUE_CHANGED, None)
+slider.set_size(10, 150)
+slider.align_to(chart, lv.ALIGN.OUT_RIGHT_MID, 20, 0)
+
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_6.c b/lib/lvgl/examples/widgets/chart/lv_example_chart_6.c
new file mode 100644
index 00000000..463ab670
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_6.c
@@ -0,0 +1,87 @@
+#include "../../lv_examples.h"
+#if LV_USE_CHART && LV_BUILD_EXAMPLES
+
+static lv_obj_t * chart;
+static lv_chart_series_t * ser;
+static lv_chart_cursor_t * cursor;
+
+static void event_cb(lv_event_t * e)
+{
+ static int32_t last_id = -1;
+ lv_event_code_t code = lv_event_get_code(e);
+ lv_obj_t * obj = lv_event_get_target(e);
+
+ if(code == LV_EVENT_VALUE_CHANGED) {
+ last_id = lv_chart_get_pressed_point(obj);
+ if(last_id != LV_CHART_POINT_NONE) {
+ lv_chart_set_cursor_point(obj, cursor, NULL, last_id);
+ }
+ }
+ else if(code == LV_EVENT_DRAW_PART_END) {
+ lv_obj_draw_part_dsc_t * dsc = lv_event_get_draw_part_dsc(e);
+ if(!lv_obj_draw_part_check_type(dsc, &lv_chart_class, LV_CHART_DRAW_PART_CURSOR)) return;
+ if(dsc->p1 == NULL || dsc->p2 == NULL || dsc->p1->y != dsc->p2->y || last_id < 0) return;
+
+ lv_coord_t * data_array = lv_chart_get_y_array(chart, ser);
+ lv_coord_t v = data_array[last_id];
+ char buf[16];
+ lv_snprintf(buf, sizeof(buf), "%d", v);
+
+ lv_point_t size;
+ lv_txt_get_size(&size, buf, LV_FONT_DEFAULT, 0, 0, LV_COORD_MAX, LV_TEXT_FLAG_NONE);
+
+ lv_area_t a;
+ a.y2 = dsc->p1->y - 5;
+ a.y1 = a.y2 - size.y - 10;
+ a.x1 = dsc->p1->x + 10;
+ a.x2 = a.x1 + size.x + 10;
+
+ lv_draw_rect_dsc_t draw_rect_dsc;
+ lv_draw_rect_dsc_init(&draw_rect_dsc);
+ draw_rect_dsc.bg_color = lv_palette_main(LV_PALETTE_BLUE);
+ draw_rect_dsc.radius = 3;
+
+ lv_draw_rect(dsc->draw_ctx, &draw_rect_dsc, &a);
+
+ lv_draw_label_dsc_t draw_label_dsc;
+ lv_draw_label_dsc_init(&draw_label_dsc);
+ draw_label_dsc.color = lv_color_white();
+ a.x1 += 5;
+ a.x2 -= 5;
+ a.y1 += 5;
+ a.y2 -= 5;
+ lv_draw_label(dsc->draw_ctx, &draw_label_dsc, &a, buf, NULL);
+ }
+}
+
+/**
+ * Show cursor on the clicked point
+ */
+void lv_example_chart_6(void)
+{
+ chart = lv_chart_create(lv_scr_act());
+ lv_obj_set_size(chart, 200, 150);
+ lv_obj_align(chart, LV_ALIGN_CENTER, 0, -10);
+
+ lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_Y, 10, 5, 6, 5, true, 40);
+ lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_X, 10, 5, 10, 1, true, 30);
+
+ lv_obj_add_event_cb(chart, event_cb, LV_EVENT_ALL, NULL);
+ lv_obj_refresh_ext_draw_size(chart);
+
+ cursor = lv_chart_add_cursor(chart, lv_palette_main(LV_PALETTE_BLUE), LV_DIR_LEFT | LV_DIR_BOTTOM);
+
+ ser = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
+ uint32_t i;
+ for(i = 0; i < 10; i++) {
+ lv_chart_set_next_value(chart, ser, lv_rand(10, 90));
+ }
+
+ lv_chart_set_zoom_x(chart, 500);
+
+ lv_obj_t * label = lv_label_create(lv_scr_act());
+ lv_label_set_text(label, "Click on a point");
+ lv_obj_align_to(label, chart, LV_ALIGN_OUT_TOP_MID, 0, -5);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_6.py b/lib/lvgl/examples/widgets/chart/lv_example_chart_6.py
new file mode 100644
index 00000000..acc4e11c
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_6.py
@@ -0,0 +1,88 @@
+class ExampleChart_6():
+
+ def __init__(self):
+ self.last_id = -1
+ #
+ # Show cursor on the clicked point
+ #
+
+ chart = lv.chart(lv.scr_act())
+ chart.set_size(200, 150)
+ chart.align(lv.ALIGN.CENTER, 0, -10)
+
+ chart.set_axis_tick(lv.chart.AXIS.PRIMARY_Y, 10, 5, 6, 5, True, 40)
+ chart.set_axis_tick(lv.chart.AXIS.PRIMARY_X, 10, 5, 10, 1, True, 30)
+
+ chart.add_event_cb(self.event_cb, lv.EVENT.ALL, None)
+ chart.refresh_ext_draw_size()
+
+ self.cursor = chart.add_cursor(lv.palette_main(lv.PALETTE.BLUE), lv.DIR.LEFT | lv.DIR.BOTTOM)
+
+ self.ser = chart.add_series(lv.palette_main(lv.PALETTE.RED), lv.chart.AXIS.PRIMARY_Y)
+
+ self.ser_p = []
+ for i in range(10):
+ self.ser_p.append(lv.rand(10,90))
+ self.ser.y_points = self.ser_p
+
+ newser = chart.get_series_next(None)
+ # print("length of data points: ",len(newser.points))
+ chart.set_zoom_x(500)
+
+ label = lv.label(lv.scr_act())
+ label.set_text("Click on a point")
+ label.align_to(chart, lv.ALIGN.OUT_TOP_MID, 0, -5)
+
+
+ def event_cb(self,e):
+
+ code = e.get_code()
+ chart = e.get_target()
+
+ if code == lv.EVENT.VALUE_CHANGED:
+ # print("last_id: ",self.last_id)
+ self.last_id = chart.get_pressed_point()
+ if self.last_id != lv.CHART_POINT.NONE:
+ p = lv.point_t()
+ chart.get_point_pos_by_id(self.ser, self.last_id, p)
+ chart.set_cursor_point(self.cursor, None, self.last_id)
+
+ elif code == lv.EVENT.DRAW_PART_END:
+ # print("EVENT.DRAW_PART_END")
+ dsc = lv.obj_draw_part_dsc_t.__cast__(e.get_param())
+ # if dsc.p1 and dsc.p2:
+ # print("p1, p2", dsc.p1,dsc.p2)
+ # print("p1.y, p2.y", dsc.p1.y, dsc.p2.y)
+ # print("last_id: ",self.last_id)
+ if dsc.part == lv.PART.CURSOR and dsc.p1 and dsc.p2 and dsc.p1.y == dsc.p2.y and self.last_id >= 0:
+
+ v = self.ser_p[self.last_id]
+
+ # print("value: ",v)
+ value_txt = str(v)
+ size = lv.point_t()
+ lv.txt_get_size(size, value_txt, lv.font_default(), 0, 0, lv.COORD.MAX, lv.TEXT_FLAG.NONE)
+
+ a = lv.area_t()
+ a.y2 = dsc.p1.y - 5
+ a.y1 = a.y2 - size.y - 10
+ a.x1 = dsc.p1.x + 10
+ a.x2 = a.x1 + size.x + 10
+
+ draw_rect_dsc = lv.draw_rect_dsc_t()
+ draw_rect_dsc.init()
+ draw_rect_dsc.bg_color = lv.palette_main(lv.PALETTE.BLUE)
+ draw_rect_dsc.radius = 3
+
+ lv.draw_rect(a, dsc.clip_area, draw_rect_dsc)
+
+ draw_label_dsc = lv.draw_label_dsc_t()
+ draw_label_dsc.init()
+ draw_label_dsc.color = lv.color_white()
+ a.x1 += 5
+ a.x2 -= 5
+ a.y1 += 5
+ a.y2 -= 5
+ lv.draw_label(a, dsc.clip_area, draw_label_dsc, value_txt, None)
+
+example_chart_6 = ExampleChart_6()
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_7.c b/lib/lvgl/examples/widgets/chart/lv_example_chart_7.c
new file mode 100644
index 00000000..506f8875
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_7.c
@@ -0,0 +1,66 @@
+#include "../../lv_examples.h"
+#if LV_USE_CHART && LV_BUILD_EXAMPLES
+
+static void draw_event_cb(lv_event_t * e)
+{
+ lv_obj_draw_part_dsc_t * dsc = lv_event_get_draw_part_dsc(e);
+ if(dsc->part == LV_PART_ITEMS) {
+ lv_obj_t * obj = lv_event_get_target(e);
+ lv_chart_series_t * ser = lv_chart_get_series_next(obj, NULL);
+ uint32_t cnt = lv_chart_get_point_count(obj);
+ /*Make older value more transparent*/
+ dsc->rect_dsc->bg_opa = (LV_OPA_COVER * dsc->id) / (cnt - 1);
+
+ /*Make smaller values blue, higher values red*/
+ lv_coord_t * x_array = lv_chart_get_x_array(obj, ser);
+ lv_coord_t * y_array = lv_chart_get_y_array(obj, ser);
+ /*dsc->id is the tells drawing order, but we need the ID of the point being drawn.*/
+ uint32_t start_point = lv_chart_get_x_start_point(obj, ser);
+ uint32_t p_act = (start_point + dsc->id) % cnt; /*Consider start point to get the index of the array*/
+ lv_opa_t x_opa = (x_array[p_act] * LV_OPA_50) / 200;
+ lv_opa_t y_opa = (y_array[p_act] * LV_OPA_50) / 1000;
+
+ dsc->rect_dsc->bg_color = lv_color_mix(lv_palette_main(LV_PALETTE_RED),
+ lv_palette_main(LV_PALETTE_BLUE),
+ x_opa + y_opa);
+ }
+}
+
+static void add_data(lv_timer_t * timer)
+{
+ LV_UNUSED(timer);
+ lv_obj_t * chart = timer->user_data;
+ lv_chart_set_next_value2(chart, lv_chart_get_series_next(chart, NULL), lv_rand(0, 200), lv_rand(0, 1000));
+}
+
+/**
+ * A scatter chart
+ */
+void lv_example_chart_7(void)
+{
+ lv_obj_t * chart = lv_chart_create(lv_scr_act());
+ lv_obj_set_size(chart, 200, 150);
+ lv_obj_align(chart, LV_ALIGN_CENTER, 0, 0);
+ lv_obj_add_event_cb(chart, draw_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);
+ lv_obj_set_style_line_width(chart, 0, LV_PART_ITEMS); /*Remove the lines*/
+
+ lv_chart_set_type(chart, LV_CHART_TYPE_SCATTER);
+
+ lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_X, 5, 5, 5, 1, true, 30);
+ lv_chart_set_axis_tick(chart, LV_CHART_AXIS_PRIMARY_Y, 10, 5, 6, 5, true, 50);
+
+ lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_X, 0, 200);
+ lv_chart_set_range(chart, LV_CHART_AXIS_PRIMARY_Y, 0, 1000);
+
+ lv_chart_set_point_count(chart, 50);
+
+ lv_chart_series_t * ser = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
+ uint32_t i;
+ for(i = 0; i < 50; i++) {
+ lv_chart_set_next_value2(chart, ser, lv_rand(0, 200), lv_rand(0, 1000));
+ }
+
+ lv_timer_create(add_data, 100, chart);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_7.py b/lib/lvgl/examples/widgets/chart/lv_example_chart_7.py
new file mode 100644
index 00000000..23f17e14
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_7.py
@@ -0,0 +1,77 @@
+#!/opt/bin/lv_micropython -i
+import utime as time
+import lvgl as lv
+import display_driver
+
+def draw_event_cb(e):
+ dsc = e.get_draw_part_dsc()
+ if dsc.part == lv.PART.ITEMS:
+ obj = e.get_target()
+ ser = obj.get_series_next(None)
+ cnt = obj.get_point_count()
+ # print("cnt: ",cnt)
+ # Make older value more transparent
+ dsc.rect_dsc.bg_opa = (lv.OPA.COVER * dsc.id) // (cnt - 1)
+
+ # Make smaller values blue, higher values red
+ # x_array = chart.get_x_array(ser)
+ # y_array = chart.get_y_array(ser)
+ # dsc->id is the tells drawing order, but we need the ID of the point being drawn.
+ start_point = chart.get_x_start_point(ser)
+ # print("start point: ",start_point)
+ p_act = (start_point + dsc.id) % cnt # Consider start point to get the index of the array
+ # print("p_act", p_act)
+ x_opa = (x_array[p_act] * lv.OPA._50) // 200
+ y_opa = (y_array[p_act] * lv.OPA._50) // 1000
+
+ dsc.rect_dsc.bg_color = lv.palette_main(lv.PALETTE.RED).color_mix(
+ lv.palette_main(lv.PALETTE.BLUE),
+ x_opa + y_opa)
+
+def add_data(timer,chart):
+ # print("add_data")
+ x = lv.rand(0,200)
+ y = lv.rand(0,1000)
+ chart.set_next_value2(ser, x, y)
+ # chart.set_next_value2(chart.gx, y)
+ x_array.pop(0)
+ x_array.append(x)
+ y_array.pop(0)
+ y_array.append(y)
+
+#
+# A scatter chart
+#
+
+chart = lv.chart(lv.scr_act())
+chart.set_size(200, 150)
+chart.align(lv.ALIGN.CENTER, 0, 0)
+chart.add_event_cb(draw_event_cb, lv.EVENT.DRAW_PART_BEGIN, None)
+chart.set_style_line_width(0, lv.PART.ITEMS) # Remove the lines
+
+chart.set_type(lv.chart.TYPE.SCATTER)
+
+chart.set_axis_tick(lv.chart.AXIS.PRIMARY_X, 5, 5, 5, 1, True, 30)
+chart.set_axis_tick(lv.chart.AXIS.PRIMARY_Y, 10, 5, 6, 5, True, 50)
+
+chart.set_range(lv.chart.AXIS.PRIMARY_X, 0, 200)
+chart.set_range(lv.chart.AXIS.PRIMARY_Y, 0, 1000)
+
+chart.set_point_count(50)
+
+ser = chart.add_series(lv.palette_main(lv.PALETTE.RED), lv.chart.AXIS.PRIMARY_Y)
+
+x_array = []
+y_array = []
+for i in range(50):
+ x_array.append(lv.rand(0, 200))
+ y_array.append(lv.rand(0, 1000))
+
+ser.x_points = x_array
+ser.y_points = y_array
+
+# Create an `lv_timer` to update the chart.
+
+timer = lv.timer_create_basic()
+timer.set_period(100)
+timer.set_cb(lambda src: add_data(timer,chart))
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_8.c b/lib/lvgl/examples/widgets/chart/lv_example_chart_8.c
new file mode 100644
index 00000000..ca2c8f8c
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_8.c
@@ -0,0 +1,131 @@
+#include "../../lv_examples.h"
+#if LV_USE_CHART && LV_DRAW_COMPLEX && LV_BUILD_EXAMPLES
+
+/* A struct is used to keep track of the series list because later we need to draw to the series in the reverse order to which they were initialised. */
+typedef struct {
+ lv_obj_t * obj;
+ lv_chart_series_t * series_list[3];
+} stacked_area_chart_t;
+
+static stacked_area_chart_t stacked_area_chart;
+
+/**
+ * Callback which draws the blocks of colour under the lines
+ **/
+static void draw_event_cb(lv_event_t * e)
+{
+ lv_obj_t * obj = lv_event_get_target(e);
+
+ /*Add the faded area before the lines are drawn*/
+ lv_obj_draw_part_dsc_t * dsc = lv_event_get_draw_part_dsc(e);
+ if(dsc->part == LV_PART_ITEMS) {
+ if(!dsc->p1 || !dsc->p2)
+ return;
+
+ /*Add a line mask that keeps the area below the line*/
+ lv_draw_mask_line_param_t line_mask_param;
+ lv_draw_mask_line_points_init(&line_mask_param, dsc->p1->x, dsc->p1->y, dsc->p2->x, dsc->p2->y,
+ LV_DRAW_MASK_LINE_SIDE_BOTTOM);
+ int16_t line_mask_id = lv_draw_mask_add(&line_mask_param, NULL);
+
+ /*Draw a rectangle that will be affected by the mask*/
+ lv_draw_rect_dsc_t draw_rect_dsc;
+ lv_draw_rect_dsc_init(&draw_rect_dsc);
+ draw_rect_dsc.bg_opa = LV_OPA_COVER;
+ draw_rect_dsc.bg_color = dsc->line_dsc->color;
+
+ lv_area_t a;
+ a.x1 = dsc->p1->x;
+ a.x2 = dsc->p2->x;
+ a.y1 = LV_MIN(dsc->p1->y, dsc->p2->y);
+ a.y2 = obj->coords.y2 -
+ 13; /* -13 cuts off where the rectangle draws over the chart margin. Without this an area of 0 doesn't look like 0 */
+ lv_draw_rect(dsc->draw_ctx, &draw_rect_dsc, &a);
+
+ /*Remove the mask*/
+ lv_draw_mask_free_param(&line_mask_param);
+ lv_draw_mask_remove_id(line_mask_id);
+ }
+}
+
+/**
+ * Helper function to round a fixed point number
+ **/
+static int32_t round_fixed_point(int32_t n, int8_t shift)
+{
+ /* Create a bitmask to isolates the decimal part of the fixed point number */
+ int32_t mask = 1;
+ for(int32_t bit_pos = 0; bit_pos < shift; bit_pos++) {
+ mask = (mask << 1) + 1;
+ }
+
+ int32_t decimal_part = n & mask;
+
+ /* Get 0.5 as fixed point */
+ int32_t rounding_boundary = 1 << (shift - 1);
+
+ /* Return either the integer part of n or the integer part + 1 */
+ return (decimal_part < rounding_boundary) ? (n & ~mask) : ((n >> shift) + 1) << shift;
+}
+
+/**
+ * Stacked area chart
+ */
+void lv_example_chart_8(void)
+{
+ /*Create a stacked_area_chart.obj*/
+ stacked_area_chart.obj = lv_chart_create(lv_scr_act());
+ lv_obj_set_size(stacked_area_chart.obj, 200, 150);
+ lv_obj_center(stacked_area_chart.obj);
+ lv_chart_set_type(stacked_area_chart.obj, LV_CHART_TYPE_LINE);
+ lv_chart_set_div_line_count(stacked_area_chart.obj, 5, 7);
+ lv_obj_add_event_cb(stacked_area_chart.obj, draw_event_cb, LV_EVENT_DRAW_PART_BEGIN, NULL);
+
+ /* Set range to 0 to 100 for percentages. Draw ticks */
+ lv_chart_set_range(stacked_area_chart.obj, LV_CHART_AXIS_PRIMARY_Y, 0, 100);
+ lv_chart_set_axis_tick(stacked_area_chart.obj, LV_CHART_AXIS_PRIMARY_Y, 3, 0, 5, 1, true, 30);
+
+ /*Set point size to 0 so the lines are smooth */
+ lv_obj_set_style_size(stacked_area_chart.obj, 0, LV_PART_INDICATOR);
+
+ /*Add some data series*/
+ stacked_area_chart.series_list[0] = lv_chart_add_series(stacked_area_chart.obj, lv_palette_main(LV_PALETTE_RED),
+ LV_CHART_AXIS_PRIMARY_Y);
+ stacked_area_chart.series_list[1] = lv_chart_add_series(stacked_area_chart.obj, lv_palette_main(LV_PALETTE_BLUE),
+ LV_CHART_AXIS_PRIMARY_Y);
+ stacked_area_chart.series_list[2] = lv_chart_add_series(stacked_area_chart.obj, lv_palette_main(LV_PALETTE_GREEN),
+ LV_CHART_AXIS_PRIMARY_Y);
+
+ for(int point = 0; point < 10; point++) {
+ /* Make some random data */
+ uint32_t vals[3] = {lv_rand(10, 20), lv_rand(20, 30), lv_rand(20, 30)};
+
+ int8_t fixed_point_shift = 5;
+ uint32_t total = vals[0] + vals[1] + vals[2];
+ uint32_t draw_heights[3];
+ uint32_t int_sum = 0;
+ uint32_t decimal_sum = 0;
+
+ /* Fixed point cascade rounding ensures percentages add to 100 */
+ for(int32_t series_index = 0; series_index < 3; series_index++) {
+ decimal_sum += (((vals[series_index] * 100) << fixed_point_shift) / total);
+ int_sum += (vals[series_index] * 100) / total;
+
+ int32_t modifier = (round_fixed_point(decimal_sum, fixed_point_shift) >> fixed_point_shift) - int_sum;
+
+ /* The draw heights are equal to the percentage of the total each value is + the cumulative sum of the previous percentages.
+ The accumulation is how the values get "stacked" */
+ draw_heights[series_index] = int_sum + modifier;
+
+ /* Draw to the series in the reverse order to which they were initialised.
+ Without this the higher values will draw on top of the lower ones.
+ This is because the Z-height of a series matches the order it was initialised */
+ lv_chart_set_next_value(stacked_area_chart.obj, stacked_area_chart.series_list[3 - series_index - 1],
+ draw_heights[series_index]);
+ }
+ }
+
+ lv_chart_refresh(stacked_area_chart.obj);
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_8.py b/lib/lvgl/examples/widgets/chart/lv_example_chart_8.py
new file mode 100644
index 00000000..20996b3a
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_8.py
@@ -0,0 +1,124 @@
+import display_driver
+import lvgl as lv
+
+# A class is used to keep track of the series list because later we
+# need to draw to the series in the reverse order to which they were initialised.
+class StackedAreaChart:
+ def __init__(self):
+ self.obj = None
+ self.series_list = [None, None, None]
+
+stacked_area_chart = StackedAreaChart()
+
+#
+# Callback which draws the blocks of colour under the lines
+#
+def draw_event_cb(e):
+
+ obj = e.get_target()
+ cont_a = lv.area_t()
+ obj.get_coords(cont_a)
+
+ #Add the faded area before the lines are drawn
+ dsc = e.get_draw_part_dsc()
+ if dsc.part == lv.PART.ITEMS:
+ if not dsc.p1 or not dsc.p2:
+ return
+
+ # Add a line mask that keeps the area below the line
+ line_mask_param = lv.draw_mask_line_param_t()
+ line_mask_param.points_init(dsc.p1.x, dsc.p1.y, dsc.p2.x, dsc.p2.y, lv.DRAW_MASK_LINE_SIDE.BOTTOM)
+ line_mask_id = lv.draw_mask_add(line_mask_param, None)
+
+ #Draw a rectangle that will be affected by the mask
+ draw_rect_dsc = lv.draw_rect_dsc_t()
+ draw_rect_dsc.init()
+ draw_rect_dsc.bg_opa = lv.OPA.COVER
+ draw_rect_dsc.bg_color = dsc.line_dsc.color
+
+ a = lv.area_t()
+ a.x1 = dsc.p1.x
+ a.x2 = dsc.p2.x
+ a.y1 = min(dsc.p1.y, dsc.p2.y)
+ a.y2 = cont_a.y2 - 13 # -13 cuts off where the rectangle draws over the chart margin. Without this an area of 0 doesn't look like 0
+ dsc.draw_ctx.rect(draw_rect_dsc, a)
+
+ # Remove the mask
+ lv.draw_mask_free_param(line_mask_param)
+ lv.draw_mask_remove_id(line_mask_id)
+
+
+#
+# Helper function to round a fixed point number
+#
+def round_fixed_point(n, shift):
+ # Create a bitmask to isolates the decimal part of the fixed point number
+ mask = 1
+ for bit_pos in range(shift):
+ mask = (mask << 1) + 1
+
+ decimal_part = n & mask
+
+ # Get 0.5 as fixed point
+ rounding_boundary = 1 << (shift - 1)
+
+ # Return either the integer part of n or the integer part + 1
+ if decimal_part < rounding_boundary:
+ return (n & ~mask)
+ return ((n >> shift) + 1) << shift
+
+
+#
+# Stacked area chart
+#
+def lv_example_chart_8():
+
+ #Create a stacked_area_chart.obj
+ stacked_area_chart.obj = lv.chart(lv.scr_act())
+ stacked_area_chart.obj.set_size(200, 150)
+ stacked_area_chart.obj.center()
+ stacked_area_chart.obj.set_type( lv.chart.TYPE.LINE)
+ stacked_area_chart.obj.set_div_line_count(5, 7)
+ stacked_area_chart.obj.add_event_cb( draw_event_cb, lv.EVENT.DRAW_PART_BEGIN, None)
+
+ # Set range to 0 to 100 for percentages. Draw ticks
+ stacked_area_chart.obj.set_range(lv.chart.AXIS.PRIMARY_Y,0,100)
+ stacked_area_chart.obj.set_axis_tick(lv.chart.AXIS.PRIMARY_Y, 3, 0, 5, 1, True, 30)
+
+ #Set point size to 0 so the lines are smooth
+ stacked_area_chart.obj.set_style_size(0, lv.PART.INDICATOR)
+
+ # Add some data series
+ stacked_area_chart.series_list[0] = stacked_area_chart.obj.add_series(lv.palette_main(lv.PALETTE.RED), lv.chart.AXIS.PRIMARY_Y)
+ stacked_area_chart.series_list[1] = stacked_area_chart.obj.add_series(lv.palette_main(lv.PALETTE.BLUE), lv.chart.AXIS.PRIMARY_Y)
+ stacked_area_chart.series_list[2] = stacked_area_chart.obj.add_series(lv.palette_main(lv.PALETTE.GREEN), lv.chart.AXIS.PRIMARY_Y)
+
+ for point in range(10):
+ # Make some random data
+ vals = [lv.rand(10, 20), lv.rand(20, 30), lv.rand(20, 30)]
+
+ fixed_point_shift = 5
+ total = vals[0] + vals[1] + vals[2]
+ draw_heights = [0, 0, 0]
+ int_sum = 0
+ decimal_sum = 0
+
+ # Fixed point cascade rounding ensures percentages add to 100
+ for series_index in range(3):
+ decimal_sum += int(((vals[series_index] * 100) << fixed_point_shift) // total)
+ int_sum += int((vals[series_index] * 100) / total)
+
+ modifier = (round_fixed_point(decimal_sum, fixed_point_shift) >> fixed_point_shift) - int_sum
+
+ # The draw heights are equal to the percentage of the total each value is + the cumulative sum of the previous percentages.
+ # The accumulation is how the values get "stacked"
+ draw_heights[series_index] = int(int_sum + modifier)
+
+ # Draw to the series in the reverse order to which they were initialised.
+ # Without this the higher values will draw on top of the lower ones.
+ # This is because the Z-height of a series matches the order it was initialised
+ stacked_area_chart.obj.set_next_value( stacked_area_chart.series_list[3 - series_index - 1], draw_heights[series_index])
+
+ stacked_area_chart.obj.refresh()
+
+lv_example_chart_8()
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_9.c b/lib/lvgl/examples/widgets/chart/lv_example_chart_9.c
new file mode 100644
index 00000000..c94b564f
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_9.c
@@ -0,0 +1,46 @@
+#include "../../lv_examples.h"
+#if LV_USE_CHART && LV_DRAW_COMPLEX && LV_BUILD_EXAMPLES
+
+
+static void add_data(lv_timer_t * t)
+{
+ lv_obj_t * chart = t->user_data;
+ lv_chart_series_t * ser = lv_chart_get_series_next(chart, NULL);
+
+ lv_chart_set_next_value(chart, ser, lv_rand(10, 90));
+
+ uint16_t p = lv_chart_get_point_count(chart);
+ uint16_t s = lv_chart_get_x_start_point(chart, ser);
+ lv_coord_t * a = lv_chart_get_y_array(chart, ser);
+
+ a[(s + 1) % p] = LV_CHART_POINT_NONE;
+ a[(s + 2) % p] = LV_CHART_POINT_NONE;
+ a[(s + 2) % p] = LV_CHART_POINT_NONE;
+
+ lv_chart_refresh(chart);
+}
+
+/**
+ * Circular line chart with gap
+ */
+void lv_example_chart_9(void)
+{
+ /*Create a stacked_area_chart.obj*/
+ lv_obj_t * chart = lv_chart_create(lv_scr_act());
+ lv_chart_set_update_mode(chart, LV_CHART_UPDATE_MODE_CIRCULAR);
+ lv_obj_set_size(chart, 200, 150);
+ lv_obj_center(chart);
+
+ lv_chart_set_point_count(chart, 30);
+ lv_chart_series_t * ser = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
+ /*Prefill with data*/
+ uint32_t i;
+ for(i = 0; i < 30; i++) {
+ lv_chart_set_next_value(chart, ser, lv_rand(10, 90));
+ }
+
+ lv_timer_create(add_data, 300, chart);
+
+}
+
+#endif
diff --git a/lib/lvgl/examples/widgets/chart/lv_example_chart_9.py b/lib/lvgl/examples/widgets/chart/lv_example_chart_9.py
new file mode 100644
index 00000000..37b16b39
--- /dev/null
+++ b/lib/lvgl/examples/widgets/chart/lv_example_chart_9.py
@@ -0,0 +1,31 @@
+import display_driver
+import lvgl as lv
+
+def add_data(t):
+ chart.set_next_value(ser, lv.rand(10, 90))
+
+ p = chart.get_point_count()
+ s = chart.get_x_start_point(ser)
+ a = chart.get_y_array(ser)
+
+ a[(s + 1) % p] = lv.CHART_POINT.NONE
+ a[(s + 2) % p] = lv.CHART_POINT.NONE
+ a[(s + 3) % p] = lv.CHART_POINT.NONE
+ chart.refresh()
+
+#
+# Circular line chart with gap
+#
+chart = lv.chart(lv.scr_act())
+
+chart.set_update_mode(lv.chart.UPDATE_MODE.CIRCULAR)
+chart.set_size(200, 150)
+chart.center()
+
+chart.set_point_count(30)
+ser = chart.add_series(lv.palette_main(lv.PALETTE.RED), lv.chart.AXIS.PRIMARY_Y)
+#Prefill with data
+for i in range(0, 30):
+ chart.set_next_value(ser, lv.rand(10, 90))
+
+lv.timer_create(add_data, 200, None)