## ----setup, include=FALSE-----------------------------------------------------
knitr::opts_chunk$set(eval = FALSE, collapse = TRUE, comment = "#>")
.shot_id <- 0L
ui_shot <- function(file, caption, crop = c(0, 0, 1280, 720),
                    marks = list(), drag = NULL, max_width = 900) {
  .shot_id <<- .shot_id + 1L
  arrow_id <- paste0("tutorial-arrow-", .shot_id)
  src <- knitr::image_uri(file.path("figures", "drag-editor", file))
  esc <- function(x) as.character(htmltools::htmlEscape(x, attribute = TRUE))
  x <- crop[1]; y <- crop[2]; w <- crop[3]; h <- crop[4]
  cat(sprintf('<figure class="ui-figure" style="max-width:%spx">', max_width))
  cat(sprintf('<div class="ui-screen" style="padding-top:%.6f%%">', 100 * h / w))
  cat(sprintf(paste0('<img class="ui-image" src="%s" alt="%s" ',
                     'style="width:%.6f%%;left:%.6f%%;top:%.6f%%">'),
              src, esc(caption), 128000 / w, -100 * x / w, -100 * y / h))
  cat(sprintf('<svg viewBox="%s %s %s %s" aria-hidden="true" xmlns="http://www.w3.org/2000/svg">', x, y, w, h))
  if (!is.null(drag)) {
    cat(sprintf(paste0('<defs><marker id="%s" markerWidth="8" markerHeight="8" ',
                       'refX="7" refY="4" orient="auto"><path d="M0 0L8 4L0 8Z" ',
                       'fill="#000000"/></marker></defs>'), arrow_id))
    cat(sprintf('<path d="M%s %s L%s %s" fill="none" stroke="#ffffff" stroke-width="5"/>',
                drag[1], drag[2], drag[3], drag[4]))
    cat(sprintf(paste0('<path d="M%s %s L%s %s" fill="none" stroke="#000000" ',
                       'stroke-width="2" stroke-dasharray="6 4" marker-end="url(#%s)"/>'),
                drag[1], drag[2], drag[3], drag[4], arrow_id))
  }
  for (m in marks) {
    cat(sprintf('<line x1="%s" y1="%s" x2="%s" y2="%s" stroke="#ffffff" stroke-width="4"/>', m[2], m[3], m[4], m[5]))
    cat(sprintf('<line x1="%s" y1="%s" x2="%s" y2="%s" stroke="#000000" stroke-width="1.5"/>', m[2], m[3], m[4], m[5]))
    cat(sprintf('<circle cx="%s" cy="%s" r="12" fill="#ffffff" stroke="#000000" stroke-width="1.5"/>', m[2], m[3]))
    cat(sprintf('<text x="%s" y="%s" text-anchor="middle" dominant-baseline="central" font-size="16">%s</text>', m[2], m[3], esc(m[1])))
  }
  cat('</svg></div>')
  cat(sprintf('<figcaption>%s</figcaption>', esc(caption)))
  cat('<details class="ui-full"><summary>Show the unannotated full-size screenshot</summary><div class="ui-pan">')
  cat(sprintf('<img src="%s" alt="Unannotated editor screenshot: %s" width="1280" height="720">', src, esc(caption)))
  cat('</div></details></figure>\n')
}

## ----interface-overview, echo=FALSE, eval=TRUE, results='asis'----------------
ui_shot("01-editor-overview.png",
  "Figure 1. The editor before any changes. The download controls are farther down the left sidebar.",
  marks = list(c(1, 364, 47, 364, 77), c(2, 473, 430, 520, 456),
               c(3, 660, 510, 542, 529), c(4, 313, 165, 277, 165)))

## ----install------------------------------------------------------------------
# install.packages(c("lvmPlot", "lavaan", "shiny", "jsonlite", "svglite", "ragg"))

## ----install-archive----------------------------------------------------------
# install.packages(file.choose(), repos = NULL, type = "source")
# packageVersion("lvmPlot")

## ----open-mouse-editor--------------------------------------------------------
# library(lavaan)
# library(lvmPlot)
# 
# model <- '
#   visual  =~ x1 + x2 + x3
#   textual =~ x4 + x5 + x6
#   speed   =~ x7 + x8 + x9
# '
# 
# fit <- cfa(model, data = HolzingerSwineford1939)
# 
# lvmPlot(
#   fit,
#   mode = "edit",
#   label = "std",
#   stars = FALSE,
#   diagram = "all",
#   export_name = "three-factor-cfa",
#   launch = TRUE
# )

## ----node-before-after, echo=FALSE, eval=TRUE, results='asis'-----------------
cat('<div class="ui-pair">')
ui_shot("01-editor-overview.png",
  "Figure 2a. Before: press inside visual and drag upward in the direction shown.",
  crop = c(415, 290, 260, 315), drag = c(547, 438, 521, 355))
ui_shot("02-node-moved.png",
  "Figure 2b. After: visual has moved, while x1, x2 and x3 remain on the original row.",
  crop = c(415, 290, 260, 315))
cat('</div>')

## ----coefficient-before-after, echo=FALSE, eval=TRUE, results='asis'----------
cat('<div class="ui-pair">')
ui_shot("02-node-moved.png",
  "Figure 3a. Before: the numbered pointer identifies the label to grab. Drag the number itself, not its path.",
  crop = c(435, 315, 230, 290), marks = list(c(1, 452, 422, 507, 468)),
  drag = c(532, 451, 550, 432))
ui_shot("03-coefficient-moved.png",
  "Figure 3b. After: 0.42 is higher on the page. The factor and all three indicators have stayed in place.",
  crop = c(435, 315, 230, 290), marks = list(c(1, 617, 412, 566, 416)))
cat('</div>')

## ----display-name-controls, echo=FALSE, eval=TRUE, results='asis'-------------
ui_shot("04-display-label.png",
  "Figure 4. Select the node, type its display name in Selected label (1), then click Apply label (2). The diagram now says Visual ability.",
  crop = c(20, 125, 665, 320),
  marks = list(c(1, 310, 311, 282, 311), c(2, 150, 361, 125, 361)))

## ----export-preview-interface, echo=FALSE, eval=TRUE, results='asis'----------
ui_shot("05-export-preview.png",
  "Figure 5. Choose Export preview (1), then Refresh export preview (2). In this R-rendered image, the renamed factor is higher (3), and the manually positioned 0.42 remains near its path (4).",
  crop = c(325, 60, 940, 565),
  marks = list(c(1, 552, 84, 516, 84), c(2, 561, 151, 502, 151),
               c(3, 572, 236, 537, 236), c(4, 588, 328, 535, 328)))

## ----save-controls-closeup, echo=FALSE, eval=TRUE, results='asis'-------------
ui_shot("06-save-and-restore.png",
  "Figure 6. The bottom of the sidebar: image downloads (1), Figure R (2), State JSON (3), and Browse under Load state JSON (4).",
  crop = c(15, 345, 310, 348), max_width = 410,
  marks = list(c(1, 264, 394, 214, 394), c(2, 264, 474, 204, 474),
               c(3, 214, 514, 139, 514), c(4, 216, 626, 101, 591)))

## ----reproduce-edited-figure--------------------------------------------------
# # Run in the directory where you want the output figures.
# source("three-factor-cfa-figure.R")

## ----alignment-controls, echo=FALSE, eval=TRUE, results='asis'----------------
ui_shot("07-align-selection.png",
  "Figure 7. The three indicators are selected (1). Align row (2) puts selected, unlocked nodes on one horizontal line; Distribute X (3) spaces them evenly. These indicators already form a row, so Align row makes no visible change here.",
  crop = c(15, 45, 1250, 575),
  marks = list(c(1, 680, 554, 652, 554), c(2, 95, 318, 95, 344),
               c(3, 248, 414, 155, 400)))

