1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
|
#include "colorscale.h"
const double ColorScale::BAR_WIDTH = 15.0;
ColorScale::ColorScale()
: _plotWidth(0.0),
_plotHeight(0.0),
_topMargin(0.0),
_scaleWidth(0.0),
_width(0.0),
_textOnLeft(false),
_verticalPlotScale() {
_verticalPlotScale.SetUnitsCaption("z");
}
void ColorScale::initWidth(const Cairo::RefPtr<Cairo::Context>& cairo) {
if (_width == 0.0) {
_textHeight = _verticalPlotScale.GetTickTextHeight(cairo);
const double scaleHeight = _plotHeight - 2.0 * _textHeight - _topMargin;
_verticalPlotScale.SetPlotDimensions(_plotWidth, scaleHeight, 0.0,
!_textOnLeft);
_scaleWidth = _verticalPlotScale.GetWidth(cairo);
_width = _scaleWidth + BAR_WIDTH;
}
}
void ColorScale::Draw(const Cairo::RefPtr<Cairo::Context>& cairo) {
initWidth(cairo);
const double textHeight = _verticalPlotScale.GetTickTextHeight(cairo);
const double scaleTop = _topMargin + textHeight;
const double scaleHeight = _plotHeight - 2.0 * textHeight - _topMargin;
ColorValue backValue;
if (!_colorValues.empty()) {
backValue = _colorValues.begin()->second;
} else {
backValue.red = 1.0;
backValue.green = 1.0;
backValue.blue = 1.0;
}
const double barX =
_textOnLeft ? (_plotWidth - _width + _scaleWidth) : (_plotWidth - _width);
cairo->rectangle(barX, scaleTop, BAR_WIDTH, scaleHeight);
cairo->set_source_rgb(backValue.red, backValue.green, backValue.blue);
cairo->fill();
const double min = _verticalPlotScale.GetTickRangeMin();
const double max = _verticalPlotScale.GetTickRangeMax();
for (const std::pair<const double, ColorValue>& item : _colorValues) {
double val;
if (_verticalPlotScale.IsLogarithmic()) {
const double minLog10 = std::log10(min);
if (item.first <= 0.0)
val = 0.0;
else
val =
(std::log10(item.first) - minLog10) / (std::log10(max) - minLog10);
} else {
val = (item.first - min) / (max - min);
if (val < 0.0) val = 0.0;
if (val > 1.0) val = 1.0;
}
const double height = scaleHeight * (1.0 - val);
const ColorValue& color = item.second;
cairo->set_source_rgb(color.red, color.green, color.blue);
cairo->rectangle(barX, scaleTop, BAR_WIDTH, height);
cairo->fill();
}
cairo->rectangle(barX, scaleTop, BAR_WIDTH, scaleHeight);
cairo->set_source_rgb(0.0, 0.0, 0.0);
cairo->stroke();
const double scaleX =
_textOnLeft ? (_plotWidth - _width) : (_plotWidth - _width + BAR_WIDTH);
_verticalPlotScale.Draw(cairo, scaleX, _topMargin + textHeight);
}
|