float wvutilsConvertRainINToMetric (float inches) { if (IsMetricRainMM) { return wvutilsConvertINToMM(inches); } else { return wvutilsConvertINToCM(inches); } }
static void drawGrid (MULTICHART_ID id) { register int i; int xlabelwidth = 0, ylabelwidth = 0; double units, step; double minR, stepR; int dataPoints, xnumhash, xhashindexlen; double hashwidth, xhashwidth; int numhash, x, y; char text[64][32], ylabelfmt[24]; char textR[64][32], ylabelfmtR[24]; // ... calculate the maximum number of hash marks and the units per hash // ... for the x-axis // build labels and calculate the maximum x-label width for (i = 0; i < id->numpoints; i ++) { if (strlen (id->pointnames[i]) > xlabelwidth) xlabelwidth = strlen (id->pointnames[i]); } xhashwidth = (xlabelwidth*gdFontSmall->h)/2; dataPoints = id->numpoints - 1; if (strlen (id->DualUnit) > 0) { // ((gdFontSmall->h/2) * strlen (id->DualUnit)))/2) - 2 id->imbx -= (gdFontMediumBold->h); if ((strcmp(id->DualUnit,"inches") == 0) || (strcmp(id->DualUnit,"knots") == 0) || (strcmp(id->DualUnit,"m/s") == 0)) id->imbx -= 7; } // see if a suggestion was given if (id->xnumhashes != 0) { xnumhash = id->xnumhashes; } else { xnumhash = (id->imbx - id->imtx)/xhashwidth; // try to normalize the number of hashmarks // try with the endpoint removed for (i = 1; i < dataPoints/2; i ++) { if (dataPoints % i != 0) continue; if (dataPoints/i <= xnumhash) { xnumhash = dataPoints/i; break; } } } xhashwidth = (double)(id->imbx - id->imtx)/(double)xnumhash; id->pointpixels = (double)(id->imbx - id->imtx)/(double)dataPoints; xhashindexlen = dataPoints/xnumhash; // ... calculate the maximum number of hash marks and the units per hash // ... for the y-axis hashwidth = (gdFontSmall->h * 3)/2; numhash = (id->imby - id->imty)/hashwidth; if (numhash > 64) numhash = 64; units = (id->max - id->min)/id->ystepSize; step = id->ystepSize; i = 0; while ((int)units > numhash && i < MAX_STEP_MULTIPLIER) { step = id->ystepSize * stepSizeMultipliers[i]; units = (id->max - id->min)/step; i ++; } id->ystepSize = step; numhash = (int)units; if ((id->min + (id->ystepSize * numhash)) < id->max) { numhash ++; } hashwidth = (double)(id->imby - id->imty)/(double)numhash; id->max = id->min + (id->ystepSize * numhash); id->ypixelconstant = (double)(id->imby - id->imty)/(double)(id->max - id->min); numhash ++; if (numhash > 64) numhash = 64; // build labels and calculate the maximum y-label width sprintf (ylabelfmt, "%%.%1.1df", id->ydecPlaces); for (i = 0; i < numhash; i ++) { sprintf (text[i], ylabelfmt, id->min + (i * id->ystepSize)); // now fill the right hand array with alternate scale @Rcm if (strlen(id->DualUnit) > 0) { textR[i][0] = ' '; if (strcmp(id->DualUnit,"C") == 0) { minR = wvutilsConvertFToC (id->min); stepR = ((id->ystepSize) * (5.0/9.0)); sprintf (textR[i], "%.1f", minR + (i * stepR)); } else if (strcmp(id->DualUnit,"F") == 0) { minR = wvutilsConvertCToF (id->min); stepR = ((id->ystepSize) * (9.0/5.0)); sprintf (textR[i], "%.1f", minR + (i * stepR)); } else if (strcmp(id->DualUnit,"mm") == 0) { minR = wvutilsConvertINToMM (id->min); stepR = wvutilsConvertINToMM (id->ystepSize); if (wvutilsConvertINToMM (id->max) >= 100) sprintf (textR[i], "%.0f", minR + (i * stepR)); else sprintf (textR[i], "%.1f", minR + (i * stepR)); } else if (strcmp(id->DualUnit,"inches") == 0) { minR = wvutilsConvertMMToIN (id->min); stepR = wvutilsConvertMMToIN (id->ystepSize); if (wvutilsConvertMMToIN (id->max) >= 100) sprintf (textR[i], "%.0f", minR + (i * stepR)); else sprintf (textR[i], "%.1f", minR + (i * stepR)); } else if (strcmp(id->DualUnit,"km/h") == 0) { minR = wvutilsConvertMilesToKilometers (id->min); stepR = wvutilsConvertMilesToKilometers (id->ystepSize); sprintf (textR[i], "%.0f", minR + (i * stepR)); } else if (strcmp(id->DualUnit,"mph") == 0) { minR = wvutilsConvertKilometersToMiles (id->min); stepR = wvutilsConvertKilometersToMiles (id->ystepSize); sprintf (textR[i], "%.0f", minR + (i * stepR)); } else if (strcmp(id->title,"m/s") == 0) { if (id->isMetric) { minR = wvutilsConvertMPSToKPH (id->min); stepR = wvutilsConvertMPSToKPH (id->ystepSize); sprintf (textR[i], "%.0f", minR + (i * stepR)); } else { minR = wvutilsConvertMPSToMPH (id->min); stepR = wvutilsConvertMPSToMPH (id->ystepSize); sprintf (textR[i], "%.0f", minR + (i * stepR)); } } else if (strcmp(id->title,"knots") == 0) { if (id->isMetric) { minR = wvutilsConvertKnotsToKPH (id->min); stepR = wvutilsConvertKnotsToKPH (id->ystepSize); sprintf (textR[i], "%.0f", minR + (i * stepR)); } else { minR = wvutilsConvertKnotsToMPH (id->min); stepR = wvutilsConvertKnotsToMPH (id->ystepSize); sprintf (textR[i], "%.0f", minR + (i * stepR)); } } else //all else: eg '%' or watts/m^2 (hum/ rad) { // same value both sides minR = id->min * 25.4; stepR = id->ystepSize * 25.4; sprintf (textR[i], "%s", text[i]); } if (strlen (text[i]) > ylabelwidth) ylabelwidth = strlen (text[i])+2; } else { if (strlen (text[i]) > ylabelwidth) ylabelwidth = strlen (text[i]); } } // ... now we know the chart area, draw it gdImageFilledRectangle (id->im, id->imtx - GLC_CONTENTS_OFFSET, id->imty - GLC_CONTENTS_OFFSET, id->imbx + GLC_CONTENTS_OFFSET, id->imby + GLC_CONTENTS_OFFSET, id->chartcolor); gdImageRectangle (id->im, id->imtx, id->imty, id->imbx, id->imby, id->gridcolor); // ... draw the y-axis gdImageSetThickness (id->im, 1); for (i = 0; i < numhash; i ++) { y = id->imby - (i * hashwidth); gdImageLine (id->im, id->imtx, y, id->imbx, y, id->gridcolor); y -= gdFontSmall->h/2; gdImageString (id->im, gdFontSmall, (id->imtx - 5) - (strlen(text[i]) * gdFontSmall->h/2), y, (UCHAR *)text[i], id->textcolor); if (strlen(id->DualUnit) > 0 ) { // right side x = id->imbx + (GLC_CONTENTS_OFFSET - 2); gdImageString (id->im, gdFontSmall, x + gdFontSmall->h/2, y, (UCHAR *)textR[i], id->textcolor); } } // ... draw the x-axis gdImageSetThickness (id->im, 1); for (i = 0; i <= xnumhash; i ++) // one more for right-most { int dataPoint = i * xhashindexlen; x = id->imtx + (i * xhashwidth); gdImageLine (id->im, x, id->imty, x, id->imby, id->gridcolor); if (strlen(id->pointnames[dataPoint]) < 2) x -= gdFontSmall->h/4; gdImageString (id->im, gdFontSmall, x - ((gdFontSmall->h/2) * (strlen(id->pointnames[dataPoint])/2)), (id->height - (3 * gdFontMediumBold->h)) + 4, (UCHAR *)id->pointnames[dataPoint], id->textcolor); } // ... finally, draw date gdImageString (id->im, gdFontSmall, ((id->width - ((gdFontSmall->h/2) * strlen (id->datetime)))/2) - 2, id->height - (gdFontMediumBold->h + 2), (UCHAR *)id->datetime, id->textcolor); }