Place Formulas (setFormula) on SpreadJS headers (colHeader) - javascript

I currently have a solution using AngularJS/SpreadJS where we need to update the header section with a formula. When we change a cell value in the header using setValue everythign displays ok, however we need to display a formula using setFormula, in these cases the formula gets calculated and displayed in the rows belonging to the actual sheet where my data is at.
//Does not work and displays in row 2 of the sheet:
sheet.setFormula(2, i, formula, GC.Spread.Sheets.SheetArea.colHeader);
//Displays value in actual header in teh correct location/header cell
sheet.setValue(2, i, 'my formula!', GC.Spread.Sheets.SheetArea.colHeader);
Any help will be appreciated. Thanks!

Implemented below solution to achieve the SUM formula in Column Header of the spread sheet.This function can be called on spread sheet events like cellChanged,clipBoardPasted to achieve functionality.
var spread = new GC.Spread.Sheets.Workbook($("#ss").get(0), { sheetCount: 2 });
var displaySheet = spread.getSheet(0);
displaySheet.setRowCount(2, GC.Spread.Sheets.SheetArea.colHeader);
for (var i = 0; i < 10; i++) {
for (var j = 0; j < 10; j++) {
displaySheet.setValue(i, j, i + j);
}
}
$("#btnSetAutoTotal").click(function () {
setTotal(displaySheet, 0);
});
function setTotal(sheet, columnIndex) {
var formula = "SUM(R[1]C[1]:R[10]C[10]";
value = GC.Spread.Sheets.CalcEngine.evaluateFormula(sheet, 'SUM(A:A)', 0,
columnIndex, false);
sheet.setValue(0, columnIndex, value, GC.Spread.Sheets.SheetArea.colHeader);
};

The team created this sample to demonstrate what you need. Hope this helps.
function setColumnHeaderFunction() {
this.name = "SetColumnHeader";
this.maxArgs = 3;
this.minArgs = 3;
}
setColumnHeaderFunction.prototype = new GC.Spread.CalcEngine.Functions.Function();
setColumnHeaderFunction.prototype.description = function () {
return {
name:"SetColumnHeader",
description: "The function will apply the calc result on specified column",
parameters: [{
name: "result",
description: "The value which will be setted on column"
}, {
name: "rowIndex",
description: "The row index"
}, {
name: "colIndex",
description: "The column index"
}]
}
}
setColumnHeaderFunction.prototype.evaluate = function () {
var value = arguments[0], rowIndex = arguments[1], colIndex = arguments[2];
var spread = GC.Spread.Sheets.findControl("ss");
var sheet = spread.getSheet(0);
sheet.setValue(rowIndex, colIndex, value, GC.Spread.Sheets.SheetArea.colHeader);
}
$(document).ready(function () {
var spread = new GC.Spread.Sheets.Workbook($("#ss").get(0), {sheetCount: 2});
spread.addCustomFunction(new setColumnHeaderFunction());
var displaySheet = spread.getSheet(0);
displaySheet.setDataSource(getSource(100));
displaySheet.setRowCount(3, GC.Spread.Sheets.SheetArea.colHeader);
displaySheet.setValue(0,0,"Count:",GC.Spread.Sheets.SheetArea.colHeader);
displaySheet.setValue(0,3,"Sum:",GC.Spread.Sheets.SheetArea.colHeader);
displaySheet.setValue(0,4,"Average:",GC.Spread.Sheets.SheetArea.colHeader);
displaySheet.setValue(0,5,"Sum:",GC.Spread.Sheets.SheetArea.colHeader);
var calcSheet = spread.getSheet(1);
calcSheet.visible(false);
calcSheet.setFormula(0, 1, "SetColumnHeader(SUM(Sheet1!D:D),1,3)");
calcSheet.setFormula(0, 2, "SetColumnHeader(AVERAGE(Sheet1!E:E),1,4)");
calcSheet.setFormula(0, 3, "SetColumnHeader(SUM(Sheet1!F:F),1,5)");
calcSheet.setFormula(0, 4, "SetColumnHeader(COUNT(Sheet1!A:A),1,0)");
});
function getSource(count) {
var dataList = [];
var _lines = ["Computers", "Washers", "Stoves"];
var _colors = ["Red", "Green", "Blue", "White"];
for (var i = 0; i < count; i++) {
dataList.push({
id: i,
line: _lines[parseInt(Math.random() * 3)],
color: _colors[parseInt(Math.random() * 4)],
price: parseInt(Math.random() * 501 + 500),
cost: parseInt(Math.random() * 601),
weight: parseInt(Math.random() * 101),
})
}
return dataList;
}

Related

Javascript Read data from spreadsheet

I am using a HTML form to get data from google spreadsheet.
I need to get the row where SerNo= 2 (or any specific number)
I am looping through the sheet and trying to get the values as below - but it does nothing
ex:
SerNo Col2
2 Option1
3 Option2
4 Option3
So,if SerNo=2 ...I want to get Option1.
This has 24 columns so i have used the getLastColumn
{function getDataRows_(ss, sheetname) {
var sh = ss.getSheetByName(sheetname);
var lr= sh.getLastRow();
for(var i=1;i<=lr;i++){
var SerNo1 = sh.getRange(i, 2).getValue();
if(SerNo1==SerNo){
return sh.getRange(i, 2, 1, sh.getLastColumn()).getValues();
}
}
}
----edit---
I have posted the whole code I use since it looks like i am filtering records at the wrong place
function read_value(request,ss){
var output = ContentService.createTextOutput(),
data = {};
var sheet="sheet1";
data.records = readData_(ss, sheet);
var callback = request.parameters.callback;
if (callback === undefined) {
output.setContent(JSON.stringify(data));
} else {
output.setContent(callback + "(" + JSON.stringify(data) + ")");
}
output.setMimeType(ContentService.MimeType.JAVASCRIPT);
return output;
}
function readData_(ss, sheetname, properties) {
if (typeof properties == "undefined") {
properties = getHeaderRow_(ss, sheetname);
properties = properties.map(function(p) { return p.replace(/\s+/g, '_'); });
}
var rows = getDataRows_(ss, sheetname),
data = [];
for (var r = 0, l = rows.length; r < l; r++) {
var row = rows[r],
record = {};
for (var p in properties) {
record[properties[p]] = row[p];
}
data.push(record);
}
return data;
}
function getDataRows_(ss, sheetname) {
var sh = ss.getSheetByName(sheetname);
return sh.getRange(2, 1, sh.getLastRow() -1,sh.getLastColumn()).getValues();
}
function getHeaderRow_(ss, sheetname) {
var sh = ss.getSheetByName(sheetname);
return sh.getRange(1, 1, 1, sh.getLastColumn()).getValues()[0];
}
One thing I would recommend is to not retrieve the data on row at a time; in other words retrieve all of the data that you want to search through into an array (i.e. row 1 through last row) and then test each row of the array, looking for your value.

generate array of merged cells handsontable

for example i have an array of rows:
{ "name1", "value1", "other1", "another1" },
{ "name1", "value2", "other2", "another2" },
{ "name2", "value3", "other3", "another3" },
{ "name2", "value4", "other4", "another4" }
i cant generate the array that will have the structure of merged cells like:
{ row: 0, col: 0, colspan: 1, rowspan: 2 },
{ row: 2, col: 0, colspan: 1, rowspan: 2 }
where row is row index, col column index, colspan is span of columns and rowspan is the span of rows on table.
so far i have the code:
var prev;
var entry = {};
var repeat = 1;
var result = [];
for(a in data){
if(a>0){
prev = data[a-1];
for(b in data[a]){
if(prev[b]===data[a][b]){
if(repeat==1){
entry["row"] = a-1;
entry["col"] = b;
entry["colspan"] = 1;
}
repeat++;
}
}
}
}
but i cant understand when i can make rowspan=repeat then make repeat=1, again and at the same time i need to push this entry inside the result
thank you all for the help!
EDIT: I've managed to do almost working example, but with little mistake, it doesnt push the last merge... any ideas to make it push the last entry?!
var cols = data[0].length;
var prev;
var entry = {};
var repeat = [];
for(var i=0;i<cols;i++){
repeat.push(1);
}
var result = [];
for(a in data){
if(a>0){
prev = data[a-1];
for(b in data[a]){
if(prev[b]!=null&&prev[b]===data[a][b]){
if(repeat[b]==1){
entry["row"] = a-1;
entry["col"] = parseInt(b);
entry["colspan"] = 1;
}
repeat[b]++;
}else{
if(repeat[b]>1){
entry["rowspan"] = repeat[b];
result.push(entry);
repeat[b] = 1;
entry = {};
}
}
}
}
}
it is clear that my structure has a minus in that it is using the prev variable and starts from second row... but i didnt come up with any other better way.
So i figured out how i can do it :) here is my code, just in case if someone will need it. Not the best way thou... but it works!
var cols = data[0].length;
var prev;
var entry = {};
var repeat = [];
for(var i=0;i<cols;i++){
repeat.push(1);
}
var result = [];
for(a in data){
if(a>0){
prev = data[a-1];
for(b in data[a]){
if(prev[b]!=null&&prev[b]===data[a][b]){
if(repeat[b]==1){
entry["row"] = a-1;
entry["col"] = parseInt(b);
entry["colspan"] = 1;
}
repeat[b]++;
}else{
if(repeat[b]>1){
entry["rowspan"] = repeat[b];
result.push(entry);
repeat[b] = 1;
entry = {};
}
}
}
if(a==data.length-1){
for(var i=0;i<repeat.length;i++){
if(repeat[i]>1){
entry["rowspan"] = repeat[i];
result.push(entry);
repeat[i] = 1;
entry = {};
}
}
}
}
}

Zingchart last element keeps changing color and not matching with legend

My zingchart's last element's color does not match with legend, and keeps on changing unlike the others. Any Ideas? Everything else works good. Though I'm parsing this data through MySQL database, this is how the JavaScript looks like.
My code:
<script>
var myData = ["12","15","7","20","2","22","10","7","7","10","8","15","9"];
var myData = myData.map(parseFloat);
var myLabels = ["General Verbal Insults","General Beatings\/Pushing","Terrorizing\/Threatening Remarks","False Gossip Inflation (Rumors)","Discrimination","Rough Fighting","Sexual Utterance\/Assaults","General Exclusion","Theft","Racist Utterance\/Assaults","Personal Property Damage","Internet Related (Cyber)","Other\/Unspecified"];
window.onload=function(){
var colorCharacters = "ACDEF0123456789";
var globalStylesArray = [];
var myConfig = {
type: "bar",
legend:{},
title: {
"text":"Showing Results For: Canada",
"color":"green"
},
subtitle: {
"text":"Total Bullying Incidents In Country: 144",
"color":"blue"
},
series : [{"values":[ myData[0] ],"text":"General Verbal Insults",},{"values":[ myData[1] ],"text":"General Beatings/Pushing",},{"values":[ myData[2] ],"text":"Terrorizing/Threatening Remarks",},{"values":[ myData[3] ],"text":"False Gossip Inflation (Rumors)",},{"values":[ myData[4] ],"text":"Discrimination",},{"values":[ myData[5] ],"text":"Rough Fighting",},{"values":[ myData[6] ],"text":"Sexual Utterance/Assaults",},{"values":[ myData[7] ],"text":"General Exclusion",},{"values":[ myData[8] ],"text":"Theft",},{"values":[ myData[9] ],"text":"Racist Utterance/Assaults",},{"values":[ myData[10] ],"text":"Personal Property Damage",},{"values":[ myData[11] ],"text":"Internet Related (Cyber)",},{"values":[ myData[12] ],"text":"Other/Unspecified",}]
};
zingchart.render({
id : 'myChart',
data : myConfig,
width:"100%",
height:500,
});
zingchart.gload = function(p) {
console.log(p);
var graphId = p.id;
var graphData = {};
graphData = zingchart.exec(graphId, 'getdata');
graphData = graphData.graphset[0] ? graphData.graphset[0] : graphData;
console.log(graphData);
createColors(graphData.series[0].values.length);
zingchart.exec(graphId, 'modifyplot', {
data: {
styles: globalStylesArray
}
});
}
function createColors(seriesLength) {
console.log('-------createColor seriesLength: ', seriesLength);
globalStylesArray = [];
for (var i = 0; i < seriesLength; i++) {
var colorString = '#';
for (var j = 0; j < 6; j++) {
colorString += colorCharacters.charAt(Math.floor(Math.random() * (colorCharacters.length - 4)));
}
globalStylesArray.push(colorString);
}
console.log('-----globalStylesArray-------', globalStylesArray);
}
};
</script>
Referring to the comment on the OP:
I just want all color to be different, since i dont know how many elements are in MyData - its generated through PHP & MYSQL
If you just want all of the colors to be different, remove the zingchart.gload function and the createColors function. ZingChart will create different colors for each series dynamically.
If you do want to specify each of those colors ahead of time since you do not know how many series your data will produce, you will need to apply a theme to your chart configuration: http://www.zingchart.com/docs/design-and-styling/javascript-chart-themes/

Add method to Constructor function that manipulates an Array

I am attempting to create a simple program for practice that has a Store constructor which takes in an inventoryList array, an InventoryItem constructor that creates an object of each item to be stored within the inventoryList array. I want to add a method to the InventoryItem list that will take a number and add it to each item within the list. Below is my code:
var Store = function(inventory){
this.inventory = inventory;
}
var InventoryItem = function(cost, color, size){
this.cost = cost;
this.color = color;
this.size = size;
}
//create each inventory item as an object
var lamp = new InventoryItem(40.00, 'blue', 'small');
var throwPillow = new InventoryItem(25.00, 'yellow', 'medium');
var sconce = new InventoryItem( 18.00, 'gold', 'large');
var candles = new InventoryItem(10.00, 'white', 'small');
var curtains = new InventoryItem(30.00, 'purple', 'large');
//store inventory items into an inventory object
var inventorylist = [lamp, throwPillow, sconce, candles, curtains];
// add number of items to each item
InventoryItem.prototype.howMany = function(num){
function addCount(inventorylist){
for(var i = 0; i < inventorylist.length; i++){
inventorylist[i].howMany = num;
}
}
}
//store inventory within a store
var deannaStore = new Store(inventorylist);
var dionStore = new Store(inventorylist);
var mikeStore = new Store(inventorylist);
I am running into an issue when I attempt add a number to an item within the list
example: dionStore.howMany(15)
this gives me the error: Uncaught TypeError: dionStore.howMany is not a function
Any help would be greatly appreciated preferably with a detailed explanation of why this doesn't work.
The problem is that the method howMany is defined for InventoryItem objects, but you try to call it to dionStore object which is a Store.
Can you please describe what you want to achieve?
EDIT1 :
Maybe add the howMany method to Store, like Lashane mentions, which will create a quantity property to each InvetoryItem in its array
Store.prototype.howMany = function(num){
function addCount(inventorylist){
for(var i = 0; i < inventorylist.length; i++){
inventorylist[i].quantity = num;
}
}
}
EDIT2 :
In this case you will need a method in InventoryItem to set the quantity and another in Store to return the total quantity
Store.prototype.howMany = function(){
var totalQuantity = 0;
for(var i = 0; i < inventorylist.length; i++){
var item = inventorylist[i];
if (item.hasOwnProperty('quantity')) {
totalQuantity += item.quantity;
}
}
return totalQuantity;
}
InventoryItem.prototype.addQuantity = function(quantity) {
if (this.hasOwnProperty('quantity')) {
this.quantity += quantity;
} else {
this.quantity = quantity;
}
}
var Store = function(inventory) {
this.inventory = inventory;
}
Store.prototype.howMany = function() {
var totalQuantity = 0;
for (var i = 0; i < inventorylist.length; i++) {
var item = inventorylist[i];
if (item.hasOwnProperty('quantity')) {
totalQuantity += item.quantity;
}
}
return totalQuantity;
}
var InventoryItem = function(cost, color, size) {
this.cost = cost;
this.color = color;
this.size = size;
}
InventoryItem.prototype.addQuantity = function(qunatity) {
if (this.hasOwnProperty('quantity')) {
this.quantity += qunatity;
} else {
this.quantity = qunatity;
}
}
//create each inventory item as an object
var lamp = new InventoryItem(40.00, 'blue', 'small');
var throwPillow = new InventoryItem(25.00, 'yellow', 'medium');
var sconce = new InventoryItem(18.00, 'gold', 'large');
var candles = new InventoryItem(10.00, 'white', 'small');
var curtains = new InventoryItem(30.00, 'purple', 'large');
//store inventory items into an inventory object
var inventorylist = [lamp, throwPillow, sconce, candles, curtains];
lamp.addQuantity(1);
throwPillow.addQuantity(2);
sconce.addQuantity(3);
candles.addQuantity(4);
curtains.addQuantity(5);
lamp.addQuantity(1);
//store inventory within a store
var deannaStore = new Store(inventorylist);
var dionStore = new Store(inventorylist);
var mikeStore = new Store(inventorylist);
document.getElementById('output').innerHTML = 'dionStore.howMany() = ' + dionStore.howMany();
<div id="output"></div>
Your prototype defines a function and does nothing. And it is on the wrong prototype. Are you looking for this?
Store.prototype.howMany = function(num){
for(var i = 0; i < this.inventory.length; i++){
this.inventory[i].howMany = num;
}
}

JavaScript - Generate Kendo Ui Grid using xml Data

I've Been using XSLT to display my xml page. I make use of the following to get the data from the xml file:
< xsl:value-of
select="ClinicalDocument/component/structuredBody/component[3]/section/text/table/tbody"/
>
After this, I have the following javascript to clean up the data and do the conversion:
-----------Get Content for Grids----------
//Split Content into array
var purposeArray = document.getElementById('purposeOfVisit').innerHTML.split("\n");
var activeProblemArray = document.getElementById('activeProblems').innerHTML.split("\n");
//------------ Remove All Unwanted Values-----------\\*/
var newDataString ="";
for( var k = 0; k < purposeArray.length; k++ )
{
newDataString += purposeArray[k] + "__";
}
newDataString = newDataString.replace(/ /g,"");
newDataString = newDataString.replace(/__________/g,"__-__");
var newDataArray = newDataString.split("__");
//------------- Save Values in final Array -------------\\*/
var semiFinalArray = new Array();
for( var x=0; x < newDataArray.length; x++)
{
if(newDataArray[x].length != 0)
{
semiFinalArray.push(newDataArray[x]);
}
}
var finalArray = new Array();
var counter = 0;
//------------ Find Number of Columns in row ------------\\*/
var numberOfRows = document.getElementById('numberOfRows').innerHTML;
var numberOfColumns = document.getElementById('numberOfColumns').innerHTML;
var columnsPerRow = parseInt(numberOfColumns) / parseInt(numberOfRows);
//------------------------------Testing ------------------------------//
var dataNamePre = "dataValue";
var temporaryArray = new Array();
var dataName;
//----------- Generate Grid Values -----------//
for( var b=0 ; b < semiFinalArray.length ; b = b + columnsPerRow)
{
var problemComment = "";
counter = 0;
var obj;
for( var a=0 ; a < columnsPerRow ; a++)
{
dataName = dataNamePre + counter.toString() + "";
//-------Generate Grid Titles------//
temporaryArray.push("Title " + (counter+1));
var key = "key"+a;
obj = { values : semiFinalArray[b+a] };
var problemComment = "";
finalArray.push(obj);
counter++;
}
}
//---------------------Generate GridArray---------------------------//
var gridArray = [];
var gridArrayHead = new Array();
counter = 0;
var objectValue = new Array();
for( var x = 0; x < finalArray.length; x++ )
{
objectValue = { head:temporaryArray[x], values: finalArray[x].values }
gridArray.push(objectValue);
}
var provFacilities = [];
for( var x = 0; x < finalArray.length; x++ )
{
provFacilities[x] =
{
head:temporaryArray[x], values: finalArray[x].values
}
}
//alert(gridArray);
$("#grid").kendoGrid(
{
columns:
[{
title:gridArray.head,
template:'#= values #'
}],
dataSource: {
data:finalArray,
pageSize:10
},
scrollable:false,
pageable:true
});
This may be a roundabout method, but I'm still prettry new to this method of coding.
Currently, all the data is being presented in one column, with the last value in my temporaryArray as the title for the column.
Everything works until I try to set the DataSource for the Kendo Grid. When working in the columns property in the grid, I made the following change:
title:gridArray[0].head
When this is done, the title is changed to the first value in the array.
What I want to know is how can I generate columns in the Kendo Grid According to the title? Is there a way to loop through all the values and create the objects from there, seeing that the date that is being sent to the grid are objects in an Array?
What I basically want is something to make this work, without the repitition:
var myGrid = $("#grid").kendoGrid( { columns: [ {
title: temporaryArray[0],
field: finalArray[0].values }, {
title: temporaryArray[1],
field: finalArray[1].values }, {
title: temporaryArray[2],
field: finalArray[2].values }, {
title: temporaryArray[3],
field: finalArray[3].values }, {
title: temporaryArray[4],
field: finalArray[4].values } ]
)};
Any help appreciated, thanks!
This issue has been fixed using the following coding:
var arrayData = [];
for( var x = 0; x < semiFinalArray.length; x=x+5 )
{
var tempArr = new Array();
for( var y = 0; y < 5; y++ )
{
var num = x + y;
tempArr.push(semiFinalArray[num]);
}
arrayData.push(tempArr);
}
var dataTitles = [];
for( var x = 0; x < titleArray.length; x++ )
{
var head = "";
head = titleArray[x];
head = head.replace(/ /g,"");
dataTitles.push(head);
}
var counter = 0;
var columnDefs = [];
for (var i = 0; i < columnsPerRow.length; i++)
{
if (counter == (columnsPerRow - 1))
{
counter = 0;
}
columnDefs.push({ field: dataTitles[counter], template: arrayData[i].values });
counter++;
}
// Create final version of grid array
var gridArray = [];
for (var i = 0; i < arrayData.length; i++)
{
var data = {};
for (var j = 0; j < dataTitles.length; j++)
{
data[dataTitles[j]] = arrayData[i][j];
}
gridArray.push(data);
}
// Now, create the grid using columnDefs as argument
$("#grid").kendoGrid(
{
dataSource:
{
data: gridArray,
pageSize: 10
},
columns: columnDefs,
scrollable: false,
pageable: true
}).data("kendoGrid");
With this, the data is displayed in the DataGrid.

Categories