Skip to content

Commit

Permalink
avoid duplicated labels and overlaps [sanremo powered]
Browse files Browse the repository at this point in the history
  • Loading branch information
AndreaGuarracino committed Feb 7, 2024
1 parent daa1c9a commit 8418ea3
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 23 deletions.
44 changes: 36 additions & 8 deletions src/algorithms/draw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,20 @@ void get_layout(const std::vector<double> &X,

}


struct label_info_t {
double x, y;
std::string content;
// Simple constructor for convenience
label_info_t(double x, double y, std::string content) : x(x), y(y), content(std::move(content)) {}
};
bool is_too_close(double x, double y, const std::string& content, double threshold, std::vector<label_info_t>& placed_labels) {
for (const auto& label : placed_labels) {
if (label.content == content && std::abs(label.x - x) < threshold && std::abs(label.y - y) < threshold) {
return true; // Found a label too close with the same content
}
}
return false;
}
void draw_svg(std::ostream &out,
const std::vector<double> &X,
const std::vector<double> &Y,
Expand All @@ -108,7 +121,7 @@ void draw_svg(std::ostream &out,
const double& border,
const double& line_width,
std::vector<algorithms::color_t>& node_id_to_color,
ska::flat_hash_map<handlegraph::nid_t, std::string>& node_id_to_label_map) {
ska::flat_hash_map<handlegraph::nid_t, std::set<std::string>>& node_id_to_label_map) {

std::vector<std::vector<handle_t>> weak_components;
coord_range_2d_t rendered_range;
Expand All @@ -123,6 +136,8 @@ void draw_svg(std::ostream &out,
double width = rendered_range.width();
double height = rendered_range.height();

std::vector<label_info_t> placed_labels;

out << std::setprecision(std::numeric_limits<double>::digits10 + 1);
out << "<svg width=\"" << width << "\" height=\"" << height << "\" "
<< "viewBox=\"" << viewbox_x1 << " " << viewbox_y1
Expand Down Expand Up @@ -163,14 +178,27 @@ void draw_svg(std::ostream &out,
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))){
out << "<text font-family=\"Arial\" font-size=\"20\" fill=\"#000000\" stroke=\"#000000\" x=\"" << (X[a] * scale) - x_off << "\" y=\"" << (Y[a] * scale) - x_off << "\">";
auto vals = split(node_id_to_label_map[graph.get_id(handle)], '\n');
for (auto x : vals){
out << "<tspan x=\"" << (X[a] * scale) - x_off << "\" dy=\"1.0em\">" << x << "</tspan>";
// 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)) {
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 << "\">";
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 << "</text>"
<< std::endl;
}
out << "</text>"
<< std::endl;
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/algorithms/draw.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ void draw_svg(std::ostream &out,
const double& border,
const double& line_width,
std::vector<algorithms::color_t>& node_id_to_color,
ska::flat_hash_map<handlegraph::nid_t, std::string>& node_id_to_label_map);
ska::flat_hash_map<handlegraph::nid_t, std::set<std::string>>& node_id_to_label_map);

std::vector<uint8_t> rasterize(const std::vector<double> &X,
const std::vector<double> &Y,
Expand Down
18 changes: 4 additions & 14 deletions src/subcommand/draw_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,8 @@ int main_draw(int argc, char **argv) {
// handle targets from BED
std::vector<odgi::path_range_t> path_ranges;
std::vector<algorithms::color_t> node_id_to_color;
ska::flat_hash_map<handlegraph::nid_t, std::string> node_id_to_label_map; // To remember the unique node to label for each path range
ska::flat_hash_map<handlegraph::nid_t, std::set<std::string>> node_id_to_label_map; // To remember the unique node to label for each path range

if (_path_bed_file && !args::get(_path_bed_file).empty()) {
std::ifstream bed_in(args::get(_path_bed_file));
std::string line;
Expand Down Expand Up @@ -158,14 +159,6 @@ int main_draw(int argc, char **argv) {
} else {
path_color = algorithms::hash_color(path_range.name);
}

const step_handle_t first_step = graph.path_begin(path_range.begin.path);
const handle_t first_handle = graph.get_handle_of_step(first_step);
if (node_id_to_label_map.find(graph.get_id(first_handle)) == node_id_to_label_map.end()) {
node_id_to_label_map[graph.get_id(first_handle)] = path_range.name;
} else{
node_id_to_label_map[graph.get_id(first_handle)] = node_id_to_label_map[graph.get_id(first_handle)] + "\n" + path_range.name;
}
}

bool first_handle_taken = path_range.name.empty(); // To avoid checking if there is no name to take
Expand All @@ -177,11 +170,8 @@ int main_draw(int argc, char **argv) {

if (!first_handle_taken) {
first_handle_taken = true;
if (node_id_to_label_map.find(node_id) == node_id_to_label_map.end()) {
node_id_to_label_map[node_id] = path_range.name;
} else{
node_id_to_label_map[node_id] = node_id_to_label_map[node_id] + "\n" + path_range.name;
}
// The set automatically handles uniqueness of labels within the set.
node_id_to_label_map[node_id].insert(path_range.name);
}
});
}
Expand Down

0 comments on commit 8418ea3

Please sign in to comment.