Friday, April 28, 2017

Add Chatter into Einstein Analytics

Another request that's appeared a few times is to have chatter more accessible within Einstein Analytics. With the action framework you can include global actions based upon the Id reference of a single record. In this example we will add the Opportunity chatter feed via a custom apex page making it accessible on the Name field of an Einstein Analytics visualization. 

Here's a screenshot of what it will look like within Einstein Analytics when we are complete.




Before we begin, this assumes that you have an Opportunity dataset that includes the "Name" and "Id" fields available from the Opportunity object. And that these are based on real opportunities that exist within your instance.


Let's get started.



  1.   Activate the Developer Console

  1.   Create a new Visualforce Page -> File -> New -> Visualforce Page


  1.   Name the file "ChatterGlobalAction", or replace your name in the subsequent actions.
  2.   Save the following text for the Visualforce page
<apex:page standardController="Opportunity">
    <apex:outputPanel layout="block" style="overflow:auto;height:500px" >
      <chatter:feed entityId="{!Id}"/>
    </apex:outputPanel>
</apex:page>
  1. Go to Setup - Build -> Customize -> Opportunities -> Buttons, Links, and Actions  (Note - for other global actions you might want to considering - Build -> Create -> Global Actions -> Global Actions)
  2. Create a "New Action" 
    Action Type: Custom Visualforce
    Visualforce Page: ChatterGlobalAction
    Height: 500px
    Standard Label Type: <none>
    Label: View and Post to Chatter
    Name: View_and_Post_to_Chatter
    Description: <blank>
    Icon: <left as is>
  1. View an opportunity
  2. Activate the Edit Layout

  1. Click on Quick Actions

  1. Drag the "View and Post to Chatter" button to the quick action Publisher section


  1. Save the update
  2. NOTE (I need to update this with screenshots of editing the action framework UI for this and the next step) Create the following xmd file on your local computer and save it with a name like opp.xmd.json. This is the step that will activate the action framework within Einstein Analytics. If you look at the code below, when you invoke "visit the record", the linkTemplate specifies how to build the link to visit the record. You can activate this selection with either the "Name" or "Id" fields based on this configuration. The recordIdField indicates what to pass to the global action.
{
    "dataset": {},
    "dates": [],
    "derivedDimensions": [
    ],
    "derivedMeasures": [],
    "dimensions": [
        {
            "customActions": [],
            "field": "Name",
            "linkTemplate": "/{{row.Id}}",
            "linkTooltip": "Opportunity",
            "members": [],
            "recordDisplayFields": [],
            "recordIdField": "Id",
            "salesforceActions": []
        },
        {
            "customActions": [],
            "field": "Id",
            "linkTemplate": "/{{row.Id}}",
            "linkTooltip": "Opportunity",
            "members": [],
            "recordDisplayFields": [],
            "recordIdField": "Id",
            "salesforceActions": []
        }        
    ],
    "measures": [],
    "organizations": [],
    "showDetailsDefaultFields": []
}


  1. Upload the XMD to your opportunity dataset 


  1. Group Opportunities by Name
  2. Then you can pull up the action menu to select the new Chatter Global Action




Monday, April 10, 2017

Wave example of dynamic groups, measures and charts

I have seen the request often enough to be able to change groups, measures and chart types based on your selections. This is beyond the scope of the normal filter/faceting that is immediately available. I wanted to post an example of how to use binding to build this solution. Because SAQL was not required exploration with the faceted results is still available. 


Links to download the full set of assets are available for download, however, please keep in mind that the dataset references, etc. will prevent you from being able to drop it in directly to work within your org. And all of this needs to be built using the flex dashboard designer.

To dynamically tailor the groups you need a selector and its binding.

            "Grouping_Selector": {
                "datasets": [],
                "dimensions": [],
                "isFacet": true,
                "selectMode": "singlerequired",
                "start": [
                    [
                        "CloseDate_Year"
                    ]
                ],
                "type": "static",
                "values": [
                    {
                        "value": [
                            "CloseDate_Year"
                        ],
                        "display": "Year"
                    },
                    {
                        "value": [
                            "CloseDate_Year",
                            "CloseDate_Quarter"
                        ],
                        "display": "Year and Quarter"
                    },
                    {
                        "value": [
                            "Region"
                        ],
                        "display": "Region"
                    },
                    {
                        "value": [
                            "Region",
                            "Account_State"
                        ],
                        "display": "Region and State"
                    },
                    {
                        "value": [
                            "StageName"
                        ],
                        "display": "Stage"
                    },
                    {
                        "value": [
                            [
                                "CloseDate_Year",
                                "CloseDate_Quarter"
                            ]
                        ],
                        "display": "Year - Quarter (NOT AVAIL, USE MEASURE SOLUTION)"
                    }
                ]

            },

Then include the binding in the groups section of your dashboard json

                    "groups": "{{ flatten(column(Grouping_Selector.selection, [\"value\"])).asObject() }}",


As another option we are loading the measure selections via CSV with the column headers:

axisMode,display,measure_comp_1,measure_comp_2,visualizationType

This dataset should be added to a list selector picking the "display" value.


            "listselector_3": {

                "parameters": {

                    "compact": false,

                    "exploreLink": false,

                    "instant": true,
                    "measureField": "count",
                    "step": "Measure_Selector",
                    "title": "Measure"
                },
                "type": "listselector"
            },


Then we create a selector based on the results of what was selected for the CSV:

            "Measure_Selections": {
                "datasets": [
                    {
                        "id": "0Fbf1000000QSeXCAW",
                        "label": "measure_info",
                        "name": "measure_info1",
                        "url": "/services/data/v39.0/wave/datasets/0Fbf1000000QSeXCAW"
                    }
                ],
                "isFacet": true,
                "isGlobal": false,
                "query": {
                    "measures": [
                        [
                            "count",
                            "*"
                        ]
                    ],
                    "groups": [
                        "measure_comp_1",
                        "measure_comp_2",
                        "axisMode",
                        "visualizationType"
                    ],
                    "filters": [
                        [
                            "display",
                            [
                                "{{ cell(Measure_Selector.selection, 0 , \"display\").asObject() }}"
                            ],
                            "in"
                        ]
                    ]
                },
                "selectMode": "single",
                "type": "aggregateflex",
                "useGlobal": true,
                "visualizationParameters": {
                    "visualizationType": "hbar",
                    "options": {}
                }
            },

Then the results of this step can update the measures dynamically as well as the chart type.

                    "measures": "{{ row(Measure_Selections.result, [], [\"measure_comp_1\", \"measure_comp_2\"]).asObject() }}",


And to be able to update the visualization


                    "axisMode": "{{ valueAt(row(Measure_Selections.result, [0], [\"axisMode\"]), 0).asString() }}",
                    "visualizationType": "{{ valueAt(row(Measure_Selections.result, [0], [\"visualizationType\"]), 0).asString() }}",



Wednesday, April 5, 2017

Counting Rows in Datasets

Would you like to count your dataset rows? There is now an app for that and the article below is now rendered obsolete. I'm leaving this available because it does show how easily a dataset can be created with some calculated information.

Where do you obtain this magical app? It's here and includes adoption metrics as well: https://appexchange.salesforce.com/appxListingDetail?listingId=a0N3A00000EJxtBUAT&modal=ask_your_admin_for_help

Now on to the legacy article:

For those times when you would like to know the row count for your existing datasets within your Salesforce Wave application you may use the following utility. Please note that this process will run as your currently logged in user. If the security predicate restricts the view of data for any dataset, then the row count will only reflect the count of rows that the currently logged in user can see. It will also be unable to count rows for datasets that may exist in the private folders of other users or applications for which the current user does not have access. This will require the installation of a bookmarklet and works best using the chrome browser.

1) Within the Chrome browser application - from the "View" menu, make sure the "Always Show Bookmarks" option is activated. 

2) Drag the following link onto the bookmarks bar


3) Login into your instance and go to the Wave Analytics home page.

4) Click the bookmarklet and it will launch a background task. Once it has the list of datasets you can access it will display a status bar in the upper right.



5) If you have datasets that have been moved, then you may see the screen turn gray with brief popups while it's progressing, you can safely do work on another tab while the task continues to run (but please be sure to leave this active tab untouched).

6) Once complete you will see this popup, you may create the dataset (it will require 1 row per dataset queried) - or you can create a file to download. Ok will create a dataset, cancel will generate a link to CSV data you may download. Your server name will be different.


7) If you selected a dataset, you will have a new dataset named "Dataset_Info" typically within 15 seconds. If selected the file you will see a link that looks like the following and clicking it will automatically trigger the file download.


8) Now you may either explore the dataset using the information provided, including a measure that specifies the count of rows observed in each dataset, along with some other relevant information (such as user created, folder, etc.)