Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
295
Displaying Polynomial Fit in UltraChart using Scatter and Spline layers
posted

I am trying to create a Composite Chart that has a Polynomial Fit using a Scatter layer and using Scatter layer for the points.
The problem is,the curve becomes really jagged. I have tried using separate X and Y axis and used SplineChart for one layer and ScatterChart for another layer but when I did the chart wouldn't display the points of the Scatter layer at the correct X,Y coordinates. Is there a better way to plot the Polynomial and display the Points in a Scatter layer? Also the user can also set the degree and interval that is used to calculate the Polynomial curve after the Chart has been displayed. This has caused issues with the chart not displaying the points correctly. All the series are bound to datatables or a binding list.

int topMargin = 5;
int leftMargin = 5;
int chartWidth = 90;
int chartHeight = 100;

var labelHash = new Hashtable();
labelHash.Add("TOOLTIPS", new CostToolTipRenderer(graphTable));
labelHash.Add("X_AXIS", new XAxisLabelRenderer(trendTable));
base.LabelHash = labelHash;
base.Tooltips.FormatString = "<TOOLTIPS>";
base.DataSource = graphTable;
base.DataBind();

this.ChartType = ChartType.Composite;
this.CompositeChart.ChartAreas.Clear();
this.Series.Clear();
this.CompositeChart.Legends.Clear();
this.CompositeChart.ChartLayers.Clear();
ChartArea chartArea = new ChartArea();
chartArea.Border.Thickness = 0;
chartArea.BoundsMeasureType = MeasureType.Percentage;

chartArea.Bounds = new Rectangle(leftMargin, topMargin, chartWidth, chartHeight);
this.CompositeChart.ChartAreas.Add(chartArea);

// Create X axis
AxisItem axisX = new AxisItem();
axisX.DataType = AxisDataType.Numeric;
axisX.Labels.ItemFormatString = "<DATA_VALUE:###,###,###>";
//axisX.Labels.ItemFormatString = "<X_AXIS> ";
axisX.SetLabelAxisType = SetLabelAxisType.ContinuousData;
axisX.OrientationType = AxisNumber.X_Axis;
axisX.Labels.Layout.Behavior = AxisLabelLayoutBehaviors.Auto;
axisX.Labels.Orientation = TextOrientation.Custom;
axisX.Labels.VerticalAlign = StringAlignment.Far;
axisX.Labels.HorizontalAlign = StringAlignment.Near;
axisX.Labels.OrientationAngle = 45;

// Set the interval for the X axis
axisX.RangeType = AxisRangeType.Custom;
var trendMax = trendTable.AsEnumerable().Max(x => x.Field<double>("X"));
var chartMax = PlanInfoList.Max(x => x.ExcessCapacity);
var max= chartMax > trendMax ? chartMax : trendMax;
axisX.RangeMin = 0;
axisX.RangeMax = max + max * .05;
axisX.TickmarkInterval = Interval;
axisX.TickmarkStyle = AxisTickStyle.DataInterval;
axisX.Extent = 150;
chartArea.Axes.Add(axisX);

// Create Y axis
AxisItem axisY = new AxisItem();
axisY.DataType = AxisDataType.Numeric;
axisY.Labels.ItemFormatString = "<DATA_VALUE:    $###,###,###>";
axisY.Labels.HorizontalAlign = StringAlignment.Far;
axisY.SetLabelAxisType = SetLabelAxisType.ContinuousData;
axisY.OrientationType = AxisNumber.Y_Axis;

// Set the custom interval for the Y axis
axisY.RangeType = AxisRangeType.Custom;
trendMax = trendTable.AsEnumerable().Max(x => x.Field<double>("Y"));
var trendMin = trendTable.AsEnumerable().Min(x => x.Field<double>("Y"));
chartMax= PlanInfoList.Max(x => x.TotalCost);
var chartMin= PlanInfoList.Min(x => x.TotalCost);

axisY.RangeMin = chartMin < trendMin ? chartMin : trendMin;
axisY.RangeMax = chartMax>trendMax?chartMax:trendMax;
axisY.Labels.Font = new Font("Ariel", 10f);
axisY.Extent = 50;
chartArea.Axes.Add(axisY);


// Create a Trend Line(Polynomial) series
XYSeries trendSeries = new XYSeries();
trendSeries.Label = "Trend Analysis";
trendSeries.PEs.Add(new PaintElement(Color.LimeGreen));

// Create a Cost series
XYSeries costSeries = new XYSeries();
costSeries.Label = "Total Cost";
costSeries.PEs.Add(new PaintElement(Color.Red));

// Add DataSource and x,y columns to trend XYSeries
trendSeries.Data.DataSource = trendTable;
trendSeries.Data.ValueXColumn = "X";
trendSeries.Data.ValueYColumn = "Y";

costSeries.Data.DataSource = graphTable;
costSeries.Data.ValueXColumn = "ExcessCapacity";
costSeries.Data.ValueYColumn = "TotalCost";


// Add a Trend ChartLayerAppearance
var trendLayer = new ChartLayerAppearance();
trendLayer.ChartType = ChartType.ScatterChart;
trendLayer.ChartArea = chartArea;
trendLayer.AxisX = axisX;
trendLayer.AxisY = axisY;
trendLayer.Series.Add(trendSeries);

// Add a LineAppearance to draw the polynomial fit
var sceTrend = new ScatterChartAppearance();
sceTrend.ConnectWithLines = true;
sceTrend.Icon = SymbolIcon.None;
sceTrend.LineAppearance.Thickness = 5;
sceTrend.LineAppearance.DrawStyle = LineDrawStyle.Dash;
trendLayer.ChartTypeAppearance = sceTrend;

// Add a Cost ChartLayerAppearance
var costLayer = new ChartLayerAppearance();
costLayer.ChartType = ChartType.ScatterChart;
costLayer.ChartArea = chartArea;
costLayer.AxisX = axisX;
costLayer.AxisY = axisY;
costLayer.Series.Add(costSeries);

// Add a Cost ScartChartAppearance
var scaCost = new ScatterChartAppearance();
scaCost.ConnectWithLines = false;
scaCost.Icon = SymbolIcon.Circle;
scaCost.LineAppearance.Thickness = 5;
scaCost.LineAppearance.DrawStyle = LineDrawStyle.Dash;
costLayer.ChartTypeAppearance = scaCost;

// Add trend XYSereies
this.Series.Add(trendSeries);
// Add cost XYSeries
this.Series.Add(costSeries);

// Add trend Chart layer to chart
this.CompositeChart.ChartLayers.Add(trendLayer);
// Add cost Chart layer to chart
this.CompositeChart.ChartLayers.Add(costLayer);

this.TitleLeft.Text = "Total Cost";
this.TitleLeft.Visible = true;
this.TitleLeft.Extent = 50;
this.TitleLeft.HorizontalAlign = StringAlignment.Center;
this.TitleLeft.Font = new Font("Ariel", 12F);
this.TitleLeft.FontColor = Color.DarkBlue;


this.TitleBottom.Text = "Excess Capacity";
this.TitleBottom.Visible = true;
this.TitleBottom.HorizontalAlign = StringAlignment.Center;
this.TitleBottom.Extent = 50;
this.TitleBottom.Font = new Font("Ariel", 12F);
this.TitleBottom.FontColor = Color.DarkBlue;


this.TitleTop.Text = "Trend Analysis Report";
this.TitleTop.Visible = true;
this.TitleTop.HorizontalAlign = StringAlignment.Center;
this.TitleTop.Font = new Font("Ariel", 14F,FontStyle.Bold);
this.TitleTop.FontColor = Color.DarkBlue;

// Create Composite legend located at bottom left hand corner of the chart
var legend = new CompositeLegend();
legend.ChartLayers.Add(trendLayer);
legend.ChartLayers.Add(costLayer);
legend.Bounds = new Rectangle(2, 90, 5, 7);
legend.BoundsMeasureType = MeasureType.Percentage;
legend.PE.ElementType = PaintElementType.Gradient;
legend.PE.FillGradientStyle = GradientStyle.ForwardDiagonal;
legend.PE.Fill = Color.CornflowerBlue;
legend.PE.FillStopColor = Color.Transparent;
legend.Border.CornerRadius = 10;
legend.Border.Thickness = 1;
this.CompositeChart.Legends.Add(legend);