@@ -144,49 +144,50 @@ static WindowDesc _graph_legend_desc(
WDP_AUTO, "graph_legend", 0, 0,
WC_GRAPH_LEGEND, WC_NONE,
0,
_nested_graph_legend_widgets, lengthof(_nested_graph_legend_widgets)
);
static void ShowGraphLegend()
{
AllocateWindowDescFront<GraphLegendWindow>(&_graph_legend_desc, 0);
}
/** Contains the interval of a graph's data. */
struct ValuesInterval {
OverflowSafeInt64 highest; ///< Highest value of this interval. Must be zero or greater.
OverflowSafeInt64 lowest; ///< Lowest value of this interval. Must be zero or less.
};
/******************/
/* BASE OF GRAPHS */
/*****************/
struct BaseGraphWindow : Window {
protected:
static const int GRAPH_MAX_DATASETS = 64;
static const int GRAPH_AXIS_LINE_COLOUR = PC_BLACK;
static const int GRAPH_AXIS_LINE_COLOUR = GREY_SCALE(1);
static const int GRAPH_ZERO_LINE_COLOUR = GREY_SCALE(8);
static const int GRAPH_NUM_MONTHS = 24; ///< Number of months displayed in the graph.
static const int MIN_GRAPH_NUM_LINES_Y = 9; ///< Minimal number of horizontal lines to draw.
static const int MIN_GRID_PIXEL_SIZE = 20; ///< Minimum distance between graph lines.
uint64 excluded_data; ///< bitmask of the datasets that shouldn't be displayed.
byte num_dataset;
byte num_on_x_axis;
byte num_vert_lines;
static const TextColour graph_axis_label_colour = TC_BLACK; ///< colour of the graph axis label.
/* The starting month and year that values are plotted against. If month is
* 0xFF, use x_values_start and x_values_increment below instead. */
byte month;
Year year;
/* These values are used if the graph is being plotted against values
* rather than the dates specified by month and year. */
uint16 x_values_start;
uint16 x_values_increment;
int graph_widget;
StringID format_str_y_axis;
byte colours[GRAPH_MAX_DATASETS];
@@ -271,49 +272,49 @@ protected:
Dimension d = GetStringBoundingBox(STR_GRAPH_Y_LABEL);
if (d.width > max_width) max_width = d.width;
y_label -= y_label_separation;
return max_width;
/**
* Actually draw the graph.
* @param r the rectangle of the data field of the graph
*/
void DrawGraph(Rect r) const
uint x, y; ///< Reused whenever x and y coordinates are needed.
ValuesInterval interval; ///< Interval that contains all of the graph data.
int x_axis_offset; ///< Distance from the top of the graph to the x axis.
/* the colours and cost array of GraphDrawer must accommodate
* both values for cargo and companies. So if any are higher, quit */
static_assert(GRAPH_MAX_DATASETS >= (int)NUM_CARGO && GRAPH_MAX_DATASETS >= (int)MAX_COMPANIES);
assert(this->num_vert_lines > 0);
byte grid_colour = _colour_gradient[COLOUR_GREY][4];
byte grid_colour = GREY_SCALE(3);
/* Rect r will be adjusted to contain just the graph, with labels being
* placed outside the area. */
r.top += 5 + GetCharacterHeight(FS_SMALL) / 2;
r.bottom -= (this->month == 0xFF ? 1 : 3) * GetCharacterHeight(FS_SMALL) + 4;
r.left += 9;
r.right -= 5;
/* Initial number of horizontal lines. */
int num_hori_lines = 160 / MIN_GRID_PIXEL_SIZE;
/* For the rest of the height, the number of horizontal lines will increase more slowly. */
int resize = (r.bottom - r.top - 160) / (2 * MIN_GRID_PIXEL_SIZE);
if (resize > 0) num_hori_lines += resize;
interval = GetValuesInterval(num_hori_lines);
int label_width = GetYLabelWidth(interval, num_hori_lines);
r.left += label_width;
int x_sep = (r.right - r.left) / this->num_vert_lines;
int y_sep = (r.bottom - r.top) / num_hori_lines;
/* Redetermine right and bottom edge of graph to fit with the integer
@@ -331,49 +332,49 @@ protected:
/* Draw the vertical grid lines. */
/* Don't draw the first line, as that's where the axis will be. */
x = r.left + x_sep;
for (int i = 0; i < this->num_vert_lines; i++) {
GfxFillRect(x, r.top, x, r.bottom, grid_colour);
x += x_sep;
/* Draw the horizontal grid lines. */
y = r.bottom;
for (int i = 0; i < (num_hori_lines + 1); i++) {
GfxFillRect(r.left - 3, y, r.left - 1, y, GRAPH_AXIS_LINE_COLOUR);
GfxFillRect(r.left, y, r.right, y, grid_colour);
y -= y_sep;
/* Draw the y axis. */
GfxFillRect(r.left, r.top, r.left, r.bottom, GRAPH_AXIS_LINE_COLOUR);
/* Draw the x axis. */
y = x_axis_offset + r.top;
GfxFillRect(r.left, y, r.right, y, GRAPH_AXIS_LINE_COLOUR);
GfxFillRect(r.left, y, r.right, y, GRAPH_ZERO_LINE_COLOUR);
/* Find the largest value that will be drawn. */
if (this->num_on_x_axis == 0) return;
assert(this->num_on_x_axis > 0);
assert(this->num_dataset > 0);
/* draw text strings on the y axis */
int64 y_label = interval.highest;
int64 y_label_separation = abs(interval.highest - interval.lowest) / num_hori_lines;
y = r.top - GetCharacterHeight(FS_SMALL) / 2;
SetDParam(0, this->format_str_y_axis);
SetDParam(1, y_label);
DrawString(r.left - label_width - 4, r.left - 4, y, STR_GRAPH_Y_LABEL, graph_axis_label_colour, SA_RIGHT);
y += y_sep;
/* draw strings on the x axis */
if (this->month != 0xFF) {
Status change: