This is a migrated thread and some comments may be shown as answers.

Custom Date Labels

14 Answers 168 Views
Chart (HTML5)
This is a migrated thread and some comments may be shown as answers.
Jon
Top achievements
Rank 1
Jon asked on 07 Apr 2015, 12:31 PM

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

Sort by
0
Danail Vasilev
Telerik team
answered on 08 Apr 2015, 11:51 AM
Hello Jon,

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:
Copy Code
<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.

 
0
Jon
Top achievements
Rank 1
answered on 09 Apr 2015, 11:16 AM

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

 

0
Accepted
Danail Vasilev
Telerik team
answered on 14 Apr 2015, 10:11 AM
Hi 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.

 
0
Jon
Top achievements
Rank 1
answered on 14 Apr 2015, 11:57 AM

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

0
Jon
Top achievements
Rank 1
answered on 14 Apr 2015, 02:30 PM

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

0
Jon
Top achievements
Rank 1
answered on 30 Apr 2015, 11:55 AM

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

0
Danail Vasilev
Telerik team
answered on 05 May 2015, 11:30 AM
Hello 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.

 
0
Jon
Top achievements
Rank 1
answered on 05 May 2015, 01:00 PM

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

0
Danail Vasilev
Telerik team
answered on 07 May 2015, 12:27 PM
Hi 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.

 
0
Jon
Top achievements
Rank 1
answered on 08 May 2015, 08:18 AM

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

0
Accepted
Danail Vasilev
Telerik team
answered on 08 May 2015, 08:35 AM
Hi 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.

 
0
Jon
Top achievements
Rank 1
answered on 08 May 2015, 09:01 AM

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

0
Accepted
Danail Vasilev
Telerik team
answered on 11 May 2015, 08:10 AM
Hi 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.

 
0
Jon
Top achievements
Rank 1
answered on 11 May 2015, 08:19 AM

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

Tags
Chart (HTML5)
Asked by
Jon
Top achievements
Rank 1
Answers by
Danail Vasilev
Telerik team
Jon
Top achievements
Rank 1
Share this question
or