You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

233 lines
6.2 KiB
C++

/*=========================================================================
Program: Visualization Toolkit
Module: TestDiagram.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.
=========================================================================*/
/**
* @class vtkTanglegramItem
* @brief Display two related trees
*
*
* This item draws two trees with connections between their leaf nodes.
* Use SetTable() to specify what leaf nodes correspond to one another
* between the two trees. See the documentation for this function for
* more details on how this table should be formatted.
*
* .SEE ALSO
* vtkTree vtkTable vtkDendrogramItem vtkNewickTreeReader
*/
#ifndef vtkTanglegramItem_h
#define vtkTanglegramItem_h
#include "vtkViewsInfovisModule.h" // For export macro
#include "vtkContextItem.h"
#include "vtkSmartPointer.h" // For SmartPointer ivars
#include "vtkTable.h" // For get/set
class vtkDendrogramItem;
class vtkLookupTable;
class vtkStringArray;
class vtkTree;
class VTKVIEWSINFOVIS_EXPORT vtkTanglegramItem : public vtkContextItem
{
public:
static vtkTanglegramItem* New();
vtkTypeMacro(vtkTanglegramItem, vtkContextItem);
void PrintSelf(ostream& os, vtkIndent indent) override;
/**
* Set the first tree
*/
virtual void SetTree1(vtkTree* tree);
/**
* Set the second tree
*/
virtual void SetTree2(vtkTree* tree);
//@{
/**
* Get/Set the table that describes the correspondences between the
* two trees. The first column should contain the names of the leaf
* nodes from tree #1. The columns of this table should be named
* after the leaf nodes of tree #2. A non-zero cell should be used
* to create a connection between the two trees. Different numbers
* in the table will result in connections being drawn in different
* colors.
*/
vtkTable* GetTable();
void SetTable(vtkTable* table);
//@}
//@{
/**
* Get/Set the label for tree #1.
*/
vtkGetStringMacro(Tree1Label);
vtkSetStringMacro(Tree1Label);
//@}
//@{
/**
* Get/Set the label for tree #2.
*/
vtkGetStringMacro(Tree2Label);
vtkSetStringMacro(Tree2Label);
//@}
/**
* Set which way the tanglegram should face within the visualization.
* The default is for tree #1 to be drawn left to right.
*/
void SetOrientation(int orientation);
/**
* Get the current orientation.
*/
int GetOrientation();
//@{
/**
* Get/Set the smallest font size that is still considered legible.
* If the current zoom level requires our vertex labels to be smaller
* than this size the labels will not be drawn at all. Default value
* is 8 pt.
*/
vtkGetMacro(MinimumVisibleFontSize, int);
vtkSetMacro(MinimumVisibleFontSize, int);
//@}
//@{
/**
* Get/Set how much larger the dendrogram labels should be compared to the
* vertex labels. Because the vertex labels automatically resize based
* on zoom levels, this is a relative (not absolute) size. Default value
* is 4 pts larger than the vertex labels.
*/
vtkGetMacro(LabelSizeDifference, int);
vtkSetMacro(LabelSizeDifference, int);
//@}
//@{
/**
* Get/Set how wide the correspondence lines should be. Default is two pixels.
*/
vtkGetMacro(CorrespondenceLineWidth, float);
vtkSetMacro(CorrespondenceLineWidth, float);
//@}
//@{
/**
* Get/Set how wide the edges of the trees should be. Default is one pixel.
*/
float GetTreeLineWidth();
void SetTreeLineWidth(float width);
//@}
/**
* Returns true if the transform is interactive, false otherwise.
*/
bool Hit(const vtkContextMouseEvent& mouse) override;
/**
* Propagate any double click onto the dendrograms to check if any
* subtrees should be collapsed or expanded.
*/
bool MouseDoubleClickEvent(const vtkContextMouseEvent& event) override;
protected:
vtkTanglegramItem();
~vtkTanglegramItem() override;
/**
* Update the bounds of our two dendrograms.
*/
void RefreshBuffers(vtkContext2D* painter);
/**
* Calculate and set an appropriate position for our second dendrogram.
*/
void PositionTree2();
/**
* Draw the lines between the corresponding vertices of our two dendrograms.
*/
void PaintCorrespondenceLines(vtkContext2D* painter);
/**
* Draw the labels of our two dendrograms.
*/
void PaintTreeLabels(vtkContext2D* painter);
/**
* Reorder the children of tree #2 to minimize the amount of crossings
* in our tanglegram.
*/
void ReorderTree();
/**
* Helper function used by ReorderTree.
* Rearrange the children of the specified parent vertex in order to minimize
* tanglegram crossings.
*/
void ReorderTreeAtVertex(vtkIdType parent, vtkTree* tree);
/**
* Helper function used by ReorderTreeAtVertex. Get the average height of
* the vertices that correspond to the vertex parameter. This information
* is used to determine what order sibling vertices should have within the
* tree.
*/
double GetPositionScoreForVertex(vtkIdType vertex, vtkTree* tree);
/**
* Initialize the lookup table used to color the lines between the two
* dendrograms.
*/
void GenerateLookupTable();
/**
* Paints the tree & associated table as a heatmap.
*/
bool Paint(vtkContext2D* painter) override;
private:
vtkSmartPointer<vtkDendrogramItem> Dendrogram1;
vtkSmartPointer<vtkDendrogramItem> Dendrogram2;
vtkSmartPointer<vtkLookupTable> LookupTable;
vtkSmartPointer<vtkTable> Table;
vtkStringArray* Tree1Names;
vtkStringArray* Tree2Names;
vtkStringArray* SourceNames;
double Tree1Bounds[4];
double Tree2Bounds[4];
double Spacing;
double LabelWidth1;
double LabelWidth2;
bool PositionSet;
bool TreeReordered;
char* Tree1Label;
char* Tree2Label;
int Orientation;
int MinimumVisibleFontSize;
int LabelSizeDifference;
float CorrespondenceLineWidth;
vtkTanglegramItem(const vtkTanglegramItem&) = delete;
void operator=(const vtkTanglegramItem&) = delete;
};
#endif