user6306985
user6306985

Reputation:

how to color a node of a graph using boost

I was trying to create a graph using boost.I want to change the properties of node and edge.i'm getting compilation error.sorry for the duplicate question

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
struct my_graph_writer {
    void operator()(std::ostream& out) const {
        out << "graph [bgcolor=lightgrey]" << std::endl;
        out << "node [shape=circle color=blue]" << std::endl;
        out << "edge [color=red]" << std::endl;
    }
} myGraphWrite;
int main()
{
    using namespace boost;
    typedef adjacency_list<vecS, vecS, directedS, no_property, int> Graph;
    Graph g;
    add_edge(0, 1, 123, g);
    std::ofstream gout;
    gout.open("graphname.dot");
    write_graphviz(gout,g,my_graph_writer);
}

I corrected as following.but fist node isn't changing .what is the problem?

#include <iostream>
#include <boost/graph/graphviz.hpp>
using namespace boost;

typedef adjacency_list< listS, vecS, directedS > digraph;

//  define a property writer to color the edges as required
class color_writer {
public:
      // constructor - needs reference to graph we are coloring
    color_writer( digraph& g ) : myGraph( g ) {}
      // functor that does the coloring

    template <class VertexOrEdge>
    void operator()(std::ostream& out, const VertexOrEdge& e) const {

        out << "graph [bgcolor=lightgrey]" << std::endl;
        out << "node [shape=Mrect color=blue]" << std::endl;
        out << "edge [color=red]" << std::endl;
    }
private:
    digraph& myGraph;
};

int main()
{
    using namespace std;

    // instantiate a digraph object with 8 vertices
    digraph g;

    // add some edges
    add_edge(0, 1, g);
    add_edge(1, 5, g);
    add_edge(5, 6, g);
    add_edge(2, 3, g);
    add_edge(2, 4, g);
    boost::write_graphviz(f, g,color_writer( g ));
    return 0;
}

Upvotes: 0

Views: 593

Answers (1)

llonesmiz
llonesmiz

Reputation: 155

As you can see here, the write_graphviz overload with three parameters expects that its third parameter be a VertexPropertyWriter, so you need to use (as you were originally) the five parameter overload. This was your approach:

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
using std::map;
struct my_node_writer {
    // my_node_writer() {}
    my_node_writer(Map& g_) : g (g_) {};
    template <class Vertex>
    void operator()(std::ostream& out, Vertex v) {
        out << " [label=\"" << v << "\"]" << std::endl;
    };
    Map g;
};

struct my_edge_writer {
    my_edge_writer(Map& g_) : g (g_) {};
    template <class Edge>
    void operator()(std::ostream& out, Edge e) {

        out << " [color=purple]" << std::endl;
        out << " [label=\"" << e  <<":" << g[e].miles << "\"]" << std::endl;
    };
    Map g;
};

struct my_graph_writer {
    void operator()(std::ostream& out) const {
        out << "graph [bgcolor=lightgrey]" << std::endl;
        out << "node [shape=circle color=blue]" << std::endl;

        out << "edge [color=red]" << std::endl;
    }
} myGraphWrite;

int main()
{
    using namespace boost;
    typedef adjacency_list<vecS, vecS, directedS, no_property, int> Graph;
    Graph g;
    add_edge(0, 1, 123, g);
    std::ofstream gout;
    gout.open("graphname.dot");
    write_graphviz(gout,map,my_node_writer(map),my_edge_writer(map),myGraphWrite);

}

You have two problems: you can't use g[e].miles with your graph as defined and Map does not refer to anything.

In order to solve the first problem you need to create a struct with a member_variable named miles and use it as your EdgeProperty in your graph definition. The easiest way to solve the Map problem is probably to make it a template parameter of the structs where it is needed (although you could also define your graph before your property writers and then use Graph instead of Map. This is the code after making those changes:

Running on Coliru:

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
using std::map;

template <typename Map>
struct my_node_writer {
    // my_node_writer() {}
    my_node_writer(Map& g_) : g (g_) {};
    template <class Vertex>
    void operator()(std::ostream& out, Vertex v) {
        out << " [label=\"" << v << "\"]" << std::endl;
    };
    Map g;
};

template <typename Map>
my_node_writer<Map> node_writer(Map& map) { return my_node_writer<Map>(map); }

template <typename Map>
struct my_edge_writer {
    my_edge_writer(Map& g_) : g (g_) {};
    template <class Edge>
    void operator()(std::ostream& out, Edge e) {

        out << " [color=purple]" << std::endl;
        out << " [label=\"" << e  <<":" << g[e].miles << "\"]" << std::endl;
    };
    Map g;
};

template <typename Map>
my_edge_writer<Map> edge_writer(Map& map) { return my_edge_writer<Map>(map); }

struct my_graph_writer {
    void operator()(std::ostream& out) const {
        out << "graph [bgcolor=lightgrey]" << std::endl;
        out << "node [shape=circle color=blue]" << std::endl;

        out << "edge [color=red]" << std::endl;
    }
} myGraphWrite;

struct edge_prop
{
    int miles;
};

int main()
{
    using namespace boost;
    typedef adjacency_list<vecS, vecS, directedS, no_property, edge_prop> Graph;
    Graph g;
    add_edge(0, 1, edge_prop{123}, g);

    write_graphviz(std::cout,g,node_writer(g),edge_writer(g),myGraphWrite);

}

Upvotes: 1

Related Questions