Why is my reversed MagnitudeAxis Polar Plot not rendering with Oxyplot? - c#

I'm trying to create a Polar Plot with Oxyplot in my WPF application. I want the MagnitudeAxis to be reversed so I made the StartPosition = 1 and the EndPosition = 0. However this causes the plot not to render. It looks it may be due to the variables a0 and a1 being set to 0 in the UpdateTransform() method in MagnitudeAxis.cs but it may be something else (not exactly sure what all these variables represent).
Here's my code to set up the polar plot:
/// dictionary of angles: magnitudes
dict = {-180: -18, -179: -17.9, ... , 0: 0, ... , 178: -17.8, 179: -17.9}
PlotModel myPlot = new PlotModel
{
Title = "Polar Plot",
PlotType = PlotType.Polar,
PlotAreaBorderThickness = new OxyThickness(0),
};
var series1 = new ScatterSeries
{
Title = "Polar Series",
MarkerType = MarkerType.Circle,
MarkerSize = 3,
MarkerFill = OxyColor.FromRgb(255, 0, 0),
};
var axis1 = new AngleAxis
{
StartPosition = 1,
EndPosition = 0,
StartAngle = 270,
EndAngle = -90,
Title = "Angle",
LabelFormatter = d => $"{d}",
MajorStep = 30,
Minimum = -180,
Maximum = 180,
MinorGridlineStyle = LineStyle.None,
};
var axis2 = new MagnitudeAxis
{
/// here's where I set the Start and End Position
StartPosition = 1,
EndPosition = 0,
MajorStep = 6,
Title = "Magnitude",
MinorGridlineStyle = LineStyle.None,
Minimum = dict.Values.Min();
Maximum = dict.Values.Max()
};
foreach (KeyValuePair<double, double> keyValuePair in dict)
{
series1.Points.Add(new ScatterPoint(keyValuePair.Value, keyValuePair.Key));
}
myPlot.Axes.Add(axis1);
myPlot.Axes.Add(axis2);
myPlot.Series.Add(series1);
This is what I get when the plot tries rendering:
This is what I get when I use default Start/End Positions:
What I want is the default plot with 0 in the center and -18 on the edge instead.
This is my first question ever on SO, so let me know if there's any other information I should provide.

Related

Oxyplot Polar Diagram with Categories

I'd like to create a polar diagram with oxyplot. The circular axis should not consist of integers, but of categories.
Meaning instead of 1 ... 10 it should say Category A Category B ... around the plot.
Neither MagnitudeAxis nor AngularAxis provide the possibility to set "strings" for the axis.
CategoryAxis however cannot be used to plot a polar diagram, because it does not support angles.
My code so far:
var plotModel = new PlotModel { Title = "", };
plotModel.PlotType = OxyPlot.PlotType.Polar;
plotModel.Axes.Add(new OxyPlot.Axes.AngleAxis()
{
MajorGridlineStyle = LineStyle.Solid,
//MinorGridlineStyle = LineStyle.Dot,
MajorStep = 1,
CropGridlines = false,
StartAngle = 450,
EndAngle = 90,
Minimum = 0,
Maximum = 19
});
plotModel.Axes.Add(new OxyPlot.Axes.MagnitudeAxis()
{
MajorGridlineStyle = LineStyle.Solid,
Minimum = 0,
Maximum = 5,
MajorStep = 1,
MinorStep = 1
});
var newValues = new OxyPlot.Series.LineSeries { Title = "New Values", StrokeThickness = 1 };
int i = 0;
foreach(var dataRow in details)
{
newValues.Points.Add(new DataPoint(dataRow.NewValue, i++)); //instead of i++ I would like to put a string of the object dataRow, but this is not supported...
}
In lack of examples and documentation online, this is my last hope to find some help...
It looks to me like the LabelFormatter property is what you need. The code below creates labels 'Category A', 'Category B'...'Category S' around the outside of the plot. It does this because (char)65 is 'A', (char)66 is 'B' etc.
plotModel.Axes.Add(new OxyPlot.Axes.AngleAxis()
{
MajorGridlineStyle = LineStyle.Solid,
MajorStep = 1,
CropGridlines = false,
StartAngle = 450,
EndAngle = 90,
Minimum = 0,
Maximum = 19,
LabelFormatter = d => $"Category {(char)(d+65)}"
});
Based on the answer of Rich N I was able to find a (nasty) workaround by myself:
plotModel.Axes.Add(new OxyPlot.Axes.AngleAxis()
{
MajorGridlineStyle = LineStyle.Solid,
//MinorGridlineStyle = LineStyle.Dot,
MajorStep = 1,
CropGridlines = false,
StartAngle = 450,
EndAngle = 90,
Minimum = 0,
Maximum = 19,
LabelFormatter = d => myCategoryList[Convert.ToInt32(d)] //myCategoryList is a list of strings
});

c# windows application Live Charts x axis date forma

Hello everyone i working in project that convert data (date and value) to graphic curve .
i have problem with x axis the value of date printing in double format , i want this values showing like this format 14:12:35
var gradientBrush = new LinearGradientBrush
{
StartPoint = new System.Windows.Point(0, 0),
EndPoint = new System.Windows.Point(0, 1)
};
gradientBrush.GradientStops.Add(new GradientStop(System.Windows.Media.Color.FromRgb(33, 148, 241), 0.2));
gradientBrush.GradientStops.Add(new GradientStop(Colors.Transparent, 1));
cartesianChart1.Series.Add(new LineSeries
{
Values = GetData(),
Fill = gradientBrush,
StrokeThickness = 0.9,
PointGeometry = null
});
cartesianChart1.Zoom = ZoomingOptions.X;
private ChartValues<DateTimePoint> GetData()
{
var values = new ChartValues<DateTimePoint>();
for (var i = 0; i <lsTemp.Count(); i++)
{
// System.DateTime.Today.AddDays(i)
values.Add(new DateTimePoint(lsDataTime[i], lsTemp[i]));
}
return values;
}
enter image description here
you need to set LabelFormatter property of Axis class.
Something like this:
AxisX = new Axis
{
Title = "Date",
Separator = new Separator { IsEnabled = false,Step = 1 },
LabelsRotation = -90,
Foreground = new SolidColorBrush(Colors.Black),
LabelFormatter = value => new System.DateTime((long)value).ToString("t")
};
And look at this link for formats ToString data formats

How Do I Get The Scale of The Secondary Axis to be Based on My Series Values?

I'm using System.Web.UI.DataVisualization. Charting to create charts in MVC.
I have a chart displaying values in a StackedColumn100 SeriesChartType with the corresponding y-axis values on the primary y-axis on the left side.
Since it is a 100% stacked column series, the primary y-axis is scaled from 0 to 100.
I have then added a secondary series in the form of a Line SeriesChartType tied to a secondary axis (on the right side). I would like this axis to adjust its scale based on the values in the series but it doesn't. No matter what the highest value of this series is, the secondary y-axis also has a scale between 0 to 100.
If I manually set the maximum value for the secondary y-axis the following way:
chart.ChartAreas[0].AxisY2.Maximum = 20;. It works but I don't want to do that since the maximum value can differ greatly based on the search criteria used.
I have really tried to find a solution for this but I can't. According to the documentation and samples it seems that the scale should be based on the series values but I don't get it to work that way. Any help would be greatly appreciated!
Below is a stand alone test function that recreates the problem. I call the function from my view with the following line:
<p><img src="#Url.Action("CreateChart_TestSecondaryAxis")" /> </p>
public FileResult CreateChart_TestSecondaryAxis()
{
System.Web.UI.DataVisualization.Charting.Chart chart = new System.Web.UI.DataVisualization.Charting.Chart();
chart.Width = 800;
chart.Height = 400;
chart.BackColor = Color.FromArgb(211, 223, 240);
chart.BorderlineDashStyle = ChartDashStyle.Solid;
chart.BackSecondaryColor = Color.White;
chart.BackGradientStyle = GradientStyle.TopBottom;
chart.BorderlineWidth = 1;
chart.Palette = ChartColorPalette.BrightPastel;
chart.BorderlineColor = Color.FromArgb(26, 59, 105);
chart.RenderType = RenderType.BinaryStreaming;
chart.BorderSkin.SkinStyle = BorderSkinStyle.Emboss;
chart.AntiAliasing = AntiAliasingStyles.All;
chart.TextAntiAliasingQuality = TextAntiAliasingQuality.Normal;
ChartArea chartArea = new ChartArea();
chartArea.Name = "TestSecondaryAxis";
chartArea.BackColor = Color.Transparent;
chartArea.AxisX.IsLabelAutoFit = false;
chartArea.AxisY.IsLabelAutoFit = false;
chartArea.AxisX.LabelStyle.Font =
new Font("Verdana,Arial,Helvetica,sans-serif",
8F, FontStyle.Regular);
chartArea.AxisY.LabelStyle.Font =
new Font("Verdana,Arial,Helvetica,sans-serif",
8F, FontStyle.Regular);
chartArea.AxisY.LineColor = Color.FromArgb(64, 64, 64, 64);
chartArea.AxisX.LineColor = Color.FromArgb(64, 64, 64, 64);
chartArea.AxisY.MajorGrid.LineColor = Color.FromArgb(64, 64, 64, 64);
chartArea.AxisX.MajorGrid.LineColor = Color.FromArgb(64, 64, 64, 64);
chartArea.AxisX.Title = "Airport";
chartArea.AxisY.Title = "LandingConf";
chartArea.AxisY.TextOrientation = TextOrientation.Rotated270;
chartArea.AxisX.LabelStyle.IsEndLabelVisible = true;
chart.ChartAreas.Add(chartArea);
Series seriesPrimaryAxisConf3 = new Series();
seriesPrimaryAxisConf3.Name = "Conf 3";
seriesPrimaryAxisConf3.IsValueShownAsLabel = false;
seriesPrimaryAxisConf3.Color = Color.Blue;
seriesPrimaryAxisConf3.ChartType = SeriesChartType.StackedColumn100;
seriesPrimaryAxisConf3.BorderWidth = 2;
seriesPrimaryAxisConf3.ChartArea = "TestSecondaryAxis";
DataPoint point;
for (int i = 1; i < 11; i++)
{
point = new DataPoint();
point.AxisLabel = "Airport" + i.ToString();
point.YValues = new double[] { i };
seriesPrimaryAxisConf3.Points.Add(point);
}
chart.Series.Add(seriesPrimaryAxisConf3);
Series seriesPrimaryAxisConfFull = new Series();
seriesPrimaryAxisConfFull.Name = "Conf Full";
seriesPrimaryAxisConfFull.IsValueShownAsLabel = false;
seriesPrimaryAxisConfFull.Color = Color.Red;
seriesPrimaryAxisConfFull.ChartType = SeriesChartType.StackedColumn100;
seriesPrimaryAxisConfFull.BorderWidth = 2;
seriesPrimaryAxisConfFull.ChartArea = "TestSecondaryAxis";
for (int i = 1; i < 11; i++)
{
point = new DataPoint();
point.AxisLabel = "Airport" + i.ToString();
point.YValues = new double[] { 11-i };
seriesPrimaryAxisConfFull.Points.Add(point);
}
chart.Series.Add(seriesPrimaryAxisConfFull);
Series seriesSecondaryAxisNoOfFlights = new Series();
seriesSecondaryAxisNoOfFlights.Name = "NoOfFLights";
seriesSecondaryAxisNoOfFlights.IsValueShownAsLabel = false;
seriesSecondaryAxisNoOfFlights.Color = Color.Red;
seriesSecondaryAxisNoOfFlights.ChartType = SeriesChartType.Line;
seriesSecondaryAxisNoOfFlights.BorderWidth = 2;
seriesSecondaryAxisNoOfFlights.ChartArea = "TestSecondaryAxis";
for (int i = 1; i < 11; i++)
{
point = new DataPoint();
point.AxisLabel = "Airport" + i.ToString();
point.YValues = new double[] { i };
seriesSecondaryAxisNoOfFlights.Points.Add(point);
}
chart.Series.Add(seriesSecondaryAxisNoOfFlights);
chart.Series["NoOfFLights"].YAxisType = AxisType.Secondary;
chart.ChartAreas["TestSecondaryAxis"].AxisY2.LineColor = Color.Transparent;
chart.ChartAreas["TestSecondaryAxis"].AxisY2.MajorGrid.Enabled = false;
chart.ChartAreas["TestSecondaryAxis"].AxisY2.MajorTickMark.Enabled = false;
MemoryStream ms = new MemoryStream();
chart.SaveImage(ms);
return File(ms.GetBuffer(), #"image/png");
}
MSChart is a nice control but unfortunately Microsoft has always failed to properly document it.
And with the latest changes at MSDN things have gone from bad to worse, so I can't actually point to the rules that go for the various ChartTypes.
In your case I deduct this (rather wacky) rule:
To attach a non 100%-series to an indepently scaled secondary y-axis
it must be the first series but the stacked series still must be added
first.
So, if you want to get a result like this:
..you need to adapt the code. Here are the changes and additions needed..:
First we have to insert the line series at the front but do that after the stack100 series have beeen added..:
chart.Series.Insert(0, seriesSecondaryAxisNoOfFlights); // instead of adding it
Next we need to owner-draw the line as it would get burried under the columns otherwise.
Code the PostPaint event like this:
private void Chart_PostPaint(object sender, ChartPaintEventArgs e)
{
Chart chart = sender as Chart; //*
Series s = chart.Series[0]; // make sure to pick the right one!
Axis ax = chart.ChartAreas[0].AxisX;
Axis ay = chart.ChartAreas[0].AxisY2; // !!
var pts = s.Points.Select(x =>
new PointF((float)ax.ValueToPixelPosition(x.XValue),
(float)ay.ValueToPixelPosition(x.YValues[0])));
using (Pen pen = new Pen(s.Color, s.BorderWidth))
e.ChartGraphics.Graphics.DrawLines(pen, pts.ToArray());
}
For this to work the series need valid x-values. So add this line:
point.XValue = i; // set both x and y-values!
I also added a few nudges to the axis positioning:
ChartArea ca = chart.ChartAreas["TestSecondaryAxis"];
ca.AxisY.Maximum = 100;
ca.AxisX.Minimum = 0.5;
ca.AxisX.IntervalOffset = 0.5;

ZedGraph How To Create a Classic Line Chart With XAxis.Type = AxisType.Text

I'm trying to create a Line Graph with zed graph. I just wanted to ask that how can I create a Line Graph which XAxis type is text and YAxis type is doubles.
Firstly i was really searching about this topic but i didnt get any result about it. Because other Line graphs are always about date&time on XAxis. I don't need date&time on XAxis. I will use labels for XAxis to name points on YAxis .
Here an Example Graph
string[] labels = { "P(A)", "P(A)+P(T)", "P(A)+P(T)+P(G)", "P(A)+P(T)+P(G)+P(C)" };
double[] y = { PA(), PA() + PT(), PA() + PT() + PG(), PA() + PT() + PG() + PC() };
LineItem myLine = myPane.AddCurve("dizi 1", null, y, Color.Red);
myLine.Line.Fill = new Fill(Color.Red, Color.White, Color.Red);
myPane.XAxis.Scale.TextLabels = labels;
myPane.XAxis.Type = AxisType.Text;
myPane.Chart.Fill = new Fill(Color.White, Color.FromArgb(255, 255, 166), 90F);
myPane.Fill = new Fill(Color.FromArgb(250, 250, 255));
zedGraphControl1.AxisChange();
****Codes are above . Is there anything wrong ?****
I just figured it out!
Here is example codes to create a basic line graph!
private void button3_Click(object sender, EventArgs e)
{
// generate some fake data
double[] y = { 1, 2, 3, 9 ,1,15,3,7,2};
string[] schools = { "A", "B", "C", "D" ,"E","F","G","H","J"};
//generate pane
var pane = zg1.GraphPane;
pane.XAxis.Scale.IsVisible = true;
pane.YAxis.Scale.IsVisible = true;
pane.XAxis.MajorGrid.IsVisible = true;
pane.YAxis.MajorGrid.IsVisible = true;
pane.XAxis.Scale.TextLabels = schools;
pane.XAxis.Type = AxisType.Text;
//var pointsCurve;
LineItem pointsCurve = pane.AddCurve("", null, y, Color.Black);
pointsCurve.Line.IsVisible = true;
pointsCurve.Line.Width = 3.0F;
//Create your own scale of colors.
pointsCurve.Symbol.Fill = new Fill(new Color[] { Color.Blue, Color.Green, Color.Red });
pointsCurve.Symbol.Fill.Type = FillType.Solid;
pointsCurve.Symbol.Type = SymbolType.Circle;
pointsCurve.Symbol.Border.IsVisible = true;
pane.AxisChange();
zg1.Refresh();
this.Controls.Add(zg1);
}

How to change OxyPlot Y-Axis string format?

Can anyone tell me how to change the Y axis string format??
I have Y-Axis percentages that I want to add the percent sign to.
I am using OxyPlot to produce the chart in wpf.
Here is my attempt, but it is NOT working:
Func<double, string> formatFunc = (x) => string.Format("{000.00}%", x);
formatFunc = new Func<double,string>("{0}");
// Add the plot to the window
line.YAxis.LabelFormatter = formatFunc;
This produces null reference error.
Thanks!
This is an example I've used previously to format the x-axis on an oxy-plot:
var xAxis = new DateTimeAxis
{
Position = AxisPosition.Bottom,
StringFormat = "dd/MM/yyyy",
Title = "End of Day",
IntervalLength = 75,
MinorIntervalType = DateTimeIntervalType.Days,
IntervalType = DateTimeIntervalType.Days,
MajorGridlineStyle = LineStyle.Solid,
MinorGridlineStyle = LineStyle.None,
};
Plot = new PlotModel();
Plot.Axes.Add(xAxis);
this._PlotModel.Axes.Add( new LinearAxis
{
Position = AxisPosition.Left,
Minimum = 0.025,
Maximum = 0.205,
StringFormat = "0.00%",
MajorStep = 0.005
} );
- add percents as ratio: 20.5% --> 0.205, 0.5% --> 0.005, etc.

Categories

Resources