Files
GoldenCheetah/qwt/examples/plotmatrix/plotmatrix.cpp
Damien 2f9130cd76 Qwt 6.0.1 Support
Upgrade to QWT 6.0.1, but still uses a locally patched copy
since support for 8 axes has not been included, despite it
being a relatively simple patch.

Fixes #634.
Fixes #567.
2012-02-12 10:43:15 +00:00

294 lines
7.6 KiB
C++

/* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
* Qwt Widget Library
* Copyright (C) 1997 Josef Wilgen
* Copyright (C) 2002 Uwe Rathmann
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the Qwt License, Version 1.0
*****************************************************************************/
// vim: expandtab
#include <qlayout.h>
#include <qpen.h>
#include <qwt_plot.h>
#include <qwt_scale_widget.h>
#include <qwt_scale_draw.h>
#include "plotmatrix.h"
class PlotMatrix::PrivateData
{
public:
PrivateData():
inScaleSync(false)
{
isAxisEnabled[QwtPlot::xBottom] = true;
isAxisEnabled[QwtPlot::xTop] = false;
isAxisEnabled[QwtPlot::yLeft] = true;
isAxisEnabled[QwtPlot::yRight] = false;
}
bool isAxisEnabled[QwtPlot::axisCnt];
QVector<QwtPlot *> plotWidgets;
mutable bool inScaleSync;
};
PlotMatrix::PlotMatrix( int numRows, int numColumns, QWidget *parent):
QFrame(parent)
{
d_data = new PrivateData();
d_data->plotWidgets.resize(numRows * numColumns);
QGridLayout *layout = new QGridLayout(this);
for ( int row = 0; row < numRows; row++ )
{
for ( int col = 0; col < numColumns; col++ )
{
QwtPlot *plot = new QwtPlot(this);
layout->addWidget(plot, row, col);
for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
{
connect(plot->axisWidget(axis),
SIGNAL(scaleDivChanged()), SLOT(scaleDivChanged()) );
}
d_data->plotWidgets[row * numColumns + col] = plot;
}
}
updateLayout();
}
PlotMatrix::~PlotMatrix()
{
delete d_data;
}
int PlotMatrix::numRows() const
{
const QGridLayout *l = qobject_cast<const QGridLayout *>(layout());
if ( l )
return l->rowCount();
return 0;
}
int PlotMatrix::numColumns() const
{
const QGridLayout *l = qobject_cast<const QGridLayout *>(layout());
if ( l )
return l->columnCount();
return 0;
}
QwtPlot* PlotMatrix::plot(int row, int column)
{
const int index = row * numColumns() + column;
if ( index < (int)d_data->plotWidgets.size() )
return d_data->plotWidgets[index];
return NULL;
}
const QwtPlot* PlotMatrix::plot(int row, int column) const
{
const int index = row * numColumns() + column;
if ( index < (int)d_data->plotWidgets.size() )
return d_data->plotWidgets[index];
return NULL;
}
void PlotMatrix::enableAxis(int axis, bool tf)
{
if ( axis >= 0 && axis < QwtPlot::axisCnt )
{
if ( tf != d_data->isAxisEnabled[axis] )
{
d_data->isAxisEnabled[axis] = tf;
updateLayout();
}
}
}
bool PlotMatrix::axisEnabled(int axis) const
{
if ( axis >= 0 && axis < QwtPlot::axisCnt )
return d_data->isAxisEnabled[axis];
return false;
}
void PlotMatrix::setAxisScale(int axis, int rowOrColumn,
double min, double max, double step)
{
int row = 0;
int col = 0;
if ( axis == QwtPlot::xBottom || axis == QwtPlot::xTop )
col = rowOrColumn;
else
row = rowOrColumn;
QwtPlot *plt = plot(row, col);
if ( plt )
{
plt->setAxisScale(axis, min, max, step);
plt->updateAxes();
}
}
void PlotMatrix::scaleDivChanged()
{
if ( d_data->inScaleSync )
return;
d_data->inScaleSync = true;
QwtPlot *plt = NULL;
int axisId = -1;
int rowOrColumn = -1;
// find the changed axis
for ( int row = 0; row < numRows(); row++ )
{
for ( int col = 0; col < numColumns(); col++ )
{
QwtPlot *p = plot(row, col);
if ( p )
{
for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
{
if ( p->axisWidget(axis) == sender() )
{
plt = p;
axisId = axis;
if ( axisId == QwtPlot::xBottom || axisId == QwtPlot::xTop )
rowOrColumn = col;
else
rowOrColumn = row;
}
}
}
}
}
if ( plt )
{
// synchronize the axes
if ( axisId == QwtPlot::xBottom || axisId == QwtPlot::xTop )
{
for ( int row = 0; row < numRows(); row++ )
{
QwtPlot *p = plot(row, rowOrColumn);
if ( p != plt )
p->setAxisScaleDiv(axisId, *plt->axisScaleDiv(axisId));
}
}
else
{
for ( int col = 0; col < numColumns(); col++ )
{
QwtPlot *p = plot(rowOrColumn, col);
if ( p != plt )
p->setAxisScaleDiv(axisId, *plt->axisScaleDiv(axisId));
}
}
updateLayout();
}
d_data->inScaleSync = false;
}
void PlotMatrix::updateLayout()
{
for ( int row = 0; row < numRows(); row++ )
{
for ( int col = 0; col < numColumns(); col++ )
{
QwtPlot *p = plot(row, col);
if ( p )
{
bool showAxis[QwtPlot::axisCnt];
showAxis[QwtPlot::xBottom] =
axisEnabled(QwtPlot::xBottom) && row == numRows() - 1;
showAxis[QwtPlot::xTop] =
axisEnabled(QwtPlot::xTop) && row == 0;
showAxis[QwtPlot::yLeft] =
axisEnabled(QwtPlot::yLeft) && col == 0;
showAxis[QwtPlot::yRight] =
axisEnabled(QwtPlot::yRight) && col == numColumns() - 1;
for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
{
if ( axis == QwtPlot::xBottom || axis == QwtPlot::xTop )
p->enableAxis(axis, showAxis[axis]);
else
{
p->enableAxis(axis, true);
QwtScaleDraw *sd = p->axisScaleDraw(axis);
sd->enableComponent(
QwtScaleDraw::Backbone, showAxis[axis]);
sd->enableComponent(
QwtScaleDraw::Ticks, showAxis[axis]);
sd->enableComponent(
QwtScaleDraw::Labels, showAxis[axis]);
}
}
}
}
}
for ( int col = 0; col < numColumns(); col++ )
{
alignVAxes(col, QwtPlot::yLeft);
alignVAxes(col, QwtPlot::yRight);
}
for ( int row = 0; row < numRows(); row++ )
{
for ( int col = 0; col < numColumns(); col++ )
{
QwtPlot *p = plot(row, col);
if ( p )
p->replot();
}
}
}
void PlotMatrix::alignVAxes(int col, int axis)
{
if ( axis != QwtPlot::yLeft && axis != QwtPlot::yRight )
return;
int maxExtent = 0;
for ( int row = 0; row < numRows(); row++ )
{
QwtPlot *p = plot(row, col);
if ( p )
{
QwtScaleWidget *scaleWidget = p->axisWidget(axis);
QwtScaleDraw *sd = scaleWidget->scaleDraw();
sd->setMinimumExtent(0);
const int extent = sd->extent( scaleWidget->font() );
if ( extent > maxExtent )
maxExtent = extent;
}
}
for ( int row = 0; row < numRows(); row++ )
{
QwtPlot *p = plot(row, col);
if ( p )
{
QwtScaleWidget *scaleWidget = p->axisWidget(axis);
scaleWidget->scaleDraw()->setMinimumExtent(maxExtent);
}
}
}