Skip to content

Commit

Permalink
fix: minor refactorings and fixes to render better on smaller devices
Browse files Browse the repository at this point in the history
This also fixes a potential bug in the timeline model computation for "forests", i.e. graphs with multiple roots.

Signed-off-by: Nick Mitchell <[email protected]>
  • Loading branch information
starpit committed Jan 23, 2025
1 parent eb04783 commit 76d5b5d
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 86 deletions.
80 changes: 2 additions & 78 deletions pdl-live-react/src/view/timeline/Timeline.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { useMemo } from "react"

import TimelineRow, { type Position } from "./TimelineRow"
import { type TimelineRow as TimelineRowModel, computeModel } from "./model"
import TimelineRow from "./TimelineRow"
import { computeModel, pushPopsFor } from "./model"

import "./Timeline.css"

Expand Down Expand Up @@ -40,79 +40,3 @@ export default function Timeline({ block }: Props) {
</div>
)
}

function positionOf(
row: TimelineRowModel,
idx: number,
A: TimelineRowModel[],
): Position {
return idx === A.length - 1 || A[idx + 1].depth < row.depth
? "pop"
: idx === 0 || A[idx - 1].depth < row.depth
? "push"
: A[idx - 1].depth === row.depth
? "middle"
: "pop"
}

function nextSibling(
row: TimelineRowModel,
idx: number,
A: TimelineRowModel[],
) {
let sidx = idx + 1
while (sidx < A.length && A[sidx].depth > row.depth) {
sidx++
}
return sidx < A.length && A[sidx].depth === row.depth ? sidx : -1
}

type PushPop = { prefix: boolean[]; position: Position }

function pushPopsFor(model: TimelineRowModel[]): PushPop[] {
if (model.length === 0) {
return []
}

const result: PushPop[] = []
const stack: number[] = [0]
const prefix: boolean[] = []
let n = 0
while (stack.length > 0) {
if (n++ > model.length * 2) {
break
}
const rootIdx = stack.pop()

if (rootIdx === undefined) {
break
} else if (rootIdx < 0) {
prefix.pop()
continue
}

const root = model[rootIdx]
const mine = {
prefix: prefix.slice(0),
position: positionOf(root, rootIdx, model),
}
result.push(mine)

stack.push(-rootIdx)
for (let idx = model.length - 1; idx >= rootIdx + 1; idx--) {
if (model[idx].parent === root) {
stack.push(idx)
}
}

const nextSibIdx = nextSibling(root, rootIdx, model)
if (nextSibIdx < 0) {
prefix.push(false)
mine.position = "pop"
} else {
prefix.push(true)
}
}

return result
}
10 changes: 4 additions & 6 deletions pdl-live-react/src/view/timeline/TimelineRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,9 @@ import prettyMs from "pretty-ms"
import TimelineBar from "./TimelineBar"
import { capitalizeAndUnSnakeCase } from "../../helpers"

export type Position = "push" | "middle" | "pop"

type Props = import("./model").TimelineRowWithExtrema & {
prefix: boolean[]
position: Position
position: import("./model").Position
}

export default function TimelineRow(row: Props) {
Expand Down Expand Up @@ -36,7 +34,7 @@ function treeSymbols(row: Props) {
}

function prefixSymbols(row: Props) {
return row.prefix.slice(1).reduce((s, p) => s + (p ? "│ " : " "), "")
return row.prefix.slice(1).reduce((s, p) => s + (p ? "│ " : " "), "")
}

function finalSymbol(row: Props) {
Expand All @@ -47,9 +45,9 @@ function finalSymbol(row: Props) {
switch (row.position) {
case "push":
case "middle":
return "├─ "
return "├─ "
default:
case "pop":
return "└─ "
return "└─ "
}
}
81 changes: 80 additions & 1 deletion pdl-live-react/src/view/timeline/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
type NonScalarPdlBlock,
} from "../../helpers"

export type TimelineRow = Pick<
type TimelineRow = Pick<
PdlBlockWithTiming,
"start_nanos" | "end_nanos" | "timezone" | "kind"
> & {
Expand All @@ -29,6 +29,8 @@ export type TimelineRowWithExtrema = TimelineRow & {

export type TimelineModel = TimelineRow[]

export type Position = "push" | "middle" | "pop"

export function computeModel(
block: unknown | PdlBlock,
depth = 0,
Expand Down Expand Up @@ -75,3 +77,80 @@ function childrenOf(block: NonScalarPdlBlock) {
.flat()
.filter(nonNullable)
}

function positionOf(row: TimelineRow, idx: number, A: TimelineRow[]): Position {
return idx === A.length - 1 || A[idx + 1].depth < row.depth
? "pop"
: idx === 0 || A[idx - 1].depth < row.depth
? "push"
: A[idx - 1].depth === row.depth
? "middle"
: "pop"
}

function nextSibling(row: TimelineRow, idx: number, A: TimelineRow[]) {
let sidx = idx + 1
while (sidx < A.length && A[sidx].depth > row.depth) {
sidx++
}
return sidx < A.length && A[sidx].depth === row.depth ? sidx : -1
}

type PushPop = { prefix: boolean[]; position: Position }

export function pushPopsFor(model: TimelineRow[]): PushPop[] {
if (model.length === 0) {
return []
}

// Push all roots for the initial set
const stack: number[] = model
.map((_, idx) => (_.depth === 0 ? idx : undefined))
.filter(nonNullable)

// This is the return value
const result: PushPop[] = []

// This is an array of parents; false indicates that the parent has
// no nextSibling; true indicates it does
const prefix: boolean[] = []

let n = 0
while (stack.length > 0) {
if (n++ > model.length * 2) {
break
}
const rootIdx = stack.pop()

if (rootIdx === undefined) {
break
} else if (rootIdx < 0) {
prefix.pop()
continue
}

const root = model[rootIdx]
const mine = {
prefix: prefix.slice(0),
position: positionOf(root, rootIdx, model),
}
result.push(mine)

stack.push(-rootIdx)
for (let idx = model.length - 1; idx >= rootIdx + 1; idx--) {
if (model[idx].parent === root) {
stack.push(idx)
}
}

const nextSibIdx = nextSibling(root, rootIdx, model)
if (nextSibIdx < 0) {
prefix.push(false)
mine.position = "pop"
} else {
prefix.push(true)
}
}

return result
}
2 changes: 1 addition & 1 deletion pdl-live-react/src/view/transcript/TranscriptItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export default function TranscriptItem(props: Props) {
const headerContent = (
<Flex alignItems={alignCenter}>
{icon && <FlexItem className="pdl-block-icon">{icon}</FlexItem>}
<Flex>{breadcrumbs}</Flex>
<FlexItem>{breadcrumbs}</FlexItem>
</Flex>
)

Expand Down

0 comments on commit 76d5b5d

Please sign in to comment.