I am showing multiple Y axis for chart by using below code. When any axis label value is having more than 3 digits then that axis Label/Title is getting overlap with other axis Label (as shown in image).
int leftIndex = 0, rightIndex = 0;
int relativePosition = 0;
foreach (Steema.TeeChart.Axis axis in this.tChart.Axes.Custom)
{
axis.Visible = true;
axis.PositionUnits = Steema.TeeChart.PositionUnits.Pixels;
axis.RelativePosition = 0 - (axis.OtherSide ? rightIndex++ : leftIndex++) * 60;
relativePosition = relativePosition + (axis.AxisRect().Width + 60);
}
You should be able to get your chart to render correctly by slightly modifying the constant in your calculation, e.g.
TChart _tChart;
public Form1()
{
InitializeComponent();
_tChart = new TChart();
_tChart.Dock = DockStyle.Fill;
_tChart.Series.Add(typeof(Line)).FillSampleValues();
_tChart.Series.Add(typeof(Line)).FillSampleValues();
_tChart.Series.Add(typeof(Line)).FillSampleValues();
_tChart.Series[0].YValues.Value = _tChart.Series[2].YValues.Value.Select(x => x * 100).ToArray();
_tChart.Header.Text = Utils.Version;
_tChart[0].CustomVertAxis = _tChart.Axes.Custom.Add();
_tChart[0].CustomVertAxis.Title.Text = "Axis One Title";
_tChart[0].CustomVertAxis.Title.Angle = 90;
_tChart[1].CustomVertAxis = _tChart.Axes.Custom.Add();
_tChart[1].CustomVertAxis.Title.Text = "Axis Two Title";
_tChart[1].CustomVertAxis.Title.Angle = 90;
_tChart[2].CustomVertAxis = _tChart.Axes.Custom.Add();
_tChart[2].CustomVertAxis.Title.Text = "Axis Three Title";
_tChart[2].CustomVertAxis.Title.Angle = 90;
int leftIndex = 0, rightIndex = 0;
for (int i = 0; i < this._tChart.Axes.Custom.Count; i++)
{
var axis = this._tChart.Axes.Custom[i];
axis.Visible = true;
axis.PositionUnits = Steema.TeeChart.PositionUnits.Pixels;
axis.RelativePosition = 0 - (axis.OtherSide ? rightIndex++ : leftIndex++) * (i == 1 ? 80: 70);
}
_tChart.Panel.MarginLeft = 30;
this.Controls.Add(_tChart);
}
Which here gives me:
Related
How can I get x,y location of graph wher X and Y Axis starts (x,y location of point 0,0 in line chart)? This location is changable depending on text values on Y Axis probably.
Image is for illustrative purpose only.
How can I change the background color (currently is linear blue) of chart (I use PDFsharp NuGet package)?
Sample code:
ChartFrame chartFrame = new ChartFrame();
chartFrame.Location = new XPoint(xOffset, yLoc);
double chartHeight = Math.Min(250, (page.Height - yLoc - 10));
chartFrame.Size = new XSize((page.Width - (xOffset * 2)), chartHeight);
Chart chart = new Chart(ChartType.Line);
//chart.PlotArea.FillFormat.Color = XColor.FromArgb(255, 255, 255, 255); //plot background???
Series series = chart.SeriesCollection.AddSeries();
series.ChartType = ChartType.Line;
series.MarkerStyle = PdfSharp.Charting.MarkerStyle.None;
series.Name = "Horizontal"; //Series 1
series.MarkerBackgroundColor = XColor.FromArgb(255, 0, 0, 255); //blue
series.MarkerSize = 1;
series.Add(line1);
series = chart.SeriesCollection.AddSeries();
series.ChartType = ChartType.Line;
series.MarkerStyle = PdfSharp.Charting.MarkerStyle.None;
series.Name = "Vertical"; //Series 2
series.MarkerBackgroundColor = XColor.FromArgb(255, 0, 170, 0); //green
series.MarkerSize = 1;
series.Add(line2);
series = chart.SeriesCollection.AddSeries();
series.ChartType = ChartType.Line;
series.MarkerStyle = PdfSharp.Charting.MarkerStyle.None;
series.Name = "3D position"; //Series 3
series.MarkerBackgroundColor = XColor.FromArgb(255, 255, 0, 0); //red
series.MarkerSize = 1;
series.Add(line3);
chart.XAxis.MajorTickMark = TickMarkType.Outside;
chart.XAxis.Title.Caption = "No. Events"; //X-Axis
chart.YAxis.MajorTickMark = TickMarkType.Outside;
chart.YAxis.HasMajorGridlines = true;
double yOffset = ((maxYscale - minYscale) / 6);
if (yOffset < 0.01f)
yOffset = 0.01f;
chart.YAxis.MinimumScale = 0;
chart.YAxis.MaximumScale = Math.Round(Math.Round((maxYscale + yOffset), 3), 2);
double jump = Math.Round(yOffset, 2);
if (jump < 0.01f)
jump = 0.01f;
chart.YAxis.MajorTick = jump;
chart.YAxis.TickLabels.Format = "#0.00";
//chart.YAxis.HasMinorGridlines = true;
chart.YAxis.Title.Caption = "[m]"; //Y-Axis
chart.YAxis.HasMajorGridlines = true;
chart.PlotArea.LineFormat.Color = XColors.DarkGray;
chart.PlotArea.LineFormat.Width = 1;
chart.PlotArea.LineFormat.Visible = true;
chart.Legend.Docking = DockingType.Bottom;
chart.Legend.LineFormat.Visible = true;
XSeries xseries = chart.XValues.AddXSeries();
xseries.Add(eventLine);
chartFrame.Add(chart);
chartFrame.Draw(gfx);
Re:for X,Y location:
I made quick check for text length on YAxis and then according to that calculate new X,Y position.
Re: Background color:
These colours are hard-coded in the ChartFrame class (Draw method). So the nugget package for PDFSharp is not good you need to download the library source code.
Search for "XColor.FromArgb(0xFFD0DEEF)" and update the source code as needed.
I want to make a tiles based scrolling game in Visual Studio C# using forms. I know its not the best platform for this but those are set parameters. I suppose the easiest way to think of the end program is like pokemon 2d top down world scrolling.
I can create a 2d array of picture boxes and allocated images to them based on a text 2d array of tile ids. I can scroll the picture boxes and when they reach a certain place, jump back to the original location and display a shifted tile.
My issue is adding controls, it only adds a column rather than the full grid. I have tried using tables but with the same problem.
Has anyone done this type of large world scroller using VSC# and forms? Are there any tutorials or suggestions? Thanks.
EDIT - Code added'
public Form1()
{
InitializeComponent();
TableLayoutPanel wholescreen = new TableLayoutPanel();
wholescreen.Location = new System.Drawing.Point(0,0);
wholescreen.Size = new System.Drawing.Size(200,200);
wholescreen.RowCount = 2;
wholescreen.ColumnCount = 2;
Controls.Add(wholescreen);
PictureBox item = new PictureBox();
item.Size = new System.Drawing.Size(50, 50);
item.ImageLocation = "C:\\Users\\i.price\\Documents\\1.png";
for (int x = 0; x < 2; x++)
{
for (int y = 0; y < 2; y++)
{
item.Left = x * 50;
item.Top = y * 50;
wholescreen.Controls.Add(item,x,y);
}
}
}
'
another way i tried....'
int WIDTH = 3;
int HEIGHT = 3;
PictureBox[] grid = new PictureBox[9];
//PictureBox[,] grid = new PictureBox[3, 3];
//int[,] level1 = new int[2, 2] { { 1, 2 }, { 3, 4 } };
int playerx = 0;
public Form1()
{
InitializeComponent();
int y = 0;
int x = 0;
for (int cntr = 0; cntr < HEIGHT*WIDTH; cntr++)
{
if ((cntr % HEIGHT) == 0)
{
x++;
y = 0;
}
grid[cntr] = new PictureBox();
grid[cntr].Left = x * 50;
grid[cntr].Top = y * 50;
grid[cntr].ImageLocation = "C:\\Users\\i.price\\Documents\\1.png";
Controls.Add(grid[cntr]);
}
}
'
I think you are just creating one square and moving it around. Try...
private void Method2()
{
TableLayoutPanel wholescreen = new TableLayoutPanel();
wholescreen.BackColor = Color.AliceBlue;
wholescreen.Location = new System.Drawing.Point(0, 0);
wholescreen.Size = new System.Drawing.Size(200, 200);
wholescreen.RowCount = 2;
wholescreen.ColumnCount = 2;
Controls.Add(wholescreen);
PictureBox item;
// item.ImageLocation = "C:\\Users\\i.price\\Documents\\1.png";
for (int x = 0; x < 2; x++)
{
for (int y = 0; y < 2; y++)
{
item = new PictureBox();
item.Size = new System.Drawing.Size(50, 50);
item.BackColor = Color.Blue;
//item.Left = 0;
//item.Top = 0;
wholescreen.Controls.Add(item, x, y);
}
}
}
enter image description here
I have captured points data from bamboo slate,and converted them to Windows.UI.Input.Inking.InkStroke data.Then I put them in a InkPresenter.StrokeContainer rendered like this image above.Strokes sticked to each other,how can I seperate them?
This is my code below.
private void DataDisplay()
{
List<InkPoint> list = new List<InkPoint>();
List<InkStroke> strokes = new List<InkStroke>();
InkDrawingAttributes drawingAttributes1 = new InkDrawingAttributes();
drawingAttributes1.Color = Colors.Black;
drawingAttributes1.Size = new Size(1, 1);
InkStrokeBuilder builder = new InkStrokeBuilder();
builder.SetDefaultDrawingAttributes(drawingAttributes1);
inkCanvas.InkPresenter.UpdateDefaultDrawingAttributes(drawingAttributes1);
inkCanvas.InkPresenter.IsInputEnabled = true;
foreach (var item in data.Stroke)
{
string[] strArray = item.Split(',');
for (int i = 9; i <= strArray.Length - 5; i += 5)
{
float x = float.Parse(strArray[i]) / 30;
float y = float.Parse(strArray[i + 1]) / 30;
float pressure = float.Parse(strArray[i + 2]) / 1000;
Point point = new Point(x, y);
InkPoint ip = new InkPoint(point, pressure);
list.Add(ip);
}
Matrix3x2 matrix3X2 = new Matrix3x2(1, 0, 0, 1, 0, 0);
InkStroke newStroke = builder.CreateStrokeFromInkPoints(list, matrix3X2);
strokes.Add(newStroke);
}
inkCanvas.InkPresenter.StrokeContainer.AddStroke(strokes);
}
I want to create a 3D Graph in 4 quadrants form in C#.NET. For instant, I could do as shown below. If you see the corner of the chart begins with (-150, -200). I wish to start with (0,0) and the extend into 4 quadrant form.
Kindly enlighten me how can I transform this 3D graph in 4 quadrant form ?
Below is the corresponding code:
void prepare3dChart(Chart chart, ChartArea ca)
{
ca.Area3DStyle.Enable3D = true;
Series s = new Series();
chart.Series.Add(s);
s.ChartType = SeriesChartType.Bubble;
s.MarkerStyle = MarkerStyle.Diamond;
s["PixelPointWidth"] = "100";
s["PixelPointGapDepth"] = "1";
chart.ApplyPaletteColors();
addTestData(chart);
}
void addTestData(Chart chart)
{
Random rnd = new Random(9);
double x = 0, y = 0, z = 0;
for (int i = 0; i < 100; i++)
{
AddXY3d(chart.Series[0], x, y, z);
x = Math.Sin(i / 11f) * 88 + rnd.Next(3);
y = Math.Cos(i / 10f) * 88 + rnd.Next(5);
z = (Math.Sqrt(i * 2f) * 88 + rnd.Next(6));
}
}
int AddXY3d(Series s, double xVal, double yVal, double zVal)
{
int p = s.Points.AddXY(xVal, yVal, zVal);
s.Points[p].Color = Color.Transparent;
return p;
}
private void chart1_PostPaint(object sender, ChartPaintEventArgs e)
{
Chart chart = sender as Chart;
if (chart.Series.Count < 1) return;
if (chart.Series[0].Points.Count < 1) return;
ChartArea ca = chart.ChartAreas[0];
List<List<PointF>> data = new List<List<PointF>>();
foreach (Series s in chart.Series)
data.Add(GetPointsFrom3D(ca, s, s.Points.ToList(), e.ChartGraphics));
renderLines(data, e.ChartGraphics.Graphics, chart, true);
renderPoints(data, e.ChartGraphics.Graphics, chart, 6);
}
List<PointF> GetPointsFrom3D(ChartArea ca, Series s,
List<DataPoint> dPoints, ChartGraphics cg)
{
var p3t = dPoints.Select(x => new Point3D((float)ca.AxisX.ValueToPosition(x.XValue),
(float)ca.AxisY.ValueToPosition(x.YValues[0]),
(float)ca.AxisY.ValueToPosition(x.YValues[1]))).ToArray();
ca.TransformPoints(p3t.ToArray());
return p3t.Select(x => cg.GetAbsolutePoint(new PointF(x.X, x.Y))).ToList();
}
void renderLines(List<List<PointF>> data, Graphics graphics, Chart chart, bool curves)
{
for (int i = 0; i < chart.Series.Count; i++)
{
if (data[i].Count > 1)
using (Pen pen = new Pen(Color.FromArgb(64, chart.Series[i].Color), 2.5f))
if (curves) graphics.DrawCurve(pen, data[i].ToArray());
else graphics.DrawLines(pen, data[i].ToArray());
}
}
void renderPoints(List<List<PointF>> data, Graphics graphics, Chart chart, float width)
{
for (int s = 0; s < chart.Series.Count; s++)
{
Series S = chart.Series[s];
for (int p = 0; p < S.Points.Count; p++)
using (SolidBrush brush = new SolidBrush(Color.FromArgb(64, S.Color)))
graphics.FillEllipse(brush, data[s][p].X - width / 2,
data[s][p].Y - width / 2, width, width);
}
}
I want my 3D graph to have 4 quadrants like this:
Thanks #TaW. I got the code right.
void prepare3dChart(Chart chart, ChartArea ca)
{
ca.Area3DStyle.Enable3D = true;
ca.BackColor = Color.Transparent;
ca.AxisX.Minimum = -300;
ca.AxisX.Maximum = 300;
ca.AxisY.Minimum = -300;
ca.AxisY.Maximum = 300;
ca.AxisX.Crossing = 0; // move both axes..
ca.AxisY.Crossing = 0; // to the middle
ca.AxisX.Interval = 50;
ca.AxisY.Interval = 50;
ca.AxisX.MajorGrid.LineColor = Color.LightGray;
ca.AxisY.MajorGrid.LineColor = Color.LightGray;
chart.Series.Clear();
Series s = new Series();
chart.Series.Add(s);
s.ChartType = SeriesChartType.Bubble;
s.MarkerStyle = MarkerStyle.Diamond;
s["PixelPointWidth"] = "100";
s["PixelPointGapDepth"] = "1";
chart.ApplyPaletteColors();
addTestData(chart);
}
You can style the chart easily to look like this by moving both axes to the middle; this is done by setting their Crossings:
The code used is this:
ChartArea ca = chart1.ChartAreas[0];
ca.BackColor = Color.Transparent;
ca.AxisX.Minimum = -300;
ca.AxisX.Maximum = 300;
ca.AxisY.Minimum = -300;
ca.AxisY.Maximum = 300;
ca.AxisX.Crossing = 0; // move both axes..
ca.AxisY.Crossing = 0; // to the middle
ca.AxisX.Interval = 100;
ca.AxisY.Interval = 100;
ca.AxisX.MajorGrid.LineColor = Color.LightGray;
ca.AxisY.MajorGrid.LineColor = Color.LightGray;
Note that the real problem with MSChart in 3d-mode always remains the z-axis because there really isn't one. (If anybody is interested in how one can simulate it by having a lot of series see here. My example uses 32 series..)
You could draw it yourself, using the built-in function for the 3d conversions (TransformPoints) but this is a lot of tedious work, especially when it comes to labelling..
The updated code :
void prepare3dChart(Chart chart, ChartArea ca)
{
ca.Area3DStyle.Enable3D = true;
ca.BackColor = Color.Transparent;
ca.AxisX.Minimum = -300;
ca.AxisX.Maximum = 300;
ca.AxisY.Minimum = -300;
ca.AxisY.Maximum = 300;
ca.AxisX.Crossing = 0; // move both axes..
ca.AxisY.Crossing = 0; // to the middle
ca.AxisX.Interval = 50;
ca.AxisY.Interval = 50;
ca.AxisX.MajorGrid.LineColor = Color.LightGray;
ca.AxisY.MajorGrid.LineColor = Color.LightGray;
chart.Series.Clear();
Series s = new Series();
chart.Series.Add(s);
s.ChartType = SeriesChartType.Bubble;
s.MarkerStyle = MarkerStyle.Diamond;
s["PixelPointWidth"] = "100";
s["PixelPointGapDepth"] = "1";
chart.ApplyPaletteColors();
addTestData(chart);
}
I have created an array of black labels and have displayed them on a picture box. Unfortunately, I am not able to line them up directly at each intersection of the black lines. How can I do this?
InitializeComponent();
int x = pictureBox1.Location.X;
int y = pictureBox1.Location.Y;
// create 361 labels, set their properties
for (int i = 0; i < 361; i++)
{
board[i] = new Label();
board[i].Parent = pictureBox1;
board[i].Location = new Point(x, y);
board[i].Name = "label" + i;
board[i].Text = "0";
board[i].BackColor = Color.Black;
//set size of labels
board[i].Size = new Size(31,31);
}
// set the position of the label
foreach (Label i in board)
{
//set distance between labels
if (x >= 1024)
{
x = pictureBox1.Location.X;
y += 52;
}
else
{
x += 52;
}
this.Controls.Add(i);
i.BringToFront();
i.Location = new Point(x, y);
}
as far as i have understand your question, and saw your code.
you are creating labels at same
Location(x,y) where x = 100 and y = 0
in the next loop
foreach (Label i in board)
{
if (x >= 1024)
{
x = 0;
y += i.Height + 55;
}
else if (y >= 1024)
{
y = 0;
x += i.Width + 55;
}
}
None of your condition will become true, because your x = 100 and y = 0
so location will remain same and all labels will be at same location
if you want to display a chess grid see this method
Chess Grid in Winforms
if you want to display labels on intersection of lines then lets modify your Code
x = PictureBox1.Location.X + 55;
y = pictureBox1.Location.Y + 55;
for (int i = 0; i < 361; i++)
{
board[i] = new Label();
board[i].Parent = pictureBox1;
board[i].Location = new Point(x,y);
board[i].Name = "label" + i;
board[i].Text = "0";
board[i].BackColor = Color.Black;
board[i].Size = new Size(55,55); //Define size of label according to your choice
if(x >= 1024)
{
x = PictureBox1.Location.X + 55; //Start position
y += 55; // Step to next line
}
else
x += 55; //jump to next horizontal box
}
I hope this helps