When reducing charts the candle begins to overlap another candle.
For example
Axises
DateTimeAxis timeSPanAxis1 = new DateTimeAxis()
{
Position = AxisPosition.Bottom,
MinorIntervalType = DateTimeIntervalType.Auto,
MajorGridlineStyle = LineStyle.Dot,
MinorGridlineStyle = LineStyle.Dot,
MajorGridlineColor = OxyColor.FromRgb(44, 44, 44),
TicklineColor = OxyColor.FromRgb(82, 82, 82)
};
PlotModel.Axes.Add(timeSPanAxis1);
LinearAxis linearAxis1 = new LinearAxis()
{
Position = AxisPosition.Right,
MajorGridlineStyle = LineStyle.Dot,
MinorGridlineStyle = LineStyle.Dot,
MajorGridlineColor = OxyColor.FromRgb(44, 44, 44),
TicklineColor = OxyColor.FromRgb(82, 82, 82)
};
PlotModel.Axes.Add(linearAxis1);
and candle stick series
CandleStickSeries candle = new CandleStickSeries()
{
Color = OxyColors.Black,
IncreasingColor = OxyColor.FromRgb(0,197,49),
DecreasingColor = OxyColor.FromRgb(255,95,95),
DataFieldX = "Time",
DataFieldHigh = "H",
DataFieldLow = "L",
DataFieldClose = "C",
DataFieldOpen = "O",
TrackerFormatString = "Date: {2}\nOpen: {5:0.00000}\nHigh: {3:0.00000}\nLow: {4:0.00000}\nClose: {6:0.00000}",
};
Why is this happening? How to fix it?
I just fixed the issue concerning the doji candles.
The pull request can be found on
GitHub.
Related
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.
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
});
I'm using SVGNet to draw SVG images and save them in both .svg and .png formats. However, when I add text and rotate it, the .png file shows the image correctly but the .svg file doesn't.
I'm exploring SvgNet, hardcoding the kind of drawings I'll have to dynamically produce.
However, I can't seem to solve this problem. I've tried different rotations and adding translations, but to no avail.
If I don't add any transformations it doesn't even add the spacing, the text elements show up on top of each other.
Here's all the code, except the saving to .svg and .png.
SvgDocument x = new SvgDocument();
x.Width = 2500;
x.Height = 2500;
List<string> exemplosParagem = new List<string>
{
"Paragem 1",
"Paragem 2",
"Paragem 3",
"Paragem 4",
"Paragem 5",
"Paragem 6",
"Paragem 7",
"Paragem 8",
"Paragem 9",
"Paragem 10",
"O Que Acontece",
"Se o Texto for de",
"Tamanhos",
"Diferentes"
};
SvgUnitCollection textPositionX = new SvgUnitCollection
{
1250
};
SvgUnitCollection textPositionY = new SvgUnitCollection
{
100
};
SvgGroup title = new SvgGroup();
title.Children.Add(new SvgText
{
Text = "Teste Espinha SVG Library",
FontSize = 80,
Fill = new SvgColourServer(Color.Blue),
Stroke = new SvgColourServer(Color.Black),
StrokeWidth = 3,
TextAnchor = SvgTextAnchor.Middle,
X = textPositionX,
Y = textPositionY
});
SvgGroup spineLine = new SvgGroup();
spineLine.Children.Add(new SvgLine
{
StrokeWidth = 10,
Stroke = new SvgColourServer(Color.Black),
StartX = 100,
StartY = 600,
EndX = 2300,
EndY = 600,
});
SvgGroup rect = new SvgGroup();
rect.Children.Add(new SvgRectangle
{
Fill = new SvgColourServer(Color.LightBlue),
Stroke = new SvgColourServer(Color.Black),
StrokeWidth = 2,
Width = x.Width - 50,
Height = x.Height - spineLine.Bounds.Bottom - 100,
X = 25,
Y = spineLine.Bounds.Bottom + 100,
});
SvgUnitCollection paragensPositionX = new SvgUnitCollection
{
spineLine.Bounds.X
};
SvgUnitCollection paragensPositionY = new SvgUnitCollection
{
spineLine.Bounds.Top
};
List<SvgText> svgText = new List<SvgText>();
for (int i = 0; i < exemplosParagem.Count; i++)
{
SvgText aux = new SvgText
{
Text = exemplosParagem[i],
Color = new SvgColourServer(Color.Black),
FontSize = 20,
X = paragensPositionX,
Y = paragensPositionY
};
SvgTransformCollection transCollect = new SvgTransformCollection();
SvgRotate rotation = new SvgRotate(-35, aux.Bounds.X, aux.Bounds.Y);
transCollect.Add(rotation);
aux.Transforms = transCollect;
paragensPositionX[0] += (spineLine.Bounds.Width / exemplosParagem.Count);
svgText.Add(aux);
}
foreach (var stop in svgText)
{
spineLine.Children.Add(stop);
}
x.Children.Add(title);
x.Children.Add(spineLine);
x.Children.Add(rect);
var bitmap = x.Draw();
The following are the images generated by this code in .png and .svg respectively. The PNG image is the correct one.
Turns out I had to create paragensPositionX inside the loop.
SvgUnitCollection paragensPositionX = new SvgUnitCollection();
if (i == 0)
{
paragensPositionX.Add(spineLine.Bounds.X);
}
else
{
paragensPositionX.Add(auxSpacing + spacing);
}
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);
}
I am trying to reproduce a radar chart in ASP.NET MVC.
This is what I should have
This is what I actually have
So far, it works, the odd colors are just for development.
But the label rotation of the bottom 3 labels is quite bad, and I can't seem to find out how to rotate them properly. Anyone ?
Also, why is it setting markers in a 20 interval step, when I set 25 ?
And addtionally, just for fun, is it possible to rotate the y-axis thick markers by 22.5 degrees, as in the sample ?
Here my code:
using System.Drawing;
using System.Web.UI.DataVisualization.Charting;
// http://stackoverflow.com/questions/6047961/c-sharp-chart-rotate-labels
public FileResult RadarSample()
{
int pixelWidth = 1000;
int pixelHeight = 1000;
// Populate series data
//string[] xValues = { "France", "Canada", "Germany", "USA", "Italy", "Spain", "Russia", "Sweden", "Japan" };
string[] xValues = { "Offene Aussenpolitik", "Liberale Wirtschaftspolitik", "Restriktive Finanzpolitik", "Law & Order", "Restriktive Migrationspolitik", "Ausgebauter Umweltschutz", "Ausgebauter Sozialstaat", "Liberale Gesellschaft" };
double[] yValues = { 80, 90, 45, 75, 37.5, 40, 28, 54 };
//double[] yValues = { 65.62, 75.54, 60.45, 34.73, 85.42, 55.9, 63.6, 55.1, 77.2 };
//double[] yValues2 = { 76.45, 23.78, 86.45, 30.76, 23.79, 35.67, 89.56, 67.45, 38.98 };
var Chart1 = new System.Web.UI.DataVisualization.Charting.Chart();
Chart1.BackColor = System.Drawing.Color.HotPink;
var area = new System.Web.UI.DataVisualization.Charting.ChartArea("ca1");
area.Area3DStyle.Enable3D = false;
area.AxisX.Interval = 1;
area.BackColor = System.Drawing.Color.Red;
//area.AxisY.Interval = 5;
area.AxisY.MajorTickMark.Enabled = false;
area.AxisY.MajorGrid.LineColor = Color.Gray;
area.AxisY.MajorGrid.Interval = 25;
area.AxisY.MinorTickMark.Enabled = false;
area.AxisY.MinorGrid.Interval = 5;
area.AxisY.MinorGrid.LineColor = Color.Yellow;
Chart1.ChartAreas.Add(area);
var series1 = new System.Web.UI.DataVisualization.Charting.Series();
var series2 = new System.Web.UI.DataVisualization.Charting.Series();
series1.Name = "Series1";
series2.Name = "Series2";
//series1.Color = System.Drawing.Color.Yellow;
series1.Color = System.Drawing.Color.FromArgb(100, 0, 0, 255);
//series1.SmartLabelStyle.Enabled = true;
//series1.LabelAngle = 90;
//Legend legend = new Legend();
////legend.Name = "mylegend";
//legend.Title = "Hello world";
//legend.BackColor = Color.Transparent;
//legend.BackColor = Color.Tomato;
//Chart1.Legends.Add(legend);
// series1.Legend = "mylegend";
series1.LegendText = "A";
series2.LegendText = "B";
// series1.Label = "kickme";
// series2.Label = "bar";
//series1.ChartArea = "ca1";
series1.ChartType = System.Web.UI.DataVisualization.Charting.SeriesChartType.Radar;
series2.ChartType = System.Web.UI.DataVisualization.Charting.SeriesChartType.Radar;
series1.ChartArea = "ca1";
series2.ChartArea = "ca1";
Chart1.Series.Add(series1);
//Chart1.Series.Add(series2);
Chart1.Series["Series1"].Points.DataBindXY(xValues, yValues);
//Chart1.Series["Series2"].Points.DataBindXY(xValues, yValues2);
string[] astrRadarStyleList = new string[] { "Area", "Line", "Marker" }; // Fill, Line, or point
string[] astrAreaDrawingStyleList = new string[] { "Circle", "Polygon" }; // Shape
string[] astrLabelStyleList = new string[] { "Circular", "Radial", "Horizontal" };
string strRadarStyle = astrRadarStyleList[0];
string strAreaDrawingStyle = astrAreaDrawingStyleList[0];
string strLabelStyle = astrLabelStyleList[0];
Chart1.Width = System.Web.UI.WebControls.Unit.Pixel(pixelWidth);
Chart1.Height = System.Web.UI.WebControls.Unit.Pixel(pixelHeight);
// Set radar chart style
Chart1.Series["Series1"]["RadarDrawingStyle"] = strRadarStyle; // RadarStyleList.SelectedItem.Text;
//Chart1.Series["Series2"]["RadarDrawingStyle"] = strRadarStyle; // RadarStyleList.SelectedItem.Text;
if (strRadarStyle == "Area")
{
Chart1.Series["Series1"].BorderColor = Color.FromArgb(100, 100, 100);
Chart1.Series["Series1"].BorderWidth = 1;
// Chart1.Series["Series2"].BorderColor = Color.FromArgb(100, 100, 100);
// Chart1.Series["Series2"].BorderWidth = 1;
}
else if (strRadarStyle == "Line")
{
Chart1.Series["Series1"].BorderColor = Color.Empty;
Chart1.Series["Series1"].BorderWidth = 2;
// Chart1.Series["Series2"].BorderColor = Color.Empty;
// Chart1.Series["Series2"].BorderWidth = 2;
}
else if (strRadarStyle == "Marker")
{
Chart1.Series["Series1"].BorderColor = Color.Empty;
// Chart1.Series["Series2"].BorderColor = Color.Empty;
}
// Set circular area drawing style
Chart1.Series["Series1"]["AreaDrawingStyle"] = strAreaDrawingStyle; // AreaDrawingStyleList.SelectedItem.Text;
//Chart1.Series["Series2"]["AreaDrawingStyle"] = strAreaDrawingStyle; // AreaDrawingStyleList.SelectedItem.Text;
// Set labels style
Chart1.Series["Series1"]["CircularLabelsStyle"] = strLabelStyle; // LabelStyleList.SelectedItem.Text;
//Chart1.Series["Series2"]["CircularLabelsStyle"] = strLabelStyle; //LabelStyleList.SelectedItem.Text;
return Chart2Image(Chart1);
}
public FileResult Chart2Image(System.Web.UI.DataVisualization.Charting.Chart chart)
{
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
chart.SaveImage(ms, System.Web.UI.DataVisualization.Charting.ChartImageFormat.Png);
ms.Seek(0, System.IO.SeekOrigin.Begin);
return File(ms.ToArray(), "image/png", "mychart.png");
} // End Using ms
}
Try this for text direction of labels:
Chart1.Series["Series1"]["CircularLabelsStyle"] = "Horizontal";