Skip to content
Open

0.1.4 #181

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

CeTZ-Plot is a library that adds plots and charts to [CeTZ](https://github.com/cetz-package/cetz), a library for drawing with [Typst](https://typst.app).

CeTZ-Plot requires CeTZ version ≥ 0.4.2!
CeTZ-Plot requires CeTZ version ≥ 0.5.0!

## Examples
<!-- img width is set so the table gets evenly spaced by GitHubs css -->
Expand Down Expand Up @@ -63,8 +63,8 @@ For information, see the [manual (stable)](https://github.com/cetz-package/cetz-

To use this package, simply add the following code to your document:
```
#import "@preview/cetz:0.4.2"
#import "@preview/cetz-plot:0.1.3": plot, chart
#import "@preview/cetz:0.5.2"
#import "@preview/cetz-plot:0.1.4": plot, chart

#cetz.canvas({
// Your plot/chart code goes here
Expand Down
Binary file modified gallery/barchart.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions gallery/barchart.typ
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#import "@preview/cetz:0.4.2": canvas, draw
#import "@preview/cetz-plot:0.1.3": chart
#import "@preview/cetz:0.5.2": canvas, draw
#import "@preview/cetz-plot:0.1.4": chart

#set page(width: auto, height: auto, margin: .5cm)

Expand Down
2 changes: 1 addition & 1 deletion gallery/bending.typ
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#import "@preview/cetz:0.4.2" as cetz: draw
#import "@preview/cetz:0.5.2" as cetz: draw
#import "/src/lib.typ": smartart

#set page(width: auto, height: auto, margin: .5cm)
Expand Down
Binary file modified gallery/chevron.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion gallery/chevron.typ
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#import "@preview/cetz:0.4.2" as cetz: draw
#import "@preview/cetz:0.5.2" as cetz: draw
#import "/src/lib.typ": smartart

#set page(width: auto, height: auto, margin: .5cm)
Expand Down
2 changes: 1 addition & 1 deletion gallery/circular.typ
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#import "@preview/cetz:0.4.2" as cetz: draw
#import "@preview/cetz:0.5.2" as cetz: draw
#import "/src/lib.typ": smartart

#set page(width: auto, height: auto, margin: .5cm)
Expand Down
2 changes: 1 addition & 1 deletion gallery/cycles.typ
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#import "@preview/cetz:0.4.2": canvas, draw
#import "@preview/cetz:0.5.2": canvas, draw
#import "/src/lib.typ": smartart

#set page(width: auto, height: auto, margin: .5cm)
Expand Down
Binary file modified gallery/line.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions gallery/line.typ
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#import "@preview/cetz:0.4.2": canvas, draw
#import "@preview/cetz-plot:0.1.3": plot
#import "@preview/cetz:0.5.2": canvas, draw
#import "@preview/cetz-plot:0.1.4": plot

#set page(width: auto, height: auto, margin: .5cm)

Expand Down
4 changes: 2 additions & 2 deletions gallery/piechart.typ
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#import "@preview/cetz:0.4.2"
#import "@preview/cetz-plot:0.1.3": chart
#import "@preview/cetz:0.5.2"
#import "@preview/cetz-plot:0.1.4": chart

#set page(width: auto, height: auto, margin: .5cm)

Expand Down
2 changes: 1 addition & 1 deletion gallery/process.typ
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#import "@preview/cetz:0.4.2" as cetz: draw
#import "@preview/cetz:0.5.2" as cetz: draw
#import "/src/lib.typ": smartart

#set page(width: auto, height: auto, margin: .5cm)
Expand Down
4 changes: 2 additions & 2 deletions gallery/pyramid.typ
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#import "@preview/cetz:0.4.2"
#import "@preview/cetz-plot:0.1.3": chart
#import "@preview/cetz:0.5.2"
#import "@preview/cetz-plot:0.1.4": chart

#set page(width: auto, height: auto, margin: .5cm)

Expand Down
Binary file added gallery/radarchart.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
28 changes: 28 additions & 0 deletions gallery/radarchart.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#import "@preview/cetz:0.5.2"
#import "/src/lib.typ": chart

#set page(width: auto, height: auto, margin: .5cm)

#cetz.canvas({
chart.radarchart(
(
[A],
[B],
[C],
[D],
[E],
[F],
),
(
(0.3, 1, 0.3, 0.8, 0.8, 1),
(0.9, 0.3, 0.9, 0.5, 0.5, 0.4),
),
radius: 3,
web-label-offset: 0.6,
data-style: (
blue.transparentize(10%),
red.transparentize(30%),
),
)
})

Binary file modified manual.pdf
Binary file not shown.
29 changes: 23 additions & 6 deletions manual.typ
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
#set terms(indent: 1em)
#set par(justify: true)
#set heading(numbering: (..num) => if num.pos().len() < 4 {
numbering("1.1", ..num)
})
numbering("1.1", ..num)
})
#show link: set text(blue)

// Outline
Expand All @@ -42,8 +42,8 @@ CeTZ-Plot is a simple plotting library for use with CeTZ.

This is the minimal starting point:
#pad(left: 1em)[```typ
#import "@preview/cetz:0.4.2"
#import "@preview/cetz-plot:0.1.3"
#import "@preview/cetz:0.5.2"
#import "@preview/cetz-plot:0.1.4"
#cetz.canvas({
import cetz.draw: *
import cetz-plot: *
Expand All @@ -58,7 +58,17 @@ module imported into the namespace.

#doc-style.parse-show-module("/src/plot.typ")

#for m in ("line", "bar", "boxwhisker", "contour", "errorbar", "annotation", "formats", "violin", "legend") {
#for m in (
"line",
"bar",
"boxwhisker",
"contour",
"errorbar",
"annotation",
"formats",
"violin",
"legend",
) {
doc-style.parse-show-module("/src/plot/" + m + ".typ")
}

Expand Down Expand Up @@ -87,7 +97,14 @@ plot.plot(size: (5, 4), axis-style: "school-book", y-tick-step: none, {
= Chart

#doc-style.parse-show-module("/src/chart.typ")
#for m in ("barchart", "boxwhisker", "columnchart", "piechart", "pyramid") {
#for m in (
"barchart",
"boxwhisker",
"columnchart",
"piechart",
"radarchart",
"pyramid",
) {
doc-style.parse-show-module("/src/chart/" + m + ".typ")
}

Expand Down
2 changes: 1 addition & 1 deletion src/cetz.typ
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// Import cetz into the root scope. Import cetz by importing this file only!
#import "@preview/cetz:0.4.2": *
#import "@preview/cetz:0.5.2": *
3 changes: 2 additions & 1 deletion src/chart.typ
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@
#import "chart/barchart.typ": barchart, barchart-default-style
#import "chart/columnchart.typ": columnchart, columnchart-default-style
#import "chart/piechart.typ": piechart, piechart-default-style
#import "chart/pyramid.typ": pyramid, pyramid-default-style
#import "chart/radarchart.typ": radarchart, radarchart-default-style
#import "chart/pyramid.typ": pyramid, pyramid-default-style
6 changes: 4 additions & 2 deletions src/chart/piechart.typ
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
#import "/src/cetz.typ": draw, styles, palette, util, vector, intersection
#import util: circle-arclen

#import "/src/plot/legend.typ"

// Piechart Label Kind
Expand Down Expand Up @@ -344,6 +342,10 @@
continue
}

let circle-arclen(radius, angle: 90deg) = {
calc.abs(angle / 360deg * 2 * calc.pi * radius)
}

// A sharp item is an item that should be round but is sharp due to the gap being big
let is-sharp = inner-radius == 0 or circle-arclen(inner-radius, angle: inner-angle) > circle-arclen(radius, angle: outer-angle)

Expand Down
176 changes: 176 additions & 0 deletions src/chart/radarchart.typ
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
#import "/src/cetz.typ": draw, palette, styles

#import "/src/plot.typ"

#let radarchart-default-style = (
web-style: (
stroke: black.lighten(40%),
),
web-ticks: 4,
web-label-offset: 0.4,
center-pos: (0, 0),
radius: 2,
)

/// Draw a radar chart (also known as spider chart or web chart). A radar
/// chart is a chart that represents multivariate data in the form of a
/// two-dimensional chart of three or more quantitative variables represented as
/// axes starting from the same point.
///
/// ```cexample
/// chart.radarchart(
/// (
/// [A],
/// [B],
/// [C],
/// [D],
/// [E],
/// [F],
/// ),
/// (0.3, 0.6, 0.3, 0.4, 0.8, 1),
/// )
/// ```
/// === Styling
/// Can be applied with `cetz.draw.set-style(radarchart: (web-ticks: 6))`.
///
/// *Root*: `radarchart`.
/// #show-parameter-block("web-style", "style", default: (stroke: black.lighten(40%)), [
/// Style of the web in the background of the chart.])
/// #show-parameter-block("web-ticks", ("int", "array"), default: 4, [
/// Amount of layers of the web or an array containing the distance of each web layer to draw.])
/// #show-parameter-block("web-label-offset", "float", default: 0.4, [
/// Distance from the end of the web to the label.])
/// #show-parameter-block("center-pos", "float", default: 1, [
/// Coordinate of the center of the chart.])
/// #show-parameter-block("radius", "float", default: 2, [
/// Radius of the radar chart.])
///
/// - labels (array): Array of content. Each entry is the label
/// of one coordinate axis.
///
/// *Example*
/// ```typc
/// ([A], [B], [C])
/// ```
/// - data (array): Array of data rows. A row can be of type array of float or
/// array of array of float. All float values must be within the
/// the range $0 <= "value" <= "radius"$. Each of the data rows must
/// contain the same amount of items as `labels`.
///
/// *Example*
/// ```typc
/// ((0.5, 0.3, 0.9), (0.3, 0.5, 0.2))
/// ```
/// - data-style (function, array): Style per data row. Can be either
/// - function: A function of the form `index => style` that must return a style dictionary.
/// This can be a `palette` function.
/// - array of style dictionaries: The dictionary at index `i` contains the style for the data row at index `i`.
/// - array of colors: The dictionary at index `i` contains the fill color for the data row at index `i`.
///
#let radarchart(
labels,
data,
data-style: palette.red,
..style,
) = {
assert(type(labels) == array)
assert(labels.len() >= 3)

assert(type(data) == array)
assert(data.len() != 0)
if type(data.at(0)) != array {
// only one single data line
data = (data,)
}

// ensure that all data lines have the same amount of coordinates
let size = labels.len()
for line in data {
assert(line.len() == size)
}

draw.group(ctx => {
let style = styles.resolve(
ctx.style,
merge: style.named(),
root: "radarchart",
base: radarchart-default-style,
)
draw.set-style(..style)

let center-pos = style.at("center-pos")
let radius = style.at("radius")
let web-ticks = style.at("web-ticks")
let web-label-offset = style.at("web-label-offset")

// ensure that no data point overflows out of the chart
for line in data {
for value in line {
assert(0 <= value and value <= radius)
}
}

assert(radius > 0)
assert(type(web-ticks) in (int, array))
if type(web-ticks) == int {
// automatically calculate ticks amount of equidistant ticks
web-ticks = range(web-ticks).map(i => (i + 1) / web-ticks)
}

let angle-step = 360deg / labels.len()

// draw labels and lines from center to label
// each of these axis is assigned the label "axis-{i}"
for (i, label) in labels.enumerate() {
let axis-name = "axis-" + str(i)
draw.line(
center-pos,
(
rel: (-angle-step * i + 90deg, radius),
),
name: axis-name,
)
draw.content(
(axis-name + ".start", radius + web-label-offset, axis-name + ".end"),
label,
)
}

// web drawing logic
for tick in web-ticks {
let web-points = ()
for i in range(labels.len()) {
web-points.push((
rel: (-angle-step * i + 90deg, radius * tick),
to: center-pos,
))
}
draw.line(..web-points, close: true, ..style.at("web-style"))
}

// draw the coordinates of each data line as a polygon
for (line-index, line) in data.enumerate() {
let pts = ()
for (i, value) in line.enumerate() {
let axis-name = "axis-" + str(i)
pts.push((axis-name + ".start", radius * value, axis-name + ".end"))
}

let polygon-style = (:)
if type(data-style) == array {
let s = data-style.at(line-index)
if type(data-style.at(line-index)) == dictionary {
// data-style = style dict
polygon-style = s
} else {
// data-style = list of colors -> fill polygon with these colors
polygon-style = (fill: s)
}
} else if type(data-style) == function {
// data-style = method taking the index as param
polygon-style = data-style(line-index)
}
draw.line(..pts, close: true, ..polygon-style)
}
})
}
Loading
Loading