使用Graph for Scala将带有自定义节点和边的图转换为Dot格式

时间:2016-02-14 00:43:35

标签: scala graph

我使用自定义节点和边创建了一个简单的图形,如下所示:

case class Agent(val name: String) {
   override def toString = name // without Airport-prefix
}

class Ask[N](nodes: Product, val message: String, val msgNo: String) 
    extends DiEdge[N](nodes)
    with    ExtendedKey[N]
    with    EdgeCopy[Ask]
    with    OuterEdge[N,Ask] {

  def mesage = message
  def keyAttributes = Seq(msgNo)
  override def copy[NN](newNodes: Product) =
    new Ask[NN](newNodes,message, msgNo)
}

object Ask {
  def apply(src: Agent, dst: Agent, message:String, msgNo: String) =
    new Ask[Agent](NodeProduct(src, dst), message, msgNo)

  def unapply(e: Ask[Agent]) = Some(e)
}


implicit class AskAssoc[A <: Agent](val e: LDiEdge[A]) {
  @inline def ## (message: String, msgNo: String) =
    new Ask[A](e.nodes, message,msgNo) //with OuterEdge[A,Ask]
}

val (ham, ny) = (Agent("HAM"), Agent("JFK")) // two nodes
val g = Graph[Agent,Ask](((ham ~+> ny) ("Ask") ) ## ("messgae", "kfree"))

所有这一切都很好。现在,我想将g转换为DOT格式。

我首先按如下方式定义root:

val root = DotRootGraph(directed = true,
 id       = Some("Wikipedia_Example"))

但是我无法绕过EdgeTransformer。我认为#EdgeT不是从自定义图中提取innerEdge的正确方法。你能帮帮我吗?

def edgeTransformer(innerEdge: Graph[Agent,Ask]#EdgeT):
        Option[(DotGraph,DotEdgeStmt)] = innerEdge.edge match {
            case LDiEdge(source, target,label) => source match {
                 case label: Agent =>
                  Some((root,
                          DotEdgeStmt(source.toString,
                                              target.toString,
                                              if (label.nonEmpty) List(DotAttr("label", label.toString))
                                             else                Nil)))                                                                                              
       }}

1 个答案:

答案 0 :(得分:0)

我得到了解决方案!

边缘变换器需要与Ask匹配,而不是LDiEdge。要做到这一点,首先要实现Ask的unapply,如

def unapply [N](e:Ask [N]):选项[(N,N,String,String)] = Some((e._1,e._2,e.message,e.msgNo))

然后你可以匹配模式

案件询问(来源,目标,消息,消息)=&gt;

这就是我所缺少的一切!