PipeGraphPy 2.0.6__py3-none-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- PipeGraphPy/__init__.py +10 -0
- PipeGraphPy/common.py +4 -0
- PipeGraphPy/config/__init__.py +276 -0
- PipeGraphPy/config/custom.py +6 -0
- PipeGraphPy/config/default_settings.py +125 -0
- PipeGraphPy/constants.py +421 -0
- PipeGraphPy/core/__init__.py +2 -0
- PipeGraphPy/core/anchor.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/edge.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/graph.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/graph_base.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/__init__.py +3 -0
- PipeGraphPy/core/modcls/base.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/branchselect.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/classifier.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/cluster.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/datacharts.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/deeplearning.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/endscript.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/ensemble.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/evaluate.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/exportdata.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/handlescript.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/importdata.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/merge.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/mergescript.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/metrics.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/postprocessor.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/preprocessor.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/pythonscript.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/regressor.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/selector.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/selectscript.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/special.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/split.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/splitscript.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/startscript.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modcls/transformer.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/module.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/modules/__init__.py +65 -0
- PipeGraphPy/core/modules/classifier/__init__.py +2 -0
- PipeGraphPy/core/modules/cluster/__init__.py +0 -0
- PipeGraphPy/core/modules/custom/__init__.py +0 -0
- PipeGraphPy/core/modules/custom/classifier/__init__.py +0 -0
- PipeGraphPy/core/modules/datacharts/__init__.py +5 -0
- PipeGraphPy/core/modules/datacharts/dataview.py +28 -0
- PipeGraphPy/core/modules/deeplearning/__init__.py +0 -0
- PipeGraphPy/core/modules/ensemble/__init__.py +0 -0
- PipeGraphPy/core/modules/evaluate/__init__.py +0 -0
- PipeGraphPy/core/modules/exportdata/__init__.py +0 -0
- PipeGraphPy/core/modules/importdata/__init__.py +0 -0
- PipeGraphPy/core/modules/merge/__init__.py +0 -0
- PipeGraphPy/core/modules/model_selector/__init__.py +3 -0
- PipeGraphPy/core/modules/postprocessor/__init__.py +0 -0
- PipeGraphPy/core/modules/preprocessor/__init__.py +0 -0
- PipeGraphPy/core/modules/pythonscript/__init__.py +0 -0
- PipeGraphPy/core/modules/regressor/__init__.py +0 -0
- PipeGraphPy/core/modules/selector/__init__.py +0 -0
- PipeGraphPy/core/modules/special/__init__.py +0 -0
- PipeGraphPy/core/modules/split/__init__.py +0 -0
- PipeGraphPy/core/modules/transformer/__init__.py +0 -0
- PipeGraphPy/core/node.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/core/pipegraph.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/db/__init__.py +2 -0
- PipeGraphPy/db/models.cp39-win_amd64.pyd +0 -0
- PipeGraphPy/db/utils.py +106 -0
- PipeGraphPy/decorators.py +42 -0
- PipeGraphPy/logger.py +170 -0
- PipeGraphPy/plot/__init__.py +0 -0
- PipeGraphPy/plot/draw.py +424 -0
- PipeGraphPy/storage/__init__.py +10 -0
- PipeGraphPy/storage/base.py +2 -0
- PipeGraphPy/storage/dict_backend.py +102 -0
- PipeGraphPy/storage/file_backend.py +342 -0
- PipeGraphPy/storage/redis_backend.py +183 -0
- PipeGraphPy/tools.py +388 -0
- PipeGraphPy/utils/__init__.py +1 -0
- PipeGraphPy/utils/check.py +179 -0
- PipeGraphPy/utils/core.py +295 -0
- PipeGraphPy/utils/examine.py +259 -0
- PipeGraphPy/utils/file_operate.py +101 -0
- PipeGraphPy/utils/format.py +303 -0
- PipeGraphPy/utils/functional.py +422 -0
- PipeGraphPy/utils/handle_graph.py +31 -0
- PipeGraphPy/utils/lock.py +1 -0
- PipeGraphPy/utils/mq.py +54 -0
- PipeGraphPy/utils/osutil.py +29 -0
- PipeGraphPy/utils/redis_operate.py +195 -0
- PipeGraphPy/utils/str_handle.py +122 -0
- PipeGraphPy/utils/version.py +108 -0
- PipeGraphPy-2.0.6.dist-info/METADATA +17 -0
- PipeGraphPy-2.0.6.dist-info/RECORD +94 -0
- PipeGraphPy-2.0.6.dist-info/WHEEL +5 -0
- PipeGraphPy-2.0.6.dist-info/top_level.txt +1 -0
PipeGraphPy/plot/draw.py
ADDED
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
import copy
|
|
2
|
+
from PipeGraphPy.constants import MODULES # , JUPYTER_TYPE
|
|
3
|
+
from prettytable import PrettyTable
|
|
4
|
+
from PipeGraphPy.config import settings
|
|
5
|
+
|
|
6
|
+
# from PipeGraphPy.plot.plt_draw import ChartNode, ChartGraph, ChartArrow
|
|
7
|
+
|
|
8
|
+
default_str = "--"
|
|
9
|
+
replace_str = "="
|
|
10
|
+
stop_str = "|"
|
|
11
|
+
connect_str = " --> "
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def get_all_node(all_pipline):
|
|
15
|
+
"""获取有序的所有节点列表"""
|
|
16
|
+
# 所有节点
|
|
17
|
+
all_nodes = []
|
|
18
|
+
_ = [all_nodes.extend(i) for i in all_pipline]
|
|
19
|
+
# 去重
|
|
20
|
+
all_nodes = list(set(all_nodes))
|
|
21
|
+
# 排序
|
|
22
|
+
for i in range(len(all_pipline)):
|
|
23
|
+
indexs = [all_nodes.index(j) for j in all_pipline[i]]
|
|
24
|
+
indexs_sort = sorted(indexs)
|
|
25
|
+
copy_nodes = copy.deepcopy(all_nodes)
|
|
26
|
+
for n, i in enumerate(indexs_sort):
|
|
27
|
+
all_nodes[i] = copy_nodes[indexs[n]]
|
|
28
|
+
return all_nodes
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def get_one_head_pipline_list(graph, head):
|
|
32
|
+
"""获取一个头节点下所有节点走向列表
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
head (Node): 头节点
|
|
36
|
+
|
|
37
|
+
Returns:
|
|
38
|
+
list(list[Node]): 走向列表
|
|
39
|
+
"""
|
|
40
|
+
|
|
41
|
+
pipline_list = list()
|
|
42
|
+
pipline = list()
|
|
43
|
+
|
|
44
|
+
def _iter_children(node):
|
|
45
|
+
pipline.append(node)
|
|
46
|
+
if not graph.a.source_nodes_group.get(node):
|
|
47
|
+
pipline_list.append(copy.deepcopy(pipline))
|
|
48
|
+
return
|
|
49
|
+
for i in graph.a.source_nodes_group[node]:
|
|
50
|
+
_iter_children(i)
|
|
51
|
+
pipline.pop()
|
|
52
|
+
|
|
53
|
+
_iter_children(head)
|
|
54
|
+
return pipline_list
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def get_head_cls(graph):
|
|
58
|
+
"""由头节点开头的子节点集合的个数"""
|
|
59
|
+
head_child_set_list = list() # 由头节点开头的子节点集合的个数
|
|
60
|
+
for head in graph.a.start_nodes:
|
|
61
|
+
node_set = set()
|
|
62
|
+
for child in graph.a._iter_children(head):
|
|
63
|
+
node_set.add(str(child))
|
|
64
|
+
head_child_set_list.append([[head], node_set])
|
|
65
|
+
for i in range(len(head_child_set_list), 1, -1):
|
|
66
|
+
for j in range(i - 1):
|
|
67
|
+
if head_child_set_list[i - 1][1] & head_child_set_list[j][1]:
|
|
68
|
+
head_child_set_list[j][0].extend(head_child_set_list[i - 1][0])
|
|
69
|
+
head_child_set_list[i - 1] = []
|
|
70
|
+
break
|
|
71
|
+
return [i[0] for i in head_child_set_list if i]
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def merge_same_node(gpl):
|
|
75
|
+
"""把相同的节点合并"""
|
|
76
|
+
# 循环所有节点
|
|
77
|
+
length = len(gpl[0])
|
|
78
|
+
for i in range(length):
|
|
79
|
+
# 统计相等的行
|
|
80
|
+
line_idx = [idx for idx, j in enumerate(gpl) if j[i] != default_str]
|
|
81
|
+
mid_idx = int((line_idx[0] + line_idx[-1]) / 2)
|
|
82
|
+
for idx in range(line_idx[0], line_idx[-1] + 1):
|
|
83
|
+
if idx == mid_idx:
|
|
84
|
+
gpl[idx][i] = gpl[line_idx[-1]][i]
|
|
85
|
+
elif gpl[idx][i] == default_str: # 变更中间的default_str 为 stop_str
|
|
86
|
+
gpl[idx][i] = stop_str
|
|
87
|
+
else:
|
|
88
|
+
gpl[idx][i] = replace_str
|
|
89
|
+
return gpl
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def compress2right(gpl):
|
|
93
|
+
"""向右压缩"""
|
|
94
|
+
length = len(gpl[0])
|
|
95
|
+
# 长度小于3直接返回, 不需要做处理
|
|
96
|
+
if length < 3:
|
|
97
|
+
return gpl
|
|
98
|
+
# 从倒数第二个至第一个循环, 逐列向右压缩
|
|
99
|
+
for i in range(length - 2, 0, -1):
|
|
100
|
+
# 统计相等的行
|
|
101
|
+
line_idx = [idx for idx, j in enumerate(gpl) if j[i] != default_str]
|
|
102
|
+
|
|
103
|
+
# 相等的中间行和最靠后的全为default_str的位置对换
|
|
104
|
+
for j in range(i + 1, length):
|
|
105
|
+
if all([gpl[k][j] == default_str for k in line_idx]):
|
|
106
|
+
if j < length - 1:
|
|
107
|
+
continue
|
|
108
|
+
else:
|
|
109
|
+
for k in line_idx:
|
|
110
|
+
gpl[k][i], gpl[k][j] = gpl[k][j], gpl[k][i]
|
|
111
|
+
break
|
|
112
|
+
else:
|
|
113
|
+
for k in line_idx:
|
|
114
|
+
gpl[k][i], gpl[k][j - 1] = gpl[k][j - 1], gpl[k][i]
|
|
115
|
+
break
|
|
116
|
+
# 去除全是default_str的列
|
|
117
|
+
# adsi:all_default_str_idx
|
|
118
|
+
adsi = list()
|
|
119
|
+
for i in range(length):
|
|
120
|
+
if all([j[i] == default_str for j in gpl]):
|
|
121
|
+
adsi.append(i)
|
|
122
|
+
if adsi:
|
|
123
|
+
for i in gpl:
|
|
124
|
+
i[adsi[0] : adsi[-1] + 1] = []
|
|
125
|
+
return gpl
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def compress2left(gpl):
|
|
129
|
+
"""向左压缩"""
|
|
130
|
+
length = len(gpl[0])
|
|
131
|
+
# 长度小于3直接返回, 不需要做处理
|
|
132
|
+
if length < 3:
|
|
133
|
+
return gpl
|
|
134
|
+
for i in range(2, length):
|
|
135
|
+
for j in range(len(gpl)):
|
|
136
|
+
if isinstance(gpl[j][i], str):
|
|
137
|
+
continue
|
|
138
|
+
for k in range(i - 1, -1, -1):
|
|
139
|
+
if gpl[j][k] == default_str:
|
|
140
|
+
continue
|
|
141
|
+
else:
|
|
142
|
+
if k + 1 == i:
|
|
143
|
+
break
|
|
144
|
+
gpl[j][k + 1], gpl[j][i] = gpl[j][i], gpl[j][k + 1]
|
|
145
|
+
break
|
|
146
|
+
return gpl
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def node_layout(graph, heads):
|
|
150
|
+
"""节点布局,各节点放在合适的位置
|
|
151
|
+
|
|
152
|
+
Args:
|
|
153
|
+
heads ([list(Node)]): 头节点
|
|
154
|
+
"""
|
|
155
|
+
|
|
156
|
+
# 所有节点走向列表
|
|
157
|
+
all_pipline = list()
|
|
158
|
+
for i in heads:
|
|
159
|
+
all_pipline.extend(get_one_head_pipline_list(graph, i))
|
|
160
|
+
|
|
161
|
+
# 有序的所有节点
|
|
162
|
+
all_node = get_all_node(all_pipline)
|
|
163
|
+
|
|
164
|
+
# 所有pipline节点按照all_node定位,使所有pipline等长,不存在的节点补default_str
|
|
165
|
+
same_len_pipline = list()
|
|
166
|
+
for i in all_pipline:
|
|
167
|
+
_lst = [default_str] * len(all_node)
|
|
168
|
+
for j in i:
|
|
169
|
+
_lst[all_node.index(j)] = j
|
|
170
|
+
same_len_pipline.append(_lst)
|
|
171
|
+
|
|
172
|
+
# 合并重名列
|
|
173
|
+
merge_pipline = merge_same_node(same_len_pipline)
|
|
174
|
+
|
|
175
|
+
# 向右压缩
|
|
176
|
+
compress_right_gpl = compress2right(merge_pipline)
|
|
177
|
+
|
|
178
|
+
# 向左压缩
|
|
179
|
+
compress_left_gpl = compress2left(compress_right_gpl)
|
|
180
|
+
|
|
181
|
+
return compress_left_gpl
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def plot_by_pt(graph):
|
|
185
|
+
"""通过pt展示图"""
|
|
186
|
+
# 分图,有可能是多张图, 把同一图的头节点,分到一个列表中
|
|
187
|
+
all_graph_node = list()
|
|
188
|
+
heads_cls = get_head_cls(graph)
|
|
189
|
+
for num, heads in enumerate(heads_cls):
|
|
190
|
+
# 节点排布
|
|
191
|
+
layout_node = node_layout(graph, heads)
|
|
192
|
+
|
|
193
|
+
if len(layout_node) > len(all_graph_node):
|
|
194
|
+
layout_node, all_graph_node = all_graph_node, layout_node
|
|
195
|
+
|
|
196
|
+
# 所有图的节点合并
|
|
197
|
+
default_lst = [default_str] * len(all_graph_node[0])
|
|
198
|
+
for i in layout_node:
|
|
199
|
+
c_lst = copy.copy(default_lst)
|
|
200
|
+
c_lst[: len(i)] = i
|
|
201
|
+
all_graph_node.append(c_lst)
|
|
202
|
+
# 节点标号
|
|
203
|
+
node2tag = dict()
|
|
204
|
+
num = 1
|
|
205
|
+
for i in all_graph_node:
|
|
206
|
+
for j in i:
|
|
207
|
+
if not isinstance(j, str):
|
|
208
|
+
node2tag[j] = num
|
|
209
|
+
num += 1
|
|
210
|
+
|
|
211
|
+
# 连接边
|
|
212
|
+
node2nodes = dict()
|
|
213
|
+
for k, v in graph.a.source_nodes_group.items():
|
|
214
|
+
node2nodes[graph.a.nodes_dict[k]] = [graph.a.nodes_dict[i] for i in v]
|
|
215
|
+
|
|
216
|
+
# 节点转字符
|
|
217
|
+
for i in range(len(all_graph_node)):
|
|
218
|
+
for j in range(len(all_graph_node[i])):
|
|
219
|
+
if not isinstance(all_graph_node[i][j], str):
|
|
220
|
+
if node2nodes.get(all_graph_node[i][j]):
|
|
221
|
+
all_graph_node[i][j] = "(%s)%s-->%s" % (
|
|
222
|
+
node2tag[all_graph_node[i][j]],
|
|
223
|
+
str(all_graph_node[i][j]),
|
|
224
|
+
",".join(
|
|
225
|
+
[str(node2tag[k]) for k in node2nodes[all_graph_node[i][j]]]
|
|
226
|
+
),
|
|
227
|
+
)
|
|
228
|
+
else:
|
|
229
|
+
all_graph_node[i][j] = "(%s)%s" % (
|
|
230
|
+
node2tag[all_graph_node[i][j]],
|
|
231
|
+
str(all_graph_node[i][j]),
|
|
232
|
+
)
|
|
233
|
+
else:
|
|
234
|
+
all_graph_node[i][j] = ""
|
|
235
|
+
|
|
236
|
+
# 打印显示
|
|
237
|
+
pt = PrettyTable()
|
|
238
|
+
pt.header = False
|
|
239
|
+
for i in all_graph_node:
|
|
240
|
+
pt.add_row(i)
|
|
241
|
+
print(pt)
|
|
242
|
+
return pt
|
|
243
|
+
|
|
244
|
+
|
|
245
|
+
def plot_by_jupyter(graph, just_build=False, load_javascript=False):
|
|
246
|
+
from pyecharts.globals import CurrentConfig
|
|
247
|
+
|
|
248
|
+
if settings.JUPYTER_TYPE not in JUPYTER_TYPE.values():
|
|
249
|
+
raise Exception("JUPYTER_TYPE设置错误")
|
|
250
|
+
CurrentConfig.NOTEBOOK_TYPE = settings.JUPYTER_TYPE
|
|
251
|
+
|
|
252
|
+
from pyecharts import options as opts
|
|
253
|
+
from pyecharts.charts import Graph
|
|
254
|
+
|
|
255
|
+
nodes = list()
|
|
256
|
+
links = list()
|
|
257
|
+
x_span = 160
|
|
258
|
+
y_span = 50
|
|
259
|
+
# merge_px = 100
|
|
260
|
+
max_width = 900
|
|
261
|
+
max_height = 500
|
|
262
|
+
sum_x, sum_y = 0, 0
|
|
263
|
+
merge = 100
|
|
264
|
+
init_edge = 50
|
|
265
|
+
|
|
266
|
+
# 分图,有可能是多张图, 把同一图的头节点,分到一个列表中
|
|
267
|
+
heads_cls = get_head_cls(graph)
|
|
268
|
+
nodes.append(opts.GraphNode(x=init_edge, y=init_edge, symbol_size=1, is_fixed=True))
|
|
269
|
+
for heads in heads_cls:
|
|
270
|
+
# 节点排布
|
|
271
|
+
layout_node = node_layout(graph, heads)
|
|
272
|
+
# 增加节点
|
|
273
|
+
for y_idx, i in enumerate(layout_node):
|
|
274
|
+
for x_idx, j in enumerate(i):
|
|
275
|
+
if not isinstance(j, str):
|
|
276
|
+
nodes.append(
|
|
277
|
+
opts.GraphNode(
|
|
278
|
+
name=str(j),
|
|
279
|
+
x=x_idx * x_span + merge,
|
|
280
|
+
y=y_idx * y_span + sum_y + merge,
|
|
281
|
+
is_fixed=True,
|
|
282
|
+
)
|
|
283
|
+
)
|
|
284
|
+
sum_y += len(layout_node) * y_span + merge
|
|
285
|
+
this_width = len(layout_node[0]) * x_span + merge
|
|
286
|
+
if this_width > sum_x:
|
|
287
|
+
sum_x = this_width
|
|
288
|
+
nodes.append(
|
|
289
|
+
opts.GraphNode(
|
|
290
|
+
x=sum_x + init_edge, y=sum_y + init_edge, symbol_size=1, is_fixed=True
|
|
291
|
+
)
|
|
292
|
+
)
|
|
293
|
+
sum_x = sum_x + merge
|
|
294
|
+
sum_y = sum_y + merge
|
|
295
|
+
|
|
296
|
+
# 生成连线
|
|
297
|
+
edges_tuple = [
|
|
298
|
+
(
|
|
299
|
+
graph.a.nodes_dict[i.info["source_id"]],
|
|
300
|
+
graph.a.nodes_dict[i.info["target_id"]],
|
|
301
|
+
)
|
|
302
|
+
for i in graph.edges
|
|
303
|
+
]
|
|
304
|
+
|
|
305
|
+
for i in edges_tuple:
|
|
306
|
+
links.append(opts.GraphLink(source=str(i[0]), target=str(i[1])))
|
|
307
|
+
|
|
308
|
+
# 画图
|
|
309
|
+
width = "%spx" % (max_width if sum_x > max_width else sum_x)
|
|
310
|
+
height = "%spx" % (max_height if sum_y > max_height else sum_y)
|
|
311
|
+
|
|
312
|
+
charts_graph = (
|
|
313
|
+
Graph(init_opts=opts.InitOpts(width=width, height=height))
|
|
314
|
+
.add(
|
|
315
|
+
"",
|
|
316
|
+
nodes,
|
|
317
|
+
links,
|
|
318
|
+
symbol_size=30,
|
|
319
|
+
layout="none",
|
|
320
|
+
edge_symbol=["circle", "arrow"],
|
|
321
|
+
)
|
|
322
|
+
.set_global_opts(title_opts=opts.TitleOpts(title=str(graph)))
|
|
323
|
+
)
|
|
324
|
+
if just_build:
|
|
325
|
+
if load_javascript:
|
|
326
|
+
charts_graph.load_javascript()
|
|
327
|
+
return charts_graph
|
|
328
|
+
return charts_graph.render_notebook()
|
|
329
|
+
|
|
330
|
+
|
|
331
|
+
# def draw_by_plt(graph):
|
|
332
|
+
# nodes = list()
|
|
333
|
+
# edges = list()
|
|
334
|
+
# x_span = 16
|
|
335
|
+
# y_span = 5
|
|
336
|
+
# sum_x, sum_y = 0, 0
|
|
337
|
+
|
|
338
|
+
# # 分图,有可能是多张图, 把同一图的头节点,分到一个列表中
|
|
339
|
+
# heads_cls = get_head_cls(graph)
|
|
340
|
+
# for heads in heads_cls:
|
|
341
|
+
# # 节点排布
|
|
342
|
+
# layout_node = node_layout(heads)
|
|
343
|
+
# # 增加节点
|
|
344
|
+
# for y_idx, i in enumerate(layout_node):
|
|
345
|
+
# for x_idx, j in enumerate(i):
|
|
346
|
+
# if not isinstance(j, str):
|
|
347
|
+
# nodes.append(
|
|
348
|
+
# ChartNode(
|
|
349
|
+
# x=x_idx * x_span + int(x_span / 2),
|
|
350
|
+
# y=y_idx * y_span + int(y_span / 2) + sum_y,
|
|
351
|
+
# name=str(j),
|
|
352
|
+
# )
|
|
353
|
+
# )
|
|
354
|
+
# sum_y += len(layout_node) * y_span
|
|
355
|
+
# this_width = len(layout_node[0]) * x_span
|
|
356
|
+
# if this_width > sum_x:
|
|
357
|
+
# sum_x = this_width
|
|
358
|
+
|
|
359
|
+
# # 生成连线
|
|
360
|
+
# edges_tuple = [
|
|
361
|
+
# (
|
|
362
|
+
# graph.a.nodes_dict[i.info["source_id"]],
|
|
363
|
+
# graph.a.nodes_dict[i.info["target_id"]],
|
|
364
|
+
# )
|
|
365
|
+
# for i in graph.edges
|
|
366
|
+
# ]
|
|
367
|
+
# nodes_dict = {i.name: i for i in nodes}
|
|
368
|
+
|
|
369
|
+
# for i in edges_tuple:
|
|
370
|
+
# edges.append(
|
|
371
|
+
# ChartArrow(start_node=nodes_dict[str(i[0])], end_node=nodes_dict[str(i[1])])
|
|
372
|
+
# )
|
|
373
|
+
|
|
374
|
+
# # 画图
|
|
375
|
+
# chart_graph = ChartGraph(nodes, edges, dict(xlim=(0, sum_x), ylim=(0, sum_y)))
|
|
376
|
+
# chart_graph.plot(sum_x, sum_y)
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
# def draw_graph(graph, load_javascript=False):
|
|
380
|
+
# """显示图
|
|
381
|
+
|
|
382
|
+
# Args:
|
|
383
|
+
# graph (Graph): 要显示的图
|
|
384
|
+
|
|
385
|
+
# Returns:
|
|
386
|
+
# object: 经过处理后的图
|
|
387
|
+
# """
|
|
388
|
+
# if not settings.ISJUPYTER:
|
|
389
|
+
# return draw_by_pt(graph)
|
|
390
|
+
# else:
|
|
391
|
+
# return draw_by_jupyter(graph, load_javascript)
|
|
392
|
+
# # return draw_by_plt(graph)
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
def draw_test(just_build=False):
|
|
396
|
+
from pyecharts.globals import CurrentConfig, NotebookType
|
|
397
|
+
|
|
398
|
+
CurrentConfig.NOTEBOOK_TYPE = NotebookType.JUPYTER_LAB
|
|
399
|
+
|
|
400
|
+
from pyecharts import options as opts
|
|
401
|
+
from pyecharts.charts import Graph
|
|
402
|
+
|
|
403
|
+
nodes = [
|
|
404
|
+
opts.GraphNode(name="结点1", symbol_size=10),
|
|
405
|
+
opts.GraphNode(name="结点2", symbol_size=20),
|
|
406
|
+
opts.GraphNode(name="结点3", symbol_size=30),
|
|
407
|
+
opts.GraphNode(name="结点4", symbol_size=40),
|
|
408
|
+
opts.GraphNode(name="结点5", symbol_size=50),
|
|
409
|
+
]
|
|
410
|
+
links = [
|
|
411
|
+
opts.GraphLink(source="结点1", target="结点2"),
|
|
412
|
+
opts.GraphLink(source="结点2", target="结点3"),
|
|
413
|
+
opts.GraphLink(source="结点3", target="结点4"),
|
|
414
|
+
opts.GraphLink(source="结点4", target="结点5"),
|
|
415
|
+
opts.GraphLink(source="结点5", target="结点1"),
|
|
416
|
+
]
|
|
417
|
+
c = (
|
|
418
|
+
Graph()
|
|
419
|
+
.add("", nodes, links, repulsion=4000)
|
|
420
|
+
.set_global_opts(title_opts=opts.TitleOpts(title="Graph-GraphNode-GraphLink"))
|
|
421
|
+
)
|
|
422
|
+
if not just_build:
|
|
423
|
+
c.load_javascript()
|
|
424
|
+
return c
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
from collections import defaultdict
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class ParamsPool:
|
|
5
|
+
"""传参池"""
|
|
6
|
+
|
|
7
|
+
def __init__(self, graph_id, object_id):
|
|
8
|
+
self.graph_id = graph_id
|
|
9
|
+
self.object_id = object_id
|
|
10
|
+
self.all_params = dict()
|
|
11
|
+
|
|
12
|
+
def __bool__(self):
|
|
13
|
+
return self.all_params
|
|
14
|
+
|
|
15
|
+
def __str__(self):
|
|
16
|
+
return str(list(self.all_params.keys()))
|
|
17
|
+
|
|
18
|
+
def add_params(self, id, anchor, data):
|
|
19
|
+
"""添加传参值"""
|
|
20
|
+
if self.get_params(id, anchor):
|
|
21
|
+
raise Exception("此参数已经存在")
|
|
22
|
+
self.all_params[(id, anchor)] = data
|
|
23
|
+
|
|
24
|
+
def get_params(self, id, anchor):
|
|
25
|
+
"""获取传参值"""
|
|
26
|
+
return self.all_params.get((id, anchor))
|
|
27
|
+
|
|
28
|
+
def get_params_by_node(self, node, anchor):
|
|
29
|
+
"""通过节点获取传参值"""
|
|
30
|
+
return self.get_params(node.id, int(str(anchor)))
|
|
31
|
+
|
|
32
|
+
def add_params_by_node(self, node, anchor, data):
|
|
33
|
+
"""通过节点添加传参"""
|
|
34
|
+
self.add_params(node.id, anchor, data)
|
|
35
|
+
|
|
36
|
+
def add_params_by_list(self, node, data_list):
|
|
37
|
+
"""通过数据列表添加传参"""
|
|
38
|
+
for idx, data in enumerate(data_list):
|
|
39
|
+
anchor = node.outidx_to_outanchor(idx)
|
|
40
|
+
self.add_params_by_node(node, anchor, data)
|
|
41
|
+
|
|
42
|
+
def is_end(self, node):
|
|
43
|
+
"""判断节点是否已运行完"""
|
|
44
|
+
return (
|
|
45
|
+
True
|
|
46
|
+
if self.get_params_by_node(node, node.anchors[1][0].anc) is not None
|
|
47
|
+
else False
|
|
48
|
+
)
|
|
49
|
+
|
|
50
|
+
def is_all_fathers_end(self, node):
|
|
51
|
+
"""循环父节点判断父节点是否已结束"""
|
|
52
|
+
return all([self.is_end(i) for i in node.fathers])
|
|
53
|
+
|
|
54
|
+
# def save_one(self, graph_id, node, anchor):
|
|
55
|
+
# '''将单个数据保存'''
|
|
56
|
+
# data = self.get_params_by_node(node, anchor)
|
|
57
|
+
# if not data:
|
|
58
|
+
# raise Exception('未找到模块输出数据')
|
|
59
|
+
# store.save_params(graph_id, node, anchor, data)
|
|
60
|
+
|
|
61
|
+
# def save_all(self, graph_id):
|
|
62
|
+
# '''将所有数据保存'''
|
|
63
|
+
# for (node, anchor), data in self.all_params.items():
|
|
64
|
+
# store.save_params(graph_id, node, anchor, data)
|
|
65
|
+
|
|
66
|
+
def gen_pass_params(self, node, nodes_group):
|
|
67
|
+
"""生成节点要传入的参数"""
|
|
68
|
+
if not self.is_all_fathers_end(node):
|
|
69
|
+
raise Exception("节点%s的父节点还有未运行完的节点" % node)
|
|
70
|
+
# edges_info = EdgesTB.find(graph_id=self.graph_id)
|
|
71
|
+
# nodes_info = NodesTB.find(graph_id=self.graph_id)
|
|
72
|
+
# nodes_info_dict = {i['id']: i for i in nodes_info}
|
|
73
|
+
# nodes_group_dict = gen_nodes_group_dict(edges_info, nodes_info_dict)
|
|
74
|
+
input_output_dict = defaultdict(list)
|
|
75
|
+
input_output_list = list()
|
|
76
|
+
# 循环所有父节点, 组合node和anchor值
|
|
77
|
+
for n in node.fathers:
|
|
78
|
+
output_anchor, input_anchor = nodes_group[(n.id, node.id)]
|
|
79
|
+
input_output_list.extend(
|
|
80
|
+
zip(list(input_anchor), [(n, int(i)) for i in output_anchor])
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
for i, o in input_output_list:
|
|
84
|
+
input_output_dict[int(i)].append(o)
|
|
85
|
+
|
|
86
|
+
# 根据node和anchor获取节点,识别列表,把接口是列表类型的数据放入一个列表中
|
|
87
|
+
input_params_list = list()
|
|
88
|
+
for k, v in input_output_dict.items():
|
|
89
|
+
if len(v) > 1:
|
|
90
|
+
input_params_list.append((k, [self.get_params_by_node(*i) for i in v]))
|
|
91
|
+
elif len(v) == 1:
|
|
92
|
+
input_params_list.append((k, self.get_params_by_node(*v[0])))
|
|
93
|
+
else:
|
|
94
|
+
raise Exception("传参错误")
|
|
95
|
+
# 参数排序
|
|
96
|
+
input_params_list.sort(key=lambda x: x[0])
|
|
97
|
+
arg = [i[1] for i in input_params_list]
|
|
98
|
+
# 当list输入为1个元素时要转成list
|
|
99
|
+
for i, item in enumerate(node.INPUT):
|
|
100
|
+
if item.startswith("list") and not isinstance(arg[i], list):
|
|
101
|
+
arg[i] = [arg[i]]
|
|
102
|
+
return arg
|