Copying rendered value instead of the data value - handsontable

I use Handsontable and in one column, the data type is an integer that is an index of a vector of strings v. So, instead of showing the integer index i, I have to show v[i]. I do so by declaring a custom renderer in handsontable:
var annotationTableSettings = {
data: componentAnnotation,
columns: [
{renderer: annotationId2StringRenderer},
...
However, when I copy the value of the cell (Ctrl+c in windows/linux or cmd+c in mac), the integer is copied instead of the rendered value. Does anyone know how to copy the rendered value (I would like to keep the integer data type and the custom renderer).
An example can be seen here: http://leoisl.gitlab.io/DBGWAS_support/full_dataset_visualization_0_4_6/components/comp_2.html
Just copy the first cell of the first line of the first table (in the north panel) - the cell with value "(Phe)CML" and you will copy the value 3, instead of "(Phe)CML" itself.
Thanks in advance!

you can use the beforeCopy hook.
var annotationTableSettings = {
data: componentAnnotation,
beforeCopy: data => {
for (let i = 0; i < data.length; i++) {
for (let j = 0; j < data[i].length; j++) {
if (!isNaN(data[i][j])) {
data[i][j] = v[data[i][j]]
}
}
}
}
columns: [
{renderer: annotationId2StringRenderer},
...

Related

Can you set the mergedCells property in Kendo UI for jQuery ooxml.Workbook.sheets without range name?

I am having an issue merging cells that are in an existing sheet in a workbook. My attempt to use mergedCells after the sheet is created has presented a roadblock, I can't seem to get the range name in string format as documented for the mergedCells option in Workbook.sheet:
mergedCells: ["A6:A8"]
All I have are indexes of the cells.
I have the logic to determine which cells' indexes I want to merge, but only the indexes. I can't figure out a way to get the range in an Excel cell name/string like "A1". In the following example, ignoring how I got the index values, I can't merge the cells based on index where indexA is the column and indexB1 and indexB2 are rows.
let indexA = 0;
let indexB1 = 5;
let indexB2 = 7;
sheet.mergedCells = [[{indexA, indexB1},{indexA,indexB2}]]
I have attached a picture of the types of cells I want to merge that are in my workbook, my loop first hits A6 through A8 and determines the indexes are to be merged because all the cells' values equal "Boat". Any help is appreciated, and I will try to provide more detail if needed, but it is difficult to provide much more because of the nature of the system I am on.
Thanks in advance.format of workbook
So you have the R1C1 notation of the cells you need to merge? If so, following the suggestion in this thread you can generate the range in A1 notation - example:
function columnName(index) {
var cname = String.fromCharCode(65 + ((index - 1) % 26));
if (index > 26)
cname = String.fromCharCode(64 + (index - 1) / 26) + cname;
return cname;
}
var r1 = 2;
var c1 = 3;
var r2 = 4;
var c2 = 5;
var rangeAsString = `${columnName(c1)}${r1}:${columnName(c2)}${r2}`;
var workbook = new kendo.ooxml.Workbook({
sheets: [{
mergedCells: [rangeAsString],
rows: [
{ cells: [ { value: "Document Title" } ] },
{ cells: [ { value: 22 }, { value: 33 }, { value: 44 }, {value: 55} ] }
]
}]
});
kendo.saveAs({
dataURI: workbook.toDataURL(),
fileName: "Test.xlsx"
});

Google script pushing data from one tab to another while retaining data validation

I have the following google apps script. It functions to look in my PENDING-IP tab and check the status (column G). If the status is "Screened - Ready for Review," then it moves the entire row of data to the SCREENED - READY FOR REVIEW tab.
My problem is this - the data in columns L, M, and N of the PENDING tab is a checkbox, but when it pushes it to the SCREENED tab, it changes it to TRUE or FALSE. Is there a way to modify my script to push the data with validation to retain the checkboxes? Thank you!
function screened() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName('PENDING-IP'); //source sheet
var testrange = sheet.getRange('G:G'); //range to check
var testvalue = (testrange.getValues());
var csh = ss.getSheetByName('SCREENED - READY FOR REVIEW'); //destination sheet
var data = [];
var j =[];
//Condition check in G:G; If true copy the same row to data array
for (i=0; i<testvalue.length;i++) {
if ( testvalue[i] == 'Screened - Ready for Review') {
data.push.apply(data,sheet.getRange(i+1,1,1,25).getValues());
//Copy matched ROW numbers to j
j.push(i);
}
}
//Copy data array to destination sheet
csh.getRange(csh.getLastRow()+1,1,data.length,data[0].length).setValues(data);
//Delete matched rows in the source sheet
for (i=0;i<j.length;i++){
var k = j[i]+1;
sheet.deleteRow(k);
//Alter j to account for deleted rows
if (!(i == j.length-1)) {
j[i+1] = j[i+1]-i-1;
}
}
}
Try this
I haven't actually tested this except in a simpler situation
function screened() {
var ss=SpreadsheetApp.getActive();
var sheet=ss.getSheetByName('PENDING-IP');
var testrange=sheet.getRange(1,7,sheet.getLastRow(),1);
var testvalue=testrange.getValues();
var valids=testrange.getDataValidations();
var csh = ss.getSheetByName('SCREENED - READY FOR REVIEW'); //destination sheet
var data = [];
var valid = [];
var j =[];
var d=0;
for (var i=0;i<testvalue.length;i++) {
if (testvalue[i][0] == 'Screened - Ready for Review') {
data.push(sheet.getRange(i+1-d,1,1,25).getValues());//I am not sure but I could see having to put [0] at the end here
valid.push(sheet.getRange(i+1-d,1,1,sh.getLastColumn()).getDataValidations());//I am not sure but I could see having to put [0] at the end here
sheet.deleteRow(i+1-d++);//this should delete matching rows
}
}
csh.getRange(csh.getLastRow()+1,1,data.length,data[0].length).setValues(data);
csh.getRange(csh.getLastRow()+1,1,data.length,data[0].length).setValues(valid);
}
What I've found is that you can treat the validations the same way you treat the data by replacing getValues() with getDataValidations() and setValues() with setValidations();

Frequencies - From fft to file to list using processing

I'm doing a project where I'm outputting the frequencies from real time mic input through fft to a txt doc and then retrieving (or trying to retrieve) them to a list of 4 frequencies. My list array is turning out empty, ie the console prints [] and no numbers in them. Pl tell me what is wrong with the logic/code. This is within the void draw()
for (int i = 0; i<fft.specSize(); i++) {
float freq = fft.getFreq(i);
int freqint = (int) freq;
//println(freqint);
output.println(freqint);}
Scanner input = new Scanner("...\\list.txt");
while (input.hasNextInt()) {
list.get(input.nextInt(4));
}
println(list);
input.close();
Split your taks into subtasks:
get FFT data (and 4 frequencies)
Save/Load float values to disk
Put the 1 and 2 together
It looks like you already have the first part done.
It's unclear what the 4 frequencies are, but you can figure that out on your own.
The part that is confusing is that you call the get FFT data once then try to save it straight to disk. I'm not 100% that's what you mean to do.
Double check if you need to save few samples/seconds worth of FFT data first.
I would imagine a more generic scenario like this:
load previously saved FFT data (if any)
process FFT data (for as long as needed - might need a start/stop boolean) and append
save current FFT data
Moving on to saving and loading data.
You've got a few of options build into Processing for storing data:
Strings via saveStrings()/loadStrings()
CSV Table via saveTable()/loadTable()/Table
JSON via JSONObject/JSONArray and available load/save functions
XML
I recommend reading Daniel Shiffman's Data Tutorial
Dealing with saving/loading floating point values to disk alone,
here's a basic proof of concept snippet using Strings:
int fftSpecSize = 10;//this will be fft.specSize() in your case
String values = "";
for(int i = 0 ; i < fftSpecSize; i++){
//random(1) is a placeholder for fft.getFreq(i);
values += random(1);
//if it's not the last value, add a separator character (in this case space)
if(i < fftSpecSize-1){
values += " ";
}
}
println("values to save:");
println(values);
println();
//save data
saveStrings("fftSingleRead.txt",values.split(" "));
//load data
String[] readValues = loadStrings("fftSingleRead.txt");
//print raw loaded data
println("readValues from .txt file:");
println(readValues);
println();
//parse values:
for(int i = 0 ; i < readValues.length; i++){
float value = float(readValues[i]);
println("readValues[",i,"] = ",value);
}
additionally here's a Table example too:
Table fftValues;
int specSize = 10;
//create a new table
fftValues = new Table();
//add columns - one per FFT bin
for(int i = 0 ; i < specSize; i++){
fftValues.addColumn();
}
//add some data, a row per reading
//create a new row
TableRow newRow = fftValues.addRow();
//add each fft value to the row
for(int fftCount = 0 ; fftCount < specSize; fftCount++){
//placeholder for newRow.setFloat(fftCount,fft.getFreq(fftCount));
newRow.setFloat(fftCount,random(1));
}
//add the row to the table
fftValues.addRow(newRow);
//save to disk
saveTable(fftValues,"fftValues.csv","csv");
//load from disk
Table readValues = loadTable("fftValues.csv","csv");
//access the data that has been saved in the table
for(int rowCount = 0; rowCount < readValues.getRowCount(); rowCount++){
TableRow currentRow = readValues.getRow(rowCount);
print("row[",rowCount,"] = ");
for(int columnCount = 0; columnCount < currentRow.getColumnCount(); columnCount++){
float value = currentRow.getFloat(columnCount);
print(value);
if(columnCount < currentRow.getColumnCount() - 1){
print(",");
}
}
println();
}
Try the code, see the output, read the comments, read the reference, tweak/retry/understand and adapt to your problem.

How do I structure the Data array for the following d3 chart, in order to populate with real data

http://nvd3.org/ghpages/scatter.html
I want to build a chart thats very similar to the above example. I'm still in the beginning phases and am having a little difficulty trying to input my own data, either as a CSV or inline in the code.
I'm pretty sure that the code below is responsible for generating fake data to populate the chart, however, I can't seem to find the correct way to input real data. I've read over the "data" reference portions of the documentation on the d3 site and tried implementing the code but have not been able to get it to work. I believe the problem is structuring. The question is, how do I find out how I need to structure the data array and use that, as input for the data?
Here is the live example of where I'm building my version of the chart.
http://goo.gl/XHela
Here is the code that is generating the random data:
function randomData(groups, points) { //# groups,# points per group
var data = [],
shapes = ['circle', 'cross', 'triangle-up', 'triangle-down', 'diamond', 'square'],
random = d3.random.normal();
for (i = 0; i < groups; i++) {
data.push({
key: 'Group ' + i,
values: []
});
for (j = 0; j < points; j++) {
data[i].values.push({
x: random(),
y: random(),
size: Math.random(),
shape: shapes[j % 6]
});
}
}
return data;
}
Before your response I tried to output the results of the function randomData to the page, using the following code, (the same just modified).
function see(groups, points) { //# groups,# points per group
var data = [],
shapes = ['circle', 'cross', 'triangle-up', 'triangle-down', 'diamond', 'square'],
random = d3.random.normal();
for (i = 0; i < groups; i++) {
data.push({
key: 'Group ' + i,
values: []
});
for (j = 0; j < points; j++) {
data[i].values.push({
x: random(),
y: random(),
size: Math.random(),
shape: shapes[j % 6]
});
}
}
data.toString();
var x=document.getElementById("demo");
x.innerHTML=data;
}
But on the page the output is
[object Object],[object Object],[object Object],[object Object]
I guess the follow up question is how do I use my own data for this chart and not generated data?
You can see how the data is structured by stepping through the code using Chrome Developer tools' console in Chrome. In the page you linked above (first link) Pressing Ctrl + Shift + C in Windows or Command + Shift + c in OSX will bring up this window. Click on Sources and find the file scatter.js from the list of files on the left. Set a break point at the line: return data. Referesh the page. Code execution will pause at that line. Now go the the Console and type data. The data used for the chart will be output. You can browse the structure and get an idea of how it was created.
You should see something like this in the end:

BIRT Palette scripting: How to access dataset row

If I want to change the color of circles in scatter chart based on a field not being used in the chart, then how do i use that column in script. I mean how can i get the that data...for example
If (row[v_count])>2
fill red color...
The exact code is below
function beforeDrawDataPoint(dph, fill, icsc)
{
//Fill implements Fill interface
//ImageImpl
//ColorDefinitionImpl
//GradientImpl
//MultipleFillImpl
//EmbeddedImageImpl
//PatternImageImpl
importPackage( Packages.org.eclipse.birt.chart.model.attribute.impl );
val = dph.getOrthogonalValue();
if( fill.getClass().isAssignableFrom(ColorDefinitionImpl)){
if (row[v_count]>2){
fill.set(255, 0, 0);
}
}
}
but i dont know do i get that v_count column in the script. is there some function to get that column ?
I mean if we are making some calculations based on a column from databinding columns..that is not being used in x or y axis, then how do we access that column in the script..is there some kind of function for that.. I tried row["v_count"], but it is not working.
Arif
You could use "persistent global variables". In any place of your report you can write the following to store and load a global variable. Note that you cannot store Integers but only Strings (but after loading you can cast your Strings back to other types). You could store the Value of your column in the Script of an invisible data field located above your chart, so inside your chart you can read the value.
//store a value
reportContext.setPersistentGlobalVariable("varName", "value");
//load the value
var load = reportContext.getPersistentGlobalVariable("varName");
I spend my day look but I did not find the solution, this is my colleague who give me :)
So I share.
in my example I had to create a vertical marker for every new year
function beforeGeneration(chart, icsc)
{
importPackage(Packages.org.eclipse.birt.chart.model.component.impl);
importPackage(Packages.org.eclipse.birt.chart.model.data.impl);
importPackage(Packages.org.eclipse.birt.chart.model.attribute);
importPackage(Packages.org.eclipse.birt.chart.model.attribute.impl);
var chart = icsc.getChartInstance();
var yAxis = chart.getBaseAxes()[0];
//get date series for my case
series = yAxis.getRuntimeSeries();
// but if you have multiple series ... (for exemple xaxis)
for (i = 0; i < series.length; i++){
var values = series[i].getDataSet().getValues();
for (j = 0; j < values.length; j++){
if(j > 1){
var date1 = values[j-1];
var date2 = values[j];
if(date1.getYear() < date2.getYear()){
min_ml = MarkerLineImpl.create(yAxis, NumberDataElementImpl.create(j));
min_ml.getLabel().getCaption().setValue("Nouveau boitier");
min_ml.getLineAttributes().getColor().set(255,0,0);
}
}
}
}
}

Resources