文章目录
集成x-spreadsheet
准备工作
去github下载最新的xspreadsheet,5.20号更新了一个功能。下载之后,解压,npm install , npm run dev没问题后。把dist文件夹下所有文件复制,包括子目录。放在新建的文件夹\superset-frontend\src\xspreadsheet下面。这个文件就是一个组件,之后去调用就可以了。
后端
修改 viz.py , 模仿TableViz,添加 XspreadsheetViz,几乎只用修改 get_data
class XspreadsheetVix(BaseViz):
"""集成xspreadsheet"""
viz_type = "xspreadsheet"
verbose_name = _("Xspreadsheet")
is_timeseries = False
enforce_numerical_metrics = False
def should_be_timeseries(self):
fd = self.form_data
# TODO handle datasource-type-specific code in datasource
conditions_met = (fd.get("granularity") and fd.get("granularity") != "all") or (
fd.get("granularity_sqla") and fd.get("time_grain_sqla")
)
if fd.get("include_time") and not conditions_met:
raise Exception(
_("Pick a granularity in the Time section or " "uncheck 'Include Time'")
)
return fd.get("include_time")
def query_obj(self) -> Dict[str, Any]: # Any类型兼容所有类型,赋值时不用安全检查
'''
重写 qurey_obj,处理查询条件
:return: d
'''
d = super().query_obj()
fd = self.form_data
if fd.get("all_columns") and (
fd.get("groupby") or fd.get("metrics") or fd.get("percent_metrics")
):
raise Exception(
_(
"Choose either fields to [Group By] and [Metrics] and/or "
"[Percentage Metrics], or [Columns], not both"
)
)
sort_by = fd.get("timeseries_limit_metric")
if fd.get("all_columns"):
d["columns"] = fd.get("all_columns")
d["groupby"] = []
order_by_cols = fd.get("order_by_cols") or []
d["orderby"] = [json.loads(t) for t in order_by_cols]
elif sort_by:
sort_by_label = utils.get_metric_name(sort_by)
if sort_by_label not in utils.get_metric_names(d["metrics"]):
d["metrics"] += [sort_by]
d["orderby"] = [(sort_by, not fd.get("order_desc", True))]
# Add all percent metrics that are not already in the list
if "percent_metrics" in fd:
d["metrics"].extend(
m for m in fd["percent_metrics"] or [] if m not in d["metrics"]
)
d["is_timeseries"] = self.should_be_timeseries()
return d
@staticmethod
def df2xspreadsheetjson(df) -> Dict:
'''
df对象转为 x-spreadsheet格式的json字符串
:param df: 从数据库得到的 dataframe
:return: str
'''
cols = []
# 重命名标题行,主要考虑标题行空等情况
for col in df.columns:
if col == "":
cols.append("N/A") # 标题行空,一般不可能
elif col is None:
cols.append("NULL") # 表是空的
else:
cols.append(col) # 复制过去
# print(cols)
df.columns = cols
if df.shape[0] < 1 or df.shape[1] < 1:
return '{}'
metrics = cols
df = df[metrics] # 取我们需要的字段
# 直接拼接字符串
info = ''