【问题标题】:How to get a drop-down filter in Spotfire Information Link?如何在 Spotfire 信息链接中获取下拉过滤器?
【发布时间】:2019-02-13 07:44:09
【问题描述】:

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

但是,我正在使用 SQL 查询将数据提取到 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;

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

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

有两个要求:

  1. 是否可以像过滤器一样为日期提供下拉菜单
  2. 如何传递多个站点名称以仅将这些站点拉入 Spotfire 文件中

【问题讨论】:

  • 1) 我会创建一个单独的信息链接或程序来获得一个不同的 Site_Names 列表并从中制作下拉列表。 2)这是可行的,但它会使您的“简单存储过程”变得更加复杂。您最终将不得不编写一个 IronPython 脚本,将所有选择的值组合成一个长分隔字符串,然后在存储过程中编写一个循环,将您的字符串解析为单独的值。根据我的经验,偶尔会有这样做的理由,但在大多数情况下,我不确定您为什么要进行如此简单的查询。
  • 非常感谢@Chelsea 的输入,如果我通过拉列来使用普通 IL 来创建 IL,则默认情况下会出现下拉菜单。但即使是列名的微小变化,我也必须再次拉出所有列以重新创建 IL。为避免这种情况,我尝试使用允许任何列名的过程,尽管列名发生了变化。希望你能解决我面临的问题。
  • 是的。完全熟悉那个。作为警告,如果您走这条路线并且列名更改或列被删除,它将破坏您用户的书签,因此对于最终版本,如果纯粹是为了列,我尽量不要使用这种方法。如果您想走存储过程路线,并且您的数据集很小,那么提取整个数据集然后在可视化本身中通过您的站点名称列表限制数据可能会更容易。 (除非您另有说明,否则我会假设您的数据集很大,并尝试稍后找时间为您编写此内容。可能需要一点时间)

标签: mysql spotfire


【解决方案1】:

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

好的,我会尽量(阅读:失败)不要太啰嗦。

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

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

虽然这是完全可以接受的,但如果您愿意添加 javascript,我个人建议使用 Popup Calendar 这些对于最终用户来说相当简单,并且可以允许他们使用日历或自己输入. (如果他们输入的不是日期,甚至可以用红色字母和感叹号告知他们没有输入实际日期)

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

Hoo boi,从哪里开始。

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

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

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

我首先为用户提供了一个文本区域,该区域的格式设置为“特定大小”,其高度大于通常的高度,以提示,是的,他们可以输入多行。如果他们知道他们要查找的值,他们可以手动输入,或者从 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)

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多