Tuesday, October 31, 2017

Spotfire - "limit data using expression" and add popup calendar for user input (Custom Expression)

Sometimes you want to use user input to limit the data to do the calculation and visualisation.
(Actually, this does the same as the filter)
e.g. User can input their own date range to calculate number of permits of operators during  that date range. You can combine a dropdown list to control when and what data to use for user input:




















Part of the code to toggle date entry part:


#Reset zoom sliders
from Spotfire.Dxp.Application.Visuals import *

#1 Loops through visuals
for vis in Application.Document.ActivePageReference.Visuals:

  #1.1 check each visual type
  if vis.TypeId==VisualTypeIdentifiers.BarChart:

    #1.2 Reset zoom sliders
    vis.As[VisualContent]().XAxis.ZoomRange=AxisRange.DefaultRange

Document.Properties['dlCompanyActivity'] = topSelection

if topSelection == 'Permit date':
 
oldHTML = vis.As[HtmlTextArea]().HtmlContent
oldDiv = '<DIV id = "norm_by_permit"  style="display:none">'
newDiv = '<DIV id = "norm_by_permit"  style="display:inline">'
newHtml = oldHTML.Replace(oldDiv,newDiv)

vis.As[HtmlTextArea]().HtmlContent = newHtml;
vis.As[HtmlTextArea]().HtmlContent += ""

else:

oldHTML = vis.As[HtmlTextArea]().HtmlContent
oldDiv = '<DIV id = "norm_by_permit"  style="display:inline">'
newDiv = '<DIV id = "norm_by_permit"  style="display:none">'
newHtml = oldHTML.Replace(oldDiv,newDiv)

vis.As[HtmlTextArea]().HtmlContent = newHtml;
vis.As[HtmlTextArea]().HtmlContent += ""


Also, for input type is date, use this reference to create a calendar:

http://spotfired.blogspot.ch/2014/05/popup-calendar-webplayer-compatible.html
http://spotfired.blogspot.com/2014/07/two-popup-calendars-start-and-end-date.html

html
<div style='display:none'>
   <div id='dt1Label'><SpotfireControl id='L4b31C0n7r01...'/>
   </div>
   <div id='dt2Label'><SpotfireControl id='L4b31C0n7r02...'/>
   </div>
</div>


Date1: <span id='dt1'><SpotfireControl id='Inpu7C0n7r01...'/>
<span id='dt1picker'></span>
Date2: <span id='dt2'><SpotfireControl id='Inpu7C0n7r02...'/>
<span id='dt2picker'></span>

js
//constraint date2 calendar based on selection and update property controls automatically
function picker1_onSelect(selectedDate,inst){

 //min date constraint based on other picker
 minDate = $(this).datepicker("getDate")
 $("#datePicker2").datepicker("option","minDate",minDate);

 //update document property after selection
 $("#dt1 input").focus(); 
 $("#dt2 input").focus(); 
}

//update document property after selection
function picker2_onSelect(selectedDate){
 $("#dt2 input").focus(); 
 $("#dt1 input").focus(); 
}

//global datepicker options
pickerOptions = {
 showOn: 'button', 
 buttonImageOnly: true, 
 buttonImage: 'http://kalender.isetegija.net/Styles/SandBeach/Images/DatePicker.gif', 
 minDate: "-36M", maxDate: "+0D",
 changeMonth: true,
 changeYear: true
}


//create first date picker
document.getElementById('dt1picker').innerHTML="<input type='hidden' id='datePicker1' value="+$('#dt1Label').text()+">"
$("#datePicker1").datepicker(pickerOptions);
$("#datePicker1").datepicker("option",{altField:"#dt1 input", onClose:picker1_onSelect})


//create second date picker
document.getElementById('dt2picker').innerHTML="<input type='hidden' id='datePicker2'value="+$('#dt2Label').text()+">"
$("#datePicker2").datepicker(pickerOptions);
$("#datePicker2").datepicker("option",{altField:"#dt2 input", onClose:picker2_onSelect})




Friday, October 27, 2017

SQL - Sometimes it is good to use cursor

This is an example of calculating distance between two coordinates.

First step is two cursors to calculate distance. two levels. Within same county, calculate distance.
Second step is one cursor to assign same Pad to coordinates within certain distance.






Monday, October 23, 2017

Spotfire - Show/Hide Items trick (Visualization)

Rule Order
You can apply one or more rules to the visualization where you select either to show or hide some of the items (e.g., bars, markers or sectors) from the visualization. The order of the rules in the Show/Hide Items tab determines which rule should be applied if multiple rules affect the same item: They are always prioritized from top to bottom so the top rule will determine whether an item should be shown or hidden.
The last active rule in the list determines whether or not items that are not matched by any rule should be shown or hidden: If the last active rule hides items, then the unmatched items will be shown. If the last active rule shows items, then the unmatched items are hidden.
This may have some implications on visualizations where multiple rules are used and some of them contradict each other. For example, using the same data as above and applying Show Top 2 and Hide Bottom 2 rules simultaneously will give the following results, depending on the order of the rules:

Friday, October 13, 2017

Spotfire - Sort Visual Cross Table (Ironpython)


from Spotfire.Dxp.Application.Visuals import TablePlot
from Spotfire.Dxp.Application.Visuals import TableLayout


myVisualTable = crossTable.As[CrossTablePlot]()
myVisualTable.SortRowsCategory = CategoryKey('Count')
myVisualTable.SortRowsOrder = SortOrder.Descending

Spotfire - Reset Zoom Sliders by looping through visuals and checking each visual type (Ironpython)

#Reset zoom sliders
from Spotfire.Dxp.Application.Visuals import * 

#1 Loops through visuals
for vis in Application.Document.ActivePageReference.Visuals: 

  #1.1 check each visual type
  if vis.TypeId==VisualTypeIdentifiers.BarChart:

    #1.2 Reset zoom sliders
    vis.As[VisualContent]().XAxis.ZoomRange=AxisRange.DefaultRange

Thursday, October 12, 2017

Spotfire - Filter data by user input (R script)

1. Create Input Field (multiple select) in the Text Area










2. Create Data Function


3. Add Input/Output Parameters

4. Edit Parameters for both Input/Output











5. Add table use the following steps:

6. To apply the function in the list box. Add "Apply" and "Clear" button and add script
7. Make sure to add relationship between the user input data table and the data Table

Tuesday, October 10, 2017

Spotfire - Document to install JavaScript Visualization - JSViz

https://d2wh20haedxe3f.cloudfront.net/sites/default/files/wiki_files/installing_the_javascript_visualization_framework_into_spotfire_desktop_0.pdf

Interesting charts:

d3js.org

https://github.com/d3/d3/wiki/Gallery


https://developer.mozilla.org/en-US/docs/Web/API/Document_Object_Model

The Document Object Model (DOM) is a programming interface for HTML and XML documents. It represents the page so that programs can change the document structure, style and content. The DOM represents the document as nodes and objects. That way, programming languages can connect to the page.


A Web page is a document. This document can be either displayed in the browser window, or as the HTML source. But it is the same document in both cases. The Document Object Model (DOM) represents that same document so it can be manipulated. The DOM is an object-oriented representation of the web page, which can be modified with a scripting language such as JavaScript.

Spotfire - Change Document Property (Ironpython)

e.g.
if col.Name == "Vertical Depth (ft)":
col.Properties['DefaultContinuousColorScheme'] = "colorMetricGradientRainbow"
col.Properties['DefaultCategoricalColorScheme'] = "colorMetricGradient"
col.Properties['ptyMapColorStyle']="[Vertical Depth (ft)]"
col.Properties['ptyNameOriginal']="Vertical Depth"
col.Properties['ptyUnitDefault']="ft"
col.Properties['ptyUnitImperial']="ft"
col.Properties['ptyUnitMetric']="m"
col.Properties['ptyUnitConversion']="0.3048"
col.Properties['ptyNormalizationFactor']="1000"
col.Properties['ptyNormalizationUnit']="thousand ft"

Monday, October 9, 2017

Spotfire - Debug TextArea HTML Javascript in Chrome

html:
<div id='textAreaUrl'>---</div>

js:
$('#textAreaUrl').text(top.location)

Copy paste the url onto Chrome and start debugging with Developer Tools (F12)

Wednesday, October 4, 2017

Spotfire - Error handling types


Spotfire - Create a button to toggle a map layer on and off (Ironpython)

from Spotfire.Dxp.Application.Visuals import *

v = viz.As[VisualContent]()

for i in v.Layers:

          if i.Title == 'County_shape':
                  if i.Enabled == True:
                          i.Enabled == False
             
                  else:
                          i.Enabled == True

Spotfire - Remove bookmarks (Ironpython)

from Spotfire.Dxp.Application.AnalyticItems import BookmarkManager

bookmarkManager = Application.Document.Context.GetService(BookmarkManager)

for b in bookmarkManager.GetBookmarks():

       bookmarkManager.Remove(b)

Spotfire - Replace and refresh data and onclick button loading event (HTML and JS)

ironPython:

import System
import Spotfire.Dxp.Application
from Spotfire.Dxp.Data import *
from Spotfire.Dxp.Data.Import import DataTableDataSource
from Spotfire.Dxp.Data import CalculatedColumn
from System.IO import FileStream, FileMode, File, MemoryStream, SeekOrigin, StreamWriter, StreamReader
import System.String
from Spotfire.Dxp.Data.Import import TextDataReaderSettings
from Spotfire.Dxp.Data.Import import TextFileDataSource
import clr
clr.AddReference("System.Windows.Forms")
import System.Windows.Forms as WinForms
from Spotfire.Dxp.Framework.ApplicationModel import NotificationService
from System.Windows.Forms import OpenFileDialog
from System.Collections.Generic import List, Dictionary
from Spotfire.Dxp.Application.Visuals import HtmlTextArea
from Spotfire.Dxp.Framework.ApplicationModel import *

#get data source location
file_loc = OpenFileDialog()
file_loc.InitialDirectory
file_loc.ShowDialog()

try: #validate the source

ds = Document.Data.CreateFileDataSource(file_loc.FileName)

     #since source_tbl is linked to source, need to replace it
source_tbl = Document.Data.Tables["well_attributes"].ReplaceData(ds)

except ValueError:
WinForms.MessageBox.Show("No file selected! Please select the file to refresh.")
        #refresh text area
vis.As[HtmlTextArea]().HtmlContent += " " # Force re-render
raise #Rethrow the original exception, so I get a stack trace to it.

 except IOError:
WinForms.MessageBox.Show("Please select the right file type.")
vis.As[HtmlTextArea]().HtmlContent += " "
raise

#notification service
notify = Application.GetService[NotificationService]();

# Tables(s) to refresh - change/add more if required
Tbls = List[DataTable]()
Tbls.Add(Document.Data.Tables['myTableName'])


# After tables are refreshed, update html
def afterLoad(exception, Document=Document, notify=notify):
if not exception:

# Hide the loading div
newHtml = vis.As[HtmlTextArea]().HtmlContent
oldDiv = '<div id="loading" style="display:inline">'
newDiv = '<div id="loading" style="display:none">'
newHtml = newHtml.Replace(oldDiv,newDiv)

# Apply change
vis.As[HtmlTextArea]().HtmlContent = newHtml;
vis.As[HtmlTextArea]().HtmlContent += " " # Force re-render

else:
notify.AddErrorNotification("Error refreshing table(s)","Error details",str(exception))

# Refresh table(s)
Document.Data.Tables.RefreshAsync(Tbls, afterLoad)

#message box after successful load and refresh data
WinForms.MessageBox.Show("Data has been successfully refreshed! ")

HTML:

<p style="text-indent: 4em;"> <font size="2"><strong> Please click to select well_attributes file (.csv file) to refresh:</strong></font>
<div id="clicker" style="visibility: visible;">
<SpotfireControl id="67e98bb593da44afaf6cfda44a8030e2" />
<font color="red" size="2"><strong>
<div id="loading"
style="display: none;">Refreshing...Please wait. DO NOT load file again!
</div></strong></font>
</div>

Javascript:
$('#67e98bb593da44afaf6cfda44a8030e2').click(function() {
   
// Show the loading prompt
$('#loading').css('display', 'inline');
// Click the python button 
$('#clickerpy input').click()
// disable the refresh button 
document.getElementById("67e98bb593da44afaf6cfda44a8030e2").disabled = true
   
});