diff --git a/src/lib/aqdiagram/0BUILD b/src/lib/aqdiagram/0BUILD
index b96f728..7e1d857 100644
--- a/src/lib/aqdiagram/0BUILD
+++ b/src/lib/aqdiagram/0BUILD
@@ -58,6 +58,7 @@
aqdg_graph
aqdg_draw
aqdg_place
+ aqdg_data
@@ -73,6 +74,7 @@
placement
draw
graph
+ data
diff --git a/src/lib/aqdiagram/data/0BUILD b/src/lib/aqdiagram/data/0BUILD
new file mode 100644
index 0000000..232d02a
--- /dev/null
+++ b/src/lib/aqdiagram/data/0BUILD
@@ -0,0 +1,97 @@
+
+
+
+
+
+
+
+
+
+ $(gwenhywfar_cflags)
+ $(cairo_cflags)
+ -I$(topsrcdir)/src/lib
+ -I$(topbuilddir)/src/lib
+ -I$(topbuilddir)
+ -I$(topsrcdir)
+ -I$(srcdir)
+
+
+
+ --include=$(builddir)
+ --include=$(srcdir)
+ --include=$(builddir)/../types
+ --include=$(topsrcdir)/src/lib/typemaker2/c
+ --include=$(topbuilddir)/src/lib/typemaker2/c
+
+
+
+ $(visibility_cflags)
+
+
+
+ --api=AQDG_API
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ $(local/built_headers_pub)
+
+
+
+ $(local/built_headers_priv)
+
+
+
+
+ average.h
+ accumulate.h
+ floatingavg.h
+ date.h
+ diff.h
+
+
+
+
+
+
+
+ $(local/typefiles)
+ average.c
+ accumulate.c
+ floatingavg.c
+ date.c
+ diff.c
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/lib/aqdiagram/data/accumulate.c b/src/lib/aqdiagram/data/accumulate.c
new file mode 100644
index 0000000..f9b83f3
--- /dev/null
+++ b/src/lib/aqdiagram/data/accumulate.c
@@ -0,0 +1,42 @@
+/****************************************************************************
+ * This file is part of the project AqDiagram.
+ * AqDiagram (c) by 2025 Martin Preuss, all rights reserved.
+ *
+ * The license for this file can be found in the file COPYING which you
+ * should have received along with this file.
+ ****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#include "./accumulate.h"
+
+
+
+AQDG_GRAPH_DATAPAIR_LIST *AQDG_Data_Accumulate(const AQDG_GRAPH_DATAPAIR_LIST *dpList)
+{
+ if (dpList && AQDG_Graph_DataPair_List_GetCount(dpList)) {
+ AQDG_GRAPH_DATAPAIR_LIST *newList;
+ const AQDG_GRAPH_DATAPAIR *dp;
+ double v=0.0;
+
+ newList=AQDG_Graph_DataPair_List_new();
+ dp=AQDG_Graph_DataPair_List_First(dpList);
+ while(dp) {
+ AQDG_GRAPH_DATAPAIR *newDp;
+
+ v+=AQDG_Graph_DataPair_GetValueY(dp);
+ newDp=AQDG_Graph_DataPair_dup(dp);
+ AQDG_Graph_DataPair_SetValueY(newDp, v);
+ AQDG_Graph_DataPair_List_Add(newDp, newList);
+
+ dp=AQDG_Graph_DataPair_List_Next(dp);
+ }
+ return newList;
+ }
+ return NULL;
+}
+
+
+
diff --git a/src/lib/aqdiagram/data/accumulate.h b/src/lib/aqdiagram/data/accumulate.h
new file mode 100644
index 0000000..30817c8
--- /dev/null
+++ b/src/lib/aqdiagram/data/accumulate.h
@@ -0,0 +1,22 @@
+/****************************************************************************
+ * This file is part of the project AqDiagram.
+ * AqDiagram (c) by 2025 Martin Preuss, all rights reserved.
+ *
+ * The license for this file can be found in the file COPYING which you
+ * should have received along with this file.
+ ****************************************************************************/
+
+#ifndef AQDG_DATA_ACCUMULATE_H
+#define AQDG_DATA_ACCUMULATE_H
+
+#include
+
+
+
+AQDG_API AQDG_GRAPH_DATAPAIR_LIST *AQDG_Data_Accumulate(const AQDG_GRAPH_DATAPAIR_LIST *dpList);
+
+
+
+
+#endif
+
diff --git a/src/lib/aqdiagram/data/average.c b/src/lib/aqdiagram/data/average.c
new file mode 100644
index 0000000..2931ac1
--- /dev/null
+++ b/src/lib/aqdiagram/data/average.c
@@ -0,0 +1,36 @@
+/****************************************************************************
+ * This file is part of the project AqDiagram.
+ * AqDiagram (c) by 2025 Martin Preuss, all rights reserved.
+ *
+ * The license for this file can be found in the file COPYING which you
+ * should have received along with this file.
+ ****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#include "./average.h"
+
+
+
+double AQDG_Data_Average(const AQDG_GRAPH_DATAPAIR_LIST *dpList)
+{
+ if (dpList && AQDG_Graph_DataPair_List_GetCount(dpList)) {
+ const AQDG_GRAPH_DATAPAIR *dp;
+ double v=0.0;
+
+ dp=AQDG_Graph_DataPair_List_First(dpList);
+ v=0.0;
+ while(dp) {
+ v+=AQDG_Graph_DataPair_GetValueY(dp);
+ dp=AQDG_Graph_DataPair_List_Next(dp);
+ }
+ v/=(double) AQDG_Graph_DataPair_List_GetCount(dpList);
+ return v;
+ }
+ return 0.0;
+}
+
+
+
diff --git a/src/lib/aqdiagram/data/average.h b/src/lib/aqdiagram/data/average.h
new file mode 100644
index 0000000..3f9e2a2
--- /dev/null
+++ b/src/lib/aqdiagram/data/average.h
@@ -0,0 +1,22 @@
+/****************************************************************************
+ * This file is part of the project AqDiagram.
+ * AqDiagram (c) by 2025 Martin Preuss, all rights reserved.
+ *
+ * The license for this file can be found in the file COPYING which you
+ * should have received along with this file.
+ ****************************************************************************/
+
+#ifndef AQDG_DATA_AVERAGE_H
+#define AQDG_DATA_AVERAGE_H
+
+#include
+
+
+
+AQDG_API double AQDG_Data_Average(const AQDG_GRAPH_DATAPAIR_LIST *dpList);
+
+
+
+
+#endif
+
diff --git a/src/lib/aqdiagram/data/date.c b/src/lib/aqdiagram/data/date.c
new file mode 100644
index 0000000..8684ed6
--- /dev/null
+++ b/src/lib/aqdiagram/data/date.c
@@ -0,0 +1,138 @@
+/****************************************************************************
+ * This file is part of the project AqDiagram.
+ * AqDiagram (c) by 2025 Martin Preuss, all rights reserved.
+ *
+ * The license for this file can be found in the file COPYING which you
+ * should have received along with this file.
+ ****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#include "./date.h"
+
+#include
+#include
+
+
+
+AQDG_GRAPH_DATAPAIR_LIST *AQDG_Data_DaySums(const AQDG_GRAPH_DATAPAIR_LIST *dpList)
+{
+ if (dpList && AQDG_Graph_DataPair_List_GetCount(dpList)) {
+ AQDG_GRAPH_DATAPAIR_LIST *newList;
+ const AQDG_GRAPH_DATAPAIR *dp;
+ GWEN_DATE *lastDate=NULL;
+ AQDG_GRAPH_DATAPAIR *newDp=NULL;
+
+ newList=AQDG_Graph_DataPair_List_new();
+ dp=AQDG_Graph_DataPair_List_First(dpList);
+ while(dp) {
+ double v;
+
+ v=AQDG_Graph_DataPair_GetValueX(dp);
+ if (lastDate==NULL) {
+ /* first value */
+ lastDate=GWEN_Date_fromLocalTime(AQDG_Graph_DataPair_GetValueX(dp));
+ newDp=AQDG_Graph_DataPair_new();
+ AQDG_Graph_DataPair_SetValueX(newDp, GWEN_Date_toLocalTime(lastDate));
+ AQDG_Graph_DataPair_SetValueY(newDp, AQDG_Graph_DataPair_GetValueY(dp));
+ AQDG_Graph_DataPair_List_Add(newDp, newList);
+ }
+ else {
+ GWEN_DATE *newDate;
+
+ newDate=GWEN_Date_fromLocalTime(AQDG_Graph_DataPair_GetValueX(dp));
+ if (GWEN_Date_Compare(newDate, lastDate)!=0) {
+ /* new date */
+ GWEN_Date_free(lastDate);
+ lastDate=newDate;
+ newDp=AQDG_Graph_DataPair_new();
+ AQDG_Graph_DataPair_SetValueX(newDp, GWEN_Date_toLocalTime(lastDate));
+ AQDG_Graph_DataPair_SetValueY(newDp, AQDG_Graph_DataPair_GetValueY(dp));
+ AQDG_Graph_DataPair_List_Add(newDp, newList);
+ }
+ else {
+ double v2;
+
+ /* add to existing date value */
+ v2=AQDG_Graph_DataPair_GetValueY(newDp);
+ v2+=v;
+ AQDG_Graph_DataPair_SetValueY(newDp, v2);
+ GWEN_Date_free(newDate);
+ }
+ }
+ dp=AQDG_Graph_DataPair_List_Next(dp);
+ }
+ GWEN_Date_free(lastDate);
+ return newList;
+ }
+ return NULL;
+}
+
+
+
+AQDG_GRAPH_DATAPAIR_LIST *AQDG_Data_MonthSums(const AQDG_GRAPH_DATAPAIR_LIST *dpList)
+{
+ if (dpList && AQDG_Graph_DataPair_List_GetCount(dpList)) {
+ AQDG_GRAPH_DATAPAIR_LIST *newList;
+ const AQDG_GRAPH_DATAPAIR *dp;
+ GWEN_DATE *lastDate=NULL;
+ AQDG_GRAPH_DATAPAIR *newDp=NULL;
+
+ newList=AQDG_Graph_DataPair_List_new();
+ dp=AQDG_Graph_DataPair_List_First(dpList);
+ while(dp) {
+ double v;
+
+ v=AQDG_Graph_DataPair_GetValueY(dp);
+ if (lastDate==NULL) {
+ GWEN_DATE *dt;
+
+ /* first value */
+ dt=GWEN_Date_fromLocalTime(AQDG_Graph_DataPair_GetValueX(dp));
+ lastDate=GWEN_Date_GetThisMonthStart(dt);
+ GWEN_Date_free(dt);
+ newDp=AQDG_Graph_DataPair_new();
+ AQDG_Graph_DataPair_SetValueX(newDp, GWEN_Date_toLocalTime(lastDate));
+ AQDG_Graph_DataPair_SetValueY(newDp, AQDG_Graph_DataPair_GetValueY(dp));
+ AQDG_Graph_DataPair_List_Add(newDp, newList);
+ DBG_ERROR(NULL, "Added first value: %.2f", AQDG_Graph_DataPair_GetValueY(dp));
+ }
+ else {
+ GWEN_DATE *dt;
+ GWEN_DATE *newDate;
+
+ dt=GWEN_Date_fromLocalTime(AQDG_Graph_DataPair_GetValueX(dp));
+ newDate=GWEN_Date_GetThisMonthStart(dt);
+ GWEN_Date_free(dt);
+ if (GWEN_Date_Compare(newDate, lastDate)!=0) {
+ /* new date */
+ GWEN_Date_free(lastDate);
+ lastDate=newDate;
+ newDp=AQDG_Graph_DataPair_new();
+ AQDG_Graph_DataPair_SetValueX(newDp, GWEN_Date_toLocalTime(lastDate));
+ AQDG_Graph_DataPair_SetValueY(newDp, AQDG_Graph_DataPair_GetValueY(dp));
+ AQDG_Graph_DataPair_List_Add(newDp, newList);
+ DBG_ERROR(NULL, "Added value: %.2f", AQDG_Graph_DataPair_GetValueY(dp));
+ }
+ else {
+ double v2;
+
+ /* add to existing date value */
+ v2=AQDG_Graph_DataPair_GetValueY(newDp);
+ AQDG_Graph_DataPair_SetValueY(newDp, v2+v);
+ DBG_ERROR(NULL, "Added %.2f to existing value: %.2f", v, v2);
+ GWEN_Date_free(newDate);
+ }
+ }
+ dp=AQDG_Graph_DataPair_List_Next(dp);
+ }
+ GWEN_Date_free(lastDate);
+ return newList;
+ }
+ return NULL;
+}
+
+
+
diff --git a/src/lib/aqdiagram/data/date.h b/src/lib/aqdiagram/data/date.h
new file mode 100644
index 0000000..5a66d17
--- /dev/null
+++ b/src/lib/aqdiagram/data/date.h
@@ -0,0 +1,23 @@
+/****************************************************************************
+ * This file is part of the project AqDiagram.
+ * AqDiagram (c) by 2025 Martin Preuss, all rights reserved.
+ *
+ * The license for this file can be found in the file COPYING which you
+ * should have received along with this file.
+ ****************************************************************************/
+
+#ifndef AQDG_DATA_DATE_H
+#define AQDG_DATA_DATE_H
+
+#include
+
+
+
+AQDG_API AQDG_GRAPH_DATAPAIR_LIST *AQDG_Data_DaySums(const AQDG_GRAPH_DATAPAIR_LIST *dpList);
+AQDG_API AQDG_GRAPH_DATAPAIR_LIST *AQDG_Data_MonthSums(const AQDG_GRAPH_DATAPAIR_LIST *dpList);
+
+
+
+
+#endif
+
diff --git a/src/lib/aqdiagram/data/diff.c b/src/lib/aqdiagram/data/diff.c
new file mode 100644
index 0000000..99f158a
--- /dev/null
+++ b/src/lib/aqdiagram/data/diff.c
@@ -0,0 +1,86 @@
+/****************************************************************************
+ * This file is part of the project AqDiagram.
+ * AqDiagram (c) by 2025 Martin Preuss, all rights reserved.
+ *
+ * The license for this file can be found in the file COPYING which you
+ * should have received along with this file.
+ ****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#include "./average.h"
+
+
+
+double AQDG_Data_GetAbsMinDiffX(const AQDG_GRAPH_DATAPAIR_LIST *dpList)
+{
+ if (dpList && AQDG_Graph_DataPair_List_GetCount(dpList)) {
+ const AQDG_GRAPH_DATAPAIR *dp;
+ double minDist=0.0;
+ double lastValue=0.0;
+ int cnt=0;
+
+ dp=AQDG_Graph_DataPair_List_First(dpList);
+ while(dp) {
+ double d;
+
+ d=AQDG_Graph_DataPair_GetValueX(dp);
+ if (cnt) {
+ double dist;
+
+ dist=abs(d-lastValue);
+ if (cnt>1) {
+ if (dist1) {
+ if (dist
+
+
+
+AQDG_API double AQDG_Data_GetAbsMinDiffX(const AQDG_GRAPH_DATAPAIR_LIST *dpList);
+
+
+
+
+
+#endif
+
diff --git a/src/lib/aqdiagram/data/floatingavg.c b/src/lib/aqdiagram/data/floatingavg.c
new file mode 100644
index 0000000..8cefae4
--- /dev/null
+++ b/src/lib/aqdiagram/data/floatingavg.c
@@ -0,0 +1,75 @@
+/****************************************************************************
+ * This file is part of the project AqDiagram.
+ * AqDiagram (c) by 2025 Martin Preuss, all rights reserved.
+ *
+ * The license for this file can be found in the file COPYING which you
+ * should have received along with this file.
+ ****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#include "./floatingavg.h"
+
+
+
+AQDG_GRAPH_DATAPAIR_LIST *AQDG_Data_FloatingAverage(const AQDG_GRAPH_DATAPAIR_LIST *dpList, int num)
+{
+ if (dpList && AQDG_Graph_DataPair_List_GetCount(dpList)) {
+ AQDG_GRAPH_DATAPAIR_LIST *newList;
+ const AQDG_GRAPH_DATAPAIR *dp;
+ double lastValues[num];
+ int cnt=0;
+ int idx=0;
+
+ newList=AQDG_Graph_DataPair_List_new();
+ dp=AQDG_Graph_DataPair_List_First(dpList);
+ while(dp) {
+ AQDG_GRAPH_DATAPAIR *newDp;
+ double v;
+ int i;
+
+ v=AQDG_Graph_DataPair_GetValueY(dp);
+ if (idx>=num)
+ idx=0;
+ lastValues[idx]=v;
+ idx++;
+ cnt++;
+
+ if (cnt
+
+
+
+AQDG_API AQDG_GRAPH_DATAPAIR_LIST *AQDG_Data_FloatingAverage(const AQDG_GRAPH_DATAPAIR_LIST *dpList, int num);
+
+
+
+
+
+#endif
+
diff --git a/src/lib/aqdiagram/graph/axis.t2d b/src/lib/aqdiagram/graph/axis.t2d
index 5d84139..833ef6d 100644
--- a/src/lib/aqdiagram/graph/axis.t2d
+++ b/src/lib/aqdiagram/graph/axis.t2d
@@ -22,6 +22,7 @@
+
@@ -46,6 +47,7 @@
if (st->tickList==NULL) \n
st->tickList=AQDG_Graph_Tick_List_new(); \n
AQDG_Graph_Tick_List_Add(tick, st->tickList); \n
+ DBG_ERROR(NULL, "Added tick: %s (%.2f) [%d]", label, v, lvl);
} \n
@@ -198,39 +200,36 @@
double maxValue; \n
double endTime; \n
GWEN_BUFFER *dbuf; \n
- GWEN_TIMESTAMP *ts; \n
+ GWEN_DATE *dt; \n
\n
maxValue=st->maxValue; \n
- ts=GWEN_Timestamp_fromLocalTime(maxValue); \n
- GWEN_Timestamp_SetTime(ts, 0, 0, 0); \n
- GWEN_Timestamp_AddSeconds(ts, 24*60*60); \n
- endTime=GWEN_Timestamp_toTimeT(ts); \n
- GWEN_Timestamp_free(ts); \n
+ dt=GWEN_Date_fromLocalTime(maxValue); \n
+ endTime=GWEN_Date_toLocalTime(dt); \n
+ GWEN_Date_free(dt); \n
\n
minValue=st->minValue; \n
- ts=GWEN_Timestamp_fromLocalTime(minValue); \n
- GWEN_Timestamp_SetTime(ts, 0, 0, 0); \n
+ dt=GWEN_Date_fromLocalTime(minValue); \n
\n
dbuf=GWEN_Buffer_new(0, 256, 0, 1); \n
while(1) { \n
double v; \n
\n
- v=GWEN_Timestamp_toTimeT(ts); \n
+ v=GWEN_Date_toLocalTime(dt); \n
if (v>=minValue && v<endTime) { \n
GWEN_Buffer_AppendArgs(dbuf, \n
"%04d/%02d/%02d", \n
- GWEN_Timestamp_GetYear(ts), \n
- GWEN_Timestamp_GetMonth(ts), \n
- GWEN_Timestamp_GetDay(ts)); \n
+ GWEN_Date_GetYear(dt), \n
+ GWEN_Date_GetMonth(dt), \n
+ GWEN_Date_GetDay(dt)); \n
$(struct_prefix)_AddNewTick(st, GWEN_Buffer_GetStart(dbuf), v, lvl, 0); \n
GWEN_Buffer_Reset(dbuf); \n
} \n
- GWEN_Timestamp_AddSeconds(ts, 24*60*60); \n
+ GWEN_Date_AddDays(dt, 1); \n
if (v>=endTime) \n
break; \n
} \n
GWEN_Buffer_free(dbuf); \n
- GWEN_Timestamp_free(ts); \n
+ GWEN_Date_free(dt); \n
} \n
@@ -249,42 +248,40 @@
{ \n
double minValue; \n
double maxValue; \n
- double endTime; \n
GWEN_BUFFER *dbuf; \n
- GWEN_TIMESTAMP *ts; \n
+ GWEN_DATE *dt; \n
\n
maxValue=st->maxValue; \n
- ts=GWEN_Timestamp_fromLocalTime(maxValue); \n
- GWEN_Timestamp_SetTime(ts, 0, 0, 0); \n
- GWEN_Timestamp_AddSeconds(ts, 24*60*60); \n
- endTime=GWEN_Timestamp_toTimeT(ts); \n
- GWEN_Timestamp_free(ts); \n
+ dt=GWEN_Date_fromLocalTime(maxValue); \n
+ GWEN_Date_free(dt); \n
\n
minValue=st->minValue; \n
- ts=GWEN_Timestamp_fromLocalTime(minValue); \n
- GWEN_Timestamp_SetTime(ts, 0, 0, 0); \n
- GWEN_Timestamp_AddSeconds(ts, -GWEN_Timestamp_GetWeekDay(ts)*24*60*60); \n
+ dt=GWEN_Date_fromLocalTime(minValue); \n
\n
dbuf=GWEN_Buffer_new(0, 256, 0, 1); \n
while(1) { \n
double v; \n
+ GWEN_DATE *dtCurrent; \n
\n
- v=GWEN_Timestamp_toTimeT(ts); \n
- if (v>=minValue && v<endTime) { \n
+ dtCurrent=GWEN_Date_GetThisWeekStartFromMonday(dt); \n
+ v=GWEN_Date_toLocalTime(dtCurrent); \n
+ if (v>=minValue && v<maxValue) { \n
GWEN_Buffer_AppendArgs(dbuf, \n
"%04d/%02d/%02d", \n
- GWEN_Timestamp_GetYear(ts), \n
- GWEN_Timestamp_GetMonth(ts), \n
- GWEN_Timestamp_GetDay(ts)); \n
+ GWEN_Date_GetYear(dtCurrent), \n
+ GWEN_Date_GetMonth(dtCurrent), \n
+ GWEN_Date_GetDay(dtCurrent)); \n
$(struct_prefix)_AddNewTick(st, GWEN_Buffer_GetStart(dbuf), v, lvl, 0); \n
GWEN_Buffer_Reset(dbuf); \n
} \n
- GWEN_Timestamp_AddSeconds(ts, 7*24*60*60); \n
- if (v>=endTime) \n
+ GWEN_Date_free(dt); \n
+ dt=dtCurrent; \n
+ GWEN_Date_AddDays(dt, 7); \n
+ if (v>=maxValue) \n
break; \n
} \n
GWEN_Buffer_free(dbuf); \n
- GWEN_Timestamp_free(ts); \n
+ GWEN_Date_free(dt); \n
} \n
@@ -302,13 +299,11 @@
{ \n
double minValue; \n
double maxValue; \n
- double endTime; \n
GWEN_BUFFER *dbuf; \n
GWEN_DATE *dt; \n
\n
maxValue=st->maxValue; \n
dt=GWEN_Date_fromLocalTime(maxValue); \n
- endTime=GWEN_Date_toLocalTime(dt); \n
GWEN_Date_free(dt); \n
\n
minValue=st->minValue; \n
@@ -320,18 +315,19 @@
GWEN_DATE *dtCurrent; \n
\n
dtCurrent=GWEN_Date_GetThisMonthStart(dt); \n
- v=GWEN_Date_toLocalTime(dt); \n
- if (v>=minValue && v<endTime) { \n
+ v=GWEN_Date_toLocalTime(dtCurrent); \n
+ if (v>=minValue && v<maxValue) { \n
GWEN_Buffer_AppendArgs(dbuf, \n
"%04d/%02d", \n
- GWEN_Date_GetYear(dt), \n
- GWEN_Date_GetMonth(dt)); \n
+ GWEN_Date_GetYear(dtCurrent), \n
+ GWEN_Date_GetMonth(dtCurrent)); \n
$(struct_prefix)_AddNewTick(st, GWEN_Buffer_GetStart(dbuf), v, lvl, 0); \n
- GWEN_Date_free(dtCurrent); \n
GWEN_Buffer_Reset(dbuf); \n
} \n
+ GWEN_Date_free(dt); \n
+ dt=dtCurrent; \n
GWEN_Date_AddDays(dt, 32); \n
- if (v>=endTime) \n
+ if (v>=maxValue) \n
break; \n
} \n
GWEN_Buffer_free(dbuf); \n
diff --git a/src/lib/aqdiagram/graph/tick.t2d b/src/lib/aqdiagram/graph/tick.t2d
index 7c1e9f4..8199c25 100644
--- a/src/lib/aqdiagram/graph/tick.t2d
+++ b/src/lib/aqdiagram/graph/tick.t2d
@@ -18,8 +18,48 @@
+
+
+
+
+
+ $(api) double $(struct_prefix)_List_DistanceBetweenTicks(const $(struct_type)_LIST *tickList, int lvl);
+
+
+
+
+
+ double $(struct_prefix)_List_DistanceBetweenTicks(const $(struct_type)_LIST *tickList, int lvl) \n
+ { \n
+ int haveFirstValue=0; \n
+ double v0; \n
+ const $(struct_type) *tick; \n
+ \n
+ tick=$(struct_prefix)_List_First(tickList); \n
+ while(tick) { \n
+ if ($(struct_prefix)_GetLevel(tick)==lvl) { \n
+ if (!haveFirstValue) { \n
+ v0=$(struct_prefix)_GetValue(tick); \n
+ haveFirstValue=1; \n
+ } \n
+ else { \n
+ DBG_ERROR(NULL, "v1=%.2f, v0=%.2f", $(struct_prefix)_GetValue(tick), v0); \n
+ return $(struct_prefix)_GetValue(tick)-v0; \n
+ } \n
+ } \n
+ \n
+ tick=$(struct_prefix)_List_Next(tick); \n
+ } \n
+ return 0; \n
+ } \n
+
+
+
+
+
+
diff --git a/src/lib/aqdiagram/graph/timegraph.c b/src/lib/aqdiagram/graph/timegraph.c
index 5830525..eddf0f6 100644
--- a/src/lib/aqdiagram/graph/timegraph.c
+++ b/src/lib/aqdiagram/graph/timegraph.c
@@ -91,19 +91,23 @@ void AQDG_TimeGraph_SetupTicks(AQDG_GRAPH *g)
{
AQDG_GRAPH_AXIS *axis;
+ DBG_ERROR(NULL, "Calc min/max values");
AQDG_Graph_CalcMinMaxValues(g);
/* create ticks for X axis */
+ DBG_ERROR(NULL, "Create ticks for X axis");
axis=AQDG_Graph_GetAxisByIndex(g, AQDG_GRAPH_AXISPOS_BOTTOM);
if (axis) {
_setupTicksForTimeAxis(axis);
}
/* create ticks for Y axis */
+ DBG_ERROR(NULL, "Create ticks for Y axis");
axis=AQDG_Graph_GetAxisByIndex(g, AQDG_GRAPH_AXISPOS_LEFT);
if (axis) {
_setupTicksForDataAxis(axis);
}
+ DBG_ERROR(NULL, "Ticks done");
}
@@ -134,11 +138,16 @@ void _setupTicksForTimeAxis(AQDG_GRAPH_AXIS *axis)
else {
DBG_ERROR(NULL, "Gen month ticks");
AQDG_Graph_Axis_GenMonthTicks(axis, 0);
- if (diffInDays<100)
+ if (diffInDays<100) {
+ DBG_ERROR(NULL, "Gen day ticks");
AQDG_Graph_Axis_GenDayTicks(axis, 1);
- else if (diffInDays<400)
+ }
+ else if (diffInDays<400) {
+ DBG_ERROR(NULL, "Gen week ticks");
AQDG_Graph_Axis_GenWeekTicks(axis, 1);
+ }
}
+ DBG_ERROR(NULL, "Ticks done");
}
diff --git a/src/lib/aqdiagram/graph/w_viewport.c b/src/lib/aqdiagram/graph/w_viewport.c
index 4b3396d..8db3410 100644
--- a/src/lib/aqdiagram/graph/w_viewport.c
+++ b/src/lib/aqdiagram/graph/w_viewport.c
@@ -37,6 +37,10 @@ static void _drawCurvePoints(AQDG_OBJECT *o, AQDG_DRAW_CONTEXT *dc, const AQDG_G
int pen);
static void _drawVerticalGrid(AQDG_OBJECT *o, AQDG_DRAW_CONTEXT *dc);
static void _drawHorizontalGrid(AQDG_OBJECT *o, AQDG_DRAW_CONTEXT *dc);
+static int _screenDistBetweenLevelTicksX(const AQDG_GRAPH_TICK_LIST *tickList, int lvl,
+ int contentSize, double minValue, double maxValue);
+static int _screenDistBetweenLevelTicksY(const AQDG_GRAPH_TICK_LIST *tickList, int lvl,
+ int contentSize, double minValue, double maxValue);
@@ -123,6 +127,7 @@ void _drawCurves(AQDG_OBJECT *o, AQDG_DRAW_CONTEXT *dc)
const AQDG_GRAPH_SUBGRAPH *subGraph;
int penIdx=AQDG_GRAPHWIDGET_PEN_IDX_CURVE0;
+ DBG_ERROR(NULL, "Draw curves");
xo=GWEN_INHERIT_GETDATA(AQDG_OBJECT, AQDG_WIDGET_VIEWPORT, o);
graph=AQDG_GraphWidget_GetGraph(xo->graphObject);
@@ -165,6 +170,7 @@ void _drawCurve(AQDG_OBJECT *o, AQDG_DRAW_CONTEXT *dc, const AQDG_GRAPH_CURVE *c
double minValueX, double maxValueX, double minValueY, double maxValueY,
int pen)
{
+ DBG_ERROR(NULL, "Draw curve");
switch(AQDG_Graph_Curve_GetGraphType(curve)) {
case AQDG_GRAPH_TYPE_LINE:
_drawCurveLines(o, dc, curve, minValueX, maxValueX, minValueY, maxValueY, pen);
@@ -286,6 +292,7 @@ void _drawVerticalGrid(AQDG_OBJECT *o, AQDG_DRAW_CONTEXT *dc)
int pen2;
int y1;
int y2;
+ int showLevel1;
y1=AQDG_Object_GetAbsoluteY(o)+AQDG_Object_GetBorderTop(o);
y2=AQDG_Object_GetAbsoluteY(o)+AQDG_Object_GetHeight(o)-AQDG_Object_GetBorderBottom(o);
@@ -295,6 +302,7 @@ void _drawVerticalGrid(AQDG_OBJECT *o, AQDG_DRAW_CONTEXT *dc)
maxValue=AQDG_Graph_Axis_GetMaxValue(axis);
pen1=AQDG_GraphWidget_GetPen(xo->graphObject, AQDG_GRAPHWIDGET_PEN_IDX_GRID1);
pen2=AQDG_GraphWidget_GetPen(xo->graphObject, AQDG_GRAPHWIDGET_PEN_IDX_GRID2);
+ showLevel1=(_screenDistBetweenLevelTicksX(tickList, 1, contentSize, minValue, maxValue)>15)?1:0;
tick=AQDG_Graph_Tick_List_First(tickList);
while(tick) {
@@ -306,8 +314,10 @@ void _drawVerticalGrid(AQDG_OBJECT *o, AQDG_DRAW_CONTEXT *dc)
xpos+=AQDG_Object_GetBorderLeft(o);
if (AQDG_Graph_Tick_GetLevel(tick)==0)
AQDG_Draw_Context_DrawLine(dc, pen1, absX+xpos, y1, absX+xpos, y2);
- else if (AQDG_Graph_Tick_GetLevel(tick)==1)
- AQDG_Draw_Context_DrawLine(dc, pen2, absX+xpos, y1, absX+xpos, y2);
+ else {
+ if (showLevel1)
+ AQDG_Draw_Context_DrawLine(dc, pen2, absX+xpos, y1, absX+xpos, y2);
+ }
tick=AQDG_Graph_Tick_List_Next(tick);
}
}
@@ -341,6 +351,7 @@ void _drawHorizontalGrid(AQDG_OBJECT *o, AQDG_DRAW_CONTEXT *dc)
int pen2;
int x1;
int x2;
+ int showLevel1;
x1=AQDG_Object_GetAbsoluteX(o)+AQDG_Object_GetBorderLeft(o);
x2=AQDG_Object_GetAbsoluteX(o)+AQDG_Object_GetWidth(o)-AQDG_Object_GetBorderLeft(o)-AQDG_Object_GetBorderRight(o);
@@ -350,6 +361,7 @@ void _drawHorizontalGrid(AQDG_OBJECT *o, AQDG_DRAW_CONTEXT *dc)
maxValue=AQDG_Graph_Axis_GetMaxValue(axis);
pen1=AQDG_GraphWidget_GetPen(xo->graphObject, AQDG_GRAPHWIDGET_PEN_IDX_GRID1);
pen2=AQDG_GraphWidget_GetPen(xo->graphObject, AQDG_GRAPHWIDGET_PEN_IDX_GRID2);
+ showLevel1=(_screenDistBetweenLevelTicksY(tickList, 1, contentSize, minValue, maxValue)>15)?1:0;
tick=AQDG_Graph_Tick_List_First(tickList);
while(tick) {
@@ -361,8 +373,10 @@ void _drawHorizontalGrid(AQDG_OBJECT *o, AQDG_DRAW_CONTEXT *dc)
ypos+=AQDG_Object_GetBorderTop(o);
if (AQDG_Graph_Tick_GetLevel(tick)==0)
AQDG_Draw_Context_DrawLine(dc, pen1, x1, absY+ypos, x2, absY+ypos);
- else
- AQDG_Draw_Context_DrawLine(dc, pen2, x1, absY+ypos, x2, absY+ypos);
+ else {
+ if (showLevel1)
+ AQDG_Draw_Context_DrawLine(dc, pen2, x1, absY+ypos, x2, absY+ypos);
+ }
tick=AQDG_Graph_Tick_List_Next(tick);
}
}
@@ -371,3 +385,33 @@ void _drawHorizontalGrid(AQDG_OBJECT *o, AQDG_DRAW_CONTEXT *dc)
+int _screenDistBetweenLevelTicksX(const AQDG_GRAPH_TICK_LIST *tickList, int lvl,
+ int contentSize, double minValue, double maxValue)
+{
+ double v;
+ int pts;
+
+ v=AQDG_Graph_Tick_List_DistanceBetweenTicks(tickList, lvl);
+ DBG_ERROR(NULL, "Value diff: %.2f", v);
+ pts=(v*(contentSize/(maxValue-minValue)));
+ DBG_ERROR(NULL, "Point diff: %d", pts);
+ return pts;
+}
+
+
+
+int _screenDistBetweenLevelTicksY(const AQDG_GRAPH_TICK_LIST *tickList, int lvl,
+ int contentSize, double minValue, double maxValue)
+{
+ double v;
+ int pts;
+
+ v=AQDG_Graph_Tick_List_DistanceBetweenTicks(tickList, lvl);
+ DBG_ERROR(NULL, "Value diff: %.2f", v);
+ pts=(v*(contentSize/(maxValue-minValue)));
+ DBG_ERROR(NULL, "Point diff: %d", pts);
+ return pts;
+}
+
+
+
diff --git a/src/lib/aqdiagram/graph/w_xaxis.c b/src/lib/aqdiagram/graph/w_xaxis.c
index bfe2b10..9abe676 100644
--- a/src/lib/aqdiagram/graph/w_xaxis.c
+++ b/src/lib/aqdiagram/graph/w_xaxis.c
@@ -34,6 +34,8 @@ static int _calcHorizontalPos(double value, int contentSize, double minValue, do
static void _setChildrenRelXFromValue(AQDG_OBJECT *o);
static void _setChildrenRelY(AQDG_OBJECT *o);
static void _setChildrenSizes(AQDG_OBJECT *o);
+static int _screenDistBetweenLevelTicks(const AQDG_GRAPH_TICK_LIST *tickList, int lvl,
+ int contentSize, double minValue, double maxValue);
@@ -121,6 +123,7 @@ void _drawTicks(AQDG_OBJECT *o, AQDG_DRAW_CONTEXT *dc, int absY)
double maxValue;
int absX;
int pen;
+ int showLevel1;
contentSize=AQDG_Object_GetWidth(o)-AQDG_Object_GetBorderLeft(o)-AQDG_Object_GetBorderRight(o);
scaleSize=AQDG_AxisWidget_GetScaleSize(o);
@@ -128,6 +131,7 @@ void _drawTicks(AQDG_OBJECT *o, AQDG_DRAW_CONTEXT *dc, int absY)
minValue=AQDG_AxisWidget_GetMinValue(o);
maxValue=AQDG_AxisWidget_GetMaxValue(o);
pen=AQDG_DrawableWidget_GetForegroundPenId(o);
+ showLevel1=(_screenDistBetweenLevelTicks(tickList, 1, contentSize, minValue, maxValue)>15)?1:0;
tick=AQDG_Graph_Tick_List_First(tickList);
while(tick) {
@@ -139,8 +143,10 @@ void _drawTicks(AQDG_OBJECT *o, AQDG_DRAW_CONTEXT *dc, int absY)
xpos+=AQDG_Object_GetBorderLeft(o);
if (AQDG_Graph_Tick_GetLevel(tick)==0)
AQDG_Draw_Context_DrawLine(dc, pen, absX+xpos, absY-(scaleSize/2), absX+xpos, absY+(scaleSize/2));
- else if (AQDG_Graph_Tick_GetLevel(tick)==1)
- AQDG_Draw_Context_DrawLine(dc, pen, absX+xpos, absY-(scaleSize/4), absX+xpos, absY+(scaleSize/4));
+ else if (AQDG_Graph_Tick_GetLevel(tick)==1) {
+ if (showLevel1)
+ AQDG_Draw_Context_DrawLine(dc, pen, absX+xpos, absY-(scaleSize/4), absX+xpos, absY+(scaleSize/4));
+ }
tick=AQDG_Graph_Tick_List_Next(tick);
}
}
@@ -149,6 +155,21 @@ void _drawTicks(AQDG_OBJECT *o, AQDG_DRAW_CONTEXT *dc, int absY)
+int _screenDistBetweenLevelTicks(const AQDG_GRAPH_TICK_LIST *tickList, int lvl,
+ int contentSize, double minValue, double maxValue)
+{
+ double v;
+ int pts;
+
+ v=AQDG_Graph_Tick_List_DistanceBetweenTicks(tickList, lvl);
+ DBG_ERROR(NULL, "Value diff: %.2f", v);
+ pts=v*(contentSize/(maxValue-minValue));
+ DBG_ERROR(NULL, "Point diff: %d", pts);
+ return pts;
+}
+
+
+
int _getDefaultWidth(AQDG_OBJECT *o)
{
return 1;
diff --git a/src/lib/aqdiagram/graph/w_yaxis.c b/src/lib/aqdiagram/graph/w_yaxis.c
index 42519f0..2bad21a 100644
--- a/src/lib/aqdiagram/graph/w_yaxis.c
+++ b/src/lib/aqdiagram/graph/w_yaxis.c
@@ -29,6 +29,8 @@ static int _getDefaultHeight(AQDG_OBJECT *o);
static int _layout(AQDG_OBJECT *object);
static int _draw(AQDG_OBJECT *object);
static void _drawTicks(AQDG_OBJECT *o, AQDG_DRAW_CONTEXT *dc, int x);
+static int _screenDistBetweenLevelTicks(const AQDG_GRAPH_TICK_LIST *tickList, int lvl,
+ int contentSize, double minValue, double maxValue);
static void _setChildrenRelX(AQDG_OBJECT *o);
static void _setChildrenRelYFromValue(AQDG_OBJECT *o);
static void _setChildrenSizes(AQDG_OBJECT *o);
@@ -148,13 +150,15 @@ void _drawTicks(AQDG_OBJECT *o, AQDG_DRAW_CONTEXT *dc, int absX)
double maxValue;
int absY;
int pen;
-
+ int showLevel1;
+
contentSize=AQDG_Object_GetHeight(o)-AQDG_Object_GetBorderTop(o)-AQDG_Object_GetBorderBottom(o);
scaleSize=AQDG_AxisWidget_GetScaleSize(o);
absY=AQDG_Object_GetAbsoluteY(o);
minValue=AQDG_AxisWidget_GetMinValue(o);
maxValue=AQDG_AxisWidget_GetMaxValue(o);
pen=AQDG_DrawableWidget_GetForegroundPenId(o);
+ showLevel1=(_screenDistBetweenLevelTicks(tickList, 1, contentSize, minValue, maxValue)>15)?1:0;
tick=AQDG_Graph_Tick_List_First(tickList);
while(tick) {
@@ -166,8 +170,10 @@ void _drawTicks(AQDG_OBJECT *o, AQDG_DRAW_CONTEXT *dc, int absX)
ypos+=AQDG_Object_GetBorderTop(o);
if (AQDG_Graph_Tick_GetLevel(tick)==0)
AQDG_Draw_Context_DrawLine(dc, pen, absX-(scaleSize/2), absY+ypos, absX+(scaleSize/2), absY+ypos);
- else
- AQDG_Draw_Context_DrawLine(dc, pen, absX-(scaleSize/4), absY+ypos, absX+(scaleSize/4), absY+ypos);
+ else {
+ if (showLevel1)
+ AQDG_Draw_Context_DrawLine(dc, pen, absX-(scaleSize/4), absY+ypos, absX+(scaleSize/4), absY+ypos);
+ }
tick=AQDG_Graph_Tick_List_Next(tick);
}
}
@@ -176,6 +182,21 @@ void _drawTicks(AQDG_OBJECT *o, AQDG_DRAW_CONTEXT *dc, int absX)
+int _screenDistBetweenLevelTicks(const AQDG_GRAPH_TICK_LIST *tickList, int lvl,
+ int contentSize, double minValue, double maxValue)
+{
+ double v;
+ int pts;
+
+ v=AQDG_Graph_Tick_List_DistanceBetweenTicks(tickList, lvl);
+ DBG_ERROR(NULL, "Value diff: %.2f", v);
+ pts=(v*(contentSize/(maxValue-minValue)));
+ DBG_ERROR(NULL, "Point diff: %d", pts);
+ return pts;
+}
+
+
+
void _setChildrenRelX(AQDG_OBJECT *o)
{
int contentSize;
diff --git a/src/lib/aqdiagram/libtest.c b/src/lib/aqdiagram/libtest.c
index 36808cc..9f5fe3f 100644
--- a/src/lib/aqdiagram/libtest.c
+++ b/src/lib/aqdiagram/libtest.c
@@ -22,6 +22,8 @@
#include
#include
#include
+#include
+#include
#include
#include
@@ -208,6 +210,46 @@ int test4()
+int test5()
+{
+ AQDG_GRAPH *g;
+ AQDG_GRAPH_DATAPAIR_LIST *dpList;
+ AQDG_GRAPH_DATAPAIR_LIST *derivedDpList;
+ AQDG_DRAW_CONTEXT *dc;
+ AQDG_OBJECT *graphObject;
+
+ g=AQDG_TimeGraph_new("Title", "Subtitle", "Value", "mm", 0);
+ dpList=_mkTestData1();
+ AQDG_TimeGraph_AddCurve(g, "Testdata", AQDG_GRAPH_TYPE_LINE, dpList);
+
+ derivedDpList=AQDG_Data_Accumulate(dpList);
+ AQDG_TimeGraph_AddCurve(g, "Accumulated", AQDG_GRAPH_TYPE_LINE, derivedDpList);
+ AQDG_TimeGraph_SetupTicks(g);
+
+ dc=AQDG_Draw_ContextCairo_Png_new("/tmp/testgraph.png", 800, 600);
+ graphObject=AQDG_GraphWidget_new(NULL, AQDG_OBJECT_OPTIONS_STRETCHX | AQDG_OBJECT_OPTIONS_STRETCHY, dc);
+ AQDG_Object_SetWidth(graphObject, 800);
+ AQDG_Object_SetHeight(graphObject, 600);
+
+ AQDG_GraphWidget_SetupDefaultPens(graphObject);
+ AQDG_GraphWidget_SetupDefaultFonts(graphObject);
+
+ AQDG_GraphWidget_SetupForGraph(graphObject, g);
+
+ AQDG_Object_ModifyBranchFlagsDown(graphObject, AQDG_OBJECT_FLAGS_RECALC, AQDG_OBJECT_FLAGS_RECALC);
+ AQDG_Object_ModifyBranchFlagsDown(graphObject, AQDG_OBJECT_FLAGS_LAYOUT, AQDG_OBJECT_FLAGS_LAYOUT);
+ AQDG_Object_Layout(graphObject);
+ AQDG_Object_Tree2_CalculateAbsPositions(graphObject);
+ AQDG_Object_Dump(graphObject, 2);
+
+ AQDG_DrawableWidget_Draw(graphObject);
+ AQDG_Draw_Context_Finish(dc);
+
+ return 0;
+}
+
+
+
AQDG_GRAPH *_mkTestGraph()
{
AQDG_GRAPH *g;
@@ -257,7 +299,7 @@ AQDG_GRAPH_DATAPAIR_LIST *_mkTestData1()
int i;
dpList=AQDG_Graph_DataPair_List_new();
- ts=GWEN_Timestamp_new(2025, 1, 1, 0, 0, 0);
+ ts=GWEN_Timestamp_new(2025, 1, 15, 2, 0, 0);
for(i=0; i<60; i++) {
AQDG_GRAPH_DATAPAIR *dp;
double v;
@@ -366,7 +408,7 @@ int main(int argc, char **argv)
// rv=test1(argc, argv);
// rv=test2(argc, argv);
- rv=test4();
+ rv=test5();
if (rv!=0){
DBG_ERROR(NULL, "here (%d)", rv);