void PlotMatrix::alignVAxes( int col, int axis ) { if ( axis != QwtPlot::yLeft && axis != QwtPlot::yRight ) return; double 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.0 ); const double 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 ); } } }
void Spectrogram::showColorScale(int axis, bool on) { if (hasColorScale() == on && color_axis == axis) return; QwtPlot *plot = this->plot(); if (!plot) return; QwtScaleWidget *colorAxis = plot->axisWidget(color_axis); colorAxis->setColorBarEnabled(false); color_axis = axis; // We must switch main and the color scale axes and their respective scales int xAxis = this->xAxis(); int yAxis = this->yAxis(); int oldMainAxis = yAxis; if (axis == QwtPlot::xBottom || axis == QwtPlot::xTop) { oldMainAxis = xAxis; xAxis = 5 - color_axis; } else if (axis == QwtPlot::yLeft || axis == QwtPlot::yRight) { oldMainAxis = yAxis; yAxis = 1 - color_axis; } // First we switch axes setAxis(xAxis, yAxis); // Next we switch axes scales QwtScaleDiv *scDiv = plot->axisScaleDiv(oldMainAxis); if (axis == QwtPlot::xBottom || axis == QwtPlot::xTop) plot->setAxisScale(xAxis, scDiv->lBound(), scDiv->hBound()); else if (axis == QwtPlot::yLeft || color_axis == QwtPlot::yRight) plot->setAxisScale(yAxis, scDiv->lBound(), scDiv->hBound()); colorAxis = plot->axisWidget(color_axis); plot->setAxisScale(color_axis, data().range().minValue(), data().range().maxValue()); colorAxis->setColorBarEnabled(on); colorAxis->setColorMap(data().range(), colorMap()); if (!plot->axisEnabled(color_axis)) plot->enableAxis(color_axis); colorAxis->show(); plot->updateLayout(); }
void PlotMatrix::alignScaleBorder( int rowOrColumn, int axis ) { int startDist = 0; int endDist = 0; if ( axis == QwtPlot::yLeft ) { QwtPlot *p = plotAt( rowOrColumn, 0 ); if ( p ) p->axisWidget( axis )->getBorderDistHint( startDist, endDist ); for ( int col = 1; col < numColumns(); col++ ) { QwtPlot *p = plotAt( rowOrColumn, col ); if ( p ) p->axisWidget( axis )->setMinBorderDist( startDist, endDist ); } } else if ( axis == QwtPlot::yRight ) { QwtPlot *p = plotAt( rowOrColumn, numColumns() - 1 ); if ( p ) p->axisWidget( axis )->getBorderDistHint( startDist, endDist ); for ( int col = 0; col < numColumns() - 1; col++ ) { QwtPlot *p = plotAt( rowOrColumn, col ); if ( p ) p->axisWidget( axis )->setMinBorderDist( startDist, endDist ); } } if ( axis == QwtPlot::xTop ) { QwtPlot *p = plotAt( rowOrColumn, 0 ); if ( p ) p->axisWidget( axis )->getBorderDistHint( startDist, endDist ); for ( int row = 1; row < numRows(); row++ ) { QwtPlot *p = plotAt( row, rowOrColumn ); if ( p ) p->axisWidget( axis )->setMinBorderDist( startDist, endDist ); } } else if ( axis == QwtPlot::xBottom ) { QwtPlot *p = plotAt( numRows() - 1, rowOrColumn ); if ( p ) p->axisWidget( axis )->getBorderDistHint( startDist, endDist ); for ( int row = 0; row < numRows() - 1; row++ ) { QwtPlot *p = plotAt( row, rowOrColumn ); if ( p ) p->axisWidget( axis )->setMinBorderDist( startDist, endDist ); } } }
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(); }
void Spectrogram::setColorBarWidth(int width) { QwtPlot *plot = this->plot(); if (!plot) return; QwtScaleWidget *colorAxis = plot->axisWidget(color_axis); colorAxis->setColorBarWidth(width); }
int Spectrogram::colorBarWidth() { QwtPlot *plot = this->plot(); if (!plot) return 0; QwtScaleWidget *colorAxis = plot->axisWidget(color_axis); return colorAxis->colorBarWidth(); }
bool Spectrogram::hasColorScale() { QwtPlot *plot = this->plot(); if (!plot) return false; if (!plot->axisEnabled(color_axis)) return false; QwtScaleWidget *colorAxis = plot->axisWidget(color_axis); return colorAxis->isColorBarEnabled(); }
void Spectrogram::setCustomColorMap(const QwtColorMap &map) { setColorMap(map); // color_map = map; color_map_policy = Custom; QwtPlot *plot = this->plot(); if (!plot) return; QwtScaleWidget *colorAxis = plot->axisWidget(color_axis); if (colorAxis) { colorAxis->setColorMap(this->data().range(), this->getColorMap()); } }
void Spectrogram::setDefaultColorMap() { color_map = defaultColorMap(); setColorMap(color_map); color_map_policy = Default; QwtPlot *plot = this->plot(); if (!plot) return; QwtScaleWidget *colorAxis = plot->axisWidget(color_axis); if (colorAxis) colorAxis->setColorMap(this->data().range(), this->colorMap()); }
void Spectrogram::setGrayScale() { color_map = QwtLinearColorMap(Qt::black, Qt::white); setColorMap(color_map); color_map_policy = GrayScale; QwtPlot *plot = this->plot(); if (!plot) return; QwtScaleWidget *colorAxis = plot->axisWidget(color_axis); if (colorAxis) colorAxis->setColorMap(data().range(), colorMap()); }
void Spectrogram::setDefaultColorMap() { MantidColorMap map = getDefaultColorMap(); mCurrentColorMap = map.getFilePath(); mColorMap = map; setColorMap(map); color_map_policy = Default; QwtPlot *plot = this->plot(); if (!plot) return; QwtScaleWidget *colorAxis = plot->axisWidget(color_axis); if (colorAxis) colorAxis->setColorMap(this->data().range(), this->colorMap()); }
void Spectrogram::updateData(Matrix *m) { if (!m) return; QwtPlot *plot = this->plot(); if (!plot) return; setData(MatrixData(m)); setLevelsNumber(levels()); QwtScaleWidget *colorAxis = plot->axisWidget(color_axis); if (colorAxis) colorAxis->setColorMap(data().range(), colorMap()); plot->setAxisScale(color_axis, data().range().minValue(), data().range().maxValue()); plot->replot(); }
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; }
// Получение геометрии индикации масштабирования шкалы QRect *QAxisZoomSvc::axisZoomRect(QPoint evpos,int ax) { // получаем указатель на график QwtPlot *plt = zoom->plot(); // определяем (для удобства) геометрию QRect gc = plt->canvas()->geometry(); // канвы графика QRect gw = plt->axisWidget(ax)->geometry(); // и виджета шкалы // определяем текущее положение курсора относительно канвы графика int x = evpos.x() + gw.x() - gc.x() - scb_pxl; int y = evpos.y() + gw.y() - gc.y() - scb_pyt; // запоминаем (для удобства) int wax = gw.width(); // ширину виджета шкалы int hax = gw.height(); // и высоту // читаем режим масштабирования QwtChartZoom::QConvType ct = zoom->regim(); // объявляем положение левого верхнего угла, int wl,wt,ww,wh; // ширину и высоту // если масштабируется горизонтальная шкала, то if (ax == QwtPlot::xBottom || ax == QwtPlot::xTop) { // если изменяется правая граница, то if (ct == QwtChartZoom::ctAxisHR) { // ограничение на положение курсора слева int mn = floor((float)(scb_pw/16)); // если курсор слишком близко к левой границе, то if (x < mn) x = mn; // ширина прямоугольника ww = floor((float)(x * scb_pw / scp_x)); // применяем ограничения ww = limitSize(ww,scb_pw); // левый отступ прямоугольника wl = sab_pxl; } else // иначе (изменяется левая граница) { // ограничение на положение курсора справа int mx = floor((float)(15*scb_pw/16)); // если курсор слишком близко к правой границе, то if (x > mx) x = mx; // ширина прямоугольника ww = floor((float)((scb_pw - x) * scb_pw / (scb_pw - scp_x))); // применяем ограничения ww = limitSize(ww,scb_pw); // левый отступ прямоугольника wl = sab_pxl + scb_pw - ww; } // высота прямоугольника wh = 4; // верхний отступ прямоугольника wt = 10; // для нижней шкалы // если не помещается на шкале, корректируем if (wt + wh > hax) wt = hax - wh; // для верхней шкалы симметрично if (ax == QwtPlot::xTop) wt = hax - wt - wh; } else // иначе (масштабируется вертикальная шкала) { // если изменяется нижняя граница, то if (ct == QwtChartZoom::ctAxisVB) { // ограничение на положение курсора сверху int mn = floor((float)(scb_ph/16)); // если курсор слишком близко к верхней границе, то if (y < mn) y = mn; // высота прямоугольника wh = floor((float)(y * scb_ph / scp_y)); // применяем ограничения wh = limitSize(wh,scb_ph); // верхний отступ прямоугольника wt = sab_pyt; } else // иначе (изменяется верхняя граница) { // ограничение на положение курсора снизу int mx = floor((float)(15*scb_ph/16)); // если курсор слишком близко к нижней границе, то if (y > mx) y = mx; // высота прямоугольника wh = floor((float)((scb_ph - y) * scb_ph / (scb_ph - scp_y))); // применяем ограничения wh = limitSize(wh,scb_ph); // верхний отступ прямоугольника = смещению курсора wt = sab_pyt + scb_ph - wh; } // ширина прямоугольника ww = 4; // верхний отступ прямоугольника wl = 10; // для правой шкалы // если не помещается на шкале, корректируем if (wl + ww > wax) wl = wax - ww; // для левой шкалы симметрично if (ax == QwtPlot::yLeft) wl = wax - wl - ww; } // создаем и возвращаем геометрию виджета // с вычисленными размерами return new QRect(wl,wt,ww,wh); }
// Обработчик нажатия на кнопку мыши над шкалой // (включение изменения масштаба шкалы) void QAxisZoomSvc::startAxisZoom(QMouseEvent *mEvent,int ax) { // фиксируем исходные границы графика (если этого еще не было сделано) zoom->fixBounds(); // если в данный момент еще не включен ни один из режимов if (zoom->regim() == QwtChartZoom::ctNone) { // если нажата левая кнопка мыши, то // включаем один из режимов масштабирования if (mEvent->button() == Qt::LeftButton) { // получаем указатели на QwtPlot *plt = zoom->plot(); // график QwtScaleWidget *sw = plt->axisWidget(ax); // виджет шкалы // получаем карту основной горизонтальной шкалы QwtScaleMap sm = plt->canvasMap(zoom->masterH()); // для того чтобы фиксировать начальные левую и правую границы scb_xl = sm.s1(); scb_xr = sm.s2(); scb_wx = sm.sDist(); // аналогично получаем карту основной вертикальной шкалы sm = plt->canvasMap(zoom->masterV()); // для того чтобы фиксировать начальные нижнюю и верхнюю границы scb_yb = sm.s1(); scb_yt = sm.s2(); scb_hy = sm.sDist(); // определяем (для удобства) геометрию QRect gc = plt->canvas()->geometry(); // канвы графика QRect gw = sw->geometry(); // и виджета шкалы // текущее левое смещение графика (в пикселах относительно канвы) scb_pxl = plt->transform(zoom->masterH(),scb_xl); // текущая ширина графика (в пикселах) scb_pw = plt->transform(zoom->masterH(),scb_xr) - scb_pxl; // текущее левое смещение графика // (в пикселах относительно виджета шкалы) sab_pxl = scb_pxl + gc.x() - gw.x(); // текущее верхнее смещение графика (в пикселах относительно канвы) scb_pyt = plt->transform(zoom->masterV(),scb_yt); // текущая высота графика (в пикселах) scb_ph = plt->transform(zoom->masterV(),scb_yb) - scb_pyt; // текущее верхнее смещение графика // (в пикселах относительно виджета шкалы) sab_pyt = scb_pyt + gc.y() - gw.y(); // запоминаем текущее положение курсора относительно канвы // (за вычетом смещений графика) scp_x = mEvent->pos().x() - sab_pxl; scp_y = mEvent->pos().y() - sab_pyt; // если масштабируется горизонтальная шкала if (ax == QwtPlot::xBottom || ax == QwtPlot::xTop) { // если левая граница меньше правой, if (scb_wx > 0) // если ширина канвы больше минимума, if (scb_pw > 36) { // в зависимости от положения курсора // (правее или левее середины шкалы) // включаем соответствующий режим - изменение if (scp_x >= floor((float)(scb_pw/2))) zoom->setRegim(QwtChartZoom::ctAxisHR); // правой границы else zoom->setRegim(QwtChartZoom::ctAxisHL); // или левой } } else // иначе (масштабируется вертикальная шкала) { // если нижняя граница меньше верхней, if (scb_hy > 0) // если высота канвы больше минимума, if (scb_ph > 18) { // в зависимости от положения курсора // (ниже или выше середины шкалы) // включаем соответствующий режим - изменение if (scp_y >= floor((float)(scb_ph/2))) zoom->setRegim(QwtChartZoom::ctAxisVB); // нижней границы else zoom->setRegim(QwtChartZoom::ctAxisVT); // или верхней } } // если один из режимов был включен if (zoom->regim() != QwtChartZoom::ctNone) { // запоминаем текущий курсор tCursor = sw->cursor(); // устанавливаем курсор PointingHand sw->setCursor(Qt::PointingHandCursor); // если легкий режим и включена индикация, то if (light && indiAxZ) { // создаем виджет, индицирующий масштабирование шкалы zwid = new QWidget(plt->axisWidget(ax)); // назначаем ему цвет zwid->setStyleSheet(QString( "background-color:rgb(%1,%2,%3);").arg( awClr.red()).arg(awClr.green()).arg(awClr.blue())); // и прорисовываем showZoomWidget(mEvent->pos(),ax); } } } } }
// Применение результатов перемещения границы шкалы void QAxisZoomSvc::axisApplyMove(QPoint evpos,int ax) { // получаем указатель на график QwtPlot *plt = zoom->plot(); // определяем (для удобства) геометрию QRect gc = plt->canvas()->geometry(); // канвы графика QRect gw = plt->axisWidget(ax)->geometry(); // и виджета шкалы // определяем текущее положение курсора относительно канвы // (за вычетом смещений графика) int x = evpos.x() + gw.x() - gc.x() - scb_pxl; int y = evpos.y() + gw.y() - gc.y() - scb_pyt; bool bndCh = false; // пока ничего не изменилось // читаем режим масштабирования QwtChartZoom::QConvType ct = zoom->regim(); // в зависимости от включенного режима выполняем некоторые действия switch (ct) { // режим изменения левой границы case QwtChartZoom::ctAxisHL: { // ограничение на положение курсора справа if (x >= scb_pw) x = scb_pw-1; // вычисляем новую ширину шкалы double wx = scb_wx * (scb_pw - scp_x) / (scb_pw - x); // применяем ограничения wx = limitScale(wx,scb_wx); // вычисляем новую левую границу double xl = scb_xr - wx; // устанавливаем ее для горизонтальной шкалы zoom->isb_x->set(xl,scb_xr); bndCh = true; // изменилась граница break; } // режим изменения правой границы case QwtChartZoom::ctAxisHR: { // ограничение на положение курсора слева if (x <= 0) x = 1; // вычисляем новую ширину шкалы double wx = scb_wx * scp_x / x; // применяем ограничения wx = limitScale(wx,scb_wx); // вычисляем новую правую границу double xr = scb_xl + wx; // устанавливаем ее для горизонтальной шкалы zoom->isb_x->set(scb_xl,xr); bndCh = true; // изменилась граница break; } // режим изменения нижней границы case QwtChartZoom::ctAxisVB: { // ограничение на положение курсора сверху if (y <= 0) y = 1; // вычисляем новую высоту шкалы double hy = scb_hy * scp_y / y; // применяем ограничения hy = limitScale(hy,scb_hy); // вычисляем новую нижнюю границу double yb = scb_yt - hy; // устанавливаем ее для вертикальной шкалы zoom->isb_y->set(yb,scb_yt); bndCh = true; // изменилась граница break; } // режим изменения верхней границы case QwtChartZoom::ctAxisVT: { // ограничение на положение курсора снизу if (y >= scb_ph) y = scb_ph-1; // вычисляем новую высоту шкалы double hy = scb_hy * (scb_ph - scp_y) / (scb_ph - y); // применяем ограничения hy = limitScale(hy,scb_hy); // вычисляем новую верхнюю границу double yt = scb_yb + hy; // устанавливаем ее для вертикальной шкалы zoom->isb_y->set(scb_yb,yt); bndCh = true; // изменилась граница break; } // для прочих режимов ничего не делаем default: ; } // если какя-либо граница изменилась, то перестраиваем график if (bndCh) plt->replot(); }
void PlotExporter::exportPlot(QwtPlot *plot, const QRectF &zoom) { QSizeF guessedDimensions; ExportPlotToImageDialog::Parameters p = m_exportDlg->parameters(); m_exportDlg->setAspectRatio(plot->size().width() / plot->size().height()); while (m_exportDlg->exec() == QDialog::Accepted) { p = m_exportDlg->parameters(); QString path; if (p.path.length() < 0) { QMessageBox::warning(nullptr, QObject::tr("Invalid input"), QObject::tr("Invalid path")); continue; } if (!m_supportedFormats.contains(p.format)) { QMessageBox::warning(nullptr, QObject::tr("Invalid input"), QObject::tr("Invalid output format")); continue; } if (p.path.endsWith("." + p.format)) path = p.path; else path = p.path + "." + p.format; /* Create a temporary QwtPlot to use to write the chart to file */ QwtPlot exPlot; QwtPlotZoomer exPlorZoomer(exPlot.canvas()); exPlorZoomer.zoom(zoom); exPlot.setCanvasBackground(QBrush(Qt::white)); exPlot.setTitle(p.title); exPlot.setAxisTitle(QwtPlot::xBottom, plot->axisTitle(QwtPlot::xBottom)); exPlot.setAxisTitle(QwtPlot::xTop, plot->axisTitle(QwtPlot::xTop)); exPlot.setAxisTitle(QwtPlot::yLeft, plot->axisTitle(QwtPlot::yLeft)); exPlot.setAxisTitle(QwtPlot::yRight, plot->axisTitle(QwtPlot::yRight)); QwtPlotItemList curves = plot->itemList(); /* Attach all plots from the GUI plot to the temporary plot * Note that this will detach the plots from the GUI plot! */ QList<qreal> curvePenWidths; for (QwtPlotItem *i : curves) { QwtPlotCurve *c = dynamic_cast<QwtPlotCurve *>(i); if (c != nullptr) { QPen p = c->pen(); qreal w = p.widthF(); qreal nw; curvePenWidths.push_back(w); nw = w - 1.0; if (nw < 0.0) nw = 0.0; p.setWidthF(nw); c->setPen(p); } i->attach(&exPlot); } /* Scale up from millimeters to centimeters*/ QSizeF dimensionsMM(p.dimensions.width() * 10.0, p.dimensions.height() * 10.0); /* Store current properties of the plot as we need to change them for rendering */ QFont xBottomFont = plot->axisWidget(QwtPlot::xBottom)->font(); QFont xTopFont = plot->axisWidget(QwtPlot::xTop)->font(); QFont yLeftFont = plot->axisWidget(QwtPlot::yLeft)->font(); QFont yRightFont = plot->axisWidget(QwtPlot::yRight)->font(); QFont xBottomTitleFont = plot->axisTitle(QwtPlot::xBottom).font(); QFont xTopTitleFont = plot->axisTitle(QwtPlot::xTop).font(); QFont yLeftTitleFont = plot->axisTitle(QwtPlot::yLeft).font(); QFont yRightTitleFont = plot->axisTitle(QwtPlot::yRight).font(); QFont titleFont = plot->title().font(); const qreal xBottomPenWidth = plot->axisWidget(QwtPlot::xBottom)->scaleDraw()->penWidth() > 0 ? plot->axisWidget(QwtPlot::xBottom)->scaleDraw()->penWidth() : 1.0; const qreal xTopPenWidth = plot->axisWidget(QwtPlot::xTop)->scaleDraw()->penWidth() > 0 ? plot->axisWidget(QwtPlot::xTop)->scaleDraw()->penWidth() : 1.0; const qreal yLeftPenWidth = plot->axisWidget(QwtPlot::yLeft)->scaleDraw()->penWidth() > 0 ? plot->axisWidget(QwtPlot::yLeft)->scaleDraw()->penWidth() : 1.0; const qreal yRightPenWidth = plot->axisWidget(QwtPlot::yRight)->scaleDraw()->penWidth() > 0 ? plot->axisWidget(QwtPlot::yRight)->scaleDraw()->penWidth() : 1.0; /* Recalculate sizes by the DPI for every element that needs it */ const qreal outputInPixels = (static_cast<qreal>(p.dimensions.width()) / 2.54) * p.dpi; const qreal scalingRatio = (static_cast<qreal>(qApp->desktop()->logicalDpiX()) / p.dpi) * (outputInPixels / plot->geometry().width()); const qreal _xBottomPenWidth = floor((xBottomPenWidth * scalingRatio) + 0.45); const qreal _xTopPenWidth = floor((xTopPenWidth * scalingRatio) + 0.45); const qreal _yLeftPenWidth = floor((yLeftPenWidth * scalingRatio) + 0.45); const qreal _yRightPenWidth = floor((yRightPenWidth * scalingRatio) + 0.45); xBottomFont.setPointSizeF(p.axisNumbersFontSize * scalingRatio); xTopFont.setPointSizeF(p.axisNumbersFontSize * scalingRatio); yLeftFont.setPointSizeF(p.axisNumbersFontSize * scalingRatio); yRightFont.setPointSizeF(p.axisNumbersFontSize * scalingRatio); xBottomTitleFont.setPointSizeF(p.axisTitlesFontSize * scalingRatio); xTopTitleFont.setPointSizeF(p.axisTitlesFontSize * scalingRatio); yLeftTitleFont.setPointSizeF(p.axisTitlesFontSize * scalingRatio); yRightTitleFont.setPointSizeF(p.axisTitlesFontSize * scalingRatio); titleFont.setPointSizeF(p.chartTitleFontSize * scalingRatio); exPlot.axisWidget(QwtPlot::xBottom)->scaleDraw()->setPenWidth(_xBottomPenWidth); exPlot.axisWidget(QwtPlot::xTop)->scaleDraw()->setPenWidth(_xTopPenWidth); exPlot.axisWidget(QwtPlot::yLeft)->scaleDraw()->setPenWidth(_yLeftPenWidth); exPlot.axisWidget(QwtPlot::yRight)->scaleDraw()->setPenWidth(_yRightPenWidth); exPlot.setPalette(m_plotPalette); exPlot.axisWidget(QwtPlot::xBottom)->setPalette(m_plotPalette); exPlot.axisWidget(QwtPlot::xTop)->setPalette(m_plotPalette); exPlot.axisWidget(QwtPlot::yLeft)->setPalette(m_plotPalette); exPlot.axisWidget(QwtPlot::yRight)->setPalette(m_plotPalette); exPlot.axisWidget(QwtPlot::xBottom)->setFont(xBottomFont); exPlot.axisWidget(QwtPlot::xTop)->setFont(xTopFont); exPlot.axisWidget(QwtPlot::yLeft)->setFont(yLeftFont); exPlot.axisWidget(QwtPlot::yRight)->setFont(yRightFont); setAxisTitleFont(&exPlot, QwtPlot::xBottom, xBottomTitleFont); setAxisTitleFont(&exPlot, QwtPlot::xTop, xTopTitleFont); setAxisTitleFont(&exPlot, QwtPlot::yLeft, yLeftTitleFont); setAxisTitleFont(&exPlot, QwtPlot::yRight, yRightTitleFont); setTitleFont(&exPlot, titleFont); exPlot.replot(); renderPlotToFile(&exPlot, path, p.format, dimensionsMM, p.dpi); /* Reattach the plots back to the GUI plot */ for (QwtPlotItem *i : curves) { QwtPlotCurve *c = dynamic_cast<QwtPlotCurve *>(i); if (c != nullptr) { QPen p = c->pen(); if (curvePenWidths.isEmpty()) break; p.setWidthF(curvePenWidths.front()); curvePenWidths.pop_front(); c->setPen(p); } i->attach(plot); } break; /* Exit the while loop */ } }
QSize MultiLayer::arrangeLayers(bool userSize) { const QRect rect = canvas->geometry(); gsl_vector *xTopR = gsl_vector_calloc( graphs); // ratio between top axis + title and canvas height gsl_vector *xBottomR = gsl_vector_calloc(graphs); // ratio between bottom axis and canvas height gsl_vector *yLeftR = gsl_vector_calloc(graphs); gsl_vector *yRightR = gsl_vector_calloc(graphs); gsl_vector *maxXTopHeight = gsl_vector_calloc(rows); // maximum top axis + title height in a row gsl_vector *maxXBottomHeight = gsl_vector_calloc(rows); // maximum bottom axis height in a row gsl_vector *maxYLeftWidth = gsl_vector_calloc(cols); // maximum left axis width in a column gsl_vector *maxYRightWidth = gsl_vector_calloc(cols); // maximum right axis width in a column gsl_vector *Y = gsl_vector_calloc(rows); gsl_vector *X = gsl_vector_calloc(cols); int i; for (i = 0; i < graphs; i++) { // calculate scales/canvas dimensions reports for each layer and // stores them in the above vectors Graph *gr = (Graph *)graphsList.at(i); QwtPlot *plot = gr->plotWidget(); QwtPlotLayout *plotLayout = plot->plotLayout(); QRect cRect = plotLayout->canvasRect(); double ch = (double)cRect.height(); double cw = (double)cRect.width(); QRect tRect = plotLayout->titleRect(); QwtScaleWidget *scale = (QwtScaleWidget *)plot->axisWidget(QwtPlot::xTop); int topHeight = 0; if (!tRect.isNull()) topHeight += tRect.height() + plotLayout->spacing(); if (scale) { QRect sRect = plotLayout->scaleRect(QwtPlot::xTop); topHeight += sRect.height(); } gsl_vector_set(xTopR, i, double(topHeight) / ch); scale = (QwtScaleWidget *)plot->axisWidget(QwtPlot::xBottom); if (scale) { QRect sRect = plotLayout->scaleRect(QwtPlot::xBottom); gsl_vector_set(xBottomR, i, double(sRect.height()) / ch); } scale = (QwtScaleWidget *)plot->axisWidget(QwtPlot::yLeft); if (scale) { QRect sRect = plotLayout->scaleRect(QwtPlot::yLeft); gsl_vector_set(yLeftR, i, double(sRect.width()) / cw); } scale = (QwtScaleWidget *)plot->axisWidget(QwtPlot::yRight); if (scale) { QRect sRect = plotLayout->scaleRect(QwtPlot::yRight); gsl_vector_set(yRightR, i, double(sRect.width()) / cw); } // calculate max scales/canvas dimensions ratio for each line and column and // stores them to vectors int row = i / cols; if (row >= rows) row = rows - 1; int col = i % cols; double aux = gsl_vector_get(xTopR, i); double old_max = gsl_vector_get(maxXTopHeight, row); if (aux >= old_max) gsl_vector_set(maxXTopHeight, row, aux); aux = gsl_vector_get(xBottomR, i); if (aux >= gsl_vector_get(maxXBottomHeight, row)) gsl_vector_set(maxXBottomHeight, row, aux); aux = gsl_vector_get(yLeftR, i); if (aux >= gsl_vector_get(maxYLeftWidth, col)) gsl_vector_set(maxYLeftWidth, col, aux); aux = gsl_vector_get(yRightR, i); if (aux >= gsl_vector_get(maxYRightWidth, col)) gsl_vector_set(maxYRightWidth, col, aux); } double c_heights = 0.0; for (i = 0; i < rows; i++) { gsl_vector_set(Y, i, c_heights); c_heights += 1 + gsl_vector_get(maxXTopHeight, i) + gsl_vector_get(maxXBottomHeight, i); } double c_widths = 0.0; for (i = 0; i < cols; i++) { gsl_vector_set(X, i, c_widths); c_widths += 1 + gsl_vector_get(maxYLeftWidth, i) + gsl_vector_get(maxYRightWidth, i); } if (!userSize) { l_canvas_width = int( (rect.width() - (cols - 1) * colsSpace - right_margin - left_margin) / c_widths); l_canvas_height = int( (rect.height() - (rows - 1) * rowsSpace - top_margin - bottom_margin) / c_heights); } QSize size = QSize(l_canvas_width, l_canvas_height); for (i = 0; i < graphs; i++) { int row = i / cols; if (row >= rows) row = rows - 1; int col = i % cols; // calculate sizes and positions for layers const int w = int(l_canvas_width * (1 + gsl_vector_get(yLeftR, i) + gsl_vector_get(yRightR, i))); const int h = int(l_canvas_height * (1 + gsl_vector_get(xTopR, i) + gsl_vector_get(xBottomR, i))); int x = left_margin + col * colsSpace; if (hor_align == HCenter) x += int(l_canvas_width * (gsl_vector_get(X, col) + gsl_vector_get(maxYLeftWidth, col) - gsl_vector_get(yLeftR, i))); else if (hor_align == Left) x += int(l_canvas_width * gsl_vector_get(X, col)); else if (hor_align == Right) x += int(l_canvas_width * (gsl_vector_get(X, col) + gsl_vector_get(maxYLeftWidth, col) - gsl_vector_get(yLeftR, i) + gsl_vector_get(maxYRightWidth, col) - gsl_vector_get(yRightR, i))); int y = top_margin + row * rowsSpace; if (vert_align == VCenter) y += int(l_canvas_height * (gsl_vector_get(Y, row) + gsl_vector_get(maxXTopHeight, row) - gsl_vector_get(xTopR, i))); else if (vert_align == Top) y += int(l_canvas_height * gsl_vector_get(Y, row)); else if (vert_align == Bottom) y += int(l_canvas_height * (gsl_vector_get(Y, row) + gsl_vector_get(maxXTopHeight, row) - gsl_vector_get(xTopR, i) + +gsl_vector_get(maxXBottomHeight, row) - gsl_vector_get(xBottomR, i))); // resizes and moves layers Graph *gr = (Graph *)graphsList.at(i); bool autoscaleFonts = false; if (!userSize) { // When the user specifies the layer canvas size, the // window is resized // and the fonts must be scaled accordingly. If the size is calculated // automatically we don't rescale the fonts in order to prevent problems // with too small fonts when the user adds new layers or when removing // layers autoscaleFonts = gr->autoscaleFonts(); // save user settings gr->setAutoscaleFonts(false); } gr->setGeometry(QRect(x, y, w, h)); gr->plotWidget()->resize(QSize(w, h)); if (!userSize) gr->setAutoscaleFonts(autoscaleFonts); // restore user settings } // free memory gsl_vector_free(maxXTopHeight); gsl_vector_free(maxXBottomHeight); gsl_vector_free(maxYLeftWidth); gsl_vector_free(maxYRightWidth); gsl_vector_free(xTopR); gsl_vector_free(xBottomR); gsl_vector_free(yLeftR); gsl_vector_free(yRightR); gsl_vector_free(X); gsl_vector_free(Y); return size; }
void PlotMatrix::alignAxes( int rowOrColumn, int axis ) { if ( axis == QwtPlot::yLeft || axis == QwtPlot::yRight ) { double maxExtent = 0; for ( int row = 0; row < numRows(); row++ ) { QwtPlot *p = plotAt( row, rowOrColumn ); if ( p ) { QwtScaleWidget *scaleWidget = p->axisWidget( axis ); QwtScaleDraw *sd = scaleWidget->scaleDraw(); sd->setMinimumExtent( 0.0 ); const double extent = sd->extent( scaleWidget->font() ); if ( extent > maxExtent ) maxExtent = extent; } } for ( int row = 0; row < numRows(); row++ ) { QwtPlot *p = plotAt( row, rowOrColumn ); if ( p ) { QwtScaleWidget *scaleWidget = p->axisWidget( axis ); scaleWidget->scaleDraw()->setMinimumExtent( maxExtent ); } } } else { double maxExtent = 0; for ( int col = 0; col < numColumns(); col++ ) { QwtPlot *p = plotAt( rowOrColumn, col ); if ( p ) { QwtScaleWidget *scaleWidget = p->axisWidget( axis ); QwtScaleDraw *sd = scaleWidget->scaleDraw(); sd->setMinimumExtent( 0.0 ); const double extent = sd->extent( scaleWidget->font() ); if ( extent > maxExtent ) maxExtent = extent; } } for ( int col = 0; col < numColumns(); col++ ) { QwtPlot *p = plotAt( rowOrColumn, col ); if ( p ) { QwtScaleWidget *scaleWidget = p->axisWidget( axis ); scaleWidget->scaleDraw()->setMinimumExtent( maxExtent ); } } } }