Points plotted in wrong locations

5 posts, 0 answers
  1. Travis
    Travis avatar
    7 posts
    Member since:
    Aug 2011

    Posted 20 Apr Link to this post

    So,I have an HtmlChart that I'm using for some graphs a client of mine needs. I've managed to get everything done up just so, but I noticed when I looked at the tooltip for the points,that the points appear to be plotted in the wrong location. (See image)

    I've double-checked that the tooltip is showing the correct values for the points. But as you can see in the image, the points are off.

     

    Any help with this is greatly appreciated.

  2. Travis
    Travis avatar
    7 posts
    Member since:
    Aug 2011

    Posted 20 Apr Link to this post

    Turns out, but subtracting an additional .5 from the MinValues of the X and Y Axis and adding an additional .5 to the MaxValues of the X and Y Axis, it plots correctly.

    So, it appears, if you set the MinValues to the minimum point values and set the MaxValues to the maximum point values + 1, the chart will not plot correctly.It doesn't make much sense to me, but at least now I have a work-around.

  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Ianko
    Admin
    Ianko avatar
    1535 posts

    Posted 25 Apr Link to this post

    Hi Travis,

    I tried to replicate the same situation locally, but to no avail. 

    Here is the code I used:
    <telerik:RadHtmlChart runat="server" ID="ScatterLineChart1" Transitions="true">
        <PlotArea>
            <Series>
                <telerik:ScatterLineSeries Name="0.8C" MissingValues="Gap">
                    <MarkersAppearance MarkersType="Circle" />
                    <SeriesItems>
                        <telerik:ScatterSeriesItem X="28.6" Y="89.8" />
                        <telerik:ScatterSeriesItem X="30" Y="90" />
                    </SeriesItems>
                </telerik:ScatterLineSeries>
            </Series>
            <XAxis MinValue="27" MaxValue="35">
                <MinorGridLines Visible="false" />
            </XAxis>
            <YAxis MinValue="84" MaxValue="91">
                <MinorGridLines Visible="false" />
            </YAxis>
             
        </PlotArea>
    </telerik:RadHtmlChart>

    And here is the result I get:


    Regards,
    Ianko
    Telerik
    Do you need help with upgrading your ASP.NET AJAX, WPF or WinForms projects? Check the Telerik API Analyzer and share your thoughts.
  5. Travis
    Travis avatar
    7 posts
    Member since:
    Aug 2011

    Posted 25 Apr in reply to Ianko Link to this post

    I am postingg the ASP.NET code and the C# code I have in the code-behind in this post so you can create a single page ASP.NET WebForms app and duplicate the results:

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="HtmlChartProblem.Default" %>
     
    <%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
     
    <!DOCTYPE html>
     
    <head runat="server">
        <title></title>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
            <telerik:RadHtmlChart ID="chartProctor" runat="server" Width="300" Height="275" BackColor="WhiteSmoke" BorderColor="Black" BorderWidth="1">
                <PlotArea>
                    <XAxis AxisCrossingValue="0" Color="Black" MajorTickType="Outside" MinorTickType="Outside"
                        Reversed="false" Step="1" Type="Auto">
                        <LabelsAppearance DataFormatString="{0:D}" RotationAngle="0" />
                        <MajorGridLines Color="#000000" Width="1" />
                        <MinorGridLines Color="Black" Width="1" Visible="false" />
                        <TitleAppearance Position="Center" RotationAngle="0" Text="Moisture Content (%)" />
                    </XAxis>
                    <YAxis AxisCrossingValue="0" Color="Black" MajorTickSize="1" MajorTickType="Outside"
                        MinorTickSize="1" MinorTickType="None" MinValue="0" Reversed="false"
                        Step="2" Type="Numeric">
                        <LabelsAppearance DataFormatString="{0:D}" RotationAngle="0" />
                        <MajorGridLines Color="#000000" Width="1" />
                        <MinorGridLines Color="#F7F7F7" Width="1" Visible="false" />
                        <TitleAppearance Position="Center" RotationAngle="-90" Text="Dry Density (pcf)" />
                    </YAxis>
                </PlotArea>
                <Legend>
                    <Appearance Visible="false" Position="Bottom" />
                </Legend>
            </telerik:RadHtmlChart>
        </div>
        </form>
    </body>
    </html>

    And here is the code I put in the code-behind:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using Telerik.Web.UI;
     
    namespace HtmlChartProblem
    {
        public partial class Default : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                PlotProctorGraph();
            }
     
            private void solveTridiag(decimal[] sub, decimal[] diag, decimal[] sup, ref decimal[] b, int n)
            {
                /*                  solve linear system with tridiagonal n by n matrix a
                                    using Gaussian elimination *without* pivoting
                                    where   a(i,i-1) = sub[i]  for 2<=i<=n
                                            a(i,i)   = diag[i] for 1<=i<=n
                                            a(i,i+1) = sup[i]  for 1<=i<=n-1
                                    (the values sub[1], sup[n] are ignored)
                                    right hand side vector b[1:n] is overwritten with solution
                                    NOTE: 1...n is used in all arrays, 0 is unused */
                int i;
                /*                  factorization and forward substitution */
                for (i = 2; i <= n; i++)
                {
                    sub[i] = sub[i] / diag[i - 1];
                    diag[i] = diag[i] - sub[i] * sup[i - 1];
                    b[i] = b[i] - sub[i] * b[i - 1];
                }
                b[n] = b[n] / diag[n];
                for (i = n - 1; i >= 1; i--)
                {
                    b[i] = (b[i] - sup[i] * b[i + 1]) / diag[i];
                }
            }
     
            private void PlotProctorGraph()
            {
                ScatterLineSeries series = new ScatterLineSeries();
                ScatterSeries scatterSeries = new ScatterSeries();
     
                scatterSeries.LabelsAppearance.DataFormatString = "{0}";
                scatterSeries.LabelsAppearance.Visible = false;
                scatterSeries.TooltipsAppearance.DataFormatString = "{0}, {1}";
                scatterSeries.TooltipsAppearance.BackgroundColor = System.Drawing.Color.White;
                scatterSeries.Appearance.FillStyle.BackgroundColor = System.Drawing.Color.Red;
     
                ScatterSeriesItem item;
     
                //Simulate reading data from the database and performing calculations to determine
                //point coordinates for plot. They are hard-coded here for simplicity so I don't have
                //to provide the database along with this sample
     
                // Plot 1
                item = new ScatterSeriesItem(16M, 100.9M, System.Drawing.Color.Red);
                scatterSeries.SeriesItems.Add(item);
     
                // Plot 2
                item = new ScatterSeriesItem(17.6M, 102.7M, System.Drawing.Color.Red);
                scatterSeries.SeriesItems.Add(item);
     
                // Plot 3
                item = new ScatterSeriesItem(19.8M, 100.6M, System.Drawing.Color.Red);
                scatterSeries.SeriesItems.Add(item);
     
                // Plot 4
                item = new ScatterSeriesItem(21.9M, 95M, System.Drawing.Color.Red);
                scatterSeries.SeriesItems.Add(item);
     
                chartProctor.PlotArea.Series.Add(scatterSeries);
     
                int numberOfPoints = scatterSeries.SeriesItems.Count;
     
                if (numberOfPoints > 1)
                {
                    int precision = 10;
                    decimal[] xcoords = new decimal[numberOfPoints], ycoords = new decimal[numberOfPoints];
     
                    for (int i = 0; i < numberOfPoints; i++)
                    {
                        xcoords[i] = (decimal) scatterSeries.SeriesItems[i].X;
                        ycoords[i] = (decimal) scatterSeries.SeriesItems[i].Y;
                    }
     
                    series = new ScatterLineSeries();
     
                    series.LabelsAppearance.DataFormatString = "{0}";
                    series.LabelsAppearance.Visible = false;
                    series.TooltipsAppearance.DataFormatString = "{0:N1}, {1:N1}";
                    series.TooltipsAppearance.BackgroundColor = System.Drawing.Color.White;
                    series.Appearance.FillStyle.BackgroundColor = System.Drawing.Color.Gray;
                    series.LineAppearance.LineStyle = Telerik.Web.UI.HtmlChart.Enums.LineStyle.Smooth;
                    series.MarkersAppearance.Visible = false;
     
                    decimal[] a = new decimal[numberOfPoints];
                    decimal x1, x2, x, y;
                    decimal[] h = new decimal[numberOfPoints];
                    for (int i = 1; i <= numberOfPoints - 1; i++)
                    {
                        h[i] = xcoords[i] - xcoords[i - 1];
                    }
                    if (numberOfPoints > 2)
                    {
                        decimal[] sub = new decimal[numberOfPoints - 1];
                        decimal[] diag = new decimal[numberOfPoints - 1];
                        decimal[] sup = new decimal[numberOfPoints - 1];
     
                        for (int i = 1; i <= numberOfPoints - 2; i++)
                        {
                            diag[i] = (h[i] + h[i + 1]) / 3;
                            sup[i] = h[i + 1] / 6;
                            sub[i] = h[i] / 6;
                            a[i] = (ycoords[i + 1] - ycoords[i]) / h[i + 1] - (ycoords[i] - ycoords[i - 1]) / h[i];
                        }
                        solveTridiag(sub, diag, sup, ref a, numberOfPoints - 2);
                    }
                    // note that a[0]=a[np-1]=0
                    // draw
     
                    for (int i = 1; i <= numberOfPoints - 1; i++)
                    {   // loop over intervals between nodes
                        for (int j = 1; j <= precision; j++)
                        {
                            x1 = (h[i] * j) / precision;
                            x2 = h[i] - x1;
                            y = ((-a[i - 1] / 6 * (x2 + h[i]) * x1 + ycoords[i - 1]) * x2 +
                                (-a[i] / 6 * (x1 + h[i]) * x2 + ycoords[i]) * x1) / h[i];
                            x = xcoords[i - 1] + x1;
     
                            item = new ScatterSeriesItem(x, y, System.Drawing.Color.Red);
                            series.SeriesItems.Add(item);
                        }
                    }
     
                    chartProctor.PlotArea.Series.Add(series);
                }
     
                series = new ScatterLineSeries();
     
                series.LabelsAppearance.DataFormatString = "{0}";
                series.LabelsAppearance.Visible = false;
                series.TooltipsAppearance.DataFormatString = "{0:N1}, {1:N1}";
                series.TooltipsAppearance.BackgroundColor = System.Drawing.Color.White;
                series.Appearance.FillStyle.BackgroundColor = System.Drawing.Color.Gray;
                series.LineAppearance.LineStyle = Telerik.Web.UI.HtmlChart.Enums.LineStyle.Smooth;
                series.MarkersAppearance.Visible = false;
     
                //Normally the arrays would contain data from the database, but as the values are hard-coded
                //for simplicity, I hard-code the array values here
     
                chartProctor.PlotArea.XAxis.MinValue = Convert.ToDecimal(GetMinNumber(new string[] { "16", "17.6", "19.8", "21.9" }) - .5);
                chartProctor.PlotArea.YAxis.MinValue = Convert.ToDecimal(GetMinNumber(new string[] { "100.9", "102.7", "100.6", "95" }) - .5);
     
                chartProctor.PlotArea.XAxis.MaxValue = Convert.ToDecimal(GetMaxNumber(new string[] { "16", "17.6", "19.8", "21.9" }) + 1.5);
                chartProctor.PlotArea.YAxis.MaxValue = Convert.ToDecimal(GetMaxNumber(new string[] { "100.9", "102.7", "100.6", "95" }) + 1.5);
            }
     
            protected double GetMaxNumber(string[] arrNumbers)
            {
                double MaxNumber = 0;
                foreach (string strNumber in arrNumbers)
                {
                    if (strNumber.Length > 0)
                    {
                        if (Convert.ToDouble(strNumber) > MaxNumber)
                        {
                            MaxNumber = Convert.ToDouble(strNumber);
                        }
                    }
                }
                return MaxNumber;
            }
     
            protected double GetMinNumber(string[] arrNumbers)
            {
                double MinNumber = 1000000000;
                foreach (string strNumber in arrNumbers)
                {
                    if (strNumber.Length > 0)
                    {
                        if (Convert.ToDouble(strNumber) < MinNumber)
                        {
                            MinNumber = Convert.ToDouble(strNumber);
                        }
                    }
                }
                return MinNumber;
            }
        }
    }

    This produces the graph in the image file attached.

  6. Ianko
    Admin
    Ianko avatar
    1535 posts

    Posted 27 Apr Link to this post

    Hi Travis,

    The encountered result is due to the used formatting. The used one ({0:D}) rounds the value. Thus, 102.5 will become 103. This is applied only to the labels, thus, plot area is accurately rendered. It is the X and Y labels that mislead that points are not rendered at the proper position. 

    I suggest you using proper formatting that does not round values. You can see this article on the matter—http://docs.telerik.com/kendo-ui/framework/globalization/numberformatting. On my end using this formatting works properly: DataFormatString="{0:n1}".

    Regards,
    Ianko
    Telerik
    Do you need help with upgrading your ASP.NET AJAX, WPF or WinForms projects? Check the Telerik API Analyzer and share your thoughts.
Back to Top
UI for ASP.NET Ajax is Ready for VS 2017