Zulip Chat Archive

Stream: general

Topic: proofwidget for game search trees


Frederick Pu (Oct 13 2025 at 04:02):

I'm trying to create a proofwidget for game search trees but i cant get the repulsion between nodes working

import ProofWidgets
import ProofWidgets.Data.Html

open ProofWidgets GraphDisplay Jsx Lean

def mkRect (attrs : Array (String × Json) := #[]) : Html :=
  <rect
    x={.num (-25)}
    y={.num (-100)}
    width={50}
    height={100}
    fill="var(--vscode-editor-background)"
    stroke="var(--vscode-editor-foreground)"
    strokeWidth={.num 1.5}
    {...attrs}
  />

/-- Create a single cell at absolute (x, y) coordinates -/
def mkCell (x y w h : Nat) (content : String) : Html :=
  Html.element "g" #[]
    #[
      -- rectangle background
      Html.element "rect"
        #[ ("x", .num x),
           ("y", .num y),
           ("width", .num w),
           ("height", .num h),
           ("fill", .str "var(--vscode-editor-background)"),
           ("stroke", .str "var(--vscode-editor-foreground)"),
           ("strokeWidth", .num 2) ]
        #[],
      -- text centered inside cell
      Html.element "text"
        #[ ("x", .num (x + w / 2)),
           ("y", .num (y + h / 2)),
           ("text-anchor", .str "middle"),
           ("dominant-baseline", .str "middle"),
           ("class", .str "font-code"),
           ("fill", .str "var(--vscode-editor-foreground)") ]
        #[ Html.text content ]
    ]


/-- Build the 2×3 grid using only for loops and get! -/
def mkGrid (grid : Array (Array String)) (cellW := 50) (cellH := 100) (spacing : Nat := 5) (attrs : Array (String × Json) := #[]) : Html := Id.run do
  let mut children : Array Html := #[]
  for rowIdx in [0: grid.size] do
    let row := grid.get! rowIdx
    for colIdx in [0: row.size] do
      let cell := row.get! colIdx
      children := children.push (mkCell (colIdx * (cellW + spacing)) (rowIdx * (cellH + spacing)) cellW cellH cell)

  -- total width and height of the grid
  let totalCols := if grid.size == 0 then 0 else grid.get! 0 |>.size
  let totalWidth := totalCols * (cellW + spacing) - spacing
  let totalHeight := grid.size * (cellH + spacing) - spacing

  -- wrap the cells in a <g> and shift so bottom middle is at (0,0)
  Html.element "g"
    (#[] ++ attrs ++
      #[ ("transform", .str s!"translate({-(totalWidth / 2 : Int)}, {-(totalHeight : Int) / 2})") ])
    children

/-- Single vertex containing the grid -/
def gridVertex : GraphDisplay.Vertex :=
  { id := "A"
    label := mkGrid #[ #["A", "."], #["B", "A"], #[".", "B"] ] 50 50,
    boundingShape := .rect 50 100
  }

/-- Single vertex containing the grid -/
def gridVertex1 : GraphDisplay.Vertex :=
  { id := "B"
    label := mkGrid #[ #["A", "."], #["B", "A"], #[".", "B"] ] 50 50,
    boundingShape := .rect 50 100
  }

/-- Single vertex containing the grid -/
def gridVertex2 : GraphDisplay.Vertex :=
  { id := "C"
    label := mkGrid #[ #["A", "."], #["B", "A"], #[".", "B"] ] 50 50,
    boundingShape := .rect 50 100
  }

#html mkGrid #[ #["A", "."], #["B", "A"], #[".", "B"] ]
def testGraph : GraphDisplay.Props :=
  { vertices := #[
      gridVertex,
      gridVertex1,
      gridVertex2
    ],
    edges := #[
      { source := "A", target := "B" },
      { source := "A", target := "C" }
    ]
    forces:=#[
        .link { distance? := Float.ofNat 50 },
        .collide { radius? := Float.ofNat 15 },
        .x { strength? := some 0.05 },
        .y { strength? := some 0.05 }
      ]
  }

#widget GraphDisplay with testGraph

𝚠𝚘𝚓𝚌𝚒𝚎𝚌𝚑 𝚗𝚊𝚠𝚛𝚘𝚌𝚔𝚒 (Oct 14 2025 at 04:25):

Could you say more about what effect you want to achieve? The nodes are quite large, so you may need to adjust the force parameters to get the desired effect. I get a reasonable behaviour with link distance 200 and collide radius 100. In this demo we set force parameters dynamically, based on node sizes.

Frederick Pu (Oct 14 2025 at 13:48):

i endedup just using d3 tree https://github.com/FrederickPu/ProofWidgetExperiments/blob/gametree/widget/src/gametree.tsx

Frederick Pu (Oct 14 2025 at 13:49):

im still having some issues displaying the proof search metadata for the bottom nodes tho, it seems like they're getting clipped


Last updated: Dec 20 2025 at 21:32 UTC