diff --git a/docs.typ b/docs.typ index f2e6a27..416e10d 100644 --- a/docs.typ +++ b/docs.typ @@ -205,6 +205,9 @@ Minimal starting point: #let radial_tournament_module = tidy.parse-module(read("./themes/radial/components/tournament.typ")) #show-module(radial_tournament_module) +#let radial_graph_module = tidy.parse-module(read("./themes/radial/components/graphs.typ")) +#show-module(radial_graph_module) + = Developer Documentation == Project Architecture diff --git a/themes/radial/components/components.typ b/themes/radial/components/components.typ index a371a58..772f703 100644 --- a/themes/radial/components/components.typ +++ b/themes/radial/components/components.typ @@ -1,7 +1,3 @@ -#import "./headings.typ": * -#import "./code-blocks.typ": * -#import "./title.typ": * - #import "./toc.typ": * #import "./glossary.typ": * @@ -9,3 +5,4 @@ #import "./pro-con.typ": * #import "./decision-matrix.typ": * #import "./tournament.typ": * +#import "./graphs.typ": * diff --git a/themes/radial/components/graphs.typ b/themes/radial/components/graphs.typ new file mode 100644 index 0000000..2060648 --- /dev/null +++ b/themes/radial/components/graphs.typ @@ -0,0 +1,99 @@ +#import "../colors.typ": * + +#import "@preview/cetz:0.1.2" + +/// Creates a labeled pie chart. +/// +/// Example Usage: +/// +/// ```typ +/// #pie_chart( +/// (8, green, "wins"), +/// (2, red, "losses") +/// ) +/// ``` +/// +/// - ..data (array): Each array must contain 3 fields. +/// + `` The value of the section +/// + `` The value of the section +/// + `` The name of the section +/// Here's an example of one of these arrays: +/// `(2, blue, "bicycles")` +/// -> content +#let pie_chart(..data) = { + let total; + let percentages = (); + + for value in data.pos() { + total += value.at(0); + } + + for value in data.pos() { + percentages.push(calc.round(value.at(0) / total * 100)) + } + + cetz.canvas( + { + import cetz.draw: * + + let chart(..values, name: none) = { + let values = values.pos() + let anchor_angles = () + + let offset = 0 + let total = values.fold(0, (s, v) => s + v.at(0)) + + let segment(from, to) = { + merge-path(close: true, { + stroke((paint: black, join: "round", thickness: 0pt)) + line((0, 0), (rel: (360deg * from, 2))) + arc((), start: from * 360deg, stop: to * 360deg, radius: 2) + }) + } + + let chart = group(name: name, { + stroke((paint: black, join: "round")) + + for v in values { + fill(v.at(1)) + let value = v.at(0) / total + + // Draw the segment + segment(offset, offset + value) + + // Place an anchor for each segment + let angle = offset * 360deg + value * 180deg + anchor(v.at(2), (angle, 1.75)) + anchor_angles.push(angle) + + offset += value + } + }) + + return (chart, anchor_angles) + } + + // Draw the chart + let (chart, angles) = chart(..data, name: "chart") + + chart + + set-style(mark: (fill: white, start: "o", stroke: black), content: (padding: .1)) + for (index, value) in data.pos().enumerate() { + let anchor = "chart." + value.at(2) + let angle = angles.at(index) + + let (line_end, anchor_direction) = if angle > 90deg and angle < 275deg { + ((-0.5, 0), "right") + } else { + ((0.5, 0), "left") + } + + line(anchor, (to: anchor, rel: (angle, 0.5)), (rel: line_end)) + + content((), [#value.at(2)], anchor: "bottom-" + anchor_direction) + content((), [ #percentages.at(index)% ], anchor: "top-" + anchor_direction) + } + }, + ) +} diff --git a/themes/radial/entries.typ b/themes/radial/entries.typ index 7189752..b69eca3 100644 --- a/themes/radial/entries.typ +++ b/themes/radial/entries.typ @@ -1,6 +1,6 @@ #import "./colors.typ": * #import "./icons/icons.typ" -#import "./components/components.typ" +#import "./components/title.typ" as components #import "/utils.typ" #import "./metadata.typ": entry_type_metadata @@ -23,11 +23,8 @@ header: components.title( beginning: image.decode( utils.change_icon_color(raw_icon: metadata.icon, fill: white), height: 1em, - ), - - end: context.start_date.display(), color: metadata.color, context.title, - ), - footer: [ + ), end: context.start_date.display(), color: metadata.color, context.title, + ), footer: [ #line(length: 100%) #align(left, [ *Designed by:* \ diff --git a/themes/radial/rules.typ b/themes/radial/rules.typ index b7d1d31..00ba54e 100644 --- a/themes/radial/rules.typ +++ b/themes/radial/rules.typ @@ -1,4 +1,6 @@ -#import "./components/components.typ" +#import "./components/headings.typ" as components_heading +#import "./components/code-blocks.typ" as components_code + #let rules(doc) = { set text(font: "Calibri", size: 11pt) @@ -23,10 +25,10 @@ _ #it.caption.body _ ] - show raw.where(block: false): components.raw_not_block - show raw.where(block: true): it => components.raw_block(it) + show raw.where(block: false): components_code.raw_not_block + show raw.where(block: true): it => components_code.raw_block(it) - show heading: components.heading + show heading: components_heading.heading // Display the whole document doc