Skip to content

Commit

Permalink
make nodes a bit longer if we are sparsifying them
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreaGuarracino committed Feb 11, 2024
1 parent 6336c63 commit 22a4c43
Showing 1 changed file with 85 additions and 18 deletions.
103 changes: 85 additions & 18 deletions src/algorithms/draw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,74 @@ bool keep_node(const nid_t& node_id, const float f) {
// hash the node_id and check if it's accepted given our sparsification factor
return node_hash(node_id) < std::numeric_limits<uint64_t>::max() * f;
}
// Define a struct to hold the coordinates for simplicity
struct Coordinates {
double x1, y1, x2, y2;
};

// Function to adjust node length
Coordinates adjustNodeLength(double x1, double y1, double x2, double y2, double scale, double x_off, double y_off, double sparsification_factor) {
// Apply scale and offsets to original coordinates
x1 = (x1 * scale) - x_off;
y1 = (y1 * scale) + y_off;
x2 = (x2 * scale) - x_off;
y2 = (y2 * scale) + y_off;

// Calculate the original length
double length = sqrt(pow(x2 - x1, 2) + pow(y2 - y1, 2));

// Adjust length based on 1.0 / sparsification_factor
double new_length = sparsification_factor == 0 ? length : length * (1.0 / sparsification_factor);

// Calculate the midpoint
double mid_x = (x1 + x2) / 2.0;
double mid_y = (y1 + y2) / 2.0;

// Calculate the unit vector for the direction
double unit_x = (x2 - x1) / length;
double unit_y = (y2 - y1) / length;

// Calculate new endpoints using the new length
double half_new_length = new_length / 2.0;
double new_x1 = mid_x - half_new_length * unit_x;
double new_y1 = mid_y - half_new_length * unit_y;
double new_x2 = mid_x + half_new_length * unit_x;
double new_y2 = mid_y + half_new_length * unit_y;

// Return the new coordinates
return Coordinates{new_x1, new_y1, new_x2, new_y2};
}
Coordinates adjustNodeEndpoints(const handle_t& handle, const std::vector<double>& X, const std::vector<double>& Y, double scale, double x_off, double y_off, double sparsification_factor) {
// Original coordinates
uint64_t a = 2 * number_bool_packing::unpack_number(handle);
double x1 = (X[a] * scale) - x_off;
double y1 = (Y[a] * scale) + y_off;
double x2 = (X[a + 1] * scale) - x_off;
double y2 = (Y[a + 1] * scale) + y_off;

// Calculate the original length
double length = std::sqrt(std::pow(x2 - x1, 2) + std::pow(y2 - y1, 2));

// Adjust length based on 1.0 / sparsification_factor
double new_length = sparsification_factor == 0 ? length : length * (1.0 / sparsification_factor);

// Calculate the midpoint
double mid_x = (x1 + x2) / 2.0;
double mid_y = (y1 + y2) / 2.0;

// Calculate the unit vector for the direction
double unit_x = (x2 - x1) / length;
double unit_y = (y2 - y1) / length;

// Calculate new endpoints using the new length
double half_new_length = new_length / 2.0;
double new_x1 = mid_x - half_new_length * unit_x;
double new_y1 = mid_y - half_new_length * unit_y;
double new_x2 = mid_x + half_new_length * unit_x;
double new_y2 = mid_y + half_new_length * unit_y;

return Coordinates{new_x1, new_y1, new_x2, new_y2};
}

void draw_svg(std::ostream &out,
const std::vector<double> &X,
Expand Down Expand Up @@ -177,47 +245,46 @@ void draw_svg(std::ostream &out,
std::vector<handle_t> highlights;

for (auto& handle : component) {
uint64_t a = 2 * number_bool_packing::unpack_number(handle);
algorithms::color_t color = node_id_to_color.empty() ? COLOR_BLACK : node_id_to_color[graph.get_id(handle)];

if (!(sparsification_factor == 0 || keep_node(graph.get_id(handle), sparsification_factor) || node_id_to_label_map.count(graph.get_id(handle)))) {
continue; // Skip this node to output a lighter SVG (do not nodes with labels, if any)
}

Coordinates newEndpoints = adjustNodeEndpoints(handle, X, Y, scale, x_off, y_off, sparsification_factor);

if (color == COLOR_BLACK || color == COLOR_LIGHTGRAY) {
out << "<line x1=\""
<< (X[a] * scale) - x_off
<< newEndpoints.x1
<< "\" x2=\""
<< (X[a + 1] * scale) - x_off
<< newEndpoints.x2
<< "\" y1=\""
<< (Y[a] * scale) + y_off
<< newEndpoints.y1
<< "\" y2=\""
<< (Y[a + 1] * scale) + y_off
<< "\" stroke=\"" << to_hexrgb(color) //to_rgba(color) // with rgb, nodes are invisible with InkScape
<< newEndpoints.y2
<< "\" stroke=\"" << to_hexrgb(color)
<< "\" stroke-width=\"" << line_width
<< "\"/>"
<< std::endl;
} else {
highlights.push_back(handle);
}

double x = (X[a] * scale) - x_off;
double y = (Y[a] * scale) + y_off;
// Check if this is a node with a label
if (node_id_to_label_map.count(graph.get_id(handle))){
// Collect the labels that can be put without overlapping identical ones
std::vector<std::string> labels;
for (auto text : node_id_to_label_map[graph.get_id(handle)]){
if (!is_too_close(x, y, text, 30.0, placed_labels)) {
if (!is_too_close(newEndpoints.x2, newEndpoints.y2, text, 30.0, placed_labels)) {
labels.push_back(text);
}
}
// Check if there is something to label
if (!labels.empty()){
out << "<text font-family=\"Arial\" font-size=\"20\" fill=\"#000000\" stroke=\"#000000\" y=\"" << y << "\">";
out << "<text font-family=\"Arial\" font-size=\"20\" fill=\"#000000\" stroke=\"#000000\" y=\"" << newEndpoints.y2 << "\">";
for (auto text : labels){
out << "<tspan x=\"" << x << "\" dy=\"1.0em\">" << text << "</tspan>";
placed_labels.emplace_back(x, y, text); // Record the label's placement
out << "<tspan x=\"" << newEndpoints.x2 << "\" dy=\"1.0em\">" << text << "</tspan>";
placed_labels.emplace_back(newEndpoints.x2, newEndpoints.y2, text); // Record the label's placement
}
out << "</text>"
<< std::endl;
Expand All @@ -227,17 +294,17 @@ void draw_svg(std::ostream &out,

// color highlights
for (auto& handle : highlights) {
uint64_t a = 2 * number_bool_packing::unpack_number(handle);
Coordinates newEndpoints = adjustNodeEndpoints(handle, X, Y, scale, x_off, y_off, sparsification_factor);
algorithms::color_t color = node_id_to_color.empty() ? COLOR_BLACK : node_id_to_color[graph.get_id(handle)];
out << "<line x1=\""
<< (X[a] * scale) - x_off
<< newEndpoints.x1
<< "\" x2=\""
<< (X[a + 1] * scale) - x_off
<< newEndpoints.x2
<< "\" y1=\""
<< (Y[a] * scale) + y_off
<< newEndpoints.y1
<< "\" y2=\""
<< (Y[a + 1] * scale) + y_off
<< "\" stroke=\"" << to_hexrgb(color) //to_rgba(color) // with rgb, nodes are invisible with InkScape
<< newEndpoints.y2
<< "\" stroke=\"" << to_hexrgb(color) //to_rgba(color) // with rgba, nodes are invisible with InkScape
<< "\" stroke-width=\"" << line_width
<< "\"/>"
<< std::endl;
Expand Down

0 comments on commit 22a4c43

Please sign in to comment.