Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
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