通过相关实体正确递归
我有一组组织及其董事会成员。 所有组织都有董事会成员,并且许多董事会成员同时担任多个组织的董事会成员。
我使用 JIT Hypertree 来说明它们的关系。 JIT 超树模式要求其中一项是所有项的父项,并且基于单个 JSON 数组绘制。
我希望重新居中事件查询并根据更改重新填充图表。那么 2 级就可以了,但我还没能弄清楚如何做到这一点。
我目前拥有的代码从起始组织手动递归三个级别,但我想要的是重新遍历所有相关记录。
因此,它将从一个 Org 开始,并添加 Org 的子数组(董事会成员)。然后获取每个董事会成员的所有董事会(当前组织除外)并将其添加为董事会成员的子级。
这种情况将持续下去,直到每一条线索都出现了死胡同——大概是在一位只属于一个董事会的董事会成员处。
有人对如何创建这个数组并避免重复有建议吗?
$board = $center->board();
$top['id'] = $center->ID;
$top['name'] = $center->Org;
$top['children'] = array();
if ($board) {
foreach ($board as $b) {
$child['id'] = $b->ID;
$child['name'] = (strlen(trim($b->Last)) > 0) ? $b->First . ' ' . $b->Last : 'Unknown';
$child['data']['orgname'] = $center->Org;
$child['data']['relation'] = $b->Role;
$child['data']['occupation'] = $b->Occupation;
$child['children'] = array();
$childboards = $b->boards();
if ($childboards) { foreach ($childboards as $cb) {
$gchild['id'] = $cb->ID;
$gchild['name'] = $cb->Org;
$gchild['data']['orgname'] = (strlen(trim($b->Last)) > 0) ? $b->First . ' ' . $b->Last : 'Unknown';
$gchild['children'] = array();
$childboardmembers = $cb->board();
if ($childboardmembers) { foreach ($childboardmembers as $cbm) {
$ggchild['id'] = $cbm->ID;
$ggchild['name'] = (strlen(trim($cbm->Last)) > 0) ? $cbm->First . ' ' . $cbm->Last : 'Unknown';
$ggchild['data']['orgname'] = $cb->Org;
$ggchild['data']['relation'] = $cbm->Role;
$ggchild['data']['occupation'] = $cbm->Occupation;
$ggchild['children'] = array();
$gchild['children'][]= $ggchild;
}}
$child['children'][]= $gchild;
}}
$top['children'][] = $child;
}
}
$top['data'] = array();
$top['data']['description'] = $center->Desc;
echo json_encode($top);
// 编辑 2011.10.24 Re hakre 回复 我的数据结构是一个具有唯一 ID 的组织表、一个具有唯一 ID 的人员表,然后是两个指定组织(实体)和人员以及人员在实体中扮演的角色的桥接表。典型的多对多。根本没有副板。我制作了它的图像,现在看起来毫无意义,但我会将其添加在底部。
JIT 库的数据结构(对我来说)有点疯狂,因为它在乐队示例中是这样的:
Top: Nine Inch Nails
Child: Jerome Dillon
Child: Howlin Maggie (another band)
{all the bands' members and then all of their bands...}
因此,组织(乐队)被视为一个人,即使它是由许多人组成的。当我使用上面的代码进行递归时,我得到了(我认为)可怕的膨胀,但是尽管有膨胀,它所生成的 JSON 仍然可以正常工作。
I have a set of Organizations and their Board Members.
All organizations have board members and many board members are on the board of more than one organization.
I am using JIT Hypertree to illustrate their relationships. The JIT Hypertree schema requires that one item be the parent of all and is drawn based on a single JSON array.
I would love to have the re-centering event query and re-populate the graph based on the change. Then 2 levels would be fine but I have not been able to work out how to do that.
The code I have at present recurses manually for three levels from the starting organization but what I want is to re-curse through all related records.
So it would start with an Org and add Org's array of children (board members). Then fetch all of the boards (other than current Org) for each board member and add those as children of the board member.
This would continue until each trail dead ends - presumably at a board member who only belongs to one board.
Anyone have advice on how to create this array and avoid duplicates?
$board = $center->board();
$top['id'] = $center->ID;
$top['name'] = $center->Org;
$top['children'] = array();
if ($board) {
foreach ($board as $b) {
$child['id'] = $b->ID;
$child['name'] = (strlen(trim($b->Last)) > 0) ? $b->First . ' ' . $b->Last : 'Unknown';
$child['data']['orgname'] = $center->Org;
$child['data']['relation'] = $b->Role;
$child['data']['occupation'] = $b->Occupation;
$child['children'] = array();
$childboards = $b->boards();
if ($childboards) { foreach ($childboards as $cb) {
$gchild['id'] = $cb->ID;
$gchild['name'] = $cb->Org;
$gchild['data']['orgname'] = (strlen(trim($b->Last)) > 0) ? $b->First . ' ' . $b->Last : 'Unknown';
$gchild['children'] = array();
$childboardmembers = $cb->board();
if ($childboardmembers) { foreach ($childboardmembers as $cbm) {
$ggchild['id'] = $cbm->ID;
$ggchild['name'] = (strlen(trim($cbm->Last)) > 0) ? $cbm->First . ' ' . $cbm->Last : 'Unknown';
$ggchild['data']['orgname'] = $cb->Org;
$ggchild['data']['relation'] = $cbm->Role;
$ggchild['data']['occupation'] = $cbm->Occupation;
$ggchild['children'] = array();
$gchild['children'][]= $ggchild;
}}
$child['children'][]= $gchild;
}}
$top['children'][] = $child;
}
}
$top['data'] = array();
$top['data']['description'] = $center->Desc;
echo json_encode($top);
// Edit 2011.10.24 In Re hakre response
My data structure is a table of Organizations with unique IDs, a table of People with Unique IDs, and then a bridging table for the two specifying Organization (Entity) and Person and the Role the Person is playing in the Entity. A typical many-to-many. No sub-boards at all. I made an image of it which now seems kind of pointless but I'll add it at the bottom.
The JIT library data structure is a little nuts (to me) in that it goes like this in their band example:
Top: Nine Inch Nails
Child: Jerome Dillon
Child: Howlin Maggie (another band)
{all the bands' members and then all of their bands...}
So the organization (band) is treated as though it is a Person even though it is comprised of a number of Persons. And when I recurse using the code above I get (I think) terrible bloat but the JSON it makes works correctly despite bloat.
Example JSON and Example Visualization
// End Edit
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你的问题很难回答,因为你的数据结构主要是未知的。
对于图形表示,如果我理解正确的话,您只需要提供简单的关系:
您的数据结构具有不同的格式,我具体不知道,但它类似于:
无论您的数据表示哪种,将您的数据映射或转置到图形表示所需的结构,您需要一些函数来处理它。
为此,您需要在两个键和特定键之间共享分类/类型,以便您可以从事件中查找所需的数据以返回数据。例如:
Your question is hard to answer in the sense that your data-structure is mainly unknown.
For the graphical represenation you only need to provide simple relationships if I understand that correctly:
Your data structure has a different format, I don't know specifically but it's something like:
Whichever your data is represented, to map or transpose your data onto the required structure for the graphical representation, you need some functions that take care of that.
To do that you need to share classification/type between both and specific keys, so that you can look-up the needed data from the event to return the data. For example:
您的多对多数据模型是一个图表。 JIT 是为树而设计的。
换句话说,每当一个人连接到多个组织时,JIT 将无法正确显示数据中表示的交叉线。
我推荐一个合适的网络图可视化 - D3.js 有一个很好的实现对于现代浏览器。
它使用的 JSON 数据格式实际上更容易实现给定的表结构 - 对于所有组织和人员,您可以定义对象:
并且对于关联表中的每个关联,您可以定义将它们连接在一起的连接对象:
D3 中的奇特编码需要照顾其余的。祝你好运!
What you have with your many-to-many data model is a graph. JIT is designed for trees.
To put it another way, JIT will not correctly show the crossing lines that are represented in the data whenever a single person is connected to multiple organizations.
I'd recommend a proper network graph visualization - D3.js has a great implementation for modern browsers.
The JSON data format it uses is actually easier to implement given your table structure - for all the organizations and people, you define objects:
And for each association in your association table you define connection objects that wire them together:
The fancy coding in D3 takes care of the rest. Good luck!
您可以使用下面的函数:
使用以下方式调用它:
You can use function below:
Call it using: