如何在Spotfire信息链接中获取下拉过滤器?

时间:2019-01-31 13:16:05

标签: mysql spotfire

通常,人们使用Spotfire提供的默认选项。连接到数据库并提取所需的一组列,并创建一个信息链接,然后将数据加载到Spotfire。

但是,我正在使用SQL Query将数据提取到Spotfire。我正在创建一个类似于Views的表,并编写一个简单的存储过程来提取数据:

Create procedure ProcA(In Start_Date date, IN End_Date date, In Site_Name text)
Begin

SELECT * FROM TableA where day between Start_Date and End_Date and
site_name = Site_Name;

如果我不使用网站名称过滤,则可以正常工作。

信息链接有助于正确过滤日期。但是当涉及到站点名称时,没有任何效果。

有2个要求:

  1. 是否可以像下拉过滤器一样为Date提供一个下拉列表
  2. 如何传递多个站点名称以仅将那些站点拉入Spotfire文件

1 个答案:

答案 0 :(得分:0)

TL; DR:有更好的方法可以做到这一点;如果只是为了列名,我认为不应该做第2部分,因为更改信息链接中的sql很容易,但是有可能。

好的,我会尽量避免(读:失败)。

1)可以对日期进行下拉吗? 是的。最简单的方法是提取所有用户的数据表最终用户可用的日期选择。这是查找better way to generate months/year table列表的示例,请记住,在创建下拉列表时,文档属性必须具有数据类型“日期”,然后您应该能够通过日期列中的“唯一值”来设置属性值从新数据中提取数据,就像处理字符串下拉列表一样。

如果您有一小部分特定日期可供选择,这可能还不错。如果下拉列表变长,您的最终用户可以输入他们要查找的日期以加快搜索速度(尽管根据我的经验,很多用户会滚动浏览直到找到所需的日期) )。

虽然这是完全可以接受的,但是如果您完全愿意添加JavaScript,我个人建议使用Popup Calendar,对于最终用户而言,它们非常简单,并且可以允许他们使用日历或输入它本身。 (而且,如果他们键入的不是日期,则甚至可以用红色字母和感叹号告知他们尚未键入实际日期,这足够了)

2)如何传递多个站点名称以仅将那些站点拉入Spotfire文件

嘘,从哪里开始。

第一步:您如何选择站点名称列表?我将继续假设您有一个包含不同站点名称列表的数据表。

您的下一个选择是如何让您的用户选择所需的站点名称。常规选项是使用列表框过滤器,显示表格和使用标记的行,或者提供文本区域,用户可以在其中键入自己的选择。

当我需要这样做的时候,我做了一个数据表和一个文本区域的组合,这就是我将在这里描述的内容。

首先,我为用户提供一个文本区域,该区域的格式设置为“特定大小”,并且具有比通常更高的高度,以提示,是的,允许他们键入多行。如果他们知道要查找的值,则可以手动键入它们,或从excel文件中复制粘贴,等等。

如果他们不知道要查找的内容,站点名称列表将显示在为用户显示的表格中,然后他们可以在可视化中标记所需的行,然后按一个按钮即可光标在标记的站点名称列表中,将它们连接在一起,然后将它们放在前面提到的文本框中(注意:如果不想让它们手动输入列表,则可以不使用文本区域,将它们合并接下来的两段代码,并将其直接放入SpecialFilterProperty)。

请注意,光标速度很慢;如果您要循环浏览的行超过数千行,则可能会停顿几秒钟。

按钮的代码:

from Spotfire.Dxp.Application.Visuals import CrossTablePlot
from Spotfire.Dxp.Data import IndexSet
from Spotfire.Dxp.Data import RowSelection
from Spotfire.Dxp.Data import DataValueCursor
from Spotfire.Dxp.Data import DataSelection

TextFltr = ""

crossSource = Document.Data.Tables["Distinct_SiteNames"]

##Get a Row Count
rowCount = Document.Data.Tables["Distinct_SiteNames"].RowCount

##Index Set of all our rows

rowIndexSet=Document.ActiveMarkingSelectionReference.GetSelection(Document.Data.Tables["Distinct_SiteNames"]).AsIndexSet()

allRows = IndexSet(rowCount,True)

if rowIndexSet.IsEmpty != True:
    allRows = rowIndexSet

colCurs = DataValueCursor.CreateFormatted(crossSource.Columns["Site_Name"])

##Optional: Loop through to determine average value
colTotal = ''
for row in crossSource.GetRows(allRows, colCurs):
    colTotal += ', ' + colCurs.CurrentValue

if TextFltr == "":
    TextFltr += colTotal[2:]
else:
    TextFltr += colTotal

Document.Properties["SelectedSiteNames"] = TextFltr 

from System.Collections.Generic import Dictionary
from Spotfire.Dxp.Application.Scripting import ScriptDefinition
import clr
scriptDef = clr.Reference[ScriptDefinition]()
Document.ScriptManager.TryGetScript("Change Special Filter Value", scriptDef)
params = Dictionary[str, object]()
Document.ScriptManager.ExecuteScript(scriptDef.ScriptCode, params)

在底部引用了第二个脚本;这是按钮上附加的脚本,当用户想要提交选择并刷新数据表时,该脚本将分析文本区域。

我在这里使用的通用代码是名为“更改特殊过滤器值”的脚本,该脚本允许按换行符,制表符,逗号,引号和其他一些字符进行定界。可以根据您的用户需要在此处随意添加或减少。

strVals = Document.Properties["SelectedSiteNames"]

lst = ""

cnt = 0

x = 0
y = 0
z = 0
for letter in strVals:
    if y == 1:
        if letter == " ":
            lst = lst + "'" + strVals[x:z] + "', "
            y = 0
        elif letter == ",":
            lst = lst + "'" + strVals[x:z] + "', "
            y = 0
        elif letter == "\n":
            lst = lst + "'" + strVals[x:z] + "', "
            y = 0
        elif letter == "\r":
            lst = lst + "'" + strVals[x:z] + "', "
            y = 0
        elif letter == "'":
            lst = lst + "'" + strVals[x:z] + "', "
            y = 0
        elif letter == '"':
            lst = lst + "'" + strVals[x:z] + "', "
            y = 0
        elif letter == '\t':
            lst = lst + "'" + strVals[x:z] + "', "
            y = 0
    else:
        if letter <> " " and letter <> "," and letter <> "\n" and letter <> "\r" and letter <> "'" and letter <> '"' and letter <> "\t":
            if y == 0:
                cnt += 1
            print letter
            x = z
            y = 1
    z += 1
if y == 1:
    lst = lst + "'" + strVals[x:z] + "', "

print lst
lst = lst.upper()
if len(lst) > 0:
    lst = lst[1:len(lst) - 3]
    Document.Properties["SpecialFilterValue"] = lst

第一步已完成!您可以在属性中找到所有选定站点名称的列表,现在可以将其传递给存储过程。

注意:我相信Spotfire可以通过字符串值传递的字符数是有限制的。在我之前的测试中,我认为它已经超过了500,000个字符(已经有一段时间了,所以我记不清了),因此您有很多回旋余地,但确实存在,并且取决于您使用的是哪个数据源,可能会更低。

第二步:更改存储过程

您的存储过程基本上就是这样:

Create procedure ProcA(In Start_Date date, IN End_Date date, In Site_Name text)
Begin

    DECLARE @Script nvarchar(max) =
    N'
    Select * from TableA where day between Start_Date and End_Date and Site_Name in (' + @Site_Name + ') '

    EXECUTE (@Script)

完全比较容易! (毕竟,没有循环!我记得的奇怪的用例在这里并不适用,除非您还使用了不允许直接传递参数的数据库...)