Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
QmitkHistogram.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include <qpainter.h>
18 #include <qwt_painter.h>
19 #include <qwt_plot.h>
20 #include <qwt_scale_map.h>
21 
22 #include "QmitkHistogram.h"
23 
24 class QmitkHistogram::HistogramData
25 {
26 public:
27  QwtIntervalSeriesData data;
28  QColor color;
29  double reference;
30 };
31 
32 QmitkHistogram::QmitkHistogram(const QwtText &title) : QwtPlotItem(title)
33 {
34  init();
35 }
36 
37 QmitkHistogram::QmitkHistogram(const QString &title) : QwtPlotItem(QwtText(title))
38 {
39  init();
40 }
41 
43 {
44  delete m_Data;
45 }
46 
47 void QmitkHistogram::init()
48 {
49  m_Data = new HistogramData();
50  m_Data->reference = 0.0;
51 
52  setItemAttribute(QwtPlotItem::AutoScale, true);
53  setItemAttribute(QwtPlotItem::Legend, true);
54 
55  setZ(20.0);
56 }
57 
58 void QmitkHistogram::setBaseline(double reference)
59 {
60  if (m_Data->reference != reference)
61  {
62  m_Data->reference = reference;
63  itemChanged();
64  }
65 }
66 
68 {
69  return m_Data->reference;
70 }
71 
72 void QmitkHistogram::setData(const QwtIntervalSeriesData &data)
73 {
74  m_Data->data.setSamples(data.samples());
75  itemChanged();
76 }
77 
78 const QwtIntervalSeriesData &QmitkHistogram::data() const
79 {
80  return m_Data->data;
81 }
82 
83 void QmitkHistogram::setColor(const QColor &color)
84 {
85  if (m_Data->color != color)
86  {
87  m_Data->color = color;
88  itemChanged();
89  }
90 }
91 
92 QColor QmitkHistogram::color() const
93 {
94  return m_Data->color;
95 }
96 
98 {
99  QRectF rect = m_Data->data.boundingRect();
100  if (!rect.isValid())
101  return rect;
102 
103  if (rect.bottom() < m_Data->reference)
104  rect.setBottom(m_Data->reference);
105  else if (rect.top() > m_Data->reference)
106  rect.setTop(m_Data->reference);
107 
108  return rect;
109 }
110 
111 void QmitkHistogram::draw(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const
112 {
113  const QwtIntervalSeriesData &iData = m_Data->data;
114 
115  painter->setPen(QPen(m_Data->color));
116 
117  const int y0 = yMap.transform(baseline());
118 
119  for (int i = 0; i < (int)iData.size(); i++)
120  {
121  const int y2 = yMap.transform(iData.sample(i).value);
122  if (y2 == y0)
123  continue;
124 
125  int x1 = xMap.transform(iData.sample(i).interval.minValue());
126  int x2 = xMap.transform(iData.sample(i).interval.maxValue());
127  if (x1 > x2)
128  qSwap(x1, x2);
129 
130  if (i < (int)iData.size() - 2)
131  {
132  const int xx1 = xMap.transform(iData.sample(i + 1).interval.minValue());
133  const int xx2 = xMap.transform(iData.sample(i + 1).interval.maxValue());
134 
135  if (x2 == qMin(xx1, xx2))
136  {
137  const int yy2 = yMap.transform(iData.sample(i + 1).value);
138  if (yy2 != y0 && ((yy2 < y0 && y2 < y0) || (yy2 > y0 && y2 > y0)))
139  {
140  // One pixel distance between neighbored bars
141  x2--;
142  }
143  }
144  }
145  drawBar(painter, Qt::Vertical, QRect(x1, y0, x2 - x1, y2 - y0));
146  }
147 }
148 
149 void QmitkHistogram::drawBar(QPainter *painter, Qt::Orientation, const QRect &rect) const
150 {
151  painter->save();
152 
153  const QColor color(painter->pen().color());
154  const QRect r = rect.normalized();
155  const int factor = 125;
156  const QColor light(color.light(factor));
157  const QColor dark(color.dark(factor));
158 
159  painter->setBrush(color);
160  painter->setPen(Qt::NoPen);
161  QwtPainter::drawRect(painter, r.x() + 1, r.y() + 1, r.width() - 2, r.height() - 2);
162  painter->setBrush(Qt::NoBrush);
163 
164  painter->setPen(QPen(light, 2));
165 
166  QwtPainter::drawLine(painter, r.left() + 1, r.top() + 2, r.right() + 1, r.top() + 2);
167 
168  painter->setPen(QPen(dark, 2));
169 
170  QwtPainter::drawLine(painter, r.left() + 1, r.bottom(), r.right() + 1, r.bottom());
171 
172  painter->setPen(QPen(light, 1));
173 
174  QwtPainter::drawLine(painter, r.left(), r.top() + 1, r.left(), r.bottom());
175  QwtPainter::drawLine(painter, r.left() + 1, r.top() + 2, r.left() + 1, r.bottom() - 1);
176 
177  painter->setPen(QPen(dark, 1));
178 
179  QwtPainter::drawLine(painter, r.right() + 1, r.top() + 1, r.right() + 1, r.bottom());
180  QwtPainter::drawLine(painter, r.right(), r.top() + 2, r.right(), r.bottom() - 1);
181 
182  painter->restore();
183 }
virtual void drawBar(QPainter *, Qt::Orientation o, const QRect &) const
QColor color() const
void setColor(const QColor &)
virtual void draw(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const override
virtual ~QmitkHistogram()
QmitkHistogram(const QString &title=QString::null)
virtual QRectF boundingRect() const override
void setData(const QwtIntervalSeriesData &data)
const QwtIntervalSeriesData & data() const
void setBaseline(double reference)
double baseline() const