TPCCLIB
Loading...
Searching...
No Matches
histplot.c
Go to the documentation of this file.
1
5/*****************************************************************************/
6#include "tpcclibConfig.h"
7/*****************************************************************************/
8#include <stdio.h>
9#include <stdlib.h>
10#include <math.h>
11#include <time.h>
12#include <string.h>
13/*****************************************************************************/
14#include "tpcextensions.h"
15#include "tpctac.h"
16#include "libtpcsvg.h"
17/*****************************************************************************/
18#include "tpctacmod.h"
19/*****************************************************************************/
20
21/*****************************************************************************/
23extern int SVG_INLINE;
24/*****************************************************************************/
32 TAC *d,
34 const char *main_title,
36 const double x1,
38 const double x2,
40 const double y1,
42 const double y2,
44 const char *fname,
46 TPCSTATUS *status
47) {
48 if(status==NULL) return TPCERROR_FAIL;
49 if(status->verbose>1)
50 printf("%s(tac, '%s', %g, %g, %g, %g, '%s')\n", __func__, main_title, x1, x2, y1, y2, fname);
51 if(d==NULL || d->sampleNr<1 || d->tacNr<1) {
52 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_NO_DATA); return(status->error);}
53 if(fname==NULL || strnlen(fname, 1)<1) {
54 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_FILENAME); return(status->error);}
55
56 /* Determine the plot min and max x and y values */
57 double minx, maxx, miny, maxy, tx1, tx2, ty1, ty2;
58 if(tacSampleXRange(d, &tx1, &tx2)) {
59 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_XRANGE); return(status->error);}
60 minx=tx1; maxx=tx2;
61 if(minx>0.0) {double f=maxx-minx; minx-=0.05*f; if(minx<0.0) minx=0.0;}
62 if(isfinite(x1)) minx=x1;
63 if(isfinite(x2)) maxx=x2;
64 if(status->verbose>1) {printf(" minx := %g\n maxx := %g\n", minx, maxx); fflush(stdout);}
65 /* Determine the plot min and max y values inside the x range */
66 if(tacYRangeInXRange(d, 0, minx, maxx, &ty1, &ty2, NULL, NULL, NULL, NULL)) {
67 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_XRANGE); return(status->error);}
68// if(ty1>0.0) ty1=0.0;
69// if(ty2<0.0) ty2=0.0;
70 miny=ty1; maxy=ty2;
71 if(miny>0.0) {double f=maxy-miny; miny-=0.05*f; if(miny<0.0) miny=0.0;}
72 else if(maxy<0.0) maxy=0.0;
73 if(isfinite(y1)) miny=y1;
74 if(isfinite(y2)) maxy=y2;
75 if(status->verbose>1) {printf(" miny := %g\n maxy := %g\n", miny, maxy); fflush(stdout);}
76
77 /* Calculate the axis ticks */
78 struct svg_viewports viewports; svg_init_viewports(&viewports);
79 viewports.x.min=minx; viewports.x.max=maxx;
80 viewports.y.min=miny; viewports.y.max=maxy;
81 viewports.label_area_viewport.is=0; // no plot legends
82 if(svg_calculate_axes(&viewports, status->verbose-1)) {
83 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE); return(status->error);}
84
85 /* Set the plot window and window area sizes */
86 if(svg_define_viewports(0, 0, strlen(main_title), 0, 0, 0, &viewports, status->verbose-1)) {
87 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_INVALID_VALUE); return(status->error);}
88
89 /* Initiate graphics file */
90 FILE *fp=svg_initiate(fname, 0, 0, &viewports, NULL, status->verbose-1);
91 if(fp==NULL) {
92 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_OPEN); return(status->error);}
93
94 /* Put the graph titles into their own viewports */
95 if(svg_create_main_title(fp, main_title, "", &viewports, NULL, status->verbose-2)) {
96 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
97 fclose(fp); return(status->error);
98 }
99 /* Put the plot into its own viewport */
100 if(svg_start_plot_viewport(fp, &viewports, NULL, status->verbose-2)) {
101 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
102 fclose(fp); return(status->error);
103 }
104 /* Start coordinate area viewport */
105 if(svg_start_coordinate_viewport(fp, &viewports, NULL, status->verbose-3)) {
106 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
107 fclose(fp); return(status->error);
108 }
109 /* Write plot axes */
110 if(svg_write_axes(fp, &viewports, NULL, status->verbose-3)) {
111 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
112 fclose(fp); return(status->error);
113 }
114
115 /*
116 * Draw the data
117 */
118 char ilc[9], tmp[1024];
119 if(SVG_INLINE) strcpy(ilc, "svg:"); else strcpy(ilc, "");
120 /* Initiate the data object group */
121 sprintf(tmp, "\n<%sg stroke=\"black\" stroke-width=\"25\" fill=\"black\">\n", ilc);
122 if(svg_write(fp, tmp, NULL, status->verbose-5)!=0) {
123 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
124 fclose(fp); return(status->error);
125 }
126 if(d->isframe==0) { // vertical lines
127 /* Open the path */
128 sprintf(tmp, "<%spath fill=\"none\" d=\"", ilc);
129 svg_write(fp, tmp, NULL, status->verbose-5);
130 for(int i=0; i<d->sampleNr; i++) {
131 if(!isfinite(d->x[i]) || !isfinite(d->c[0].y[i])) continue;
132 double nx1, ny1, nx2, ny2;
133 nx1=nx2=viewports.x.origo+d->x[i]*viewports.x.scale;
134 ny1=viewports.coordinate_area_viewport.h-(viewports.y.origo+viewports.y.scale*0.0);
135 ny2=viewports.coordinate_area_viewport.h-(viewports.y.origo+viewports.y.scale*d->c[0].y[i]);
136 /* Do not plot if x is outside viewport */
137 if(nx1<0 && nx2<=0) continue;
138 if(nx1>viewports.coordinate_area_viewport.w+1 || nx1>viewports.coordinate_area_viewport.w+1)
139 continue;
140 /* Do not plot if both y's are outside viewport */
141 if((ny1<0 || ny2>viewports.coordinate_area_viewport.h+1) &&
142 (ny2<0 || ny1>viewports.coordinate_area_viewport.h+1)) continue;
143 /* Set y limit to the viewport border */
144 if(ny1<0) ny1=0.0; else if(ny2<0) ny2=0.0;
145 if(ny1>viewports.coordinate_area_viewport.h+1) ny1=viewports.coordinate_area_viewport.h+1;
146 else if(ny2>viewports.coordinate_area_viewport.h+1) ny2=viewports.coordinate_area_viewport.h+1;
147 /* Draw */
148 sprintf(tmp, " M%.0f %.0f L%.0f %.0f", nx1, ny1, nx2, ny2);
149 svg_write(fp, tmp, NULL, status->verbose-5);
150 }
151 /* Close the path */
152 strcpy(tmp, "\" />\n");
153 svg_write(fp, tmp, NULL, status->verbose-5);
154 } else { // rectangles
155 for(int i=0; i<d->sampleNr; i++) {
156 if(!isfinite(d->x[i]) || !isfinite(d->c[0].y[i])) continue;
157 double nx1, ny1, nx2, ny2;
158 nx1=viewports.x.origo+d->x1[i]*viewports.x.scale;
159 nx2=viewports.x.origo+d->x2[i]*viewports.x.scale;
160 ny1=viewports.coordinate_area_viewport.h-(viewports.y.origo+viewports.y.scale*0.0);
161 ny2=viewports.coordinate_area_viewport.h-(viewports.y.origo+viewports.y.scale*d->c[0].y[i]);
162 /* Do not plot if x is outside viewport */
163 if(nx1<0 && nx2<=0) continue;
164 if(nx1>viewports.coordinate_area_viewport.w+1 || nx1>viewports.coordinate_area_viewport.w+1)
165 continue;
166 /* Do not plot if both y's are outside viewport */
167 if((ny1<0 || ny2>viewports.coordinate_area_viewport.h+1) &&
168 (ny2<0 || ny1>viewports.coordinate_area_viewport.h+1)) continue;
169 /* Set y limit to the viewport border */
170 if(ny1<0) ny1=0.0; else if(ny2<0) ny2=0.0;
171 if(ny1>viewports.coordinate_area_viewport.h+1) ny1=viewports.coordinate_area_viewport.h+1;
172 else if(ny2>viewports.coordinate_area_viewport.h+1) ny2=viewports.coordinate_area_viewport.h+1;
173 if(ny1>ny2) {double f=ny1; ny1=ny2; ny2=f;}
174 /* Draw */
175 sprintf(tmp, " <rect x=\"%.0f\" y=\"%.0f\" width=\"%.0f\" height=\"%.0f\" />\n",
176 nx1, ny1, nx2-nx1, fabs(ny2-ny1));
177 svg_write(fp, tmp, NULL, status->verbose-5);
178 }
179 }
180 /* Close the data object group */
181 sprintf(tmp, "</%sg>\n", ilc);
182 if(svg_write(fp, tmp, NULL, status->verbose-5)!=0) {
183 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
184 fclose(fp); return(status->error);
185 }
186
187 /* Close the coordinate viewport */
188 if(svg_end_coordinate_viewport(fp, NULL, status->verbose-1)) {
189 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
190 fclose(fp); return(status->error);
191 }
192
193 /* Write the axis ticks */
194 if(svg_write_xticks(fp, &viewports, NULL, status->verbose-3)!=0 ||
195 svg_write_yticks(fp, &viewports, NULL, status->verbose-3)!=0) {
196 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
197 fclose(fp); return(status->error);
198 }
199
200 /* Close the plot viewport */
201 if(svg_end_plot_viewport(fp, NULL, status->verbose-2)) {
202 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
203 fclose(fp); return(status->error);
204 }
205
206 /* Close the SVG file */
207 if(svg_close(fp, NULL, status->verbose-1)) {
208 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_CANNOT_WRITE);
209 fclose(fp); return(status->error);
210 }
211
212 if(status->verbose>0) fprintf(stdout, " written file %s\n", fname);
213
214 statusSet(status, __func__, __FILE__, __LINE__, TPCERROR_OK);
215 return(TPCERROR_OK);
216}
217/*****************************************************************************/
218
219/*****************************************************************************/
int SVG_INLINE
int tacPlotHistogramSVG(TAC *d, const char *main_title, const double x1, const double x2, const double y1, const double y2, const char *fname, TPCSTATUS *status)
Definition histplot.c:30
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
Definition statusmsg.c:142
size_t strnlen(const char *s, size_t n)
Definition stringext.c:566
double * y
Definition tpctac.h:75
Definition tpctac.h:87
double * x
Definition tpctac.h:97
int sampleNr
Definition tpctac.h:89
int isframe
Definition tpctac.h:95
TACC * c
Definition tpctac.h:117
double * x2
Definition tpctac.h:101
double * x1
Definition tpctac.h:99
int tacNr
Definition tpctac.h:91
int verbose
Verbose level, used by statusPrint() etc.
tpcerror error
Error code.
int tacSampleXRange(TAC *d, double *xmin, double *xmax)
Get the range of x values (times) in TAC structure.
Definition tacx.c:162
int tacYRangeInXRange(TAC *d, int i, const double xmin, const double xmax, double *ymin, double *ymax, int *smin, int *smax, int *imin, int *imax)
Get the range of y values (concentrations) in TAC struct, including only samples with x (times) insid...
Definition tacy.c:99
Header file for library libtpcextensions.
@ TPCERROR_INVALID_XRANGE
Invalid sample time range.
@ TPCERROR_INVALID_VALUE
Invalid value.
@ TPCERROR_FAIL
General error.
@ TPCERROR_CANNOT_OPEN
Cannot open file.
@ TPCERROR_OK
No error.
@ TPCERROR_INVALID_FILENAME
Invalid file name.
@ TPCERROR_NO_DATA
File contains no data.
@ TPCERROR_CANNOT_WRITE
Cannot write file.
Header file for library libtpctac.
Header file for libtpctacmod.