BloX - Dropdown list as a dashboard filter
Introduction: The below article will provide a BloX template that will help you create a dropdown filter The ‘Dynamic Dropdown’ snippet allows you to populate your dropdown list with a list of values from a specific field (for example, list of Brands). The structure of the attached template is 3 columns, with 3 containers (in order to place the 3 components in one row, and not one below the other). Instructions: Create a JSON file with the code provided below Open your dashboard and add the dashboard filter you would like to affect Open a BloX widget. Click on the menu icon -> Import template, then choose the created file - Refresh your browser Create a new BloX widget and choose the imported template – Add the field you would like to filter by under 'Items' section Widget's editor section: Replace the "Brand" in: "choices" with the exact field name you have placed in the panel in order to get the list of values (you can use ctrl+f to find it). For example: "{choices:Brand}" with" {choices:My_Field}" Replace the "Brand" of "filterName": "Brand" with the exact name of the dashboard filter you have added and want to affect Optional: Go to the widget's 'Filters' tab and toggle off the "dashboard filters" so it will not affect this widget (this way you will be able to see the entire list of values anytime) If you would like to display a specific value as a default one (instead of the first value in your list), you can write the exact name of the value here – 10. Please note that the above ID field ("id": "data.filters[0].filterJaql.members[0]") relates to the below action path - CAROUSEL In order to show the widget’s components only once, and avoiding a stacked view according to our number of values, we are showing the carousel but hiding the arrows - Additional Configuration: If you want BloX widget to be populated with the current filter value, please try to use the script below. You need to update filter index if it is not the first filter on the dashboard in …dashboard.filters.$$items[x]. widget.on('ready', ()=>{ $(`widget[widgetid="${widget.oid}"]`).find('select').val(widget.dashboard.filters.$$items[0].jaql.filter.members[0]) }) DynamicChoiceDropDown.json: { "card": { "style": {}, "script": "", "title": "", "titleStyle": [ { "display": "none" } ], "showCarousel": true, "carouselAnimation": { "showButtons": false }, "body": [ { "type": "Container" }, { "type": "ColumnSet", "separator": false, "spacing": "default", "columns": [ { "type": "Column", "width": "170px", "items": [ { "type": "TextBlock", "size": "small", "weight": "regular", "wrap": true, "text": "Choose a Brand", "style": { "color": "black", "padding-left": "10px", "margin-left": "10px", "backgroundColor": "white" } } ] }, { "type": "Column", "spacing": "none", "width": "175px", "items": [ { "type": "Container", "spacing": "none", "width": "150px", "items": [ { "type": "Input.ChoiceSet", "id": "data.filters[0].filterJaql.members[0]", "class": "", "value": "Reseller", "displayType": "compact", "choices": "{choices:Brand}" } ] } ] }, { "type": "Column", "spacing": "none", "width": "175px", "items": [ { "type": "Container", "spacing": "none", "width": "80px", "items": [ { "type": "ActionSet", "margin": "0px", "padding": "0px", "actions": [ { "type": "Filters", "title": "Apply", "data": { "filters": [ { "filterName": "Brand", "filterJaql": { "explicit": true, "members": [ "" ] } } ] } } ] } ] } ] } ] } ], "actions": [] }, "config": { "fontFamily": "Open Sans", "fontSizes": { "default": 14, "small": 16, "medium": 20, "large": 50, "extraLarge": 32 }, "fontWeights": { "default": 500, "light": 100, "bold": 1000 }, "containerStyles": { "default": { "backgroundColor": "#FFFFFF", "foregroundColors": { "default": { "normal": "#3a4356" }, "white": { "normal": "#ffffff" }, "grey": { "normal": "#9ea2ab" }, "orange": { "normal": "#f2B900" }, "yellow": { "normal": "#ffcb05" }, "black": { "normal": "#000000" }, "lightGreen": { "normal": "#3ADCCA" }, "green": { "normal": "#54a254" }, "red": { "normal": "#dd1111" }, "accent": { "normal": "#2E89FC" }, "good": { "normal": "#54a254" }, "warning": { "normal": "#e69500" }, "attention": { "normal": "#cc3300" } } } }, "imageSizes": { "default": 40, "small": 40, "medium": 80, "large": 160 }, "imageSet": { "imageSize": "medium", "maxImageHeight": 100 }, "actions": { "color": "white", "backgroundColor": "", "maxActions": 5, "spacing": "none", "buttonSpacing": 20, "actionsOrientation": "horizontal", "actionAlignment": "left", "showCard": { "actionMode": "inline", "inlineTopMargin": 16, "style": "default" } }, "spacing": { "default": 5, "none": 0, "small": 20, "medium": 60, "large": 20, "extraLarge": 40, "padding": 0 }, "separator": { "lineThickness": 3, "lineColor": "#ffcb05" }, "factSet": { "title": { "size": "default", "color": "default", "weight": "bold", "warp": true }, "value": { "size": "default", "color": "default", "weight": "default", "warp": true }, "spacing": 20 }, "supportsInteractivity": true, "height": 49, "imageBaseUrl": "" } }6.9KViews0likes6CommentsBloX - Executive Dashboard Example
Article Topics: Tabs to switch between dashboards Indicators + Conditional Formatting Switch between widgets- Including modeling solution (Alternative for Tabber plugin) Tabs to switch between dashboards: Add an action type "jump to dashboard" - the new dashboard will open within the current tab { "type": "ActionSet", "actions": [ { "type": "JTD", "title": "Dashboard 1", "data": { "dashboardId": "5e8ad317dcb7732288a129da", "panelsToInclude": [], "args": { "displayDashboardsPane": false, "displayFilterPane": true, "drilledDashboardDisplayType": 3 } } } ] } The "drilledDashboardDisplayType" parameter determines if the new page opens in the same window, new tab, or lightbox modal. Read more about this parameter in the jump to dashboard official documentation. Indicators + Conditional Formatting: 1. Add Value with the condition, using CASE WHEN and Name it "Color1": case when ([Total Cost]) > 950000 then 1 else 0 end 2. Change the "contatingerStyles" in the configuration tab based on the condition: "1": { "normal": "#dd1111" } 3. Add a TextBlock - use "color" : "{value:Color1}" to apply the color conditional formatting { "type": "Column", "items": [ { "type": "TextBlock", "spacing": "medium", "text": "Sales", "color": "grey", "size": "extraLarge", "horizontalAlignment": "center", "weight": "default" }, { "type": "TextBlock", "spacing": "medium", "text": "{panel:Sales}$", "color": "{value:Color1}", "horizontalAlignment": "center", "weight": "center", "size": "large" } ] } Switch between widgets (Including modeling solution): 1. Add the relevant Filter buttons: { "type": "Filters", "title": "Days", "data": { "filters": [ { "filterName": "WidgetType", "filterJaql": { "explicit": true, "userMultiSelect": false, "multiSelection": false, "members": [ "Days" ] } } ] } } 2. Add a TextBlock and change the the "src" to the relevant dashboard URL and replace the widgetID with {panel:widgetID} { "type": "TextBlock", "id": "", "class": "", "text": "<iframe src='https://10.122.10.132/app/main#/dashboards/5e8b54e92f58dd2294029d28/widgets/{panel:widgetID}?embed=true&r=false&l=false&t=false&h=false' width='100%' height='600' style='border:none;overflow:hidden'></iframe>" } 3. Create a new table in your data model using this SQL or as a CSV file and map the relevant widgetIDs to the filter name & EC build changes only: select 'Days' as WidgetType , '5e8b54e92f58dd2294029d29' as widgetID union select 'Week' , '5e8b55012f58dd2294029d35' union select 'Month' , '5e8b55042f58dd2294029d37' 4. Add "WidgetType" column as a filter: Attachments: 1. Main Dashboard - 1stexample.dash 2. Line chart widgets to switch - WidgetSwitch-1stexample.dash4KViews0likes0CommentsChange Date Granularity of a Widget using BloX
This article will cover the below options: Section 1- Buttons + Highlight Background-Color - Creating Buttons of date granularity slicing options (Alternative for Tabber plugin) OR Section 2 - Dropdown List - Creating Drop-down list with Date granularity slicing options (Alternative for Tabber plugin) ------------------------------------------------------------------------ Section 1- Buttons + Highlight Background-Color: You can follow the steps below or download the dashboard file , import it and create a custom action as described in Step 2. (Buttons-DateGranularityBloX.dash) Step 1: Create a BloX widget and use this snippet in the Editor tab: (or import this JSON file as a BloX template) Provide the widget ID to apply the change, you can apply on multiple widgets : "widgetToModify": ["5f7b91e27051052128453cdf","5f7b91e27051052128sdfcer"] "style": "", "script": "", "title": "", "titleStyle": [ { "display": "none" } ], "showCarousel": true, "body": [], "actions": [ { "type": "dynamicGranSwap", "title": "Years", "style": { "background-color": "#1D426C" }, "data": { "widgetToModify": [ "5f7b91e27051052128453cdf" ] }, "dategran": "years" }, { "type": "dynamicGranSwap", "title": "Quarters", "style": { "background-color": "#D3D3D3" }, "data": { "widgetToModify": [ "5f7b91e27051052128453cdf" ] }, "dategran": "quarters" }, { "type": "dynamicGranSwap", "title": "Months", "style": { "background-color": "#D3D3D3" }, "data": { "widgetToModify": [ "5f7b91e27051052128453cdf" ] }, "dategran": "months" }, { "type": "dynamicGranSwap", "title": "Weeks", "style": { "background-color": "#D3D3D3" }, "data": { "widgetToModify": [ "5f7b91e27051052128453cdf" ] }, "dategran": "weeks" }, { "type": "dynamicGranSwap", "title": "Days", "style": { "background-color": "#D3D3D3" }, "data": { "widgetToModify": [ "5f7b91e27051052128453cdf" ] }, "dategran": "days" }, { "type": "dynamicGranSwap", "title": "Hours", "style": { "background-color": "#D3D3D3" }, "data": { "widgetToModify": [ "5f7b91e27051052128453cdf" ] }, "dategran": "minutes" } ] } Step 2: Create a custom action with the below code and name it "dynamicGranSwap": Adjust the background color of unselected & selected buttons // Holds the chosen granularity from the selected button 'months' for example const dategran = payload.dategran; var widgetIds = payload.data.widgetToModify; //Change the background color for unselected buttons payload.widget.style.currentCard.actions.forEach(function(i){ i.style["background-color"] = '#D3D3D3' }) //Change the background color for selected buttons payload.widget.style.currentCard.actions .filter(i => i.dategran == dategran)[0].style["background-color"] = "#1D426C" //Redraw the changes payload.widget.redraw() //For each widget change the data granularity payload.widget.dashboard.widgets.$$widgets .filter(i=>widgetIds.includes(i.oid)) .forEach(function(widget){ //change the level of granularity to the chosen value from our button: 'months' for example widget.metadata.panels[0].items[0].jaql.level = dategran; //Apply changes to Mongo widget.changesMade() //Refresh widget widget.refresh() }) Section 2 - Dropdown List: You can follow the steps below or download the dashboard file , import it and create a custom action as described in Step 2. (DateGrnularityBloX.dash) Step 1: Create a BloX widget and use this snippet to create the choice-set: { "type": "Input.ChoiceSet", "id": "data.choicesetvalue", "class": "", "displayType": "compact", "value": "1", "choices": [ { "title": "Hours", "value": "minutes" }, { "title": "Days", "value": "days" }, { "title": "Weeks", "value": "weeks" }, { "title": "Months", "value": "months" }, { "title": "Quarters", "value": "quarters" }, { "title": "Years", "value": "years" } ] } Step 2: Create a custom action with the below code and name it "DateGranDrill" (provide the widget ID to apply the change - can apply on multiple widgets): var gran = payload.data.choicesetvalue // Holds the chosen granularity 'months' for example var widgets = ['5ec291c181203611649756f6','5ec291c121803611649756c7'] //Apply this action on widget ids //for each widget id widgets.forEach(myfunction) function myfunction (item) { var widgetfindid = prism.activeDashboard.widgets.$$widgets.find(w => w.oid === item) widgetfindid.metadata.panels[0].items[0].jaql.level = gran //change the level of granularity to the chosen value 'months' for example or the item location (currently 0) widgetfindid.changesMade() //apply changes to Mongo widgetfindid.refresh() //refresh the widget } Step 3: Use the action you've created in the editor under "actions" section: "actions": [ { "type": "DateGranDrill", "title": "Apply" } ]3.6KViews3likes8CommentsSisense BloX Custom Actions Guide
Sisense BloX 2.0 has introduced custom actions. These answer any need for interactivity that is not met by the 5 native action types. Once an action is created, its snippet is added to the “My Actions” section of the actions tab, and it can be called, updated or deleted by any designer working in Sisense. When creating a custom action, you may use pure JavaScript syntax as well as libraries used in Sisense, such as jQuery, underscore.js, and moment.js. The action can access prism and other global variables. Upon saving, the action's, code goes through Babel, transforming it into ES5 for cross-browser compliance purposes. This transformation is transparent to the designers, that will still see their original syntax any time they choose to edit the action. Payload Custom actions can use an argument named payload to access most of their relevant information. We’ll review a few important payload properties that any action will be able to access: Container: The DOM element holding the widget body. Can be very useful for jQuery selectors. Data: The action’s data property. When you define a new custom action, the best practice is to populate the data property with all attributes and variables that you would like your action to get from the card. This is also where all input fields’ values are contained. <link to populating data> Result: Contains the data panels of the specific card that triggered the action. For the full widget result set, it is better to access payload.widget.queryResult. Widget: The Sisense BloX widget object. You can use this object to access the widget’s structure and result set as well as the parent dashboard and its attributes (filters, other widgets in the dashboard, etc.) In addition to the above native properties, the payload will also contain any property that will be added to the action (see example below). Creating An Action To create a custom action, open the editor’s main menu and choose “Create Action”. The design panel Should now turn into a Javascript editor. Give your action a javascript-friendly name, preferably camel cased. Now you can define your action’s functionality. Click Next to go to the next step and define your action’s snippet. As snippets were meant to help designers add elements and actions to their cards, it’s crucial to make sure that yours includes all of the inputs that your action needs to run properly. Once saved, the action and snippets will be saved on the Sisense application DB and will be visible to all other designers in the Sisense BloX actions tab. Copy the snippet to the clipboard and paste it to an action container in the Sisense BloX editor to test it. You can find the snippets for action containers in the Actions tab’s Action Buttons section. If any inputs were included, such as the text attribute, adjust their values to this action button’s specific requirements. Now, click on one of the action buttons to trigger it. In our case, we will see out action’s output in the browser’s JavaScript console: Editing and Deleting Actions Any designer can currently edit or delete existing custom actions. To do so, find your action in My Actions section, click on the menu button on the rightmost of the screen and choose the desired option from the dropdown menu. In case you are using widgets and Blox scripts please remember: 1. Widget script: executed before the widget is initialized (when you open a dashboard or refresh the page). That's a good place to create widget event handlers, or create parameters that you only need to define once regardless of result sets. 2. BloX script tag: runs every time the BloX widget is rendered and loaded to the screen (includes filters update, screen resizing and anything that triggers redrawing of the BloX widget). This is a good place to execute scripts that should run every time the view is loaded (for example: selecting elements from the DOM and applying different manipulations on them).3.3KViews2likes1CommentChanging Measures In The Entire Dashboard Using Blox User Interface
Objective Display several related values (KPIs/Measures) in multiple widgets in the dashboard based on the user selection, in a simple and easy way, without duplicating widgets/formulas or tables in the Elasticube. As a direct result - the queries behind the widgets are extremely faster - lead to shorter loading time when the end-user needs to change the whole dashboard KPIs. Example files (works with Ecommerce Sample Elasticube): Dashboard Blox Template Blox Action Demonstration: Preparation Create a new Indicator widget and save its WidgetId. Create a custom action with this code below and name it SwitchMeasure var dimIndex = payload.data.selectVal - 1; var dimToSwapTo = payload.widget.metadata.panels[1].items[dimIndex].jaql; var widgetIds = payload.data.widgetToModify; payload.widget.dashboard.widgets.$$widgets .filter(i=>widgetIds.includes(i.oid)) .forEach(function(widget){ if(widget.metadata.panels[1].$$widget.type == 'indicator') { widget.metadata.panels[0].items[0].jaql = dimToSwapTo; } else { widget.metadata.panels[1].items[0].jaql = dimToSwapTo; } widget.changesMade(); widget.refresh(); }) Implementation 1. ADDING MEASURES TO SWITCH BETWEEN The formulas in the values panel define the measures your other widgets will switch between. Create a new Blox widget and add all the formulas (Up to 20 Formulas) you want to switch between into the values panel in the selection of the button Blox widget. Please pay attention to the order (top value to bottom -> left to right buttons) 2. CUSTOMIZING THE BUTTONS SELECTION WIDGET This step will define the values that are visible to the user in the button selection widget. -Add choices that reflect the ORDER and intuitive name the formulas in the values panel. -Add the widget IDs of the widgets you'd like to modify to the script of each option. You can find the widget ids in the URL when in widget editing mode. -Change the button color by editing the Background color for each option. For example, we will be switching between Revenue, Cost, and Quantity, our Blox script would be: { "style": "", "script": "", "title": "", "showCarousel": true, "titleStyle": [ { "display": "none" } ], "carouselAnimation": { "delay": 0, "showButtons": false }, "body": [ { "type": "TextBlock", "id": "", "class": "", "text": " " } ], "actions": [ { "type": "SwitchMeasure", "title": "Revenue", "style": { "backgroundColor": "#298C1A" }, "data": { "widgetToModify": [ "5f1b462e336d9c242cb9e8ea", "5f1b462e336d9c242cb9e8e5", "5f1b462e336d9c242cb9e8e7", "5f1b462e336d9c242cb9e8e9", "5f1b462e336d9c242cb9e8e8" ], "selectVal": "1" } }, { "type": "SwitchMeasure", "title": "Cost", "style": { "backgroundColor": "#A31818" }, "data": { "widgetToModify": [ "5f1b462e336d9c242cb9e8ea", "5f1b462e336d9c242cb9e8e5", "5f1b462e336d9c242cb9e8e7", "5f1b462e336d9c242cb9e8e9", "5f1b462e336d9c242cb9e8e8" ], "selectVal": "2" } }, { "type": "SwitchMeasure", "title": "Quantity", "style": { "backgroundColor": "#708AA5" }, "data": { "widgetToModify": [ "5f1b462e336d9c242cb9e8ea", "5f1b462e336d9c242cb9e8e5", "5f1b462e336d9c242cb9e8e7", "5f1b462e336d9c242cb9e8e9", "5f1b462e336d9c242cb9e8e8" ], "selectVal": "3" } } ] } 3. CUSTOMIZING THE BUTTON SELECTION ANIMATION Add the script (widget script) below to the indicator you created in the preparation section: Change the WidgetID to your indicator Widget ID Change the formula names based on the value list from the buttons selection widget Change the button’s titles based on the titles you selected the buttons selection widget //Widget Script: var ChooseYourUnselectColor = '#D3D3D3'; var Button1Color = '#298C1A'; var Button2Color = '#A31818'; var Button3Color = '#708AA5'; var widgetIndicator = '5f1b462e336d9c242cb9e8ea' widget.on('ready',function(widget, args){ var widgetOID = widgetIndicator; //Get the selected KPI object var widget = prism.activeDashboard.widgets.$$widgets.find(w => w.oid === widgetOID) if(widget.metadata.panels[0].items[0].jaql.title == 'Total Revenue'){ var textOfButtonToFormat1 = 'Cost'; var textOfButtonToFormat2 = 'Quantity'; var selectedButton = 'Revenue' $('button.btn:contains('+textOfButtonToFormat1+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": ChooseYourUnselectColor }); $('button.btn:contains('+textOfButtonToFormat2+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": ChooseYourUnselectColor }); $('button.btn:contains('+selectedButton+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": Button1Color }); } else if (widget.metadata.panels[0].items[0].jaql.title == 'Total Cost') { var textOfButtonToFormat1 = 'Revenue'; var textOfButtonToFormat2 = 'Quantity'; var selectedButton = 'Cost' $('button.btn:contains('+textOfButtonToFormat1+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": ChooseYourUnselectColor }); $('button.btn:contains('+textOfButtonToFormat2+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": ChooseYourUnselectColor }); $('button.btn:contains('+selectedButton+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": Button2Color }); } else { var textOfButtonToFormat1 = 'Revenue'; var textOfButtonToFormat2 = 'Cost'; var selectedButton = 'Quantity' $('button.btn:contains('+textOfButtonToFormat1+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": ChooseYourUnselectColor }); $('button.btn:contains('+textOfButtonToFormat2+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": ChooseYourUnselectColor }); $('button.btn:contains('+selectedButton+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": Button3Color }); } })3.2KViews0likes9CommentsUsing BloX To Dynamically Change A Dimension
The goal is to allow users to dynamically choose a dimension. The below script will work with a table or a pivot table, but it can be modified to work with other widget types as well. Step 1 Create a BloX widget with the below script. It will consist of a simple drop down input and an action button. { "style": "", "script": "", "title": "", "showCarousel": true, "carouselAnimation": { "delay": 0, "showButtons": false }, "body": [ { "type": "Container", "items": [ { "type": "TextBlock", "id": "", "class": "", "text": "Choices", "style": { "margin-left": "100px", "margin-right": "100px" } }, { "type": "Input.ChoiceSet", "id": "dropdownVal", "class": "", "displayType": "compact", "value": "1", "choices": "{choices:colName}", "style": { "margin-left": "100px", "margin-right": "100px" } } ] } ], "actions": [ { "type": "Modify Pivot", "title": "Change Dimension" } ] } Please note: In the above example, the drop down choices are coming from the field 'ColName.' The values in ColName exactly match the target field names in the ElastiCube. The drop down choices could be input manually, but they must exactly match the target field names in the ElastiCube. Step 2 Create a table, or pivot table. In this example, I have added two columns. The title in the example is 'Test Widget Title.' Step 3 Using the console, determine the widget index and target panel. First, open the developer console and type: prism.activeDashboard.widgets.$$widgets You will see a list of all widgets on a dashboard. Look for the correct title or widget type. Note the widget index (it is 6, in this example). Second, navigate to: prism.activeDashboard.widgets.$$widgets[6].metadata.panels There, note the index of the panel we would like to modify. In this example, we want to modify a column, that is the first object in panels (index = 0). Finally, open 'Items.' Each item is a field that was added to the columns panel in the target widget. Note the index of the field we want to change. In the example, we want to change the second column (index = 1). Step 4 Create a custom BloX action to target the correct panel item and change it to the user input value. Use the below script for the action: //Variable that stores the user's input var dropdownInput = payload.data.dropdownVal; //Variable that stores the target widget var widget = prism.activeDashboard.widgets.$$widgets[6]; widget.metadata.panels[0].items[1].field.id = "[Exports." + dropdownInput + "]"; widget.metadata.panels[0].items[1].jaql.dim = "[Exports." + dropdownInput + "]"; widget.metadata.panels[0].items[1].jaql.title = dropdownInput; widget.metadata.panels[0].items[1].jaql.column = dropdownInput; //Refresh widget widget.refresh(); The following lines will need to match the incidences from step three. var widget = prism.activeDashboard.widgets.$$widgets[6]; widget.metadata.panels[0].items[1].x You can see the above custom action changes four things about the panel item. Please note: the below lines must match the table name where the field resides. Replace it with the appropriate table name: "[Exports." That's it! Apply all changes and the drop down filter should change the field in the second column of the table! If you wish to change a dimension in a different chart, be sure to look for the correct panel in step 3.2.9KViews0likes6CommentsUsing BloX Buttons - Changing Date Granularity Of Widgets In A Dashboard
This article covers the steps to change the date granularity of a widget using BloX actions along with the dropdown input of BloX. In this post, we shall achieve the functionality with the help of single-select BloX buttons that has some color animations. STEP 1: CREATING ACTION WITH LIST OF WIDGETS TO BE AFFECTED On a dashboard, create a BloX widget. Using the BloX widget, create an action with code below and name the action "dategran_buttons". Note: you need to include the widget IDs of all the widget you'd want to get affected using the BloX date granularity changer. const dategran = payload.dategran; // Holds the chosen granularity from the selected button 'months' for example var widgets = ['5f33224e15e4d70d748910f6','5f34d3218a3c0d1bc43ddb48']; //Include the widgetsIDs here as array of strings ['widgetID_1', 'widgetID_2'] /*for each widget id, we grab the granularity from the selected button, apply it to all the widgets listed in the array above, save the changes and then refresh*/ widgets.forEach(myfunction); function myfunction (item){ var widgetfindid = prism.activeDashboard.widgets.$$widgets.find(w => w.oid === item) widgetfindid.metadata.panels[0].items[0].jaql.level = dategran //change the level of granularity to the chosen value from our button: 'months' for example widgetfindid.changesMade() //apply changes to MongoDB - the application database widgetfindid.refresh() //refresh the widget }; STEP 2: CREATING BLOX LAYOUT WITH BUTTONS Now, to build the buttons with the appropriate values of date granularity, download the BloX template from here or use the code below and paste it in the 'Editor' tab of BloX widget. In this example, we will have 4 buttons in the following order - Quarters, Months, Weeks and Days. Each button will have the action type as 'dategran_buttons' (the BloX action we created in the last step) and also will carry the date granularity in a json key "date_gran' - for example "date_gran":"months" on the button for Months. { "style": "", "script": "", "title": "", "showCarousel": true, "body": [ { "type": "Container", "items": [ { "type": "TextBlock", "horizontalAlignment": "center", "size": "medium", "spacing": "small", "color": "black", "text": "Choose Date Granularity" } ] } ], "actions": [ { "type": "dategran_buttons", "title": "Quarters", "style": { "backgroundColor": "#1D426C" }, "dategran": "quarters" }, { "type": "dategran_buttons", "title": "Months", "style": { "backgroundColor": "#1D426C" }, "dategran": "months" }, { "type": "dategran_buttons", "title": "Weeks", "style": { "backgroundColor": "#1D426C" }, "dategran": "weeks" }, { "type": "dategran_buttons", "title": "Days", "style": { "backgroundColor": "#1D426C" }, "dategran": "days" } ] } STEP 3: COLOR ANIMATION ON THE BUTTONS USING A WIDGET THAT IS AFFECTED Now the functionality of button helping to change the date granularity in the list of widgets whose widgetIDs you pasted in the action will work as expected. Now, let us get the buttons to animate in the desired fashion which is: 'when a button is clicked, the clicked button has SELECTED color and all other buttons take the UNSELECTED color. Before you begin implementing this step, get the hex codes of the selected and unselected colors as per your UI preference. In one of the widgets (line/bar/column) that will be affected by the BloX buttons, paste the code below into the script editor of that widget. This logic can be updated: The functionality has been refined such that a button when in clicked state cannot be clicked again and will be unavailable for any click action. For example, when 'Month' is selected which modifies all the widgets, then only the 3 other buttons are now clickable. Note: Pasting this into one of the widgets will be enough. Also, in the variable 'widgetID' used in the code below, replace it with the current widget whose script editor you're making use of. This should be available in the URL of the script editor you are in. var ChooseYourUnselectColor = '#D3D3D3'; //Unselected Color var ChooseYourSelectedColor = '#1D426C'; //Selected Color var widgetID = '5f33224e15e4d70d748910f6'; //Current Widget which runs this script widget.on('ready',function(widget, args){ var widgetOID = widgetID; //Get the selected date granularity var widget = prism.activeDashboard.widgets.$$widgets.find(w => w.oid === widgetOID) if(widget.metadata.panels[0].items[0].jaql.level == 'quarters'){ var textOfButtonToFormat1 = 'Months'; var textOfButtonToFormat2 = 'Weeks'; var textOfButtonToFormat3 = 'Days'; var selectedButton = 'Quarters'; $('button.btn:contains('+textOfButtonToFormat1+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": ChooseYourUnselectColor, "pointer-events": "auto" }); $('button.btn:contains('+textOfButtonToFormat2+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": ChooseYourUnselectColor, "pointer-events": "auto" }); $('button.btn:contains('+textOfButtonToFormat3+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": ChooseYourUnselectColor, "pointer-events": "auto" }); $('button.btn:contains('+selectedButton+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": ChooseYourSelectedColor, "pointer-events": "none" }); } if(widget.metadata.panels[0].items[0].jaql.level == 'months'){ var textOfButtonToFormat1 = 'Quarters'; var textOfButtonToFormat2 = 'Weeks'; var textOfButtonToFormat3 = 'Days'; var selectedButton = 'Months'; $('button.btn:contains('+textOfButtonToFormat1+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": ChooseYourUnselectColor, "pointer-events": "auto" }); $('button.btn:contains('+textOfButtonToFormat2+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": ChooseYourUnselectColor, "pointer-events": "auto" }); $('button.btn:contains('+textOfButtonToFormat3+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": ChooseYourUnselectColor, "pointer-events": "auto" }); $('button.btn:contains('+selectedButton+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": ChooseYourSelectedColor, "pointer-events": "none" }); } if(widget.metadata.panels[0].items[0].jaql.level == 'weeks'){ var textOfButtonToFormat1 = 'Months'; var textOfButtonToFormat2 = 'Quarters'; var textOfButtonToFormat3 = 'Days'; var selectedButton = 'Weeks'; $('button.btn:contains('+textOfButtonToFormat1+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": ChooseYourUnselectColor, "pointer-events": "auto" }); $('button.btn:contains('+textOfButtonToFormat2+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": ChooseYourUnselectColor, "pointer-events": "auto" }); $('button.btn:contains('+textOfButtonToFormat3+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": ChooseYourUnselectColor, "pointer-events": "auto" }); $('button.btn:contains('+selectedButton+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": ChooseYourSelectedColor, "pointer-events": "none" }); } if(widget.metadata.panels[0].items[0].jaql.level == 'days'){ var textOfButtonToFormat1 = 'Months'; var textOfButtonToFormat2 = 'Weeks'; var textOfButtonToFormat3 = 'Quarters'; var selectedButton = 'Days'; $('button.btn:contains('+textOfButtonToFormat1+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": ChooseYourUnselectColor, "pointer-events": "auto" }); $('button.btn:contains('+textOfButtonToFormat2+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": ChooseYourUnselectColor, "pointer-events": "auto" }); $('button.btn:contains('+textOfButtonToFormat3+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": ChooseYourUnselectColor, "pointer-events": "auto" }); $('button.btn:contains('+selectedButton+')').css({ transition : 'background-color 50ms ease-in-out', "background-color": ChooseYourSelectedColor, "pointer-events": "none" }); } }); To see this demo in action in your own Sisense environment, first create the BloX action using the Step 1 and then, use this dash file (Make sure you have the Sample Ecommerce elasticube available - one of the sample elasticubes that comes with your initial installation of Sisense). Also, check the widgetIDs in the BloX action you created (Step1) and in the script editor of the column chart on the dashboard (Step3). BONUS: If you want to automatically change the date granularity on all the widgets which have a time series slicer instead of grabbing the specific widget ids, then replace the code when creating the action (In Step 1) with the code below: const dategran = payload.dategran; // Holds the chosen granularity 'months' for example var widgets = prism.activeDashboard.widgets.$$widgets; //get all the widgets in the dashboard //for each widget widgets.forEach(myfunction); function myfunction (item){ //checking if the widget has a slicer (valid dimension in Category/X-Axis panels of the chart) and if it does, checking if it contains a date grouping if(typeof(item.metadata.panels[0].items[0]) !== 'undefined' && typeof(item.metadata.panels[0].items[0].jaql.level) !== 'undefined'){ var currentGran = item.metadata.panels[0].items[0].jaql.level; //gettting the current granularity if(currentGran === 'days'||currentGran === 'weeks'||currentGran === 'months'||currentGran === 'quarters'){ item.metadata.panels[0].items[0].jaql.level = dategran //change the level of granularity to the chosen value 'months' for example item.changesMade() //apply changes to Mongo item.refresh() //refresh the widget } } };2.8KViews1like3CommentsBloX Template: Indicators With Sparkline
Introduction In many use cases, the most current state of your KPI is as important as the trend of that KPI over time (for example, the trend of stock price, impressions or reach of your social media campaigns, etc), so you want to show both an indicator and a sparkline chart next to it. Creating multiple indicator and line chart widgets is not the most efficient way to implement this requirement considering the performance (multiple widgets and queries) and the complexity of the UI design (fonts size, layout etc). The Indicators with Sparklines template allows you to implement this requirement easily using BloX. This template is structured in 3 columns, one for the sparkline (shows history of the value), one for the indicator (shows the current value), and one for the name of the KPI. Installation Instructions 1. Download the template. Change the extension from txt to json 2. Import the template and choose the downloaded file. 3. Refresh your browser. 4. Create a new Blox Widget and open the Templates menu under the design panel. You should now be able to see and choose the new template. If you cannot see the template in the All Templates menu, please restart the Sisense.Blox service on your Sisense server. 5. Populate the Items and Values panels with relevant fields and aggregations. Please note that any change in panel item names should be reflected in the card editor. In Items, add the date column. In Values, add two columns for each KPI: one column for the unfiltered KPI to show the trendline, e.g. SUM(Impressions), and another column for the current value of the KPI using measured value, e.g. (SUM(Impressions), Date) where Date is set to Today. Technical Notes CAROUSEL & CAROUSEL BUTTON The "showCarousel" parameter should always be set to True, otherwise, the entire block will be repeated vertically for all the different dates in the data (all the numbers will be exactly the same). To remove the carousel button, please use this widget script below. widget.on('ready', function(sender, ev){ //remove carousel button $('.carousel-button', element).remove(); }); COLORS To modify the color of the sparkline, search for this piece of code in the Editor. You can then modify the line-color, fill-color, and point-color. You can also modify other parameters such as the width of the graph. <span class='blox-sparkline' type='line' line-color='#3a5694' width='220' height='40' line-width='3' fill-color='#c6d8f8' point-color:'#28467a'>{spark:Organic}</span> To change the color of the fonts, search for this piece of code in the Editor. You can then modify the color paramater. "style": { "color": "#395795" } PDF EXPORT This template works with PDF Export. To hide the carousel arrow buttons: place below the "showCarousel": true, "carouselAnimation": { "showButtons": false },2.8KViews1like6CommentsTurn Any HTML Into A Blox Template
In this example we'll cover how to take any piece of HTML and turn it into a blox template. Find A Template I like to find templates on codepen or jsfiddle through google or through their search. https://codepen.io/yyildiz/pen/XjRAYv On each Tab you may need to select "View Compiled CSS" to get standard CSS you can use. You may want to copy the Compiled HTML and replace the Existing compiler with "None" so that it is easier to play with it. Modifying The HTML/CSS Remove as much of the extra divs as possible to get the HTML to only show the stuff you need. Remove any CSS pointing to "body" , by transferring it to the root element. You may also want to scope the CSS rules so that it doesnt apply to anything else. This can easily be done by wrapping the rules into a selector which we will apply to our Blox and using the Less Compiler. .profilecardblox { myrules } See example here https://codepen.io/lemoogle/pen/XWKKxpX Transferring To A Blox Create a New blox visualisation, try to have a query which returns multiple items for ease of development. CLEAN THE HTML AND CSS Step 1: convert to single line: https://lingojam.com/TexttoOneLine Step 2: replace " with " MOVE THE CSS AND HTML INTO A BLOX Use the default template; Copy the CSS into the "Style Tag". Copy the HTML into the "textBlock" Remove extra rules from the template DEFAULT TEMPLATE CLEANUP Remove the style tags from the default template Set showCarousel to False In Configuration Change the Default Color to "transparent" REMOVE THE WRAPPER CLASS Remove the profilecardblox div we had wrapped around our code and simply put it in the "class" field of the container: This will ensure that the css rules apply to this blox and this blox only. ( or blox with this class ) ALMOST THERE From Rows To Columns: All your files and folders are presented as a tree in the file explorer. You can switch from one to another by clicking a file in the tree. ADD CSS AND JAVASCRIPT TO THE STYLE AND SCRIPT ELEMENTS .blox-container{display:flex; overflow-x:scroll; overflow-y:hidden; padding: 3rem 1rem;background-color:#3d394f} .blox-slides{display:flex; position:relative; transition:.2s} .blox-slides:hover{transform:scale(1.1);z-index:50;} .blox-slides:hover~.blox-slides{transform: translateX(0px)} $('.blox-slides').parent().eq(0).attr('class', 'blox-container') You can change the CSS to play with the transition , this will zoom in on a card when hovering. ADD A FEW STYLE RULES TO THE ITEM TO GIVE IT THE PADDING TEXT STYLING YOU WANT! "style": { "text-align": "center", "font-weight": "bold", "background": "transparent", "padding-left": "20px" } We also set the background to transparent to ignore the default yellow. Map The Blox To The Data All you need to do now is to edit the textblock to map to the Query! Make sure to escape the quotes and set it back to single line afterwards! <div class="profile-card-1"> <div class="img"><img src="//joeschmoe.io/api/v1/{panel:fullname}" style="background-color:#f2f2f2"/></div> <a class="view-more" href=""> <i class="fa fa-plus-circle" aria-hidden="true"></i> <div class="popup"></div> </a> <div class="mid-section"> <div class="name">{panel:fullname}</div> <div class="description">{panel:title}</div> <div class="line"></div> <div class="stats"> <div class="stat"> {panel:Revenue} <div class="subtext">Revenue</div> </div> <div class="stat"> {panel:Total Quantity} <div class="subtext">Amount</div> </div> <div class="stat"> {panel:vslast} <div class="subtext">vs. Last Year</div> </div> </div> </div> <div class="links"><a class="fb" href=""><i class="fa fa-facebook-f" aria-hidden="true"></i></a><a class="twitter" href=""><i class="fa fa-twitter" aria-hidden="true"></i></a><a class="follow" href=""><i class="fa fa-rocket" aria-hidden="true"></i></a></div> </div> Final Template { "style":".blox-container{display:flex; overflow-x:scroll; overflow-y:hidden; padding: 3rem 1rem;background-color:#3d394f} .blox-slides{display:flex; position:relative; transition:.2s} .blox-slides:hover{transform:scale(1.2);z-index:50;} .blox-slides:hover~.blox-slides{transform: translateX(0px)} .profile-card-1 { font-family: \"Ubuntu\", sans-serif; width: 300px; height: 390px; background: white; margin: 0 auto; border-radius: 10px; text-align: center; box-shadow: 4px 4px 10px #999; position: relative; box-sizing: border-box; overflow: hidden; } .profile-card-1 .view-more { position: absolute; top: calc(50% - .5em); left: calc(50% - .5em); z-index: 2; color: #2ECC71; font-size: 2em; } .profile-card-1 .view-more .fa-plus-circle { position: absolute; background: white; border-radius: 50%; width: 1.004em; } .profile-card-1 .view-more .fa-plus-circle:hover { background: #2ECC71; color: white; } .profile-card-1 .popup { height: 500px; width: 500px; display: block; position: absolute; top: 0; left: 0; } .profile-card-1 .mid-section { position: absolute; height: 200px; width: 100%; top: 200px; left: 0; padding: 10px 20px 0; box-sizing: border-box; background: white; } .profile-card-1 .mid-section .name { color: #333333; font-size: 1.4em; padding-top: 5px; background: rgba(255, 255, 255, 0.1); font-weight: bold; } .profile-card-1 .mid-section .description { color: gray; font-size: 0.9em; padding-bottom: 5px; background: rgba(255, 255, 255, 0.1); } .profile-card-1 .mid-section .description a { color: inherit; text-decoration: none; font-weight: bold; } .profile-card-1 .mid-section .line { background: #7ee2a8; width: 80%; height: 2px; margin: 5px auto -3px; } .profile-card-1 .mid-section .stats { display: flex; position: absolute; left: 10%; padding-top: 10px; width: 80%; justify-content: space-around; } .profile-card-1 .mid-section .stats .stat { font-size: 1.3em; color: #333333; padding: 5px; font-weight: bold; } .profile-card-1 .mid-section .stats .subtext { color: gray; font-size: 0.6em; font-weight: normal; } .profile-card-1 .img { height: 130px; width: 100%; background-image: linear-gradient(rgba(46, 204, 113, 0.4), rgba(46, 204, 113, 0.95)), url(\"https://static.pexels.com/photos/21014/pexels-photo-medium.jpg\"); padding: 20px; box-sizing: border-box; position: relative; } .profile-card-1 .img img { width: 160px; height: 160px; padding: 3px; border-radius: 50%; border: 3px solid rgba(255, 255, 255, 0.6); position: absolute; left: calc(50% - 84px); top: 26px; } .profile-card-1 .img:after { content: \"\"; position: absolute; width: 180px; height: 180px; border-radius: 50%; left: calc(50% - 91.5px); top: 20px; border: 3px solid rgba(255, 255, 255, 0.4); } .profile-card-1 .img:before { content: \"\"; position: absolute; width: 190px; height: 190px; border-radius: 50%; left: calc(50% - 95px); top: 15.5px; border: 2px solid rgba(255, 255, 255, 0.2); } .profile-card-1 .links { width: 100%; height: 50px; background: #F2F2F2; border-top: 1px solid #44d581; margin-top: 35px; border-radius: 5px; color: white; font-size: 2em; line-height: 1.5em; position: absolute; bottom: 0; } .profile-card-1 .links a { color: white; } .profile-card-1 .links .fb { position: absolute; left: 0; width: 25%; height: 100%; background-color: #3b5998; } .profile-card-1 .links .fb:hover { background-color: #4264aa; } .profile-card-1 .links .twitter { position: absolute; left: 25%; width: 25%; height: 100%; background-color: #55ACEE; } .profile-card-1 .links .twitter:hover { background-color: #6cb7f0; } .profile-card-1 .links .follow { position: absolute; left: 50%; width: 50%; height: 100%; background-color: #2ECC71; } .profile-card-1 .links .follow:hover { background-color: #40d47e; }.profile-card-2 { width: 250px; height: 500px; background: #2ECC71; }", "script":"$('.blox-slides').parent().eq(0).attr('class', 'blox-container')", "title":"", "showCarousel":false, "body":[ { "type":"Container", "items":[ { "type":"TextBlock", "text":"<link href=\"https://fonts.googleapis.com/css?family=Ubuntu\" rel=\"stylesheet\"/><link href=\"https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css\" rel=\"stylesheet\" integrity=\"sha384-T8Gy5hrqNKT+hzMclPo118YTQO6cYprQmhrYwIiQ/3axmI1hQomh7Ud2hPOy8SP1\" crossorigin=\"anonymous\"/><div class=\"profile-card-1\"><div class=\"img\"><img src=\"//joeschmoe.io/api/v1/{panel:fullname}\" style=\"background-color:#f2f2f2\"/></div><a class=\"view-more\" href=\"\"><i class=\"fa fa-plus-circle\" aria-hidden=\"true\"></i><div class=\"popup\"></div></a><div class=\"mid-section\"><div class=\"name\">{panel:fullname}</div><div class=\"description\">{panel:title}</div><div class=\"line\"></div><div class=\"stats\"><div class=\"stat\">{panel:Revenue}<div class=\"subtext\">Revenue</div></div><div class=\"stat\">{panel:Total Quantity}<div class=\"subtext\">Amount</div></div><div class=\"stat\">{panel:vslast}<div class=\"subtext\">vs. Last Year</div></div></div></div><div class=\"links\"><a class=\"fb\" href=\"\"><i class=\"fa fa-facebook-f\" aria-hidden=\"true\"></i></a><a class=\"twitter\" href=\"\"><i class=\"fa fa-twitter\" aria-hidden=\"true\"></i></a><a class=\"follow\" href=\"\"><i class=\"fa fa-rocket\" aria-hidden=\"true\"></i></a></div></div>", "style":{ "text-align":"center", "font-weight":"bold", "background":"transparent", "padding-left":"20px" } } ] } ], "actions":[ ] }2.6KViews0likes0CommentsBloX Template: Dynamic Pivot Table
Introduction: The Dynamic Table template allows you to create a pivot table which dynamically sizes columns based on the size of the browser. This template is structured for 4 columns, each of which are set to 25% of the column set size, which changes based on the browser window. LARGE BROWSER WINDOW: SMALLER BROWSER WINDOW: Installation Instructions: Download the attached template Import template and choose the downloaded file: 3. Refresh your browser 4. Create a new Blox Widget and open the Templates menu under the design panel. You should now be able to see and choose the new template. If you cannot see the template in the All Templates menu, please restart the Sisense.blox service on your Sisense server. Populate the Items and Values panels with relevant fields and aggregations. Please note that any change in panel item names should be reflected in the card editor. Technical Notes CAROUSEL To show items stacked vertically instead of via the default carousel view, the carousel is set to false in row 8 of the Editor. "showCarousel": false HEADER To configure a header to only repeat for the first carousel item, see line 2 in Editor where the title is not loaded for all items with class "blox-pivot-title" which is specified for each column header TextBlock. except the first based on class. "style": ".blox-slides:first-child .blox-pivot-title{display:block; !important;} .blox-slides .blox-pivot-title{margin-bottom:10px; font-weight:bold; color:black; font-size:1em}" SEPARATOR Separator attributes (color, thickness) are specified in Configuration at line 91. Separators are then added to the top of each textbox item as well as to each Column type for vertical separators at Line 19, 23, 33, 41, 48, 54, 63, 71, 80, 89, 97 and 106 in the Editor. "separator": { "lineThickness": 1, "lineColor": "#9b9999", "padding": 25, "spacing": 40 }, PADDING To eliminate item padding to generate continuous separator lines, padding is set to -1 in line 89 in Configuration. DYNAMIC COLUMN WIDTH Each column’s width is specified to 25% of the ColumnSet at Lines 17, 42, 64 and 90. "width": "25%", Limitations DASHBOARD RENDER ITEM LIMIT Regardless of font size, 100 sets of items will render on the dashboard (items sets, not rows). Everything still exports to CSV. PDF EXPORT LIMITATION However man rows can fit on a single page (depends on font size), that's what will show in the preview. Any overflow is not thrown a subsequent page and is dropped from the PDF.2.6KViews2likes0Comments