Hi All,
I have a chart that has a whole year shown by day on the xaxis.
Obviously 365 axis labels don't work very well. I'd like to still display the data as days but show the lebels as 12 Months - with corresponding vertical grid lines.
How would I go about doing this?
Regards
Jon
14 Answers, 1 is accepted
What I can suggest is that you try one of the following steps:
- Take advantage of the Data Navigation functionality - http://demos.telerik.com/aspnet-ajax/htmlchart/examples/functionality/datanavigation/defaultcs.aspx
- Set the maxDateGroup property as illustrated in the http://feedback.telerik.com/Project/108/Feedback/Details/153340 feedback item.
- Set a particular step for the x-axis labels through the XAxis.LabelsAppearance.Step property.
- You can also set the x-axis labels step dynamically like this:
<
script
>
function pageLoad() {
var kendoWidget = $find("<%=RadHtmlChart1.ClientID%>").get_kendoWidget();
var count = kendoWidget._plotArea.categoryAxis.labels.length;
kendoWidget.options.categoryAxis.labels.step = Math.max(1, Math.round(100 / count));
kendoWidget.redraw();
}
</
script
>
<
telerik:RadHtmlChart
runat
=
"server"
ID
=
"RadHtmlChart1"
Width
=
"600px"
Height
=
"400px"
>
<
PlotArea
>
<
Series
>
<
telerik:LineSeries
DataFieldY
=
"SellQuantity"
>
</
telerik:LineSeries
>
</
Series
>
<
XAxis
DataLabelsField
=
"SellDate"
>
</
XAxis
>
</
PlotArea
>
</
telerik:RadHtmlChart
>
- Try to use a numeric series with dates - scatterline series.
Regards,
Danail Vasilev
Telerik
See What's Next in App Development. Register for TelerikNEXT.
Hi Danail
Thanks for that. I've tried these methods but I end up with either the data being grouped into a month or in the code example with a modified step value I get 30 days at a time.
So using a different chart example I thought maybe I could make it run a function on each label to either hide it or clear the text and effectively hide it if it isn't the label for the start of the month. That didn't work, code below, is there a variation of this that would work?
var
kendoWidget = $find(
"<%=uxRadHtmlChart.ClientID%>"
).get_kendoWidget();
var
count = kendoWidget._plotArea.categoryAxis.labels.length;
for
(
var
i = 0; i < count; i++) {
if
(kendoWidget._plotArea.categoryAxis.labels[i].content.indexOf(
'01'
) !== 0) {
kendoWidget._plotArea.categoryAxis.labels[i].options.visible =
false
;
kendoWidget._plotArea.categoryAxis.labels[i].content =
''
;
kendoWidget._plotArea.categoryAxis.labels[i].text =
''
;
}
}
kendoWidget.redraw();
Regards
Jon
You can use function for each label only through visual. You can change the color to black/transparent based on some logic:
function
pageLoad() {
var
kendoWidget = $find(
"<%=RadHtmlChart1.ClientID%>"
).get_kendoWidget();
kendoWidget.options.categoryAxis.labels.visual =
function
(e) {
var
rect =
new
kendo.geometry.Rect(e.rect.origin, [e.rect.size.width, 100]);
var
layout =
new
kendo.drawing.Layout(rect, {
orientation:
"vertical"
,
alignContent:
"center"
});
var
color;
if
(...) {
color =
"transparent"
;
}
else
{
color =
"black"
;
}
layout.append(
new
kendo.drawing.Text(e.text, [0, 0], {
fill: {
color: color
}
}));
layout.reflow();
console.log(month);
return
layout;
};
kendoWidget.redraw();
}
</script>
Regards,
Danail Vasilev
Telerik
See What's Next in App Development. Register for TelerikNEXT.
Hi Danail
Thanks for that, I can see that it should work but it just doesn't fire the event. I don't seem to be having any errors appear.
What might be the cause of it not working properly.
Note the issues that I am having with the minorgridlines in another post. Might the two issues be related?
Regards
Jon
Hi Danail
I've installed the Service Pack 1 update and that fixed it. Now to get the grid lines to be hidden in the same fashion.
Regards
Jon
Hi Danail,
Expanding on the earlier tweak I wanted to display grid lines when the date starts with 01 (same technique used to allow only certain labels to show). I have tried some code above and below the labels.visual function but neither works. Unlike an alternate thread of mine where I look at stepping the label that will not work here thanks to the inequal number of days in a month - I wonder how much extra effort is needed worldwide to cope with the inequal number of days in a month?
Anyway my code that doesn't work is shown below:
for
(
var
i = 0; i < kendoWidget._plotArea.categoryAxis.labels.length; i++) {
if
(kendoWidget._plotArea.categoryAxis.labels[i].text.indexOf(
'01'
) !== 0) {
kendoWidget._plotArea.categoryAxis._gridLines.children[i].options.stroke.color =
"transparent"
;
kendoWidget._plotArea.axisX._gridLines.children[i].options.stroke.color =
"transparent"
;
}
}
Any suggestions?
Regards
Jon
I am sorry to say that I cannot offer a reliable approach for plotting only particular grid lines based on the x-axis labels because grid lines doesn't support visual templates nor functions.
Regards,
Danail Vasilev
Telerik
See What's Next in App Development. Register for TelerikNEXT.
Hi Danail
Thanks for letting me know. Could a change request be put in for mechanism be added to allow for custom drawing on the graphs? I see that it would be a great mechanism that would be able to act as a way of making up for this and any other issues that people have.
In this case I'd simply set the grid lines to transparent then draw my own.
Regards
Jon
Indeed it is possible to draw grid lines only for particular labels. You can utilize the kendo.drawing API along with some logic regarding the labels. You can examine the code below:
<
script
>
function pageLoad() {
var $ = $telerik.$;
var chart = $find("<%=RadHtmlChart1.ClientID%>").get_kendoWidget();
chart.options.categoryAxis.labels.template = "#=kendo.format('{0:dd-MM}', new Date(value))#";
chart.redraw();
var categories = chart.options.categoryAxis.categories;
var targetDatesArray = [];
for (var i = 0; i <
categories.length
; i++) {
var
currCategory
=
kendo
.format('{0:dd-MM}', new Date(categories[i]));
if (currCategory.indexOf("01-") != -1) {
targetDatesArray.push(1);
}
else {
targetDatesArray.push(0);
}
};
var
valueAxis
=
chart
.getAxis("value");
var
categoryAxis
=
chart
.getAxis("category");
var
valueRange
=
valueAxis
.range();
var
valueSlot
=
valueAxis
.slot(valueRange.max);
var
categoryRange
=
categoryAxis
.range();
for (var
i
=
0
; i < categories.length; i++) {
if (targetDatesArray[i] == 1) {
var
categorySlot
=
categoryAxis
.slot(i);
var
path
=
new
kendo.drawing.Path({
stroke: {
color: "red",
width: 3
}
}).moveTo(categorySlot.origin.x, categorySlot.origin.y)
.lineTo(categorySlot.origin.x, valueSlot.origin.y);
chart.surface.draw(path);
}
}
}
</script>
<
telerik:RadHtmlChart
runat
=
"server"
ID
=
"RadHtmlChart1"
Width
=
"800px"
Height
=
"400px"
>
<
PlotArea
>
<
Series
>
<
telerik:LineSeries
DataFieldY
=
"SellQuantity"
>
<
LabelsAppearance
DataFormatString
=
"{1} cars sold on {0:m}"
>
</
LabelsAppearance
>
<
TooltipsAppearance
Color
=
"White"
DataFormatString="{1} cars sold on<br/>{0:D}" />
</
telerik:LineSeries
>
</
Series
>
<
XAxis
Type
=
"Category"
DataLabelsField
=
"SellDate"
Name
=
"category"
>
<
TitleAppearance
Text
=
"Sell Date"
>
</
TitleAppearance
>
<
LabelsAppearance
DataFormatString
=
"d"
>
</
LabelsAppearance
>
<
MajorGridLines
Color
=
"#EFEFEF"
Width
=
"1"
></
MajorGridLines
>
<
MinorGridLines
Color
=
"#F7F7F7"
Width
=
"1"
></
MinorGridLines
>
</
XAxis
>
<
YAxis
Name
=
"value"
>
<
TitleAppearance
Text
=
"Quantity"
>
</
TitleAppearance
>
<
MajorGridLines
Color
=
"#EFEFEF"
Width
=
"1"
></
MajorGridLines
>
<
MinorGridLines
Color
=
"#F7F7F7"
Width
=
"1"
></
MinorGridLines
>
</
YAxis
>
</
PlotArea
>
<
ChartTitle
Text
=
"Sold Cars per Date"
>
</
ChartTitle
>
</
telerik:RadHtmlChart
>
C#:
protected
void
Page_Load(
object
sender, EventArgs e)
{
RadHtmlChart1.DataSource = GetData();
RadHtmlChart1.DataBind();
}
protected
DataTable GetData()
{
DataTable dt =
new
DataTable();
dt.Columns.Add(
"ID"
,
typeof
(
int
));
dt.Columns.Add(
"SellQuantity"
,
typeof
(
int
));
dt.Columns.Add(
"SellDate"
,
typeof
(DateTime));
dt.Rows.Add(1, 2,
new
DateTime(2014, 06, 01));
dt.Rows.Add(2, 5,
new
DateTime(2014, 06, 13));
dt.Rows.Add(3, 6,
new
DateTime(2014, 07, 01));
dt.Rows.Add(4, 4,
new
DateTime(2014, 07, 16));
dt.Rows.Add(5, 7,
new
DateTime(2014, 07, 20));
dt.Rows.Add(5, 7,
new
DateTime(2014, 08, 01));
dt.Rows.Add(5, 7,
new
DateTime(2014, 08, 20));
return
dt;
}
The chart above renders like this - http://screencast.com/t/l8gAGlPRpQO2
Regards,
Danail Vasilev
Telerik
See What's Next in App Development. Register for TelerikNEXT.
Hi Danail,
Many thanks for that, I'll give it a try now. One question though, I'm a little unclear why there are two for loops in the example. Is the targetDatesArray really necessary?
Regards
Jon
I totally agree with you. Thanks for the pointing !
The code can be optimized as follows:
<script>
function
pageLoad() {
var
$ = $telerik.$;
var
chart = $find(
"<%=RadHtmlChart1.ClientID%>"
).get_kendoWidget();
chart.options.categoryAxis.labels.template =
"#=kendo.format('{0:dd-MM}', new Date(value))#"
;
chart.redraw();
var
valueAxis = chart.getAxis(
"value"
);
var
categoryAxis = chart.getAxis(
"category"
);
var
valueRange = valueAxis.range();
var
valueSlot = valueAxis.slot(valueRange.max);
var
categoryRange = categoryAxis.range();
var
categories = chart.options.categoryAxis.categories;
for
(
var
i = 0; i < categories.length; i++) {
var
isTargetCategory = kendo.format(
'{0:dd-MM}'
,
new
Date(categories[i])).indexOf(
"01-"
) != -1;
if
(isTargetCategory) {
var
categorySlot = categoryAxis.slot(i);
var
path =
new
kendo.drawing.Path({
stroke: {
color:
"red"
,
width: 3
}
}).moveTo(categorySlot.origin.x, categorySlot.origin.y)
.lineTo(categorySlot.origin.x, valueSlot.origin.y);
chart.surface.draw(path);
}
}
}
</script>
Regards,
Danail Vasilev
Telerik
See What's Next in App Development. Register for TelerikNEXT.
Hi Danail,
:)
This works very well with two remaining questions.
How would I go about getting the custom axis lines to go behind the chart - as if they were normal axis grid lines.
If the above isn't possible the alternate option is to make them transparent. I've tried various things on the stroke colour but they all seem to cause an error, in the api docs there doesn't seem to be any specific reference for transparency. Is there a way to do that?
Best Regards
Jon
You can use the code below in order to change the index of the drawing:
//chart.surface.draw(path);
chart._plotArea.panes[0].visual.insertAt(path, 3);
As for the transparency you can use the opacity property:
var
path =
new
kendo.drawing.Path({
stroke: {
color:
"red"
,
width: 3,
opacity: 0.2
}
}).moveTo(categorySlot.origin.x, categorySlot.origin.y)
.lineTo(categorySlot.origin.x, valueSlot.origin.y);
Regards,
Danail Vasilev
Telerik
See What's Next in App Development. Register for TelerikNEXT.
Hi Danail
Perfect many thanks.
Of course - just getting started with the Kendo and jQuery stuff and I'm still in the old css2 mindset of having the transparency mixed with the colour itself. That said with that insertAt function I don't need the transparency now.
Thank you for your help.
Regards
Jon