MTGA plots in SVG format.
501 {
502 int verbose=0;
if(status!=NULL) verbose=status->
verbose;
503 if(verbose>0) {printf("%s(MTAC, '%s', '%s')\n", __func__, main_title, fname); fflush(stdout);}
504
505 if(mtac==NULL || mtac->
nr<1) {
508 }
509 if(fname==NULL ||
strnlen(fname, 1)<1) {
512 }
513 if(status!=NULL && status->
forgiving==0) {
514
515 }
516 if(verbose>1) {printf(
"%d plot(s)\n", mtac->
nr); fflush(stdout);}
517
518
519 int is_label=0;
if(mtac->
nr>1) is_label=1;
520
521
522 double minx=nan(""), maxx=nan(""), miny=nan(""), maxy=nan(""), maxly=nan("");
523 for(
int i=0; i<mtac->
nr; i++) {
525 double x1, x2, y1, y2;
527 if(isfinite(x1) && !(x1>minx)) minx=x1;
528 if(isfinite(x2) && !(x2<maxx)) maxx=x2;
529 if(
tacYRange(mtac->
tac+i, -1, &y1, &y2, NULL, NULL, NULL, NULL)!=0)
continue;
530 if(isfinite(y1) && !(y1>miny)) miny=y1;
531 if(isfinite(y2) && !(y2<maxy)) maxy=y2;
532
533 if(
tacYRange(mtac->
tac+i, 2, &y1, &y2, NULL, NULL, NULL, NULL)!=0)
continue;
534 if(isfinite(y2) && !(y2<maxly)) maxly=y2;
535 }
536 if(verbose>1) {
537 printf("x-range := %g - %g\n", minx, maxx);
538 printf("y-range := %g - %g (%g for the line)\n", miny, maxy, maxly);
539 }
540 if(!(maxx>minx) || !(maxy>miny)) {
543 }
544
545 {
546 double yrange=maxy-miny;
547 double ylim=maxly+0.025*yrange;
548 if(maxy>ylim) maxy=ylim;
549 if(verbose>2) printf(" yrange := %g\n ylim := %g\n maxy := %g\n", yrange, ylim, maxy);
550 }
551
552
553 struct svg_viewports viewports; svg_init_viewports(&viewports);
554 viewports.x.min=minx; viewports.x.max=maxx;
555 viewports.y.min=miny; viewports.y.max=maxy;
556 viewports.label_area_viewport.is=is_label;
557
558
559 if(svg_calculate_axes(&viewports, verbose-3)) {
562 }
563
564
565 char x_title[64], y_title[64];
566 strcpy(x_title, ""); strcpy(y_title, "");
567
568
569 if(svg_define_viewports(0, 0, strlen(main_title), strlen(y_title),
570 strlen(x_title), is_label, &viewports, verbose-3))
571 {
574 }
575
576
577 FILE *fp=svg_initiate(fname, 0, 0, &viewports, NULL, verbose-3);
578 if(fp==NULL) {
581 }
582
583
584
585 if(svg_create_main_title(fp, main_title, "", &viewports, NULL,verbose-3)) {
586 fclose(fp);
589 }
590 if(svg_create_yaxis_title(fp, y_title, &viewports, NULL, verbose-3)) {
591 fclose(fp);
594 }
595 if(svg_create_xaxis_title(fp, x_title, &viewports, NULL, verbose-3)) {
596 fclose(fp);
599 }
600
601
602 if(svg_start_plot_viewport(fp, &viewports, NULL, verbose-3)) {
603 fclose(fp);
606 }
607
608
609 if(svg_start_coordinate_viewport(fp, &viewports, NULL, verbose-3)) {
610 fclose(fp);
613 }
614
615
616 if(svg_write_axes(fp, &viewports, NULL, verbose-3)) {
617 fclose(fp);
620 }
621
622
623
624
625
626 SVG_LEGENDS legends; svg_init_legends(&legends);
627
628 int max_color_nr=0; while(svgColorName(max_color_nr)!=NULL) max_color_nr++;
629 if(verbose>3) {printf("max_color_nr := %d\n", max_color_nr); fflush(stdout);}
630 int color_nr;
if(mtac->
nr==1) color_nr=0;
else color_nr=1;
631 int max_symbol_nr=0; while(svgSymbolName(max_symbol_nr)!=NULL) max_symbol_nr++;
632 if(verbose>3) printf("max_symbol_nr := %d\n", max_symbol_nr);
633 int n=0, symbol_nr=0;
634 for(
int ri=0; ri<mtac->
nr; ri++) {
636 char tac_id[32], tac_title[64];
637 sprintf(tac_id, "plot_%d", n);
638 strcpy(tac_title, mtac->
tac[ri].
c[0].
name);
639
640
641
642 int ret=svg_write_tac(fp, &viewports, 2, tac_id, tac_title,
644 svgColorName(color_nr%max_color_nr), symbol_nr%max_symbol_nr, SYMBOLOPEN,
645 NULL, verbose-3);
646 if(!ret) ret=svg_write_tac(fp, &viewports, 2, tac_id, tac_title,
648 svgColorName(color_nr%max_color_nr), symbol_nr%max_symbol_nr, SYMBOLFILLED,
649 NULL, verbose-3);
650
651 if(!ret) ret=svg_write_tac(fp, &viewports, 1, tac_id, tac_title,
653 svgColorName(color_nr%max_color_nr), symbol_nr%max_symbol_nr, SYMBOLOPEN,
654 NULL, verbose-3);
655 if(ret) {
656 svg_legend_empty(&legends); fclose(fp);
659 }
660
661
662
663 if(is_label!=0) {
664 unsigned int ci, si;
665 if(max_color_nr<1) ci=0; else ci=color_nr % max_color_nr;
666 if(max_symbol_nr<1) si=0; else si=symbol_nr % max_symbol_nr;
667 svg_legend_add(&legends, 0, si, SYMBOLFILLED, ci, tac_title);
668 }
669
670 color_nr++; n++;
671 if(color_nr==max_color_nr) color_nr=0;
672 }
673
674
675
676
677 if(svg_end_coordinate_viewport(fp, NULL, verbose-3)) {
678 fclose(fp); svg_legend_empty(&legends);
681 }
682
683
684 if(svg_write_xticks(fp, &viewports, NULL, verbose-3)!=0 ||
685 svg_write_yticks(fp, &viewports, NULL, verbose-3)!=0)
686 {
687 fclose(fp); svg_legend_empty(&legends);
690 }
691
692
693 if(svg_end_plot_viewport(fp, NULL, verbose-3)) {
694 fclose(fp); svg_legend_empty(&legends);
697 }
698
699
700 if(viewports.label_area_viewport.is!=0) {
701 if(verbose>2) {printf("creating plot legends\n"); fflush(stdout);}
702 int ret=svg_create_legends(fp, &viewports, &legends, NULL, verbose-3);
703 if(ret) {
704 fclose(fp); svg_legend_empty(&legends);
707 }
708 }
709 svg_legend_empty(&legends);
710
711
712 if(svg_close(fp, NULL, verbose-3)) {
713 fclose(fp);
716 }
717
720}
void statusSet(TPCSTATUS *s, const char *func, const char *srcfile, int srcline, tpcerror error)
size_t strnlen(const char *s, size_t n)
char name[MAX_TACNAME_LEN+1]
int verbose
Verbose level, used by statusPrint() etc.
int forgiving
Force level, 0 for strict tests for data units etc.
int tacSampleXRange(TAC *d, double *xmin, double *xmax)
Get the range of x values (times) in TAC structure.
int tacYRange(TAC *d, int i, double *ymin, double *ymax, int *smin, int *smax, int *imin, int *imax)
Get the range of y values (concentrations) in TAC struct.
@ TPCERROR_INVALID_VALUE
Invalid value.
@ TPCERROR_INVALID_FILENAME
Invalid file name.
@ TPCERROR_NO_DATA
File contains no data.
@ TPCERROR_CANNOT_WRITE
Cannot write file.