4 #include "qwt_painter.h"
5 #include "qwt_double_interval.h"
6 #include "qwt_scale_map.h"
7 #include "qwt_color_map.h"
8 #include "plot_waterfall.h"
10 #if QT_VERSION < 0x040000
11 typedef Q3ValueVector<QRgb> QwtColorTable;
13 typedef QVector<QRgb> QwtColorTable;
17 class PlotWaterfallImage: public QImage
19 // This class hides some Qt3/Qt4 API differences
21 PlotWaterfallImage(const QSize &size, QwtColorMap::Format format):
22 #if QT_VERSION < 0x040000
23 QImage(size, format == QwtColorMap::RGB ? 32 : 8)
25 QImage(size, format == QwtColorMap::RGB
26 ? QImage::Format_ARGB32 : QImage::Format_Indexed8 )
31 PlotWaterfallImage(const QImage &other):
36 void initColorTable(const QImage& other)
38 #if QT_VERSION < 0x040000
39 const unsigned int numColors = other.numColors();
41 setNumColors(numColors);
42 for ( unsigned int i = 0; i < numColors; i++ )
43 setColor(i, other.color(i));
45 setColorTable(other.colorTable());
49 #if QT_VERSION < 0x040000
51 void setColorTable(const QwtColorTable &colorTable)
53 setNumColors(colorTable.size());
54 for ( unsigned int i = 0; i < colorTable.size(); i++ )
55 setColor(i, colorTable[i]);
58 QwtColorTable colorTable() const
60 QwtColorTable table(numColors());
61 for ( int i = 0; i < numColors(); i++ )
69 class PlotWaterfall::PrivateData
75 colorMap = new QwtLinearColorMap();
83 QwtColorMap *colorMap;
87 Sets the following item attributes:
88 - QwtPlotItem::AutoScale: true
89 - QwtPlotItem::Legend: false
91 The z value is initialized by 8.0.
95 \sa QwtPlotItem::setItemAttribute(), QwtPlotItem::setZ()
97 PlotWaterfall::PlotWaterfall(WaterfallData* data, const QString &title):
98 QwtPlotRasterItem(title)
100 d_data = new PrivateData();
103 // setCachePolicy(QwtPlotRasterItem::PaintCache);
105 setItemAttribute(QwtPlotItem::AutoScale, true);
106 setItemAttribute(QwtPlotItem::Legend, false);
112 PlotWaterfall::~PlotWaterfall()
117 const WaterfallData* PlotWaterfall::data()const{
121 //! \return QwtPlotItem::Rtti_PlotSpectrogram
122 int PlotWaterfall::rtti() const
124 return QwtPlotItem::Rtti_PlotSpectrogram;
130 Often it is useful to display the mapping between intensities and
131 colors as an additional plot axis, showing a color bar.
133 \param colorMap Color Map
135 \sa colorMap(), QwtScaleWidget::setColorBarEnabled(),
136 QwtScaleWidget::setColorMap()
138 void PlotWaterfall::setColorMap(const QwtColorMap &colorMap)
140 delete d_data->colorMap;
141 d_data->colorMap = colorMap.copy();
148 \return Color Map used for mapping the intensity values to colors
151 const QwtColorMap &PlotWaterfall::colorMap() const
153 return *d_data->colorMap;
156 \return Bounding rect of the data
157 \sa QwtRasterData::boundingRect
159 QwtDoubleRect PlotWaterfall::boundingRect() const
161 return d_data->data->boundingRect();
165 \brief Returns the recommended raster for a given rect.
167 F.e the raster hint is used to limit the resolution of
168 the image that is rendered.
170 \param rect Rect for the raster hint
171 \return data().rasterHint(rect)
173 QSize PlotWaterfall::rasterHint(const QwtDoubleRect &rect) const
175 return d_data->data->rasterHint(rect);
179 \brief Render an image from the data and color map.
181 The area is translated into a rect of the paint device.
182 For each pixel of this rect the intensity is mapped
185 \param xMap X-Scale Map
186 \param yMap Y-Scale Map
187 \param area Area that should be rendered in scale coordinates.
189 \return A QImage::Format_Indexed8 or QImage::Format_ARGB32 depending
192 \sa QwtRasterData::intensity(), QwtColorMap::rgb(),
193 QwtColorMap::colorIndex()
195 QImage PlotWaterfall::renderImage(
196 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
197 const QwtDoubleRect &area) const
199 if ( area.isEmpty() )
202 QRect rect = transform(xMap, yMap, area);
204 QwtScaleMap xxMap = xMap;
205 QwtScaleMap yyMap = yMap;
207 const QSize res = d_data->data->rasterHint(area);
211 It is useless to render an image with a higher resolution
212 than the data offers. Of course someone will have to
213 scale this image later into the size of the given rect, but f.e.
214 in case of postscript this will done on the printer.
216 rect.setSize(rect.size().boundedTo(res));
219 int px2 = rect.x() + rect.width();
220 if ( xMap.p1() > xMap.p2() )
223 double sx1 = area.x();
224 double sx2 = area.x() + area.width();
225 if ( xMap.s1() > xMap.s2() )
229 int py2 = rect.y() + rect.height();
230 if ( yMap.p1() > yMap.p2() )
233 double sy1 = area.y();
234 double sy2 = area.y() + area.height();
235 if ( yMap.s1() > yMap.s2() )
238 xxMap.setPaintInterval(px1, px2);
239 xxMap.setScaleInterval(sx1, sx2);
240 yyMap.setPaintInterval(py1, py2);
241 yyMap.setScaleInterval(sy1, sy2);
244 PlotWaterfallImage image(rect.size(), d_data->colorMap->format());
246 const QwtDoubleInterval intensityRange = d_data->data->range();
247 if ( !intensityRange.isValid() )
250 d_data->data->initRaster(area, rect.size());
252 if ( d_data->colorMap->format() == QwtColorMap::RGB )
254 for ( int y = rect.top(); y <= rect.bottom(); y++ )
256 const double ty = yyMap.invTransform(y);
258 QRgb *line = (QRgb *)image.scanLine(y - rect.top());
259 for ( int x = rect.left(); x <= rect.right(); x++ )
261 const double tx = xxMap.invTransform(x);
263 *line++ = d_data->colorMap->rgb(intensityRange,
264 d_data->data->value(tx, ty));
268 else if ( d_data->colorMap->format() == QwtColorMap::Indexed )
270 image.setColorTable(d_data->colorMap->colorTable(intensityRange));
272 for ( int y = rect.top(); y <= rect.bottom(); y++ )
274 const double ty = yyMap.invTransform(y);
276 unsigned char *line = image.scanLine(y - rect.top());
277 for ( int x = rect.left(); x <= rect.right(); x++ )
279 const double tx = xxMap.invTransform(x);
281 *line++ = d_data->colorMap->colorIndex(intensityRange,
282 d_data->data->value(tx, ty));
287 d_data->data->discardRaster();
289 // Mirror the image in case of inverted maps
291 const bool hInvert = xxMap.p1() > xxMap.p2();
292 const bool vInvert = yyMap.p1() < yyMap.p2();
293 if ( hInvert || vInvert )
297 #if QT_VERSION < 0x040000
298 image = image.mirror(hInvert, vInvert);
300 image = image.mirrored(hInvert, vInvert);
308 \brief Draw the spectrogram
310 \param painter Painter
311 \param xMap Maps x-values into pixel coordinates.
312 \param yMap Maps y-values into pixel coordinates.
313 \param canvasRect Contents rect of the canvas in painter coordinates
315 \sa setDisplayMode, renderImage,
316 QwtPlotRasterItem::draw, drawContourLines
319 void PlotWaterfall::draw(QPainter *painter,
320 const QwtScaleMap &xMap, const QwtScaleMap &yMap,
321 const QRect &canvasRect) const
323 QwtPlotRasterItem::draw(painter, xMap, yMap, canvasRect);