I have a couple of problems with a MSChart plotted in a Winform.
I can't get axis Y2 values displayed on the right hand side of the chart, which should be the default - similar to this question
the stripline won't plot, and
is it possible to line up the zero values of axes Y1 and Y2?
Thanks for any help.
ChartArea TestChartArea = new ChartArea();
public void CreateChartArea()
{
TestChartArea.Name = "TestChartArea";
TestChartArea.BackColor = Color.LightGreen;
TestChartArea.Position = new ElementPosition { Height = 100, Width = 80, X = 2, Y = 5 };
//TestChartArea.Position = new ElementPosition { Auto = true };
TestChartArea.AxisY = new Axis
{
Enabled = AxisEnabled.True,
IsLabelAutoFit = true,
IsMarginVisible = true,
LabelStyle = new LabelStyle { Format = "P2", ForeColor = Color.DarkBlue, Font = new Font("Arial", 10, FontStyle.Regular) },
LineColor = Color.Black,
MajorGrid = new Grid { LineColor = Color.White, LineDashStyle = ChartDashStyle.Solid },
MajorTickMark = new TickMark { LineColor = Color.Black }
};
TestChartArea.AxisY2 = new Axis
{
Enabled = AxisEnabled.True,
IsLabelAutoFit = true,
IsMarginVisible = true,
LabelStyle = new LabelStyle { Format = "P2", ForeColor = Color.DarkBlue, Font = new Font("Arial", 10, FontStyle.Regular) },
LineColor = Color.Transparent,
MajorGrid = new Grid { LineColor = Color.Yellow, LineDashStyle = ChartDashStyle.Solid },
MajorTickMark = new TickMark { LineColor = Color.Blue }
};
TestChartArea.AxisX = new Axis
{
Enabled = AxisEnabled.True,
Crossing = 0,
LineWidth = 1,
IsLabelAutoFit = true,
IsMarginVisible = false,
LabelStyle = new LabelStyle { Angle=-45,Format = "N0", ForeColor = Color.Black, Font = new Font("Arial", 8, FontStyle.Regular) },
LineColor = Color.Black,
MajorGrid = new Grid { LineColor = Color.White, LineDashStyle = ChartDashStyle.Solid },
MajorTickMark = new TickMark { LineColor = Color.LightGray, Size = 4.0f },
Name="Spot"
};
}
public void PlotChart()
{
int[] Xseries = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
double[] AXJO = { 0.0025, 0.0015, -0.001, 0.002, 0.0045, -0.002, -0.003, 0.0001, -0.004, -0.0075 };
double[] ES = { 0.0020, 0.0010, -0.0005, 0.003, 0.0025, -0.001, -0.0015, 0.0005, -0.0032, -0.006 };
double[] Diff = new double[10];
// pair return
for (int i = 0; i < 10; i++)
{
Diff[i] = AXJO[i] - ES[i];
}
TestChart.BackColor = Color.LightGoldenrodYellow;
TestChart.BackSecondaryColor = Color.LightBlue;
if (TestChart.Series.IsUniqueName("AXJO"))
{
TestChart.Series.Add("AXJO");
TestChart.Series["AXJO"].YAxisType = AxisType.Primary;
TestChart.Series["AXJO"].Color = Color.Green;
TestChart.Series["AXJO"].ChartType = SeriesChartType.Line;
TestChart.Series["AXJO"].Points.DataBindXY(Xseries, AXJO);
TestChart.Series["AXJO"].ChartArea = "TestChartArea";
}
if (TestChart.Series.IsUniqueName("ES"))
{
TestChart.Series.Add("ES");
TestChart.Series["ES"].YAxisType = AxisType.Primary;
TestChart.Series["ES"].Color = Color.Red;
TestChart.Series["ES"].ChartType = SeriesChartType.Line;
TestChart.Series["ES"].Points.DataBindXY(Xseries, ES);
TestChart.Series["ES"].ChartArea = "TestChartArea";
}
if (TestChart.Series.IsUniqueName("Diff"))
{
TestChart.Series.Add("Diff");
TestChart.Series["Diff"].YAxisType = AxisType.Secondary;
TestChart.Series["Diff"].Color = Color.Blue;
TestChart.Series["Diff"].ChartType = SeriesChartType.Line;
TestChart.Series["Diff"].Points.DataBindXY(Xseries, Diff);
TestChart.Series["Diff"].ChartArea = "TestChartArea";
}
}
public void AddStripLine()
{
// add stripline at Diff=zero
StripLine ZeroDiff = new StripLine();
ZeroDiff.ForeColor = Color.Black;
ZeroDiff.BackColor = Color.Black;
ZeroDiff.StripWidth = 1;
ZeroDiff.BorderWidth = 2;
ZeroDiff.Interval = 0;
ZeroDiff.IntervalOffset = 10;
TestChart.ChartAreas["TestChartArea"].AxisY2.StripLines.Add(ZeroDiff);
}
private void button1_Click(object sender, EventArgs e)
{
PlotChart();
AddStripLine();
}
}
You asked about the unwanted placement of the AxisY2 by setting its Crossing property to 0
Simply not setting it, thus leaving it at the default double.NaN for automatically placing it at the right will resolve the issue..:
Crossing = double.NaN
To make a stripline show, it needs to start within the visible range of its axis. Offsetting it by 10 is way overboard for your data.. Also making it black is probably not what you want, unless you only want a thin line, not a colored area..
The basic rules for StripLines are:
When Interval = 0 only one stripline is shown at IntervalOffset with a width/height of StripWidth
When Interval > 0 many striplines are shown, going over the whole axis; unless you have a semi-tranparent color you need to make sure that StripWidth < Interval or else there is no space between them!
All measures are in axis-values; the types can be set with StripWidthType and IntervalType; useful especially when using one of the DateTime units.
To make the 0 values of both y-axes align, you need to tweak the Minimum and/or Maximum values of one or both axes. This may be a bit tricky and you will probably need to look into your data and take full control of spacing and placing the axis labels..
Related
I know how to set font family and size to main xaxis and yaxis.
But I have tried many ways to do with other yaxis when the yaxis index is y2 and y7.
As the picture shows, DD-Prices is a yaxis with yaxisindex = y2, and PD-Price is a yaxis with yaxisindex = y7.
Here is my code:
if (plotValue.Keys.Contains("DD_CurrentPrice"))
{
y2 = graphArea.AddYAxis("DD - Price");
curve = new LineItem("DD - Current Price", null, plotValue["DD_CurrentPrice"], Color.FromArgb(255, 198, 001), SymbolType.None) { YAxisIndex = y2 };
curve.Label.FontSpec = new FontSpec("Cambria", 10.0f, Color.Black, false, false, false);
graphArea.CurveList.Add(curve);
}
if (plotValue.Keys.Contains("PD_MarkdownPrice") || plotValue.Keys.Contains("PD_CurrentPrice"))
{
y7 = graphArea.AddYAxis("PD - Price");
if (plotValue.Keys.Contains("PD_MarkdownPrice"))
{
curve = new LineItem("PD - Markdown Price", null, plotValue["PD_MarkdownPrice"], Color.FromArgb(045, 186, 030), SymbolType.None) { YAxisIndex = y7 };
curve.Label.FontSpec = new FontSpec("Cambria", 10.0f, Color.Black, false, false, false);
graphArea.CurveList.Add(curve);
}
if (plotValue.Keys.Contains("PD_CurrentPrice"))
{
curve = new LineItem("PD - Current Price", null, plotValue["PD_CurrentPrice"], Color.FromArgb(011, 138, 000), SymbolType.None) { YAxisIndex = y7 };
curve.Label.FontSpec = new FontSpec("Cambria", 10.0f, Color.Black, false, false, false);
graphArea.CurveList.Add(curve);
}
}
There is no property to set the curve scale font family and size. Is there any other solution? Thanks.
Add the code below can solve this problem:
Axis axis = graphArea.CurveList[y2].GetYAxis(graphArea);
axis.Scale.FontSpec.Family = "Cambria";
axis.Scale.FontSpec.Size = fontSize;
axis.Title.FontSpec.Family = "Cambria";
axis.Title.FontSpec.Size = fontSize;
I have a WinForm that has a TableLayoutPanel control. My code will detect the number of attached monitors on screen, create a column per monitor, and then add a button for each display within each individual column in the TableLayoutControl so I can ensure that no matter how many monitors are attached, the buttons will appear "centered" across the form. One/two monitors renders just fine, however three monitors results in end columns not being evenly distributed.
Here is my code:
int count = Screen.AllScreens.Count();
this.monitorLayoutPanel.ColumnCount = count;
ColumnStyle cs = new ColumnStyle(SizeType.Percent, 100 / count);
this.monitorLayoutPanel.ColumnStyles.Add(cs);
this.monitorLayoutPanel.AutoSize = true;
var buttonSize = new Size(95, 75);
int z = 0;
foreach (var screen in Screen.AllScreens.OrderBy(i => i.Bounds.X))
{
Button monitor = new Button
{
Name = "Monitor" + screen,
AutoSize = true,
Size = buttonSize,
BackgroundImageLayout = ImageLayout.Stretch,
BackgroundImage = Properties.Resources.display_enabled,
TextAlign = ContentAlignment.MiddleCenter,
Font = new Font("Segoe UI", 10, FontStyle.Bold),
ForeColor = Color.White,
BackColor = Color.Transparent,
Text = screen.Bounds.Width + "x" + screen.Bounds.Height,
Anchor = System.Windows.Forms.AnchorStyles.None
};
this.monitorLayoutPanel.Controls.Add(monitor, z, 0);
z++;
monitor.MouseClick += new MouseEventHandler(monitor_Click);
}
I've tried making the buttons smaller, and increased the form size but the last column is always smaller than the first two. I can't understand it!
Clear ColumnStyles first.
this.monitorLayoutPanel.ColumnStyles.Clear();
then:
int count = Screen.AllScreens.Count();
for (int i = 0; i < count; i++)
{
ColumnStyle cs = new ColumnStyle(SizeType.Percent, (float)100 / count);
this.monitorLayoutPanel.ColumnStyles.Add(cs);
}
this.monitorLayoutPanel.AutoSize = true;
...
Reza Aghaei pointed me to this thread How to create a magic square using Windows Forms? which pointed me in the right direction. Updated (and working) code below. :)
int screens = Screen.AllScreens.Count();
this.monitorLayoutPanel.ColumnStyles.Clear();
this.monitorLayoutPanel.ColumnCount = screens;
this.monitorLayoutPanel.AutoSize = true;
int z = 0;
foreach (var screen in Screen.AllScreens.OrderBy(i => i.Bounds.X))
{
var percent = 100f / screens;
this.monitorLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, percent));
Button monitor = new Button
{
Name = "Monitor" + screen,
Size = new Size(95, 75),
BackgroundImageLayout = ImageLayout.Stretch,
BackgroundImage = Properties.Resources.display_enabled,
TextAlign = ContentAlignment.MiddleCenter,
Font = new Font("Segoe UI", 10, FontStyle.Bold),
ForeColor = Color.White,
BackColor = Color.Transparent,
Text = screen.Bounds.Width + "x" + screen.Bounds.Height,
Anchor = System.Windows.Forms.AnchorStyles.None
};
this.monitorLayoutPanel.Controls.Add(monitor, z, 0);
z++;
monitor.MouseClick += new MouseEventHandler(monitor_Click);
I try to change WP8 button background from code. I have the variable
private Color bColor = new Color() { R = 74, G = 10, B = 180 };
And I try to do
mButton.Background = new SolidColorBrush(bColor);
But it's don't work. How can I do it correctly?
You forgot to set Alpha:
private Color bColor = new Color() { R = 74, G = 10, B = 180, A = 0xFF };
You would be better off using the construction methods, like Color.FromArgb()
I don't understand something. If i don't use the customlabels, the chart will use the default label. And then if I move the scrollbar , the chart size won't adjust. The Chart view maintain the original size.
But if I use this code to change the label at row 0. (other rows don't have this problem)
chart1.ChartAreas[0].AxisY2.CustomLabels.Add((i) ,
(i+1), (ntemp * 10).ToString(), 0, LabelMarkStyle.SideMark);
And Move the scrollbar, the chart View will be a little different for size. The chart will flicker, and I don't want it.
Thanks in advance.
Here is example
Random rand = new Random();
chart1.Series.Clear();
var series = chart1.Series.Add("My Series");
series.ChartType = SeriesChartType.RangeBar;
series.Color = Color.Black;
series.YAxisType = AxisType.Secondary;
for (int i = 10; i > 2; i--)
series.Points.AddXY(i, (rand.Next(3600, 7200)), (rand.Next(30000, 80000)));
var chartArea = chart1.ChartAreas[series.ChartArea];
chartArea.BorderDashStyle = ChartDashStyle.Solid; //最外圍的框框
chartArea.BorderWidth = 10;
chartArea.AxisY.Enabled = AxisEnabled.False;
chartArea.AxisY2.Enabled = AxisEnabled.True;
chartArea.AxisY2.LabelStyle.IntervalType = DateTimeIntervalType.Number;
chartArea.AxisY2.Interval = 3600;
chartArea.AxisY2.Minimum = 0;
chartArea.AxisY2.Maximum = 86400;
chartArea.AxisY2.ScaleView.Zoom(0, 3600 * 4);
for (int i = 0; i <= 24 * 6; i++)
{
int ntemp = i % 6;
if (ntemp != 0)
{
/*Problem Here !!*/
//chart1.ChartAreas[0].AxisY2.CustomLabels.Add((i) * 600, (i + 1) * 600, (ntemp * 10).ToString(), 0, LabelMarkStyle.Box);
}
}
chartArea.CursorY.AutoScroll = true;
chartArea.AxisY2.ScaleView.Zoomable = true;
chartArea.AxisY2.ScrollBar.ButtonStyle = ScrollBarButtonStyles.SmallScroll;
chartArea.AxisY2.ScrollBar.IsPositionedInside = false;
}
Well, I was intrigued about how and if this can be achieved with OxyPlot, and I think it can ...
Here's the code I've used, and here's a screenshot:
var model = new PlotModel("IntervalBarSeries") { LegendPlacement = LegendPlacement.Outside };
var temp_serie = new IntervalBarSeries
{
Title = "IntervalBarSeries 1",
FillColor = OxyColors.Black
};
var categoryAxis = new CategoryAxis
{
Position = AxisPosition.Left,
IsZoomEnabled = false, // No zoom on this axis
IsPanEnabled = false, // Right mouse move won't affect this axis
MajorGridlineStyle = LineStyle.Solid
,StartPosition = 1, EndPosition = 0 // This will reverse the order
};
var valueAxis = new LinearAxis(AxisPosition.Top)
{
MinimumPadding = 0.1, MaximumPadding = 0.1,
IsZoomEnabled = true,
MajorGridlineStyle = LineStyle.Solid,
MajorStep = 3600,
AbsoluteMinimum = 0
};
for (int i = 10; i > 2; i--)
{
temp_serie.Items.Add(new IntervalBarItem {
Start = rand.Next(3600, 7200),
End = rand.Next(30000, 80000)
});
categoryAxis.Labels.Add("Activity "+i);
}
model.Series.Add(temp_serie);
model.Axes.Add(categoryAxis);
model.Axes.Add(valueAxis);
MyPlotModel = model;
Now, I'm using MVVM and just binding to the plot model from my View with:
<oxy:Plot Model="{Binding MyPlotModel}"/>
But you can figure out how to do the same with WinForms once (if?) you decide to use OxyPlot and import it.
I'm assuming you're doing some work that is related to times, but your code obviously doesn't say so ... you could play around with the top header, and maybe set how to show the numbers (ATM, with no zoom, they overlap each other a bit. zooming with scroller solves that, but that's just because i've set the tick size to 3600 ... )
I have a simple chart, and I'd like the labels on the x-axis to be rotated 45 degrees. What am I doing wrong?
Chart c = new Chart();
c.ChartAreas.Add(new ChartArea());
c.Width = 200;
c.Height = 200;
Series mySeries = new Series();
mySeries.Points.DataBindXY(new string[] { "one", "two", "three" }, new int[] { 1, 2, 3 });
mySeries.LabelAngle = 45; // why doesn't this work?
c.Series.Add(mySeries);
The output is:
I'm using the charting stuff from System.Web.UI.DataVisualization.Charting.
The documentation says that Series.LabelAngle sets data point label angle, which (I think) is a label above the chart's column.
To set an angle of axis labels try this one:
var c = Chart1;
c.ChartAreas.Add(new ChartArea());
c.Width = 200;
c.Height = 200;
Series mySeries = new Series();
mySeries.Points.DataBindXY(new string[] { "one", "two", "three" }, new int[] { 1, 2, 3 });
//mySeries.LabelAngle = -45; // why doesn't this work?
c.Series.Add(mySeries);
c.ChartAreas[0].AxisX.LabelStyle.Angle = 45; // this works
Here is how I usually rotate my X Axis labels.
ChartArea area = new ChartArea();
area.AxisX.IsLabelAutoFit = true;
area.AxisX.LabelAutoFitStyle = LabelAutoFitStyles.LabelsAngleStep30;
area.AxisX.LabelStyle.Enabled = true;
Results
The key property/line to look at above is the "LabelAutoFitStyle".
I needed these lines to get it to work:
chartarea.AxisX.LabelStyle.Angle = -90;
chartarea.AxisX.IntervalAutoMode = IntervalAutoMode.VariableCount;
chartarea.AxisX.IsLabelAutoFit = false;
I know this question is old and answered. I just want to say that Series.LabelAngle controls series' label, not Axis'. If you add these two lines, the label would be shown above the column and is rotated 45 degrees:
mySeries.IsValueShownAsLabel = true;
mySeries.SmartLabelStyle.Enabled = false;
So you have to set AxisX's LabelAngle as Maciej Rogoziński said.
Axis.IsLabelAutoFit default value is true, so it must be set to false in order for LabelStyle.Angle to be applied.