Skip to content

Commit

Permalink
Merge pull request #36 from asalzburger/feat-add-grid-display
Browse files Browse the repository at this point in the history
feat: adding connection to grid view
  • Loading branch information
asalzburger authored Mar 30, 2023
2 parents 8a5c297 + 84ea10d commit 6253710
Show file tree
Hide file tree
Showing 4 changed files with 210 additions and 9 deletions.
88 changes: 85 additions & 3 deletions core/include/actsvg/core/connectors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace actsvg {

namespace connectors {

// The type of connections that exist
enum type { e_highlight, e_associate_id, e_associate_info };

/** Helper method to connect objects
Expand All @@ -32,15 +33,15 @@ enum type { e_highlight, e_associate_id, e_associate_info };
* @param on_off_ are the connection effects
*
* In case of e.g. a grid surface connection:
* - the @param sources_ are the grid tiles
* - the @param targets_ are the surfaces
* - the @param sources_ [in, out]are the grid tiles
* - the @param targets_ [in, out] are the surfaces
* - the @param s_t_connections are the indices which type of association
* - the @param font_ is used for associate info action
*
**/
static inline std::vector<svg::object> connect_action(
std::vector<svg::object> &sources_, std::vector<svg::object> &targets_,
const std::vector<std::vector<size_t> > &s_t_connections_, bool ls_ = true,
const std::vector<std::vector<size_t>> &s_t_connections_, bool ls_ = true,
const std::array<std::string, 2u> &on_off_ = {"mouseover", "mouseout"},
const std::vector<connectors::type> &ct_ = {e_highlight, e_associate_info},
const style::font &font_ = style::font()) {
Expand Down Expand Up @@ -138,5 +139,86 @@ static inline std::vector<svg::object> connect_action(
}
return additional_connections;
}

struct name_extractor {
/// Strips the name out of an object
template <typename source_type>
auto name(const source_type &s_) {
return s_._name;
}
};

struct id_extractor {
/// Strips the id out of an object
template <typename source_type>
auto name(const source_type &s_) {
return s_._id;
}
};

/** Helper method to connect the appearance of an object to some other
* objects
*
* @tparam source_objects_type the type of the source objects
* @tparam source_name_getter_type the way the name is provided
*
* @param sources_ are the source objects
* @param targests_ [in, out] are the target objects
* @param s_t_connections_ an association which source belongs to which target
*
**/
template <typename source_objects_type,
typename source_name_getter_type = name_extractor>
void connect_action(const source_objects_type &sources_,
std::vector<svg::object> &targets_,
const std::vector<std::vector<size_t>> &s_t_connections_) {

// Ignore if the s_t_connections and sources don't match up
if (sources_.size() != s_t_connections_.size()) {
return;
}

// Loop over the sources and and register the connections
for (auto [is, s] : utils::enumerate(sources_)) {
// Isolate the name
std::string sid = source_name_getter_type{}.name(s);

// Get the target list and create the connection
auto st_cs = s_t_connections_[is];

for (auto it : st_cs) {
// Ignore if not available
if (it >= targets_.size()) {
continue;
}

svg::object &t = targets_[it];
t._attribute_map["display"] = "none";

// Object information to appear
svg::object on;
on._tag = "animate";
on._attribute_map["fill"] = "freeze";
on._attribute_map["attributeName"] = "display";
on._attribute_map["from"] = "none";
on._attribute_map["to"] = "block";
on._attribute_map["begin"] = sid + __d + "mouseout";

svg::object off;

off._tag = "animate";
off._attribute_map["fill"] = "freeze";
off._attribute_map["attributeName"] = "display";
off._attribute_map["to"] = "none";
off._attribute_map["from"] = "block";
off._attribute_map["begin"] = sid + __d + "mouseover";

// Store the animation
t._sub_objects.push_back(off);
t._sub_objects.push_back(on);
}
}
}

} // namespace connectors
} // namespace actsvg
31 changes: 25 additions & 6 deletions meta/include/actsvg/display/grids.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

#include "actsvg/core.hpp"
#include "actsvg/proto/grid.hpp"
#include "actsvg/styles/defaults.hpp"

namespace actsvg {

Expand All @@ -33,22 +32,42 @@ namespace display {
*/
svg::object grid(const std::string& id_, const proto::grid& g_) {

// The grid object
svg::object g;
g._id = id_;
g._tag = "g";

// Get the tiles
std::vector<svg::object> grid_tiles;

// Generate the grid
if (g_._type == proto::grid::type::e_r_phi) {
g = draw::tiled_polar_grid(id_, g_._edges_0, g_._edges_1, __g_fill,
__g_stroke);
} else {
grid_tiles = draw::tiled_polar_grid(id_, g_._edges_0, g_._edges_1,
g_._fill, g_._stroke)
._sub_objects;

} else {
// cartesian view grid
std::vector<scalar> edges_1 = g_._edges_1;
if (g_._type == proto::grid::type::e_z_phi) {
std::for_each(edges_1.begin(), edges_1.end(),
[&](auto& e) { e *= g_._reference_r; });
}
grid_tiles = draw::tiled_cartesian_grid(id_, g_._edges_0, edges_1,
g_._fill, g_._stroke)
._sub_objects;
}

g = draw::tiled_cartesian_grid(id_, g_._edges_0, edges_1, __g_fill,
__g_stroke);
if (not g_._connections.empty()) {
std::vector<svg::object> local_connections = g_._connections;
connectors::connect_action<decltype(grid_tiles),
connectors::id_extractor>(
grid_tiles, local_connections, g_._connection_associations);
g.add_objects(local_connections);
} else {
g.add_objects(g_._connections);
}
g.add_objects(grid_tiles);

return g;
}
Expand Down
14 changes: 14 additions & 0 deletions meta/include/actsvg/proto/grid.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <vector>

#include "actsvg/core/defs.hpp"
#include "actsvg/styles/defaults.hpp"

namespace actsvg {

Expand Down Expand Up @@ -39,6 +40,19 @@ struct grid {

/// Reference r for drawing
scalar _reference_r = 0.;

/// Connections
std::vector<svg::object> _connections;
/// Connection types
std::vector<connectors::type> _connection_types = {};
/// Associations
std::vector<std::vector<size_t>> _connection_associations = {};

/// Stroke
style::fill _fill = defaults::__g_fill;

/// Stroke
style::stroke _stroke = defaults::__g_stroke;
};

} // namespace proto
Expand Down
86 changes: 86 additions & 0 deletions tests/meta/grid.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@

#include <gtest/gtest.h>

#include <string>
#include <vector>

#include "actsvg/display/grids.hpp"
#include "actsvg/styles/defaults.hpp"

Expand Down Expand Up @@ -45,6 +48,29 @@ TEST(proto, grid_z_phi_closed) {
g._edges_0 = {-200, -100, 0, 100, 200};
g._edges_1 = {-0.75 * M_PI, -0.5 * M_PI, -0.25 * M_PI,
0., 0.25 * M_PI, 0.5 * M_PI};
// Create connection text
size_t ig = 0u;
std::vector<svg::object> tile_ids;
for (size_t i1 = 0; i1 + 1u < g._edges_1.size(); ++i1) {
for (size_t i0 = 0; i0 + 1u < g._edges_0.size(); ++i0) {
std::string global_id = "g = [";
global_id += std::to_string(ig++) + std::string("]");
std::string local_id = "l = [";
local_id += std::to_string(i0) + std::string(", ");
local_id += std::to_string(i1) + std::string("]");
std::string tile_name = std::string("tile_") + std::to_string(i0) +
std::string("_") + std::to_string(i1);
point2 text_pos = {static_cast<scalar>(0.9 * g._edges_0[i0] +
0.1 * g._edges_0[i0 + 1u]),
static_cast<scalar>((0.3 * g._edges_1[i1] +
0.7 * g._edges_1[i1 + 1u]) *
g._reference_r)};
tile_ids.push_back(
draw::text(tile_name, text_pos, {global_id, local_id}));
}
}

g._connections = tile_ids;

svg::object d_grid_z_phi = display::grid("grid_z_phi", g);

Expand Down Expand Up @@ -86,6 +112,29 @@ TEST(proto, grid_r_phi_full) {
g._edges_1 = {-M_PI, -0.75 * M_PI, -0.5 * M_PI, -0.25 * M_PI, 0.,
0.25 * M_PI, 0.5 * M_PI, 0.75 * M_PI, M_PI};

// Create connection text
size_t ig = 0u;
std::vector<svg::object> tile_ids;
for (size_t i1 = 0; i1 + 1u < g._edges_1.size(); ++i1) {
for (size_t i0 = 0; i0 + 1u < g._edges_0.size(); ++i0) {
scalar r = 0.5 * (g._edges_0[i0] + g._edges_0[i0 + 1u]);
scalar phi = 0.5 * (g._edges_1[i1] + g._edges_1[i1 + 1u]);
std::string global_id = "g = [";
global_id += std::to_string(ig++) + std::string("]");
std::string local_id = "l = [";
local_id += std::to_string(i0) + std::string(", ");
local_id += std::to_string(i1) + std::string("]");
std::string tile_name = std::string("tile_") + std::to_string(i0) +
std::string("_") + std::to_string(i1);

point2 text_pos = {r * cos(phi), r * sin(phi)};
tile_ids.push_back(
draw::text(tile_name, text_pos, {global_id, local_id}));
}
}

g._connections = tile_ids;

svg::object d_grid_r_phi = display::grid("grid_r_phi", g);

svg::file gfile_r_phi;
Expand All @@ -96,3 +145,40 @@ TEST(proto, grid_r_phi_full) {
rstream << gfile_r_phi;
rstream.close();
}

TEST(proto, grid_r_phi_full_connections) {

proto::grid g;
ASSERT_TRUE(g._type == proto::grid::type::e_r_phi);

g._edges_0 = {200., 300., 400., 500.};
g._edges_1 = {-M_PI, -0.75 * M_PI, -0.5 * M_PI, -0.25 * M_PI, 0.,
0.25 * M_PI, 0.5 * M_PI, 0.75 * M_PI, M_PI};

// Create connection text
std::vector<svg::object> rows;
svg::object row0 = draw::text("row_0", {0., 0.}, {"row 0"});
svg::object row1 = draw::text("row_1", {0., 0.}, {"row 1"});
svg::object row2 = draw::text("row_2", {0., 0.}, {"row 2"});
g._connections = {row0, row1, row2};

std::vector<std::vector<size_t> > associations;
for (size_t i0 = 0; i0 + 1u < g._edges_0.size(); ++i0) {
for (size_t i1 = 0; i1 + 1u < g._edges_1.size(); ++i1) {
associations.push_back({i0});
}
}

g._connection_types = {connectors::type::e_highlight};
g._connection_associations = associations;

svg::object d_grid_r_phi = display::grid("grid_r_phi", g);

svg::file gfile_r_phi;
gfile_r_phi.add_object(d_grid_r_phi);

std::ofstream rstream;
rstream.open("test_meta_grid_r_phi_connections.svg");
rstream << gfile_r_phi;
rstream.close();
}

0 comments on commit 6253710

Please sign in to comment.