Object to arraycollection - apache-flex

linedataColl is an AC that contains 100+ of rows extract from CSV, I wish to add item into SuperDataCollection object by object but the only problem was I'm unable to see any data display in "S" which is a datagrid. What wrong with my code?
var superDataCollection:ArrayCollection = new ArrayCollection();
var dc:ArrayCollection = new ArrayCollection();
var di:Object = new Object();
for(var aa:int=0; aa<5;aa++){
di.username = linedataColl[aa].username;
di.email = linedataColl[aa].email;
dc.addItem(di);
superDataCollection.addItem(dc);
}
s.dataProvider = dc;
For my datagrid:
var columns:Array = [];
var myDataGridColumn:DataGridColumn = new DataGridColumn("id");
myDataGridColumn.headerText = "ID";
myDataGridColumn.width = 40;
columns.push(myDataGridColumn);
... // so on for other column
dg1.columns = columns;

I Found Two thing wrong in your code
1) Declare di in For loop, new instance for each iteration
for(var aa:int=0; aa<5;aa++){
var di:Object = new Object();
2) You are not defining proper dataField for DataGridColumn, although you are passing id in constructor, but i didn't find it in upper code you share,it could be
di.id = aa
or
myDataGridColumn.headerText = "ID";
myDataGridColumn.width = 40;
myDataGridColumn.dataField = "username";
Hopes that helps

Related

Linechart show info on point tapped

I'm implementing a little app with Xamarin Forms for a web page, the thing is that in this web is a linear chart with multiple entries and if the user clicks on a point of the line shows info about that point, as you can see in the picture:
Web Line Chart
After some work, I could create a more or less similar line chart using the OxyPlot.Xamarin.Forms plugin with multiple entries which shows the points
My App Line Chart
This is my code:
OnPropertyChanged("GraphModel");
var model = new PlotModel
{
LegendPlacement = LegendPlacement.Outside,
LegendPosition = LegendPosition.BottomCenter,
LegendOrientation = LegendOrientation.Horizontal,
LegendBorderThickness = 0
};
model.PlotType = PlotType.XY;
model.InvalidatePlot(false);
Dictionary<string, List<Prices>> values = HistoricData[Selected.ProductId];
int colorIndex = 0;
List<string> x_names = new List<string>();
foreach (var item in values.Keys)
{
if (item.ToUpper() == Selected.ProductName) { SelectedIndex = colorIndex; }
var lineSeries = new LineSeries()
{
Title = item,
MarkerType = MarkerType.Circle,
};
lineSeries.MarkerResolution = 3;
lineSeries.MarkerFill = OxyPlot.OxyColor.Parse(SubCategoriesViewModel.AvailableColors[colorIndex]);
lineSeries.MarkerStroke = OxyPlot.OxyColor.Parse(SubCategoriesViewModel.AvailableColors[colorIndex]);
lineSeries.MarkerSize = 3;
var points = new List<DataPoint>();
lineSeries.Color = OxyColor.Parse(SubCategoriesViewModel.AvailableColors[colorIndex]);
foreach (var price in values[item])
{
points.Add(new DataPoint(price.Week+price.Year, price.Price));
}
if (ButtonsVisibility.Count == 0)
{
lineSeries.IsVisible = (Selected.ProductName == item.ToUpper()) ? true : false;
}
else
{
lineSeries.IsVisible = ButtonsVisibility[colorIndex];
}
lineSeries.ItemsSource = points;
lineSeries.MarkerType = OxyPlot.MarkerType.Circle;
model.Series.Add(lineSeries);
colorIndex++;
}
NumButtons = colorIndex;
LinearAxis yaxis = new LinearAxis();
yaxis.Position = AxisPosition.Left;
yaxis.MajorGridlineStyle = LineStyle.Dot;
model.Axes.Add(yaxis);
LineChart = model;
OnPropertyChanged("GraphModel");
return LineChart;
My doubt is which property I should work with and show at least the value of a concrete point, I have seen the property OnTouchStarted but is only for all the LineSeries and not for a single point. I read in some articles that OxyPlot.Xamarin.Forms include a tracker. I added this line in my code:
lineSeries.TrackerFormatString = "X={2},\nY={4}";
Is supposed to show the x and y values on click but doesn't show anything, any suggestion?
Should show something like that: Tracker info on point
From the following example: Tracker Example
Updated Code
public PlotModel GetLineChart()
{
OnPropertyChanged("GraphModel");
var model = new PlotModel
{
LegendPlacement = LegendPlacement.Outside,
LegendPosition = LegendPosition.BottomCenter,
LegendOrientation = LegendOrientation.Horizontal,
LegendBorderThickness = 0
};
model.PlotType = PlotType.XY;
model.InvalidatePlot(false);
Dictionary<string, List<Prices>> values = HistoricData[Selected.ProductId];
int colorIndex = 0;
List<string> x_names = new List<string>();
foreach (var item in values.Keys)
{
if (item.ToUpper() == Selected.ProductName) { SelectedIndex = colorIndex; }
var lineSeries = new LineSeries()
{
Title = item,
MarkerType = MarkerType.Circle,
CanTrackerInterpolatePoints = false
};
lineSeries.MarkerResolution = 3;
lineSeries.MarkerFill = OxyPlot.OxyColor.Parse(SubCategoriesViewModel.AvailableColors[colorIndex]);
lineSeries.MarkerStroke = OxyPlot.OxyColor.Parse(SubCategoriesViewModel.AvailableColors[colorIndex]);
lineSeries.MarkerSize = 3;
var points = new List<DataPoint>();
lineSeries.Color = OxyColor.Parse(SubCategoriesViewModel.AvailableColors[colorIndex]);
foreach (var price in values[item])
{
points.Add(new DataPoint(price.Week+price.Year, price.Price));
}
if (ButtonsVisibility.Count == 0)
{
lineSeries.IsVisible = (Selected.ProductName == item.ToUpper()) ? true : false;
}
else
{
lineSeries.IsVisible = ButtonsVisibility[colorIndex];
}
lineSeries.ItemsSource = points;
lineSeries.MarkerType = OxyPlot.MarkerType.Circle;
lineSeries.TrackerFormatString = "X={2},\nY={4}";
lineSeries.TextColor = OxyPlot.OxyColor.Parse(SubCategoriesViewModel.AvailableColors[colorIndex]);
model.Series.Add(lineSeries);
colorIndex++;
}
NumButtons = colorIndex;
LinearAxis yaxis = new LinearAxis();
yaxis.Position = AxisPosition.Left;
//yaxis.StringFormat = "X={2},\nY={4}";
yaxis.MajorGridlineStyle = LineStyle.Dot;
model.Axes.Add(yaxis);
LineChart = model;
OnPropertyChanged("GraphModel");
return LineChart;
}
}
protected async override void OnAppearing()
{
await _viewModel.LinearViewModel.GetSubCategoryHistoricWeekPrices(App.ViewModel.LoginViewModel.SesionToken, FROM_DATE, TO_DATE);
Plot.Model = _viewModel.LinearViewModel.GetLineChart();
PlotController controller = new PlotController();
controller.UnbindAll();
controller.BindTouchDown(PlotCommands.PointsOnlyTrackTouch);
Plot.Controller = controller;
AddButtons();
}
Xaml Declaration for plot view:
<oxy:PlotView
Grid.Row="2"
Grid.RowSpan="2"
Grid.ColumnSpan="4"
x:Name="Plot" />
Your problem lies with following line.
lineSeries.TrackerKey = "X={2},\nY={4}";
When you use series.TrackerKey, you are specifying that you are using a CustomTracker, which in this case you are not. Custom trackers would be useful if you need to use different trackers for each series in the model.
In you case, you should remove that line and use only TrackerFormatString.
lineSeries.TrackerFormatString = "X={2},\nY={4}";
This would show the tooltip using the format string parameters, where {2} signifies X Value and {4} signifies Y. For your information, following are place holders.
{0} = Title of Series
{1} = Title of X-Axis
{2} = X Value
{3} = Title of Y-Axis
{4} = Y Value
If you need to include additional/custom information in your tool, your Data Point needs to be include that information. This where IDataPointProvider interface becomes handy. You could create a Custom DataPoint by implementing the interface and then you could include the same information in your tooltip as well.
Update Based On Comments
Additionally, to include "Touch", you can specify TouchDown in the PlotController. You can do so by defining the PlotController in your viewModel as following.
public PlotController CustomPlotController{get;set;}
You can define the property as follows.
CustomPlotController = new PlotController();
CustomPlotController.UnbindAll();
CustomPlotController.BindTouchDown(PlotCommands.PointsOnlyTrackTouch);
And in your Xaml
<oxy:Plot Controller="{Binding CustomPlotController}"......

Join two dynamic Linq in Asp.net

I have used linq to store data, below is the code:
var result = (dynamic)null;
var serviceData = (dynamic)null;
var userData = (dynamic)null;
/****Linq 1*****/
serviceData= dtPasscode.AsEnumerable().Select(m => new
{
ACCOUNT_ID = intAccountId,
SUB_ACC_ID = m.Field<string>("ACCOUNT_ID_ALIAS")
});
/**Linq 2**/
userData = DisplyCustomerDetails(Convert.ToInt64(strSubAccountID));
result = serviceData.Concat(userData);
And another linq through function:
/**Function**/
System.Data.EnumerableRowCollection DisplyCustomerDetails(Int64 intAccountId)
{
var result = (dynamic)null;
/** Data Display if no service avaiable **/
IAccount_BL objAccount_BL = new Account_BL();
Customer objCustomer = new Customer();
DataTable dtCustomer = null;
int intErrorCount = 0;
objCustomer.Account_Id = Convert.ToInt64(intAccountId);
dtCustomer = objAccount_BL.GetCustomerDetails(objCustomer, ref intErrorCount);
objAccount_BL = null;
objCustomer = null;
if (intErrorCount == 0)
{
if (dtCustomer != null)
{
if (dtCustomer.Rows.Count > 0)
{
result = dtCustomer.AsEnumerable().Select(m => new
{
ACCOUNT_ID = intAccountId,
SUB_ACC_ID = m.Field<string>("ACCOUNT_ID_ALIAS")
});
}
}
}
return result;
}
I wanted to join both the result of Linq1 & Linq2, I tired Concat & Union, getting below error
'System.Data.EnumerableRowCollection<<>f__AnonymousTypea>' does not contain a definition for 'Concat'
To Concat both enumerables must of the same class; you cannot use anonymous classes. Define a class that has the two fields and change the code to Select them.
Also, don't use ... = (dynamic) null; just assign the variable directly
var serviceData= dtPasscode ...
var userData = DisplyCustomerDetails ...
var result = serviceData.Concat(userData);

In DevExpress xtra reports, I would like to increase height of table dynamically

In devexpress report, I have two tables. Based on content T2 table height increases, based on T1 height should be set.
I tried to set height in BeforePrint, AfterPrint, SizeChanged, TextChanged events of T2 and also DataSourceChanged event of report, as follows, added image for reference.
T1.HeightF = T2.HeightF;
or
T1.SizeF = new SizeF(T1.WidthF, T2.HeightF);
But above ways didn't work out.
Any idea how to set height of table dynamically?
You can set XRControl.AnchorVertical property of your table to VerticalAnchorStyles.Both value, so your table will be always attached to sides of its container.
xrTable1.AnchorVertical = VerticalAnchorStyles.Both;
Here is example:
var source = new List<Tuple<string>>()
{
new Tuple<string>("Text"),
new Tuple<string>("Some\ntext"),
new Tuple<string>("Some long long\nlong long long\nlong long long text.")
};
var cell = new XRTableCell();
cell.Text = "Just table";
var someCell = new XRTableCell();
someCell.Text = "Some text";
var anotherCell = new XRTableCell();
anotherCell.Text = "Another cell text";
var contentCell = new XRTableCell();
contentCell.DataBindings.Add(new XRBinding("Text", null, "Item1"));
contentCell.Multiline = true;
var anotherContentCell = new XRTableCell();
anotherContentCell.Text = "Content table";
var row = new XRTableRow();
row.Cells.AddRange(new[] { cell, someCell, anotherCell });
var contentRow = new XRTableRow();
contentRow.Cells.AddRange(new[] { contentCell, anotherContentCell });
var table = new XRTable();
table.Rows.Add(row);
table.Borders = DevExpress.XtraPrinting.BorderSide.All;
table.AnchorVertical = VerticalAnchorStyles.Both;
var contentTable = new XRTable();
contentTable.Rows.Add(contentRow);
contentTable.Borders = DevExpress.XtraPrinting.BorderSide.All;
contentTable.LeftF = 350F;
var panel = new XRPanel();
panel.HeightF = contentTable.HeightF = table.HeightF = 15F;
panel.WidthF = 650F;
panel.Controls.AddRange(new[] { table, contentTable });
var detail = new DetailBand();
detail.HeightF = 30F;
detail.Controls.Add(panel);
var report = new XtraReport();
report.Bands.Add(detail);
report.DataSource = source;
report.ShowRibbonPreview();
Here is result of example:

Extracting values of textbox in array?

I have dynamically created textbox in asp.net. Now i am extracting the values through following code.
string[] sublist = new string[] { };
int[] maxmarkslist = new int[] { };
int i;
for (i = 0; i < Convert.ToInt32(Label15.Text); i++)
{
string sub = "subject" + i;
string marks = "maxmarks" + i;
TextBox subject = (TextBox)PlaceHolder1.FindControl(sub);
TextBox maxmarks = (TextBox)PlaceHolder1.FindControl(marks);
sublist[i] = subject.Text;
maxmarkslist[i] = Convert.ToInt32(maxmarks.Text);
}
But I getting error "Index was outside the bounds of the array" for the below two lines:
sublist[i] = subject.Text;
maxmarkslist[i] = Convert.ToInt32(maxmarks.Text);
When I debugged it, values are coming in subject.Text and maxmarks.Text but not going to array.
Did I define the array in a wrong way?
You define both the arrays as empty arrays. So you will get index out of bound erros if you try to index into those.
Arrays are not dynamically expanding. If you want that, use a collection type and may be later convert to an array.
Try this:
int length = Convert.ToInt32(Label15.Text);
string[] sublist = new string[length-1];
int[] maxmarkslist = new int[length-1];
for (int i = 0; i < length; i++)
{
string sub = "subject" + i;
string marks = "maxmarks" + i;
TextBox subject = (TextBox)PlaceHolder1.FindControl(sub);
TextBox maxmarks = (TextBox)PlaceHolder1.FindControl(marks);
sublist[i] = subject.Text;
maxmarkslist[i] = Convert.ToInt32(maxmarks.Text);
}
Or here is how to do this with a collection (List) type:
int length = Convert.ToInt32(Label15.Text);
List<string> sublist1 = new List<string>();
List<int> maxmarkslist1 = new List<int>();
for (int i = 0; i < Convert.ToInt32(Label15.Text); i++)
{
string sub = "subject" + i;
string marks = "maxmarks" + i;
TextBox subject = (TextBox)PlaceHolder1.FindControl(sub);
TextBox maxmarks = (TextBox)PlaceHolder1.FindControl(marks);
sublist1.Add(subject.Text);
maxmarkslist1.Add(Convert.ToInt32(maxmarks.Text));
}
string[] sublist = sublist1.ToArray();
int[] maxmarkslist = maxmarkslist1.ToArray();
Note with collections you dont have to specify the size upfront. But keep adding items to it as it can expand as needed. But arrays can not do this.
Your string[] sublist = new string[] { }; is a shortcut method where you create and initialize the array. In that you don't have to specify the size, but compiler will count the elements between {} and set the size appropriately. In your case since there are no elements inside {} it will create an empty array.
string[] sublist = new string[100];
int[] maxmarkslist = new int[100];
Put this..replace 100 with the max possible value of your loop...but this is not a good practice...will come back to this thread if i found something better...

sort ArrayCollection by date then time - Flex

I have an ArrayCollection that I'd like to sort by date and then time (in case there's two items with the same date). I've got it sorting by date fine (YYYY/MM/DD) but I can't figure out the time bit, time is in 24 hour format so the code would be basically the same as for the date.
This is the code I used for the date sorting, it works fine.
import mx.collections.SortField;
import mx.collections.Sort;
private function sort():void
{
var dataSortField:SortField = new SortField();
dataSortField.name = "date";
var arrayDataSort:Sort = new Sort();
arrayDataSort.fields = [dataSortField];
reminderXMLArray.sort = arrayDataSort;
reminderXMLArray.refresh();
}
You can use this code to sort by date and time:
private function sort():void
{
var dataSortField:SortField = new SortField();
dataSortField.name = "date";
dataSortField.compareFunction = function (a:Object, b:Object) : int {
var na:Number = a.date.getTime();
var nb:Number = b.date.getTime();
if (na < nb)
return -1;
if (na > nb)
return 1;
return 0;
};
var arrayDataSort:Sort = new Sort();
arrayDataSort.fields = [dataSortField];
reminderXMLArray.sort = arrayDataSort;
reminderXMLArray.refresh();
}
As there are two separate fields that you want to sort on you can just use the Sort object's fields Array to add two sort fields:
var sort:Sort = new Sort();
var fields:Array = [ new SortField("date"), new SortField("time") ];
sort.fields = sort;

Resources