Medical Imaging Interaction Toolkit  2018.4.99-389bf124
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 (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include <qpainter.h>
14 #include <qwt_painter.h>
15 #include <qwt_plot.h>
16 #include <qwt_scale_map.h>
17 
18 #include "QmitkHistogram.h"
19 
20 class QmitkHistogram::HistogramData
21 {
22 public:
23  QwtIntervalSeriesData data;
24  QColor color;
25  double reference;
26 };
27 
28 QmitkHistogram::QmitkHistogram(const QwtText &title) : QwtPlotItem(title)
29 {
30  init();
31 }
32 
33 QmitkHistogram::QmitkHistogram(const QString &title) : QwtPlotItem(QwtText(title))
34 {
35  init();
36 }
37 
39 {
40  delete m_Data;
41 }
42 
43 void QmitkHistogram::init()
44 {
45  m_Data = new HistogramData();
46  m_Data->reference = 0.0;
47 
48  setItemAttribute(QwtPlotItem::AutoScale, true);
49  setItemAttribute(QwtPlotItem::Legend, true);
50 
51  setZ(20.0);
52 }
53 
54 void QmitkHistogram::setBaseline(double reference)
55 {
56  if (m_Data->reference != reference)
57  {
58  m_Data->reference = reference;
59  itemChanged();
60  }
61 }
62 
64 {
65  return m_Data->reference;
66 }
67 
68 void QmitkHistogram::setData(const QwtIntervalSeriesData &data)
69 {
70  m_Data->data.setSamples(data.samples());
71  itemChanged();
72 }
73 
74 const QwtIntervalSeriesData &QmitkHistogram::data() const
75 {
76  return m_Data->data;
77 }
78 
79 void QmitkHistogram::setColor(const QColor &color)
80 {
81  if (m_Data->color != color)
82  {
83  m_Data->color = color;
84  itemChanged();
85  }
86 }
87 
88 QColor QmitkHistogram::color() const
89 {
90  return m_Data->color;
91 }
92 
94 {
95  QRectF rect = m_Data->data.boundingRect();
96  if (!rect.isValid())
97  return rect;
98 
99  if (rect.bottom() < m_Data->reference)
100  rect.setBottom(m_Data->reference);
101  else if (rect.top() > m_Data->reference)
102  rect.setTop(m_Data->reference);
103 
104  return rect;
105 }
106 
107 void QmitkHistogram::draw(QPainter *painter, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const
108 {
109  const QwtIntervalSeriesData &iData = m_Data->data;
110 
111  painter->setPen(QPen(m_Data->color));
112 
113  const int y0 = yMap.transform(baseline());
114 
115  for (int i = 0; i < (int)iData.size(); i++)
116  {
117  const int y2 = yMap.transform(iData.sample(i).value);
118  if (y2 == y0)
119  continue;
120 
121  int x1 = xMap.transform(iData.sample(i).interval.minValue());
122  int x2 = xMap.transform(iData.sample(i).interval.maxValue());
123  if (x1 > x2)
124  qSwap(x1, x2);
125 
126  if (i < (int)iData.size() - 2)
127  {
128  const int xx1 = xMap.transform(iData.sample(i + 1).interval.minValue());
129  const int xx2 = xMap.transform(iData.sample(i + 1).interval.maxValue());
130 
131  if (x2 == qMin(xx1, xx2))
132  {
133  const int yy2 = yMap.transform(iData.sample(i + 1).value);
134  if (yy2 != y0 && ((yy2 < y0 && y2 < y0) || (yy2 > y0 && y2 > y0)))
135  {
136  // One pixel distance between neighbored bars
137  x2--;
138  }
139  }
140  }
141  drawBar(painter, Qt::Vertical, QRect(x1, y0, x2 - x1, y2 - y0));
142  }
143 }
144 
145 void QmitkHistogram::drawBar(QPainter *painter, Qt::Orientation, const QRect &rect) const
146 {
147  painter->save();
148 
149  const QColor color(painter->pen().color());
150  const QRect r = rect.normalized();
151  const int factor = 125;
152  const QColor light(color.light(factor));
153  const QColor dark(color.dark(factor));
154 
155  painter->setBrush(color);
156  painter->setPen(Qt::NoPen);
157  QwtPainter::drawRect(painter, r.x() + 1, r.y() + 1, r.width() - 2, r.height() - 2);
158  painter->setBrush(Qt::NoBrush);
159 
160  painter->setPen(QPen(light, 2));
161 
162  QwtPainter::drawLine(painter, r.left() + 1, r.top() + 2, r.right() + 1, r.top() + 2);
163 
164  painter->setPen(QPen(dark, 2));
165 
166  QwtPainter::drawLine(painter, r.left() + 1, r.bottom(), r.right() + 1, r.bottom());
167 
168  painter->setPen(QPen(light, 1));
169 
170  QwtPainter::drawLine(painter, r.left(), r.top() + 1, r.left(), r.bottom());
171  QwtPainter::drawLine(painter, r.left() + 1, r.top() + 2, r.left() + 1, r.bottom() - 1);
172 
173  painter->setPen(QPen(dark, 1));
174 
175  QwtPainter::drawLine(painter, r.right() + 1, r.top() + 1, r.right() + 1, r.bottom());
176  QwtPainter::drawLine(painter, r.right(), r.top() + 2, r.right(), r.bottom() - 1);
177 
178  painter->restore();
179 }
const QwtIntervalSeriesData & data() const
void setColor(const QColor &)
void draw(QPainter *, const QwtScaleMap &xMap, const QwtScaleMap &yMap, const QRectF &) const override
QmitkHistogram(const QString &title=QString::null)
QRectF boundingRect() const override
void setData(const QwtIntervalSeriesData &data)
~QmitkHistogram() override
double baseline() const
QColor color() const
virtual void drawBar(QPainter *, Qt::Orientation o, const QRect &) const
void setBaseline(double reference)