Jump to content
  • Custom KPI Visualization Mod


    Custom KPI Mod allows maximum flexibility through CSS, HTML and JavaScript

    The Custom KPI Visualization Mod

    This Custom KPI Visualization Mod can be used as is without any coding required. There are many examples to choose from from the examples menu for each category,  but to make the most of it and customize it to the fullest, It requires basic knowledge of JavaScript, HTML or CSS to be able to change the look and feel. With JavaScript you can manipulate the data and behavior before and after rendering the visualization. 

    CK_HMTL_KPIS.thumb.gif.6e97cc4f2c7747f7fb827f0ed84f534f.gif

     

    Default view

    Before we continue with the details on how to customize it, let's first understand how it works with the default values

    Here is a screenshot of the default Custom KPI Visualization view at glance. 

    at_glance.thumb.png.564b45a55a17056e79b3fded8ad5a066.png

    The Custom KPI Mod consist of cards, values (KPIs) and optional hierarchies. The hierarchies will help organize the categories in big cards containing the small white cards.  

    The Default view is also mobile friendly so it will adjust the layout, font and text for small displays

    image.thumb.png.da770a4879f088449c9f171bf23e8b8a.png

    Data Structure

    The data can be of any type. Not all selectors are required to use the Custom KPI rendering capabilities, but It is useful to well organized hierarchies in it's data and the different KPI values defined

    Sample Dataset

    For example, consider the following dataset

    Hospital ID|Hospital Name|Location|Department|Subcategory|Area|New Patients|Completed Appointments|Median Appointment Rate (days)|Fill Rate (%)
    101|City Hospital|New York, NY|Cardiology|Heart Attack|East Wing|150|145|2|96
    101|City Hospital|New York, NY|Neurology|Stroke|West Wing|120|115|3|95
    101|City Hospital|New York, NY|Orthopedics|Fracture|North Wing|100|98|5|98
    102|Green Valley Hospital|Los Angeles, CA|Maternity|Normal Delivery|South Wing|200|198|1|99
    102|Green Valley Hospital|Los Angeles, CA|Oncology|Lung Cancer|East Wing|180|170|7|94
    102|Green Valley Hospital|Los Angeles, CA|Gastroenterology|Ulcer|West Wing|130|125|4|96
    103|Mountain Health|Denver, CO|Neurology|Parkinson's Disease|East Wing|110|105|5|95
    103|Mountain Health|Denver, CO|Endocrinology|Diabetes|South Wing|160|158|2|99
    104|Lakeside Medical|Dallas, TX|Neurology|Stroke|West Wing|125|120|4|96
    104|Lakeside Medical|Dallas, TX|Orthopedics|Fracture|North Wing|105|103|6|98
    105|Seaside Health|Miami, FL|Maternity|Normal Delivery|South Wing|210|205|1|98
    105|Seaside Health|Miami, FL|Oncology|Lung Cancer|East Wing|185|180|8|95
    105|Seaside Health|Miami, FL|Gastroenterology|Ulcer|West Wing|135|130|3|97
    101|City Hospital|Boston, MA|Cardiology|Arrhythmia|North Wing|145|140|3|96
    101|City Hospital|Boston, MA|Neurology|Parkinson's Disease|East Wing|115|110|5|94
    101|City Hospital|Boston, MA|Endocrinology|Diabetes|South Wing|165|160|2|99
    101|City Hospital|Boston, MA|Dermatology|Psoriasis|West Wing|95|90|7|97
    102|Green Valley Hospital|San Francisco, CA|Neurology|Stroke|West Wing|130|125|4|95
    102|Green Valley Hospital|San Francisco, CA|Orthopedics|Fracture|North Wing|110|108|5|98
    103|Mountain Health|Seattle, WA|Maternity|Normal Delivery|South Wing|205|200|1|99
    103|Mountain Health|Seattle, WA|Oncology|Lung Cancer|East Wing|190|185|6|94
    103|Mountain Health|Seattle, WA|Gastroenterology|Ulcer|West Wing|140|135|3|96
    104|Lakeside Medical|Chicago, IL|Cardiology|Arrhythmia|North Wing|150|145|2|97
    104|Lakeside Medical|Chicago, IL|Neurology|Parkinson's Disease|East Wing|120|115|4|96
    104|Lakeside Medical|Chicago, IL|Endocrinology|Diabetes|South Wing|170|165|3|99
    105|Seaside Health|Houston, TX|Neurology|Stroke|West Wing|135|130|4|95
    105|Seaside Health|Houston, TX|Orthopedics|Fracture|North Wing|115|110|5|98
    101|City Hospital|Atlanta, GA|Maternity|Normal Delivery|South Wing|215|210|1|98
    101|City Hospital|Atlanta, GA|Oncology|Lung Cancer|East Wing|195|190|7|95
    101|City Hospital|Atlanta, GA|Gastroenterology|Ulcer|West Wing|145|140|3|97
    102|Green Valley Hospital|Las Vegas, NV|Cardiology|Arrhythmia|North Wing|155|150|3|96
    102|Green Valley Hospital|Las Vegas, NV|Neurology|Parkinson's Disease|East Wing|125|120|5|94
    102|Green Valley Hospital|Las Vegas, NV|Endocrinology|Diabetes|South Wing|175|170|2|99
    102|Green Valley Hospital|Las Vegas, NV|Dermatology|Psoriasis|West Wing|105|100|6|97
    103|Mountain Health|Phoenix, AZ|Neurology|Stroke|West Wing|140|135|3|95
    103|Mountain Health|Phoenix, AZ|Orthopedics|Fracture|North Wing|120|115|4|98
    104|Lakeside Medical|Philadelphia, PA|Maternity|Normal Delivery|South Wing|220|215|1|99
    104|Lakeside Medical|Philadelphia, PA|Oncology|Lung Cancer|East Wing|200|195|6|94
    104|Lakeside Medical|Philadelphia, PA|Gastroenterology|Ulcer|West Wing|150|145|4|96
    105|Seaside Health|San Diego, CA|Neurology|Parkinson's Disease|East Wing|130|125|5|96
    105|Seaside Health|San Diego, CA|Endocrinology|Diabetes|South Wing|180|175|2|99
    101|City Hospital|San Jose, CA|Dermatology|Psoriasis|West Wing|110|105|7|98
    101|City Hospital|San Jose, CA|Cardiology|Heart Attack|East Wing|175|170|3|96
    101|City Hospital|San Jose, CA|Neurology|Stroke|West Wing|145|140|4|95
    101|City Hospital|San Jose, CA|Orthopedics|Fracture|North Wing|125|120|5|98
    102|Green Valley Hospital|Austin, TX|Maternity|Normal Delivery|South Wing|225|220|1|98
    102|Green Valley Hospital|Austin, TX|Oncology|Lung Cancer|East Wing|205|200|7|95
    102|Green Valley Hospital|Austin, TX|Gastroenterology|Ulcer|West Wing|155|150|3|97
    103|Mountain Health|San Antonio, TX|Neurology|Parkinson's Disease|East Wing|135|130|5|94
    103|Mountain Health|San Antonio, TX|Endocrinology|Diabetes|South Wing|185|180|2|99
    104|Lakeside Medical|Dallas, TX|Neurology|Stroke|West Wing|150|145|3|95
    104|Lakeside Medical|Dallas, TX|Orthopedics|Fracture|North Wing|130|125|4|98
    105|Seaside Health|Orlando, FL|Maternity|Normal Delivery|South Wing|230|225|1|99
    105|Seaside Health|Orlando, FL|Oncology|Lung Cancer|East Wing|210|205|6|94
    105|Seaside Health|Orlando, FL|Gastroenterology|Ulcer|West Wing|160|155|4|96
    

    The dataset contains detailed information about hospital performance across various departments and subcategories. The data is structured with the following columns:

    • Hospital ID: Unique identifier for each hospital.
    • Hospital Name: Name of the hospital.
    • Location: City and state where the hospital is located.
    • Department: Medical department within the hospital.
    • Subcategory: Specific medical condition or treatment within the department.
    • Area: Section or wing of the hospital where the department is located.
    • New Patients: Number of new patients admitted to the department.
    • Completed Appointments: Number of appointments completed in the department.
    • Median Appointment Rate (days): Median number of days for an appointment to be scheduled and completed.
    • Fill Rate (%): Percentage of available appointment slots that were filled.

    Example Records:

    • City Hospital in New York, NY:
      • Cardiology department handling heart attacks with 150 new patients and a 96% fill rate.
      • Neurology department dealing with strokes with 120 new patients and a 95% fill rate.
    • Green Valley Hospital in Los Angeles, CA:
      • Maternity department handling normal deliveries with 200 new patients and a 99% fill rate.
      • Oncology department dealing with lung cancer with 180 new patients and a 94% fill rate.

    We can organize the same information with the Custom KPI Mod:

    CKCards.png.0cdfc3f104004e86aef2ee668d826f09.png

    We can use the selectors to define what values to display on these cards. We have up to 6 available selectors, the color by and the hierarchy.

    Spotfire Selectors

    • Hierarchy: Allows to break down the cards in different categories
    • Value 1: The value at the center of the card
    • Value 2: The value at the center of the card, under Value 1
    • Value 3: The value at the top left corner of the card
    • Value 4: The tooltip value of the top right corner of the card
    • Value 5: The value at the bottom left of the card
    • Value 6: The value at the bottom right of the card

    CKVals.png.3756b8bde42bb4488681e70eb17f4f2b.png

    Configuration

    There are different ways to modify the Custom KPI

    • HTML - Modifies the html portion of the KPI's
    • CSS - Changes the look and feel of the KPI's
    • JavaScript - Performs data before and after rendering the KPI's

    Code Editor Window

    These modification can be performed by clicking the configuration icon image.png.5d8e970f71894929fd72050e3cc05574.png located on the top right of the Mod while the Spotfire analysis is in edit mode. The configuration icon brings up a built in code editor window. There last 3 icons from the Code Editor hides, maximizes or restores the editor from the screen.

    CKEditor.png.fa837eb28edb2919481d80afe07a2c9e.png

    Please note that this editor is not draggable and can be only be maximized or show in the center of the Visualization Mod window. The best way to take advantage of it is by maximizing the Mod itself

    Editor Menu

    The editor menu has options to save, reset a mode or all modes, and to load a mode example. The default view of the editor is the CSS (override) mode. Depending on the selected mode, the reset menu can reset changes for that particular mode or all changes from all selected modes. This is also true for the last menu item in which each mode has code snippet examples.

    CKMenu1.png.ca0cc39b756e6d63f381dfbfa353b311.pngCKMenu2.png.a41f33fce89299e9153dabb9710f1616.pngCKMenu3.png.89cde95fd96ee367597e577d7433fc35.png

    Editor Modes Menu

    There are 3 mode categories: HTML, CSS and JavaScript. Each mode has different samples from the Editor Menu. The editor modes menu can be found at the center of the editor. 

    CKModes.png.f4070286c4f3680b5d95943cdfbf2a79.png

    To understand these modes, we need to first understand the KPI HTML Structure 

    KPI Rendering Structure

    There are 4 html elements that forms the structure of the Custom KPI. These elements are nested to each other in the following order

    • Root Hierarchy
    • Nested Hierarchy
    • Last Hierarchy
    • KPI

    CKStructure.png.8b12a07f81790cbdded0a702f1b14b16.png

    HTML Structure

    The full html with two root categories, looks like this: 

    <div id="mod-container">
      <div>
        <div class="root category"><span class="title" id="root_2058">root hierarchy</span>
          <div>
            <div class="nested category"><span class="title" id="nested_2059">nested hierarchy</span>
              <div>
                <div class="last category"><span class="title" id="last_2060">last hierarchy</span>
                  <div class="kpis">KPI's<div class="kpi" id="kpi_2061">
                      <div class="kpi-val1">kpi 1</div>
                      <div class="kpi-val2">kpi 2</div>
                      <div class="kpi-val3">kpi 3</div>
                      <div class="kpi-val4" title="xxxxx" style="color:#FA7864">kpi 4</div>
                      <div class="kpi-val5">kpi 5</div>
                      <div class="kpi-val6">kpi 6</div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>

    Editor Modes

    HTML Modes

    Root hierarchy

    The root hierarchy in the HTML editor mode renders the piece of html portion that corresponds to the title of each hierarchy. It has a placeholder to render the category from the Hierarchy selector. You can also put the ${level} which is the level of the hierarchy. For example, if you have 4 nested hierarchies, the level will always render 1 because it's the root hierarchy.

    <span class="title">${category}</span>

    Use the examples from the editor menu to see different ways in which you can change the html for this specific element. Just be mindful that if you add markup styles it will generate a lot of overhead depending on how much data you have. In that case, it is better to edit or change the CSS and if you need to perform some logic, then  you will need to edit the JavaScript section for it.

    CK_HMTL_RootHierarchy.thumb.gif.7af9dd7c1a28edffa26d7cffbe0a24ff.gif

    Nested Hierarchy

    Similar to the root hierarchy, this affects the portion that creates the nested hierarchies for each root category. Keep in mind that if you add a style tag like in the example, it can lead to a lot of overhead so it is better to make these type of modifications in the CSS section. You can even add script tag and perform some logic and even passing the ${category} or the ${level} variables, but again, it is better to do this on the JavaScript section that handles this part. The HTML modes are meant for small modifications or slight changes in the html structure for further processing, if required with CSS or JavaScript. 

    Last hierarchy

    The example on this last hierarchy mode includes an onclick event that illustrates how a JavaScript call can be made when clicking on the last hierarchy. As mentioned with the nested hierarchy, it is better to just call a JavaScript function vs rendering the same code for all elements of this kind to reduce unnecessary code.

    CK_HMTL_LastHierarchy.thumb.gif.7f0b5ddde80325b9afc363537c7f292e.gif

    KPI

    This is the container that holds each KPI. In this mode, we have more variables (${val1},${val1},..,${val6}) to replace the value from each selector in addition to the ${category} and  ${level} variables available on each hierarchy.

    There are many examples to illustrate how to modify the KPI's for maximum flexibility for your specific needs

    CK_HMTL_KPIS.thumb.gif.6e97cc4f2c7747f7fb827f0ed84f534f.gif

    CSS Modes

    The two CSS Modes allows to alter the stylesheet associated with the Custom KPI Mod. The "CSS" mode is the master stylesheet and the "CSS (Override)" mode is to override some rules for easy changes.  Consider the HTML Structure above to notice the different CSS classes

    • mod-container - applies to the outermost element that holds the rest of the html that conforms the kip's
    • root - for the root hierarchy
    • category - for the root, nested and last hierarchies
    • nested - for the nested hierarchy
    • last - for the last hierarchy that holds the kip's element
    • kpis - the element that contains the kip's
    • kpi-val1 to kpi-val6 - for the individual KPIs

    CSS 

    There is so much you can do just by changing the CSS alone. This mode applies the CSS at the beginning of the document and contains the master stylesheet rules for the Custom KPI Mod instance. This means that any change you make it will only affect this particular visualization and not other instances. This is true for all modes. 

    CSS (override) 

    It is designed to override the master CSS. This mode applies the CSS rules at the end of the document so it will override or merge any existing rules applied on the CSS mode. This mode requires to explicit save changes every time you change the code from the examples. Some examples work best with one or no hierarchies

     

    CK_CSS.thumb.gif.8c0d5df5540c924ce9ee84cbdd0ee0d4.gif

     

    JavaScript Modes

    These modes are the internal JavaScript functions that allows you to make modification in the logic and how the data is processed and displayed. Good programming and understanding of how this works can help you 

    • Before Render - This function is executed before rendering 
    • Root Hierarchy - This function is executed every time a root element is created. Returns the root Element
    • Nested Hierarchy - Returns the html portion for each nested category
    • Last Hierarchy - Executed every time a last hierarchy is found for each root or nested hierarchy and returns the html portion of it
    • KPI - Returns the html portion of the KPI element
    • After Render - Placeholder for a function to execute after the code is rendered

    CP_JSFunctions.thumb.gif.6929753095761cf52de48bf69dd59b8c.gif

    Before Render

    Before the Custom KPI is rendered, this function passes important argument to the CustomKPI.init internal function that renders the final visualization after clearing the container. You can use this function to create any other visualization completely different than the Custom KPI output by exploring the examples

    Definition
    function beforeRender(json, hierarchy, data, mod, allRows, valueAxes, windowSize, dataView) {
          document.getElementById("mod-container").innerHTML = ""; //clears the container
          CustomKPI.init(hierarchy, data, mod, dataView); //renders the visual
     }
    Parameters

    json

    JSON array containing only text values of the data from the axes. For example

    [
        {
            "val1": "City Hospital",
            "val2": "San Jose, CA",
            "val3": "Cardiology",
            "val4": "132",
            "val5": "175",
            "val6": "96%",
            "color": "#6489FA",
            "cat1": "Cardiology",
            "cat2": "101"
        },
    :
        {
            "val1": "City Hospital",
            "val2": "San Jose, CA",
            "val3": "Orthopedics",
            "val4": "456",
            "val5": "125",
            "val6": "98%",
            "color": "#FA7864",
            "cat1": "Orthopedics",
            "cat2": "101"
        }
    ]

     

    hierarchy

    This is the DataViewHierarchy object defined by the Spotfire Visualization Mods interface. For example, you could execute its methods or display the properties from it:

    function beforeRender (json,hierarchy) {  
        //this function renders the visual. you can comment it out if you want and code your own parser.
        document.getElementById("mod-container").innerHTML = "";
        //CustomKPI.init(hierarchy, data, mod);
        
        result = "Hierarchy name:"+hierarchy.name+"\n"+
                 "Number of levels:"+hierarchy.leafCount+"\n"+
                 "is empty?:"+hierarchy.isEmpty
    
        const modContainer = document.getElementById("mod-container")
        modContainer.innerHTML = "<pre>"+result+"</pre>"
    }

     

    data

    The json object array containing values and Visualization Mod objects for each record

    [
        {
            "allRows": "<DataViewRow[]>"
            "axis": "<DataViewCategoricalAxis>"
            "cat1": "Orthopedics",
            "cat2": "101"
            :
            "catN": "<the last nested category>"
            "color": "#FA7864",
            "hierarchy": "<DataViewHierarchy>"
            "row": "<DataViewRow>"
            "val1": "City Hospital",
            "val2": "San Jose, CA",
            "val3": "Orthopedics",
            "val4": "123",
            "val5": "125",
            "val6": "98%",
            "valueAxes": <DataViewAxis>
        }
    ]

    mod

    Represents the entire Mod API and exposes methods for interacting with and reading data from the Mod Visualization and the Spotfire document. Here is a simple example on how to show one of many mod properties directly that shows and hide the progress indicator after 5 seconds

    function beforeRender (json,hierarchy, data, mod, allRows, valueAxes, windowSize, dataView) {  
       mod.controls.progress.show()
       setTimeout(mod.controls.progress.hide,5000)
    }

    Here is another example that illustrates the mod.controls.tooltip for each json element array

    function beforeRender (json,hierarchy, data, mod, allRows, valueAxes, windowSize, dataView) {  
    
      const modContainer = document.getElementById("mod-container")
      modContainer.innerHTML = ""
      modContainer.style.display="block"
    
      json.forEach(e =>{
          div = document.createElement("span")
          div.style.padding="10px";
          div.style.background=e.color;
          div.style.border="1px solid black";
          div.onmouseenter = x=>{mod.controls.tooltip.show(e.val3)}
          div.onmouseleave = mod.controls.tooltip.hide
          modContainer.appendChild(div);
          div.innerHTML=e.val2
      })
    
    }

     

    allRows

    This is a DataViewRow array. Here is an example usage that loops through all rows and performs some operation, like marking.

    function beforeRender(json, hierarchy, data, mod, allRows, valueAxes, windowSize, dataView) {
    
        const modContainer = document.getElementById("mod-container")
        modContainer.innerHTML = ""
        modContainer.style.display = "block"
    
        allRows.forEach((row, i) => {
    
            div = document.createElement("span")
            div.innerHTML = row.categorical("Value 2").formattedValue()
            div.style.background = json[i].color;
            div.style.padding = "10px";
    
            if (row.isMarked()) {
                div.style.border = "2px solid black";
            }
    
            div.onclick = event => {
                if (event.ctrlKey) {
                    row.mark("Add")
                } else {
                    row.mark()
                }
            }
    
            modContainer.appendChild(div);
        })
    }

     

    valueAxes

    DataViewAxis array. This array only includes the kpi values and it is defined as:

            const valueAxes = (await dataView.axes()).filter(axis => axis.name.startsWith("Value"));

     

    windowSize

    Provides read-only access to the current Size of the browser window in which the Mod is rendered. That is, the size of the iframe created for the Mod in the Spotfire UI. The beforeRender function executes every time the window size changes. This is equivalent to the Mod.WindowSize() method

    Here is a simple example to show the window size

    function beforeRender (json,hierarchy, data, mod, allRows, valueAxes, windowSize, dataView) {  
        const modContainer = document.getElementById("mod-container")
        modContainer.innerHTML = "Mod visualization size is: "+ windowSize.width + " X " + windowSize.height
    }

     

    dataView

    The DataView Represents a view of the data from which the visualization can be rendered.

    This object contains the result of the query made by Spotfire against the DataTable currently used by the Mod Visualization, using the Filtering, Marking, expressions on the Axes and other relevant settings.

    Root Hierarchy

    The function that is executed every time a root hierarchy node is rendered. This value must be returned if the beforeRender function calls the CustomKPI.init method. It is intended to expose the DOM element and being able to manipulate it. 

    Definition
    function generateFirstCategoryElement(rootElement, category, level, items) {
       return rootElement;
    }
    Parameters

    rootElement

    DOM element containing the entire html of the root element and its children. Here is an example html structure output

    <div class="root category"><span class="title" id="root_91">Cardiology</span>
      <div>
        <div class="last category"><span class="title" id="last_92">101</span>
          <div class="kpis">
            <div class="kpi" id="kpi_93">
              <div class="kpi-val1">City Hospital</div>
              <div class="kpi-val2">Boston, MA</div>
              <div class="kpi-val3">Cardiology</div>
              <div class="kpi-val4" title="123" style="color:#FEE4E0"></div>
              <div class="kpi-val5">145</div>
              <div class="kpi-val6">96%</div>
            </div>
            <div class="kpi" id="kpi_94">
              <div class="kpi-val1">City Hospital</div>
              <div class="kpi-val2">New York, NY</div>
              <div class="kpi-val3">Cardiology</div>
              <div class="kpi-val4" title="465" style="color:#E0E7FE"></div>
              <div class="kpi-val5">150</div>
              <div class="kpi-val6">96%</div>
            </div>
            <div class="kpi" id="kpi_95">
              <div class="kpi-val1">City Hospital</div>
              <div class="kpi-val2">San Jose, CA</div>
              <div class="kpi-val3">Cardiology</div>
              <div class="kpi-val4" title="789" style="color:#E0E7FE"></div>
              <div class="kpi-val5">175</div>
              <div class="kpi-val6">96%</div>
            </div>
          </div>
        </div>
      </div>
    </div>

    You can manipulate this as any other DOM Object. Here is an example that makes the first child of the rootElement (the span) clickable so it uses the Mods API to navigate to the first page

    function generateFirstCategoryElement(rootElement, category, level = 0, items) {
      //goes to the first page when clicking the root category title
      rootElement.firstChild.addEventListener('click', event => {
        CustomKPI.mod.document.pages().then(pages => pages[0].setAsActive());
      });
    
      return rootElement;
    }

     

    category

    String representing the category for the rendered root hierarchy

    level

    The level of the root category. In this case is always 1 if the root category exists

    items

    The logical JavaScript object of the hierarchy and items. For example the object is dynamically created depending on the hierarchy and values.  The items property for each hierarchical leaf corresponds to the Mod API as defined as the beforeRender "data" parameter.

    The logical JavaScript Object conforming the hierarchy and all it's items

    This parameter is designed to attach it to a DOM element or node as a handy way for further process in some cases

    {
      "Arrhythmia": {
          "North Wing": {
              "items": [
                  {
                      "val1": "City Hospital",
                      "val2": "Boston, MA",
                      "val3": "Cardiology",
                      "val4": "123",
                      "val5": "145",
                      "val6": "96%",
                      "axis": {
                          "name": "Value 6",
                          "isCategorical": true,
                          "hierarchy": "<the item DataViewHierarchy for this item>"
                      },
                      "color": "#FA7864",
                      "row": "<the corresponding DataViewRow>",
                      "hierarchy": "<the item hierarchy for this item>",
                      "allRows": "<all the DataViewRows for this item>",
                      "valueAxes": "<the DataViewAxis for this item>",
                      "cat1": "Cardiology",
                      "cat2": "Arrhythmia",
                      "cat3": "North Wing"
                      :
                      "catN": "the last hierarchical item value"
                  },...,
                  {
                      "val1": "Green Valley Hospital",
                      "val2": "Las Vegas, NV",
                      "val3": "Cardiology",
                      "val4": "456",
                      "val5": "155",
                      "val6": "96%",
                      "axis": {
                          "name": "Value 6",
                          "isCategorical": true,
                          "hierarchy": "<the item hierarchy for this item>"
                      },
                      "color": "#FA7864",
                      "row": "<the corresponding DataViewRow>",
                      "hierarchy": "<the item hierarchy for this item>",
                      "allRows": "<all the DataViewRows for this item>",
                      "valueAxes": "<the DataViewAxis for this item>",
                      "cat1": "Cardiology",
                      "cat2": "Arrhythmia",
                      "cat3": "North Wing",
                      :
                      "catN": "the last hierarchical item value"
                  }
              ]
          }
      },
      "Heart Attack": {
          "East Wing": {
              "items": [..."<same as above>"]
          }
      }
    }

     

    Nested Hierarchy

    Function responsible for the rendering of any category or categories between the first and last hierarchy. The function provides some arguments that can allow enhace or modify the returned DOM element that represents the HTML structure of the nested categories and its children. 

    Definition
    function generateNestedCategoryElement(nestedCategoryElement, category, level, items) {
          return nestedCategoryElement;
    }
    Parameters

    nestedCategoryElement

    DOM element containing the HTML structure for nested category. Here is an example html structure output

    <div class="nested category"><span class="title" id="nested_2507">North Wing</span>
        <div>
            <div class="last category"><span class="title" id="last_2508">101</span>
                <div class="kpis">
                    <div class="kpi" id="kpi_2509">
                        <div class="kpi-val1">City Hospital</div>
                        <div class="kpi-val2">Boston, MA</div>
                        <div class="kpi-val3">Cardiology</div>
                        <div class="kpi-val4" title="xxxxx" style="color:#FA7864"></div>
                        <div class="kpi-val5">145</div>
                        <div class="kpi-val6">96%</div>
                    </div>
                </div>
            </div>
            :
            <div class="last category"><span class="title" id="last_2510">102</span>
                <div class="kpis">
                    <div class="kpi" id="kpi_2511">
                        <div class="kpi-val1">Green Valley Hospital</div>
                        <div class="kpi-val2">Las Vegas, NV</div>
                        <div class="kpi-val3">Cardiology</div>
                        <div class="kpi-val4" title="xxxxx" style="color:#FA7864"></div>
                        <div class="kpi-val5">155</div>
                        <div class="kpi-val6">96%</div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    category

    String representing the category for the rendered nested category hierarchy between the root or the last category node

    level

    The level of the nested category. it can be any number between 2 and the number of nested categories before the last hierarchy level

    items

    The logical JavaScript object of the hierarchy and items. For example the object is dynamically created depending on the hierarchy and values.  The items property for each hierarchical leaf corresponds to the Mod API as defined as the beforeRender "data" parameter.

    This parameter is designed to attach it to a DOM element or node as a handy way for further process in some cases

    {
      "Arrhythmia": {
          "North Wing": {
              "items": [
                  {
                      "val1": "City Hospital",
                      "val2": "Boston, MA",
                      "val3": "Cardiology",
                      "val4": "123",
                      "val5": "145",
                      "val6": "96%",
                      "axis": {
                          "name": "Value 6",
                          "isCategorical": true,
                          "hierarchy": "<the item DataViewHierarchy for this item>"
                      },
                      "color": "#FA7864",
                      "row": "<the corresponding DataViewRow>",
                      "hierarchy": "<the item hierarchy for this item>",
                      "allRows": "<all the DataViewRows for this item>",
                      "valueAxes": "<the DataViewAxis for this item>",
                      "cat1": "Cardiology",
                      "cat2": "Arrhythmia",
                      "cat3": "North Wing"
                      :
                      "catN": "the last hierarchical item value"
                  },...,
                  {
                      "val1": "Green Valley Hospital",
                      "val2": "Las Vegas, NV",
                      "val3": "Cardiology",
                      "val4": "456",
                      "val5": "155",
                      "val6": "96%",
                      "axis": {
                          "name": "Value 6",
                          "isCategorical": true,
                          "hierarchy": "<the item hierarchy for this item>"
                      },
                      "color": "#FA7864",
                      "row": "<the corresponding DataViewRow>",
                      "hierarchy": "<the item hierarchy for this item>",
                      "allRows": "<all the DataViewRows for this item>",
                      "valueAxes": "<the DataViewAxis for this item>",
                      "cat1": "Cardiology",
                      "cat2": "Arrhythmia",
                      "cat3": "North Wing",
                      :
                      "catN": "the last hierarchical item value"
                  }
              ]
          }
      },
      "Heart Attack": {
          "East Wing": {
              "items": [..."<same as above>"]
          }
      }
    }

     

    Last Hierarchy

    Similar to the first and nested hierarchies, the last hierarchy is the function that is executed every time a last hierarchy is found. If the hierarchy has only two levels, then there are no nested hierarchies, but just the root category and the last category hierarchy. This function can be useful to generate other types of outputs since the items for that last hierarchy are available through its parameters. For example, you can create a function that summarizes or aggregates the KPI's that corresponds to that branch. Check the examples to see some use cases.

    Definition
    function generateLastCategoryElement(lastCategoryElement, category, level, items) {
          return lastCategoryElement;
    }
     parameter

    lastCategoryElement

    DOM element containing the HTML structure for nested category. Here is an example html structure output

    <div class="nested category"><span class="title" id="nested_2507">North Wing</span>
        <div>
            <div class="last category"><span class="title" id="last_2508">101</span>
                <div class="kpis">
                    <div class="kpi" id="kpi_2509">
                        <div class="kpi-val1">City Hospital</div>
                        <div class="kpi-val2">Boston, MA</div>
                        <div class="kpi-val3">Cardiology</div>
                        <div class="kpi-val4" title="xxxxx" style="color:#FA7864"></div>
                        <div class="kpi-val5">145</div>
                        <div class="kpi-val6">96%</div>
                    </div>
                </div>
            </div>
            :
            <div class="last category"><span class="title" id="last_2510">102</span>
                <div class="kpis">
                    <div class="kpi" id="kpi_2511">
                        <div class="kpi-val1">Green Valley Hospital</div>
                        <div class="kpi-val2">Las Vegas, NV</div>
                        <div class="kpi-val3">Cardiology</div>
                        <div class="kpi-val4" title="xxxxx" style="color:#FA7864"></div>
                        <div class="kpi-val5">155</div>
                        <div class="kpi-val6">96%</div>
                    </div>
                </div>
            </div>
        </div>
    </div>

    category

    String representing the category for the rendered last category hierarchy

    level

    The level of the nested category. it can be any number between 2 and the number of nested categories before the last hierarchy level

    items

    The logical JavaScript object of the hierarchy and items. For example the object is dynamically created depending on the hierarchy and values.  The items property for each hierarchical leaf corresponds to the Mod API as defined as the beforeRender "data" parameter.

    This parameter is designed to attach it to a DOM element or node as a handy way for further process in some cases

    {
      "Arrhythmia": {
          "North Wing": {
              "items": [
                  {
                      "val1": "City Hospital",
                      "val2": "Boston, MA",
                      "val3": "Cardiology",
                      "val4": "123",
                      "val5": "145",
                      "val6": "96%",
                      "axis": {
                          "name": "Value 6",
                          "isCategorical": true,
                          "hierarchy": "<the item DataViewHierarchy for this item>"
                      },
                      "color": "#FA7864",
                      "row": "<the corresponding DataViewRow>",
                      "hierarchy": "<the item hierarchy for this item>",
                      "allRows": "<all the DataViewRows for this item>",
                      "valueAxes": "<the DataViewAxis for this item>",
                      "cat1": "Cardiology",
                      "cat2": "Arrhythmia",
                      "cat3": "North Wing"
                      :
                      "catN": "the last hierarchical item value"
                  },...,
                  {
                      "val1": "Green Valley Hospital",
                      "val2": "Las Vegas, NV",
                      "val3": "Cardiology",
                      "val4": "456",
                      "val5": "155",
                      "val6": "96%",
                      "axis": {
                          "name": "Value 6",
                          "isCategorical": true,
                          "hierarchy": "<the item hierarchy for this item>"
                      },
                      "color": "#FA7864",
                      "row": "<the corresponding DataViewRow>",
                      "hierarchy": "<the item hierarchy for this item>",
                      "allRows": "<all the DataViewRows for this item>",
                      "valueAxes": "<the DataViewAxis for this item>",
                      "cat1": "Cardiology",
                      "cat2": "Arrhythmia",
                      "cat3": "North Wing",
                      :
                      "catN": "the last hierarchical item value"
                  }
              ]
          }
      },
      "Heart Attack": {
          "East Wing": {
              "items": [..."<same as above>"]
          }
      }
    }

     

    KPI

    This function is executed for each KPI or group of KPI that is rendered. This function must return a DOM object representing the kPI Element structure

    Definition
    function generateKpiElement(kpiElement, item, category, level) {
          return kpiElement;
    }
    Parameters

    kpiElement 

    The DOM object representing the KPI's HTML structure. For example:

    <div class="kpi" id="kpi_3732">
      <div class="kpi-val1">Lakeside Medical</div>
      <div class="kpi-val2">Dallas, TX</div>
      <div class="kpi-val3">Orthopedics</div>
      <div class="kpi-val4" title="xxxxx" style="color:#FA7864"></div>
      <div class="kpi-val5">235</div>
      <div class="kpi-val6">98%</div>
    </div>

     

    item

    The JavaScript Object containing the KPI information, for example:
     

    {
        "val1": "City Hospital",
        "val2": "Boston, MA",
        "val3": "Cardiology",
        "val4": "123",
        "val5": "145",
        "val6": "96%",
        "axis": {
            "name": "Value 6",
            "isCategorical": true,
            "hierarchy": "<the item DataViewHierarchy for this item>"
        },
        "color": "#FA7864",
        "row": "<the corresponding DataViewRow>",
        "hierarchy": "<the item hierarchy for this item>",
        "allRows": "<all the DataViewRows for this item>",
        "valueAxes": "<the DataViewAxis for this item>",
        "cat1": "Cardiology",
        "cat2": "Arrhythmia",
        "cat3": "North Wing": "catN": "the last hierarchical item value"
    }

     

    category

    The last category hierarchy that corresponds to this KPI

    level

    The total number of hierarchy levels as long as there are at least one column selected in the Hierarchy selector

    After Render

    This function runs after the Custom KPI function finishes rendering. It exposes elements that can be useful when post-processing is required. This function is executed only once

    Definition
    function afterRender(data, hierarchyNames, nestedObject, hierarchy) {
          //your code here
    }
    Parameters

    data

    Array of objects with the following structure

    {
      "val1": "City Hospital",
      "val2": "Boston, MA",
      "val3": "Cardiology",
      "val4": "123",
      "val5": "145",
      "val6": "96%",
      "axis": {
        "name": "Value 6",
        "isCategorical": true,
        "hierarchy": "<the item DataViewHierarchy for this item>"
      },
      "color": "#FA7864",
      "row": "<the corresponding DataViewRow>",
      "hierarchy": "<the item hierarchy for this item>",
      "allRows": "<all the DataViewRows for this item>",
      "valueAxes": "<the DataViewAxis for this item>",
      "cat1": "Cardiology",
      "cat2": "Arrhythmia",
      "cat3": "North Wing"
      :
      "catN": "the last hierarchical item value"
      }

     

    hierarchyNames

    The name of the nested column (not the values) for the Hierarchy object. If no hierarchy values are selected, returns an empty array. For example:

    [
        "Department",
        "Subcategory",
        "Area"
    ]


     

    nestedObject

    The logical JavaScript object of the hierarchy and items. For example the object is dynamically created depending on the hierarchy and values.  The items property for each hierarchical leaf corresponds to the Mod API as defined as the beforeRender "data" parameter. For example:

    {
      "Arrhythmia": {
          "North Wing": {
              "items": [
                  {
                      "val1": "City Hospital",
                      "val2": "Boston, MA",
                      "val3": "Cardiology",
                      "val4": "123",
                      "val5": "145",
                      "val6": "96%",
                      "axis": {
                          "name": "Value 6",
                          "isCategorical": true,
                          "hierarchy": "<the item DataViewHierarchy for this item>"
                      },
                      "color": "#FA7864",
                      "row": "<the corresponding DataViewRow>",
                      "hierarchy": "<the item hierarchy for this item>",
                      "allRows": "<all the DataViewRows for this item>",
                      "valueAxes": "<the DataViewAxis for this item>",
                      "cat1": "Cardiology",
                      "cat2": "Arrhythmia",
                      "cat3": "North Wing"
                      :
                      "catN": "the last hierarchical item value"
                  },...,
                  {
                      "val1": "Green Valley Hospital",
                      "val2": "Las Vegas, NV",
                      "val3": "Cardiology",
                      "val4": "456",
                      "val5": "155",
                      "val6": "96%",
                      "axis": {
                          "name": "Value 6",
                          "isCategorical": true,
                          "hierarchy": "<the item hierarchy for this item>"
                      },
                      "color": "#FA7864",
                      "row": "<the corresponding DataViewRow>",
                      "hierarchy": "<the item hierarchy for this item>",
                      "allRows": "<all the DataViewRows for this item>",
                      "valueAxes": "<the DataViewAxis for this item>",
                      "cat1": "Cardiology",
                      "cat2": "Arrhythmia",
                      "cat3": "North Wing",
                      :
                      "catN": "the last hierarchical item value"
                  }
              ]
          }
      },
      "Heart Attack": {
          "East Wing": {
              "items": [..."<same as above>"]
          }
      }
    }

     

    hierarchy

    the DataViewHierarchy Mod Visualization API for that particular hierarchy

    CustomKPI Object

    This is the main object that contains all the methods described before and more. This Object has a global scope, which means you can access it from the developer tools inspector. Feel free to type CustomKPI on the Console to explore further.

    One of the handy feature is that you can get the Spotfire Mod Row object associated with the KPI by calling the CustomKPI.map method. It holds values for each generated KPI id. Each individual KPI card has a unique ID. For example, if you need to programmatically mark a row,  you could:

    CustomKPI.map.get("kpi_1")[0].row.mark()

    Here is the entire CustomKPI Object definition
     

    {
        "map": <Map Object that holds the kpi data and Mod objects like axes, rows, hierarchies and values>,
        "mod": <Spotfire Mod object>,
        "dataView": <Spotfire Mod DataView object>,
        "custom": {
            "rootNodeTemplate": <customized html template string for the root hierarchy>,
            "nestedNodeTemplate": <customized html template string for the nested hierarchy>,
            "lastNodeTemplate": <customized html template string for the last hierarchy>,
            "kpiTemplate": <customized html template string for the kpi>,
            "overrideCSS": <customized css string to override the main css>,
            "mainCSS": <customized main css string>
        },
        "default": {
            "rootNodeTemplate": "<span class=\"title\">${category}</span>",
            "nestedNodeTemplate": "<span class=\"title\">${category}</span>",
            "lastNodeTemplate": "<span class=\"title\">${category}</span>",
            "kpiTemplate": "<div class=\"kpi\">\n  ...",
            "overrideCSS": ".kpi-val1 {\n    font-family: 'Roboto Regular';...",
            "mainCSS": "#mod-container {\n  display: flex;\n  flex-direction..."
        }
        "init": <the function used to initialize the mod>,
        "render":<function that renders the data and hierarchies>,
        "kpisDiv": <for internal use only>
    }

     

    • Like 3

    User Feedback

    Recommended Comments

    There are no comments to display.


×
×
  • Create New...