/*========================================================================= Program: Visualization Toolkit Module: vtkChartWarning.cxx Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen All rights reserved. See Copyright.txt or http://www.kitware.com/Copyright.htm for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notice for more information. =========================================================================*/ #include "vtkChartWarning.h" // Get my new commands #include "vtkCommand.h" #include "vtkContext2D.h" #include "vtkContextScene.h" #include "vtkContextMouseEvent.h" #include "vtkPen.h" #include "vtkBrush.h" #include "vtkTextProperty.h" #include "vtkStdString.h" #include "vtkVectorOperators.h" #include "vtkAxis.h" #include "vtkChart.h" #include "vtkPlot.h" #include "vtkObjectFactory.h" //----------------------------------------------------------------------------- vtkStandardNewMacro(vtkChartWarning) //----------------------------------------------------------------------------- vtkChartWarning::vtkChartWarning() { this->TextPad = 16.; } //----------------------------------------------------------------------------- vtkChartWarning::~vtkChartWarning() { } //----------------------------------------------------------------------------- void vtkChartWarning::PrintSelf(ostream &os, vtkIndent indent) { this->Superclass::PrintSelf(os, indent); os << indent << "TextPad: " << this->TextPad << "\n"; } //----------------------------------------------------------------------------- bool vtkChartWarning::Paint(vtkContext2D* painter) { vtkChart* parent = vtkChart::SafeDownCast(this->GetParent()); if (!parent) { return true; } if (!this->ArePlotsImproperlyScaled(parent)) { // Don't render anything when the plots are OK. return true; } vtkRectf cbds = parent->GetSize(); float factorw = (this->Dimensions[0] + this->Dimensions[2]) / cbds.GetWidth(); float factorh = (this->Dimensions[1] + this->Dimensions[3]) / cbds.GetHeight(); float factor = factorw > factorh ? factorw : factorh; // Now convert factor from a proportion of the width/height to a scale factor for this->Dimension // if when the proportion (it's starting value) is too high. factor = factor > 0.5 ? 0.5 / factor : 1.; float dims[4]; for (int i = 0; i < 4; ++i) { dims[i] = factor * this->Dimensions[i]; } painter->GetTextProp()->SetVerticalJustificationToCentered(); painter->GetTextProp()->SetJustificationToCentered(); painter->GetTextProp()->SetBold(1); painter->GetTextProp()->SetColor(1.0, 1.0, 1.0); int fontSize; float lbds[4]; // label bounds for (fontSize = 64; fontSize > 4; --fontSize) { painter->GetTextProp()->SetFontSize(fontSize); painter->ComputeStringBounds(this->Label, lbds); if ( (lbds[3] - lbds[1] < cbds.GetHeight() - dims[3] - dims[1] - 2 * this->TextPad) && (lbds[2] - lbds[0] < cbds.GetWidth() - dims[2] - dims[0] - 2 * this->TextPad)) { break; } } painter->GetPen()->SetColor(167, 40, 40); painter->GetBrush()->SetColor(167, 40, 40); painter->GetPen()->SetLineType(vtkPen::SOLID_LINE); painter->GetPen()->SetWidth(2); // Draw both a rect and a diagonal to avoid the ugly antialiasing // artifact generated by drawing the rectangle as 2 triangles. painter->DrawRect( cbds.GetX() + dims[0], cbds.GetY() + dims[1], cbds.GetWidth() - dims[2] - dims[0], cbds.GetHeight() - dims[3] - dims[1]); painter->DrawLine( cbds.GetX() + dims[0], cbds.GetY() + dims[1], cbds.GetX() + dims[0] + cbds.GetWidth() - dims[2] - dims[0], cbds.GetY() + dims[1] + cbds.GetHeight() - dims[3] - dims[1]); //float x = cbds.GetX() + dims[0] - lbds[0] + 0.5 * lbds[2]; float x = cbds.GetX() + dims[0] - lbds[0] + 0.5 * (cbds.GetWidth() - dims[2] - dims[0]); float y = cbds.GetY() + dims[1] - lbds[1] + 0.5 * (cbds.GetHeight() - dims[3] - dims[1]); if (this->Label) { painter->DrawString(x, y, this->Label); } this->PaintChildren(painter); return true; } //----------------------------------------------------------------------------- bool vtkChartWarning::Hit(const vtkContextMouseEvent&) { return false; } //----------------------------------------------------------------------------- bool vtkChartWarning::ArePlotsImproperlyScaled(vtkChart* chart) { for (int i = 0; i < chart->GetNumberOfPlots(); ++i) { vtkPlot* plot = chart->GetPlot(i); if (!plot->GetVisible()) { continue; } plot->Update(); double bds[4]; plot->GetUnscaledInputBounds(bds); // If the bounds are invalid, ignore the plot (it has no extent) if (bds[1] < bds[0]) { continue; } // Are there improper values on the axes that are log-scaled? int badAxes = (bds[0] * bds[1] <= 0. ? 1 : 0) + (bds[2] * bds[3] <= 0. ? 2 : 0); int logAxes = (plot->GetXAxis()->GetLogScale() ? 1 : 0) + (plot->GetYAxis()->GetLogScale() ? 2 : 0); if (badAxes & logAxes) { if ( (!(badAxes & logAxes & 1) || plot->GetXAxis()->GetLogScaleActive()) && (!(badAxes & logAxes & 2) || plot->GetYAxis()->GetLogScaleActive())) { // Has the user changed the vtkAxis range so that no invalid // region of the unscaled axis is shown? If so, we do not // need to warn (for this plot). continue; } return true; } } return false; }