I am using Migradoc and wish to replicate a table structure as follows:
What I really DON'T want to do is add each table into a cell of a larger table with 2 columns and 2 rows... Mainly because i) the number of tables generated can vary so it needs to be more dynamic and ii) Adding tables within tables can cause issues when spilling across to the next page.
What I had initially hoped is that I could just keep adding each new table to a TextFrame and the tables will be added horizontally and wrap to the next page if the next table wouldn't fit... Of course, not that straight forward. So far the closest I have come to even seeing a Table next to another one is with the following:
TextFrame newTF = new TextFrame
{
Width = Unit.FromPoint(200)
};
WrapFormat wf = new WrapFormat();
wf.Style = WrapStyle.Through;
newTF.WrapFormat = wf;
newTF.Add(newTable.Clone());
this.document.LastSection.Add(newTF);
TextFrame newTF2 = new TextFrame
{
Width = Unit.FromPoint(200)
};
WrapFormat wf2 = new WrapFormat();
wf2.Style = WrapStyle.Through;
newTF2.RelativeHorizontal = RelativeHorizontal.Page;
newTF2.RelativeVertical = RelativeVertical.Paragraph;
newTF2.Left = ShapePosition.Right;
newTF2.WrapFormat = wf2;
newTF2.Add(newTable.Clone());
this.document.LastSection.Add(newTF2);
However this is very static and would require a new definition for each TextFrame. Plus, the layout doesn't look amazing as the second table ignores any margins set out in the page.
If what I am asking is at all possible, am I even on the correct path? I have been looking into this all morning and am starting to feel my options sllipping away! I would have thought this would be a big requirement for a lot of Migradoc users so am surprised to find it is tricky to do? Unless I am just missing something silly of course.
Another option: create a table with 5 columns and set table borders to make it look like 2 tables with 2 columns each.
Depending on the data you add to the tables it might be better to use a table row for each line of text or have all text lines in a single row.
From your picture I assume that using a table with 2 columns and 1 row, each cell containing a table, would work, too, provided the visible tables are small enough to fit a single page.
Related
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.
This is my first post on here. I'm attempting to create a 'simple' charting program (windows form based in c#). I say simple because I'm currently only playing around with only 2 series maximum, and a few transformations (percent changes, actual changes, moving averages and moving sums). It will get more complicated than this but having the limited functionality first might help me get a better handle on how all of this works in C#.
I've been searching on and off for a couple of days now but have had no luck so far with my specific situation. I'll try to be as detailed as possible. The user retrieves the time series data from a SQL Server. This part of the program is behaving as expected. I'm creating 2 queries (one for each series) to retrieve the data separately. I do the transformations in the SQL query. Each comes via a SQL adapter which is then placed into a data table. The series may be of different frequencies and the dates may not overlap (i.e. sometimes a stock prices will be daily, and exports will be monthly, or GDP quarterly). The exports number may come in as the first of every month, while stock prices may be missing a value on this date if it was a weekend. I suspect this part is important for my issue.
Nonetheless, I double checked this step and everything works as expected (the values are all coming in correctly at the right dates).
To add those series to a chart, I merge the two data tables like so (I believe this is where my issues are coming from):
myTable = myTables1.Copy();
myTables1.PrimaryKey = new DataColumn[] { myTables1.Columns["dates"] };
myTables2.PrimaryKey = new DataColumn[] { myTables2.Columns["dates"] };
myTable.Merge(myTables2, true);
Datagridview of the Merged data table here looks good to me
Then I create the chart: I've tried two different methods here. The first is to create each series in a 2 step loop (one for each series) and loop through each row in the table and add an x and y value for each series. I've also tried to set the data source for the chart to be the table, and create 2 series and set the X and Y members as the names of the columns in the table.
Like so:
mychart.DataSource = myTable;
Then in a loop for each series:
mychart.Series.Add(seriesname);
mychart.Series[seriesname].XValueMember = "dates";
mychart.Series[seriesname].YValueMembers = seriesname;
Regardless, my second series is always a bit off. Either there are straight lines going across or it misses some values (and by adding a tool tip i can tell that the dates where one series may have a value while the other does not, is where the problems are occurring).
I'm not looking for help with syntax (just ideas). So my question is: is there a standard or preferred way of getting and plotting series with different frequencies (or which may have different x values)? Alternatively, is there a good source/documentation where i can read up on this? I would add that i have a similar program using visual basic which uses one SQL query regardless of how many series there are. This works in terms of the chart looking as I'd expect it to, but it makes transformations much more complicated given the randomness of the null or empty values in the final table.
So I'm dynamically creating a FlowDocument by using code (based on this MSDN article on How to build a table programatically).
The FlowDocument contains a number of blocks including paragraphs and tables. The tables being generated are of varying sizes and some are nested amongst other blocks. If a table can't fit on the remaining space on a page, I want to start that table at the beginning of the next page.
I am doing this by recording the current page when creating a particular block and then when the table has been finished, if I am on a new page, I set the BreakPageBefore property to true. Something like this:
foreach (var item in Data)
{
Table table = new Table();
flowDoc.Blocks.Add(table);
paginatorSource.DocumentPaginator.ComputePageCount();
pagecount = paginatorSource.DocumentPaginator.PageCount;
//do some work populating the table details...
TableColumn t = new TableColumn(); //etc...
paginatorSource.DocumentPaginator.ComputePageCount();
int newPagecount = paginatorSource.DocumentPaginator.PageCount;
if (newPagecount != pagecount)
{
//The table has spanned a new page so set the page break!
table.BreakPageBefore = true;
}
}
But this doesn't appear to work. However, if I wrap the table in a Section and set the BreakPageBefore on the section, it works fine. Also, If I have a Paragraph just before the table, I can set the BreakPageBefore on the Paragraph and that also works fine.
I have tried creating a simple FlowDocument that just has a bunch of repeating tables and that doesn't make any difference and I still have to wrap them in a Section.
They all inherit from Block So why won't it work on the Table directly?
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.
My program that I am writing's purpose arose with this issue:
There are two users, each user saves to a .MDB file. One user has half the updated / correct information (the other half is outdated) and the other user has half the information (the other half is outdated).
User1: 25% + 25% = 50% current information needed the other 50% is outdated
User1 works on 2 out of the 4 items.
User2: 25% + 25% = 50% current information needed the other 50% is outdated
User2 works on 2 out of the 4 items.
I need to take that 50% (2 out of the 4 items) from lets say...User1 and add it to User2 making it 100% current (4 out of 4 items).
Their SQL style table structure is (should be anyways) identical (but if possible I would like to provide an event where for some a new table was added I would know)
If I could find out how to get all the table names from the DataTable, I could systematically array through the DataTable and replace the tables with the tables from the other .MDB file that I know need to be updated. I know DataSet has "DataSet.Tables" ...but that doesn't help me very much.
If I can do that, I can also add the tables to a combo box and create functionality to where whatever the combo box says, thats the table I will list on my Datagrid.
If any of you have any ideas on how to go about doing this (or if you even understand what i'm saying) please let me know. I'm 70% done with ths project, and these seem to be my last logic road blocks. I think I explained this right.
How do I list just the Table names
in a DataTable object.
What are your ideas on taking specific Tables out of a .MDB file and adding them to another .MDB file?
How would I go about inputting a ComboList drop-down box that included all the tables names...when I changed the table name it would list those contents on a Datagrid.
Is there a way to list tables on a Datagrid, and when you click on a Table it lists the contents of that table (kind of like a Tree structure).
EDIT:
I think he is right! I think DataTables are just one table whereas DataSets are sets of Tables. With that in mind, how do I list all the tables in a .MDB file into a DataSet? That would fix my problem perfectly.
I thought that a DataTable object was only a single table and a DataSet was what contained one to many DataTables.
If you are looking for the actual name of your DataTable, that would be accessed through the DataTable.TableName property.
Edit: If you are wanting to add DataTables into a DataSet object, just create a new DataSet and then use the .Add() method.
Dim DS as new DataSet
Dim DT as new DataTable("TableName")
DS.Add(DT)
You should then be able to loop through your DataSet and retrieve table names by accessing each DataTable's TableName property:
For each table as DataTable in DS.Tables
Console.Writeline(table.TableName)
Next