Way of drawing a Black Circle inside a Table field

I want to draw a black circle inside a table field, I currently do it with a UNI-Code character, but this causes problems when rendering on some systems and with SVG Output it is not centered(Text in Table in SVG output not completly centered).

If there is any other better way to do this, without a Character, I would be thankful.

For reference for what it would be used for:

Wonder if it would work to center with -Tsvg:cairo ? That does better font measurements

I was going to say you could add a css class to cells you want a circle in, then style with css to add a circle maybe, but now I’m not sure if css class works on table cells in graphviz yet. Maybe we could make that work without much fuss.

The Problem I am having with this is that it does not work with the pip install of cairo/graphviz (on Windows at least) and that is a requierment.

How are you installing graphviz from pip?

To be precise, I install WireViz and that installs graphviz · PyPI

Ok, -Tsvg:cairo works now, do not know what I have done before, still it converts a Text to a path, what I would prefer not to do

Ok. The graphviz pypi module is just Python bindings, doesn’t include a dot binary, you have to install dot (graphviz) separately.

Yes, apently I did and forged it. Still a way to draw A Black Circle inside a Table field, Without a Caracter is what I am searching for. Becaus this could be a much more reliable way than depending on fonts

Have you considered inserting an image <TD> <IMG/> </TD>?
Not trying to sell the idea, but it would seem to simple to implement - though not necessarily easy to make work with many users.

Yes I thought about it and am working on it, but I had the hope that there would be a more elegant solution.

I don’t consider this elegant, but …
wireviz3

The improved pin2pin is modified again to add point-shaped nodes at the ends of marked edges.

/*******************************************************************

  see https://forum.graphviz.org/t/straitening-one-line-throu-a-table/2196
  input must include pos values (must be output from one of the engines w/ -Tdot)

*******************************************************************/
BEG_G{
  double x1,y1,x2,y2,x3,y3,x4,y4;
  string ptSize, tok[int], pt[];
  int cnt, circ, i;
  node_t aNode;

  circ=0;
}
/********************************************************
  it would be better to mark every target edge with a new attribute and test for that attribute
*********************************************************/
E{
  if (hasAttr($, "addPTS") && $.addPTS!="") {  // explicitly marked edges
    cnt=tokens($.pos,tok," ");
    $.oldpos=$.pos;
    x1 = xOf(tok[0]);
    y1 = yOf(tok[0]);
    x4 = xOf(tok[cnt-1]);
    y4 = yOf(tok[cnt-1]);
    x2 = x1 + (x4-x1)/3.;
    y2 = y1 + (y4-y1)/3.;
    x3 = x1 + 2.*(x4-x1)/3.;
    y3 = y1 + 2.*(y4-y1)/3.;
    pos=sprintf("%.3f,%.3f %.3f,%.3f %.3f,%.3f %.3f,%.3f", x1,y1, x2,y2, x3,y3, x4,y4);
    // now we place point nodes at the edge ends
    pt[1]=tok[0];
    pt[2]=tok[cnt-1];
    ptSize=".13";
    for (pt[i]) {
      if (i==2 && pt[1]==pt[2])
        continue;
      aNode=node($G, "__CIRCLE__" + (string)++circ);
      aNode.pos=pt[i];
      aNode.shape="point";
      aNode.width=ptSize;
      aNode.height=ptSize;
      aNode.style="filled";
      aNode.fillcolor="green";  // just for fun
    }
  }
}

And the input looks like this:

graph {
// Graph generated by WireViz 0.3.2
// https://github.com/formatc1702/WireViz
	graph [bgcolor="#FFFFFF" fontname=arial nodesep=0.33 rankdir=LR ranksep=2]
	node [fillcolor="#FFFFFF" fontname=arial height=0 margin=0 shape=none style=filled width=0]
	edge [fontname=arial style=bold label=" "]

	X2 [label=<
<table border="0" cellspacing="0" cellpadding="0">
 <tr><td>
  <table border="0" cellspacing="0" cellpadding="3" cellborder="1"><tr>
   <td balign="left">X2</td>
  </tr></table>
 </td></tr>
 <tr><td>
  <table border="0" cellspacing="0" cellpadding="3" cellborder="1"><tr>
   <td balign="left">P1</td>
   <td balign="left">9-pin</td>
  </tr></table>
 </td></tr>
 <tr><td>
  <table border="0" cellspacing="0" cellpadding="3" cellborder="1">
   <tr>
    <td port="p1l">1</td>
    <td>+28VDC</td>
    <td width="38"  port="p1I"></td>
    <td width="38"  port="p1J"></td>
    <td width="38"  port="p1K"></td>
   </tr>
   <tr>
    <td port="p2l">2</td>
    <td>+28VDC RTN</td>
    <td width="38"  port="p2I"></td>
    <td width="38"  port="p2J"></td>
    <td width="38"  port="p2K"></td>
   </tr>
   <tr>
    <td port="p3l">3</td>
    <td>Token-In REF</td>
    <td width="38"  port="p3I"></td>
    <td width="38"  port="p3J"></td>
    <td width="38"  port="p3K"></td>
    </tr>
   <tr>
    <td port="p4l">4</td>
    <td>Token-In</td>
    <td width="38"  port="p4I"></td>
    <td width="38"  port="p4J"></td>
    <td width="38"  port="p4K"></td>
   </tr>
   <tr>
    <td port="p5l">5</td>
    <td>NC</td>
    <td width="38"  port="p5I"></td>
    <td width="38"  port="p5J"></td>
    <td width="38"  port="p5K"></td>
   </tr>
   <tr>
    <td port="p6l">6</td>
    <td>NC</td>
    <td width="38"  port="p6I"></td>
    <td width="38"  port="p6J"></td>
    <td width="38"  port="p6K"></td>
   </tr>
   <tr>
    <td port="p7l">7</td>
    <td>RS-485+</td>
    <td width="38"  port="p7I"></td>
    <td width="38"  port="p7J"></td>
    <td width="38"  port="p7K"></td>
   </tr>
   <tr>
    <td port="p8l">8</td>
    <td>RS-485-</td>
    <td width="38"  port="p8I"></td>
    <td width="38"  port="p8J"></td>
    <td width="38"  port="p8K"></td>
    </tr>
   <tr>
    <td port="p9l">9</td>
    <td>RS-485 Shield</td>
    <td width="38"  port="p9I"></td>
    <td width="38"  port="p9J"></td>
    <td width="38"  port="p9K"></td>
   </tr>
  </table>
 </td></tr>
</table>
> fillcolor="#FFFFFF" shape=box style=filled]

	edge [color="#000000:#ff0000:#000000" label=" "]
	W1:w1:e -- X2:p1l:w
	edge [color="#000000:#000000:#000000" label=" "]
	W1:w2:e -- X2:p2l:w
	edge [color="#000000:#f5f0d0:#000000" label=" "]
	W1:w3:e -- X2:p7l:w
	edge [color="#000000:#0066ff:#000000" label=" "]
	W1:w4:e -- X2:p8l:w
	edge [color="#000000:#00ff00:#000000" label=" "]
	W1:w5:e -- X2:p9l:w

      {  // keep edge attributes contained within subgraph
	edge [color="#000000" addPTS=1 headclip=false, tailclip=false, style="dashed", constraint=false]
	X2:p2I:c -- X2:p2I:c 
	X2:p1J:c -- X2:p5J:c 
	X2:p8J:c -- X2:p8J:c 
	X2:p9J:c -- X2:p9J:c 
	X2:p3K:c -- X2:p4K:c 
	X2:p6K:c -- X2:p9K:c [color=red]  // for fun
	X2:p4I:c -- X2:p5I:c 
	X2:p5I:c -- X2:p8I:c
     }
	W1 [label=<
<table border="0" cellspacing="0" cellpadding="0">
 <tr><td>
  <table border="0" cellspacing="0" cellpadding="3" cellborder="1"><tr>
   <td balign="left">W1</td>
  </tr></table>
 </td></tr>
 <tr><td>
  <table border="0" cellspacing="0" cellpadding="3" cellborder="1"><tr>
   <td balign="left">5x</td>
  </tr></table>
 </td></tr>
 <tr><td>
  <table border="0" cellspacing="0" cellborder="0">
   <tr><td>&nbsp;&nbsp;&nbsp;</td></tr>
   <tr>
    <td><!-- 1_in --></td>
    <td>
     1:RD
    </td>
    <td>X2:1:+28VDC</td>
   </tr>
   <tr>
    <td colspan="3" border="0" cellspacing="0" cellpadding="0" port="w1" height="6">
     <table cellspacing="0" cellborder="0" border="0">
      <tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr>
      <tr><td colspan="3" cellpadding="0" height="2" bgcolor="#ff0000" border="0"></td></tr>
      <tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr>
     </table>
    </td>
   </tr>
   <tr>
    <td><!-- 2_in --></td>
    <td>
     2:BK
    </td>
    <td>X2:2:+28VDC RTN</td>
   </tr>
   <tr>
    <td colspan="3" border="0" cellspacing="0" cellpadding="0" port="w2" height="6">
     <table cellspacing="0" cellborder="0" border="0">
      <tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr>
      <tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr>
      <tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr>
     </table>
    </td>
   </tr>
   <tr>
    <td><!-- 3_in --></td>
    <td>
     3:IV
    </td>
    <td>X2:7:RS-485+</td>
   </tr>
   <tr>
    <td colspan="3" border="0" cellspacing="0" cellpadding="0" port="w3" height="6">
     <table cellspacing="0" cellborder="0" border="0">
      <tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr>
      <tr><td colspan="3" cellpadding="0" height="2" bgcolor="#f5f0d0" border="0"></td></tr>
      <tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr>
     </table>
    </td>
   </tr>
   <tr>
    <td><!-- 4_in --></td>
    <td>
     4:BU
    </td>
    <td>X2:8:RS-485-</td>
   </tr>
   <tr>
    <td colspan="3" border="0" cellspacing="0" cellpadding="0" port="w4" height="6">
     <table cellspacing="0" cellborder="0" border="0">
      <tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr>
      <tr><td colspan="3" cellpadding="0" height="2" bgcolor="#0066ff" border="0"></td></tr>
      <tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr>
     </table>
    </td>
   </tr>
   <tr>
    <td><!-- 5_in --></td>
    <td>
     5:GN
    </td>
    <td>X2:9:RS-485 Shield</td>
   </tr>
   <tr>
    <td colspan="3" border="0" cellspacing="0" cellpadding="0" port="w5" height="6">
     <table cellspacing="0" cellborder="0" border="0">
      <tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr>
      <tr><td colspan="3" cellpadding="0" height="2" bgcolor="#00ff00" border="0"></td></tr>
      <tr><td colspan="3" cellpadding="0" height="2" bgcolor="#000000" border="0"></td></tr>
     </table>
    </td>
   </tr>
   <tr><td>&nbsp;&nbsp;&nbsp;</td></tr>
  </table>
 </td></tr>
</table>
> fillcolor="#FFFFFF" shape=box style=filled]
}

@ steveroush I like it, in my opinion much better than inserting Images

@steveroush Thx, modifyed it to do what I want

My end resault:

/*******************************************************************

  see https://forum.graphviz.org/t/straitening-one-line-throu-a-table/2196 and https://forum.graphviz.org/t/way-of-drawing-a-black-circle-inside-a-table-field/2273/12
  input must include pos values (must be output from one of the engines w/ -Tdot)#
  Thanks to steveroush and FeRDNYC
  
*******************************************************************/
BEG_G{
  double x1,y1,x2,y2,x3,y3,x4,y4;
  string ptSize, tok[int], pt[];
  int cnt, circ, i;
  node_t aNode;

  circ=0;

/***************************************
  $G.bb="";
  $G.nodesep="";
  $G.ranksep="";
  $G.splines="true";
****************************************/
}
E[straight] {
  cnt=tokens($.pos,tok," ");
  $.oldpos=$.pos;
  x1 = xOf(tok[0]);
  y1 = yOf(tok[0]);
  x4 = xOf(tok[cnt-1]);
  y4 = yOf(tok[cnt-1]);
  x2 = x1 + (x4-x1)/3.;
  y2 = y1 + (y4-y1)/3.;
  x3 = x1 + 2.*(x4-x1)/3.;
  y3 = y1 + 2.*(y4-y1)/3.;
  pos=sprintf("%.3f,%.3f %.3f,%.3f %.3f,%.3f %.3f,%.3f", x1,y1, x2,y2, x3,y3, x4,y4);
  $.label="";  // remove pesky label
  $.lp="";      // remove peskier label pos

  if (hasAttr($, "addPTS") && $.addPTS!="" && $.colorPTS!=""){
    // now we place point nodes at the edge ends
    pt[1] = tok[0];
    pt[2] = tok[cnt-1];
    ptSize=$.addPTS;
    for (pt[i]) {
      if (i==2 && pt[1]==pt[2])
        continue;
      aNode=node($G, "__CIRCLE__" + (string)++circ);
      aNode.pos=pt[i];
      aNode.shape="point";
      aNode.width=ptSize;
      aNode.height=ptSize;
      aNode.style="filled";
      aNode.fillcolor=$.colorPTS;
      aNode.color=$.colorPTS;
    }
  }

}

I think this has come up before and the unfortunate conclusion was this is not within our control but a decision Cairo makes on its own.

I understand that this is not in the scope of GraphViz, and it was less of a complaint that the Text is converted to a Path but more of saying that I would prefer a solution that would not do it, that I got at the end.
Also, there are situations where this Text to Path conversion is wanted/needed.
One thing is that maybe that it should be mentioned somewhere in the documentation, I at least did not see such thing in the doc.