I have a bar chart and I got a little problem in it.. it's grouping all bars to one single x value column .. i need to split each bar to its x value.. take a look at the snap shoot of the problem..
and my code:
RadChart1.PlotArea.XAxis.AutoScale = false;
RadChart1.PlotArea.XAxis.Items.Clear();
RadChart1.Series.Clear();
for (int i = 0; i < dt.Rows.Count; i++)
{
ChartSeries series = new ChartSeries(dt.Rows[i]["day_name"].ToString(), ChartSeriesType.Bar);
series.Items.Add(new ChartSeriesItem(Convert.ToDouble(dt.Rows[i]["total_timesheet"])));
ChartAxisItem axisItem = new ChartAxisItem(dt.Rows[i]["doc_date"].ToString());
RadChart1.PlotArea.XAxis.Items.Add(axisItem);
RadChart1.Series.Add(series);
}
Related
I'm using the Winform DataVisualization.Charting.Chart control. I have added 3 data series into the default chartarea. Each series has an integer y value and a Datetime x value.
If I show any one data series, it works as expected; however, if I combine the data series the dates overlap and are not in chronological order thus making the chart useless. I've hard-coded the values just for a sanity check but still see the same issue.
If anyone knows for a way for this chart to have a single x axis timeline that all data series will just plot the y value onto, it would be greatly appreciated. I've run out of things to try. (Image include below...)
chrtSessions.ChartAreas.Clear();
chrtSessions.ChartAreas.Add(new ChartArea("Default"));
chrtSessions.Series.Clear();
chrtSessions.Titles.Clear();
chrtSessions.Titles.Add("Hours Left For Licensure");
chrtSessions.ChartAreas["Default"].AxisY.Title = "Hours";
chrtSessions.ChartAreas["Default"].AxisX.Title = "Dates";
chrtSessions.ChartAreas["Default"].AxisX.IntervalType = DateTimeIntervalType.Days;
chrtSessions.ChartAreas["Default"].AxisX.LabelStyle.Format = "DD/MM/YYYY";
chrtSessions.Series.Add("Individual");
chrtSessions.Series["Individual"].AxisLabel = "Individual Sessions";
chrtSessions.Series["Individual"].ChartType = SeriesChartType.Line;
chrtSessions.Series["Individual"].BorderWidth = 4;
chrtSessions.Series["Individual"].XValueType = ChartValueType.Date;
for (int index = 0; index < individualData.hours.Count; index++)
{
chrtSessions.Series["Individual"].Points.AddXY(individualData.dates[index].ToShortDateString(), individualData.hours[index]);
}
chrtSessions.Series.Add("Relational");
chrtSessions.Series["Relational"].AxisLabel = "Relational Sessions";
chrtSessions.Series["Relational"].ChartType = SeriesChartType.Line;
chrtSessions.Series["Relational"].BorderWidth = 4;
chrtSessions.Series["Relational"].XValueType = ChartValueType.Date;
for (int index = 0; index < relationalData.hours.Count; index++)
{
chrtSessions.Series["Relational"].Points.AddXY(relationalData.dates[index].ToShortDateString(), relationalData.hours[index]);
}
chrtSessions.Series.Add("Supervision");
chrtSessions.Series["Supervision"].AxisLabel = "Supervision Sessions";
chrtSessions.Series["Supervision"].ChartType= SeriesChartType.Line;
chrtSessions.Series["Supervision"].BorderWidth = 4;
chrtSessions.Series["Supervision"].XValueType = ChartValueType.Date;
for (int index = 0; index < supervisionData.hours.Count; index++)
{
chrtSessions.Series["Supervision"].Points.AddXY(supervisionData.dates[index].ToShortDateString(), supervisionData.hours[index]);
}
Notice on this image that the Date 11/19/2021 occurs twice, but with 11/20/2021 occurring in-between and only yellow dataset actually has data that goes to the 23rd (data should show from 10/29-11/23). The blue line should span 10/31-11/20 and the red line should span from 10/26-11/19.
I have a c# Windows forms application that generates a stacked line graph using the standard MS Chart control, as in the below example.
Is there a way of "smoothing" the lines by formatting the series or some other property?
Looking at MSDN and Google I can't seem to find a way to do this, in Excel there a series.Smooth property...
I have I missed it or is it not possible?
If you liked the smooth look of the SplineAreas you can calculate the necessary values to get just that look:
A few notes:
I have reversed the order of the series; many ways to get the colors right.. (Instead one probably should accumulate in reverse)
The stacked DataPoints need to be aligned, as usual and any empty DataPoints should have their Y-Values to be 0.
Of course in the new series you can't access the actual data values any longer as you now have the accumulated values instead; at least not without reversing the calulation. So if need them keep them around somewhere. The new DataPoints' Tag property is one option..
You can control the ' smoothness' of each Series by setting its LineTension custom attribute:
chart2.Series[0].SetCustomProperty("LineTension", "0.15");
Here is the full example code that creates the above screenshots calculating a 'stacked' SplineArea chart2 from the data in a StackedArea chart1:
// preparation
for (int i = 0; i < 4; i++)
{
Series s = chart1.Series.Add("S" + i);
s.ChartType = SeriesChartType.StackedArea;
Series s2 = chart2.Series.Add("S" + i);
s2.ChartType = SeriesChartType.SplineArea;
}
for (int i = 0; i < 30; i++) // some test data
{
chart1.Series[0].Points.AddXY(i, Math.Abs(Math.Sin(i / 8f)));
chart1.Series[1].Points.AddXY(i, Math.Abs(Math.Sin(i / 4f)));
chart1.Series[2].Points.AddXY(i, Math.Abs(Math.Sin(i / 1f)));
chart1.Series[3].Points.AddXY(i, Math.Abs(Math.Sin(i / 0.5f)));
}
// the actual calculations:
int sCount = chart1.Series.Count;
for (int i = 0; i < chart1.Series[0].Points.Count ; i++)
{
double v = chart1.Series[0].Points[i].YValues[0];
chart2.Series[sCount - 1].Points.AddXY(i, v);
for (int j = 1; j < sCount; j++)
{
v += chart1.Series[j].Points[i].YValues[0];
chart2.Series[sCount - j - 1].Points.AddXY(i, v);
}
}
// optionally control the tension:
chart2.Series[0].SetCustomProperty("LineTension", "0.15");
I'm not sure if the title is correct because I wasn't sure how to explain it. I've encountered many scenarios where being able to dynamically modify part of a variable name such a suffixing integer could save me a great deal of time and keep my code much cleaner but I'm not sure how to do it. Here's an example of my most recent encounter.
I have 9 PictureBox's in a 3 x 3 grid. Each PictureBox has a name of cell followed by it's number so cell1, cell2, cell3 etc. I want to get the background colour of each of these cells and assign them to a variable whilst converting them to strings... something like this:
for (int i = 1; i < 10; i++)
{
string ci = celli.BackColor.ToString();
}
Is there a way I can have the i variable insert only it's numeric value to the placeholder rather than appending an i to the variable name? Can I wrap it in some sort of bracket? I've tried Googleing this but I'm finding it difficult to search for using just keywords.
Thanks in advance.
You are probably using a visual form editor, the best way to do this whould probably be to generate the grid by code (and not visually).
Another solution is to make it a matrix:
PictureBox[,] cell = new PictureBox[,] {
{ cell1, cell2, cell3 },
{ cell4, cell5, cell6 },
{ cell7, cell8, cell9 }
};
string[,] c = new string[3, 3];
for(int y=0; y<3; y++)
for(int x=0; x<3; x++)
c[x, y] = cell[x, y].BackColor.ToString();
Good luck with your code.
You would like to generate a list or collection of all your pictureboxes so that you can access them by specifying their index. One way is to generate the PictureBoxes on runtime:
Like this:
List<PictureBox> myPics = new List<PictureBox>();
int picWidth = 100;
int picHeight = 100;
for (x = 0; x <= this.Width; x += picWidth) {
for (y = 0; y <= this.Height; y += picHeight) {
PictureBox pic = new PictureBox();
pic.Image = pic.Image;
// Your image
pic.Location = new Point(x, y);
this.Controls.Add(pic);
myPics.Add(pic);
}
}
// Do something with myPics...
The other method is that when you do have all the pictureboxes on your form already, you can iterate through all the controls, check which ones are pictureboxes and then check their Name property to identify their index. Then do something with them accordingly.
foreach (void ctrl_loopVariable in this.Controls) {
ctrl = ctrl_loopVariable;
if (ctrl.GetType() == typeof(PictureBox)) {
if (ctrl.Name == "your picture box name to test") {
// Do something here with ctrl
}
}
}
(The above code is converted from VB to C#, excuse conversion issues)
Your intend here is to dynamically reference those controls.
In order to achieve this, there is two options:
You create those controls dynamically
You create dynamic references for the controls created by your form-designer
The first point is explained ny Shreyas Kapur's answer.
The second could be cone like this,
readonly Dictionary<Point,PictureBox> _dynamicMappedBoxes =
new Dictionary<Point,PictureBox>();
// Call this once in the beginning ofr your program
void createDynamicMapping()
{
foreach(PictureBox box in Controls.OfType<PictureBox>())
{
Point coords = getCoordinatesFromName(box);
_dynamicMappedBoxes.Add(coords, box);
}
}
Point getCoordinatesFromName(PictrueBox box)
{
int x = int.Parse(box.Name.SubString(IdontKnow);
int y = int.Parse(box.Name.SubString(IdontKnow);
retrun new Point(x,y);
}
//usage
string colorName = dynamicMappedBoxes[new Point(x,y)].BackColor.ToString();
I'm trying to create a stacked bar chart ,
But I'm getting an error in the lines that has ".Series " (How to define the Series ? )
SeriesChartType chart1 = new SeriesChartType();
// Populate series data
Random random = new Random();
for (int pointIndex = 0; pointIndex < 10; pointIndex++)
{
chart1.Series["LightBlue"].Points.AddY(random.Next(45, 95));
}
// Set chart type
chart1.Series["LightBlue"].ChartType = SeriesChartType.StackedArea100;
// Show point labels
chart1.Series["LightBlue"].IsValueShownAsLabel = true;
// Disable X axis margin
chart1.ChartAreas["Default"].AxisX.IsMarginVisible = false;
// Set the first two series to be grouped into Group1
chart1.Series["LightBlue"]["StackedGroupName"] = "Group1";
chart1.Series["Gold"]["StackedGroupName"] = "Group1";
// Set the last two series to be grouped into Group2
chart1.Series["Red"]["StackedGroupName"] = "Group2";
chart1.Series["DarkBlue"]["StackedGroupName"] = "Group2";
The source code above seems to be from the MS Chart Samples application. Looking at the MS example stacked bar chart on screen, and the source code above, its obvious that the sample code is inadequate and does not show us how to do stacked bar charts.
You can either programmatically create and attach a series:
Series s1 = new Series("LightBlue");
s1.ChartType = SeriesChartType.StackedBar100;
chart1.Series.Add(s1);
or alternatively, you can define the series in your ASPX file and simple add Y values to each series in the code behind:
Random random = new Random();
for(int pointIndex = 0; pointIndex < 10; pointIndex++)
{
Chart1.Series["Series1"].Points.AddY(Math.Round((double)random.Next(45, 95),0));
Chart1.Series["Series2"].Points.AddY(Math.Round((double)random.Next(5, 75),0));
Chart1.Series["Series3"].Points.AddY(Math.Round((double)random.Next(5, 95),0));
Chart1.Series["Series4"].Points.AddY(Math.Round((double)random.Next(35, 95),0));
}
In the MS Chart Samples web solution, have a look at
/ChartTypes/BarColumnCharts/Stacked/stackedchart.aspx
it should have all you need.
I am new to C#.I have been thinking of adding a ButtonControlArray where i can store each button control.Here is part of my code.I am creating a 6*6 array of button Control.
ButtonControl buttonControl;
ButtonControl[,] arrayButtons = new ButtonControl[6,6];
public void createGrid()
{
l = 0;
for (int i = 0; i < numberOfButtons; i++)
{
for (int k = 0; k < numberOfButtons; k++)
{
buttonControl = new ButtonControl();
buttonControl.Location = new Point(l,j);
j += 55;
arrayButtons[i, k] = buttonControl;
//After the above statement if i print Console.WriteLine(""+arrayButtons[i,k]); i am getting only my projectname.buttoncontrol
myGridControl.Controls.Add(buttonControl);
}
l += 55; j = 10;
}
}
I want to access each variable in arrayButtons[][]..like in a 3*3 matrix..if i want 2nd row 1 column element..then i get something like arrayname[2][1]..same way if i want 2nd button in 2nd row how can i get..i tried doing one way but i couldnt figure it out...Can you help me out with this..
What are you having difficulty with?
If you're running into bounds checking problems, you should know that C# arrays start at zero, not one. So the button in the second row, first column is a[1,0] not a[2,1]
If you Google Control Arrays in C# you will get several good matches, including this one.