How to define a slider with dynamic range min/max of data to filter rows - iccube

I am trying to define a filter on rows based on a slider filter where its range is min/max of a given measure instead of the beginning and end of the data (the default behaviour).

slider widget was designed to select ranges of level members, so it doesn't support selection over measure values. You can either try to create own widget based on slider or use statical defined data as in How to use a static range and display members according a TOP(x) style query, just change:
function consumeEvent( context, event ) {
if (event.name == 'ic3-report-init') {
// Following code will replace a data provider for Slider
// with generated numbers. But to do so, you'll need UID of
// the Slider widget, in this example it's "w1"
var widget = event.value.widgetMgr().getItemById("w1");
_.assign(widget.builder().guts_, {
items:_.times(STEPS_COUNT, function(idx){
return {
name:MIN_VALUE + idx * STEP_SIZE,
uniqueName:idx
}
})})
}
}
define STEPS_COUNT, MIN_VALUE, STEP_SIZE.
After that you can try to apply event value as the filter to your MDX

Related

How to use MDX constants/functions in icCube Reporting?

I have several functions/constants defined in the schema. An example is:
_latestPeriodWithData() which returns a date.
Goal: I want to use this value in the Reporting to set a Guide in a chart, using the demo example 'On Widget Options':
This is what I tried so far:
I have assigned this function as 'MDX / Value' for a Report Constant _lastDate and obtained the value for this constant using the java script function: context.eventValue('_lastDate'); but that just gives me the caption. The function context.eventObject("_lastDate").options.asMdx gives me _latestPeriodWithData(), but not its value.
On Widget Options
/**
* Result will be used while rendering.
*/
function(context, options, $box) {
// for debugging purpose
console.log(context.eventObject("_lastDate").options.asMdx);
options.guides[0].value = context.eventObject("_lastDate").options.asMdx; // <-- gives me _latestPeriodeWith data
// but not its value
options.guides[0].toValue = context.eventObject("_lastDate").options.asMdx;
options.guides[0].lineAlpha = 1;
options.guides[0].lineColor = "#c44";
return options;
}

How can I make a button within Google Sheets that toggles the values 1 and 0 in a destination cell?

I am trying to learn to do basic buttons within a spreadsheet to help with a project at school. I am a simple teacher that is trying to find resources to help. I have learned how to create a button that adds one or subtracts one with the value which will allow me to do what I need to do, but ideally I am looking for script code to make a button that would toggle between the values of 1 and 0 upon pressing the button.
Thanks for any help.
function plus1() {
SpreadsheetApp.getActiveSheet().getRange('A1').setValue(
SpreadsheetApp.getActiveSheet().getRange('A1').getValue() + 1
);
}
I believe your goal as follows.
You want to switch the number of 1 and 0 at the cell "A1" on the active sheet by clicking a button.
In this case, at first, it is required to retrieve the value from the cell "A1" on the active sheet. And, the value is put by checking the retrieved value. So how about the following sample script?
Sample script:
function sample() {
var range = SpreadsheetApp.getActiveSheet().getRange('A1');
var value = range.getValue();
if (value == 1) {
range.setValue(0);
} else if (value == 0) {
range.setValue(1);
}
}
In this case, when the cell "A1" is not 1 or 0, the value in the cell is not modified.
References:
getValue()
setValue(value)
if...else
function toggleActiveCell() {
const sh=SpreadsheetApp.getActiveSheet();
const rg=sh.getActiveCell();
rg.setValue(rg.getValue()?0:1);
}
function toggleUniqueCell() {
const sh=SpreadsheetApp.getActiveSheet();
const rg=sh.getRange(row,col);
rg.setValue(rg.getValue()?0:1);
}

Very simple if else check in Google App Maker

This is likely embarrassingly easy but I'm new and I've been beating my head against the wall on this for a while now. What I am attempting to do is basically a modified version of the "Hello App Maker!" If else test.
The necessary info I have the following widgets attached to the appropriate data sources:
Dropdown widget called source_name (string - list)
Label widget I've called name (string)
Text Box widget called qty_duration (number)
Label widget I've called hours (number)
I have a dropdown widget called source_name with 5 options. On selection I have the value appear in a label widget I've called name. If the option selected from the drop down widget is ever LABOUR I am trying to then have the value of a Text Box widget called qty_duration appear in a label widget I've called hours
On the source_name dropdown event - onValueChange I have the following code:
// Define variables for the input and output widgets
var nameWidget = app.pages.Apex_job_details.descendants.name;
var outputWidget = app.pages.Apex_job_details.descendants.hours;
var techhours = app.pages.Apex_job_details.descendants.qty_duration;
var nothing = 0;
// If a name is LABOUR, add the qty to the output widget Else output 0.
if (nameWidget == 'LABOUR') {
outputWidget.text = techhours;
} else {
outputWidget = nothing;
}
It's not giving me any errors, but it's also not outputting to the hours label. If I edit the code as follows just to muck with it:
// Define variables for the input and output widgets
var nameWidget = app.pages.Apex_job_details.descendants.name;
var outputWidget = app.pages.Apex_job_details.descendants.hours;
var techhours = app.pages.Apex_job_details.descendants.qty_duration;
var nothing = 0;
// If a name is LABOUR, add the qty to the output widget Else output 0.
if (nameWidget == 'LABOUR') {
outputWidget.text = techhours;
} else {
outputWidget.text = nothing;
}
I'm not sure what I'm doing wrong.
Assuming all labels and input widgets are inside a table row you will want to adjust your code as follows:
var tablerow = widget.parent;
var nameWidget = tablerow.descendants.name.text;
var outputWidget = tablerow.descendants.hours;
var techhours = tablerow.descendants.qty_duration.value;
if(nameWidget === 'LABOUR') {
outputWidget.text = techhours;
} else {
outputWidget.text = null;
}
By using widget.parent in the onValueChange event of the dropdown you will automatically reference the table row and then by using descendants you are referencing only the descendants of that table row. This will bridge the error by using an absolute reference when using table rows. If it still doesn't work let me know.

One item per line (row) in timeline? - Vis.js

Is there a way to always have one item per line in the timeline? I don't want two or more items to share the same line, whatever the dates are.
Thanks.
You have to use groups, or if you're already using those for another purpose, you have to use subgroups.
Here's the official documentation for items, groups and subgroups (I'm assuming the website isn't gonna expire anytime soon... again...).
If you can use groups
Specify a different group for every item. You can set the group's content as an empty string, if you don't want to have a label for it on the left side of the Timeline.
If you want to arrange the groups in a specific way, specify an ordering function as the Timeline's options' groupOrder property. Example:
var options = {
// other properties...
groupOrder: function (a, b) {
if(a.content > b.content)// alphabetic order
return 1;
else if(a.content < b.content)
return -1;
return 0;
}
};
If you have to use subgroups
When you create an item, put it in the group it belongs to but also specify for it the subgroup property so that it's unique, like the item's id. For example, you can use the id itself, or add a prefix or suffix to it.
In the Timeline's options, set the stack and stackSubgroups properties to true.
In each group, set the subgroupStack property to true and specify an ordering function as the group's subgroupOrder property. Example:
var group = {
id: 1,
content: 'example group',
subgroupStack: true,
subgroupOrder: function(a, b) {
var tmp = a.start.getTime() - b.start.getTime();
return tmp === 0 ? parseInt(a.id) - parseInt(b.id) : tmp;
// if the start dates are the same, I compare the items' ids.
// this is because due to a bug (I guess) the ordering of items
// that return 0 in the ordering function might "flicker" in certain
// situations. if you want to order the items alphabetically in that
// case, compare their "content" property, or whatever other
// property you want.
}
};

Can I just style decimals of a number in Angular?

I am trying to style just the decimals to look just like this:
Didn't had success, I guess that I need to make my own filter, tried but didn't had success either, I guess it is because I am using it inside a state.
Here the code I am using for the number:
<h2><sup>$</sup>{{salary | number:0}}<sub>.00</sub></h2>
Inside the .app iam using this scope:
$scope.salary = 9000;
Thing is, number can be whatever the user salary is, it get the number from an input, in other places I have more numbers with decimals too.
Possible solutions:
Extract only the decimals from value and print them inside de
tag.
Use a filter to do this?
Use a directive that will split the amount and generate the proper HTML. For example:
app.directive('salary', function(){
return {
restrict: 'E'
, scope: {
salary: '#'
}
, controller: controller
, controllerAs: 'dvm'
, bindToController: true
, template: '<h2><sup>$</sup>{{ dvm.dollar }}<sub>.{{ dvm.cents }}</sub></h2>'
};
function controller(){
var parts = parseFloat(this.salary).toFixed(2).split(/\./);
this.dollar = parts[0];
this.cents = parts[1];
}
});
The easiest solution would be to split out the number into it's decimal portion and the whole number portion:
var number = 90000.99111;
console.log(number % 1);
Use this in your controller, and split your scope variable into an object:
$scope.salary = {
whole: salary,
decimal: salary % 1
}
Protip: Using an object like this is better than using two scope variables for performance

Resources