Skip to content
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

How to modify data labels? #92

Closed
AlvinSartorTrityum opened this issue May 18, 2022 · 12 comments · Fixed by #128
Closed

How to modify data labels? #92

AlvinSartorTrityum opened this issue May 18, 2022 · 12 comments · Fixed by #128
Labels
enhancement New feature or request

Comments

@AlvinSartorTrityum
Copy link

I have played with the treemap and got to this result:
image

But what I aim at is this:
image

Is is possible to modify the labels and set different sizes (maybe via a plugin?)
Also, labels currently do not wrap (unless we wrap them manually by using arrays). You think this is something we have to stick with or it would be possible to also automatically wrap them somehow?

@nullpaper
Copy link

@kurkle would it be possible as OP requests to override implementations using some kind of plugin system? Writing up a custom label renderer would help solve this.

Re: https://github.com/kurkle/chartjs-chart-treemap/blob/next/src/controller.js#L136

@stockiNail
Copy link
Collaborator

@nullpaper I think, instead of referring to a plugin, the controller could expose the hooks which can be implemented.

  data: {
    datasets: [{
      ...
      captions: {
        display: true,
        draw(context) { 
          ....  // <-- custom drawing  
        } 
      },
      labels: {
        display: true,
        draw(context) {
          ....  // <-- custom drawing
        }
      }
    }]
  },

This kind of enhancement could open the door to many issues even if it could be the most flexible solution.

Maybe you could evaluate to invoke the scriptable options for color and font for each line of the label, and draw them accordingly with the result of the callback. This must be checked if doable (due to proxies) and could increase complexity on size calculation of the elements as well.

@stockiNail
Copy link
Collaborator

@AlvinSartorTrityum @nullpaper I had a look a bit to the implementation and I think this could be doable changing how the font and color are managed now for the labels, using a scriptable option.
Now, activating a scriptable option, the font and color options must return a single instance. But we could change that, allowing to return an array of objects and the controller could apply the font and color at index of the provided array using the index of the label in the labels array.

 ....
  formatter: () => ['label1', 'label2', 'label3'],
  font: () => [{size: 24}, {size:14}],
  color: {} => ['white', 'grey'],
 ....

With above sample, we could have:

  • label1 will be drawn with font: {size: 24} and color 'white'
  • label2 will be drawn with font: {size: 14} and color 'gray'
  • label3 will be drawn with font: {size: 14} and color 'gray'

I have played a bit locally and sounds working. The calculation of the label point, where starting drawing, should be rewritten and it could be a breaking change.

@kurkle @LeeLenaleee what do you think? This could be also applicable to annotation plugin to address the enhancement chartjs/chartjs-plugin-annotation#739

@AlvinSartorTrityum
Copy link
Author

@stockiNail thanks for your answer! Having the possibility to use different formatting for the labels would be great, but it would not solve 100% of our problem.

The fact is that labels are often cut and that looks quite bad. Ideally, the labels should be removed altogether if the square is too small for them. If the user wanted to get more info, they could still mouse-hover and see the tooltip.

image

My company is asking to stop using this plugin because of the cut labels, while I am rooting to keep it, but I need this feature to allow that 🤓

@stockiNail
Copy link
Collaborator

Got it! I agree. Similar to #67. As soon as I have time, I'll have a look. Maybe that last one issue, could be addressable as the first one if you agree

@stockiNail
Copy link
Collaborator

And if you agree, I'd like to complete the PR #102 where the drawing is moved to the element to be more consistent. Some functions to draw the label are changed and maybe you can wait for a while.
Furthermore I think it could helpful to add an additional option, clip, where the user can decide if he/she wants to cut the label or to show anyway overriding the other elements or automatically decide to omit the label is bigger then the box.

 ... clip: true ! false | 'auto'

That's my thought, thinking loud, but the community will decide if the feature could be added or not. ;)

@stockiNail
Copy link
Collaborator

stockiNail commented Sep 17, 2022

@AlvinSartorTrityum I have created another issue about the labels visibility if the rectangle is too small.

EDIT: created PR #106

@stockiNail
Copy link
Collaborator

@AlvinSartorTrityum as you can see the issue has been closed. In next version of this controller, 2 features, related to this issue, will be released and they are:

  1. with new overflow option in labels configuration set to 'hidden', you can hide the label if the square is too small for it. Default is 'cut'.
  2. when the label to draw has multiple lines, you can use different font and color for each row of the label. This is enabled configuring an array of fonts or colors for those options. When the lines are more than the configured fonts or colors, the last configuration of those options is used for all remaining lines.

@lrdj
Copy link

lrdj commented Nov 3, 2022

Hello all, late to this and not a JS developer.

I'm having both issues identified by @AlvinSartorTrityum that is:

  1. Labels are rendered in boxes too small to do so legibly
  2. Labels do not accept line breaks (<br> or \n are removed in the standard code?) and do not wrap natively, always being rendered as one line that can be cropped by the edge of the box

My question is could the script hand the rendering back to the browser?

It seems like being able to handle this with CSS box specifications and font behaviours (which would also include right-to-left an unicode fonts etc.) would allow the tool to be used by nonscripters and would ultimately made the the rendering more robust.

Is that an idea?

All the best:-)

@stockiNail
Copy link
Collaborator

  1. Labels are rendered in boxes too small to do so legibly

@lrdj new overflow option in labels configuration set to 'hidden', you can hide the label if the square is too small for it. Default is 'cut'.

2. Labels do not accept line breaks (
or \n are removed in the standard code?) and do not wrap natively, always being rendered as one line that can be cropped by the edge of the box

@lrdj the controller doesn't split any label/string (with
or \n char) but you can provide an array of strings which will be drawn as multiline label.

It seems like being able to handle this with CSS box specifications and font behaviours (which would also include right-to-left an unicode fonts etc.)

We can have a look! Thanks!

@lrdj
Copy link

lrdj commented Nov 3, 2022

  1. Labels are rendered in boxes too small to do so legibly

@lrdj new overflow option in labels configuration set to 'hidden', you can hide the label if the square is too small for it. Default is 'cut'.

2. Labels do not accept line breaks (
or \n are removed in the standard code?) and do not wrap natively, always being rendered as one line that can be cropped by the edge of the box

@lrdj the controller doesn't split any label/string (with
or \n char) but you can provide an array of strings which will be drawn as multiline label.

It seems like being able to handle this with CSS box specifications and font behaviours (which would also include right-to-left an unicode fonts etc.)

We can have a look! Thanks!

Thanks for the response!

Could you point me to a code sample of using arrays to create a multi-line label?

Thanks again for all the work you do!

@stockiNail
Copy link
Collaborator

Have a look to the sample section: https://chartjs-chart-treemap.pages.dev/samples/labelsFontsAndColors.html

To have a multiline label, the formatter scriptable option must return an array.

          formatter(ctx) {
            if (ctx.type !== 'data') {
              return;
            }
            return [ctx.raw._data.what, 'Value is ' + ctx.raw.v];
          },

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
4 participants