#include #include #include #include #include "GdCharts.h" void createChart(std::string filename, ChartPrices const &prices, int width, int height) { assert(width >= 1); assert(height >= 1); gdImagePtr im = gdImageCreate(width, height); assert(im); /*int background =*/ gdImageColorAllocate(im, 0, 0, 0); const int count = std::min((int)prices.size(), width); if (count) { const double newest = prices[0]; const double oldest = prices[count - 1]; double lowest = newest; double highest = newest; for (int i = 1; i < count; i++) { double current = prices[i]; lowest = std::min(lowest, current); highest = std::max(highest, current); } if (lowest == highest) { highest = highest + 1; lowest = lowest - 1; // Technically this could still fail for large numbers! } int topColor; int bodyColor; if (oldest > newest) { // Red topColor = gdImageColorAllocate(im, 0xff, 0, 0); bodyColor = gdImageColorAllocate(im, 0x80, 0x14, 0x14); } else if (oldest < newest) { // Green topColor = gdImageColorAllocate(im, 0, 0xff, 0); bodyColor = gdImageColorAllocate(im, 0, 0x80, 0); } else { // Grey topColor = gdImageColorAllocate(im, 0xc0, 0xc0, 0xc0); bodyColor = gdImageColorAllocate(im, 0x60, 0x60, 0x60); } for (int i = 0; i < count; i++) { int lineTop = (int)((highest - prices[i]) / (highest - lowest) * height); // Ideally we don't need this, but there might be a round off // error. if (lineTop < 0) lineTop = 0; else if (lineTop >= height) lineTop = height - 1; const int imageX = width - i - 1; gdImageSetPixel(im, imageX, lineTop, topColor); gdImageLine(im, imageX, lineTop + 1, imageX, height, bodyColor); } } FILE *file = fopen(filename.c_str(), "wb"); assert(file); gdImageGif(im, file); fclose(file); gdImageDestroy(im); }; #ifdef GD_CHARTS_UNIT_TEST // Build with g++ -DGD_CHARTS_UNIT_TEST -lgd GdCharts.C int main(int, char **) { ChartPrices prices; for (int i = 0; i < 19; i++) prices.push_back(sin(i * 0.314159)); prices.push_back(prices[0]); createChart("full_sine_wave.gif", prices, 20); createChart("quarter_sine_wave.gif", prices, 5); createChart("three_quarter_sine_wave.gif", prices, 15); createChart("extra_space.gif", prices, 30); } #endif