vtkPlotHistogram2D.cxx 7.96 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtk2DHistogramItem.h

  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.

=========================================================================*/

16
#include "vtkPlotHistogram2D.h"
17 18 19 20

#include "vtkAxis.h"
#include "vtkContext2D.h"
#include "vtkDoubleArray.h"
21
#include "vtkImageData.h"
22
#include "vtkMath.h"
23
#include "vtkScalarsToColors.h"
24
#include "vtkStringArray.h"
25 26 27 28

#include "vtkObjectFactory.h"

//-----------------------------------------------------------------------------
29
vtkStandardNewMacro(vtkPlotHistogram2D);
30 31

//-----------------------------------------------------------------------------
32
vtkPlotHistogram2D::vtkPlotHistogram2D()
33
{
34
  this->TooltipDefaultLabelFormat = "%x,  %y:  %v";
35 36 37
}

//-----------------------------------------------------------------------------
38
vtkPlotHistogram2D::~vtkPlotHistogram2D()
39 40 41
{
}

42
void vtkPlotHistogram2D::Update()
43 44 45 46
{
  this->GenerateHistogram();
}

47
//-----------------------------------------------------------------------------
48
bool vtkPlotHistogram2D::Paint(vtkContext2D *painter)
49 50 51 52 53 54
{
  if (this->Output)
    {
    if (this->Input)
      {
      double bounds[4];
55
      this->GetBounds(bounds);
56 57 58 59 60 61 62 63 64
      this->Position = vtkRectf(bounds[0], bounds[2],
                                bounds[1] - bounds[0], bounds[3] - bounds[2]);
      }
    painter->DrawImage(this->Position, this->Output);
    }
  return true;
}

//-----------------------------------------------------------------------------
65
void vtkPlotHistogram2D::SetInputData(vtkImageData *data, vtkIdType)
66
{
67
  // FIXME: Store the z too, for slices.
68 69 70 71
  this->Input = data;
}

//-----------------------------------------------------------------------------
72
vtkImageData * vtkPlotHistogram2D::GetInputImageData()
73 74 75 76 77
{
  return this->Input;
}

//-----------------------------------------------------------------------------
78
void vtkPlotHistogram2D::SetTransferFunction(vtkScalarsToColors *function)
79 80 81 82 83
{
  this->TransferFunction = function;
}

//-----------------------------------------------------------------------------
84
vtkScalarsToColors * vtkPlotHistogram2D::GetTransferFunction()
85 86 87 88
{
  return this->TransferFunction;
}

89
//-----------------------------------------------------------------------------
90
void vtkPlotHistogram2D::GetBounds(double bounds[4])
91 92 93 94 95 96
{
  if (this->Input)
    {
    int *extent = this->Input->GetExtent();
    bounds[0] = this->Input->GetOrigin()[0];
    bounds[1] = bounds[0] +
97
        (extent[1] - extent[0] + 1) * this->Input->GetSpacing()[0];
98 99 100

    bounds[2] = this->Input->GetOrigin()[1];
    bounds[3] = bounds[2] +
101
        (extent[3] - extent[2] + 1) * this->Input->GetSpacing()[1];
102 103 104 105 106 107 108 109
    }
  else
    {
    bounds[0] = bounds[1] = bounds[2] = bounds[3] = 0.0;
    }
}

//-----------------------------------------------------------------------------
110
void vtkPlotHistogram2D::SetPosition(const vtkRectf& pos)
111 112 113 114 115
{
  this->Position = pos;
}

//-----------------------------------------------------------------------------
116
vtkRectf vtkPlotHistogram2D::GetPosition()
117 118 119 120 121
{
  return this->Position;
}

//-----------------------------------------------------------------------------
122 123 124 125
vtkIdType vtkPlotHistogram2D::GetNearestPoint(const vtkVector2f& point,
                                              const vtkVector2f& tolerance,
                                              vtkVector2f* location)
{
126
  (void)tolerance;
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143
  double bounds[4];
  this->GetBounds(bounds);
  double spacing[3];
  this->Input->GetSpacing(spacing);

  if (point.GetX() < bounds[0] ||
      point.GetX() > bounds[1]+spacing[0] ||
      point.GetY() < bounds[2] ||
      point.GetY() > bounds[3]+spacing[1])
    {
    return -1;
    }

  // Can't use vtkImageData::FindPoint() / GetPoint(), as ImageData points are
  // rendered as the bottom left corner of a histogram cell, not the center
  int locX = vtkMath::Floor( (point.GetX() - bounds[0]) / spacing[0] );
  int locY = vtkMath::Floor( (point.GetY() - bounds[2]) / spacing[1] );
144
  int width = this->Input->GetExtent()[1] - this->Input->GetExtent()[0] + 1;
145 146 147 148 149 150 151 152 153

  // Discretize to ImageData point values
  location->SetX(locX * spacing[0] + bounds[0]);
  location->SetY(locY * spacing[1] + bounds[2]);

  return (locX + (locY * width));
}

//-----------------------------------------------------------------------------
154
vtkStdString vtkPlotHistogram2D::GetTooltipLabel(const vtkVector2d &plotPos,
155 156 157 158 159 160 161 162 163 164 165
                                                 vtkIdType seriesIndex,
                                                 vtkIdType)
{
  // This does not call the Superclass vtkPlot::GetTooltipLabel(), since the
  // format tags internally refer to different values
  vtkStdString tooltipLabel;
  vtkStdString &format = this->TooltipLabelFormat.empty() ?
        this->TooltipDefaultLabelFormat : this->TooltipLabelFormat;

  double bounds[4];
  this->GetBounds(bounds);
166
  int width = this->Input->GetExtent()[1] - this->Input->GetExtent()[0] + 1;
167
  int height = this->Input->GetExtent()[3] - this->Input->GetExtent()[2] + 1;
168 169 170 171 172 173 174 175 176 177 178 179
  int pointX = seriesIndex % width;
  int pointY = seriesIndex / width;

  // Parse TooltipLabelFormat and build tooltipLabel
  bool escapeNext = false;
  for (size_t i = 0; i < format.length(); ++i)
    {
    if (escapeNext)
      {
      switch (format[i])
        {
        case 'x':
180
          tooltipLabel += this->GetNumber(plotPos.GetX(), this->XAxis);
181 182
          break;
        case 'y':
183
          tooltipLabel += this->GetNumber(plotPos.GetY(), this->YAxis);
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201
          break;
        case 'i':
          if (this->XAxis->GetTickLabels() &&
              pointX >= 0 &&
              pointX < this->XAxis->GetTickLabels()->GetNumberOfTuples())
            {
            tooltipLabel += this->XAxis->GetTickLabels()->GetValue(pointX);
            }
          break;
        case 'j':
          if (this->YAxis->GetTickLabels() &&
              pointY >= 0 &&
              pointY < this->YAxis->GetTickLabels()->GetNumberOfTuples())
            {
            tooltipLabel += this->YAxis->GetTickLabels()->GetValue(pointY);
            }
          break;
        case 'v':
202 203 204 205 206 207
          if (pointX >= 0 && pointX < width && pointY >= 0 && pointY < height)
            {
            tooltipLabel +=
              this->GetNumber(this->Input->GetScalarComponentAsDouble(
                pointX, pointY, 0, 0), NULL);
            }
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230
          break;
        default: // If no match, insert the entire format tag
          tooltipLabel += "%";
          tooltipLabel += format[i];
          break;
        }
      escapeNext = false;
      }
    else
      {
      if (format[i] == '%')
        {
        escapeNext = true;
        }
      else
        {
        tooltipLabel += format[i];
        }
      }
    }
  return tooltipLabel;
}

231
//-----------------------------------------------------------------------------
232
void vtkPlotHistogram2D::GenerateHistogram()
233
{
234 235 236 237
  if (!this->Input)
    {
    return;
    }
238 239 240 241 242
  if (!this->Output)
    {
    this->Output = vtkSmartPointer<vtkImageData>::New();
    }
  this->Output->SetExtent(this->Input->GetExtent());
243
  this->Output->AllocateScalars(VTK_UNSIGNED_CHAR, 4);
244 245 246 247 248 249 250 251 252 253 254 255 256 257

  int dimension = this->Input->GetDimensions()[0] * this->Input->GetDimensions()[1];
  double *input = reinterpret_cast<double *>(this->Input->GetScalarPointer());
  unsigned char *output =
    reinterpret_cast<unsigned char*>(this->Output->GetScalarPointer(0,0,0));

  if (this->TransferFunction)
    {
    this->TransferFunction->MapScalarsThroughTable2(input, output, VTK_DOUBLE,
                                                    dimension, 1, 4);
    }
}

//-----------------------------------------------------------------------------
258
void vtkPlotHistogram2D::PrintSelf(ostream &os, vtkIndent indent)
259 260 261
{
  this->Superclass::PrintSelf(os, indent);
}