/* * LayoutVertical.hh * * Created on: Sep, 2, 2014 * Author: AKKA */ #include "LayoutVertical.hh" #include "PlotLogger.hh" #include "DecoratorPlot.hh" #include "PlPlotUtil.hh" #include namespace plot { /** * @Brief Add a panel characterized by it's constraint to the layout */ void LayoutVertical::addPanel (PanelConstraint panelConstraint, double preferedWidth/*=-1*/, double preferedHeight/*=-1*/, bool isHeightFixed /*=false*/, double fixedHeight /*0*/) { double width=0, height=0; switch (panelConstraint) { case PanelConstraint::MaxWidth: width = 1.0; if(isHeightFixed){ height = fixedHeight; break; } if (preferedHeight != -1) height = preferedHeight; else height = _requestPanelHeight; break; case PanelConstraint::Square: if (preferedWidth != -1) width = preferedWidth; else width = _requestPanelHeight / _xyRatio; if (preferedHeight != -1) height = preferedHeight; else height = _requestPanelHeight; break; default: // TODO lever exception ici ??? break; } _panelsInfo.push_back (new PanelInfo (panelConstraint, preferedWidth, preferedHeight, width, height, isHeightFixed)); } /** * @Brief Reset Layout internal parameters and compute optimized parameters * like _panelHeight, _panelWidth, _panelYSpacing... */ void LayoutVertical::reset (void) { // Reset current panels and position _curPanel = 0; _curYPosition = 0; _maxWidthConstraintFound = false; // Compute general data for the layout depending on // - the number of panel // - their constraint _panelYSpacing = _requestPanelSpacing; double layoutWidth, layoutHeight; double fixedHeight; computeLayoutSize (layoutWidth, layoutHeight,fixedHeight); // Normalize width & height if more than 1 if(layoutHeight > (1 - fixedHeight)){ for (auto panelInfo : _panelsInfo) { if(!panelInfo->_isHeightFixed){ if(fixedHeight > 0.){ float nbPanelFactor =1.; if (layoutHeight > 1.) nbPanelFactor = (1./panelInfo->_height) /(layoutHeight/ panelInfo->_height); panelInfo->_preferedHeight = panelInfo->_preferedHeight / (1/(1-fixedHeight))*nbPanelFactor ; panelInfo->_height =panelInfo->_height / (1/(1-fixedHeight))*nbPanelFactor; } else{ panelInfo->_preferedHeight /= layoutHeight; panelInfo->_height /= layoutHeight; } } } _panelYSpacing /= (layoutHeight+fixedHeight); } if (layoutWidth > 1) { for (auto panelInfo : _panelsInfo) { if (panelInfo->_constraint != PanelConstraint::MaxWidth) { panelInfo->_preferedWidth /= layoutWidth; panelInfo->_width /= layoutWidth; } } } // Expand _requestPanelHeight if necessary and asked if ((layoutHeight <(1-fixedHeight) ) && (layoutWidth <= 1) && (_autoExpand == true)) { expand (1.01); expand (1.001); expand (1.0001); } } /** * @Brief Increase panelHeight by step until layoutHeight reach (but not over step) 1.0 */ void LayoutVertical::expand (double ratio) { double fixedHeight; double layoutWidth, layoutHeight; do { // Increase panelHeight by step and keep the same ratio for panelSpacing _panelYSpacing *= ratio; for (auto panelInfo : _panelsInfo) { if(!panelInfo->_isHeightFixed) panelInfo->_height *= ratio; if (panelInfo->_constraint != PanelConstraint::MaxWidth) { if (panelInfo->_preferedWidth != -1) { panelInfo->_width = panelInfo->_preferedWidth; } else { panelInfo->_width *= ratio; } } } computeLayoutSize (layoutWidth, layoutHeight,fixedHeight); } while ((layoutHeight < 1.0-fixedHeight) && (layoutWidth <= 1.0)); // Restore last valid value for panelHeight and panelSpacing _panelYSpacing /= ratio; for (auto panelInfo : _panelsInfo) { if(!panelInfo->_isHeightFixed) panelInfo->_height /= ratio; if (panelInfo->_constraint != PanelConstraint::MaxWidth) { if (panelInfo->_preferedWidth == -1) { panelInfo->_width /= ratio; } } } computeLayoutSize (layoutWidth, layoutHeight,fixedHeight); } void LayoutVertical::computeLayoutSize (double &layoutWidth, double &layoutHeight, double &fixedHeight) { layoutWidth = 0; layoutHeight = 0; fixedHeight = 0; _firstPanelHeightDelta = 0; bool maxWidthConstraintFound = false; for (auto panelInfo : _panelsInfo) { if (panelInfo->_isHeightFixed) fixedHeight += (panelInfo->_height+ _panelYSpacing); else layoutHeight += (panelInfo->_height + _panelYSpacing); if (panelInfo->_width > layoutWidth) layoutWidth = panelInfo->_width; if ((maxWidthConstraintFound == false) && (panelInfo->_constraint == PanelConstraint::MaxWidth)) { maxWidthConstraintFound = true; _firstPanelHeightDelta = (_firstPanelHeightFactor-1.0) * panelInfo->_height; layoutHeight += _firstPanelHeightDelta; } } // Remove one spacing if more than 1 panel if (_panelsInfo.size () > 1) layoutHeight -= _panelYSpacing; } Bounds & LayoutVertical::getNextBounds (PanelConstraint panelConstraint) { PanelInfo *panelInfo = _panelsInfo.at(_curPanel); // Computes panels position on the layout depending on their constraints switch (panelConstraint) { case PanelConstraint::MaxWidth: _computedPanelBounds._x = 0; _computedPanelBounds._y = _curYPosition; _computedPanelBounds._width = 1.0; _computedPanelBounds._height = panelInfo->_height; // The first MaxWidth panel can have an extra panel height if (_maxWidthConstraintFound == false) { _maxWidthConstraintFound = true; _computedPanelBounds._height += _firstPanelHeightDelta; _curYPosition += _firstPanelHeightDelta; } _curPanel++; _curYPosition += (panelInfo->_height + _panelYSpacing); break; case PanelConstraint::Square: // Compute x position of the SquarePanel on the line (centered) _computedPanelBounds._x = 0.5 - (panelInfo->_width / 2.0); _computedPanelBounds._y = _curYPosition; _computedPanelBounds._width = panelInfo->_width; _computedPanelBounds._height = panelInfo->_height; _curPanel++; _curYPosition += (panelInfo->_height + _panelYSpacing); break; default: // TODO lever exception ici ??? break; } return _computedPanelBounds; } void LayoutVertical::computePanelsPosition (std::vector> _plots, std::map *parameterValues) { // Add panels constraint to the layout bool isFirstPlot = true; for (auto plot : boost::adaptors::reverse(_plots)) { if (!plot->isStandalone()) continue; double height = 0; if(plot->isHeightFixed()){ bool isLegendHeightAdded = false; for (auto parameter : plot->_parameterAxesList) { SeriesProperties lSeries; for (auto lSeries : parameter.getYSeriePropertiesList()) { boost::shared_ptr lAxis( plot->_panel->getAxis(lSeries.getXAxisId())); Font legendFont(lAxis->getLegendFont(plot->_panel.get())); PlPlotUtil::setPlFont(legendFont); CharSize legendSize = PlPlotUtil::getCharacterSizeInPlPage(plot->_panel->_page); unsigned int nbComponent = lSeries.getIndexList(parameterValues).size(); if(plot->subTypeName()=="tickPlot"){ if (!isLegendHeightAdded){ if(isFirstPlot){ height += 0.05; } height += (nbComponent + 2) * legendSize.second*1.4; isLegendHeightAdded = true; } else{ height += 0.05+ (nbComponent + 1) * legendSize.second*1.4; } } else if(plot->subTypeName()=="statusPlot"){ if(isFirstPlot){ if(!isLegendHeightAdded){ height += 5.3*legendSize.second; isLegendHeightAdded = true; } } else{ height += 0.025; } height += nbComponent*0.025 + nbComponent*legendSize.second*2.4; } else{ continue; } } } } this->addPanel ( plot->getLayoutConstraint(), plot->_panel->_preferedWidth, plot->_panel->_preferedHeight, plot->isHeightFixed(), height); if(isFirstPlot) isFirstPlot = false; } // Reset layout this->reset(); for (auto plot : boost::adaptors::reverse(_plots)) { if (!plot->isStandalone()) continue; plot->_panel->_bounds = this->getNextBounds (plot->getLayoutConstraint()); } } }