From 0093338296f4688a38baad5723fc1611800ceaa6 Mon Sep 17 00:00:00 2001 From: Martin Preuss Date: Thu, 24 Mar 2022 21:58:17 +0100 Subject: [PATCH] Imported latest changes from AqFinance. --- src/lib/aqdiagram/graph/0BUILD | 16 +- src/lib/aqdiagram/graph/draw.c | 557 ++++++++++++++++++ .../graph/{g_draw_xticks.h => draw.h} | 6 +- src/lib/aqdiagram/graph/g_draw_data.c | 245 -------- src/lib/aqdiagram/graph/g_draw_data.h | 24 - src/lib/aqdiagram/graph/g_draw_xticks.c | 232 -------- src/lib/aqdiagram/graph/g_draw_yticks.c | 214 ------- src/lib/aqdiagram/graph/g_draw_yticks.h | 22 - src/lib/aqdiagram/graph/graph.c | 270 +++++++-- .../aqdiagram/graph/{g_layout.c => layout.c} | 21 +- .../aqdiagram/graph/{g_layout.h => layout.h} | 6 +- .../aqdiagram/graph/{g_config.c => setup.c} | 187 +++--- .../aqdiagram/graph/{g_config.h => setup.h} | 6 +- 13 files changed, 886 insertions(+), 920 deletions(-) create mode 100644 src/lib/aqdiagram/graph/draw.c rename src/lib/aqdiagram/graph/{g_draw_xticks.h => draw.h} (81%) delete mode 100644 src/lib/aqdiagram/graph/g_draw_data.c delete mode 100644 src/lib/aqdiagram/graph/g_draw_data.h delete mode 100644 src/lib/aqdiagram/graph/g_draw_xticks.c delete mode 100644 src/lib/aqdiagram/graph/g_draw_yticks.c delete mode 100644 src/lib/aqdiagram/graph/g_draw_yticks.h rename src/lib/aqdiagram/graph/{g_layout.c => layout.c} (92%) rename src/lib/aqdiagram/graph/{g_layout.h => layout.h} (89%) rename src/lib/aqdiagram/graph/{g_config.c => setup.c} (83%) rename src/lib/aqdiagram/graph/{g_config.h => setup.h} (88%) diff --git a/src/lib/aqdiagram/graph/0BUILD b/src/lib/aqdiagram/graph/0BUILD index 5cff903..bf62f1c 100644 --- a/src/lib/aqdiagram/graph/0BUILD +++ b/src/lib/aqdiagram/graph/0BUILD @@ -86,27 +86,23 @@ graph.h + draw.h + layout.h + setup.h graph_p.h - g_draw_data.h - g_draw_xticks.h - g_draw_yticks.h - g_config.h - g_layout.h $(local/typefiles) graph.c - g_draw_data.c - g_draw_xticks.c - g_draw_yticks.c - g_config.c - g_layout.c + draw.c + layout.c + setup.c diff --git a/src/lib/aqdiagram/graph/draw.c b/src/lib/aqdiagram/graph/draw.c new file mode 100644 index 0000000..b3249b3 --- /dev/null +++ b/src/lib/aqdiagram/graph/draw.c @@ -0,0 +1,557 @@ +/**************************************************************************** + * This file is part of the project AqFinance. + * AqFinance (c) by 2011 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 "aqdiagram/graph/draw.h" +#include "aqdiagram/graph/dataset_fns.h" +#include "graph_p.h" + +#include + + +#define MAX_TICK_LEVELS 5 + +#define MIN_DIST_FOR_TICKS 5 +#define MIN_DIST_FOR_GRIDS 5 + + +#define TICKDRAWFLAGS_MARKS 0x01 +#define TICKDRAWFLAGS_GRIDS 0x02 +#define TICKDRAWFLAGS_LABELS 0x04 + + + +static void _drawXAxis(AQDG_GRAPH *gr); +static void _drawYAxis(AQDG_GRAPH *gr); +static void _drawTitleIfSet(const AQDG_GRAPH *gr); +static void _drawSubTitleIfSet(const AQDG_GRAPH *gr); + +static void _drawXTicks(AQDG_GRAPH *gr); +static void _drawYTicks(AQDG_GRAPH *gr); + +static int _isPositionFree(int m1, int m2, const uint8_t *pMask, int maxLen); +static void _reservePosition(int m1, int m2, uint8_t *pMask, int maxLen); + +static void _probablyDrawGridLineForXTick(const AQDG_GRAPH *gr, int x, uint8_t tickDrawFlags); +static void _probablyDrawMarkForXTick(const AQDG_GRAPH *gr, int x, int y, uint8_t tickDrawFlags, int level); + +static int _getMaxTickLabelWidthForLevel(const AQDG_GRAPH *gr, const AQDG_GRAPH_TICK_LIST *tl, int level); +static int _calcDistBetweenFirstTwoTicksOfLevel(const AQDG_GRAPH *gr, const AQDG_GRAPH_TICK_LIST *tl, int level); + + + +void AQDG_Graph_DrawFramework(AQDG_GRAPH *gr) +{ + /* draw background */ + AQDG_Draw_Context_DrawFilledRect(gr->drawContext, gr->penBackground, + 0, 0, gr->width, gr->height); + + /* draw graph area */ + AQDG_Draw_Context_DrawFilledRect(gr->drawContext, gr->penGraphBackground, + gr->graphAreaPosX, gr->graphAreaPosY, + gr->graphAreaWidth, gr->graphAreaHeight); + + _drawXAxis(gr); + _drawYAxis(gr); + _drawTitleIfSet(gr); + _drawSubTitleIfSet(gr); +} + + + +void _drawXAxis(AQDG_GRAPH *gr) +{ + const char *s; + + /* ticks, axis, label */ + _drawXTicks(gr); + AQDG_Draw_Context_DrawLine(gr->drawContext, gr->penAxis, + gr->graphAreaPosX, gr->xAxisPosY, + gr->graphAreaPosX+gr->graphAreaWidth, gr->xAxisPosY); + s=AQDG_Graph_DataSet_GetLabelX(gr->dataSet); + if (s && *s) + AQDG_Draw_Context_DrawText(gr->drawContext, gr->penAxisLabel, gr->fontAxisLabel, AQDG_Direction_Horizontal, + gr->xAxisLabelPosX, gr->xAxisLabelPosY, s); +} + + + +void _drawYAxis(AQDG_GRAPH *gr) +{ + const char *s; + + /* ticks, axis, label */ + _drawYTicks(gr); + AQDG_Draw_Context_DrawLine(gr->drawContext, gr->penAxis, + gr->yAxisPosX, gr->graphAreaPosY, + gr->yAxisPosX, gr->graphAreaPosY+gr->graphAreaHeight); + s=AQDG_Graph_DataSet_GetLabelY(gr->dataSet); + if (s && *s) + AQDG_Draw_Context_DrawText(gr->drawContext, gr->penAxisLabel, gr->fontAxisLabel, AQDG_Direction_Horizontal, + gr->yAxisLabelPosX, gr->yAxisLabelPosY, s); +} + + + +void _drawTitleIfSet(const AQDG_GRAPH *gr) +{ + const char *s; + + s=AQDG_Graph_DataSet_GetTitle(gr->dataSet); + if (s && *s) + AQDG_Draw_Context_DrawText(gr->drawContext, gr->penTitle, gr->fontTitle, AQDG_Direction_Horizontal, + gr->titlePosX, gr->titlePosY, s); +} + + + +void _drawSubTitleIfSet(const AQDG_GRAPH *gr) +{ + const char *s; + + s=AQDG_Graph_DataSet_GetSubTitle(gr->dataSet); + if (s && *s) + AQDG_Draw_Context_DrawText(gr->drawContext, gr->penSubTitle, gr->fontSubTitle, AQDG_Direction_Horizontal, + gr->subTitlePosX, gr->subTitlePosY, s); +} + + + +void _drawXTicks(AQDG_GRAPH *gr) +{ + AQDG_GRAPH_TICK_LIST *tl; + + tl=AQDG_Graph_DataSet_GetXTickList(gr->dataSet); + if (tl) { + AQDG_GRAPH_TICK *t; + uint8_t *pMask; + int level; + + /* reset */ + pMask=(uint8_t *) malloc(gr->graphAreaWidth); + assert(pMask); + memset(pMask, 0, gr->graphAreaWidth); + + /* handle each level */ + for (level=1; levelgraphAreaWidth; + if (dist>MIN_DIST_FOR_TICKS) + tickDrawFlags|=TICKDRAWFLAGS_MARKS; + if (dist>MIN_DIST_FOR_GRIDS) + tickDrawFlags|=TICKDRAWFLAGS_GRIDS; + +#if 0 + if (dist>maxWidth+SMALL_BORDER) { + tickDrawFlags|=TICKDRAWFLAGS_LABELS; + } + else if ((dist*2)>maxWidth+SMALL_BORDER) { + tickDrawFlags|=TICKDRAWFLAGS_LABELS; + every=2; + } + else if ((dist*4)>maxWidth+SMALL_BORDER) { + tickDrawFlags|=TICKDRAWFLAGS_LABELS; + every=4; + } +#else + tickDrawFlags|=TICKDRAWFLAGS_LABELS; +#endif + + /* now draw according to flags */ + if (tickDrawFlags) { + double minVal; + double maxVal; + int tickIntervalCnt=every; + + minVal=AQDG_Graph_DataSet_GetMinValueX(gr->dataSet); + maxVal=AQDG_Graph_DataSet_GetMaxValueX(gr->dataSet); + t=AQDG_Graph_Tick_List_First(tl); + while (t) { + if (AQDG_Graph_Tick_GetLevel(t)==level) { + double v; + + tickIntervalCnt--; + v=AQDG_Graph_Tick_GetValue(t); + if (v>=minVal && v<=maxVal) { + int x, y; + + x=gr->graphOriginX + (v * gr->graphFactorX); + y=gr->xAxisPosY; + + _probablyDrawGridLineForXTick(gr, x, tickDrawFlags); + _probablyDrawMarkForXTick(gr, x, y, tickDrawFlags, level); + + if (tickDrawFlags & TICKDRAWFLAGS_LABELS) { + const char *s; + + /* draw label */ + if (tickIntervalCnt<1) { + s=AQDG_Graph_Tick_GetLabel(t); + if (s && *s) { + int i; + + i=AQDG_Draw_Context_GetTextWidth(gr->drawContext, gr->penAxisLabel, s); + if (i>=0) { + if ((x+(i/2) < (gr->graphAreaPosX+gr->graphAreaWidth)) && + (x-(i/2) > gr->graphAreaPosX)) { + int m1, m2; + + m1=x-(i/2)-gr->graphAreaPosX; + m2=x+(i/2)-gr->graphAreaPosX; + if (_isPositionFree(m1, m2, pMask, gr->graphAreaWidth)) { + _reservePosition(m1, m2, pMask, gr->graphAreaWidth); + AQDG_Draw_Context_DrawText(gr->drawContext, gr->penAxisLabel, gr->fontTickLabel, AQDG_Direction_Horizontal, + x-(i/2), gr->xTickLabelPosY, s); + } + } + } + } + tickIntervalCnt=every; + } + } /* if labels to be drawn */ + } /* if value within limits */ + } + t=AQDG_Graph_Tick_List_Next(t); + } /* while t */ + } /* if tickDrawFlags */ + + + } /* for level */ + + free(pMask); + } /* if tl */ +} + + +int _isPositionFree(int m1, int m2, const uint8_t *pMask, int maxLen) +{ + int j; + + for (j=m1; j=maxLen) + return 0; + if (pMask[j]!=0) + return 0; + } + + return 1; +} + + + +void _reservePosition(int m1, int m2, uint8_t *pMask, int maxLen) +{ + int j; + + m1-=SMALL_BORDER/2; + m2+=SMALL_BORDER/2; + + if (m1<0) + m1=0; + if (m2>=maxLen) + m2=maxLen-1; + for (j=m1; jflags & AQDG_GRAPH_FLAGS_WITH_GRID) + AQDG_Draw_Context_DrawLine(gr->drawContext, gr->penGrid, x, gr->graphAreaPosY, x, gr->graphAreaPosY+gr->graphAreaHeight); + } +} + + + +void _probablyDrawMarkForXTick(const AQDG_GRAPH *gr, int x, int y, uint8_t tickDrawFlags, int level) +{ + if (tickDrawFlags & TICKDRAWFLAGS_MARKS) { + int w; + + switch (level) { + case 1: + w=9; + break; + case 2: + w=5; + break; + default: + case 3: + w=1; + break; + } + + /* draw tick mark */ + AQDG_Draw_Context_DrawLine(gr->drawContext, gr->penAxis, x, y-w, x, y+w); + } +} + + + +int _getMaxTickLabelWidthForLevel(const AQDG_GRAPH *gr, const AQDG_GRAPH_TICK_LIST *tl, int level) +{ + AQDG_GRAPH_TICK *t; + int maxWidth=0; + + /* determine width of labels for this level */ + t=AQDG_Graph_Tick_List_First(tl); + while (t) { + if (AQDG_Graph_Tick_GetLevel(t)==level) { + const char *s; + + s=AQDG_Graph_Tick_GetLabel(t); + if (s && *s) { + int i; + + //DBG_ERROR(0, "X-Level %d: [%s] = %f", level, s, AQDG_Graph_Tick_GetValue(t)); + i=AQDG_Draw_Context_GetTextWidth(gr->drawContext, gr->fontTickLabel, s); + if (i<0) { + DBG_ERROR(0, "Invalid text width (%d)", i); + } + else { + if (i>maxWidth) + maxWidth=i; + } + } + else { + DBG_ERROR(0, "X-Level %d: No tick label", level); + } + } + t=AQDG_Graph_Tick_List_Next(t); + } + + return maxWidth; +} + + + +int _calcDistBetweenFirstTwoTicksOfLevel(const AQDG_GRAPH *gr, const AQDG_GRAPH_TICK_LIST *tl, int level) +{ + const AQDG_GRAPH_TICK *t; + + t=AQDG_Graph_Tick_List_First(tl); + while (t && AQDG_Graph_Tick_GetLevel(t)!=level) + t=AQDG_Graph_Tick_List_Next(t); + if (t) { + const AQDG_GRAPH_TICK *tick1=t; + + t=AQDG_Graph_Tick_List_Next(t); + while (t && AQDG_Graph_Tick_GetLevel(t)!=level) + t=AQDG_Graph_Tick_List_Next(t); + if (t) { + const AQDG_GRAPH_TICK *tick2=t; + double v1, v2; + int dist; + + v1=AQDG_Graph_Tick_GetValue(tick1); + v2=AQDG_Graph_Tick_GetValue(tick2); + dist=(int)((v2-v1)*gr->graphFactorX); + return dist; + } + } + + return 0; +} + + + +void _drawYTicks(AQDG_GRAPH *gr) +{ + AQDG_GRAPH_TICK_LIST *tl; + + tl=AQDG_Graph_DataSet_GetYTickList(gr->dataSet); + if (tl) { + AQDG_GRAPH_TICK *t; + uint8_t *pMask; + int level; + + /* reset */ + pMask=(uint8_t *) malloc(gr->graphAreaHeight); + assert(pMask); + memset(pMask, 0, gr->graphAreaHeight); + + /* handle each level */ + for (level=1; leveldrawContext, gr->fontTickLabel, s); + if (i<0) { + DBG_ERROR(0, "Invalid text width (%d)", i); + } + else { + if (i>maxHeight) + maxHeight=i; + } + } + else { + DBG_ERROR(0, "No tick label"); + } + } + t=AQDG_Graph_Tick_List_Next(t); + } + + + /* get 1st and 2nd entry for the current level and check width */ + { + int first=1; + int hasSecond=0; + double lastValue; + + t=AQDG_Graph_Tick_List_First(tl); + while (t) { + if (AQDG_Graph_Tick_GetLevel(t)==level) { + double v; + + v=AQDG_Graph_Tick_GetValue(t); + if (first) { + lastValue=v; + first=0; + } + else { + int dist; + + dist=(int)((v-lastValue)*gr->graphFactorY); + if (dist>MIN_DIST_FOR_TICKS) + tickDrawFlags|=TICKDRAWFLAGS_MARKS; + if (dist>MIN_DIST_FOR_GRIDS) + tickDrawFlags|=TICKDRAWFLAGS_GRIDS; + if (dist>maxHeight+5) + tickDrawFlags|=TICKDRAWFLAGS_LABELS; + DBG_ERROR(0, "Y-Level %d: dist=%d (flags=%02x)", level, dist, tickDrawFlags); + hasSecond=1; + break; + } + } + + t=AQDG_Graph_Tick_List_Next(t); + } + + if (!first && !hasSecond) { + int dist; + + dist=gr->graphAreaHeight; + if (dist>MIN_DIST_FOR_TICKS) + tickDrawFlags|=TICKDRAWFLAGS_MARKS; + if (dist>MIN_DIST_FOR_GRIDS) + tickDrawFlags|=TICKDRAWFLAGS_GRIDS; + if (dist>maxHeight+2) + tickDrawFlags|=TICKDRAWFLAGS_LABELS; + } + } + + /* now draw according to flags */ + if (tickDrawFlags) { + double minVal; + double maxVal; + + minVal=AQDG_Graph_DataSet_GetMinValueY(gr->dataSet); + maxVal=AQDG_Graph_DataSet_GetMaxValueY(gr->dataSet); + t=AQDG_Graph_Tick_List_First(tl); + while (t) { + double v; + + v=AQDG_Graph_Tick_GetValue(t); + if (AQDG_Graph_Tick_GetLevel(t)==level) { + if (v>=minVal && v<=maxVal) { + int x, y; + int w; + + x=gr->yAxisPosX; + y=gr->graphOriginY - (v * gr->graphFactorY); + + /* draw grid line */ + if (tickDrawFlags & TICKDRAWFLAGS_GRIDS) { + if (gr->flags & AQDG_GRAPH_FLAGS_WITH_GRID) + AQDG_Draw_Context_DrawLine(gr->drawContext, gr->penGrid, gr->graphAreaPosX, y, gr->graphAreaPosX+gr->graphAreaWidth, y); + } + + if (tickDrawFlags & TICKDRAWFLAGS_MARKS) { + switch (level) { + case 1: + w=9; + break; + case 2: + w=5; + break; + default: + case 3: + w=1; + break; + } + + /* draw tick mark */ + AQDG_Draw_Context_DrawLine(gr->drawContext, gr->penAxis, x-w, y, x+w, y); + } + + if (tickDrawFlags & TICKDRAWFLAGS_LABELS) { + const char *s; + + /* draw label */ + s=AQDG_Graph_Tick_GetLabel(t); + if (s && *s) { + int i; + + i=AQDG_Draw_Context_GetTextHeight(gr->drawContext, gr->penAxisLabel, s); + if (i>=0) { + if ((y+(i/2) < (gr->graphAreaPosY+gr->graphAreaHeight)) && (y-(i/2)>= gr->graphAreaPosY)) { + int m1, m2; + + m1=y-(i/2)-gr->graphAreaPosY; + m2=y+(i/2)-gr->graphAreaPosY; + + if (_isPositionFree(m1, m2, pMask, gr->graphAreaHeight)) { + _reservePosition(m1, m2, pMask, gr->graphAreaHeight); + AQDG_Draw_Context_DrawText(gr->drawContext, gr->penAxisLabel, gr->fontTickLabel, AQDG_Direction_Horizontal, + gr->yTickLabelPosX, y-(i/2), s); + } + } + } + } + } /* if labels to be drawn */ + } /* if value within limits */ + } + t=AQDG_Graph_Tick_List_Next(t); + } /* while t */ + } /* if tickDrawFlags */ + + + } /* for level */ + + free(pMask); + } /* if tl */ +} + + + + diff --git a/src/lib/aqdiagram/graph/g_draw_xticks.h b/src/lib/aqdiagram/graph/draw.h similarity index 81% rename from src/lib/aqdiagram/graph/g_draw_xticks.h rename to src/lib/aqdiagram/graph/draw.h index 300b4f0..54a81c8 100644 --- a/src/lib/aqdiagram/graph/g_draw_xticks.h +++ b/src/lib/aqdiagram/graph/draw.h @@ -7,15 +7,15 @@ ****************************************************************************/ -#ifndef AQDG_G_DRAW_XTICKS_H -#define AQDG_G_DRAW_XTICKS_H +#ifndef AQDG_GRAPH_DRAW_H +#define AQDG_GRAPH_DRAW_H #include -void AQDG_Graph_DrawXTicks(AQDG_GRAPH *gr); +void AQDG_Graph_DrawFramework(AQDG_GRAPH *gr); #endif diff --git a/src/lib/aqdiagram/graph/g_draw_data.c b/src/lib/aqdiagram/graph/g_draw_data.c deleted file mode 100644 index ed4993a..0000000 --- a/src/lib/aqdiagram/graph/g_draw_data.c +++ /dev/null @@ -1,245 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqDiagram. - * AqDiagram (c) by 2020 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 "aqdiagram/graph/g_draw_data.h" -#include "aqdiagram/graph/dataset_fns.h" -#include "graph_p.h" - -#include - - - - - -void AQDG_Graph_DrawDataAsLine(AQDG_GRAPH *gr, int level, int penId) -{ - AQDG_GRAPH_DATAPAIR_LIST *dpl; - - dpl=AQDG_Graph_DataSet_GetDataPairList(gr->dataSet); - if (dpl) { - AQDG_GRAPH_DATAPAIR *dp; - double minValX; - double maxValX; - double minValY; - double maxValY; - int lastX; - int lastY; - int first=1; - - minValX=AQDG_Graph_DataSet_GetMinValueX(gr->dataSet); - maxValX=AQDG_Graph_DataSet_GetMaxValueX(gr->dataSet); - minValY=AQDG_Graph_DataSet_GetMinValueY(gr->dataSet); - maxValY=AQDG_Graph_DataSet_GetMaxValueY(gr->dataSet); - dp=AQDG_Graph_DataPair_List_First(dpl); - while (dp) { - if (AQDG_Graph_DataPair_GetLevel(dp)==level) { - double vX; - double vY; - int x, y; - - vX=AQDG_Graph_DataPair_GetValueX(dp); - vY=AQDG_Graph_DataPair_GetValueY(dp); - - if (vXmaxValX) - vX=maxValX; - - if (vYmaxValY) - vY=maxValY; - - x=gr->graphOriginX + (vX * gr->graphFactorX); - y=gr->graphOriginY - (vY * gr->graphFactorY); - - /* draw a small star */ - AQDG_Draw_Context_DrawLine(gr->drawContext, penId, x-3, y-3, x+3, y+3); - AQDG_Draw_Context_DrawLine(gr->drawContext, penId, x-3, y+3, x+3, y-3); - AQDG_Draw_Context_DrawLine(gr->drawContext, penId, x, y-3, x, y+3); - AQDG_Draw_Context_DrawLine(gr->drawContext, penId, x-3, y, x+3, y); - - if (!first) - AQDG_Draw_Context_DrawLine(gr->drawContext, penId, lastX, lastY, x, y); - else - first=0; - - lastX=x; - lastY=y; - } - - dp=AQDG_Graph_DataPair_List_Next(dp); - } - - } -} - - - -void AQDG_Graph_DrawDataAsBars(AQDG_GRAPH *gr, int level, int penId) -{ - AQDG_GRAPH_DATAPAIR_LIST *dpl; - double dataWidth; - int barWidth; - int rv; - - rv=AQDG_Graph_DataSet_GetMinValueDistX(gr->dataSet, level, &dataWidth); - if (rv<0) { - DBG_INFO(AQDG_LOGDOMAIN, "here (%d)", rv); - return; - } - else if (rv==1) { - /* use full width */ - barWidth=(gr->graphAreaWidth)-10; - } - else { - barWidth=((int)(dataWidth*gr->graphFactorX))-10; - } - - if (barWidth<1) - barWidth=1; - - dpl=AQDG_Graph_DataSet_GetDataPairList(gr->dataSet); - if (dpl) { - AQDG_GRAPH_DATAPAIR *dp; - double minValX; - double maxValX; - double minValY; - double maxValY; - - minValX=AQDG_Graph_DataSet_GetMinValueX(gr->dataSet); - maxValX=AQDG_Graph_DataSet_GetMaxValueX(gr->dataSet); - minValY=AQDG_Graph_DataSet_GetMinValueY(gr->dataSet); - maxValY=AQDG_Graph_DataSet_GetMaxValueY(gr->dataSet); - dp=AQDG_Graph_DataPair_List_First(dpl); - while (dp) { - if (AQDG_Graph_DataPair_GetLevel(dp)==level) { - double vX; - double vY; - int x, y; - int leftX, bw; - - vX=AQDG_Graph_DataPair_GetValueX(dp); - vY=AQDG_Graph_DataPair_GetValueY(dp); - - if (vXmaxValX) - vX=maxValX; - - if (vYmaxValY) - vY=maxValY; - - x=gr->graphOriginX + (vX * gr->graphFactorX); - y=gr->graphOriginY - (vY * gr->graphFactorY); - - /* draw the bar */ - if ((x-(barWidth/2))graphAreaPosX) { - leftX=x; - bw=barWidth/2; - } - else { - leftX=x-(barWidth/2); - bw=barWidth; - } - if ((leftX+bw)>=(gr->graphAreaPosX+gr->graphAreaWidth)) { - bw=barWidth/2; - } - - AQDG_Draw_Context_DrawFilledRect(gr->drawContext, penId, - leftX, gr->xAxisPosY, - bw, y-gr->xAxisPosY); - } - - dp=AQDG_Graph_DataPair_List_Next(dp); - } - - } -} - - - -void AQDG_Graph_DrawDataAsPoints(AQDG_GRAPH *gr, int level, int penId) -{ - AQDG_GRAPH_DATAPAIR_LIST *dpl; - double dataWidth; - int barWidth; - int rv; - - rv=AQDG_Graph_DataSet_GetMinValueDistX(gr->dataSet, level, &dataWidth); - if (rv<0) { - DBG_INFO(AQDG_LOGDOMAIN, "here (%d)", rv); - return; - } - else if (rv==1) { - /* use full width */ - barWidth=(gr->graphAreaWidth)-10; - } - else { - barWidth=((int)(dataWidth*gr->graphFactorX))-10; - } - - if (barWidth<1) - barWidth=1; - - dpl=AQDG_Graph_DataSet_GetDataPairList(gr->dataSet); - if (dpl) { - AQDG_GRAPH_DATAPAIR *dp; - double minValX; - double maxValX; - double minValY; - double maxValY; - - minValX=AQDG_Graph_DataSet_GetMinValueX(gr->dataSet); - maxValX=AQDG_Graph_DataSet_GetMaxValueX(gr->dataSet); - minValY=AQDG_Graph_DataSet_GetMinValueY(gr->dataSet); - maxValY=AQDG_Graph_DataSet_GetMaxValueY(gr->dataSet); - dp=AQDG_Graph_DataPair_List_First(dpl); - while (dp) { - if (AQDG_Graph_DataPair_GetLevel(dp)==level) { - double vX; - double vY; - int x, y; - - vX=AQDG_Graph_DataPair_GetValueX(dp); - vY=AQDG_Graph_DataPair_GetValueY(dp); - - if (vXmaxValX) - vX=maxValX; - - if (vYmaxValY) - vY=maxValY; - - x=gr->graphOriginX + (vX * gr->graphFactorX); - y=gr->graphOriginY - (vY * gr->graphFactorY); - - /* draw a small star */ - AQDG_Draw_Context_DrawLine(gr->drawContext, penId, x-3, y-3, x+3, y+3); - AQDG_Draw_Context_DrawLine(gr->drawContext, penId, x-3, y+3, x+3, y-3); - AQDG_Draw_Context_DrawLine(gr->drawContext, penId, x, y-3, x, y+3); - AQDG_Draw_Context_DrawLine(gr->drawContext, penId, x-3, y, x+3, y); - } - - dp=AQDG_Graph_DataPair_List_Next(dp); - } - - } -} - - - diff --git a/src/lib/aqdiagram/graph/g_draw_data.h b/src/lib/aqdiagram/graph/g_draw_data.h deleted file mode 100644 index 5e27848..0000000 --- a/src/lib/aqdiagram/graph/g_draw_data.h +++ /dev/null @@ -1,24 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqDiagram. - * AqDiagram (c) by 2022 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_G_DRAW_DATA_H -#define AQDG_G_DRAW_DATA_H - - -#include - - -void AQDG_Graph_DrawDataAsLine(AQDG_GRAPH *gr, int level, int penId); -void AQDG_Graph_DrawDataAsBars(AQDG_GRAPH *gr, int level, int penId); -void AQDG_Graph_DrawDataAsPoints(AQDG_GRAPH *gr, int level, int penId); - - - -#endif - diff --git a/src/lib/aqdiagram/graph/g_draw_xticks.c b/src/lib/aqdiagram/graph/g_draw_xticks.c deleted file mode 100644 index 5719e68..0000000 --- a/src/lib/aqdiagram/graph/g_draw_xticks.c +++ /dev/null @@ -1,232 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqDiagram. - * AqDiagram (c) by 2020 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 "aqdiagram/graph/g_draw_data.h" -#include "graph_p.h" - -#include - - - - -void AQDG_Graph_DrawXTicks(AQDG_GRAPH *gr) -{ - AQDG_GRAPH_TICK_LIST *tl; - - tl=AQDG_Graph_DataSet_GetXTickList(gr->dataSet); - if (tl) { - AQDG_GRAPH_TICK *t; - uint8_t *pMask; - int level; - - /* reset */ - pMask=(uint8_t *) malloc(gr->graphAreaWidth); - assert(pMask); - memset(pMask, 0, gr->graphAreaWidth); - - /* handle each level */ - for (level=1; leveldrawContext, gr->fontTickLabel, s); - if (i<0) { - DBG_ERROR(0, "Invalid text width (%d)", i); - } - else { - if (i>maxWidth) - maxWidth=i; - } - } - else { - DBG_ERROR(0, "X-Level %d: No tick label", level); - } - } - t=AQDG_Graph_Tick_List_Next(t); - } - - - /* check medium width for the current level */ - { - int first=1; - int hasSecond=0; - double lastValue; - - t=AQDG_Graph_Tick_List_First(tl); - while (t) { - if (AQDG_Graph_Tick_GetLevel(t)==level) { - double v; - - v=AQDG_Graph_Tick_GetValue(t); - if (first) { - lastValue=v; - first=0; - } - else { - int dist; - - dist=(int)((v-lastValue)*gr->graphFactorX); - if (dist>MIN_DIST_FOR_TICKS) - tickDrawFlags|=TICKDRAWFLAGS_MARKS; - if (dist>MIN_DIST_FOR_GRIDS) - tickDrawFlags|=TICKDRAWFLAGS_GRIDS; - - if (dist>maxWidth+SMALL_BORDER) { - tickDrawFlags|=TICKDRAWFLAGS_LABELS; - } - else if ((dist*2)>maxWidth+SMALL_BORDER) { - tickDrawFlags|=TICKDRAWFLAGS_LABELS; - every=2; - } - else if ((dist*4)>maxWidth+SMALL_BORDER) { - tickDrawFlags|=TICKDRAWFLAGS_LABELS; - every=4; - } - - DBG_ERROR(0, "X-Level %d: dist=%d (flags=%02x)", level, dist, tickDrawFlags); - hasSecond=1; - break; - } - } - - t=AQDG_Graph_Tick_List_Next(t); - } - if (!first && !hasSecond) { - int dist; - - dist=gr->graphAreaWidth; - if (dist>MIN_DIST_FOR_TICKS) - tickDrawFlags|=TICKDRAWFLAGS_MARKS; - if (dist>MIN_DIST_FOR_GRIDS) - tickDrawFlags|=TICKDRAWFLAGS_GRIDS; - if (dist>maxWidth+SMALL_BORDER) - tickDrawFlags|=TICKDRAWFLAGS_LABELS; - DBG_ERROR(0, "X-Level %d: dist=%d (flags=%02x)", level, dist, tickDrawFlags); - } - } - - /* now draw according to flags */ - if (tickDrawFlags) { - double minVal; - double maxVal; - int tickIntervalCnt=every; - - minVal=AQDG_Graph_DataSet_GetMinValueX(gr->dataSet); - maxVal=AQDG_Graph_DataSet_GetMaxValueX(gr->dataSet); - t=AQDG_Graph_Tick_List_First(tl); - while (t) { - if (AQDG_Graph_Tick_GetLevel(t)==level) { - double v; - - tickIntervalCnt--; - v=AQDG_Graph_Tick_GetValue(t); - if (v>=minVal && v<=maxVal) { - int x, y; - int w; - - x=gr->graphOriginX + (v * gr->graphFactorX); - y=gr->xAxisPosY; - - /* draw grid line */ - if (tickDrawFlags & TICKDRAWFLAGS_GRIDS) { - if (gr->flags & AQDG_GRAPH_FLAGS_WITH_GRID) - AQDG_Draw_Context_DrawLine(gr->drawContext, gr->penGrid, x, gr->graphAreaPosY, x, gr->graphAreaPosY+gr->graphAreaHeight); - } - - if (tickDrawFlags & TICKDRAWFLAGS_MARKS) { - switch (level) { - case 1: - w=9; - break; - case 2: - w=5; - break; - default: - case 3: - w=1; - break; - } - - /* draw tick mark */ - AQDG_Draw_Context_DrawLine(gr->drawContext, gr->penAxis, x, y-w, x, y+w); - } - - if (tickDrawFlags & TICKDRAWFLAGS_LABELS) { - const char *s; - - /* draw label */ - if (tickIntervalCnt<1) { - - s=AQDG_Graph_Tick_GetLabel(t); - if (s && *s) { - int i; - - i=AQDG_Draw_Context_GetTextWidth(gr->drawContext, gr->penAxisLabel, s); - if (i<0) { - } - else { - if ((x+(i/2) < (gr->graphAreaPosX+gr->graphAreaWidth)) && - (x-(i/2) > gr->graphAreaPosX)) { - int j; - int doesFit=1; - int m1, m2; - - m1=SMALL_BORDER+x-(i/2)-gr->graphAreaPosX; - m2=SMALL_BORDER+x+(i/2)-gr->graphAreaPosX; - - for (j=m1; jgraphAreaPosX; - m2=x+(i/2)-gr->graphAreaPosX; - - for (j=m1; jdrawContext, gr->penAxisLabel, gr->fontTickLabel, AQDG_Direction_Horizontal, - x-(i/2), gr->xTickLabelPosY, s); - } - } - } - } - tickIntervalCnt=every; - } - } /* if labels to be drawn */ - } /* if value within limits */ - } - t=AQDG_Graph_Tick_List_Next(t); - } /* while t */ - } /* if tickDrawFlags */ - - - } /* for level */ - - free(pMask); - } /* if tl */ -} - diff --git a/src/lib/aqdiagram/graph/g_draw_yticks.c b/src/lib/aqdiagram/graph/g_draw_yticks.c deleted file mode 100644 index 0d50a44..0000000 --- a/src/lib/aqdiagram/graph/g_draw_yticks.c +++ /dev/null @@ -1,214 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqDiagram. - * AqDiagram (c) by 2020 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 "aqdiagram/graph/g_draw_data.h" -#include "graph_p.h" - -#include - - - -void AQDG_Graph_DrawYTicks(AQDG_GRAPH *gr) -{ - AQDG_GRAPH_TICK_LIST *tl; - - tl=AQDG_Graph_DataSet_GetYTickList(gr->dataSet); - if (tl) { - AQDG_GRAPH_TICK *t; - uint8_t *pMask; - int level; - - /* reset */ - pMask=(uint8_t *) malloc(gr->graphAreaHeight); - assert(pMask); - memset(pMask, 0, gr->graphAreaHeight); - - /* handle each level */ - for (level=1; leveldrawContext, gr->fontTickLabel, s); - if (i<0) { - DBG_ERROR(0, "Invalid text width (%d)", i); - } - else { - if (i>maxHeight) - maxHeight=i; - } - } - else { - DBG_ERROR(0, "No tick label"); - } - } - t=AQDG_Graph_Tick_List_Next(t); - } - - - /* get 1st and 2nd entry for the current level and check width */ - { - int first=1; - int hasSecond=0; - double lastValue; - - t=AQDG_Graph_Tick_List_First(tl); - while (t) { - if (AQDG_Graph_Tick_GetLevel(t)==level) { - double v; - - v=AQDG_Graph_Tick_GetValue(t); - if (first) { - lastValue=v; - first=0; - } - else { - int dist; - - dist=(int)((v-lastValue)*gr->graphFactorY); - if (dist>MIN_DIST_FOR_TICKS) - tickDrawFlags|=TICKDRAWFLAGS_MARKS; - if (dist>MIN_DIST_FOR_GRIDS) - tickDrawFlags|=TICKDRAWFLAGS_GRIDS; - if (dist>maxHeight+5) - tickDrawFlags|=TICKDRAWFLAGS_LABELS; - DBG_ERROR(0, "Y-Level %d: dist=%d (flags=%02x)", level, dist, tickDrawFlags); - hasSecond=1; - break; - } - } - - t=AQDG_Graph_Tick_List_Next(t); - } - - if (!first && !hasSecond) { - int dist; - - dist=gr->graphAreaHeight; - if (dist>MIN_DIST_FOR_TICKS) - tickDrawFlags|=TICKDRAWFLAGS_MARKS; - if (dist>MIN_DIST_FOR_GRIDS) - tickDrawFlags|=TICKDRAWFLAGS_GRIDS; - if (dist>maxHeight+2) - tickDrawFlags|=TICKDRAWFLAGS_LABELS; - } - } - - /* now draw according to flags */ - if (tickDrawFlags) { - double minVal; - double maxVal; - - minVal=AQDG_Graph_DataSet_GetMinValueY(gr->dataSet); - maxVal=AQDG_Graph_DataSet_GetMaxValueY(gr->dataSet); - t=AQDG_Graph_Tick_List_First(tl); - while (t) { - double v; - - v=AQDG_Graph_Tick_GetValue(t); - if (AQDG_Graph_Tick_GetLevel(t)==level) { - if (v>=minVal && v<=maxVal) { - int x, y; - int w; - - x=gr->yAxisPosX; - y=gr->graphOriginY - (v * gr->graphFactorY); - - /* draw grid line */ - if (tickDrawFlags & TICKDRAWFLAGS_GRIDS) { - if (gr->flags & AQDG_GRAPH_FLAGS_WITH_GRID) - AQDG_Draw_Context_DrawLine(gr->drawContext, gr->penGrid, gr->graphAreaPosX, y, gr->graphAreaPosX+gr->graphAreaWidth, y); - } - - if (tickDrawFlags & TICKDRAWFLAGS_MARKS) { - switch (level) { - case 1: - w=9; - break; - case 2: - w=5; - break; - default: - case 3: - w=1; - break; - } - - /* draw tick mark */ - AQDG_Draw_Context_DrawLine(gr->drawContext, gr->penAxis, x-w, y, x+w, y); - } - - if (tickDrawFlags & TICKDRAWFLAGS_LABELS) { - const char *s; - - /* draw label */ - s=AQDG_Graph_Tick_GetLabel(t); - if (s && *s) { - int i; - - i=AQDG_Draw_Context_GetTextHeight(gr->drawContext, gr->penAxisLabel, s); - if (i<0) { - } - else { - if ((y+(i/2) < (gr->graphAreaPosY+gr->graphAreaHeight)) && - (y-(i/2)>= gr->graphAreaPosY)) { - int j; - int doesFit=1; - int m1, m2; - - m1=SMALL_BORDER+y-(i/2)-gr->graphAreaPosY; - m2=SMALL_BORDER+y+(i/2)-gr->graphAreaPosY; - for (j=m1; jgraphAreaPosY; - m2=y+(i/2)-gr->graphAreaPosY; - - for (j=m1; jdrawContext, gr->penAxisLabel, gr->fontTickLabel, AQDG_Direction_Horizontal, - gr->yTickLabelPosX, y-(i/2), s); - } - } - } - } - } /* if labels to be drawn */ - } /* if value within limits */ - } - t=AQDG_Graph_Tick_List_Next(t); - } /* while t */ - } /* if tickDrawFlags */ - - - } /* for level */ - - free(pMask); - } /* if tl */ -} - - - diff --git a/src/lib/aqdiagram/graph/g_draw_yticks.h b/src/lib/aqdiagram/graph/g_draw_yticks.h deleted file mode 100644 index c7fcf56..0000000 --- a/src/lib/aqdiagram/graph/g_draw_yticks.h +++ /dev/null @@ -1,22 +0,0 @@ -/**************************************************************************** - * This file is part of the project AqDiagram. - * AqDiagram (c) by 2022 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_G_DRAW_YTICKS_H -#define AQDG_G_DRAW_YTICKS_H - - -#include - - -void AQDG_Graph_DrawYTicks(AQDG_GRAPH *gr); - - - -#endif - diff --git a/src/lib/aqdiagram/graph/graph.c b/src/lib/aqdiagram/graph/graph.c index c1ffd2b..e5847d7 100644 --- a/src/lib/aqdiagram/graph/graph.c +++ b/src/lib/aqdiagram/graph/graph.c @@ -11,11 +11,9 @@ #endif #include "graph_p.h" -#include "aqdiagram/graph/g_draw_data.h" -#include "aqdiagram/graph/g_draw_xticks.h" -#include "aqdiagram/graph/g_draw_yticks.h" -#include "aqdiagram/graph/g_layout.h" -#include "aqdiagram/graph/g_config.h" +#include "aqdiagram/graph/draw.h" +#include "aqdiagram/graph/layout.h" +#include "aqdiagram/graph/setup.h" #include @@ -25,6 +23,10 @@ GWEN_LIST2_FUNCTIONS(AQDG_GRAPH, AQDG_Graph) +void AQDG_Graph_DrawDataAsBars(AQDG_GRAPH *gr, int level, int penId); +void AQDG_Graph_DrawDataAsLine(AQDG_GRAPH *gr, int level, int penId); + + AQDG_GRAPH *AQDG_Graph_new(AQDG_GRAPH_DATASET *ds, AQDG_DRAW_CONTEXT *drawContext, int width, int height) { @@ -48,77 +50,232 @@ void AQDG_Graph_free(AQDG_GRAPH *gr) if (gr) { GWEN_LIST_FINI(AQDG_GRAPH, gr) AQDG_Draw_Context_free(gr->drawContext); - AQDG_Graph_DataSet_free(gr->dataSet); GWEN_FREE_OBJECT(gr); } } -void AQDG_Graph_DrawFramework(AQDG_GRAPH *gr) +void AQDG_Graph_DrawDataAsLine(AQDG_GRAPH *gr, int level, int penId) { - const char *s; + AQDG_GRAPH_DATAPAIR_LIST *dpl; - /* draw background */ - AQDG_Draw_Context_DrawFilledRect(gr->drawContext, gr->penBackground, - 0, 0, gr->width, gr->height); + dpl=AQDG_Graph_DataSet_GetDataPairList(gr->dataSet); + if (dpl) { + AQDG_GRAPH_DATAPAIR *dp; + double minValX; + double maxValX; + double minValY; + double maxValY; + int lastX; + int lastY; + int first=1; - /* draw graph area */ - AQDG_Draw_Context_DrawFilledRect(gr->drawContext, gr->penGraphBackground, - gr->graphAreaPosX, gr->graphAreaPosY, - gr->graphAreaWidth, gr->graphAreaHeight); + minValX=AQDG_Graph_DataSet_GetMinValueX(gr->dataSet); + maxValX=AQDG_Graph_DataSet_GetMaxValueX(gr->dataSet); + minValY=AQDG_Graph_DataSet_GetMinValueY(gr->dataSet); + maxValY=AQDG_Graph_DataSet_GetMaxValueY(gr->dataSet); + dp=AQDG_Graph_DataPair_List_First(dpl); + while (dp) { + if (AQDG_Graph_DataPair_GetLevel(dp)==level) { + double vX; + double vY; + int x, y; - AQDG_Graph_DrawXTicks(gr); + vX=AQDG_Graph_DataPair_GetValueX(dp); + vY=AQDG_Graph_DataPair_GetValueY(dp); - /* draw x-axis */ - AQDG_Draw_Context_DrawLine(gr->drawContext, gr->penAxis, - gr->graphAreaPosX, gr->xAxisPosY, - gr->graphAreaPosX+gr->graphAreaWidth, gr->xAxisPosY); + if (vXmaxValX) + vX=maxValX; - /* x-axis label */ - s=AQDG_Graph_DataSet_GetLabelX(gr->dataSet); - if (s && *s) - AQDG_Draw_Context_DrawText(gr->drawContext, gr->penAxisLabel, gr->fontAxisLabel, AQDG_Direction_Horizontal, - gr->xAxisLabelPosX, gr->xAxisLabelPosY, s); + if (vYmaxValY) + vY=maxValY; + x=gr->graphOriginX + (vX * gr->graphFactorX); + y=gr->graphOriginY - (vY * gr->graphFactorY); + /* draw a small star */ + AQDG_Draw_Context_DrawLine(gr->drawContext, penId, x-3, y-3, x+3, y+3); + AQDG_Draw_Context_DrawLine(gr->drawContext, penId, x-3, y+3, x+3, y-3); + AQDG_Draw_Context_DrawLine(gr->drawContext, penId, x, y-3, x, y+3); + AQDG_Draw_Context_DrawLine(gr->drawContext, penId, x-3, y, x+3, y); + if (!first) + AQDG_Draw_Context_DrawLine(gr->drawContext, penId, lastX, lastY, x, y); + else + first=0; - /* draw y ticks */ - AQDG_Graph_DrawYTicks(gr); + lastX=x; + lastY=y; + } - /* draw y-axis */ - AQDG_Draw_Context_DrawLine(gr->drawContext, gr->penAxis, - gr->yAxisPosX, gr->graphAreaPosY, - gr->yAxisPosX, gr->graphAreaPosY+gr->graphAreaHeight); + dp=AQDG_Graph_DataPair_List_Next(dp); + } - /* y-axis label */ - s=AQDG_Graph_DataSet_GetLabelY(gr->dataSet); - if (s && *s) - AQDG_Draw_Context_DrawText(gr->drawContext, gr->penAxisLabel, gr->fontAxisLabel, AQDG_Direction_Horizontal, - gr->yAxisLabelPosX, gr->yAxisLabelPosY, s); - - - - - - - /* title */ - s=AQDG_Graph_DataSet_GetTitle(gr->dataSet); - if (s && *s) - AQDG_Draw_Context_DrawText(gr->drawContext, gr->penTitle, gr->fontTitle, AQDG_Direction_Horizontal, - gr->titlePosX, gr->titlePosY, s); - - /* subtitle */ - s=AQDG_Graph_DataSet_GetSubTitle(gr->dataSet); - if (s && *s) - AQDG_Draw_Context_DrawText(gr->drawContext, gr->penSubTitle, gr->fontSubTitle, AQDG_Direction_Horizontal, - gr->subTitlePosX, gr->subTitlePosY, s); + } } +void AQDG_Graph_DrawDataAsBars(AQDG_GRAPH *gr, int level, int penId) +{ + AQDG_GRAPH_DATAPAIR_LIST *dpl; + double dataWidth; + int barWidth; + int rv; + rv=AQDG_Graph_DataSet_GetMinValueDistX(gr->dataSet, level, &dataWidth); + if (rv<0) { + DBG_INFO(AQDG_LOGDOMAIN, "here (%d)", rv); + return; + } + else if (rv==1) { + /* use full width */ + barWidth=(gr->graphAreaWidth)-10; + } + else { + barWidth=((int)(dataWidth*gr->graphFactorX))-10; + } + + if (barWidth<1) + barWidth=1; + + dpl=AQDG_Graph_DataSet_GetDataPairList(gr->dataSet); + if (dpl) { + AQDG_GRAPH_DATAPAIR *dp; + double minValX; + double maxValX; + double minValY; + double maxValY; + + minValX=AQDG_Graph_DataSet_GetMinValueX(gr->dataSet); + maxValX=AQDG_Graph_DataSet_GetMaxValueX(gr->dataSet); + minValY=AQDG_Graph_DataSet_GetMinValueY(gr->dataSet); + maxValY=AQDG_Graph_DataSet_GetMaxValueY(gr->dataSet); + dp=AQDG_Graph_DataPair_List_First(dpl); + while (dp) { + if (AQDG_Graph_DataPair_GetLevel(dp)==level) { + double vX; + double vY; + int x, y; + int leftX, bw; + + vX=AQDG_Graph_DataPair_GetValueX(dp); + vY=AQDG_Graph_DataPair_GetValueY(dp); + + if (vXmaxValX) + vX=maxValX; + + if (vYmaxValY) + vY=maxValY; + + x=gr->graphOriginX + (vX * gr->graphFactorX); + y=gr->graphOriginY - (vY * gr->graphFactorY); + + /* draw the bar */ + if ((x-(barWidth/2))graphAreaPosX) { + leftX=x; + bw=barWidth/2; + } + else { + leftX=x-(barWidth/2); + bw=barWidth; + } + if ((leftX+bw)>=(gr->graphAreaPosX+gr->graphAreaWidth)) { + bw=barWidth/2; + } + + AQDG_Draw_Context_DrawFilledRect(gr->drawContext, penId, + leftX, gr->xAxisPosY, + bw, y-gr->xAxisPosY); + } + + dp=AQDG_Graph_DataPair_List_Next(dp); + } + + } +} + + + +void AQDG_Graph_DrawDataAsPoints(AQDG_GRAPH *gr, int level, int penId) +{ + AQDG_GRAPH_DATAPAIR_LIST *dpl; + double dataWidth; + int barWidth; + int rv; + + rv=AQDG_Graph_DataSet_GetMinValueDistX(gr->dataSet, level, &dataWidth); + if (rv<0) { + DBG_INFO(AQDG_LOGDOMAIN, "here (%d)", rv); + return; + } + else if (rv==1) { + /* use full width */ + barWidth=(gr->graphAreaWidth)-10; + } + else { + barWidth=((int)(dataWidth*gr->graphFactorX))-10; + } + + if (barWidth<1) + barWidth=1; + + dpl=AQDG_Graph_DataSet_GetDataPairList(gr->dataSet); + if (dpl) { + AQDG_GRAPH_DATAPAIR *dp; + double minValX; + double maxValX; + double minValY; + double maxValY; + + minValX=AQDG_Graph_DataSet_GetMinValueX(gr->dataSet); + maxValX=AQDG_Graph_DataSet_GetMaxValueX(gr->dataSet); + minValY=AQDG_Graph_DataSet_GetMinValueY(gr->dataSet); + maxValY=AQDG_Graph_DataSet_GetMaxValueY(gr->dataSet); + dp=AQDG_Graph_DataPair_List_First(dpl); + while (dp) { + if (AQDG_Graph_DataPair_GetLevel(dp)==level) { + double vX; + double vY; + int x, y; + + vX=AQDG_Graph_DataPair_GetValueX(dp); + vY=AQDG_Graph_DataPair_GetValueY(dp); + + if (vXmaxValX) + vX=maxValX; + + if (vYmaxValY) + vY=maxValY; + + x=gr->graphOriginX + (vX * gr->graphFactorX); + y=gr->graphOriginY - (vY * gr->graphFactorY); + + /* draw a small star */ + AQDG_Draw_Context_DrawLine(gr->drawContext, penId, x-3, y-3, x+3, y+3); + AQDG_Draw_Context_DrawLine(gr->drawContext, penId, x-3, y+3, x+3, y-3); + AQDG_Draw_Context_DrawLine(gr->drawContext, penId, x, y-3, x, y+3); + AQDG_Draw_Context_DrawLine(gr->drawContext, penId, x-3, y, x+3, y); + } + + dp=AQDG_Graph_DataPair_List_Next(dp); + } + + } +} @@ -158,10 +315,3 @@ int AQDG_Graph_Draw(AQDG_GRAPH *gr) return 0; } - - - - - - - diff --git a/src/lib/aqdiagram/graph/g_layout.c b/src/lib/aqdiagram/graph/layout.c similarity index 92% rename from src/lib/aqdiagram/graph/g_layout.c rename to src/lib/aqdiagram/graph/layout.c index d9a406e..e28cac6 100644 --- a/src/lib/aqdiagram/graph/g_layout.c +++ b/src/lib/aqdiagram/graph/layout.c @@ -1,6 +1,6 @@ /**************************************************************************** - * This file is part of the project AqDiagram. - * AqDiagram (c) by 2020 Martin Preuss, all rights reserved. + * This file is part of the project AqFinance. + * AqFinance (c) by 2011 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. @@ -10,21 +10,21 @@ # include #endif -#include "aqdiagram/graph/g_layout.h" -#include "aqdiagram/graph/tick_fns.h" +#include "aqdiagram/graph/layout.h" +//#include "aqdiagram/graph/dataset_fns.h" #include "graph_p.h" #include - -static void _getTickLabelMaxSizes(AQDG_GRAPH *gr, AQDG_GRAPH_TICK_LIST *tl, int *pMaxWidth, int *pMaxHeight); +static void _calcTickLabelMaxSizes(AQDG_GRAPH *gr, AQDG_GRAPH_TICK_LIST *tl, int *pMaxWidth, int *pMaxHeight); static void _sampleSizes(AQDG_GRAPH *gr, AQDG_GRAPH_DATASET *ds); static void _layout(AQDG_GRAPH *gr, AQDG_GRAPH_DATASET *ds); static void _calcGraphArea(AQDG_GRAPH *gr, AQDG_GRAPH_DATASET *ds); + void AQDG_Graph_PrepareGraph(AQDG_GRAPH *gr) { AQDG_GRAPH_TICK_LIST *tl; @@ -44,8 +44,7 @@ void AQDG_Graph_PrepareGraph(AQDG_GRAPH *gr) - -void _getTickLabelMaxSizes(AQDG_GRAPH *gr, AQDG_GRAPH_TICK_LIST *tl, int *pMaxWidth, int *pMaxHeight) +void _calcTickLabelMaxSizes(AQDG_GRAPH *gr, AQDG_GRAPH_TICK_LIST *tl, int *pMaxWidth, int *pMaxHeight) { if (tl) { AQDG_GRAPH_TICK *t; @@ -102,14 +101,14 @@ void _sampleSizes(AQDG_GRAPH *gr, AQDG_GRAPH_DATASET *ds) gr->xTickLabelPosY=-1; tl=AQDG_Graph_DataSet_GetXTickList(ds); if (tl) - _getTickLabelMaxSizes(gr, tl, &(gr->xTickLabelMaxWidth), &(gr->xTickLabelMaxHeight)); + _calcTickLabelMaxSizes(gr, tl, &(gr->xTickLabelMaxWidth), &(gr->xTickLabelMaxHeight)); gr->yTickLabelMaxWidth=-1; gr->yTickLabelMaxHeight=-1; gr->yTickLabelPosX=-1; tl=AQDG_Graph_DataSet_GetYTickList(ds); if (tl) - _getTickLabelMaxSizes(gr, tl, &(gr->yTickLabelMaxWidth), &(gr->yTickLabelMaxHeight)); + _calcTickLabelMaxSizes(gr, tl, &(gr->yTickLabelMaxWidth), &(gr->yTickLabelMaxHeight)); /* title */ gr->titleWidth=-1; @@ -293,7 +292,7 @@ void _calcGraphArea(AQDG_GRAPH *gr, AQDG_GRAPH_DATASET *ds) gr->xAxisPosY=gr->graphAreaPosY; } else if (gr->graphOriginY>=gr->graphAreaHeight) { - /* x-axis on lower border */ + /* y-axis on lower border */ gr->xAxisPosY=gr->graphAreaPosY+gr->graphAreaHeight-1; } else { diff --git a/src/lib/aqdiagram/graph/g_layout.h b/src/lib/aqdiagram/graph/layout.h similarity index 89% rename from src/lib/aqdiagram/graph/g_layout.h rename to src/lib/aqdiagram/graph/layout.h index 675ae06..b976b6a 100644 --- a/src/lib/aqdiagram/graph/g_layout.h +++ b/src/lib/aqdiagram/graph/layout.h @@ -7,15 +7,15 @@ ****************************************************************************/ -#ifndef AQDG_G_LAYOUT_H -#define AQDG_G_LAYOUT_H +#ifndef AQDG_GRAPH_LAYOUT_H +#define AQDG_GRAPH_LAYOUT_H #include -void AQDG_Graph_PrepareGraph(AQDG_GRAPH *gr); +void AQDG_Graph_PrepareGraph(AQDG_GRAPH *gr); #endif diff --git a/src/lib/aqdiagram/graph/g_config.c b/src/lib/aqdiagram/graph/setup.c similarity index 83% rename from src/lib/aqdiagram/graph/g_config.c rename to src/lib/aqdiagram/graph/setup.c index 476ff58..e674939 100644 --- a/src/lib/aqdiagram/graph/g_config.c +++ b/src/lib/aqdiagram/graph/setup.c @@ -1,6 +1,6 @@ /**************************************************************************** - * This file is part of the project AqDiagram. - * AqDiagram (c) by 2020 Martin Preuss, all rights reserved. + * This file is part of the project AqFinance. + * AqFinance (c) by 2011 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. @@ -10,21 +10,23 @@ # include #endif -#include "aqdiagram/graph/g_config.h" +#include "aqdiagram/graph/setup.h" +#include "aqdiagram/graph/tick_fns.h" #include "graph_p.h" #include -static int _createPenFromConfig(AQDG_GRAPH *gr, GWEN_DB_NODE *dbConfig, const char *name); -static int _createFontFromConfig(AQDG_GRAPH *gr, GWEN_DB_NODE *dbConfig, const char *name, int defaultFontSize); +static int _createPenFromDb(AQDG_GRAPH *gr, GWEN_DB_NODE *dbConfig, const char *name); +static int _createFontFromDb(AQDG_GRAPH *gr, GWEN_DB_NODE *dbConfig, const char *name, int defaultFontSize); static int _createPensAndFontsFromDb(AQDG_GRAPH *gr, GWEN_DB_NODE *dbConfig); + static int _createPenFromSettings(AQDG_GRAPH *gr, const AQDG_GRAPH_SETTINGS_PEN *sp); static int _createFontFromSettings(AQDG_GRAPH *gr, const AQDG_GRAPH_SETTINGS_FONT *sf); static int _createPensAndFontsFromSettings(AQDG_GRAPH *gr, const AQDG_GRAPH_SETTINGS *settings); -static void _releasePensAndFonts(AQDG_GRAPH *gr); +static void _releasePensAndFonts(AQDG_GRAPH *gr); @@ -83,69 +85,7 @@ int AQDG_Graph_Fini(AQDG_GRAPH *gr) -void _releasePensAndFonts(AQDG_GRAPH *gr) -{ - if (gr->penTitle>=0) { - AQDG_Draw_Context_PenRelease(gr->drawContext, gr->penTitle); - gr->penTitle=-1; - } - - if (gr->penSubTitle>=0) { - AQDG_Draw_Context_PenRelease(gr->drawContext, gr->penSubTitle); - gr->penSubTitle=-1; - } - - if (gr->penAxisLabel>=0) { - AQDG_Draw_Context_PenRelease(gr->drawContext, gr->penAxisLabel); - gr->penAxisLabel=-1; - } - - if (gr->penAxis>=0) { - AQDG_Draw_Context_PenRelease(gr->drawContext, gr->penAxis); - gr->penAxis=-1; - } - - if (gr->penGraph>=0) { - AQDG_Draw_Context_PenRelease(gr->drawContext, gr->penGraph); - gr->penGraph=-1; - } - - if (gr->penGraphBackground>=0) { - AQDG_Draw_Context_PenRelease(gr->drawContext, gr->penGraphBackground); - gr->penGraphBackground=-1; - } - - if (gr->penGrid>=0) { - AQDG_Draw_Context_PenRelease(gr->drawContext, gr->penGrid); - gr->penGrid=-1; - } - - - if (gr->fontTitle>=0) { - AQDG_Draw_Context_FontRelease(gr->drawContext, gr->fontTitle); - gr->fontTitle=-1; - } - - if (gr->fontSubTitle>=0) { - AQDG_Draw_Context_FontRelease(gr->drawContext, gr->fontSubTitle); - gr->fontSubTitle=-1; - } - - if (gr->fontAxisLabel>=0) { - AQDG_Draw_Context_FontRelease(gr->drawContext, gr->fontAxisLabel); - gr->fontAxisLabel=-1; - } - - if (gr->fontTickLabel>=0) { - AQDG_Draw_Context_FontRelease(gr->drawContext, gr->fontTickLabel); - gr->fontTickLabel=-1; - } -} - - - - -int _createPenFromConfig(AQDG_GRAPH *gr, GWEN_DB_NODE *dbConfig, const char *name) +int _createPenFromDb(AQDG_GRAPH *gr, GWEN_DB_NODE *dbConfig, const char *name) { GWEN_DB_NODE *db; uint32_t frontColour; @@ -170,7 +110,7 @@ int _createPenFromConfig(AQDG_GRAPH *gr, GWEN_DB_NODE *dbConfig, const char *nam -int _createFontFromConfig(AQDG_GRAPH *gr, GWEN_DB_NODE *dbConfig, const char *name, int defaultFontSize) +int _createFontFromDb(AQDG_GRAPH *gr, GWEN_DB_NODE *dbConfig, const char *name, int defaultFontSize) { GWEN_DB_NODE *db; const char *fontName; @@ -182,6 +122,7 @@ int _createFontFromConfig(AQDG_GRAPH *gr, GWEN_DB_NODE *dbConfig, const char *na db=GWEN_DB_GetGroup(dbConfig, 0, name); assert(db); + fontName=GWEN_DB_GetCharValue(db, "fontName", 0, ""); fontSize=GWEN_DB_GetIntValue(db, "fontSize", 0, defaultFontSize); fontSlant=AQDG_Slant_fromString(GWEN_DB_GetCharValue(db, "fontSlant", 0, "none")); @@ -204,56 +145,56 @@ int _createPensAndFontsFromDb(AQDG_GRAPH *gr, GWEN_DB_NODE *dbConfig) int rv; AQDG_GRAPH_SUBGRAPH_LIST *sgList; - rv=_createPenFromConfig(gr, dbConfig, "penTitle"); + rv=_createPenFromDb(gr, dbConfig, "penTitle"); if (rv<0) { DBG_INFO(0, "here (%d)", rv); return rv; } gr->penTitle=rv; - rv=_createPenFromConfig(gr, dbConfig, "penSubTitle"); + rv=_createPenFromDb(gr, dbConfig, "penSubTitle"); if (rv<0) { DBG_INFO(0, "here (%d)", rv); return rv; } gr->penSubTitle=rv; - rv=_createPenFromConfig(gr, dbConfig, "penAxisLabel"); + rv=_createPenFromDb(gr, dbConfig, "penAxisLabel"); if (rv<0) { DBG_INFO(0, "here (%d)", rv); return rv; } gr->penAxisLabel=rv; - rv=_createPenFromConfig(gr, dbConfig, "penAxis"); + rv=_createPenFromDb(gr, dbConfig, "penAxis"); if (rv<0) { DBG_INFO(0, "here (%d)", rv); return rv; } gr->penAxis=rv; - rv=_createPenFromConfig(gr, dbConfig, "penGraph"); + rv=_createPenFromDb(gr, dbConfig, "penGraph"); if (rv<0) { DBG_INFO(0, "here (%d)", rv); return rv; } gr->penGraph=rv; - rv=_createPenFromConfig(gr, dbConfig, "penGraphBackground"); + rv=_createPenFromDb(gr, dbConfig, "penGraphBackground"); if (rv<0) { DBG_INFO(0, "here (%d)", rv); return rv; } gr->penGraphBackground=rv; - rv=_createPenFromConfig(gr, dbConfig, "penGrid"); + rv=_createPenFromDb(gr, dbConfig, "penGrid"); if (rv<0) { DBG_INFO(0, "here (%d)", rv); return rv; } gr->penGrid=rv; - rv=_createPenFromConfig(gr, dbConfig, "penBackground"); + rv=_createPenFromDb(gr, dbConfig, "penBackground"); if (rv<0) { DBG_INFO(0, "here (%d)", rv); return rv; @@ -262,28 +203,28 @@ int _createPensAndFontsFromDb(AQDG_GRAPH *gr, GWEN_DB_NODE *dbConfig) - rv=_createFontFromConfig(gr, dbConfig, "fontTitle", 16); + rv=_createFontFromDb(gr, dbConfig, "fontTitle", 16); if (rv<0) { DBG_INFO(0, "here (%d)", rv); return rv; } gr->fontTitle=rv; - rv=_createFontFromConfig(gr, dbConfig, "fontSubTitle", 14); + rv=_createFontFromDb(gr, dbConfig, "fontSubTitle", 14); if (rv<0) { DBG_INFO(0, "here (%d)", rv); return rv; } gr->fontSubTitle=rv; - rv=_createFontFromConfig(gr, dbConfig, "fontAxisLabel", 12); + rv=_createFontFromDb(gr, dbConfig, "fontAxisLabel", 12); if (rv<0) { DBG_INFO(0, "here (%d)", rv); return rv; } gr->fontAxisLabel=rv; - rv=_createFontFromConfig(gr, dbConfig, "fontTickLabel", 10); + rv=_createFontFromDb(gr, dbConfig, "fontTickLabel", 10); if (rv<0) { DBG_INFO(0, "here (%d)", rv); return rv; @@ -299,9 +240,9 @@ int _createPensAndFontsFromDb(AQDG_GRAPH *gr, GWEN_DB_NODE *dbConfig) while (sg) { rv=AQDG_Draw_Context_PenCreate(gr->drawContext, - AQDG_Graph_SubGraph_GetColour(sg), - AQDG_Graph_SubGraph_GetLineWidth(sg), - AQDG_Graph_SubGraph_GetDashType(sg)); + AQDG_Graph_SubGraph_GetColour(sg), + AQDG_Graph_SubGraph_GetLineWidth(sg), + AQDG_Graph_SubGraph_GetDashType(sg)); if (rv<0) { DBG_INFO(0, "here (%d)", rv); return rv; @@ -318,17 +259,14 @@ int _createPensAndFontsFromDb(AQDG_GRAPH *gr, GWEN_DB_NODE *dbConfig) - - - int _createPenFromSettings(AQDG_GRAPH *gr, const AQDG_GRAPH_SETTINGS_PEN *sp) { int rv; rv=AQDG_Draw_Context_PenCreate(gr->drawContext, - AQDG_Graph_SettingsPen_GetFrontColour(sp), - AQDG_Graph_SettingsPen_GetLineWidth(sp), - AQDG_Graph_SettingsPen_GetDashType(sp)); + AQDG_Graph_SettingsPen_GetFrontColour(sp), + AQDG_Graph_SettingsPen_GetLineWidth(sp), + AQDG_Graph_SettingsPen_GetDashType(sp)); if (rv<0) { DBG_INFO(0, "here (%d)", rv); return rv; @@ -344,9 +282,9 @@ int _createFontFromSettings(AQDG_GRAPH *gr, const AQDG_GRAPH_SETTINGS_FONT *sf) int rv; rv=AQDG_Draw_Context_FontCreate(gr->drawContext, "", - AQDG_Graph_SettingsFont_GetFontSize(sf), - AQDG_Graph_SettingsFont_GetFontSlant(sf), - AQDG_Graph_SettingsFont_GetFontWeight(sf)); + AQDG_Graph_SettingsFont_GetFontSize(sf), + AQDG_Graph_SettingsFont_GetFontSlant(sf), + AQDG_Graph_SettingsFont_GetFontWeight(sf)); if (rv<0) { DBG_INFO(0, "here (%d)", rv); return rv; @@ -515,3 +453,64 @@ int _createPensAndFontsFromSettings(AQDG_GRAPH *gr, const AQDG_GRAPH_SETTINGS *s +void _releasePensAndFonts(AQDG_GRAPH *gr) +{ + if (gr->penTitle>=0) { + AQDG_Draw_Context_PenRelease(gr->drawContext, gr->penTitle); + gr->penTitle=-1; + } + + if (gr->penSubTitle>=0) { + AQDG_Draw_Context_PenRelease(gr->drawContext, gr->penSubTitle); + gr->penSubTitle=-1; + } + + if (gr->penAxisLabel>=0) { + AQDG_Draw_Context_PenRelease(gr->drawContext, gr->penAxisLabel); + gr->penAxisLabel=-1; + } + + if (gr->penAxis>=0) { + AQDG_Draw_Context_PenRelease(gr->drawContext, gr->penAxis); + gr->penAxis=-1; + } + + if (gr->penGraph>=0) { + AQDG_Draw_Context_PenRelease(gr->drawContext, gr->penGraph); + gr->penGraph=-1; + } + + if (gr->penGraphBackground>=0) { + AQDG_Draw_Context_PenRelease(gr->drawContext, gr->penGraphBackground); + gr->penGraphBackground=-1; + } + + if (gr->penGrid>=0) { + AQDG_Draw_Context_PenRelease(gr->drawContext, gr->penGrid); + gr->penGrid=-1; + } + + + + if (gr->fontTitle>=0) { + AQDG_Draw_Context_FontRelease(gr->drawContext, gr->fontTitle); + gr->fontTitle=-1; + } + + if (gr->fontSubTitle>=0) { + AQDG_Draw_Context_FontRelease(gr->drawContext, gr->fontSubTitle); + gr->fontSubTitle=-1; + } + + if (gr->fontAxisLabel>=0) { + AQDG_Draw_Context_FontRelease(gr->drawContext, gr->fontAxisLabel); + gr->fontAxisLabel=-1; + } + + if (gr->fontTickLabel>=0) { + AQDG_Draw_Context_FontRelease(gr->drawContext, gr->fontTickLabel); + gr->fontTickLabel=-1; + } +} + + diff --git a/src/lib/aqdiagram/graph/g_config.h b/src/lib/aqdiagram/graph/setup.h similarity index 88% rename from src/lib/aqdiagram/graph/g_config.h rename to src/lib/aqdiagram/graph/setup.h index 930c4ae..142b4d5 100644 --- a/src/lib/aqdiagram/graph/g_config.h +++ b/src/lib/aqdiagram/graph/setup.h @@ -7,12 +7,14 @@ ****************************************************************************/ -#ifndef AQDG_G_CONFIG_H -#define AQDG_G_CONFIG_H +#ifndef AQDG_GRAPH_SETUP_H +#define AQDG_GRAPH_SETUP_H #include + + #endif