cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Community Tip - Did you get an answer that solved your problem? Please mark it as an Accepted Solution so others with the same problem can find the answer easily. X

How to get an output as float with 2 decimal values from valuestream without using for loop

Suraj_Patil
15-Moonstone

How to get an output as float with 2 decimal values from valuestream without using for loop

How to get an output as float with 2 decimal values from valuestream without using for loop

- we tried using querynumberpropertyhistory to get an output as float values with2 decimal points with for loop. but for loop is creating an performance issues on server.

 

so tried to bind querynumberpropertyhistory service to line chart and tried to to achieve y axis values as float with 2 decimals but its not working on line chart. its working only on y axis labels not values.

 

can anyone knows how to achieve this?

 

Thanks!!!

1 ACCEPTED SOLUTION

Accepted Solutions

Hi @Suraj_Patil ,

 

Kindly refer the below given code FYR. 

let data = me.QueryNumberPropertyHistory({
	oldestFirst: false /* BOOLEAN */ ,
	maxItems: 9999999 /* NUMBER {"defaultValue":500} */ ,
	endDate: endTime /* DATETIME */ ,
	propertyName: PropertyInput /* STRING */ ,
	query: undefined /* QUERY */ ,
	startDate: startTime /* DATETIME */ ,
	quality: undefined /* STRING */
});
///***/// Dervie the data based on the expression ///****////
let params = {
	types: 'NUMBER' /* STRING */ ,
	t: data /* INFOTABLE */ ,
	columns: 'value' /* STRING */ ,
	expressions: 'value.toFixed(2)' /* STRING */
};
var derivedData = Resources["InfoTableFunctions"].DeriveFields(params);

///***/// Remove unwanted column or feild - id ///****////
derivedData.RemoveField('id');

///***/// Rename the infotable with actual feild values ///****////
var timestamp_Rename = renameFeildName(derivedData, 'timestamp', 'Timestamp');
var value_Rename = renameFeildName(timestamp_Rename, 'value', 'PropertyInput');
result = value_Rename;

///****/// Function to rename feildName without any loop ///***////
function renameFeildName(InfoTable, OldName, NewName) {
	let params = {
		t: InfoTable /* INFOTABLE */ ,
		from: OldName /* STRING */ ,
		to: NewName /* STRING */
	};
	return Resources["InfoTableFunctions"].RenameField(params);
}

It may helps in your case.

 

Thanks & Regards,

Arun C 

View solution in original post

7 REPLIES 7

Hi @Suraj_Patil , Hope this snippet Dervie feild may helps you in this case.

 

let params = {
	types: 'NUMBER' /* STRING */,
	t: IP_Data /* INFOTABLE */,
	columns: 'Value' /* STRING */,
	expressions: 'Value.toFixed(2)' /* STRING */
};

// result: INFOTABLE
let result = Resources["InfoTableFunctions"].DeriveFields(params);

 Note: Rename 'Value' columnname based on your property name.

 

Thanks & Regards,

Arun C

Suraj_Patil
15-Moonstone
(To:Arun_C)

it will work actually but i need to use for loop again to get updated info table with separate data shape. i want to avaoid for loop anyhow . can anyone help in this

Hi @Suraj_Patil ,

 

Can you please paste the piece of your code and let us know what exactly you looking for our better understand.

 

Thanks & Regards,

Arun C

Suraj_Patil
15-Moonstone
(To:Arun_C)

right now i am using code as below:

 

////////////////////////////////////////////////////////////////////////////////

let result = Resources["InfoTableFunctions"].CreateInfoTableFromDataShape({
    infoTableName: "InfoTable",
    dataShapeName: "Test_DS"
});
// result: INFOTABLE dataShape: "NumberValueStream"
let data = me.QueryNumberPropertyHistory({
  oldestFirst: false /* BOOLEAN */,
  maxItems: 9999999 /* NUMBER {"defaultValue":500} */,
  endDate: endTime /* DATETIME */,
  propertyName: PropertyInput /* STRING */,
  query: undefined /* QUERY */,
  startDate: startTime /* DATETIME */,
  quality: undefined /* STRING */
});
for(let i = 0; i < data.getRowCount(); i++){
    var row = new Object();
  row.PropertyInput = data[i].value.toFixed(2);
    row.Timestamp = data[i].timestamp;
    result.AddRow(row);
}
////////////////////////////////////////////////////////////////

now here i am using valuestream service querynumberpropertyhistory to get an info table values for one property

we are getting values in float like eg. 10.568742729 but we want to show on mashup as 10.56. To get this we used for loop which creating performance issue as there is huge data in value stream

here we mentioned input as startTime  and endTime which used as date range on mashup.

now suppose user is selecting one year data thingworx is facing performance issue. so we want avoid this for loop here.

we are displaying this data on line chart.

 

Thanks!!!

Hi @Suraj_Patil ,

 

Kindly refer the below given code FYR. 

let data = me.QueryNumberPropertyHistory({
	oldestFirst: false /* BOOLEAN */ ,
	maxItems: 9999999 /* NUMBER {"defaultValue":500} */ ,
	endDate: endTime /* DATETIME */ ,
	propertyName: PropertyInput /* STRING */ ,
	query: undefined /* QUERY */ ,
	startDate: startTime /* DATETIME */ ,
	quality: undefined /* STRING */
});
///***/// Dervie the data based on the expression ///****////
let params = {
	types: 'NUMBER' /* STRING */ ,
	t: data /* INFOTABLE */ ,
	columns: 'value' /* STRING */ ,
	expressions: 'value.toFixed(2)' /* STRING */
};
var derivedData = Resources["InfoTableFunctions"].DeriveFields(params);

///***/// Remove unwanted column or feild - id ///****////
derivedData.RemoveField('id');

///***/// Rename the infotable with actual feild values ///****////
var timestamp_Rename = renameFeildName(derivedData, 'timestamp', 'Timestamp');
var value_Rename = renameFeildName(timestamp_Rename, 'value', 'PropertyInput');
result = value_Rename;

///****/// Function to rename feildName without any loop ///***////
function renameFeildName(InfoTable, OldName, NewName) {
	let params = {
		t: InfoTable /* INFOTABLE */ ,
		from: OldName /* STRING */ ,
		to: NewName /* STRING */
	};
	return Resources["InfoTableFunctions"].RenameField(params);
}

It may helps in your case.

 

Thanks & Regards,

Arun C 

Suraj_Patil
15-Moonstone
(To:Arun_C)

it worked actually ...Thanks

DanZ
15-Moonstone
(To:Suraj_Patil)

If there is no way in the frontend to cut the decimals (like in a Grid-widget with the "Render" settings) you have to other option than using a loop. Even the "DeriveField" function will probably do the same in the background (and surely has more overhead).

 

I noticed that the "maxItems" parameter can have a significant impact on performance if the value is too high. Unfortunately there is no "GetDataTableEntryCount()" service (like in a data table) available in a stream to set this dynamically. But if you stream is storing values in a fixed interval you can may write a helper function that returns a realistic number in regards of the start- and enddate.

 

But the first thing you should do is to remove the "getRowCount()" from the header of your for-loop. Because you execute this function on each iteration. Assign the rowcount to a variable:

const entryCount = data.getRowCount()
for(let i = 0; i < entryCount; i++){
  ...
}

Just that can have a measurable impact on performance.

 

IMHO I would drop the "for-loop" altogether and use "foreach". Which is even slightly faster (Tips and Tricks for ThingWorx Developers: Dependen... - PTC Community)

 

data.rows.toArray().forEach(row => {
  row.PropertyInput = row.PropertyInput.toFixed(2);
  result.AddRow(row);
});

 

 

Top Tags