1 #ifndef DASH__PATTERN_VISUALIZER_H 2 #define DASH__PATTERN_VISUALIZER_H 12 #define PATTERN_VISUALIZER_HSV 15 #ifdef PATTERN_VISUALIZER_HSV 16 #include <dash/tools/Colorspace.h> 29 template<
typename PatternT>
34 typedef typename PatternT::index_type index_t;
49 const PatternT & _pattern;
63 RGB(
unsigned r,
unsigned g,
unsigned b) {
68 std::string hex()
const {
69 std::ostringstream ss;
70 ss <<
"#" << std::hex << std::uppercase << std::setfill(
'0');
71 ss << std::setw(2) << _r << std::setw(2) << _g << std::setw(2) << _b;
86 std::string title =
"",
88 std::string descr =
"")
90 , _title(
std::move(title))
91 , _descr(
std::move(descr))
94 _block_base_size = 26;
125 bool blocked_display =
false,
133 sz.tileszx = sz.tileszy = _tile_base_size;
134 sz.blockszx = sz.blockszy = _block_base_size;
135 if(!blocked_display) {
136 sz.grid_width = _pattern.extent(dimx);
137 sz.grid_height = _pattern.extent(dimy);
138 sz.grid_base = _tile_base_size + 2;
139 sz.gridx = sz.gridy = sz.grid_base;
141 sz.grid_width = _pattern.blockspec().extent(dimx);
142 sz.grid_height = _pattern.blockspec().extent(dimy);
143 sz.grid_base = _block_base_size + 2;
146 float block_format =
static_cast<float>(_pattern.blocksize(dimy)) /
147 static_cast<float>(_pattern.blocksize(dimx));
148 if (block_format < 1) {
149 block_format = 1.0 / block_format;
150 sz.blockszx *= block_format;
152 sz.blockszy *= block_format;
154 sz.gridx = sz.blockszx + 2;
155 sz.gridy = sz.blockszy + 2;
158 std::string title = _title;
159 replace_all(title,
"<",
"<");
160 replace_all(title,
">",
">");
162 os <<
"<svg xmlns=\"http://www.w3.org/2000/svg\"";
163 os <<
" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n";
166 os << R
"(<text x="10" y="15" )"; 167 os << R"( fill="grey" font-size=")" << _fontsz_title << "\">";
172 os <<
"<g transform=\"translate(10,30)\">\n";
173 draw_pane(os, blocked_display, sz, coords, dimx, dimy);
176 os <<
"</svg>" << std::endl;
187 int dimx,
int dimy) {
188 os <<
"<g transform=\"translate(10,10)\">" << std::endl;
191 os <<
"<g transform=\"translate(4,4)\">" << std::endl;
192 if(!blocked_display) {
199 os <<
"</g>" << std::endl;
201 draw_key(os, sz, sz.grid_width * sz.gridx + 2*sz.grid_base, 0);
202 os <<
"</g>" << std::endl;
211 int offsx = 0,
int offsy = 0) {
215 int lenx = sz.grid_width * sz.gridx + sz.grid_base;
216 int leny = sz.grid_height * sz.gridy + sz.grid_base;
219 os << R
"(<marker id="arrowhead" orient="auto")"; 220 os << R"( markerWidth="6" markerHeight="6")"; 221 os << R"( refX="0" refY="0")"; 222 os << " viewBox=\"-10 -15 30 30\">\n";
224 os <<
"M " << -10 <<
" " << -15 <<
" ";
225 os <<
"L " << 20 <<
" " << 0 <<
" ";
226 os <<
"L " << -10 <<
" " << 15 <<
" ";
227 os <<
"L " << 0 <<
" " << 0 <<
" ";
230 os <<
" style=\"fill:#808080;stroke:#808080;stroke-width:1\"";
236 os <<
"M " << startx <<
" " << starty <<
" ";
237 os <<
"h " << lenx <<
" ";
239 os <<
" style=\"fill:none;stroke:#808080;stroke-width:1\"";
240 os <<
" marker-end=\"url(#arrowhead)\"";
243 os <<
"<text x=\"" << startx + lenx/3 <<
"\" y=\"" << starty - _fontsz/2 <<
"\" ";
244 os << R
"( fill="grey" font-size=")" << _fontsz << "\" >";
245 os <<
"Dimension " << dimx << std::endl;
246 os <<
"</text>" << std::endl;
249 os <<
"M " << startx <<
" " << starty <<
" ";
250 os <<
"v " << leny <<
" ";
252 os <<
" style=\"fill:none;stroke:#808080;stroke-width:1\"";
253 os <<
" marker-end=\"url(#arrowhead)\"";
256 os <<
"<text x=\"" << startx - _fontsz/2 <<
"\" y=\"" << starty + leny/3 <<
"\" ";
257 os <<
" transform=\"rotate(-90," << startx - _fontsz/2 <<
"," << starty + leny/3 <<
")\" ";
258 os << R
"( fill="grey" font-size=")" << _fontsz << "\" >";
259 os <<
"Dimension " << dimy << std::endl;
260 os <<
"</text>" << std::endl;
268 int offsx = 0,
int offsy = 0) {
272 for (
int unit = 0; unit < _pattern.num_units(); unit++) {
274 starty = offsy + (unit * (sz.tileszy + 2));
275 os <<
"<rect x=\"" << startx <<
"\" y=\"" << starty <<
"\" ";
276 os <<
"height=\"" << sz.tileszy <<
"\" width=\"" << sz.tileszx <<
"\" ";
277 os << tilestyle(unit);
279 os <<
"</rect>" << std::endl;
281 starty += sz.tileszy - 2;
282 startx += sz.tileszx + 1;
283 os <<
"<text x=\"" << startx <<
"\" y=\"" << starty <<
"\" ";
284 os << R
"( fill="grey" font-size=")" << _fontsz << "\"";
286 os <<
"Unit " << unit << std::endl;
287 os <<
"</text>" << std::endl;
297 int dimx,
int dimy) {
298 for (
int i = 0; i < _pattern.extent(dimx); i++) {
299 for (
int j = 0; j < _pattern.extent(dimy); j++) {
301 os <<
"<rect x=\"" << (i * sz.gridx) <<
"\" y=\"" << (j * sz.gridy) <<
"\" ";
302 os <<
"height=\"" << sz.tileszy <<
"\" width=\"" << sz.tileszx <<
"\" ";
307 auto unit = _pattern.unit_at(coords);
308 auto loffs = _pattern.at(coords);
310 os << tilestyle(unit);
311 os <<
" tooltip=\"enable\" > ";
312 os <<
" <title>Elem: (" << j <<
"," << i <<
"),";
313 os <<
" Unit " << unit;
314 os <<
" Local offs. " << loffs;
318 os <<
"</rect>" << std::endl;
328 int dimx,
int dimy) {
329 std::array<index_t, PatternT::ndim()> block_coords;
330 std::array<index_t, PatternT::ndim()> block_begin_coords;
331 auto blockspec = _pattern.blockspec();
332 for (
int i = 0; i < blockspec.extent(dimx); i++) {
333 for (
int j = 0; j < blockspec.extent(dimy); j++) {
334 block_coords[dimx] = i;
335 block_coords[dimy] = j;
336 auto block_idx = _pattern.blockspec().at(block_coords);
337 auto block = _pattern.block(block_idx);
338 block_begin_coords[dimx] =
block.offset(dimx);
339 block_begin_coords[dimy] =
block.offset(dimy);
340 auto unit = _pattern.unit_at(block_begin_coords);
342 int i_grid = i * sz.gridx;
343 int j_grid = j * sz.gridy;
345 os <<
"<rect x=\"" << i_grid <<
"\" y=\"" << j_grid <<
"\" ";
346 os <<
"height=\"" << sz.blockszy <<
"\" width=\"" << sz.blockszx <<
"\" ";
347 os << tilestyle(unit);
349 os <<
"<!-- i=" << i <<
" j=" << j <<
"--> ";
350 os <<
"</rect>" << std::endl;
361 int dimx,
int dimy) {
363 std::array<index_t, PatternT::ndim()> block_coords = coords;
364 std::array<index_t, PatternT::ndim()> block_begin_coords = coords;
366 auto blockspec = _pattern.blockspec();
368 for (
int i = 0; i < blockspec.extent(dimx); i++) {
369 for (
int j = 0; j < blockspec.extent(dimy); j++) {
371 block_coords[dimx] = i;
372 block_coords[dimy] = j;
373 auto block_idx = _pattern.blockspec().at(block_coords);
374 auto block = _pattern.block(block_idx);
376 block_begin_coords[dimx] =
block.offset(dimx);
377 block_begin_coords[dimy] =
block.offset(dimy);
378 auto unit = _pattern.unit_at(block_begin_coords);
381 int i_grid =
block.offset(dimx)*sz.gridx - 1;
382 int j_grid =
block.offset(dimy)*sz.gridy - 1;
384 int width = (
block.extent(dimx)-1)*sz.gridx + sz.tileszx + 2;
385 int height = (
block.extent(dimy)-1)*sz.gridy + sz.tileszy + 2;
387 os <<
"<rect x=\"" << i_grid <<
"\" y=\"" << j_grid <<
"\" ";
388 os <<
"height=\"" << height <<
"\" width=\"" << width <<
"\" ";
389 os <<
"style=\"fill:#999999;stroke-width:0\" >";
390 os <<
"</rect>" << std::endl;
401 int dimx,
int dimy) {
406 for (
auto offset = 0; offset < _pattern.local_size(); offset++ ) {
407 auto coords = _pattern.coords(_pattern.global(offset));
409 endx = (coords[dimx] * sz.gridx) + sz.tileszx / 2;
410 endy = (coords[dimy] * sz.gridy) + sz.tileszy / 2;
412 if ( startx > 0 && starty > 0 ) {
413 os <<
"<line x1=\"" << startx <<
"\" y1=\"" << starty <<
"\"";
414 os <<
" x2=\"" << endx <<
"\" y2=\"" << endy <<
"\"";
415 os <<
" style=\"stroke:#E0E0E0;stroke-width:1\"/>";
416 os <<
" <!-- (" << offset <<
") -->";
420 os <<
"<circle cx=\"" << endx <<
"\" cy=\"" << endy << R
"(" r="1.5" )"; 421 os << " style=\"stroke:#E0E0E0;stroke-width:1;fill:#E0E0E0\" />";
431 #ifndef PATTERN_VISUALIZER_HSV 433 unsigned r = 0, g = 0, b = 0;
477 r += 20 * (unit / 8);
478 g += 20 * (unit / 8);
479 b += 20 * (unit / 8);
481 return RGB(r % 255, g % 255, b % 255);
486 float max = _pattern.num_units();
487 float nx = _pattern.teamspec().extent(1);
488 float ny = _pattern.teamspec().extent(0);
489 auto unit_coord = _pattern.teamspec().coords(unit);
492 float unit_h_perc =
static_cast<float>(unit) / max;
493 float unit_s_perc =
static_cast<float>(unit_coord[0]) / ny;
494 float unit_v_perc =
static_cast<float>(unit_coord[1]) / nx;
497 hsv.h = 360.0 * unit_h_perc;
498 hsv.s = 0.5 + 0.5 * unit_s_perc;
499 hsv.v = 0.5 + 0.4 * unit_v_perc;
501 auto rgb = dash::tools::color::hsv2rgb(hsv);
502 int r =
static_cast<int>(rgb.r * 255);
503 int g =
static_cast<int>(rgb.g * 255);
504 int b =
static_cast<int>(rgb.b * 255);
512 std::ostringstream ss;
513 ss <<
"style=\"fill:" << color(unit).hex() <<
";";
514 ss <<
"stroke-width:0\"";
518 bool replace_string(std::string & str,
519 const std::string & from,
520 const std::string & to)
522 size_t start_pos = str.find(from);
523 if (start_pos == std::string::npos) {
526 str.replace(start_pos, from.length(), to);
530 bool replace_all(std::string & str,
531 const std::string & from,
532 const std::string & to)
534 while (replace_string(str, from, to)) {};
542 #endif // DASH__PATTERN_VISUALIZER_H void draw_pane(std::ostream &os, bool blocked_display, const sizes &sz, std::array< index_t, PatternT::ndim()> coords, int dimx, int dimy)
Draws a pane (svg group) containing axes, key, tiles/blocks For the non blocked display (tiles) the l...
This class is a simple memory pool which holds allocates elements of size ValueType.
void draw_axes(std::ostream &os, const sizes &sz, int dimx, int dimy, int offsx=0, int offsy=0)
Draws the axes labeled with their dedicated dimension.
int32_t dart_unit_t
Data type for storing a unit ID.
Reduce operands to their maximum value.
void set_description(const std::string &str)
Sets a description for the pattern.
void draw_pattern(std::ostream &os, bool blocked_display=false, std::array< index_t, PatternT::ndim()> coords={}, int dimx=1, int dimy=0)
Outputs the pattern as a svg over the given output stream.
PatternVisualizer(const PatternT &pat, std::string title="", std::string descr="")
Constructs the Pattern Visualizer with a pattern instance.
void draw_tiles(std::ostream &os, const sizes &sz, std::array< index_t, PatternT::ndim()> coords, int dimx, int dimy)
Draws the seperate tiles of the pattern.
Take a generic pattern instance and visualize it as an SVG image.
constexpr dim_t ndim(const DimensionalType &d)
void set_title(const std::string &str)
Sets the title displayed above the pattern.
void draw_local_blocks(std::ostream &os, const sizes &sz, std::array< index_t, PatternT::ndim()> coords, int dimx, int dimy)
Draws the local blocks of the current unit (usually unit 0)
void draw_key(std::ostream &os, const sizes &sz, int offsx=0, int offsy=0)
Draws a list of units with their matching color.
see https://en.cppreference.com/w/cpp/feature_test for recommended feature tests
void draw_local_memlayout(std::ostream &os, const sizes &sz, int dimx, int dimy)
Draws the memory layout for the current unit (usually unit 0)
void draw_blocks(std::ostream &os, const sizes &sz, int dimx, int dimy)
Draws the blocks of the pattern.
constexpr auto block(OffsetT block_idx, const ViewType &view) -> typename std::enable_if<(!dash::view_traits< ViewType >::is_local::value), ViewBlockMod< ViewType > >::type
Blocks view from global view.