javascript - Sankey 图,在 PHP 中使用查询创建多维数组

标签 javascript php mysql d3.js multidimensional-array

我想为 d3.sankey 创建一个多维数组。

但我不明白如何构建多维数组。

我需要的是:

d3.Sankey 需要如下输入:

{
"nodes":[
{"node":0,"name":"node0"},
{"node":1,"name":"node1"},
{"node":2,"name":"node2"},
{"node":3,"name":"node3"},
{"node":4,"name":"node4"}
],
"links":[
{"source":0,"target":2,"value":2},
{"source":1,"target":2,"value":2},
{"source":1,"target":3,"value":2},
{"source":0,"target":4,"value":2},
{"source":2,"target":3,"value":2},
{"source":2,"target":4,"value":2},
{"source":3,"target":4,"value":4}
]}

实际上我是用字符串构建那个东西的。这听起来真的很复杂,确实如此。犯了一个错误,它就不再起作用了。

所以我的问题是如何用数组构建该表单。

首先,我调用数据库来为我提供来自输入表的所有条目。 看起来像:(是的,我来自德国,所以该查询中的某些单词是德语单词;))

$stmt = self::$_db->prepare("SELECT BalancesheetInput.RessourceName, "
            . "SUM(BalancesheetInput.Amount) AS Amount, "
            . "Einheiten.Einheit AS Unit "
            . "FROM BalancesheetInput "
            . "INNER JOIN Einheiten ON Unit_FK = Unit_ID "
            . "GROUP BY BalancesheetInput.RessourceName");
        $stmt->execute();

        $fetcharray = $stmt->fetchALL(PDO::FETCH_ASSOC);

“输入”查询获取节点和链接的条目,这些节点和链接应该引用位于桑基图中间的一个节点(为了更好地理解,我添加了一张图片)

下一步我需要输出表中的所有条目

 $stmtOutput = self::$_db->prepare("SELECT BalancesheetOutput.RessourceName, "
            ."SUM(BalancesheetOutput.Amount) AS AmountOutput, "
            ."Einheiten.Einheit AS UnitOutput "
            ."FROM BalancesheetOutput "
            ."INNER JOIN Einheiten ON Unit_FK = Unit_ID "
            ."GROUP BY BalancesheetOutput.RessourceName");
        $stmtOutput->execute();
        $fetcharrayOutput = $stmtOutput->fetchAll(PDO::FETCH_ASSOC);

所有这些条目都来自中间的节点,因此它本身(希望您理解我的意思)

我在 atm 上所做的是获取输入和输出查询,并通过创建一个很长的字符串将它们放在一起。

$counter = 0;
    $ziel = count($fetcharray);
    $array_values = count($fetcharray);

    $counterafterInput = 0;

    $jsonNodes ='{"nodes":[';
    $jsonLinkes = '],"links":[';
    foreach ($fetcharray as $getnodes){

        if (($array_values-1) == $counter) {
           // saves node to string,
            //// wenn letzer Datenbankeintrag erreicht ist addet Schöneweide als Node
            $jsonNodes .= '{"node":'. $counter. ',"name":"' . $getnodes['RessourceName'] . '","units":"'.$getnodes['Unit'].'"},';
            $jsonNodes .= '{"node":'. ($counter+1). ',"name":"Schöneweide","units":"Blackbox"},';
           // $jsonNodes .= '{"node":'. ($counter+2). ',"name":"weiter","units":"'.$getnodes['Unit'].'"},'; //irgendwann obsolete

            // saves node to string, wenn letzer Datenbankeintrag erreicht ist
            $jsonLinkes .= '{"source":'.$counter .',"target":' .$ziel .  ',"value":' . $getnodes['Amount'] . ',"units":"'.$getnodes['Unit'].'"},';
           // $jsonLinkes .= '{"source":'.($counter+1) .',"target":' .($ziel+1) .  ',"value":' . $getnodes['Amount'] . ',"units":"'.$getnodes['Unit'].'"}';

            $counter++;
            $counterafterInput = $counter;
            $counter++;

        }
        else{
        //saves nodes to string while counter != Anzahl der Datenbankeinträge
        //If else weil durch Komma getrennte Schreibeweise die nodes und Links eingetragen werden .... geht in die if ,wenn der vorletzte eintrag erreicht wird um
        //die letze Node anzuhängen. Die letzte Node ist die Blackbox Schöneweide(oder später auch ein anderes Gebiet

            $jsonNodes .= '{"node":'. $counter. ',"name":"' . $getnodes['RessourceName'] . '","units":"'.$getnodes['Unit'].'"},';
            $jsonLinkes .= '{"source":'.$counter .',"target":' .$ziel .  ',"value":' . $getnodes['Amount'] . ',"units":"'.$getnodes['Unit'].'"},';


        $counter++;
    }
    }

    $counterOutput = 0;

    $array_values_output = count($fetcharrayOutput);
    $jsnonnodesOutput = "";
    $jsonLinkesOutput = "";


    foreach ($fetcharrayOutput as $getnodesOutput)
    {
        if (($array_values_output-1) == $counterOutput){

        $jsnonnodesOutput .= '{"node":'.$counter.',"name":"'.$getnodesOutput['RessourceName'].'","units":"'.$getnodesOutput['UnitOutput'].'"}';
        $jsonLinkesOutput .= '{"source":'.$counterafterInput.',"target":'.$counter.',"value":'.$getnodesOutput['AmountOutput'].',"units":"'.$getnodesOutput['UnitOutput'].'"}]}';
        }
        else
        {
            $jsnonnodesOutput .= '{"node":'.$counter.',"name":"'.$getnodesOutput['RessourceName'].'","units":"'.$getnodesOutput['UnitOutput'].'"},';
            $jsonLinkesOutput .= '{"source":'.$counterafterInput.',"target":'.$counter.',"value":'.$getnodesOutput['AmountOutput'].',"units":"'.$getnodesOutput['UnitOutput'].'"},';
            $counterOutput++;
            $counter++;
        }


    }

    $JSONstring = $jsonNodes. $jsnonnodesOutput . $jsonLinkes .$jsonLinkesOutput;


   return $JSONstring;

所以让我解释一下我在做什么:

第一步我设置了一个计数器。 接下来,我计算查询中的所有条目以将节点设置在中间。 例如我有 5 个条目,所以我需要将中间的节点设置为 6。 下一步是初始化

`$jsonNodes ='{"nodes":[';`

下一步我运行 foreach 循环来填充字符串中的所有条目,我需要得到类似的东西

{"node":0,"name":"node0"},

我的代码是

 $jsonNodes .= '{"node":'. $counter. ',"name":"' . $getnodes['RessourceName'] . '","units":"'.$getnodes['Unit'].'"},';

计数器计算每个条目的 ID

而且我还必须设置链接。所以节点指的是中间的Node

 $jsonLinkes .= '{"source":'.$counter .',"target":' .$ziel .  ',"value":' . $getnodes['Amount'] . ',"units":"'.$getnodes['Unit'].'"},';

因此,源与节点中的 ID 相同,目标是中间数量的节点,单位是不言自明的。

简而言之,我做同样的事情来获取输出,只是源是中间的节点,目标是它本身的每个节点

实际上它是有效的,但我认为有一个更好的数组解决方案。

所以现在我需要帮助来创建一个数组,我可以将其保存为 JavaScript 变量。

如果有人知道这是如何工作的并告诉我。那太棒了!

最佳答案

更好的数组解决方案是构建一个具有所需结构的数组,然后通过 json_encode() 运行它:

$nodes = array();
$nodes[] = array('node' => 0, 'name' => 'node0');
$nodes[] = array('node' => 1, 'name' => 'node1');
$nodes[] = array('node' => 2, 'name' => 'node2');

$links = array();
$links[] = array('source' => 0, 'target' => 2, 'value' => 2);
$links[] = array('source' => 0, 'target' => 1, 'value' => 2);

echo json_encode(array('nodes' => $nodes, 'links' => $links));
// {"nodes":[{"node":0,"name":"node0"},{"node":1,"name":"node1"},{"node":2,"name":"node2"}],"links":[{"source":0,"target":2,"value":2},{"source":0,"target":1,"value":2}]}

关于javascript - Sankey 图,在 PHP 中使用查询创建多维数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39310528/

相关文章:

php - 优化子串字谜比较算法

python - 传递cursor.execute mysql 查询中的元素列表

php - Foreach 循环不会将 Quickbooks 中的所有记录插入 MySQL 数据库。

php - ajax获取下拉依赖值

php - 从 txt 文件中的字符串中删除行

php - 在数千个 MYSQL 查询中插入几行的最快方法

javascript - 谷歌地理编码,异步Javascript,不起作用

javascript - 如何使用javascript事件从angularjs指令范围传回值

prototypal-inheritance - 这个 Animal = function Animal 是做什么的?

javascript - App.js 中的组件未以 React-Native 方式呈现。请纠正我。