我想为 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/