/*
* mygraph.c
*
* My Graph - source file
*
* Author: Filip Kinovic
* Version: 1.1
* Date: 12.10.2006
*/
/* --- NOTES ---
1) erase graph-background by myself.....................OK
2) set graph-background color...........................OK
3) calculate min & max (auto range).....................OK
4) line out of plot area ??.............................OK
5) auto axis-style (format "%x.ylf")....................OK
6) more types (void *x)
7) function for getting/setting graph's parameters......OK
8) zoom in, out
9) time axis............................................OK (need time estimation yet)
10) limit of ticks for interger data (when too few)
11) function for getting/setting plot's parameters......OK
12) font parameter for rotated text.....................OK
13) legend..............................................OK
14) remove flickering...................................OK
15) thick dotted line...................................OK
16) function for manual ticks and ticklabels
17) more line styles (stem, stairs, ...)
18) print better test page (+abort print dialog)
19) better full automatic ticks.........................OK
20) scaling graph.......................................OK
21) scaling plots.......................................OK
22) unicode ??
23) cursors.............................................OK
24) getting values by mouse position....................OK
25) optimize plotting of many values....................OK
26) optimize plotting (recalculate and draw only if needed; internal draw)
27) make MY_GRAPH as Registered WindowClass!!!!!
*/
#include <windows.h>
#include <stdio.h>
#include <stdarg.h>
//#include <locale.h>
#include <math.h>
#include "useful.h"
#include "mytime.h"
#include "mygraph.h"
//#define MGG_DEBUG
#define MGG_PLOTLONG //???
#define MGG_BORDERSPACE 2
#define MGG_TITLESPACE 6
#define MGG_LABELSPACE 4
#define MGG_TICKLENGTH 3
#define MGG_TICKSPACE MGG_TICKLENGTH+2
#define MGG_LEGENDOUTSPACE 2
#define MGG_LEGENDXSPACE 8
#define MGG_LEGENDYSPACE 2
#define MGG_LEGENDMARKWIDTH 20
#define MGG_LEGENDMARKHEIGTH 6
#define MGG_DEF_LINEWIDTH 0.4
#define MGG_DEF_PLOTLINEWIDTH 0.6
#define MGG_DEF_PLOTPOINTSIZE 4.0
#define DEF_BORDER_VISIBLE TRUE
#define DEF_TITLE_VISIBLE TRUE
#define DEF_XLABEL_VISIBLE TRUE
#define DEF_YLABEL_VISIBLE TRUE
#define DEF_XGRID_VISIBLE TRUE
#define DEF_YGRID_VISIBLE TRUE
#define DEF_LEGEND_VISIBLE TRUE
#define DEF_FONTNAME TEXT("Arial")
#define MGG_DEF_TITLE TEXT("Graph title")
#define MGG_DEF_XLABEL TEXT("X-axis")
#define MGG_DEF_YLABEL TEXT("Y-axis")
#define MGG_DEF_PLOTNAME TEXT("Plot")
#define MGG_DEF_LEGPOSITION MGG_LEGPOS_IN_UPLEFT
//macros
#define MGG_SCALE(x, mx, mo) (((x)*(mx)+(mo)))
//#define MGG_XSPACENESS 2.0
//#define MGG_YSPACENESS 1.7
#define MGG_XSPACENESS 1.5 //insawcom
#define MGG_YSPACENESS 1.7 //insawcom
const TCHAR *MGG_cStrOutOfSpace = TEXT("Enlarge window!");
//********************************************************************
//*** function creates graph __structure, initiates it and returns MGG_HGRAPH
//style format for numeric type corespond to format of printf()
//style format for time type:
//%h, %0h --> hour (e.g. 2, 02)
//%m, %0m --> minutes (e.g. 2, 02)
//%s, %0s --> seconds (e.g. 2, 02)
//%w, %0w, %1w --> weekday (e.g. 2, Ut, Utery; 0=Nedele)
//%d, %0d --> day (e.g. 2, 02)
//%M, %0M, %1M, %2M, %3M --> month (e.g. 2, 02, Unor, Unora, Uno)
//%y, %0y --> year (e.g. 2004, 04)
MGG_HGRAPH MGG_CreateGraph(HWND hwnd, RECT r, TCHAR *title,
MGGTYPE xtype, TCHAR *xstyle,
MGGTYPE ytype, TCHAR *ystyle, BOOL idraw)
{
MGGGRAPH *gg;
HDC hDC;
//allocate graph
if ((gg = (MGGGRAPH *)malloc(sizeof(MGGGRAPH))) == NULL)
return(NULL);
memset(gg, 0, sizeof(MGGGRAPH));
//default values
gg->r = r;
gg->owner = hwnd;
gg->idraw = idraw;
gg->pwidth = MGG_DEF_LINEWIDTH;
gg->trueplot = TRUE; //???
//--- border ---
gg->border.visible = DEF_BORDER_VISIBLE;
gg->border.color = MGC_COLOR_BLACK; //black
gg->border.bgcolor = MGC_COLOR_WHITE; //white
gg->border.space = MGG_BORDERSPACE; //default space
//--- title ---
if (title == NULL) {
gg->title.visible = DEF_TITLE_VISIBLE;
title = (TCHAR *)MGG_DEF_TITLE;
}
else
gg->title.visible = TRUE;
if ((gg->title.text = (TCHAR *)malloc((__strlen(title)+1)*sizeof(TCHAR))) == NULL)
return(NULL); //out of memory
__strcpy(gg->title.text, title);
gg->title.color = MGC_COLOR_BLACK; //black
//font
gg->title.font.height = 14;
gg->title.font.tflag = FW_BOLD;
gg->title.font.angle = 0; //only horizontal (0, 1800)
__strcpy(gg->title.font.name, DEF_FONTNAME);
//x-axis
gg->xa.visible = TRUE;
if (xtype > mggTIME)
xtype = mggINT;
gg->xa.type = xtype;
gg->xa.min = 0.0;
gg->xa.max = 100.0;
//x-axis-label
gg->xa.label.visible = DEF_XLABEL_VISIBLE;
if ((gg->xa.label.text = (TCHAR *)malloc((__strlen(MGG_DEF_XLABEL)+1)*sizeof(TCHAR))) == NULL)
return(NULL); //out of memory
__strcpy(gg->xa.label.text, MGG_DEF_XLABEL);
gg->xa.label.color = MGC_COLOR_BLACK; //black
//font
gg->xa.label.font.height = 14;
gg->xa.label.font.tflag = FW_NORMAL;
gg->xa.label.font.angle = 0;
__strcpy(gg->xa.label.font.name, DEF_FONTNAME);
//x-axis-ticks
//grid
gg->xa.ticks.grid = DEF_XGRID_VISIBLE;
gg->xa.ticks.color = MGC_COLOR_BLACK; //black
//font
gg->xa.ticks.font.height = 12;
gg->xa.ticks.font.tflag = FW_NORMAL;
gg->xa.ticks.font.angle = 0;
__strcpy(gg->xa.ticks.font.name, DEF_FONTNAME);
//test style
if (xstyle == NULL) {
switch(xtype) {
case mggINT: xstyle = (TCHAR *)TEXT("%d"); break;
case mggUINT: xstyle = (TCHAR *)TEXT("%u"); break;
// case mggDOUBLE: xstyle = (TCHAR *)TEXT("%g"); break;
case mggDOUBLE: xstyle = (TCHAR *)TEXT(""); break;
case mggTIME: xstyle = (TCHAR *)TEXT("%0h:%0m:%0s %d.%M.%y"); break;
}
}
__strncpy(gg->xa.ticks.style, xstyle, MGC_STYLETEXT_LEN-1);
*(gg->xa.ticks.style+MGC_STYLETEXT_LEN-1) = '\0';
//y-axis
gg->ya.visible = TRUE;
if (ytype > mggTIME)
ytype = mggINT;
gg->ya.type = ytype;
gg->ya.min = 0.0;
gg->ya.max = 100.0;
//y-axis-label
gg->ya.label.visible = DEF_YLABEL_VISIBLE;
if ((gg->ya.label.text = (TCHAR *)malloc((__strlen(MGG_DEF_YLABEL)+1)*sizeof(TCHAR))) == NULL)
return(NULL); //out of memory
__strcpy(gg->ya.label.text, MGG_DEF_YLABEL);
gg->ya.label.color = MGC_COLOR_BLACK; //black
//font
gg->ya.label.font.height = 14;
gg->ya.label.font.tflag = FW_NORMAL;
gg->ya.label.font.angle = 900;
__strcpy(gg->ya.label.font.name, DEF_FONTNAME);
//y-axis-ticks
//grid
gg->ya.ticks.grid = DEF_YGRID_VISIBLE;
gg->ya.ticks.color = MGC_COLOR_BLACK; //black
//font
gg->ya.ticks.font.height = 12;
gg->ya.ticks.font.tflag = FW_NORMAL;
gg->ya.ticks.font.angle = 0;
__strcpy(gg->ya.ticks.font.name, DEF_FONTNAME);
//test style
if (ystyle == NULL) {
switch(ytype) {
case mggINT: ystyle = (TCHAR *)TEXT("%d"); break;
case mggUINT: ystyle = (TCHAR *)TEXT("%u"); break;
// case mggDOUBLE: ystyle = (TCHAR *)TEXT("%g"); break;
case mggDOUBLE: ystyle = (TCHAR *)TEXT(""); break;
case mggTIME: ystyle = (TCHAR *)TEXT("%0h:%0m:%0s %d.%M.%y"); break;
}
}
__strncpy(gg->ya.ticks.style, ystyle, MGC_STYLETEXT_LEN-1);
*(gg->ya.ticks.style+MGC_STYLETEXT_LEN-1) = '\0';
//legend
gg->legend.visible = DEF_LEGEND_VISIBLE;
gg->legend.pos = MGG_DEF_LEGPOSITION;
gg->legend.color = MGC_COLOR_BLACK; //black
gg->legend.bgcolor = MGC_COLOR_WHITE; //white
gg->legend.font.height = 12;
gg->legend.font.tflag = FW_NORMAL;
gg->legend.font.angle = 0;
__strcpy(gg->legend.font.name, DEF_FONTNAME);
//scale
gg->sc.mx = 1.0;
gg->sc.ox = 0.0;
gg->sc.my = 1.0;
gg->sc.oy = 0.0;
//------------------------
/*
//create graphic device
hDC = CreateDC(TEXT("DISPLAY"), N
- 1
- 2
- 3
前往页