A library for working with phylogenetic and population genetic data.
v0.27.0
formats/svg/matrix.cpp
Go to the documentation of this file.
1 /*
2  Genesis - A toolkit for working with phylogenetic data.
3  Copyright (C) 2014-2020 Lucas Czech and HITS gGmbH
4 
5  This program is free software: you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation, either version 3 of the License, or
8  (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program. If not, see <http://www.gnu.org/licenses/>.
17 
18  Contact:
19  Lucas Czech <lucas.czech@h-its.org>
20  Exelixis Lab, Heidelberg Institute for Theoretical Studies
21  Schloss-Wolfsbrunnenweg 35, D-69118 Heidelberg, Germany
22 */
23 
32 
36 
40 
41 #include <stdexcept>
42 
43 namespace genesis {
44 namespace utils {
45 
46 // =================================================================================================
47 // Svg Matrix
48 // =================================================================================================
49 
51  Matrix<Color> const& mat,
52  SvgMatrixSettings settings,
53  std::vector<std::string> const& row_labels,
54  std::vector<std::string> const& col_labels
55 ) {
56  // Result
57  SvgGroup group;
58 
59  // Input checks.
60  if( ! row_labels.empty() && row_labels.size() != mat.rows() ) {
61  throw std::invalid_argument(
62  "Svg Matrix drawing expects same number of row labels that the matrix has rows. "
63  );
64  }
65  if( ! col_labels.empty() && col_labels.size() != mat.cols() ) {
66  throw std::invalid_argument(
67  "Svg Matrix drawing expects same number of col labels that the matrix has cols. "
68  );
69  }
70 
71  // Fill the matrix.
72  SvgGroup rct_gr;
73  for( size_t r = 0; r < mat.rows(); ++r ) {
74  for( size_t c = 0; c < mat.cols(); ++c ) {
75 
76  // Get pixel dimensions.
77  double x = c * settings.pixel_width;
78  double y = r * settings.pixel_height;
79  double w = settings.pixel_width;
80  double h = settings.pixel_height;
81 
82  // Add overlap where needed (all except last col/row).
83  if( c < mat.cols() - 1 ) {
84  w += settings.width_overlap;
85  }
86  if( r < mat.rows() - 1 ) {
87  h += settings.height_overlap;
88  }
89 
90  group << SvgRect(
91  x, y, w, h,
93  SvgFill( mat( r, c ))
94  );
95  }
96  }
97  group << std::move( rct_gr );
98 
99  // Fill the row labels, if needed.
100  if( ! row_labels.empty() ) {
101  SvgGroup row_gr;
102  for( size_t i = 0; i < row_labels.size(); ++i ) {
103  auto label = settings.label_template;
104  label.text = row_labels[i];
105  label.anchor = SvgText::Anchor::kEnd;
106  label.alignment_baseline = SvgText::AlignmentBaseline::kMiddle;
107 
108  double const x = - settings.pixel_width / 2.0;
109  double const y = ( i * settings.pixel_height ) + ( settings.pixel_height / 2.0 );
110  label.transform.append( SvgTransform::Translate( x, y ));
111  row_gr << std::move( label );
112  }
113  group << std::move( row_gr );
114  }
115 
116  // Fill the col labels, if needed.
117  if( ! col_labels.empty() ) {
118  SvgGroup col_gr;
119  for( size_t i = 0; i < col_labels.size(); ++i ) {
120  auto label = settings.label_template;
121  label.text = col_labels[i];
122  label.anchor = SvgText::Anchor::kStart;
123  label.alignment_baseline = SvgText::AlignmentBaseline::kMiddle;
124 
125  double const x = ( i * settings.pixel_width ) + ( settings.pixel_width / 2.0 );
126  double const y = - settings.pixel_height / 2.0;
127  label.transform.append( SvgTransform::Translate( x, y ));
128  label.transform.append( SvgTransform::Rotate( settings.column_label_rotation ));
129  col_gr << std::move( label );
130  }
131  group << std::move( col_gr );
132  }
133 
134  return group;
135 }
136 
138  Matrix<Color> const& mat,
139  SvgMatrixSettings settings,
140  std::vector<std::string> const& row_labels
141 ) {
142  return make_svg_matrix(
143  mat, settings, row_labels, std::vector<std::string>()
144  );
145 }
146 
148  Matrix<Color> const& mat,
149  SvgMatrixSettings settings
150 ) {
151  return make_svg_matrix(
152  mat, settings, std::vector<std::string>(), std::vector<std::string>()
153  );
154 }
155 
156 } // namespace utils
157 } // namespace genesis
genesis::utils::Matrix::cols
size_t cols() const
Definition: containers/matrix.hpp:167
genesis::utils::SvgMatrixSettings::column_label_rotation
double column_label_rotation
Rotation of the column labels.
Definition: formats/svg/matrix.hpp:78
genesis::utils::SvgTransform::Rotate
Definition: attributes.hpp:297
genesis::utils::make_svg_matrix
SvgGroup make_svg_matrix(Matrix< Color > const &mat, SvgMatrixSettings settings, std::vector< std::string > const &row_labels, std::vector< std::string > const &col_labels)
Definition: formats/svg/matrix.cpp:50
shapes.hpp
genesis::utils::SvgText::Anchor::kEnd
@ kEnd
genesis::utils::SvgMatrixSettings::height_overlap
double height_overlap
Definition: formats/svg/matrix.hpp:68
group.hpp
genesis::utils::SvgText::Anchor::kStart
@ kStart
genesis::utils::Matrix
Definition: placement/function/emd.hpp:53
genesis::utils::SvgStroke
Definition: attributes.hpp:49
genesis::utils::SvgMatrixSettings::pixel_height
double pixel_height
Definition: formats/svg/matrix.hpp:65
genesis::utils::SvgRect
Definition: shapes.hpp:110
genesis::utils::SvgTransform::Translate
Definition: attributes.hpp:252
genesis::utils::SvgMatrixSettings::pixel_width
double pixel_width
Definition: formats/svg/matrix.hpp:64
genesis::utils::SvgText::text
std::string text
Definition: text.hpp:147
genesis::utils::SvgMatrixSettings::width_overlap
double width_overlap
Definition: formats/svg/matrix.hpp:67
matrix.hpp
genesis::utils::SvgMatrixSettings
Definition: formats/svg/matrix.hpp:56
genesis::utils::SvgStroke::Type::kNone
@ kNone
genesis
Container namespace for all symbols of genesis in order to keep them separate when used as a library.
Definition: placement/formats/edge_color.cpp:42
genesis::utils::SvgFill
Definition: attributes.hpp:131
genesis::utils::SvgMatrixSettings::label_template
utils::SvgText label_template
Definition: formats/svg/matrix.hpp:70
color.hpp
Header of Color class.
genesis::utils::SvgText::AlignmentBaseline::kMiddle
@ kMiddle
text.hpp
operators.hpp
Matrix operators.
matrix.hpp
genesis::utils::Matrix::rows
size_t rows() const
Definition: containers/matrix.hpp:162
genesis::utils::SvgGroup
Definition: group.hpp:50