Hello, I have a requirement to change categoryAxis labels positions as per the negative and positive value so that they don't overlap with the bars. Like the one in below image. I tried the label rotation property, but it gets applied to all the bars irrespective of it's value. Is there any workaround to achieve this?
13 Answers, 1 is accepted
Hello Abhi,
In order to customize the position of the categoryAxis labels depending on the values, I would suggest using the categoryAxis.labels.visual function. It will give you full control over how the labels will be drawn.
Here is a runnable dojo example: https://dojo.telerik.com/AkiqinAW/2
Kind Regards,
Silviya Stoyanova
Progress Telerik
Hello Silviya,
I tried the solution you provided. It works pretty well. But the labels which have long text, overlap each other. How can i avoid that? I tried the rotation property. But it didn't work. I have created a Dojo (link below) with my requirement and you will be able to see the problem that i am talking about. Please provide a way to avoid overlapping of labels.
https://dojo.telerik.com/EMIGaNiw
Hello Abhi,
In order to overcome the issue related to labels overlapping, you will need to do some additional transformations into the visual function. It is necessary because that function takes control over the labels' outlook.
For example, set the rotation as follows:
https://docs.telerik.com/kendo-ui/api/javascript/geometry/transformation/methods/rotate
var text;
for (var i = 0; i < words.length; i++) {
text = new kendo.drawing.Text(words[i]);
text.transform( kendo.geometry.transform().rotate(-10))
layout.append(text);
}
I have prepared two examples:
I hope that helps.
Kind Regards,
Silviya Stoyanova
Progress Telerik
Hello Silviya,
It works well. Thank you so much for the solution.
The example you posted works fine. In my requirement, I am cropping the labels if they are above certain length. I have created below example, in which you can see that 1st label 'StartSportsStartSports1' got cropped as there isn't enough space below to show entire label. But in case of label 'StarttPlusHDD23', there is enough space above to show complete label, still it got cropped. So how can I show label without cropping, if there is enough space for the complete label to show up? Is there a workaround to detect space above/below the label? or any other way?
Link to my example: https://dojo.telerik.com/aXoxodEh
Hello Abhi,
I am afraid I can not propose a solution for a dynamic cropping of the labels. However, I have noticed that the length of 'StarttPlusHDD23' is 15 characters, and you are cropping the text when the length is greater than 14. Is not it possible to compare it with 20 characters for example?
If it is applicable in your scenario try adding an ellipsis to all labels and showing the full text in a tooltip. The disadvantage will be that the Chart will have tooltips for the series and tooltips for the labels. Something like that:
Kind Regards,
Silviya Stoyanova
Progress Telerik
Hello Silviya,
I have used render method for displaying complete label on hover. It is working fine. I can make do without dynamic cropping. I have alignment problem of labels. I have attached an image and example to show the issue. I tried the alignContent: start property so that alignment of all labels will be from start. But it doesn't solve the issue. How can I fix it so that all labels will begin from same position? (as it happens with default positioning)
Example: https://dojo.telerik.com/aXoxodEh/2
Hello Abhi,
In order to overcome the alignment issue with the labels, I would suggest the following small change in the visual function:
visual: function(e) {
var origin = e.rect.origin;
if(e.value === "BTS" || e.value === "StarttPlusHDD23" ||
e.value == "Jul2" || e.value == "E!" || e.value == "Seppp"){
origin.y -= e.rect.size.height + 20;
}
//...
I hope that helps.
Kind Regards,
Silviya Stoyanova
Progress Telerik
Hello Silviya,
Thank you so much. It works perfectly. Thanks for your quick help!
Hello Silviya,
I have a strange issue here. I have made the chart movable along Y axis using 'Pannable: { lock: "Y" }' property as I have lots of data. And also set the min and max values for categoryAxis. Now when I move along Y axis to right, if the chart has both positive & negative values, labels look fine. but if only negative values are seen in the chart then labels are placed way above the axis. I have attached images of both cases. Also added an example code. Please suggest some workaround to position the labels normally in the latter case.
Example- https://dojo.telerik.com/UlufebAs
Hi,
You may add another condition and watch the value of the new label y does not become less than a value that suits you.
I tested the provided example and it seems that 120 looks and behaves well:
https://dojo.telerik.com/@bubblemaster/OpiLoRIv
if(origin.y- e.rect.size.height + 20 > 120){
origin.y -= e.rect.size.height + 20;
}
Regards,
Alex Hajigeorgieva
Progress Telerik
Five days of Blazor, Angular, React, and Xamarin experts live-coding on twitch.tv/CodeItLive, special prizes, and more, for FREE?! Register now for DevReach 2.0(20).
Hi Alex,
Thanks for this. I will surely try it and post my response. Also, Can you please suggest some solution for the issue I asked earlier. I am cropping the labels if they are above certain length. I have created below example, in which you can see that 1st label 'StartSportsStartSports1' got cropped as there isn't enough space below to show entire label. But in case of label 'StarttPlusHDD23', there is enough space above to show complete label, still it got cropped. So how can I show label without cropping, if there is enough space for the complete label to show up? Is there a workaround to detect space above/below the label? or any other way?
Please refer my previous example: https://dojo.telerik.com/UlufebAs
Hello Janhavi,
One way the template can check if the label is above or below is setting the series.categoryField and series.field. Then, the dataItem will be available in the categoryAxis.labels.template.
Series with defined categoryField and field:
series: [{
name: "Unique visitors",
categoryField: "visitor",
field: "amount",
data: [
{ visitor: "StartSportsStartSports1", amount: 52000 },
{ visitor: "SonySports2", amount: 34000 },
{ visitor: "BTS", amount: -23000 },
{ visitor: "VisualTV", amount: 48000 },
{ visitor: "MonDayBlue", amount: 50000 },
{ visitor: "StarttPlusHDD23", amount: -3000 },
{ visitor: "Jul2", amount: -40000 },
{ visitor: "E!", amount: -50000 },
{ visitor: "Seppp", amount: -55000},
{ visitor: "Oct", amount: -67000 },
{ visitor: "Nov", amount: -86000},
{ visitor: "Dec", amount: -91000 }]
}],
CategoryAxis with template:
categoryAxis: {
majorGridLines: {
visible: false
},
line: {
visible: true
},
min: 0,
max: 5,
labels: {
template: "#=cropLabels(value, dataItem)#",
justified: true,
visual: function(e) {
//....
return layout;
}
}
}
Now, the template can be modified to check if the amount is greater than 0:
function cropLabels(value, dataItem) {
if (value.length > 14 && dataItem.amount > 0) {
value = value.substring(0, 10);
return value + "...";
}
return value;
}
Please take a look at this modified Progress Kendo UI Dojo which demonstrates the above.
Hope this helps!
Regards,
Patrick
Progress Telerik
Virtual Classroom, the free self-paced technical training that gets you up to speed with Telerik and Kendo UI products quickly just got a fresh new look + new and improved content including a brand new Blazor course! Check it out at https://learn.telerik.com/.