histogram.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. /* histogram.c:
  2. * Draws a histogram along the left side of a smooth gradient legend
  3. * (stats fetching code adapted from d.histogram)
  4. *
  5. * Copyright (C) 2014 by Hamish Bowman, and the GRASS Development Team*
  6. * This program is free software under the GPL (>=v2)
  7. * Read the COPYING file that comes with GRASS for details.
  8. */
  9. #include <grass/gis.h>
  10. #include <grass/display.h>
  11. #include "local_proto.h"
  12. void draw_histogram(const char *map_name, int x0, int y0, int width,
  13. int height, int color, int flip, int horiz,
  14. int map_type, int is_fp)
  15. {
  16. int i, nsteps;
  17. long cell_count = 0;
  18. double max_width, width_mult, dx;
  19. double dy, y0_adjust; /* only needed for CELL maps */
  20. struct stat_list dist_stats;
  21. struct stat_node *ptr;
  22. if (horiz) {
  23. max_width = height * 1.75;
  24. nsteps = width - 3;
  25. }
  26. else {
  27. max_width = width * 1.75;
  28. nsteps = height - 3;
  29. }
  30. /* get the distribution statistics */
  31. get_stats(map_name, &dist_stats, nsteps, map_type);
  32. width_mult = max_width / dist_stats.maxstat;
  33. D_use_color(color);
  34. D_begin();
  35. ptr = dist_stats.ptr;
  36. if (!is_fp) {
  37. dy = (nsteps + 3.0) / (1 + dist_stats.maxcat - dist_stats.mincat);
  38. if (flip)
  39. dy *= -1;
  40. if (dist_stats.mincat == 0)
  41. y0_adjust = dy;
  42. else
  43. y0_adjust = 0;
  44. if (!flip) /* mmph */
  45. y0_adjust += 0.5;
  46. }
  47. for (i = dist_stats.mincat; i <= dist_stats.maxcat; i++) {
  48. if (!ptr)
  49. break;
  50. if (ptr->cat == i) { /* AH-HA!! found the stat */
  51. cell_count = ptr->stat;
  52. if (ptr->next != NULL)
  53. ptr = ptr->next;
  54. }
  55. else { /* we have to look for the stat */
  56. /* loop until we find it, or pass where it should be */
  57. while (ptr->cat < i && ptr->next != NULL)
  58. ptr = ptr->next;
  59. if (ptr->cat == i) { /* AH-HA!! found the stat */
  60. cell_count = ptr->stat;
  61. if (ptr->next != NULL)
  62. ptr = ptr->next;
  63. }
  64. else /* stat cannot be found */
  65. G_debug(4, "No matching stat found, i=%d", i);
  66. }
  67. if (!cell_count)
  68. continue;
  69. dx = cell_count * width_mult;
  70. if (is_fp) {
  71. if (horiz) {
  72. if (flip)
  73. D_move_abs(x0 + width - i - 1, y0 - 1);
  74. else
  75. D_move_abs(x0 + i + 1, y0 - 1);
  76. D_cont_rel(0, -dx);
  77. }
  78. else { /* vertical */
  79. if (flip)
  80. D_move_abs(x0 - 1, y0 - 1 + height - i);
  81. else
  82. D_move_abs(x0 - 1, y0 + 1 + i);
  83. D_cont_rel(-dx, 0);
  84. }
  85. }
  86. else { /* categorical */
  87. if (horiz) {
  88. if (flip)
  89. D_box_abs(x0 + width + y0_adjust + ((i - 1) * dy),
  90. y0 - 1,
  91. x0 + width + y0_adjust + 1 + (i * dy),
  92. y0 - 1 - dx);
  93. else
  94. D_box_abs(x0 + y0_adjust + ((i - 1) * dy),
  95. y0 - 1,
  96. x0 - 1 + y0_adjust + (i * dy),
  97. y0 - 1 - dx);
  98. }
  99. else { /* vertical */
  100. if (flip)
  101. /* GRASS_EPSILON fudge around D_box_abs() weirdness + PNG driver */
  102. D_box_abs(x0 - 1 - GRASS_EPSILON * 10,
  103. y0 + height + y0_adjust + ((i - 1) * dy),
  104. x0 - 1 - dx,
  105. y0 + height + y0_adjust + 1 + (i * dy));
  106. else
  107. D_box_abs(x0 - 1 - GRASS_EPSILON * 10,
  108. y0 + y0_adjust + ((i - 1) * dy),
  109. x0 - 1 - dx,
  110. y0 + y0_adjust - 1 + (i * dy));
  111. }
  112. }
  113. }
  114. D_close();
  115. D_end();
  116. D_stroke();
  117. }