Skip to content

Customize value labels for lower/upper in range charts #83

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
kentcb opened this issue Jun 4, 2021 · 3 comments
Closed

Customize value labels for lower/upper in range charts #83

kentcb opened this issue Jun 4, 2021 · 3 comments

Comments

@kentcb
Copy link

kentcb commented Jun 4, 2021

Description

Labels for lower/upper values are based on Ticktext except when they don't align perfectly, in which case there does not appear to be a way to customize the labels (they instead show raw values).

Repro steps

let yAxis =
    Axis.LinearAxis.init(
        Title = "Y",
        Showline = true,
        Range = StyleParam.Range.MinMax (0.0, 2.0),
        Tickvals = [0.0 .. 2.0],
        Ticktext = [ "zero"; "one"; "two" ]
    )
Chart.Range(
    [1;2],
    [1;1],
    [0.0;0.53622183],
    [1.0;2.0],
    StyleParam.Mode.None,
    Name = "",
    LowerName = "Lower",
    UpperName = "Upper",
    Labels = [])
|> Chart.withY_Axis (yAxis)
|> Chart.Show

This looks fine when hovering over values that align perfectly with tick increments:

image

But when hovering over misaligned values, one sees the raw value:

image

Expected behavior

A means of providing labels for both upper and lower. In my case, I'm mapping values to times, so when it aligns perfectly I see a time of day, but when it doesn't I see an ugly floating point value.

Actual behavior

As far as I can tell, there's no API for this.

Known workarounds

None.

Related information

  • Windows 10
  • 2.0.0-preview.1
  • .NET 5
@kMutagene
Copy link
Collaborator

kMutagene commented Jun 11, 2021

I think this is definitely a meaningful addition to the range chart, i will add LowerLabels and UpperLabels to the method.

Two suggestions from my side in the meantime:

  1. You seem to be very interested in Range Charts - in your case it might be in the long run worth it to compose the Chart yourself (it is three line charts for upper, mean and lower values, with a Fill=StyleParam.Fill.ToNext_y for the upper trace). That way you have full control over all three traces, and the argument list of this function stays manageable - I do not think that it is good to get all possible styling arguments of Line traces for all three subtraces of the range chart into the Chart.Range method, it would be quite an amount of arguments.

  2. Another approach for full control would be customizing each trace via the genericChart.mapiTrace function, customizing each trace after you used the Chart.Range method:

Chart.Range(
    [1;2],
    [1;1],
    [0.0;0.53622183],
    [1.0;2.0],
    StyleParam.Mode.None,
    Name = "",
    LowerName = "Lower",
    UpperName = "Upper",
    Labels = [])
|> Chart.withY_Axis (yAxis)
|> GenericChart.mapiTrace (fun i t ->
    match i with
    | 0 -> t |> Trace.TraceStyle.TextLabel ["upperOne";"upperTwo"]
    | 1 -> t |> Trace.TraceStyle.TextLabel ["lowerOne";"lowerTwo"]
    | 2 -> t
)
|> Chart.Show

image

Not sure if you want to get rid of the value display above the label as well though.

@kentcb
Copy link
Author

kentcb commented Jun 11, 2021

Haha, I was just looking at this again and came back to post my (ugly) solution. I also added LowerLabels and UpperLabels to Chart.Range with an intent to PR, but then found I also needed control over the template and went down the dynamic route. However, I wasn't aware of mapiTrace, so I ended up with this monstrosity:

let yAxis =
    Axis.LinearAxis.init(
        Title = "Y",
        Showline = true,
        Range = StyleParam.Range.MinMax (0.0, 2.0),
        Tickvals = [0.0 .. 2.0],
        Ticktext = [ "zero"; "one"; "two" ]
    )

Chart.Range(
    [1;2],
    [1;1],
    [1.0;2.0],
    [0.0;0.53622183],
    StyleParam.Mode.None,
    Name = "",
    LowerName = "Lower",
    //LowerLabels = ["nada";"around one half"],
    UpperName = "Upper",
    //UpperLabels = ["one";"Two!"],
    Labels = [])
|> Chart.withY_Axis (yAxis)
|> (fun chart ->
        match chart with
        | GenericChart.MultiChart ([lower;upper;_], _, _, _) ->
            lower?text <- ["nada";"around one half"]
            lower?hovertemplate <- "%{text}"

            upper?text <- ["one";"Two!"]
            upper?hovertemplate <- "%{text}"

            chart
        | _ -> failwith "Couldn't set dynamic options")
|> Chart.Show

@kMutagene
Copy link
Collaborator

As long as it worked out for you and you found where to customize things, i would count that as a win generally 😄. I added LowerLabels and UpperLabels to Chart.Range, so you do not have to do this in the future though ;) the package (2.0.0-preview.4) should be up on nuget any minute

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants