I have a column chart that I am using to display percentage values. There is some JS used to colour columns depending on their %, normally I have 70 or lower red, 70-90 amber and above 90 as green. On occasion I want to drop the green tolerance down to 80. I can do all this fine.
What I need to do is display some form of indication for each column. I was thinking that perhaps I could display 3 plotbands behind each column as an indication of where the various tolerances are.
Would this be possible?
Failing that is there a way to do custom drawing on the canvas behind the columns?
Regards
Jon
5 Answers, 1 is accepted
I can suggest that you utilize the kendo.drawing API in order to draw the threshold lines, as illustrated here - http://docs.telerik.com/kendo-ui/api/javascript/dataviz/ui/chart#methods-getAxis
For example:
<script> var valueSlots = [1.5, 3, 2.5]; function OnLoad(args) { var chart = args.get_kendoWidget(); var valueAxis = chart.getAxis("value"); var categoryAxis = chart.getAxis("category"); var catetgoriesCount = categoryAxis._axis.labelsCount(); for (var i = 0; i < catetgoriesCount; i++) { var valueSlot = valueAxis.slot(valueSlots[i]); var categorySlot = categoryAxis.slot(i, i + 1); var path = new kendo.drawing.Path({ stroke: { color: "red", width: 3 } }).moveTo(categorySlot.origin.x, valueSlot.origin.y) .lineTo(categorySlot.bottomRight().x, valueSlot.origin.y); chart.surface.draw(path); } }</script><telerik:RadHtmlChart runat="server" ID="RadHtmlChart1" Width="600px" Height="400px"> <ClientEvents OnLoad="OnLoad" /> <PlotArea> <Series> <telerik:ColumnSeries Name="Product 1"> <SeriesItems> <telerik:CategorySeriesItem Y="1" /> <telerik:CategorySeriesItem Y="2" /> <telerik:CategorySeriesItem Y="3" /> </SeriesItems> </telerik:ColumnSeries> </Series> <YAxis Name="value"></YAxis> <XAxis Name="category"> <Items> <telerik:AxisItem LabelText="1" /> <telerik:AxisItem LabelText="2" /> <telerik:AxisItem LabelText="3" /> </Items> </XAxis> </PlotArea> <ChartTitle Text="Product sales for 2011"> </ChartTitle> <Legend> <Appearance Position="Bottom" /> </Legend></telerik:RadHtmlChart>The only thing you should modify is the valueSlots array where are defined the y points for the thresholds. You should also ensure names for the x and y axis in order to reference them.
Regards,
Danail Vasilev
Telerik
See What's Next in App Development. Register for TelerikNEXT.
Hi Danail,
Thanks for this. I have it working - kind of. I've had to muck around with it because I had the custom colouring on the series columns. How would I go about getting the lines to go behind the series column bars, at the moment they appear in front.
I've attached the code below.
Regards
Jon
function pageLoad() { //var chart = $find("uxRadHtmlChart"); ////chart._chartObject.options.yAxis.majorGridLines.step = 5; //chart.get_kendoWidget().options.valueAxis.minorGridLines.step = 5; //chart.get_kendoWidget().options.valueAxis.majorGridLines.step = 10; //chart.repaint(); if ($find("uxRadHtmlChart") !== null) { //try { var kendoWidget = $find("<%=uxRadHtmlChart.ClientID%>").get_kendoWidget(); kendoWidget.options.series[0].color = function (e) { if (e.value < e.dataItem.RedValue) { return "red"; } else { if (e.value >= e.dataItem.GreenValue) { return "green"; } else { return "orange"; } } } kendoWidget.redraw(); var valueAxis = kendoWidget.getAxis("value"); var categoryAxis = kendoWidget.getAxis("category"); var catetgoriesCount = categoryAxis._axis.labelsCount(); for (var i = 0; i < catetgoriesCount; i++) { var categorySlot = categoryAxis.slot(i, i + 1); var redValueSlot = valueAxis.slot(categoryAxis._axis.children[i].dataItem.RedValue); var redPath = new kendo.drawing.Path({ stroke: { color: "rgba(255, 0, 0, 0.3)", width: 3 } }).moveTo(categorySlot.origin.x, redValueSlot.origin.y) .lineTo(categorySlot.bottomRight().x, redValueSlot.origin.y); kendoWidget.surface.draw(redPath); var amberValueSlot = valueAxis.slot(categoryAxis._axis.children[i].dataItem.GreenValue); var amberPath = new kendo.drawing.Path({ stroke: { color: "rgba(255, 115, 30, 0.3)", width: 3 } }).moveTo(categorySlot.origin.x, amberValueSlot.origin.y) .lineTo(categorySlot.bottomRight().x, amberValueSlot.origin.y); kendoWidget.surface.draw(amberPath); } //} catch (err) { // // do nothing //} } };There isn't a public API for this yet. However, you can try to replace the following line of code:
kendoWidget.surface.draw(amberPath);kendoWidget._plotArea.panes[0].visual.insertAt(amberPath, 0);Regards,
Danail Vasilev
Telerik
See What's Next in App Development. Register for TelerikNEXT.
Hi Danail
Ah that gets it closer - many thanks.
I have noticed that if the line hits a grid line then the grid line appears above the custom line. What is the structure of the kendoWidget._plotArea.panes[0].visual object? If I understand that I can adjust where the lines get inserted. I tried adjusting the insertion point and it worked for some columns but not others.
Regards
Jon
Hi Danail,
Not sure what happened to my first test but retrying I have found that using position 2 in the array allows for the perfect insertion, above the grid but below the columns.
kendoWidget._plotArea.panes[0].visual.insertAt(redPath, 2);
Thanks for your help.
Regards
Jon