通过相关实体正确递归

发布于 2024-12-11 02:09:08 字数 2983 浏览 0 评论 0原文

我有一组组织及其董事会成员。 所有组织都有董事会成员,并且许多董事会成员同时担任多个组织的董事会成员。

我使用 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 仍然可以正常工作。

示例 JSON可视化示例 // 结束编辑

schema

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

schema

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

雨后咖啡店 2024-12-18 02:09:08

你的问题很难回答,因为你的数据结构主要是未知的。

对于图形表示,如果我理解正确的话,您只需要提供简单的关系:

*- Parent
   +- Child
   +- Child
   ...
   `- Child

您的数据结构具有不同的格式,我具体不知道,但它类似于:

Org <-- 1:n --> Board

Board <-- n:n --> Board # If you have sub-boards

Board <-- n:n --> Member

无论您的数据表示哪种,将您的数据映射或转置到图形表示所需的结构,您需要一些函数来处理它。

为此,您需要在两个键和特定键之间共享分类/类型,以便您可以从事件中查找所需的数据以返回数据。例如:

if (request_parent_is_org())
{
    $id = request_parent_id();
    $parent = data_get_board($id);
    $parent->addChildrent(data_get_board_children($id));
}
else
{
    ... # All the other decisions you need to take based on request type
}

view_response_to_json($parent);

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:

*- Parent
   +- Child
   +- Child
   ...
   `- Child

Your data structure has a different format, I don't know specifically but it's something like:

Org <-- 1:n --> Board

Board <-- n:n --> Board # If you have sub-boards

Board <-- n:n --> Member

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:

if (request_parent_is_org())
{
    $id = request_parent_id();
    $parent = data_get_board($id);
    $parent->addChildrent(data_get_board_children($id));
}
else
{
    ... # All the other decisions you need to take based on request type
}

view_response_to_json($parent);
你的背包 2024-12-18 02:09:08

您的多对多数据模型是一个图表。 JIT 是为而设计的。

换句话说,每当一个人连接到多个组织时,JIT 将无法正确显示数据中表示的交叉线。

我推荐一个合适的网络图可视化 - D3.js 有一个很好的实现对于现代浏览器。

它使用的 JSON 数据格式实际上更容易实现给定的表结构 - 对于所有组织和人员,您可以定义对象:

{
    "name": "Mme.Hucheloup",
    "group": 1
},
{
    "name": "Afton School Board",
    "group": 2
}

并且对于关联表中的每个关联,您可以定义将它们连接在一起的连接对象:

{
    "source": 1,
    "target": 2
},

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:

{
    "name": "Mme.Hucheloup",
    "group": 1
},
{
    "name": "Afton School Board",
    "group": 2
}

And for each association in your association table you define connection objects that wire them together:

{
    "source": 1,
    "target": 2
},

The fancy coding in D3 takes care of the rest. Good luck!

此岸叶落 2024-12-18 02:09:08

您可以使用下面的函数:

function get_orgs_and_childs ($child_id, $found = array()) 
{
    array_push ($found, $child['name']);

    if($child['children'])){
            $found[] = get_parents($child['id'], $found);
    }
    return $found;
}

使用以下方式调用它:

$orgs = get_orgs_and_childs($child['id']);

You can use function below:

function get_orgs_and_childs ($child_id, $found = array()) 
{
    array_push ($found, $child['name']);

    if($child['children'])){
            $found[] = get_parents($child['id'], $found);
    }
    return $found;
}

Call it using:

$orgs = get_orgs_and_childs($child['id']);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文