I have a chart that shows two distinct Y values for the same DateTime X values. I am graphing them using a Spline on the same chart area with primary and secondary Y axes. The graph seems to work correctly with the exception that the Y axis labels are swapped. The expected primary Y axes labels are on the secondary axis and vice-versa.
Also, it should be noted that the charts are never displayed on screen, they are saved as image files in the file system and in a database using the chart.SaveImage method.
Here is an image of the output of the chart:
Here is the code to generate the chart:
// create the chart
Chart chart = new Chart();
chart.Size = new Size(width, height);
chart.AntiAliasing = AntiAliasingStyles.All;
string datatype = data[0].DataType;
string datatype2 = data2[0].DataType;
SampleUnit unit = GetSampleUnit(data[0].Unit);
string u = "";
if (unit != null)
{
u = unit.ShortName;
}
SampleUnit unit2 = GetSampleUnit(data2[0].Unit);
string u2 = "";
if (unit2 != null)
{
u2 = unit2.ShortName;
}
var chartArea = new ChartArea();
chartArea.AxisX.LabelStyle.Format = "dd MMM\nHH:mm";
chartArea.AxisX.MajorGrid.LineColor = Color.LightGray;
chartArea.AxisY.MajorGrid.LineColor = Color.LightGray;
chartArea.AxisX.LabelStyle.Font = new Font("Calibri", 8);
chartArea.AxisY.LabelStyle.Font = new Font("Calibri", 8);
chartArea.AxisY2.LabelStyle.Font = new Font("Calibri", 8);
chartArea.AxisY2.Enabled = AxisEnabled.True;
chartArea.AxisY2.MajorGrid.Enabled = false;
if (string.IsNullOrEmpty(u))
{
chartArea.AxisY.Title = datatype;
}
else
{
chartArea.AxisY.Title = datatype + " (" + u + ")";
}
if (string.IsNullOrEmpty(u2))
{
chartArea.AxisY2.Title = datatype2;
}
else
{
chartArea.AxisY2.Title = datatype2 + " (" + u2 + ")";
}
chartArea.AxisY.TitleForeColor = Color.MediumBlue;
chartArea.AxisY2.TitleForeColor = Color.Red;
chart.ChartAreas.Add(chartArea);
var series = new Series();
series.Name = datatype;
series.ChartType = SeriesChartType.Spline;
series.XValueType = ChartValueType.DateTime;
series.YValueType = ChartValueType.Double;
series.YAxisType = AxisType.Primary;
series.Color = Color.MediumBlue;
chart.Series.Add(series);
var series2 = new Series();
series2.Name = datatype2;
series2.ChartType = SeriesChartType.Spline;
series2.XValueType = ChartValueType.DateTime;
series2.YValueType = ChartValueType.Double;
series.Color = Color.Red;
series.YAxisType = AxisType.Secondary;
chart.Series.Add(series2);
chart.Titles.Add(sensor.Name + " " + char.ToUpper(datatype[0]) + datatype.Substring(1) + " " + char.ToUpper(datatype2[0]) + datatype2.Substring(1));
// bind the datapoints
chart.Series[datatype].Points.DataBindXY(data, "Timestamp", data, "Value");
chart.Series[datatype2].Points.DataBindXY(data2, "Timestamp", data2, "Value");
// draw!
chart.Invalidate();
So, I have two questions:
Why are the axis labels reversed?
Cosmetic: Why is the axis title putting a bar "|" at the end instead of a closing parenthesis ")"? Is this just a visual artifact from saving the chart as an image?
You have a cut-n-paste typo
change
series.Color = Color.Red;
series.YAxisType = AxisType.Secondary;
to
series2.Color = Color.Red;
series2.YAxisType = AxisType.Secondary;
Related
I am trying to make a Windows Form that shows display data from data a table. Every thing is working fine until I start scrolling in the Form using the auto scroll property.
I don't know why that's happening. I hope someone can help me.
private void allShowsToolStripMenuItem_Click(object sender, EventArgs e)
{
try
{
// Load All the Shows from the database
DataTable dt = accesse.LoadAllShows();
// Create the allShows From
Form allShows = new Form();
// Create the Controls for the AllShows form.
PictureBox[] pic = new PictureBox[dt.Rows.Count];
Label[] showName = new Label[dt.Rows.Count], season = new Label[dt.Rows.Count], eps = new Label[dt.Rows.Count], typ = new Label[dt.Rows.Count];
TextBox[] txtShowName = new TextBox[dt.Rows.Count], txtSeason = new TextBox[dt.Rows.Count], txtEps = new TextBox[dt.Rows.Count], txtTyp = new TextBox[dt.Rows.Count];
// AllShows Form properties
allShows.BackColor = Color.White;
allShows.Font = new Font("Calibri", 14f, FontStyle.Regular);
allShows.ForeColor = Color.Black;
allShows.Size = new Size(1050, 700);
allShows.StartPosition = FormStartPosition.CenterScreen;
allShows.AutoScroll = true;
allShows.AutoScrollMargin = new Size(0, 18);
// Variables
int y = 325; // the distens bettwen the controls on the Y and X.
bool xTurn = false; // the axies turn.
int yTurnNum = 0; // the y turn number.
for (int i = 0; i < dt.Rows.Count; i++)
{
// PictureBox Poster Properties
pic[i] = new PictureBox();
pic[i].BorderStyle = BorderStyle.FixedSingle;
pic[i].Size = new Size(162, 288);
pic[i].SizeMode = PictureBoxSizeMode.StretchImage;
pic[i].Image = Image.FromFile(dt.Rows[i][4].ToString());
// Label showName Properties
showName[i] = new Label();
showName[i].Text = "Show Name: " + dt.Rows[i][0];
showName[i].AutoSize = true;
// Label Season Properties
season[i] = new Label();
season[i].Text = "Season: " + dt.Rows[i][1];
season[i].AutoSize = true;
// Label Eps Properties
eps[i] = new Label();
eps[i].Text = "Episodes: " + dt.Rows[i][2];
eps[i].AutoSize = true;
// Label Typ Properties
typ[i] = new Label();
typ[i].Text = "Typ: " + dt.Rows[i][3];
typ[i].AutoSize = true;
if (xTurn)
{
// Sitting the location of the controls on the X turn
pic[i].Location = new Point(515, pic[i - 1].Location.Y);
showName[i].Location = new Point(687, showName[i - 1].Location.Y);
season[i].Location = new Point(687, season[i - 1].Location.Y);
eps[i].Location = new Point(687, eps[i - 1].Location.Y);
typ[i].Location = new Point(687, typ[i - 1].Location.Y);
xTurn = false;
}
else
{
// Sitting the location of the controls on the Y turn
pic[i].Location = new Point(15, 15 + (yTurnNum * y));
showName[i].Location = new Point(187, 20 + (yTurnNum * y));
season[i].Location = new Point(187, 55 + (yTurnNum * y));
eps[i].Location = new Point(187, 90 + (yTurnNum * y));
typ[i].Location = new Point(187, 125 + (yTurnNum * y));
yTurnNum += 1;
xTurn = true;
}
allShows.Controls.Add(pic[i]);
allShows.Controls.Add(showName[i]);
allShows.Controls.Add(season[i]);
allShows.Controls.Add(eps[i]);
allShows.Controls.Add(typ[i]);
}
allShows.ShowDialog();
}
catch (Exception ex)
{
tools.ShowErrorMessageBox(ex.Message, "Error");
}
}
I hope this gif will help you to understand what is happening.
enter image description here
I am working with a RangeBar Chart in a c# form app. When I add the series to the chart they do no line up correctly. When I change the "DrawSideBySide=false" it works fine, but I need some of the series to be side by side.
Any help on this would be greatly appreciated.
My code is just a List of Series being populated and then those series being added to a chart.
I loop through this populating series and adding them to a series list.
Populating-
double yplot1 = (double)user.Projects[i].StartDate.ToOADate();
double yplot2 = (double)user.Projects[i].EndDate.ToOADate();
// Use a different series for each datapoint
Series seriesInstance = new Series();
//seriesInstance.Name = user.Name;
seriesInstance.Label = user.Projects[i].Name + " - " + (user.Projects[i].AllocationPercent * 100).ToString() + "%";
seriesInstance.AxisLabel = user.Name;
seriesInstance.ChartType = SeriesChartType.RangeBar;
// Have a start and end date so plotting 2 points on the y-axis
seriesInstance.YValuesPerPoint = 2;
//seriesInstance.CustomProperties = "DrawSideBySide=true";
//seriesInstance["PixelPointWidth"] = "200";
seriesInstance["MinPixelPointWidth"] = "150";
int xordinal = j;
seriesInstance.IsXValueIndexed = false;
seriesInstance.Points.AddXY(xordinal, yplot1, yplot2);
/*seriesInstance.Points[0].ToolTip = someTipText;
seriesInstance.Points[0].Color = resourceColor;
seriesInstance.Points[0].AxisLabel = xlabel;*/
seriesList.Add(seriesInstance);
Then I add all the series in the list to the chart
foreach (Series plotSeries in seriesList)
{
chart1.Series.Add(plotSeries);
}
// Force x-axis to show each task or resource
chart1.ChartAreas[0].AxisX.Interval = 1;
// Set y-axis to show each day of the month
chart1.ChartAreas[0].AxisY.Interval = 1;
ChartArea chartArea1 = chart1.ChartAreas[0];
chartArea1.AxisX.IsReversed = true;
// Set other y-axis properties
chartArea1.AxisX.ScrollBar.Enabled = true;
chartArea1.AxisX.IsLabelAutoFit = true;
chartArea1.AxisX.ScaleView.Size = 5;
chartArea1.AxisY.IsStartedFromZero = false;
chartArea1.AxisY.IsMarginVisible = false;
if ((lastDate - firstDate).TotalDays < 60)
{
chartArea1.AxisY.IntervalType = DateTimeIntervalType.Days;
}
else if (((lastDate - firstDate).TotalDays > 60) && ((lastDate - firstDate).TotalDays < 365))
{
chartArea1.AxisY.IntervalType = DateTimeIntervalType.Weeks;
}
else
{
chartArea1.AxisY.IntervalType = DateTimeIntervalType.Months;
}
// Set the y-axis labels
chart1.ChartAreas[0].AxisY.Minimum = firstDate.AddDays(-1).ToOADate();
chart1.ChartAreas[0].AxisY.Maximum = lastDate.AddDays(+1).ToOADate();
chart1.ChartAreas[0].AxisY.LabelStyle.Format = "ddd M/d";
// Force redraw of chart
chart1.Update();
I had a an web application in which i want to show some data in graph for which i used zedgraph dll but now i want to draw graph only by using system dll's not with zed graph
zed graph code is as follows
protected void ZedGraphWeb1_RenderGraph(ZedGraph.Web.ZedGraphWeb webObject, System.Drawing.Graphics g, ZedGraph.MasterPane masterPane)
{
// Get the GraphPane so we can work with it
GraphPane myPane = masterPane[0];
// Set the title and axis labels
myPane.XAxis.Title.Text = "Order Status";
myPane.YAxis.Title.Text = "No Of Orders";
myPane.XAxis.Type = AxisType.Text;
string[] labels = { "Pending", "Elapsed", "Dispatched", "Delivered" };
myPane.XAxis.Scale.TextLabels = labels;
//myPane.XAxis.Scale.TextLabels = arr1;
// Declare a BarItem:- Bar Item is used for creating a bar
BarItem myCurve;
BarItem myCurve2;
// Declare a LineItem:- LineItem is used for creating a line
PointPairList listEcoPack = new PointPairList();
PointPairList listProduct = new PointPairList();
double[] lstEcoPack = new double[4];
double[] lstProduct = new double[4];
OrderStatusoutput objOrderStatusoutput = new OrderStatusoutput();
OrderStatusinput objOrderStatusinput = new OrderStatusinput();
objOrderStatusinput.StartDate = Convert.ToDateTime(txtfromdatepacks.Text).ToShortDateString();
objOrderStatusinput.EndDate = Convert.ToDateTime(txttodatepacks.Text).ToShortDateString();
objOrderStatusoutput.dsorderstatusresult = objHrservice.OrderStatus(objOrderStatusinput).dsorderstatusresult;
objHrservice.Close();
DataSet dsoreder = objOrderStatusoutput.dsorderstatusresult;
double EcoPendingOrders = Convert.ToDouble(dsoreder.Tables[4].Rows[0]["PendingOrders"]);
double EcoElapsed = Convert.ToDouble(dsoreder.Tables[4].Rows[0]["Elapsed"]);
double EcoDispatchedOrders = Convert.ToDouble(dsoreder.Tables[4].Rows[0]["DispatchedOrders"]);
double EcoDeliveredOrders = Convert.ToDouble(dsoreder.Tables[4].Rows[0]["DeliveredOrders"]);
double ProPendingOrders = Convert.ToDouble(dsoreder.Tables[3].Rows[0]["PendingOrders"]);
double ProElapsed = Convert.ToDouble(dsoreder.Tables[3].Rows[0]["Elapsed"]);
double ProDispatchedOrders = Convert.ToDouble(dsoreder.Tables[3].Rows[0]["DispatchedOrders"]);
double ProDeliveredOrders = Convert.ToDouble(dsoreder.Tables[3].Rows[0]["DeliveredOrders"]);
lstEcoPack[0] = EcoPendingOrders;
lstEcoPack[1] = EcoElapsed;
lstEcoPack[2] = EcoDispatchedOrders;
lstEcoPack[3] = EcoDeliveredOrders;
lstProduct[0] = ProPendingOrders;
lstProduct[1] = ProElapsed;
lstProduct[2] = ProDispatchedOrders;
lstProduct[3] = ProDeliveredOrders;
}
try Microsoft's Chart Controls In An ASP.NET
https://web.archive.org/web/20211020203246/https://www.4guysfromrolla.com/articles/072209-1.aspx
GraphPane pane = zedGraphControl1.GraphPane;
pane.Title.Text = "Graph By Alax Technology";
pane.XAxis.Title.Text = "EMPLOYEE";
pane.YAxis.Title.Text = "SALARY";
PieItem Attendence = pane.AddPieSlice(Convert.ToDouble(textBox1.Text), System.Drawing.Color.Orange, 0f, "Attendence");
PieItem Grown = pane.AddPieSlice(Convert.ToDouble(textBox2.Text), System.Drawing.Color.White, 0f, "Grown Up");
PieItem Salary = pane.AddPieSlice(Convert.ToDouble(textBox3.Text), System.Drawing.Color.Green, 0f, "Salary Increase");
Attendence.LabelType = PieLabelType.Value;
Grown.LabelType = PieLabelType.Value;
Salary.LabelType = PieLabelType.Value;
zedGraphControl1.AxisChange();
zedGraphControl1.Invalidate();
zedGraphControl1.Refresh();
I have a function that I need to call every once in a while. But, every time I do, the graph (a pie chart) resizes itself and becomes smaller than the previously obtained piechart.
void LoadPieChart(DateTime lower, DateTime higher)
{
splitContainer1.Panel1.Controls.Remove(pieChart);
pieChart.Series.Clear();
pieChart.Palette = ChartColorPalette.Fire;
pieChart.BackColor = Color.Black;
pieChart.Titles.Add("LOST OPPORTUNITY");
pieChart.ChartAreas[0].BackColor = Color.Transparent;
Series series1 = new Series
{
Name = "series1",
IsVisibleInLegend = true,
Color = System.Drawing.Color.White,
ChartType = SeriesChartType.Pie
};
pieChart.Series.Add(series1);
int num = A.CountLO();
List<string>[] lista = new List<string>[7];
lista = A.SelectLO();
float counter_manpower = 0;
float counter_spares = 0;
float counter_tools = 0;
float counter_other = 0;
string[] reason = lista[6].ToArray();
string[] low = lista[4].ToArray();
string[] up = lista[5].ToArray();
string[] collection = new string[366];
for (int j = num-LO; j < num; j++)
{
DateTime x = DateTime.Parse(low[j]);
DateTime y = DateTime.Parse(up[j]);
if (x.Date>=lower.Date && y.Date<=higher.Date)
{
if (reason[j].Equals("LACK OF MANPOWER"))
counter_manpower++;
if (reason[j].Equals("LACK OF SPARES"))
counter_spares++;
if (reason[j].Equals("LACK OF TOOLS"))
counter_tools++;
if (!reason[j].Equals("LACK OF MANPOWER") && !reason[j].Equals("LACK OF SPARES") && !reason[j].Equals("LACK OF TOOLS"))
{
counter_other++;
}
}
}
float a = ((counter_manpower/(counter_manpower+counter_spares+counter_tools+counter_other))*100);
float b = ((counter_spares / (counter_manpower + counter_spares + counter_tools+counter_other)) * 100);
float c = ((counter_tools / (counter_manpower + counter_spares + counter_tools+counter_other)) * 100);
float d = ((counter_other / (counter_manpower + counter_spares + counter_tools + counter_other)) * 100);
double aa = Math.Truncate(100 * a) / 100;
double bb = Math.Truncate(100 * b) / 100;
double cc = Math.Truncate(100 * c) / 100;
double dd = Math.Truncate(100 * d) / 100;
series1.Points.Add(counter_manpower);
var p1 = series1.Points[0];
Math.Round(a, 1);
Math.Round(b, 1);
Math.Round(c, 1);
if (counter_manpower!=0)
p1.AxisLabel = (aa.ToString() + "%");
p1.LegendText = "LACK OF MANPOWER";
p1.Color = Color.Red;
series1.Points.Add(counter_spares);
p1 = series1.Points[1];
if (counter_spares!=0)
p1.AxisLabel = (bb.ToString() + "%");
p1.LegendText = "LACK OF SPARES";
p1.Color = Color.Yellow;
series1.Points.Add(counter_tools);
p1 = series1.Points[2];
if(counter_tools!=0)
p1.AxisLabel = (cc.ToString() + "%");
p1.LegendText = "LACK OF TOOLS";
p1.Color = Color.Orange;
series1.Points.Add(counter_other);
p1 = series1.Points[3];
p1.AxisLabel = (dd.ToString() + "%");
p1.LegendText = "OTHER";
p1.Color = Color.Maroon;
//pieChart.Invalidate();
splitContainer1.Panel1.Controls.Add(pieChart);
}
I can't seem to find out why, any suggestions?
I use the following function to initalize the graph:
private void InitializeChart()
{
this.components = new System.ComponentModel.Container();
ChartArea chartArea1 = new ChartArea();
Legend legend1 = new Legend() { BackColor = Color.White, ForeColor = Color.Black, Title = "CAUSE" };
pieChart = new Chart();
((ISupportInitialize)(pieChart)).BeginInit();
SuspendLayout();
//===Pie chart
chartArea1.Name = "PieChartArea";
pieChart.ChartAreas.Add(chartArea1);
pieChart.Dock = System.Windows.Forms.DockStyle.Fill;
legend1.Name = "Legend1";
pieChart.Legends.Add(legend1);
pieChart.Location = new System.Drawing.Point(0, 50);
//====Bar Chart
AutoScaleDimensions = new System.Drawing.Size(284,262);
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
//this.ClientSize = new System.Drawing.Size(284, 262);
this.Load += new EventHandler(Form1_Load);
((ISupportInitialize)(this.pieChart)).EndInit();
this.ResumeLayout(false);
}
I'm not sure where pieChart is defined... a private field?? If so, try creating a new PieChart after you have removed the previous one from the container:
splitContainer1.Panel1.Controls.Remove(pieChart);
pieChart = new PieChart();
pieChart.Series.Clear();
I'm guessing somewhere in your code you are accumulating a value instead of assigning it, so it is getting progressively smaller as you call the function on the same PieChart. Clearing out the pieChart should fix this problem.
I need to Export my Chart as an image without showing it first in WPF. So i built the Chart in Code:
public void CreateHistogram(CalcRepository cr, int i)
{
Chart chart = new Chart();
chart.Width = 300;
chart.Height = 200;
chart.ScrollingEnabled = false;
chart.AnimationEnabled = false;
chart.TrendLines.Add(new TrendLine{Value = cr.Mean,Orientation = System.Windows.Controls.Orientation.Vertical});
chart.TrendLines.Add(new TrendLine{Value = cr.ChartTrippleNegativeStdDeviation,Orientation = System.Windows.Controls.Orientation.Vertical,LineStyle = LineStyles.Dashed});chart.TrendLines.Add(new TrendLine{Value = cr.ChartTripplePositiveStdDeviation,Orientation = System.Windows.Controls.Orientation.Vertical,LineStyle = LineStyles.Dashed});
chart.TrendLines.Add(new TrendLine{Value = cr.UpperSpecificationLimit,Orientation = System.Windows.Controls.Orientation.Vertical});
chart.TrendLines.Add(new TrendLine{Value = cr.LowerSpecificationLimit,Orientation = System.Windows.Controls.Orientation.Vertical});
chart.TrendLines[0].SetValue(Canvas.ZIndexProperty, 40);
chart.TrendLines[1].SetValue(Canvas.ZIndexProperty, 40);
chart.TrendLines[2].SetValue(Canvas.ZIndexProperty, 40);
chart.TrendLines[3].SetValue(Canvas.ZIndexProperty, 40);
chart.TrendLines[4].SetValue(Canvas.ZIndexProperty, 40);
chart.DataPointWidth = cr.DataPointWidth;
chart.Visibility = Visibility.Visible;
Axis x = new Axis();
x.AxisMaximum = cr.VisUpperBound;
x.AxisMinimum = cr.VisLowerBound;
x.AxisType = AxisTypes.Primary;
CustomAxisLabels cal = new CustomAxisLabels();
cal.Labels.Add(new CustomAxisLabel {From = cr.Mean, To = cr.Mean, Text = "Mean"});
cal.Labels.Add(new CustomAxisLabel {From = cr.ChartTrippleNegativeStdDeviation,To = cr.ChartTrippleNegativeStdDeviation,Text = "LCL"});
cal.Labels.Add(new CustomAxisLabel{From = cr.ChartTripplePositiveStdDeviation,To = cr.ChartTripplePositiveStdDeviation,Text= "UCL"});
cal.Labels.Add(new CustomAxisLabel {From = cr.UpperSpecificationLimit, To = cr.UpperSpecificationLimit , Text = "USL"});
cal.Labels.Add(new CustomAxisLabel {From = cr.LowerSpecificationLimit, To = cr.LowerSpecificationLimit, Text = "LSL"});
cal.FontSize = 10;
cal.Angle = 0;
cal.FontColor = new SolidColorBrush(Colors.Black);
cal.Enabled = true;
x.CustomAxisLabels.Add(cal);
chart.AxesX.Add(x);
var ds = new DataSeries();
var dpc = new DataPointCollection(cr.HistogramValues);
ds.DataPoints = dpc;
chart.Series.Add(ds);
ds.ZIndex = 1;
ds.Bevel = false;
ds.ShadowEnabled = false;
ds.LightingEnabled = false;
ds.Color = new SolidColorBrush(Colors.SteelBlue);
chart.BeginInit();
chart.EndInit();
chart.Measure(new Size(300, 200));
chart.Arrange(new Rect(0, 0, 300, 200));
chart.UpdateLayout();
ExportToPng(new Uri("C:\\" + i + ".png"), chart);
}
everything works fine, except the custom Axis Labels are missing. This is how the Output looks like:
As you can see, there is even space allocated for the CustomAxis Labels but they are not shown. Anyone got an idea?
Hint: AnimationEnabled has to be set false otherwise the series is not rendered yet when the image is taken - took me a long time to figure that out.
I found already a solution:
When exceeding the bounds, the values are set to Double.NaN. I found out, that the creation of all Labels fails, if any value in the Collections Double.Nan or Double.Infinity - Seems lika a bug in visifire.
I solved it by adding each Label in its seperate Collection.