📄 qwt_plot_layout.cpp
字号:
- dimAxis[QwtPlot::yRight];
length += qwtMin(dimAxis[QwtPlot::yLeft],
scaleData.start - backboneOffset);
length += qwtMin(dimAxis[QwtPlot::yRight],
scaleData.end - backboneOffset);
}
else // QwtPlot::yLeft, QwtPlot::yRight
{
length = rect.height() - dimAxis[QwtPlot::xTop]
- dimAxis[QwtPlot::xBottom];
if ( dimAxis[QwtPlot::xBottom] > 0 )
{
length += qwtMin(
d_data->layoutData.scale[QwtPlot::xBottom].tickOffset,
scaleData.start - backboneOffset);
}
if ( dimAxis[QwtPlot::xTop] > 0 )
{
length += qwtMin(
d_data->layoutData.scale[QwtPlot::xTop].tickOffset,
scaleData.end - backboneOffset);
}
if ( dimTitle > 0 )
length -= dimTitle + d_data->spacing;
}
int d = scaleData.dimWithoutTitle;
if ( !scaleData.scaleWidget->title().isEmpty() )
{
d += scaleData.scaleWidget->titleHeightForWidth(length);
}
if ( d > dimAxis[axis] )
{
dimAxis[axis] = d;
done = false;
}
}
}
}
}
/*!
Align the ticks of the axis to the canvas borders using
the empty corners.
*/
void QwtPlotLayout::alignScales(int options,
QRect &canvasRect, QRect scaleRect[QwtPlot::axisCnt]) const
{
int axis;
int backboneOffset[QwtPlot::axisCnt];
for (axis = 0; axis < QwtPlot::axisCnt; axis++ )
{
backboneOffset[axis] = 0;
if ( !d_data->alignCanvasToScales )
backboneOffset[axis] += d_data->canvasMargin[axis];
if ( !(options & IgnoreFrames) )
backboneOffset[axis] += d_data->layoutData.canvas.frameWidth;
}
for (axis = 0; axis < QwtPlot::axisCnt; axis++ )
{
if ( !scaleRect[axis].isValid() )
continue;
const int startDist = d_data->layoutData.scale[axis].start;
const int endDist = d_data->layoutData.scale[axis].end;
QRect &axisRect = scaleRect[axis];
if ( axis == QwtPlot::xTop || axis == QwtPlot::xBottom )
{
const int leftOffset = backboneOffset[QwtPlot::yLeft] - startDist;
if ( scaleRect[QwtPlot::yLeft].isValid() )
{
int minLeft = scaleRect[QwtPlot::yLeft].left();
int left = axisRect.left() + leftOffset;
axisRect.setLeft(qwtMax(left, minLeft));
}
else
{
if ( d_data->alignCanvasToScales && leftOffset < 0 )
{
canvasRect.setLeft(qwtMax(canvasRect.left(),
axisRect.left() - leftOffset));
}
else
{
if ( leftOffset > 0 )
axisRect.setLeft(axisRect.left() + leftOffset);
}
}
const int rightOffset = backboneOffset[QwtPlot::yRight] - endDist;
if ( scaleRect[QwtPlot::yRight].isValid() )
{
int maxRight = scaleRect[QwtPlot::yRight].right();
int right = axisRect.right() - rightOffset;
axisRect.setRight(qwtMin(right, maxRight));
}
else
{
if ( d_data->alignCanvasToScales && rightOffset < 0 )
{
canvasRect.setRight( qwtMin(canvasRect.right(),
axisRect.right() + rightOffset) );
}
else
{
if ( rightOffset > 0 )
axisRect.setRight(axisRect.right() - rightOffset);
}
}
}
else // QwtPlot::yLeft, QwtPlot::yRight
{
const int bottomOffset =
backboneOffset[QwtPlot::xBottom] - endDist;
if ( scaleRect[QwtPlot::xBottom].isValid() )
{
int maxBottom = scaleRect[QwtPlot::xBottom].top() +
d_data->layoutData.scale[QwtPlot::xBottom].tickOffset;
int bottom = axisRect.bottom() - bottomOffset;
axisRect.setBottom(qwtMin(bottom, maxBottom));
}
else
{
if ( d_data->alignCanvasToScales && bottomOffset < 0 )
{
canvasRect.setBottom(qwtMin(canvasRect.bottom(),
axisRect.bottom() + bottomOffset));
}
else
{
if ( bottomOffset > 0 )
axisRect.setBottom(axisRect.bottom() - bottomOffset);
}
}
const int topOffset = backboneOffset[QwtPlot::xTop] - startDist;
if ( scaleRect[QwtPlot::xTop].isValid() )
{
int minTop = scaleRect[QwtPlot::xTop].bottom() -
d_data->layoutData.scale[QwtPlot::xTop].tickOffset;
int top = axisRect.top() + topOffset;
axisRect.setTop(qwtMax(top, minTop));
}
else
{
if ( d_data->alignCanvasToScales && topOffset < 0 )
{
canvasRect.setTop(qwtMax(canvasRect.top(),
axisRect.top() - topOffset));
}
else
{
if ( topOffset > 0 )
axisRect.setTop(axisRect.top() + topOffset);
}
}
}
}
if ( d_data->alignCanvasToScales )
{
/*
The canvas has been aligned to the scale with largest
border distances. Now we have to realign the other scale.
*/
if ( scaleRect[QwtPlot::xBottom].isValid() &&
scaleRect[QwtPlot::xTop].isValid() )
{
for ( int axis = QwtPlot::xBottom; axis <= QwtPlot::xTop; axis++ )
{
scaleRect[axis].setLeft(canvasRect.left() + 1
- d_data->layoutData.scale[axis].start);
scaleRect[axis].setRight(canvasRect.right() - 1
+ d_data->layoutData.scale[axis].end);
}
}
if ( scaleRect[QwtPlot::yLeft].isValid() &&
scaleRect[QwtPlot::yRight].isValid() )
{
for ( int axis = QwtPlot::yLeft; axis <= QwtPlot::yRight; axis++ )
{
scaleRect[axis].setTop(canvasRect.top() + 1
- d_data->layoutData.scale[axis].start);
scaleRect[axis].setBottom(canvasRect.bottom() - 1
+ d_data->layoutData.scale[axis].end);
}
}
}
}
/*!
\brief Recalculate the geometry of all components.
\param plot Plot to be layout
\param plotRect Rect where to place the components
\param options Options
\sa invalidate(), titleRect(),
legendRect(), scaleRect(), canvasRect()
*/
void QwtPlotLayout::activate(const QwtPlot *plot,
const QRect &plotRect, int options)
{
invalidate();
QRect rect(plotRect); // undistributed rest of the plot rect
if ( !(options & IgnoreMargin) )
{
// subtract the margin
rect.setRect(
rect.x() + d_data->margin,
rect.y() + d_data->margin,
rect.width() - 2 * d_data->margin,
rect.height() - 2 * d_data->margin
);
}
// We extract all layout relevant data from the widgets,
// filter them through pfilter and save them to d_data->layoutData.
d_data->layoutData.init(plot, rect);
if (!(options & IgnoreLegend)
&& d_data->legendPos != QwtPlot::ExternalLegend
&& plot->legend() && !plot->legend()->isEmpty() )
{
d_data->legendRect = layoutLegend(options, rect);
// subtract d_data->legendRect from rect
const QRegion region(rect);
rect = region.subtract(d_data->legendRect).boundingRect();
if ( d_data->layoutData.legend.frameWidth &&
!(options & IgnoreFrames ) )
{
// In case of a frame we have to insert a spacing.
// Otherwise the leading of the font separates
// legend and scale/canvas
switch(d_data->legendPos)
{
case QwtPlot::LeftLegend:
rect.setLeft(rect.left() + d_data->spacing);
break;
case QwtPlot::RightLegend:
rect.setRight(rect.right() - d_data->spacing);
break;
case QwtPlot::TopLegend:
rect.setTop(rect.top() + d_data->spacing);
break;
case QwtPlot::BottomLegend:
rect.setBottom(rect.bottom() - d_data->spacing);
break;
case QwtPlot::ExternalLegend:
break; // suppress compiler warning
}
}
}
/*
+---+-----------+---+
| Title |
+---+-----------+---+
| | Axis | |
+---+-----------+---+
| A | | A |
| x | Canvas | x |
| i | | i |
| s | | s |
+---+-----------+---+
| | Axis | |
+---+-----------+---+
*/
// axes and title include text labels. The height of each
// label depends on its line breaks, that depend on the width
// for the label. A line break in a horizontal text will reduce
// the available width for vertical texts and vice versa.
// expandLineBreaks finds the height/width for title and axes
// including all line breaks.
int dimTitle, dimAxes[QwtPlot::axisCnt];
expandLineBreaks(options, rect, dimTitle, dimAxes);
if (dimTitle > 0 )
{
d_data->titleRect = QRect(rect.x(), rect.y(),
rect.width(), dimTitle);
if ( d_data->layoutData.scale[QwtPlot::yLeft].isEnabled !=
d_data->layoutData.scale[QwtPlot::yRight].isEnabled )
{
// if only one of the y axes is missing we align
// the title centered to the canvas
d_data->titleRect.setX(rect.x() + dimAxes[QwtPlot::yLeft]);
d_data->titleRect.setWidth(rect.width()
- dimAxes[QwtPlot::yLeft] - dimAxes[QwtPlot::yRight]);
}
// subtract title
rect.setTop(rect.top() + dimTitle + d_data->spacing);
}
d_data->canvasRect.setRect(
rect.x() + dimAxes[QwtPlot::yLeft],
rect.y() + dimAxes[QwtPlot::xTop],
rect.width() - dimAxes[QwtPlot::yRight] - dimAxes[QwtPlot::yLeft],
rect.height() - dimAxes[QwtPlot::xBottom] - dimAxes[QwtPlot::xTop]);
for ( int axis = 0; axis < QwtPlot::axisCnt; axis++ )
{
// set the rects for the axes
if ( dimAxes[axis] )
{
int dim = dimAxes[axis];
QRect &scaleRect = d_data->scaleRect[axis];
scaleRect = d_data->canvasRect;
switch(axis)
{
case QwtPlot::yLeft:
scaleRect.setX(d_data->canvasRect.left() - dim);
scaleRect.setWidth(dim);
break;
case QwtPlot::yRight:
scaleRect.setX(d_data->canvasRect.right() + 1);
scaleRect.setWidth(dim);
break;
case QwtPlot::xBottom:
scaleRect.setY(d_data->canvasRect.bottom() + 1);
scaleRect.setHeight(dim);
break;
case QwtPlot::xTop:
scaleRect.setY(d_data->canvasRect.top() - dim);
scaleRect.setHeight(dim);
break;
}
#if QT_VERSION < 0x040000
scaleRect = scaleRect.normalize();
#else
scaleRect = scaleRect.normalized();
#endif
}
}
// +---+-----------+---+
// | <- Axis -> |
// +-^-+-----------+-^-+
// | | | | | |
// | | | |
// | A | | A |
// | x | Canvas | x |
// | i | | i |
// | s | | s |
// | | | |
// | | | | | |
// +-V-+-----------+-V-+
// | <- Axis -> |
// +---+-----------+---+
// The ticks of the axes - not the labels above - should
// be aligned to the canvas. So we try to use the empty
// corners to extend the axes, so that the label texts
// left/right of the min/max ticks are moved into them.
alignScales(options, d_data->canvasRect, d_data->scaleRect);
if (!d_data->legendRect.isEmpty() )
{
// We prefer to align the legend to the canvas - not to
// the complete plot - if possible.
d_data->legendRect = alignLegend(d_data->canvasRect, d_data->legendRect);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -