Pie Chart Display member - c#

I'm using a pie chart in visual studio 2010 but I don't know how to set the values on display (the values that showed on each slice).
I need to use a different value member that the X and Y values.

In a Pie Chart you only need to use the Y-Values.
So if you have a DataSource data with a Y-Value called "value" you can use this to bind:
yourSeries.Points.DataBindY(data, "value");
You can also use this, more general binding method:
yourSeries.Points.DataBind(data, "", "value", "");
Note how the first, i.e. the X-Value is left empty; all points are always added indexed anyway. The last string otherfields would be for extended properties.
And there is even another way to bind the Points of a Series:
yourSeries.Points.DataBindXY(data, "somePropery", data, "value");
Note that here you can use two different data sources. But you can't leave the name string of the first one empty, even though the actual values will be ignored againm as with any Pie chart..
Besides binding the the Points you could also use other binding methods, see here for a discussion or the pros and cons..!
Also note that the first DataPoint, i.e. the first slice starts at 0°. If you want to start it at the top set a 'Custom attribute' : PieStartAngle :
yourSeries["PieStartAngle"] = "270";
To display the values you can set this:
yourSeries.IsValueShownAsLabel = true;
To move the labels off the slices use this:
yourSeries["PieLabelStyle"] = "Outside";

Related

Multiple Series from DataSet

I have a relatively simple problem, I want to display 2 simple line series in a Chart from a DataSet with 2 tables in it.
Right now I simply create a second series with the same ValueMembers but they are displayed on top of one another. The DataSet is filled correctly with different values.
dataAdapter.Fill(dataSetChart);
chartKunden.Series.Add("Kunden");
chartKunden.Series.Add("Table1");
chartKunden.Series["Kunden"].ChartType = SeriesChartType.Line;
chartKunden.Series["Table1"].ChartType = SeriesChartType.Column;
chartKunden.Series["Table1"].XValueMember = "Woche";
chartKunden.Series["Table1"].YValueMembers = "Stunden";
chartKunden.Series["Kunden"].XValueMember = "Woche";
chartKunden.Series["Kunden"].YValueMembers = "Stunden";
chartKunden.DataSource = dataSetChart;
I basically just want to know how to seperate them so the second series gets the data from the second table of the DataSet.
Updated DataBind:
chartKunden.Series["Table2"].Points.DataBind(dataSetChart.Tables[1].Rows, "Woche", "Stunden", "");
chartKunden.Series["Table1"].Points.DataBind(dataSetChart.Tables[0].Rows, "Woche", "Stunden", "");
There are many ways to do databinding.
You can bind each Series to a separate data source for example like so:
s1.XValueMember = "col11";
s1.YValueMembers = "col12";
s2.XValueMember = "col21";
s2.YValueMembers = "col22";
s1.Points.DataBind(t1.Rows, "col11", "col12", "");
s2.Points.DataBind(t2.Rows, "col21", "col22", "");
This assumes a two DataTables t1 and t2 with Columns "col11", "col12" and "col21", "col22".
Note the empty string as last parameter. Here one can add a list of comma-separated custom properties to add to the binding. Example:
s1.Points.DataBind(t1.Rows, "col11", "col12", "Tooltip=colcom1");
See here for a duscussion of limitations for this!
Also note that this binding overload needs to find x- and y-values in the same data source. Check out the overview of bindings above for even more flexible ways!!
A simple example to bind x- and y-values to different sources could be written as:
s2.Points.DataBindXY(t2.Rows, "col21", t1.Rows, "col12");
Note that now we can't set extended properties!
Okay I think I could narrow down the problem, I draw the Chart in 2 different ways depending on a CheckButton, usually I draw the other version first, but now I draw the version with the mistake first and the data is now displayed correctly.
I thought I cleared the Chart and DataSet properly before adding the new Values but doesn't seem to be the case, I will further look into this.

Updating Grid items in a List

I have a list of Grid items called gridCache.
I have a TabItem called ti.
This line of code:
gridCache.Last().Name = ti.Name;
...is updating the Name property of every single Grid item in the list. It should just be updating the last item's Name property.
Why is it doing this?
Maybe I'm rubberducking here, but I've followed it through a break point while debugging and they all just update simultaneously when this line is called.
EDIT: I'd like to basically make 'copies' of flyGrid as it's modified to store them for later use. The idea is to use this to cache data from some SQL calls. Here's what I'm trying:
//some stuff that defines flyGrid
Grid cacheGrid = new Grid();
cacheGrid = flyGrid;
cacheGrid.Name = ti.Name;
gridCache.Add(cacheGrid);
After this recurs 3 or 4 times, the Name property of every item in the list is always the last name supplied.
How can I make a copy of flyGrid that is its own instance each time this code recurs?
SOLUTION EDIT:
I ended up solving the root problem in a completely different way. The idea was to get cached ReportParameterInfoCollection items to keep from talking to the database constantly.
I ended up creating a simple class for an object with two properties: one random string of letters, and a list of ReportParameterInfoCollection items.
This allowed me to populate this list as tabs are opened, and assign these tabs unique IDs that match the parameter information stored in this list of objects.
I didn't really solve the question, so I decided not to post this as an answer.
That would happen if every Grid is the same instance.
Make sure you're actually creating multiple instances when populating the list.

Interop - Setting a range for an Excel chart to an entire row

How do I set the source data of an excel interop chart to several entire rows?
I have a .csv file that is created by my program to display some results that are produced. For the sake of simplicity let's say these results and chart are displayed like this: (which is exactly how I want it to be)
Now the problem I am having is that the number of people is variable. So I really need to access the entire rows data.
Right now, I am doing this:
var range = worksheet.get_range("A1","D3");
xlExcel.ActiveChart.SetSourceData(range);
and this works great if you only have three Persons, but I need to access the entire row of data.
So to restate my question, how can I set the source data of my chart to several entire rows?
I tried looking here but couldn't seem to make that work with rows instead of columns.
var range = worksheet.get_range("A1").CurrentRegion;
xlExcel.ActiveChart.SetSourceData(range);
EDIT: I am assuming that the cells in the data region won't be blank.
To test this,
1) place cursor on cell A1
2) press F5
3) click on "Special"
4) choose "Current Region" as option
5) click "OK"
This will select the cells surrounding A1 which are filled, which I believe is what you are looking for.
The translation of that in VBA code points to CurrentRegion property. I think, that should work.
Check Out the option Range.EntireRow I'm not 100% on how to expand that to a single range containing 3 entire rows, but it shouldn't be that difficult to accomplish.
Another thing you can do is scan to get the actual maximum column index you need (this is assuming that there are guaranteed to be no gaps in the names), then use that index as you declare your range.
Add Code
int c = 2;//column b
while(true)
{
if (String.IsNullOrEmpty(worksheet.GetRange(1,c).Value2))
{
c--;
break;
}
c++;
}
Take a column from A to D that you're sure has no empty cells.
Do some loop to find the first empty one in that column and it will be one after the last.
Range Cell = SHeet.Range["A1"]; //or another column you're sure there's no empty data
int LineOffset = 0;
while (Cell.Offset[LineOffset, 0].Value != "") //maybe you should cast the left side to string, not sure.
{
LineOffset++;
}
int LastLine = LineOffset - 1;
Then you can get Range[Sheet.Cells[1,1], Sheet.Cells[LastLine, 4]]
Out of the box here, but why not transpose the data? Three columns for Name, Height, Weight. Convert this from an ordinary range to a Table.
When any formula, including a chart's SERIES formula references a column of a table, it always references that column, no matter how long the table gets. Add another person (another row) and the chart displays the data with the added person. Remove a few people, and the chart adjusts without leaving blanks at the end.
This is illustrated in my tutorial, Easy Dynamic Charts Using Lists or Tables.

How to call a textbox dynamically from a string C# WPF?

So I have 70 "nodes" which are all textboxes in WPF and I'm trying to change the value in the textbox from a function call.
I have a function called:
private void changeNode(int row, int column, int cost)
{
int nodeNumber= row * 10 + column;
call node"nodeNumber".Text = Convert.String(cost);
//example node0.Text = Convert.String(cost);
}
I determine what node I want to change then call nodeX.Text to change it however I want X to be a variable that I can rather than having to create 70 cases where I call the appropriate textbox.
I saw a couple of ways of doing this with reflection however it seemed to only work if the function had no parameters and also was within the function not a textbox in XAML.
Let me know if there is a simple way to convert say a string "node37" to call node37.Text = cost or something like that.
Sounds like your approach is wrong. Why do you have a set of strings which represent the names of the textboxes? You should instead have in-memory references to TextBox objects. If you have more than one, and you don't know how many there will be, then use an array of TextBox objects instead. You can index into the array with the number that represents the textbox you're looking to interact with.
Avoid the use of reflection, it is completely unnecessary here.
I assume you have put names for all your textboxes (you can do this dynamically if you haven't). Then you can use the answers for this question to find the appropriate control by name.
Are all your textboxes children of the same canvas or other control? Loop through the children and add the controls to a dictionary. Parse the name to get the number and use that as the key.
It is always better to use List when you are dealing with Data. Create an ObservableCollection with the DataObjects which you want to load, and now deal with the Data object rather than actual Controls.
In WPF, if you follow the rules, you should not point to the actual object. Check the sample application here :
http://www.abhisheksur.com/2010/08/woring-with-icollectionviewsource-in.html
I think you will get the approach.

displaying enumeration values in a DataGridComboBox problem

I have a dll that has a class called Series. This class has a field which is an enumeration of DataTypes. I am binding the datagrid to a list of objects of this class, and I am able to display the enumeration values in a combobox fashion
However, the values' names don't make a lot of sense. For example, I want to display 'prc' as 'price' and still represent the correct object value.
this is what I currently do
this.seriesDataTypeColumn.Items.AddRange(new object[] {
MuDBLayer.DataType.mv,
MuDBLayer.DataType.vol,
MuDBLayer.DataType.num,
MuDBLayer.DataType.prc,
MuDBLayer.DataType.Composite});
mv, vol, num and prc are displayed in the datagridcomboboxes.
I wanna display
money value, volume, number, and price instead
any ideas?
Description attribute cannot be localized. Do take a look at this reply.
Can my enums have friendly names?
Take a look at https://msmvps.com/blogs/deborahk/archive/2009/07/10/enum-binding-to-the-description-attribute.aspx or http://blogs.freshlogicstudios.com/Posts/View.aspx?Id=388f7d39-0b90-43bc-b03a-c1f605dfb499. You can add a Description attribute to your enums to display a more friendly value.
You might also find some more information in this related question How to bind a custom Enum description to a DataGrid.

Categories

Resources