I have a small test program that creates a DataTable with 1M rows.
Then I add a calculated column (Expression column), it's super fast like a second.
Then I just try to add a new column and set values to it, it takes more than 10 seconds.
DataTable update is slow. How can I make it as fast as calculated column?
10 seconds does seem acceptable but that is just a test program to show the difference.
This can become worst depending on how many rows, columns, etc.
Anyway if calculated column is able to do it that fast, hopefully we can get same performance with normal updates.
It seems calculated columns is able to turn off some notifications or other things. I'm not sure.
Any idea? Advice? Maybe I'm missing something when updating the DataTable.
Thanks in advance
Below is the code sample I'm using:
using System;
using System.Data;
namespace Test1
{
class Program
{
static void Main(string[] args)
{
try
{
System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
watch.Start();
Console.WriteLine("DataTable creation started ...");
DataTable data = new DataTable();
int nbrCols = 50;
for (int i = 0; i < nbrCols; i++)
{
data.Columns.Add(string.Concat("COL_", (i + 1)), typeof(double));
}
System.Random r = new System.Random();
data.BeginLoadData();
int nbrows = 1000000;
for (int i = 0; i < nbrows; i++)
{
DataRow newRow = data.NewRow();
for (int j = 0; j < nbrCols; j++)
{
newRow[j] = r.NextDouble();
}
data.Rows.Add(newRow);
}
data.EndLoadData();
watch.Stop();
Console.WriteLine("DataTable creation = " + watch.ElapsedMilliseconds / 1000.0);
int colIndexFlow1 = data.Columns.IndexOf("COL_1");
int colIndexFlow2 = data.Columns.IndexOf("COL_2");
/* Add a calculated columns */
watch.Restart();
data.Columns.Add("CALC_1", typeof(double), "COL_1 + COL_2");
data.AcceptChanges();
watch.Stop();
Console.WriteLine("Calculated Column creation = " + watch.ElapsedMilliseconds / 1000.0);
/* Add a new column */
watch.Restart();
data.BeginLoadData();
data.Columns.Add("NEW_1", typeof(double));
int colIdx = data.Columns.IndexOf("NEW_1");
foreach (DataRow row in data.Rows)
{
//double val = row.Field<double>("COL_1") + row.Field<double>("COL_2");
//row.SetField<double>(colIdx, val);
// Most of the time is spent to actually set the data
// Question is how can we make the update happening as fast as the update done when using a calculated column.
row.SetField<double>(colIdx, 2.0);
}
data.AcceptChanges();
data.EndLoadData();
watch.Stop();
Console.WriteLine("New Column creation = " + watch.ElapsedMilliseconds / 1000.0);
}
catch (Exception ex)
{
Console.WriteLine("Error=" + ex.Message);
}
finally
{
Console.ReadLine();
Console.WriteLine("Press any key to exit");
}
}
}
}
I'm having trouble building a dashboard in WP8.1.
I'm using the MVVM Light toolkit.
I'm looking after this outcome:
screenshot of dashboard
I can currently build a dashboard but only with one object per row.
I've searched a lot but haven't found anything to get the desired effect.
Here's the code of the dashboard done programatically:
int i = 0;
Grid grid = new Grid();
grid.RowDefinitions.Add(new RowDefinition());
for (int ct = 0; ct < 3; ct++)
grid.ColumnDefinitions.Add(new ColumnDefinition());
StackPanel stackPanel = new StackPanel();
stackPanel.Name = "stackPanel";
stackPanel.Background = new SolidColorBrush(new Windows.UI.Color());
foreach (var flow in dashboard.DashboardFlows)
{
if (flow.Flow.IsInstalled)
{
//if next object should change line
if (i == 3)
{
stackPanel.Children.Add(grid);
grid = new Grid();
grid.RowDefinitions.Add(new RowDefinition());
for (int ct = 0; ct < 3; ct++)
grid.ColumnDefinitions.Add(new ColumnDefinition());
i = 0;
}
Button button = new Button();
if (flow.Flow.Type.Equals("COMPNEWS"))
{
button.Click += delegate { Frame.Navigate(typeof(NewsPage), flow); };
}
//button stackpanel
StackPanel stack = new StackPanel();
//Button image
Image buttonImage = new Image();
if (!String.IsNullOrEmpty(flow.Flow.IconUrl) || !String.IsNullOrWhiteSpace(flow.Flow.IconUrl))
buttonImage.Source = new BitmapImage(new Uri(flow.Flow.IconUrl));
buttonImage.Height = 45;
buttonImage.VerticalAlignment = VerticalAlignment.Top;
stack.Children.Add(buttonImage);
//Button name
TextBlock buttonName = new TextBlock();
buttonName.Text = flow.Flow.Name;
buttonName.FontSize = 12;
buttonName.TextWrapping = TextWrapping.Wrap;
stack.Children.Add(buttonName);
button.Content = stack;
button.Margin = new Thickness(5, 0, 5, 0);
button.SetValue(Grid.ColumnProperty, i);
button.SetValue(Grid.RowProperty, 0);
button.HorizontalAlignment = HorizontalAlignment.Stretch;
button.VerticalAlignment = VerticalAlignment.Stretch;
button.Background = new SolidColorBrush(Color.FromArgb(130, 30, 30, 30));
grid.Children.Add(button);
i++;
}
}
scroll.Content = stackPanel;
Thank you in advance.
where allValues is array list and i am creating 5 column table.So help me to implement text click event on each text of each cell.I searched and found click event of table row but by this way i am not able to implement cell click event in table layout.
TableLayout tl = (TableLayout) findViewById(R.id.tlparent);
for (int j = 0, k = 0; j < allValues.size() / 5; j++)
{
final TableRow tableRow = new TableRow(this);
for (int y = 1; y <= 5; y++)
{
TextView tv = new TextView(this);
tv.setText(allValues.get(k));
tableRow.addView(tv);
k++;
}
tl.removeView(tableRow);
tl.addView(TABROW);
}
Simply add an onClickListener to your TextView:
TextView tv = new TextView(this);
tv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
TextView tv = (TextView) v;
String text = tv.getText().toString();
// process your text
}
});
If you want to pass your table "coordinates" (j,k,y, etc.) to your calling function, make additional final variables before setting the OnClickListener and use these inside the onClick method.
How to put a subtotal in multiple cells?
AggregationSubtotalBuilder totalBase = sbt.sum(total_, config.getColumn("base").getCol());
AggregationSubtotalBuilder member_count = sbt.text("Total Employes :", config.getColumn("code").getCol());
jrb.subtotalsAtGroupFooter( emp_number_group, member_count, totalBase );
Worked with some tricks
Class ComponentPosition
private static void recalculateWidth(String name, DRDesignList list, int availableWidth) throws DRException {
for (int i=0;i<list.getListCells().size();i++) {
DRDesignListCell listCell = list.getListCells().get(i);
DRDesignComponent component = listCell.getComponent();
if (component instanceof DRDesignList){
for (DRDesignComponent cp : ((DRDesignList)component).getComponents()){
Integer colSpan = colSpans.get( cp.getName() );
if (colSpan!=null){
int w = 0;
for (int j=0;j<colSpan;j++){
w += list.getListCells().get(i+j).getComponent().getWidth();
list.getListCells().get(i+j).getComponent().setWidth(0);
}
cp.setWidth(w);
component.setWidth(w);
}
}
}
}
Then ComponentPosition.colSpans.put(memeber_count.getName(), 3);
I am new be in RCP development.
I want to create two tables with, each table contains different data.
Data from two tables have either 1 to 1 , 1 to many or many to 1 relationship.
And that can be done by drawing arrows between two tables.
For example,
**Row 1** **Row 2**
R1 V1 R2 V1
R1 V2 R2 V2
R1 V3 R2 V3
I want to draw arrows from R1V1 to ( R2V1 and R2V3 ) or vice a versa.
How can I show it graphically.
How can I find that which rows are combined by arrows.
Any help is appreciated.
--- Mandar
Here is the code that is based on the idea proposed by Nick. It is just to give an idea for someone who might wonder where to start to implement something like this shown below
This would let you click on any column on the left hand side table, then draws a line as your mouse moves on towards the right table, and anchors the line as soon as a column on the right hand side table is selected. It keeps a mapping between the left table row and right table row in a linked list as the mapping data model.
package sample;
import java.util.LinkedList;
import org.eclipse.draw2d.AutomaticRouter;
import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.FreeformLayeredPane;
import org.eclipse.draw2d.FreeformLayout;
import org.eclipse.draw2d.LightweightSystem;
import org.eclipse.draw2d.MarginBorder;
import org.eclipse.draw2d.PolylineConnection;
import org.eclipse.draw2d.PolylineDecoration;
import org.eclipse.draw2d.XYAnchor;
import org.eclipse.draw2d.geometry.PointList;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
public class GraphicTableMapper {
private static Point sourcePosition;
private static PathFigure currentPath;
private static Figure bf;
private static Canvas canvas;
private static int sourceRow;
private static int targetRow;
private static LinkedList<RowMapper> rowmapList = new LinkedList<RowMapper>();
public static void main(String[] args) {
Display display = Display.getDefault();
final Shell shell = new Shell(display);
shell.setSize(550, 500);
shell.setLayout(new GridLayout(3, false));
final Table table = new Table(shell, SWT.MULTI | SWT.BORDER
| SWT.FULL_SELECTION);
table.setLinesVisible(true);
table.setHeaderVisible(true);
final String[] titles = { "Serial Number", "Whatever" };
for (int i = 0; i < titles.length; i++) {
TableColumn column = new TableColumn(table, SWT.NONE);
column.setText(titles[i]);
}
int count = 100;// create 100 rows in table
for (int i = 0; i < count; i++) {
TableItem item = new TableItem(table, SWT.NONE);
item.setText(0, "x");
item.setText(1, "y");
item.setText(2, "!");
item.setText(3, "this stuff behaves the way I expect");
item.setText(4, "almost everywhere");
item.setText(5, "some.folder");
item.setText(6, "line " + i + " in nowhere");
}
for (int i = 0; i < titles.length; i++) {
table.getColumn(i).pack();
}
table.addListener(SWT.MouseDown, new Listener() {
public void handleEvent(Event event) {
Point pt = new Point(event.x, event.y);
TableItem item = table.getItem(pt);
if (item == null)
return;
for (int i = 0; i < titles.length; i++) {
Rectangle rect = item.getBounds(i);
if (rect.contains(pt)) {
int index = table.indexOf(item);
System.out.println("Item " + index + "-" + i);
sourcePosition = pt;
sourceRow = index;
currentPath = new PathFigure();
currentPath.setSourceAnchor(new XYAnchor(
new org.eclipse.draw2d.geometry.Point(-10,
event.y)));
currentPath
.setTargetAnchor(new XYAnchor(
new org.eclipse.draw2d.geometry.Point(
0, pt.y)));
bf.add(currentPath);
}
}
}
});
table.addMouseMoveListener(new MouseMoveListener() {
public void mouseMove(MouseEvent arg0) {
if (currentPath != null) {
((XYAnchor) (currentPath.getTargetAnchor()))
.setLocation(new org.eclipse.draw2d.geometry.Point(
0, arg0.y));
}
}
});
canvas = new Canvas(shell, SWT.None);
canvas.setBackground(shell.getDisplay().getSystemColor(SWT.COLOR_GREEN));
LightweightSystem lws = new LightweightSystem(canvas);
bf = new BaseFigure();
lws.setContents(bf);
canvas.addMouseMoveListener(new MouseMoveListener() {
public void mouseMove(MouseEvent arg0) {
if (currentPath != null) {
((XYAnchor) (currentPath.getTargetAnchor()))
.setLocation(new org.eclipse.draw2d.geometry.Point(
arg0.x > canvas.getSize().x - 5 ? canvas
.getSize().x - 5 : arg0.x, arg0.y));
}
}
});
GridData data2 = new GridData();
data2.verticalAlignment = SWT.TOP;
data2.grabExcessHorizontalSpace = false;
data2.grabExcessVerticalSpace = true;
data2.horizontalIndent = -10;
data2.widthHint = 200;
data2.heightHint = 1000;
canvas.setLayoutData(data2);
final Table table2 = new Table(shell, SWT.MULTI | SWT.BORDER
| SWT.FULL_SELECTION);
table2.setLinesVisible(true);
table2.setHeaderVisible(true);
data2 = new GridData();
data2.grabExcessHorizontalSpace = false;
data2.horizontalIndent = -10;
table2.setLayoutData(data2);
final String[] titles2 = { "Serial Number", "Whatever" };
for (int i = 0; i < titles.length; i++) {
TableColumn column = new TableColumn(table2, SWT.NONE);
column.setText(titles[i]);
canvas.redraw();
}
table2.addMouseMoveListener(new MouseMoveListener() {
public void mouseMove(MouseEvent event) {
if (currentPath != null) {
Point pt = new Point(event.x, event.y);
TableItem item = table2.getItem(pt);
if (item == null)
return;
for (int i = 0; i < titles2.length; i++) {
Rectangle rect = item.getBounds(i);
if (rect.contains(pt)) {
((XYAnchor) (currentPath.getTargetAnchor()))
.setLocation(new org.eclipse.draw2d.geometry.Point(
canvas.getSize().x - 5, event.y));
}
}
}
}
});
int count2 = 100;// create 100 rows in table 2
for (int i = 0; i < count2; i++) {
TableItem item = new TableItem(table2, SWT.NONE);
item.setText(0, "x");
item.setText(1, "y");
item.setText(2, "!");
item.setText(3, "this stuff behaves the way I expect");
item.setText(4, "almost everywhere");
item.setText(5, "some.folder");
item.setText(6, "line " + i + " in nowhere");
}
for (int i = 0; i < titles.length; i++) {
table2.getColumn(i).pack();
}
table2.addListener(SWT.MouseDown, new Listener() {
public void handleEvent(Event event) {
try {
Point pt = new Point(event.x, event.y);
TableItem item = table2.getItem(pt);
if (item == null)
return;
for (int i = 0; i < titles2.length; i++) {
Rectangle rect = item.getBounds(i);
if (rect.contains(pt)) {
int index = table2.indexOf(item);
targetRow = index;
System.out.println("Item " + index + "-" + i);
if (sourcePosition != null) {
add(event);
}
}
}
} finally {
sourcePosition = null;
sourceRow = -1;
targetRow = -1;
}
}
});
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
}
public static void add(Event event) {
bf.remove(currentPath);
PathFigure figure = new PathFigure();
figure.setSourceAnchor(currentPath.getSourceAnchor());
figure.setTargetAnchor(currentPath.getTargetAnchor());
bf.add(figure);
currentPath = null;
RowMapper mapper = new RowMapper();
mapper.sourceRow = sourceRow;
mapper.targetRow = targetRow;
if (!rowmapList.contains(mapper)) {
rowmapList.add(mapper);
}
}
class BaseFigure extends FreeformLayeredPane {
public BaseFigure() {
setLayoutManager(new FreeformLayout());
setBorder(new MarginBorder(5));
setBackgroundColor(ColorConstants.white);
setOpaque(true);
}
}
class PathFigure extends PolylineConnection {
public PathFigure() {
setTargetDecoration(new PolylineDecoration());
setConnectionRouter(new AutomaticRouter() {
#Override
protected void handleCollision(PointList list, int index) {
}
});
}
}
class RowMapper {
int sourceRow;
int targetRow;
#Override
public boolean equals(Object obj) {
if (obj instanceof RowMapper) {
RowMapper mapper = (RowMapper) obj;
return (sourceRow == mapper.sourceRow && targetRow == mapper.targetRow);
}
return false;
}
}
This is quite a difficult component to implement, I did one of these for Tibco Business Studio some time ago.
You'll need to place a Canvas between your two tables to draw the links on. You presumably have data models for your two tables, you'll also need a third model for storing the links and ensure that any modifications to this model trigger a refresh of the Canvas.
Next add drag and drop support to the two tables, dropping an item from table 1 onto table 2 should create a new item in your link model (thus triggering a Canvas refresh to draw the link).
Actually drawing the links in the right locations you'll have to work out yourself, but hopefully this gives you some ideas to start with.
Am I right in thinking that this implementation uses the mouse location to draw the arrows? So if you wanted to save / load a relationship you would have to save the x,y positions of the arrows and you'd have to make sure your components always stayed the same size?