cetz-package / cetz

CeTZ: ein Typst Zeichenpaket - A library for drawing stuff with Typst.
https://cetz-package.github.io
GNU Lesser General Public License v3.0
819 stars 35 forks source link

Columnchart - Unable to change font of text in Axis #412

Closed f3rn0s closed 8 months ago

f3rn0s commented 8 months ago

Okay so, by my understanding the default way the text in the axis gets rendeered is:

$#value$

Now, by specifying a custom format function for the axis I should be able to get it to render as normal text, and thus have the same font as the rest of my document. The problem comes in when we look at the implementation of bar/column charts. These define the axis themselves:

  let x = axes.axis(min: min-value, max: max-value,
                    label: x-label,
                    ticks: (grid: true, step: x-tick-step,
                            minor-step: none,
                            unit: x-unit, decimals: 1,
                            list: x-ticks))
  let y = axes.axis(min: data.len(), max: -1,
                    label: y-label,
                    ticks: (grid: true,
                            step: none,
                            minor-step: none,
                            list: y-tic-list))

From my understanding, since I can't edit these function calls to supply my own format function to them, I can't actually make it so the font renders as normal content.

In this case, this leads to a weird looking chart:

image

If ther eis a way to fix this and I've missed it, my apologies.

johannes-wolf commented 8 months ago

You have to wait for 0.2.0 to get released (or, if you are using Typst locally, you can install the cetz 0.2.0 branch on your machine). With 0.2.0 it is: x-format: label => text(<your-formatting..>, label) - you can provide a custom label formatting callback.

f3rn0s commented 7 months ago

Hey @johannes-wolf, with the push of 0.2.0 to latest, I'm still struggling to get this working.

You mention x-format, but in this case it would have to be something like y-format? I would love some help on this cause I can't seem to resolve the original issue using options mentioned in the manual.

johannes-wolf commented 7 months ago

You can give your data labels as content. Example:

  let data = (
    ([Item A], 1),
    ([*Bold Text*], 4)
  )

  cetz.chart.columnchart(size: (8, 6),
    data,
    label-key: 0,
    value-key: 1,
  )

The x-format and y-format only work on auto-generated tick-labels. You can also set the tick-labels using x-ticks: (...) (see manual).

johannes-wolf commented 7 months ago

Can you give example code and what you want to achieve?

f3rn0s commented 7 months ago

Sure!

This is the output:

image

Here is the code used to generate it:

#let password_lengths = (
    "< 8" : 1,
    "8"   : 5,
    "9"   : 10,
    "10"  : 55,
    "11"  : 1337,
    "12"  : 100,
    "13"  : 43,
    "> 13": 12,
)

#align(center, canvas({
    import draw: *

    let colors = palette.new(colors: (color_palette.at("main").lighten(30%), black))

    // Remove background grid
    set-style(
        grid: (
            stroke: none,
        ),
    )

    chart.columnchart(
        size: (auto, password_lengths.keys().len()),
        mode: "stacked",
        value-key: (1,),
        bar-style: colors,
        {
            let result_data = ()

            for key in password_lengths.keys() {
                result_data.push((key, password_lengths.at(key)))
            }

            //panic(result_data)
           result_data
        },
    )
}))

Since the y-tick is auto-generated, I'd like it to be text as opposed to $$, but I wasn't sure how to get that working.

johannes-wolf commented 7 months ago

Set y-format: v => [#calc.round(v)],

f3rn0s commented 7 months ago

That worked perfectly, thank you very much :)