Skip to documentation
SLOP

tiny.zen.diagram.ego.layout

Reference tiny.zen diagram ego layout

Defined in diagram.ego.

API (14)

Actions

Public operations.

Types and contracts

Public types and contracts.

Values and defaults

Public values and defaults.

No direct callersNo direct callsdiagram.egolayout
Static calls · unresolved targets: unknown · external targets: unknown.

Source

Called byCallsdiagram.ego.svgwriteprivate sourcelib.zen.src.diagram.ego.layouthorizontalPlanprivate sourcelib.zen.src.diagram.ego.layoutselectprivate sourcelib.zen.src.diagram.ego.layoutverticalPlandiagram.ego.modelslotsPerBanddiagram.ego.LayoutPlaninspect
Static calls · unresolved targets: 0 · external targets: 1.

Source: lib/zen/src/diagram/ego/layout.zig

zig
const std = @import("std");const root = @import("root.zig");const model = root.model;pub const margin_width_max: u16 = 256;pub const margin_height_min: u16 = 268;pub const margin_height_max: u16 = 520;const wide_leaf_width: u16 = 640;const wide_leaf_height: u16 = 120;const wide_leaf_loop_height: u16 = 152;const wide_leaf_node_width: f32 = 150;const wide_header_y: f32 = 26;const wide_content_top: f32 = 50;const wide_content_bottom: f32 = 408;const vertical_heading_extent: f32 = 18;const vertical_heading_gap: f32 = 16;const vertical_empty_extent: f32 = 32;const vertical_item_gap: f32 = 10;const vertical_flow_gap: f32 = 28;pub const Point = struct {    x: f32,    y: f32,};pub const Rect = struct {    x: f32,    y: f32,    width: f32,    height: f32,    pub fn centerX(self: Rect) f32 {        return self.x + self.width / 2;    }    pub fn centerY(self: Rect) f32 {        return self.y + self.height / 2;    }};pub const More = struct {    count: u32,    href: []const u8,};pub const Content = union(enum) {    node: model.Node,    more: More,};pub const Item = struct {    box: Rect,    content: Content,};pub const Band = struct {    items: [model.max_slots_per_band]Item = undefined,    count: u8 = 0,    heading: Point,    empty: Point,    pub fn slice(self: *const Band) []const Item {        std.debug.assert(self.count <= model.max_slots_per_band);        return self.items[0..self.count];    }};pub const Plan = struct {    geometry: model.Geometry,    subject: Rect,    callers: Band,    callees: Band,    pub fn inspect(network: model.Network, surface: model.Surface) model.Error!Plan {        try model.validate(network);        const slot_limit = model.slotsPerBand(surface);        const callers = try select(network.callers, slot_limit);        const callees = try select(network.callees, slot_limit);        return switch (surface) {            .margin => verticalPlan(network, callers, callees),            .wide => horizontalPlan(network, callers, callees),        };    }};const Columns = struct {    callers: Rect,    subject: Rect,    callees: Rect,};const Selection = struct {    node_count: u8,    more_count: u32,    fn visibleCount(self: Selection) u8 {        return self.node_count + @intFromBool(self.more_count > 0);    }};fn horizontalPlan(    network: model.Network,    callers: Selection,    callees: Selection,) Plan {    const empty = network.callers.total == 0 and network.callees.total == 0;    const geometry = wideGeometry(empty, network.recursive);    const columns = horizontalColumns(geometry);    var plan = Plan{        .geometry = geometry,        .subject = columns.subject,        .callers = horizontalBand(columns.callers, geometry),        .callees = horizontalBand(columns.callees, geometry),    };    placeBand(        &plan.callers,        network.callers,        callers,        columns.callers,        horizontalFirstY(geometry, callers.visibleCount()),        horizontalStep(geometry, callers.visibleCount()),    );    placeBand(        &plan.callees,        network.callees,        callees,        columns.callees,        horizontalFirstY(geometry, callees.visibleCount()),        horizontalStep(geometry, callees.visibleCount()),    );    return plan;}fn verticalPlan(    network: model.Network,    callers: Selection,    callees: Selection,) Plan {    var geometry = marginGeometry();    const center_x = @as(f32, @floatFromInt(geometry.width)) / 2;    const callers_extent = verticalBandExtent(geometry, callers.visibleCount());    const callees_extent = verticalBandExtent(geometry, callees.visibleCount());    const callers_top = geometry.outer_inset + vertical_heading_extent +        vertical_heading_gap;    const subject_y = callers_top + callers_extent + vertical_flow_gap;    const calls_header_top = subject_y + geometry.subject_height + vertical_flow_gap;    const callees_top = calls_header_top + vertical_heading_extent +        vertical_heading_gap;    const height = callees_top + callees_extent + geometry.outer_inset;    geometry.height = @intFromFloat(height);    std.debug.assert(geometry.height >= margin_height_min);    std.debug.assert(geometry.height <= margin_height_max);    var plan = Plan{        .geometry = geometry,        .subject = .{            .x = center_x - geometry.subject_width / 2,            .y = subject_y,            .width = geometry.subject_width,            .height = geometry.subject_height,        },        .callers = verticalBand(geometry, callers_top, geometry.outer_inset),        .callees = verticalBand(geometry, callees_top, calls_header_top),    };    const node_box = Rect{        .x = center_x - geometry.node_width / 2,        .y = 0,        .width = geometry.node_width,        .height = geometry.node_height,    };    const step = geometry.node_height + vertical_item_gap;    placeBand(&plan.callers, network.callers, callers, node_box, callers_top, step);    placeBand(&plan.callees, network.callees, callees, node_box, callees_top, step);    return plan;}fn horizontalBand(column: Rect, geometry: model.Geometry) Band {    return .{        .heading = .{ .x = column.centerX(), .y = wide_header_y },        .empty = .{            .x = column.centerX(),            .y = @as(f32, @floatFromInt(geometry.height)) / 2,        },    };}fn verticalBand(geometry: model.Geometry, content_y: f32, heading_top: f32) Band {    const center_x = @as(f32, @floatFromInt(geometry.width)) / 2;    return .{        .heading = .{ .x = center_x, .y = heading_top + geometry.heading_size },        .empty = .{ .x = center_x, .y = content_y + vertical_empty_extent / 2 },    };}fn placeBand(    result: *Band,    source: model.Band,    selection: Selection,    template: Rect,    first_y: f32,    step: f32,) void {    result.count = selection.visibleCount();    std.debug.assert(result.count <= model.max_slots_per_band);    var index: u8 = 0;    while (index < selection.node_count) : (index += 1) {        result.items[index] = .{            .box = placedBox(template, first_y, step, index),            .content = .{ .node = source.nodes[index] },        };    }    if (selection.more_count == 0) return;    result.items[index] = .{        .box = placedBox(template, first_y, step, index),        .content = .{ .more = .{            .count = selection.more_count,            .href = source.more_href,        } },    };}fn placedBox(template: Rect, first_y: f32, step: f32, index: u8) Rect {    var result = template;    result.y = first_y + step * @as(f32, @floatFromInt(index));    return result;}fn select(source: model.Band, slot_limit: u8) model.Error!Selection {    std.debug.assert(slot_limit > 1);    std.debug.assert(slot_limit <= model.max_slots_per_band);    var node_count: u8 = @intCast(@min(source.nodes.len, slot_limit));    if (source.total > node_count and node_count == slot_limit) node_count -= 1;    const result = Selection{        .node_count = node_count,        .more_count = source.total - node_count,    };    if (result.more_count > 0 and source.more_href.len == 0) {        return error.MissingOverflowLink;    }    return result;}fn horizontalColumns(geometry: model.Geometry) Columns {    const width: f32 = @floatFromInt(geometry.width);    const subject_x = (width - geometry.subject_width) / 2;    return .{        .callers = .{            .x = geometry.outer_inset,            .y = 0,            .width = geometry.node_width,            .height = geometry.node_height,        },        .subject = .{            .x = subject_x,            .y = (@as(f32, @floatFromInt(geometry.height)) -                geometry.subject_height) / 2,            .width = geometry.subject_width,            .height = geometry.subject_height,        },        .callees = .{            .x = width - geometry.outer_inset - geometry.node_width,            .y = 0,            .width = geometry.node_width,            .height = geometry.node_height,        },    };}fn horizontalFirstY(geometry: model.Geometry, count: u8) f32 {    std.debug.assert(count <= model.wide_slots_per_band);    if (count == 1) {        return (@as(f32, @floatFromInt(geometry.height)) - geometry.node_height) / 2;    }    return wide_content_top;}fn horizontalStep(geometry: model.Geometry, count: u8) f32 {    std.debug.assert(count <= model.wide_slots_per_band);    if (count <= 1) return 0;    const span = wide_content_bottom - wide_content_top - geometry.node_height;    return span / @as(f32, @floatFromInt(count - 1));}fn verticalBandExtent(geometry: model.Geometry, count: u8) f32 {    std.debug.assert(count <= model.margin_slots_per_band);    if (count == 0) return vertical_empty_extent;    return geometry.node_height * @as(f32, @floatFromInt(count)) +        vertical_item_gap * @as(f32, @floatFromInt(count - 1));}fn marginGeometry() model.Geometry {    return .{        .arrangement = .vertical,        .width = margin_width_max,        .height = margin_height_min,        .slots_per_band = model.margin_slots_per_band,        .outer_inset = 8,        .node_width = 208,        .subject_width = 232,        .node_height = 46,        .subject_height = 64,        .heading_size = 13,        .empty_size = 12.5,        .label_size = 13,        .context_size = 10.5,        .badge_size = 8.5,        .subject_label_size = 16,    };}fn wideGeometry(empty: bool, recursive: bool) model.Geometry {    const leaf_height = if (recursive) wide_leaf_loop_height else wide_leaf_height;    return .{        .arrangement = .horizontal,        .width = if (empty) wide_leaf_width else 920,        .height = if (empty) leaf_height else 420,        .slots_per_band = model.wide_slots_per_band,        .outer_inset = 20,        .node_width = if (empty) wide_leaf_node_width else 240,        .subject_width = 260,        .node_height = 48,        .subject_height = 72,        .heading_size = 11,        .empty_size = 12,        .label_size = 14,        .context_size = 10.5,        .badge_size = 8.5,        .subject_label_size = 18,    };}

Source: lib/zen/src/diagram/ego/root.zig:1

zig
pub const layout = @import("layout.zig");

Audit

Definitions15
Public names17
Members20
Version26.7.0
Revisiondaab053ee433