6AJGWL32GZFO5CSSNKXMI24SB27I65K6LQDWWX5WVL5Z7ES4VUUQC
render_thread_to_surface = function(thread_data)
-- design constraints:
-- trees only, no graphs or DAGs
-- parents above children
-- a child shares its parent's column exactly only if it's an only child
-- parents can overlap columns with children and more distant descendants
-- siblings never share a column
-- siblings never overlap columns
-- siblings always occupy the same row
-- cousins/aunts/nephews never overlap columns
Surface = {}
-- we're going to be computing box heights
love.graphics.setFont(love.graphics.newFont(scale(20)))
-- compute mapping from ids to nodes
local nodes = {} -- id to object
nodes[thread_data.id] = thread_data
for _,x in ipairs(thread_data.descendants) do
nodes[x.id] = x
end
local root = thread_data
-- compute children
for _,x in pairs(nodes) do
parent_id = x.in_reply_to_id
if x.id ~= root.id then
assert(parent_id)
local parent = nodes[parent_id]
if parent.children == nil then
parent.children = {}
end
table.insert(parent.children, x.id)
end
end
-- sort children by time
for _,x in pairs(nodes) do
if x.children then
table.sort(x.children)
end
end
-- compute number of tracks needed
for _,x in pairs(nodes) do
if x.ntracks == nil then
x.ntracks = compute_ntracks(nodes, x)
end
end
-- prepare the tracks
-- each track is 600px + 20px of gutter between nodes
N_edges = 2
render_node_and_descendants(nodes, root.id, --[[y]] 0, --[[xlo]] 0, --[[xhi]] 620 * root.ntracks)
end
{"compute_ntracks":519,"render_thread_to_surface":583,"Cursor_node":172,"dehtml":456,"add_thick_line":400,"copy_shape":396,"on.draw":418,"on.code_change":578,"A":582,"add_edge":575,"vy":8,"B":379,"font":353,"fw_app":"mastodon-luaML","on.mouse_release":367,"on.update":368,"to_text":180,"on.keychord_press":391,"schema1_of_y":366,"add_node":576,"y_of_schema1":364,"render_node_and_descendants":579,"scale":7,"vx":5,"on.initialize":446,"on.text_input":388,"Viewport":303,"Input_filename":436,"Surface":434,"on":1,"compute_layout":385,"box_height":345,"fw_parent":582,"load_from_iterator":463,"split_lines":469,"line_height":365,"on.mouse_press":179,"initialize_editor":338,"ntracks":505,"update_editor_box":430}
{"compute_ntracks":519,"render_thread_to_surface":571,"Cursor_node":172,"dehtml":456,"add_thick_line":400,"copy_shape":396,"on.draw":418,"on.code_change":578,"A":582,"add_edge":575,"vy":8,"B":379,"font":353,"fw_app":"mastodon-luaML","on.mouse_release":367,"on.update":368,"to_text":180,"on.keychord_press":391,"schema1_of_y":366,"add_node":576,"y_of_schema1":364,"render_node_and_descendants":579,"scale":7,"vx":5,"on.initialize":446,"on.text_input":388,"Viewport":303,"Input_filename":436,"Surface":434,"on":1,"compute_layout":385,"box_height":345,"fw_parent":581,"load_from_iterator":463,"split_lines":469,"line_height":365,"on.mouse_press":179,"initialize_editor":338,"ntracks":505,"update_editor_box":430}
A = function(filename)
if filename then
local f = io.open(filename)
assert(f)
local thread_data = json.decode(f:read('*a'))
render_thread_to_surface(thread_data)
end
B()
end
{"compute_ntracks":519,"render_thread_to_surface":571,"Cursor_node":172,"dehtml":456,"add_thick_line":400,"copy_shape":396,"on.draw":418,"on.code_change":578,"A":581,"add_edge":575,"vy":8,"B":379,"font":353,"fw_app":"mastodon-luaML","on.mouse_release":367,"on.update":368,"to_text":180,"on.keychord_press":391,"schema1_of_y":366,"add_node":576,"y_of_schema1":364,"render_node_and_descendants":579,"scale":7,"vx":5,"on.initialize":446,"on.text_input":388,"Viewport":303,"Input_filename":436,"Surface":434,"on":1,"compute_layout":385,"box_height":345,"fw_parent":580,"load_from_iterator":463,"split_lines":469,"line_height":365,"on.mouse_press":179,"initialize_editor":338,"ntracks":505,"update_editor_box":430}
A = function(filename)
if filename then
local f = io.open(filename)
assert(f)
local thread_data = json.decode(f:read('*a'))
print(love.graphics.getFont())
render_thread_to_surface(thread_data)
end
B()
end
{"render_node_and_descendants":579,"add_edge":575,"initialize_editor":338,"Input_filename":436,"add_thick_line":400,"copy_shape":396,"box_height":345,"compute_layout":385,"on.code_change":578,"ntracks":505,"compute_ntracks":519,"render_thread_to_surface":571,"Surface":434,"dehtml":456,"on.draw":418,"to_text":180,"line_height":365,"vy":8,"fw_parent":579,"load_from_iterator":463,"fw_app":"mastodon-luaML","on.mouse_press":179,"y_of_schema1":364,"A":580,"font":353,"on.update":368,"split_lines":469,"B":379,"on.keychord_press":391,"update_editor_box":430,"on.mouse_release":367,"on":1,"Viewport":303,"scale":7,"Cursor_node":172,"on.text_input":388,"on.initialize":446,"add_node":576,"vx":5,"schema1_of_y":366}
A = function(filename)
if filename then
local f = io.open(filename)
assert(f)
local thread_data = json.decode(f:read('*a'))
print(love.graphics.getFont())
render_thread_to_surface(thread_data)
end
B()
end
render_node_and_descendants = function(nodes, id, y, xlo, xhi, grandparent_surface_node)
-- draw a parent 'id' and its children
-- also draw an edge from grandparent to parent if provided
-- position the root between xlo and xhi to be closer to children with fewer tracks
local parent = nodes[id]
if parent.children == nil then
add_node(xlo, y, parent.content, grandparent_surface_node)
return
end
local parent_xlo
if #parent.children <= 1 then
parent_xlo = xlo
else
local total_boundaries = 0
local curr_boundary = xlo
for child_idx = 1,#parent.children-1 do
local child_id = parent.children[child_idx]
local child = nodes[child_id]
curr_boundary = curr_boundary + 620 * child.ntracks
total_boundaries = total_boundaries + curr_boundary
end
local parent_x = total_boundaries / (#parent.children-1)
parent_xlo = parent_x - 620/2
end
local parent_surface_node = add_node(parent_xlo, y, parent.content, grandparent_surface_node)
local parent_height = box_height(parent_surface_node)
local curr_boundary = xlo
for _,child_id in ipairs(parent.children) do
local child = nodes[child_id]
render_node_and_descendants(nodes, child_id, y + parent_height + 50, curr_boundary, curr_boundary + 620*child.ntracks, parent_surface_node)
curr_boundary = curr_boundary + 620*child.ntracks
end
end
{"render_node_and_descendants":579,"add_edge":575,"initialize_editor":338,"Input_filename":436,"add_thick_line":400,"copy_shape":396,"box_height":345,"compute_layout":385,"on.code_change":578,"ntracks":505,"compute_ntracks":519,"render_thread_to_surface":571,"Surface":434,"dehtml":456,"on.draw":418,"to_text":180,"line_height":365,"vy":8,"fw_parent":578,"load_from_iterator":463,"fw_app":"mastodon-luaML","on.mouse_press":179,"y_of_schema1":364,"A":474,"font":353,"on.update":368,"split_lines":469,"B":379,"on.keychord_press":391,"update_editor_box":430,"on.mouse_release":367,"on":1,"Viewport":303,"scale":7,"Cursor_node":172,"on.text_input":388,"on.initialize":446,"add_node":576,"vx":5,"schema1_of_y":366}