Flex's AreaChart bug - apache-flex

What's up with Flex's AreaChart bug, does anybody know how to fix it? It causes ones tooltips to display the wrong value for minFields.
I.e. for:
<mx:AreaSeries yField="TotalVariableCost" minField="TotalFixedCost" displayName="Total Cost">
It will show:
Total Cost
high: TotalVariableCost
low: TotalVariableCost
As opposed to:
Total Cost
high: TotalVariableCost
low: TotalFixedCost
This bug is suppose to be in lines 2058 to 2083 of AreaSeries.as - but that stuff is way beyond my comprehension.
--Stephen

Yep, it's a bug in AreaSeries. Due to the stupid way that flex charts are designed, the only real way to fix it is to set a custom dataTipFunction on the AreaChart.
Here's a copy of the relevant code with the bug fixed:
/**
* Create a data tip function for the given AreaSeries. Uses a copy of
* the formatDataTip code from AreaSeries with the minValue bug fixed.
*
* #param series
* #return a data tip function
*
*/
private function createAreaSeriesTipFunc(series:AreaSeries):Function {
var displayName:String = series.displayName;
var dataTransform:DataTransform = series.dataTransform;
var xField:String = series.xField;
var minField:String = series.minField;
// formatDataTip relies on AreaSeries member data so simulate that
// with a closure to minimize code modifications
return function(hd:HitData):String {
var dt:String = "";
var n:String = displayName;
if (n && n != "")
dt += "<b>"+ n + "</b><BR/>";
var xName:String = dataTransform.getAxis(CartesianTransform.HORIZONTAL_AXIS).displayName;
if (xName == "")
xName = xField;
if (xName != "")
dt += "<i>" + xName + ": </i>";
var item:AreaSeriesItem = AreaSeriesItem(hd.chartItem);
var lowItem:AreaSeriesItem = (minField != "") ?
item :
null;
dt += dataTransform.getAxis(CartesianTransform.HORIZONTAL_AXIS).formatForScreen(item.xValue) + "\n";
var yName:String = dataTransform.getAxis(CartesianTransform.VERTICAL_AXIS).displayName;
if (!lowItem)
{
if (yName != "")
dt += "<i>" + yName + ":</i> ";
dt += dataTransform.getAxis(CartesianTransform.VERTICAL_AXIS).formatForScreen(item.yValue) + "\n";
}
else
{
if (yName != "")
dt += "<i>" + yName + " (high):</i> ";
else
dt += "<i>high: </i>";
dt += dataTransform.getAxis(CartesianTransform.VERTICAL_AXIS).formatForScreen(item.yValue) + "\n";
if (yName != "")
dt += "<i>" + yName + " (low):</i> ";
else
dt += "<i>low:</i> ";
dt += dataTransform.getAxis(CartesianTransform.VERTICAL_AXIS).formatForScreen(lowItem.minValue) + "\n";
}
return dt;
};
}
I just changed formatForScreen(lowItem.yValue) to formatForScreen(lowItem.minValue) in one place. You can use it like this:
<mx:AreaChart dataProvider="{chartData}" showDataTips="true" dataTipFunction="{createAreaSeriesTipFunc(areaSeries)}">
<mx:series>
<mx:AreaSeries id="areaSeries" yField="TotalVariableCost" minField="TotalFixedCost" displayName="Total Cost" />
</mx:series>
</mx:AreaChart>

Related

How to write script in BS in siebel to store multiple records in the output?

i have a scenario where there is an LOV with High Value as "Package" and TYPE="TO_NEW_PACKAGE" and i have to fetch the value of Low and there are 8 records in Low. I Have to display all the 8 records and their component cost for each record. All this should be gone as a display Message which will be output. Please let me know how to do this.
var sSearchExp = "[Type]= '" + "PACKAGE_PLAN" + "' AND [High] = '" + PACKAGEPLAN + "'"; SetSearchExpr(sSearchExp); ExecuteQuery(); var isRecord = FirstRecord(); while(isRecord) { Slow = GetFieldValue("Low"); Outputs.SetProperty ("NEW_PACKAGE_PLAN",Slow); Outputs.SetProperty("ErrorCode", "00"); Outputs.SetProperty("ErrorDesc", "Success"); i = i+1; isRecord = NextRecord(); }
this is storing only 1 record... i want all the eight records to be displayed!
This should get you started
var sSearchExp = "[Type]= '" + "PACKAGE_PLAN" + "' AND [High] = '" + PACKAGEPLAN + "'";
var Slow = "";
SetSearchExpr(sSearchExp);
ExecuteQuery();
var isRecord = FirstRecord();
while (isRecord) {
Slow += GetFieldValue("Low");
Slow += " ";
i = i + 1;
isRecord = NextRecord();
}
Outputs.SetProperty("NEW_PACKAGE_PLAN", Slow);
Outputs.SetProperty("ErrorCode", "00");
Outputs.SetProperty("ErrorDesc", "Success");
This sample code will print the values downwards:
var boAsset = TheApplication().GetBusObject("List Of Values");
var bcAsset = boAsset.GetBusComp("List Of Values");
with (bcAsset)
{
ActivateField("Value");
var sSearchExp = "[Type]= 'AAG_TABLE_TYPE'";
var Slow = "";
SetSearchExpr(sSearchExp);
ExecuteQuery();
var isRecord = FirstRecord();
while (isRecord)
{
Slow += GetFieldValue("Value");
Slow += "\n";
isRecord = NextRecord();
}
TheApplication().RaiseErrorText(Slow);
}
Output:
AAG Account
AAG Holdg
AAG Portf
AAG Txn
Changing Slow += "\n"; to Slow += " "; will print the values sideways.
Hope you get the trick here.

put csv data to array imacros js

I am trying to loop through a csv file pushing each column into an array but I am not sure how to do that, I know that the tag {{!COL1}} will give me the data I want but I can't figure out how to save it into a variable I can use to push inside an array.
csvToArray = "CODE:";
csvToArray += "SET !DATASOURCE artist.csv" + "\n";
csvToArray += "SET !ERRORIGNORE YES" + "\n";
csvToArray += "SET !DATASOURCE_LINE {{CSV}}" + "\n";
csvToArray += "SET !VAR1 {{!COL1}}" + "\n";
for(i = 0; i < 10; i++){
iimSet("CSV", i);
iimPlay(csvToArray);
}
This code will allow me to loop through a csv file, and the {{!COL1}} tag gives me the data i want, how do i save this into a varialbe i can use, please someone help cant figure this one out. :(
To get the data of COL1 you will need to set EXTRACT = COL1, then assign your variable to iimGetLastExtract().
Add this to your macro:
csvToArray += "SET !EXTRACT {{!COL1}}";
Then add this to your js file:
var myArray = []; // place at top of file for readability
myArray.push(iimGetLastExtract()); // place at end of for loop
// puts each extraction into myArray
Try the below code block.
function read_file(path) {
var content = '', i = 1, f, res = '',spl;
while (1){
content = res;
if (content != "") {
spl = content.split("|");
//spl[0] will contain the Row1 and Column1 value, spl[1] will contain Row 1 and Column 2 value etc.,
/*Here you can specify your script/conditions
Example:
iimPlay('CODE:TAG POS=1 TYPE=INPUT:TEXT ATTR=NAME:login[username] CONTENT='+spl[0]);
iimPlay('CODE:TAG POS=1 TYPE=INPUT:PASSWORD ATTR=NAME:login[password] CONTENT='+spl[1]);
I used the infinite loop, so in order to come out of the loop, you need to add a condition like below
if (spl[0]=="End") {//In your input sheet if the Row1,Col1 contains the value 'End', then it will exit the loop
iimDisplay("All Rows Completed");
return;
}
*/
f = "CODE: "+"\n";
f += "SET !EXTRACT null" + "\n";
f += "SET !LOOP 3" + "\n";
f += "SET !DATASOURCE \""+path+"\" "+"\n";
f += "SET !DATASOURCE_COLUMNS 5" + "\n"; //Assume that you have five columns in the your input file
f += "SET !DATASOURCE_LINE " + i + "\n";
f += "SET !EXTRACT {{!col1}}|{{!col2}}|{{!col3}}|{{!col4}}|{{!col5}}" + "\n";
iimPlay(f);
res = iimGetLastExtract();
i++;
}
return content;
}
var file_conten = read_file("yourinputfilename.csv");

How to deserialize an array using c# dynamics?

I am trying to deserialize the following JSON to an array using C# dynamics:
[
{
"itemId":"15",
"quantity":101,
"eventTimestamp":"00000000-0000-0000-0000-000000000000",
"salesChannel":"1",
"unlimitedQuantity":false
},
{
"itemId":"15",
"quantity":101,
"eventTimestamp":"00000000-0000-0000-0000-000000000000",
"salesChannel":"2",
"unlimitedQuantity":false
}
]
I have already tried two different approaches, without success:
dynamic itemsBalance = JObject.Parse(content);
and
var itemBalanceType = new {
itemId = "", quantity = 0, eventTimestamp = "", salesChannel = ""
};
var itemsBalance = JsonConvert.DeserializeAnonymousType(content, itemBalanceType);
I am currently using C# dynamics with all other deserializations, and would not like to create classes for each response.
Is there any way to do this ?
Thanks
I found a solution:
JArray itemsBalance = JArray.Parse(content);
if (itemsBalance != null)
{
for (int i = 0; i < itemsBalance.Count; i++)
{
string itemBalanceJSON = itemsBalance[i].ToString();
dynamic itemBalance = JObject.Parse(itemBalanceJSON);
lbxResponse.Items.Add(itemBalance.itemId + " - " + itemBalance.salesChannel +": " + itemBalance.quantity.ToString());
}
}
Should there be any better, please let me know...
You could do it with less amount of code:
dynamic result = JsonConvert.Deserialize(content);
foreach(var entry in result)
{
lbxResponse.Items.Add(entry.itemId + " - " + entry.salesChannel + ": " + entry.quantity);
}

Converting "2.800000000000000e+001" to ""28" in ASP.NET

Here is XML received by any web service,
<diy>
<tag1>14</tag1>
<tag2>2.000000000000000e+000</tag2>
<tag3>2.800000000000000e+001</tag3>
</diy>
This is code:
IEnumerable<XElement> xTag = from p in xmlDoc.Elements("document").Elements("xServ").Elements("b")
select p;
string tab = "<Table>";
foreach (var xTags in xTag)
{
tab += "<tr><td>" + Convert.ToString(xTags.Element("r").Element("Exp").Value) + "</td>";
tab += "<td>" + Convert.ToString(xTags.Element("r").Element("diy").Element("tag1").Value) + "</td>";
string s = Convert.ToString(xTags.Element("r").Element("diy").Element("tag2").Value);
string d = Math.Round(Convert.ToDouble(s)).ToString();
tab += "<td>" + d + "</td>";
tab += "<td>" + Convert.ToString(xTags.Element("r").Element("diy").Element("tag3").Value) + "</td>";
tab += "</tr>";
}
divTag.InnerHtml = tab + "</Table>";
When I used Math.Round(), it gives me "2,8E+16" !
how can I convert "2.000000000000000e+000" to "2" and "2.800000000000000e+001" to "28" in ASP.NET ?
Use Math library:
Math.Round(Convert.ToDouble("2.800000000000000e+001")).ToString();
that will return "28" .
How about this:
decimal.Parse("2.800000000000000e+001", System.Globalization.NumberStyles.Float).ToString("0.#");
Edit: added .NET format string to reduce to "28"
public static int function(float tag2)
{
do
{
if(tag2%10==0)
{
tag2=tag2/10.0;
}
else
{
int res = tag2;
return res;
}
}
while(true)
}
well I have to say that my solution is a bit funny! and beside that uses more memory than other ways.although other solutions use more cpu! life is trade off!
string MyNumber = "2.8000000e+1";
int DotIndex = MyNumber.IndexOf('.');
MyNumber = MyNumber.Remove(DotIndex, 1);
if(MyNumber[DotIndex] != '0')
DotIndex++;
MyNumber = MyNumber.Remove(DotIndex, MyNumber.Length - DotIndex);
DotIndex = Int32.Parse(MyNumber);
//MessageBox.Show(MyNumber); just to show the result!
It will return "2" for an input like "2.00000000e+1" AND "28" for "2.8000000e+1"!

Extjs4 multigrouping header value css

I am using the Extjs4 multigrouping plugin from here.
I have used it successfully, however i want to show the summary of the totals of each column within the group header itself . how do i set up the appropriate CSS for that ?
In Multigrouping.js
getFragmentTpl: function() {
var me = this;
return {
indentByDepth: me.indentByDepth,
depthToIndent: me.depthToIndent,
renderGroupHeaderTpl: function(values, parent) {
return Ext.XTemplate.getTpl(me, 'groupHeaderTpl').apply(values, parent);
//var z = new Ext.XTemplate('{name} ({rows.grouplength})');
//return z.apply(values, parent);
}
};
},
In my grid
features: [
{
ftype:'multigrouping',
groupHeaderTpl: [
'{[this.readOut(values)]}',
{
readOut:function(values) {
debugger;
var sum1 =0 ,sum2=0,sum3=0;
for( var i = 0 ; i< values.records.length ; i++)
{
var val = parseFloat(values.records[i].data.d2012.mp);
sum1 += isNaN(val) ? 0.0 : val;
val = parseFloat(values.records[i].data.d2013.mp);
sum2 += isNaN(val) ? 0.0 : val;
val = parseFloat(values.records[i].data.d2014.mp);
sum3 += isNaN(val) ? 0.0 : val;
}
return values.name + '(' + values.records.length + ')' + ' ' + sum1.toFixed(2) + ' ' + sum2.toFixed(2) + ' ' + sum3.toFixed(2);
}
}
]
},
had to resort to a few hacks to get this to work. still waiting on an official answer.
The main reason i had to do this and not use the multigrouping summary is because
- i want to limit the number of records from the server. I can do some smart grouping of
my business objects at the server side.
- the main reason to do this is because of IE8's performance on larger sets of data.
- had already tried the extjs4 tree grid component which works well on chrome but had performance issues on IE8.
the hack is to
a) use an array property in the grid to store the dom elements which i want to manipulate
b) use a boolean to know when the layout is completed the first time
b) add listeners for afterlayout ( when your app can do an Ext.get('..dom element..') you know you are done )
The listener :
listeners :
{
afterlayout : function(eopts)
{
var x = this.mOwnArray;
if(!this.loadedwithVals && x.length > 0)
{
for(var i =0 ; i<x.length ; i++)
{
var dom = Ext.get(x[i].id);
var theId = dom.id;
theId = theId.match(/\d+/)[0];
var title = dom.query("td[class='x-grid-cell x-grid-cell-first']");
title[0].className = 'x-grid-cell x-grid-cell-gridcolumn-' + theId + ' x-grid-cell-first';
title[0].colSpan=1;
var groupedHeader = dom.query("div[class='x-grid-group-title']");
groupedHeader[0].innerHTML = x[i].name + '(' + x[i].length + ')';
for(var year=2012;year<=2018;year++)
{
var t = "t"+year;
var someText1 = '<td class=" x-grid-cell x-grid-cell-numbercolumn">';
var someText2 = '<div class="x-grid-cell-inner " style="text-align: left; ;">';
var someText3 = '<div class="x-grid-group-title">' + x[i].total[t] + '</div></div></td>';
var someText = someText1 + someText2 + someText3;
dom.insertHtml("beforeEnd",someText);
}
}
this.loadedwithVals = true;
}
}
And the feature as in
features: [
{
ftype:'multigrouping',
startCollapsed : true,
groupHeaderTpl: [
'{[this.readOut(values)]}',
{
readOut:function(values) {
var header = new Object();
header.id = values.groupHeaderId;
header.sum = [];
header.total = new Object();
for(var year = 2012 ; year <= 2018 ; year++)
{
var t = "t"+year;
header.total[t] = [];
}
// all the records in this header
for( var i = 0 ; i< values.records.length ; i++)
{
// for all the 'years' in this record
for(var year=2012;year<=2018;year++)
{
var d = "d"+year;
var ct = "t" + year;
var arecord = values.records[i].data;
var val = parseFloat(arecord[d].mp);
val = isNaN(val) ? 0.0 : val;
Ext.Array.push(header.total[ct],val);
}
}
// push the sum of the records into its top level group
for(var year = 2012 ; year <= 2018 ; year++)
{
var t = "t"+year;
var sum = Ext.Array.sum(header.total[t]);
header.total[t] = sum.toFixed(2);
}
header.name = values.name;
header.length = values.records.length;
var headerName = values.name;
if(values.hasOwnProperty('parent'))
{
var parent = values.parent;
headerName = headerName.replace(parent,'');
}
header.name = headerName;
header.length = values.records.length;
Ext.Array.push(grid.mOwnArray,header);
// really not used
return values.name + '(' + values.records.length + ')';
}
}
]
},
]

Resources