<?php | <?php |
include_once('include/common.inc.php'); | include_once('include/common.inc.php'); |
include_header(); | include_header('About'); |
?> | ?> |
<div class="foundation-header"> | <div class="foundation-header"> |
<h1><a href="about.php">About/FAQ</a></h1> | <h1><a href="about.php">About/FAQ</a></h1> |
<h4 class="subheader">Lorem ipsum.</h4> | <h4 class="subheader">Lorem ipsum.</h4> |
</div> | </div> |
<h2> What is this? </h2> | <h2> What is this? </h2> |
Disclosr is a project to monitor Australian Federal Government agencies | Disclo.gs is a project to monitor Australian Federal Government agencies |
compliance with their <a href="http://www.oaic.gov.au/publications/other_operational/foi_policy_frequently_asked_questions.html#_Toc291837571">"proactive disclosure requirements"</a>. | compliance with their <a href="http://www.oaic.gov.au/publications/other_operational/foi_policy_frequently_asked_questions.html#_Toc291837571">"proactive disclosure requirements"</a>. |
OGRE (Open Government Realization Evaluation) is a ranking of compliance with these requirements. | <h2> Attributions </h2> |
Prometheus is the agent which polls agency websites to assess compliance. | National Archives of Australia, Australian Governments’ Interactive Functions Thesaurus, 2nd edition, September 2005, published at http://www.naa.gov.au/recordkeeping/thesaurus/index.htm. |
<h2> Open everything </h2> | <h2> Open everything </h2> |
All documents released CC-BY 3 AU | All documents released CC-BY 3 AU |
Open source git @ | Open source git @ |
<h2>Organisational Data Sources</h2> | <h2>Organisational Data Sources</h2> |
http://www.comlaw.gov.au/Browse/Results/ByTitle/AdministrativeArrangementsOrders/Current/Ad/0 defines departments | http://www.comlaw.gov.au/Browse/Results/ByTitle/AdministrativeArrangementsOrders/Current/Ad/0 defines departments |
Agencies can be found in the Schedule to an Appropriation Bill (budget), Schedule to FMA Regulations and/or Public Service Act.<br> | Agencies can be found in the Schedule to an Appropriation Bill (budget), Schedule to FMA Regulations and/or Public Service Act.<br> |
http://www.finance.gov.au/publications/flipchart/docs/FMACACFlipchart.pdf summarises these. view-source:https://www.tenders.gov.au/?event=public.advancedsearch.home is great for the suspended/active status<br> | http://www.finance.gov.au/publications/flipchart/docs/FMACACFlipchart.pdf summarises these. view-source:https://www.tenders.gov.au/?event=public.advancedsearch.home is great for the suspended/active status<br> |
Fraud in gov depts by Fairfax Media http://www.smh.com.au/national/public-service-keeps-fraud-cases-private-20110923-1kpdr.html | Fraud in gov depts by Fairfax Media http://www.smh.com.au/national/public-service-keeps-fraud-cases-private-20110923-1kpdr.html |
When defining the hierachy, this system is designed towards monitoring accountablity. Thus large agencies that have registered their own ABN | When defining the hierachy, this system is designed towards monitoring accountablity. Thus large agencies that have registered their own ABN |
and have their own accountablity mechanisms/website receive a seperate record as a child of their department. | and have their own accountablity mechanisms/website receive a seperate record as a child of their department. |
Some small agencies will choose to simply rely on their parent department's accountablity measures.<br> | Some small agencies will choose to simply rely on their parent department's accountablity measures.<br> |
This flows through to organisation name and other/past names. A department that completely accounts for an agency will list that agency as an other child name. | This flows through to organisation name and other/past names. A department that completely accounts for an agency will list that agency as an other child name. |
As agencies themselves shift between departments, there may be scope for providing time ranges but typically the newest hierarchy will be the one recorded. | As agencies themselves shift between departments, there may be scope for providing time ranges but typically the newest hierarchy will be the one recorded. |
A department/agency name will be the newest active name assigned to that ABN.<br> | A department/agency name will be the newest active name assigned to that ABN.<br> |
ABN information is derived from the ABR. This is the definitive umpire about which former name should be linked to which current name. | ABN information is derived from the ABR. This is the definitive umpire about which former name should be linked to which current name. |
For example "Department of Transport and Regional Services" became "Department of Infrastructure, Transport, Regional Development and Local Government" (same ABN) | For example "Department of Transport and Regional Services" became "Department of Infrastructure, Transport, Regional Development and Local Government" (same ABN) |
however it later split into "Department of Infrastructure and Transport" (same ABN) | however it later split into "Department of Infrastructure and Transport" (same ABN) |
and "Department of Regional Australia, Regional Development and Local Government" (new ABN).<br> | and "Department of Regional Australia, Regional Development and Local Government" (new ABN).<br> |
Statistical information from http://www.apsc.gov.au/stateoftheservice/1011/statsbulletin/section1.html#t2total https://www.apsedii.gov.au/apsedii/CustomQueryx33.shtml | Statistical information from http://www.apsc.gov.au/stateoftheservice/1011/statsbulletin/section1.html#t2total https://www.apsedii.gov.au/apsedii/CustomQueryx33.shtml |
and individual annual reports.<br> | and individual annual reports.<br> |
<h2>Webpage Assessment</h2> | <h2>Webpage Assessment</h2> |
Much due care has been put into correctly recording disclosure URLs. Typically the "About", "Corporate", "Publications" and "Sitemap" sections are checked at the very least. | Much due care has been put into correctly recording disclosure URLs. Typically the "About", "Corporate", "Publications" and "Sitemap" sections are checked at the very least. |
Occasionally it is nessicary to use a site or Google search. In several rare cases, there is a secret "Disclosure" navigation menu you can find if you find one of the mandatory publishing obligations in that category (seriously).<br> | Occasionally it is nessicary to use a site or Google search. In several rare cases, there is a secret "Disclosure" navigation menu you can find if you find one of the mandatory publishing obligations in that category (seriously).<br> |
Some rules about leniency:<br> | Some rules about leniency:<br> |
<ul> | <ul> |
<li>An empty FOI disclosure log counts, a page outlining what the FOI Act is does not.</li> | <li>An empty FOI disclosure log counts, a page outlining what the FOI Act is does not.</li> |
<li>A disclosure log in PDF or Word format counts :(</li> | <li>A disclosure log in PDF or Word format counts :(</li> |
<li>An empty File/Record list counts (although that's very minimalistic that you have no files, electronic or paper)</li> | <li>An empty File/Record list counts (although that's very minimalistic that you have no files, electronic or paper)</li> |
<li>Only a current information publication scheme page counts, not a s.9 FOI Act page or an organisation chart.</li> | <li>Only a current information publication scheme page counts, not a s.9 FOI Act page or an organisation chart.</li> |
<li>If there isn't a page easily listing all current and past Annual Reports, the most current one (html, pdf) counts.</li> | <li>If there isn't a page easily listing all current and past Annual Reports, the most current one (html, pdf) counts.</li> |
<li>Consultancy contracts might not need it's own webpage (if in Annual Report), grants/appointments might not apply to all organisations but Legal Services Expenditure (and all other obligations) does need a webpage. </li> | <li>Consultancy contracts might not need it's own webpage (if in Annual Report), grants/appointments might not apply to all organisations but Legal Services Expenditure (and all other obligations) does need a webpage. </li> |
<h2>Open Government Scoring</h2> | <h2>Open Government Scoring</h2> |
+1 point for every true Has... attribute<br> | +1 point for every true Has... attribute<br> |
-1 point for every false Has... (ie. Has Not) attribute</br> | -1 point for every false Has... (ie. Has Not) attribute</br> |
Don't like this? Make your own score, suggest a better scoring mechanism.</br> | Don't like this? Make your own score, suggest a better scoring mechanism.</br> |
<?php | <?php |
include_footer(); | include_footer(); |
?> | ?> |
<?php | |
include_once('../include/common.inc.php'); | |
include_header(); | |
require_once '../lib/php-diff/lib/Diff.php'; | |
require_once '../lib/php-diff/lib/Diff/Renderer/Html/SideBySide.php'; | |
$db = $server->get_db('disclosr-agencies'); | |
try { | |
$rows = $db->get_view("app", "getConflicts", null, true)->rows; | |
//print_r($rows); | |
foreach ($rows as $row) { | |
echo "<h2>".$row->id."</h2>"; | |
$request = Requests::get($serverAddr."disclosr-agencies/".$row->id); | |
$origSort = object_to_array(json_decode($request->body)); | |
ksort($origSort); | |
$origDoc = explode(",",json_encode($origSort)); | |
foreach($row->value as $conflictRev) { | |
$conflictURL = $serverAddr."disclosr-agencies/".$row->id."?rev=".$conflictRev; | |
$request = Requests::get($conflictURL); | |
$conflictSort = object_to_array(json_decode($request->body)); | |
ksort($conflictSort); | |
$conflictDoc = explode(",",json_encode($conflictSort)); | |
echo "curl -X DELETE ".$conflictURL."<br>".PHP_EOL; | |
// Options for generating the diff | |
$options = array( | |
//'ignoreWhitespace' => true, | |
//'ignoreCase' => true, | |
); | |
// Initialize the diff class | |
$diff = new Diff($conflictDoc, $origDoc, $options); | |
// Generate a side by side diff | |
$renderer = new Diff_Renderer_Html_SideBySide; | |
echo $diff->Render($renderer); | |
} | |
die(); | |
} | |
} catch (SetteeRestClientException $e) { | |
setteErrorHandler($e); | |
} | |
include_footer(); | |
?> | |
<?php | |
$nodes = Array(Array("id" => "gov", "label" => "Federal Government")); | |
$edges = Array(); | |
function addEdge($source, $target) { | |
global $edges; | |
$edges[] = Array("id" => md5($source . $target), "source" => $source, "target" => $target); | |
} | |
function addNode($id, $label, $pid) { | |
global $nodes; | |
$nodes[] = Array("id" => $id, "label" => $label , "pid" => $pid); | |
} | |
function addChildren($parentID, $parentXML) { | |
foreach ($parentXML as $childXML) { | |
if ($childXML->getName() == "organization" || $childXML->getName() == "organizationalUnit" || $childXML->getName() == "person") { | |
$attr = $childXML->attributes(); | |
$id = $attr['UUID']; | |
if ($childXML->getName() == "organization" || $childXML->getName() == "organizationalUnit") { | |
$label = $childXML->name; | |
} else if ($childXML->getName() == "person") { | |
$label = $childXML->fullName; | |
} | |
addNode($id, $label, $parentID); | |
addEdge($id, $parentID); | |
addChildren($id, $childXML); | |
} | |
} | |
} | |
if (file_exists('directoryexport.xml')) { | |
$xml = simplexml_load_file('directoryexport.xml'); | |
addChildren("gov", $xml); | |
} else { | |
exit('Failed to open directoryexport.xml'); | |
} | |
header('Content-Type: application/gexf+xml'); | |
echo '<?xml version="1.0" encoding="UTF-8"?> | |
<gexf xmlns="http://www.gexf.net/1.2draft" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.gexf.net/1.2draft http://www.gexf.net/1.2draft/gexf.xsd" version="1.2"> | |
<graph mode="static" defaultedgetype="directed"> | |
<nodes>'; | |
foreach ($nodes as $node) { | |
echo ' <node id="' . $node['id'] . '" label="' . htmlentities($node['label'],ENT_XML1) . '" ' . (isset($node['pid']) ? 'pid="' . $node['pid'] . '"' : "") . ' />'; | |
} | |
echo '</nodes> | |
<edges>'; | |
foreach ($edges as $edge) { | |
echo ' <edge id="' . $edge['id'] . '" source="' . $edge['source'] . '" target="' . $edge['target'] . '" />'; | |
} | |
echo '</edges> | |
</graph> | |
</gexf>'; | |
?> | |
<?php | <?php |
include_once("../include/common.inc.php"); | include_once("../include/common.inc.php"); |
$format = "csv"; | $format = "csv"; |
//$format = "json"; | //$format = "json"; |
if (isset($_REQUEST['format'])) $format = $_REQUEST['format']; | if (isset($_REQUEST['format'])) $format = $_REQUEST['format']; |
setlocale(LC_CTYPE, 'C'); | setlocale(LC_CTYPE, 'C'); |
if ($format == "csv") { | if ($format == "csv") { |
$headers = Array("name"); | $headers = Array("name"); |
} else { | } else { |
$headers = Array(); | $headers = Array(); |
} | } |
$db = $server->get_db('disclosr-agencies'); | $db = $server->get_db('disclosr-agencies'); |
try { | try { |
$rows = $db->get_view("app", "all", null, true)->rows; | $rows = $db->get_view("app", "all", null, true)->rows; |
$dataValues = Array(); | $dataValues = Array(); |
foreach ($rows as $row) { | foreach ($rows as $row) { |
if (isset($row->value->statistics->employees)) { | if (isset($row->value->statistics->employees)) { |
$headers = array_unique(array_merge($headers, array_keys(object_to_array($row->value->statistics->employees)))); | $headers = array_unique(array_merge($headers, array_keys(object_to_array($row->value->statistics->employees)))); |
} | } |
} | } |
} catch (SetteeRestClientException $e) { | } catch (SetteeRestClientException $e) { |
setteErrorHandler($e); | setteErrorHandler($e); |
} | } |
$fp = fopen('php://output', 'w'); | $fp = fopen('php://output', 'w'); |
if ($fp && $db) { | if ($fp && $db) { |
if ($format == "csv") { | if ($format == "csv") { |
header('Content-Type: text/csv; charset=utf-8'); | header('Content-Type: text/csv; charset=utf-8'); |
header('Content-Disposition: attachment; filename="export.employeestats.' . date("c") . '.csv"'); | header('Content-Disposition: attachment; filename="export.employeestats.' . date("c") . '.csv"'); |
} | } |
header('Pragma: no-cache'); | header('Pragma: no-cache'); |
header('Expires: 0'); | header('Expires: 0'); |
if ($format == "csv") { | if ($format == "csv") { |
fputcsv($fp, $headers); | fputcsv($fp, $headers); |
} else if ($format == "json") { | } else if ($format == "json") { |
echo '{ | echo '{ |
"labels" : ["' . implode('","', $headers) . '"],'.PHP_EOL; | "labels" : ["' . implode('","', $headers) . '"],'.PHP_EOL; |
} | } |
try { | try { |
$agencies = $db->get_view("app", "all", null, true)->rows; | $agencies = $db->get_view("app", "all", null, true)->rows; |
//print_r($agencies); | //print_r($agencies); |
$first = true; | $first = true; |
if ($format == "json") { | if ($format == "json") { |
echo '"data" : ['.PHP_EOL; | echo '"data" : ['.PHP_EOL; |
} | } |
foreach ($agencies as $agency) { | foreach ($agencies as $agency) { |
if (isset($agency->value->statistics->employees)) { | if (isset($agency->value->statistics->employees)) { |
$row = Array(); | $row = Array(); |
$agencyEmployeesArray = object_to_array($agency->value->statistics->employees); | $agencyEmployeesArray = object_to_array($agency->value->statistics->employees); |
foreach ($headers as $i => $fieldName) { | foreach ($headers as $i => $fieldName) { |
if (isset($agencyEmployeesArray[$fieldName])) { | if (isset($agencyEmployeesArray[$fieldName])) { |
$row[] = '['.$i.','.$agencyEmployeesArray[$fieldName]["value"].']'; | $row[] = '['.$i.','.$agencyEmployeesArray[$fieldName]["value"].']'; |
} else { | } else { |
$row[] = '['.$i.',0]'; | $row[] = '['.$i.',0]'; |
} | } |
} | } |
if ($format == "csv") { | if ($format == "csv") { |
fputcsv($fp, array_values($row)); | fputcsv($fp, array_values($row)); |
} else if ($format == "json") { | } else if ($format == "json") { |
if (!$first) echo ","; | if (!$first) echo ","; |
echo '{"data" : [' . implode(",", array_values($row)) . '], "label": "'.$agency->value->name.'", "lines" : { "show" : true }, "points" : { "show" : true }}'.PHP_EOL; | echo '{"data" : [' . implode(",", array_values($row)) . '], "label": "'.$agency->value->name.'", "lines" : { "show" : true }, "points" : { "show" : true }}'.PHP_EOL; |
$first = false; | $first = false; |
} | } |
} | } |
} | } |
if ($format == "json") { | if ($format == "json") { |
echo '] | echo '] |
}'.PHP_EOL; | }'.PHP_EOL; |
} | } |
} catch (SetteeRestClientException $e) { | } catch (SetteeRestClientException $e) { |
setteErrorHandler($e); | setteErrorHandler($e); |
} | } |
die; | die; |
} | } |
?> | ?> |
<?php | <?php |
require_once '../include/common.inc.php'; | require_once '../include/common.inc.php'; |
$db = $server->get_db('disclosr-agencies'); | $db = $server->get_db('disclosr-agencies'); |
$rows = $db->get_view("app", "byName")->rows; | $rows = $db->get_view("app", "byName")->rows; |
$nametoid = Array(); | $nametoid = Array(); |
$sums = Array(); | $sums = Array(); |
foreach ($rows as $row) { | foreach ($rows as $row) { |
$nametoid[trim($row->key)] = $row->value; | $nametoid[trim($row->key)] = $row->value; |
} | } |
$employeeCSVs = Array("2002-2003" => "0203apsemployees.csv", | $employeeCSVs = Array("2002-2003" => "0203apsemployees.csv", |
"2003-2004" => "0304apsemployees.csv", | "2003-2004" => "0304apsemployees.csv", |
"2004-2005" => "0405apsemployees.csv", | "2004-2005" => "0405apsemployees.csv", |
"2005-2006" => "0506apsemployees.csv", | "2005-2006" => "0506apsemployees.csv", |
"2006-2007" => "0607apsemployees.csv", | "2006-2007" => "0607apsemployees.csv", |
"2007-2008" => "0708apsemployees.csv", | "2007-2008" => "0708apsemployees.csv", |
"2008-2009" => "0809apsemployees.csv", | "2008-2009" => "0809apsemployees.csv", |
"2009-2010" => "0910apsemployees.csv", | "2009-2010" => "0910apsemployees.csv", |
"2010-2011" => "1011apsemployees.csv" | "2010-2011" => "1011apsemployees.csv" |
); | ); |
foreach ($employeeCSVs as $timePeriod => $employeeCSV) { | foreach ($employeeCSVs as $timePeriod => $employeeCSV) { |
echo $employeeCSV . "<br>" . PHP_EOL; | echo $employeeCSV . "<br>" . PHP_EOL; |
$row = 1; | $row = 1; |
if (($handle = fopen($employeeCSV, "r")) !== FALSE) { | if (($handle = fopen($employeeCSV, "r")) !== FALSE) { |
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { | while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { |
//print_r($data); | //print_r($data); |
$name = trim($data[0]); | $name = trim($data[0]); |
if (isset($nametoid[$name])) { | if (isset($nametoid[$name])) { |
$id = $nametoid[$name]; | $id = $nametoid[$name]; |
//echo $id . "<br>" . PHP_EOL; | //echo $id . "<br>" . PHP_EOL; |
@$sums[$id][$timePeriod] += $data[1]; | @$sums[$id][$timePeriod] += $data[1]; |
} else { | } else { |
echo "<br>ERROR NAME MISSING FROM ID LIST<br><bR>" . PHP_EOL; | echo "<br>ERROR NAME MISSING FROM ID LIST<br><bR>" . PHP_EOL; |
die(); | die(); |
} | } |
} | } |
fclose($handle); | fclose($handle); |
} | } |
} | } |
foreach ($sums as $id => $sum) { | foreach ($sums as $id => $sum) { |
echo $id. "<br>" . PHP_EOL; | echo $id . "<br>" . PHP_EOL; |
$doc = $db->get($id); | $doc = $db->get($id); |
// print_r($doc); | echo $doc->name . "<br>" . PHP_EOL; |
if (isset($doc->statistics)) $doc->statistics = Array(); | // print_r($doc); |
$changed = false; | |
if (!isset($doc->statistics)) { | |
$changed = true; | |
$doc->statistics = Array(); | |
} | |
foreach ($sum as $timePeriod => $value) { | foreach ($sum as $timePeriod => $value) { |
$doc->statistics["employees"][$timePeriod] = Array("value"=>$value, "source"=>"http://apsc.gov.au/stateoftheservice/"); | if (!isset($doc->statistics->employees->$timePeriod->value) |
|| $doc->statistics->employees->$timePeriod->value != $value) { | |
$changed = true; | |
$doc->statistics["employees"][$timePeriod] = Array("value" => $value, "source" => "http://apsc.gov.au/stateoftheservice/"); | |
} | |
} | } |
$db->save($doc); | if ($changed) { |
$db->save($doc); | |
} else { | |
echo "not changed" . "<br>" . PHP_EOL; | |
} | |
} | } |
// employees: timeperiod, source = apsc state of service, value | // employees: timeperiod, source = apsc state of service, value |
?> | ?> |
#http://packages.python.org/CouchDB/client.html | |
import couchdb | |
from BeautifulSoup import BeautifulSoup | |
couch = couchdb.Server('http://127.0.0.1:5984/') | |
# select database | |
docsdb = couch['disclosr-documents'] | |
for row in docsdb.view('app/getMetadataExtractRequired'): | |
print row.id | |
html = docsdb.get_attachment(row.id,row.value.iterkeys().next()).read() | |
metadata = [] | |
# http://www.crummy.com/software/BeautifulSoup/documentation.html | |
soup = BeautifulSoup(html) | |
metatags = soup.meta | |
for metatag in metatags: | |
print metatag['name'] | |
doc = docsdb.get(row.id) | |
//doc['metadata'] = metadata | |
//docsdb.save(doc) | |
Binary files /dev/null and b/admin/naa-agift.7z differ
[ | |
"Home", | |
"index.htm", | |
[ | |
"BUSINESS SUPPORT AND REGULATION", | |
"000411.htm", | |
[ | |
"Association registration", | |
"000396.htm" | |
], | |
[ | |
"Business process auditing", | |
"000413.htm" | |
], | |
[ | |
"Business registration and licensing", | |
"000414.htm" | |
], | |
[ | |
"Business sponsorship", | |
"001371.htm" | |
], | |
[ | |
"Consumer protection", | |
"000439.htm" | |
], | |
[ | |
"Fair trading compliance", | |
"000482.htm", | |
[ | |
"Prices surveillance", | |
"000533.htm" | |
], | |
[ | |
"Product safety", | |
"000534.htm" | |
], | |
[ | |
"Trade practices compliance", | |
"000583.htm" | |
] | |
], | |
[ | |
"Financial institutions regulation", | |
"000485.htm" | |
], | |
[ | |
"Government procurement regulation", | |
"000491.htm" | |
], | |
[ | |
"Industry assistance schemes", | |
"000499.htm" | |
], | |
[ | |
"Industry development", | |
"000500.htm" | |
], | |
[ | |
"Insurance regulation", | |
"000501.htm", | |
[ | |
"General insurance", | |
"000489.htm" | |
], | |
[ | |
"Life insurance", | |
"000505.htm" | |
] | |
], | |
[ | |
"Professional accreditation", | |
"000535.htm" | |
], | |
[ | |
"Small business services", | |
"000565.htm", | |
[ | |
"Small business advocacy", | |
"000563.htm" | |
], | |
[ | |
"Small business development", | |
"000564.htm" | |
] | |
], | |
[ | |
"Stock market regulation", | |
"000572.htm" | |
] | |
], | |
[ | |
"CIVIC INFRASTRUCTURE", | |
"000424.htm", | |
[ | |
"Civic management", | |
"000425.htm", | |
[ | |
"Architectural services", | |
"000387.htm" | |
], | |
[ | |
"Building approval services", | |
"000406.htm" | |
], | |
[ | |
"Building regulations and standards", | |
"000408.htm" | |
], | |
[ | |
"Engineering services", | |
"000477.htm" | |
], | |
[ | |
"Town planning", | |
"000582.htm" | |
] | |
], | |
[ | |
"Energy supply", | |
"000476.htm" | |
], | |
[ | |
"Integrated services planning", | |
"000503.htm" | |
], | |
[ | |
"Public housing", | |
"000536.htm", | |
[ | |
"Public housing construction", | |
"000537.htm" | |
], | |
[ | |
"Public housing design", | |
"000538.htm" | |
], | |
[ | |
"Public housing maintenance", | |
"000540.htm" | |
] | |
], | |
[ | |
"Public land management", | |
"000541.htm", | |
[ | |
"Burial ground management", | |
"000410.htm" | |
], | |
[ | |
"Cultural centre management", | |
"000444.htm" | |
], | |
[ | |
"Garden management", | |
"000488.htm" | |
], | |
[ | |
"Memorial maintenance", | |
"000509.htm" | |
], | |
[ | |
"Recreational park management", | |
"000549.htm" | |
], | |
[ | |
"Sporting facilities management", | |
"000571.htm" | |
] | |
], | |
[ | |
"Regional development", | |
"000552.htm" | |
], | |
[ | |
"Transport network maintenance", | |
"000586.htm" | |
], | |
[ | |
"Waste management", | |
"001349.htm" | |
] | |
], | |
[ | |
"COMMUNICATIONS", | |
"000433.htm", | |
[ | |
"Advertising standards", | |
"000381.htm" | |
], | |
[ | |
"Broadcasting", | |
"000403.htm", | |
[ | |
"Broadcasting standards", | |
"000404.htm" | |
], | |
[ | |
"Radio broadcasting", | |
"000546.htm" | |
], | |
[ | |
"Television broadcasting", | |
"000580.htm" | |
] | |
], | |
[ | |
"Call centre administration", | |
"000417.htm" | |
], | |
[ | |
"Electronic commerce", | |
"000468.htm", | |
[ | |
"Authentication", | |
"000399.htm" | |
], | |
[ | |
"Online transaction standards", | |
"000526.htm" | |
] | |
], | |
[ | |
"Government media", | |
"000490.htm" | |
], | |
[ | |
"Information management standards", | |
"000283.htm", | |
[ | |
"Data management", | |
"000448.htm" | |
], | |
[ | |
"Information dissemination", | |
"000502.htm" | |
], | |
[ | |
"Information technology standards", | |
"000282.htm" | |
] | |
], | |
[ | |
"Media ownership regulation", | |
"000508.htm" | |
], | |
[ | |
"Postal services", | |
"000530.htm", | |
[ | |
"Courier services", | |
"000441.htm" | |
], | |
[ | |
"Electronic postal services", | |
"000469.htm" | |
], | |
[ | |
"Retail postal services", | |
"000554.htm" | |
] | |
], | |
[ | |
"Publishing", | |
"000543.htm", | |
[ | |
"Electronic publishing", | |
"000470.htm" | |
], | |
[ | |
"Publishing standards", | |
"000544.htm" | |
], | |
[ | |
"Website development", | |
"000591.htm" | |
] | |
], | |
[ | |
"Radio communication", | |
"000547.htm", | |
[ | |
"Apparatus licensing", | |
"000385.htm" | |
], | |
[ | |
"Spectrum management", | |
"000570.htm" | |
] | |
], | |
[ | |
"Satellite communication", | |
"000560.htm" | |
], | |
[ | |
"Telecommunications", | |
"000578.htm", | |
[ | |
"Carriage service providers", | |
"000420.htm" | |
], | |
[ | |
"Carrier licensing", | |
"000421.htm" | |
], | |
[ | |
"Equipment licensing", | |
"000480.htm" | |
], | |
[ | |
"Mobile telephone services", | |
"000516.htm" | |
], | |
[ | |
"Telephone services", | |
"000579.htm" | |
] | |
] | |
], | |
[ | |
"COMMUNITY SERVICES", | |
"000435.htm", | |
[ | |
"Accommodation services", | |
"000377.htm", | |
[ | |
"Defence housing", | |
"000458.htm" | |
], | |
[ | |
"Emergency accommodation", | |
"000471.htm" | |
], | |
[ | |
"Public housing entitlements", | |
"000539.htm" | |
], | |
[ | |
"Refuge support", | |
"000551.htm" | |
] | |
], | |
[ | |
"Community support", | |
"000436.htm", | |
[ | |
"Adoption services", | |
"000378.htm" | |
], | |
[ | |
"Aged care services", | |
"000382.htm" | |
], | |
[ | |
"Child and youth support", | |
"000422.htm" | |
], | |
[ | |
"Child-care services", | |
"000423.htm" | |
], | |
[ | |
"Defence community programs", | |
"000452.htm" | |
], | |
[ | |
"Family reunion programs", | |
"000483.htm" | |
], | |
[ | |
"Veterans\" entitlements", | |
"000587.htm" | |
] | |
], | |
[ | |
"Counselling services", | |
"000440.htm" | |
], | |
[ | |
"Emergency services", | |
"000474.htm", | |
[ | |
"Ambulance services", | |
"000384.htm" | |
], | |
[ | |
"Emergency funding", | |
"000472.htm" | |
], | |
[ | |
"Firefighting services", | |
"000487.htm" | |
] | |
], | |
[ | |
"Financial assistance", | |
"000484.htm", | |
[ | |
"Benefits", | |
"000402.htm" | |
], | |
[ | |
"Income support schemes", | |
"000494.htm" | |
] | |
], | |
[ | |
"Natural disasters", | |
"000521.htm", | |
[ | |
"Disaster recovery", | |
"000462.htm" | |
], | |
[ | |
"Disaster relief", | |
"000463.htm" | |
] | |
], | |
[ | |
"Rural community development", | |
"000557.htm" | |
], | |
[ | |
"Social justice and equity", | |
"000566.htm" | |
], | |
[ | |
"Transport access schemes", | |
"000901.htm" | |
] | |
], | |
[ | |
"CULTURAL AFFAIRS", | |
"000442.htm", | |
[ | |
"Arts development", | |
"000391.htm", | |
[ | |
"Arts funding", | |
"000393.htm" | |
], | |
[ | |
"Arts incentive schemes", | |
"000394.htm" | |
], | |
[ | |
"Arts promotion", | |
"000395.htm" | |
] | |
], | |
[ | |
"Collection access", | |
"000427.htm", | |
[ | |
"Descriptive standards", | |
"000461.htm" | |
], | |
[ | |
"Finding aids development", | |
"000486.htm" | |
], | |
[ | |
"Reference services", | |
"000550.htm" | |
] | |
], | |
[ | |
"Collection management", | |
"000430.htm", | |
[ | |
"Artefact export regulation", | |
"000390.htm" | |
], | |
[ | |
"Collection accessioning", | |
"000428.htm" | |
], | |
[ | |
"Collection acquisition", | |
"000429.htm" | |
], | |
[ | |
"Collection storage", | |
"000432.htm" | |
], | |
[ | |
"Preservation services", | |
"000532.htm" | |
] | |
], | |
[ | |
"Collection promotion", | |
"000431.htm", | |
[ | |
"Exhibition programs", | |
"000481.htm" | |
], | |
[ | |
"Publicity programs", | |
"000542.htm" | |
] | |
], | |
[ | |
"Cultural awards and scholarships", | |
"000443.htm" | |
], | |
[ | |
"Cultural festivals", | |
"000445.htm" | |
], | |
[ | |
"Cultural gifts programs", | |
"000446.htm" | |
], | |
[ | |
"Multicultural heritage promotion", | |
"000518.htm", | |
[ | |
"Multicultural festivals", | |
"000517.htm" | |
], | |
[ | |
"Multicultural services", | |
"000519.htm" | |
] | |
] | |
], | |
[ | |
"DEFENCE", | |
"000449.htm", | |
[ | |
"Australian Defence Forces", | |
"000397.htm", | |
[ | |
"Air Force", | |
"002266.htm" | |
], | |
[ | |
"Army", | |
"000388.htm" | |
], | |
[ | |
"Badges and insignia", | |
"000401.htm" | |
], | |
[ | |
"Cadets", | |
"000416.htm" | |
], | |
[ | |
"Defence force commands", | |
"000456.htm" | |
], | |
[ | |
"Military bands", | |
"000510.htm" | |
], | |
[ | |
"Navy", | |
"000524.htm" | |
], | |
[ | |
"Reserves", | |
"000553.htm" | |
], | |
[ | |
"Roulettes", | |
"000556.htm" | |
] | |
], | |
[ | |
"Defence estate management", | |
"000454.htm" | |
], | |
[ | |
"Defence force careers", | |
"000455.htm", | |
[ | |
"Defence career development", | |
"000450.htm" | |
], | |
[ | |
"Military employment services", | |
"000512.htm" | |
] | |
], | |
[ | |
"Defence strategic development", | |
"000574.htm", | |
[ | |
"Defence efficiency review", | |
"000453.htm" | |
], | |
[ | |
"Defence reform program", | |
"000460.htm" | |
] | |
], | |
[ | |
"Defence strategic policy", | |
"000576.htm", | |
[ | |
"Strategic decisions", | |
"000573.htm" | |
], | |
[ | |
"Strategic planning", | |
"000575.htm" | |
] | |
], | |
[ | |
"Defence strategic support", | |
"000577.htm", | |
[ | |
"Capital equipment programs", | |
"000419.htm" | |
], | |
[ | |
"Defence industry", | |
"000459.htm" | |
], | |
[ | |
"Defence science and technology", | |
"000905.htm" | |
], | |
[ | |
"Logistics", | |
"000506.htm" | |
] | |
], | |
[ | |
"Emergency management", | |
"000473.htm", | |
[ | |
"Civil community assistance", | |
"000426.htm" | |
], | |
[ | |
"Disaster support", | |
"000464.htm" | |
] | |
], | |
[ | |
"Military law", | |
"001814.htm" | |
], | |
[ | |
"Military operations", | |
"000515.htm", | |
[ | |
"Australian theatre of war", | |
"000398.htm" | |
], | |
[ | |
"Military exercises", | |
"000514.htm" | |
], | |
[ | |
"Special operations", | |
"000569.htm" | |
], | |
[ | |
"Warfare", | |
"000589.htm" | |
] | |
] | |
], | |
[ | |
"EDUCATION AND TRAINING", | |
"000467.htm", | |
[ | |
"Arts education", | |
"000392.htm" | |
], | |
[ | |
"Community education", | |
"000434.htm", | |
[ | |
"Adult education programs", | |
"000379.htm" | |
], | |
[ | |
"Adult migrant education", | |
"000380.htm" | |
], | |
[ | |
"Road safety awareness", | |
"000555.htm" | |
] | |
], | |
[ | |
"Curriculum development", | |
"000447.htm" | |
], | |
[ | |
"Early childhood education", | |
"000466.htm" | |
], | |
[ | |
"Military education and training", | |
"000511.htm", | |
[ | |
"Army reserve training", | |
"000389.htm" | |
], | |
[ | |
"Defence college training", | |
"000451.htm" | |
] | |
], | |
[ | |
"Overseas skills recognition", | |
"000527.htm" | |
], | |
[ | |
"School education", | |
"000561.htm", | |
[ | |
"Discipline programs", | |
"000465.htm" | |
], | |
[ | |
"School transport regulation", | |
"000562.htm" | |
], | |
[ | |
"Special needs programs", | |
"000568.htm" | |
] | |
], | |
[ | |
"Tertiary education", | |
"000581.htm" | |
], | |
[ | |
"Vocational education", | |
"000588.htm", | |
[ | |
"Apprenticeship programs", | |
"000386.htm" | |
], | |
[ | |
"Hospital teaching programs", | |
"000493.htm" | |
], | |
[ | |
"Trainee programs", | |
"000584.htm" | |
], | |
[ | |
"Workplace training", | |
"000595.htm" | |
] | |
] | |
], | |
[ | |
"EMPLOYMENT", | |
"000016.htm", | |
[ | |
"Human resources development", | |
"000348.htm", | |
[ | |
"Occupational health and safety", | |
"000355.htm" | |
], | |
[ | |
"Recruitment programs", | |
"000356.htm" | |
], | |
[ | |
"Termination processes", | |
"002103.htm" | |
], | |
[ | |
"Workers compensation schemes", | |
"000363.htm" | |
], | |
[ | |
"Workplace discrimination monitoring", | |
"000364.htm" | |
], | |
[ | |
"Workplace equity and justice programs", | |
"000365.htm" | |
] | |
], | |
[ | |
"Industrial awards and conditions", | |
"000349.htm", | |
[ | |
"Award conditions", | |
"000366.htm" | |
], | |
[ | |
"Remuneration review", | |
"000368.htm" | |
] | |
], | |
[ | |
"Labour market programs", | |
"000347.htm", | |
[ | |
"Employment services marketing", | |
"000351.htm" | |
], | |
[ | |
"Job placement programs", | |
"000352.htm" | |
], | |
[ | |
"Job vacancy data management", | |
"000353.htm" | |
] | |
], | |
[ | |
"Workplace agreement processes", | |
"000350.htm", | |
[ | |
"Agreement bargaining processes", | |
"002141.htm" | |
], | |
[ | |
"Agreement dispute mediation", | |
"000370.htm" | |
], | |
[ | |
"Certified employment conditions", | |
"000371.htm" | |
], | |
[ | |
"Employment advocacy services", | |
"000374.htm" | |
] | |
] | |
], | |
[ | |
"ENVIRONMENT", | |
"000478.htm", | |
[ | |
"Built environment", | |
"000409.htm", | |
[ | |
"Building acoustics", | |
"000405.htm" | |
], | |
[ | |
"Building preservation", | |
"000407.htm" | |
] | |
], | |
[ | |
"Climate information services", | |
"000203.htm" | |
], | |
[ | |
"Conservation programs", | |
"000438.htm", | |
[ | |
"Endangered species protection", | |
"000475.htm" | |
], | |
[ | |
"Landcare programs", | |
"000504.htm" | |
], | |
[ | |
"Soil preservation programs", | |
"000567.htm" | |
] | |
], | |
[ | |
"Environmental impact assessment", | |
"000479.htm" | |
], | |
[ | |
"Historic relic protection", | |
"000492.htm" | |
], | |
[ | |
"Marine life protection programs", | |
"000507.htm" | |
], | |
[ | |
"Natural heritage protection", | |
"000522.htm", | |
[ | |
"National park management", | |
"000520.htm" | |
], | |
[ | |
"Nature reserve management", | |
"000523.htm" | |
], | |
[ | |
"Wilderness area management", | |
"000593.htm" | |
], | |
[ | |
"Wildlife sanctuary management", | |
"000594.htm" | |
] | |
], | |
[ | |
"Oceans governance", | |
"000525.htm" | |
], | |
[ | |
"Pollutant prevention programs", | |
"000529.htm" | |
], | |
[ | |
"World heritage listings", | |
"000596.htm" | |
] | |
], | |
[ | |
"FINANCE MANAGEMENT", | |
"000001.htm", | |
[ | |
"Commonwealth State funding", | |
"000017.htm" | |
], | |
[ | |
"Currency", | |
"000018.htm", | |
[ | |
"Counterfeiting control", | |
"000027.htm" | |
] | |
], | |
[ | |
"Financial investment", | |
"000021.htm", | |
[ | |
"Investment scheme regulation", | |
"000031.htm" | |
] | |
], | |
[ | |
"Financial system management", | |
"002302.htm", | |
[ | |
"Financial system monitoring", | |
"002306.htm" | |
], | |
[ | |
"Payments management", | |
"002297.htm" | |
] | |
], | |
[ | |
"Fiscal policy", | |
"000022.htm", | |
[ | |
"Public borrowing", | |
"000032.htm" | |
], | |
[ | |
"Public debt", | |
"000033.htm" | |
], | |
[ | |
"Public expenditure", | |
"000034.htm" | |
] | |
], | |
[ | |
"Foreign investment control", | |
"000030.htm" | |
], | |
[ | |
"International monetary regulation", | |
"000023.htm" | |
], | |
[ | |
"Monetary policy", | |
"000020.htm", | |
[ | |
"Exchange rates", | |
"000028.htm" | |
], | |
[ | |
"Inflation", | |
"000029.htm" | |
], | |
[ | |
"Interest rates", | |
"002295.htm" | |
] | |
], | |
[ | |
"Resource management", | |
"000024.htm", | |
[ | |
"Contract management", | |
"000037.htm" | |
], | |
[ | |
"Financial administration", | |
"000035.htm" | |
], | |
[ | |
"Financial budgeting", | |
"000036.htm" | |
] | |
], | |
[ | |
"Retirement income", | |
"000025.htm", | |
[ | |
"Asset assessment", | |
"000038.htm" | |
], | |
[ | |
"Retirement saving", | |
"000039.htm" | |
], | |
[ | |
"Superannuation regulation", | |
"000040.htm" | |
] | |
], | |
[ | |
"Statistical analysis", | |
"000019.htm" | |
], | |
[ | |
"Taxation", | |
"000026.htm", | |
[ | |
"Income assessment", | |
"000041.htm" | |
], | |
[ | |
"Revenue raising", | |
"000042.htm" | |
], | |
[ | |
"Taxation compliance", | |
"000043.htm" | |
] | |
] | |
], | |
[ | |
"GOVERNANCE", | |
"000002.htm", | |
[ | |
"Civic celebrations", | |
"000046.htm" | |
], | |
[ | |
"Constitutional matters", | |
"000048.htm", | |
[ | |
"Constitutional conventions", | |
"000061.htm" | |
], | |
[ | |
"Constitutional referenda", | |
"000062.htm" | |
] | |
], | |
[ | |
"Electoral matters", | |
"000049.htm", | |
[ | |
"Declaration of interests", | |
"000063.htm" | |
], | |
[ | |
"Election campaigning", | |
"000064.htm" | |
], | |
[ | |
"Electoral boundary assessment", | |
"000065.htm" | |
] | |
], | |
[ | |
"Honours and awards programs", | |
"000050.htm" | |
], | |
[ | |
"Intergovernmental relations", | |
"000052.htm", | |
[ | |
"Cross-border cooperation", | |
"000067.htm" | |
], | |
[ | |
"Intergovernment policy dissemination", | |
"000069.htm" | |
] | |
], | |
[ | |
"Legislative drafting", | |
"000053.htm", | |
[ | |
"Draft Bill amendment process", | |
"000070.htm" | |
], | |
[ | |
"Legislation review", | |
"000071.htm" | |
], | |
[ | |
"Preparation of legislative regulations", | |
"000072.htm" | |
] | |
], | |
[ | |
"Official protocol", | |
"000054.htm", | |
[ | |
"Ceremonial events and representation", | |
"000073.htm" | |
], | |
[ | |
"Head of Government protocol", | |
"000074.htm" | |
], | |
[ | |
"Official establishment management", | |
"000075.htm" | |
], | |
[ | |
"Official hospitality", | |
"000076.htm" | |
], | |
[ | |
"Official visits", | |
"000077.htm" | |
] | |
], | |
[ | |
"Parliamentary chamber support", | |
"000045.htm", | |
[ | |
"Hansard services", | |
"000058.htm" | |
], | |
[ | |
"Parliamentary papers", | |
"000059.htm" | |
], | |
[ | |
"Tabling of official documents", | |
"000060.htm" | |
] | |
], | |
[ | |
"Parliamentary committee and member support", | |
"000047.htm" | |
], | |
[ | |
"Population census", | |
"000044.htm", | |
[ | |
"Demographic surveys", | |
"000055.htm" | |
], | |
[ | |
"Household census", | |
"000056.htm" | |
], | |
[ | |
"Population distribution analysis", | |
"000057.htm" | |
] | |
], | |
[ | |
"Public administration", | |
"002290.htm", | |
[ | |
"Government auditing", | |
"002291.htm" | |
], | |
[ | |
"Public service", | |
"002292.htm" | |
], | |
[ | |
"Territories administration", | |
"002293.htm" | |
] | |
], | |
[ | |
"Statistics", | |
"002289.htm" | |
] | |
], | |
[ | |
"HEALTH CARE", | |
"000003.htm", | |
[ | |
"Community health services", | |
"000078.htm", | |
[ | |
"Clinical health services", | |
"000087.htm" | |
], | |
[ | |
"Health promotion", | |
"000089.htm" | |
], | |
[ | |
"Primary health care", | |
"000090.htm" | |
] | |
], | |
[ | |
"Health insurance schemes", | |
"000079.htm" | |
], | |
[ | |
"Health protocol administration", | |
"000080.htm", | |
[ | |
"Drugs and poisons regulation", | |
"000091.htm" | |
], | |
[ | |
"Food hygiene regulation", | |
"000092.htm" | |
], | |
[ | |
"Practitioner discipline", | |
"000093.htm" | |
], | |
[ | |
"Practitioner registration", | |
"000095.htm" | |
] | |
], | |
[ | |
"Hospital services", | |
"000081.htm", | |
[ | |
"Hospital administration", | |
"000096.htm" | |
], | |
[ | |
"Patient care", | |
"000097.htm" | |
], | |
[ | |
"Pharmaceutical and drug support", | |
"000098.htm" | |
] | |
], | |
[ | |
"Medical research", | |
"000083.htm", | |
[ | |
"Ethical compliance", | |
"000099.htm" | |
], | |
[ | |
"Medical aids regulation", | |
"000100.htm" | |
], | |
[ | |
"Medical research funding", | |
"000101.htm" | |
], | |
[ | |
"National referral laboratory services", | |
"000102.htm" | |
], | |
[ | |
"Population-based research", | |
"000103.htm" | |
] | |
], | |
[ | |
"Public health services", | |
"000084.htm", | |
[ | |
"Epidemiology", | |
"000104.htm" | |
], | |
[ | |
"Health disaster preparedness", | |
"000106.htm" | |
], | |
[ | |
"Health hazard prevention", | |
"000105.htm" | |
], | |
[ | |
"Medical quarantine services", | |
"000108.htm" | |
], | |
[ | |
"Notifiable disease management", | |
"000109.htm" | |
] | |
], | |
[ | |
"Special needs services", | |
"000085.htm", | |
[ | |
"Dental health services", | |
"000111.htm" | |
], | |
[ | |
"Independent living services", | |
"000112.htm" | |
], | |
[ | |
"Mental health services", | |
"000113.htm" | |
], | |
[ | |
"Residential services", | |
"000114.htm" | |
] | |
], | |
[ | |
"Veterans\" health services", | |
"000086.htm" | |
] | |
], | |
[ | |
"IMMIGRATION", | |
"000004.htm", | |
[ | |
"Citizenship", | |
"000115.htm", | |
[ | |
"Naturalisation assessment", | |
"000121.htm" | |
], | |
[ | |
"Presentation arrangements", | |
"000122.htm" | |
] | |
], | |
[ | |
"Deportation", | |
"000116.htm" | |
], | |
[ | |
"Detention programs", | |
"000117.htm" | |
], | |
[ | |
"Migrant services", | |
"000118.htm", | |
[ | |
"Interpreter services", | |
"000123.htm" | |
], | |
[ | |
"Migrant accommodation services", | |
"000125.htm" | |
], | |
[ | |
"Migrant settlement programs", | |
"000126.htm" | |
] | |
], | |
[ | |
"Refugee services", | |
"000119.htm" | |
], | |
[ | |
"Travel authorisation", | |
"000120.htm", | |
[ | |
"Permanent entry arrangements", | |
"000127.htm" | |
], | |
[ | |
"Temporary entry arrangements", | |
"000128.htm" | |
] | |
] | |
], | |
[ | |
"INDIGENOUS AFFAIRS", | |
"002285.htm", | |
[ | |
"Indigenous cultural heritage", | |
"000495.htm", | |
[ | |
"Cultural artefact repatriation", | |
"001772.htm" | |
] | |
], | |
[ | |
"Indigenous enterprise development", | |
"000496.htm" | |
], | |
[ | |
"Indigenous health services", | |
"000082.htm" | |
], | |
[ | |
"Indigenous heritage conservation", | |
"000497.htm" | |
], | |
[ | |
"Indigenous reconciliation", | |
"000051.htm" | |
], | |
[ | |
"Indigenous welfare programs", | |
"000498.htm" | |
] | |
], | |
[ | |
"INTERNATIONAL RELATIONS", | |
"000005.htm", | |
[ | |
"Consular services", | |
"000129.htm" | |
], | |
[ | |
"Defence liaison", | |
"000132.htm", | |
[ | |
"000140.htm" | |
], | |
[ | |
"Defence cooperation programs", | |
"000141.htm" | |
], | |
[ | |
"Defence personnel exchanges", | |
"000142.htm" | |
], | |
[ | |
"Military advisors", | |
"000143.htm" | |
] | |
], | |
[ | |
"Diplomatic missions", | |
"000130.htm" | |
], | |
[ | |
"International affairs", | |
"000131.htm", | |
[ | |
"Disarmament and arms control", | |
"000137.htm" | |
], | |
[ | |
"Nuclear safeguards", | |
"000139.htm" | |
] | |
], | |
[ | |
"International treaties", | |
"000133.htm", | |
[ | |
"Treaty administration", | |
"001384.htm" | |
] | |
], | |
[ | |
"Overseas aid programs", | |
"000134.htm", | |
[ | |
"Development assistance programs", | |
"000146.htm" | |
], | |
[ | |
"Overseas student scholarship programs", | |
"000147.htm" | |
] | |
], | |
[ | |
"Overseas promotion", | |
"000135.htm" | |
], | |
[ | |
"Passport services", | |
"000136.htm" | |
] | |
], | |
[ | |
"JUSTICE ADMINISTRATION", | |
"000006.htm", | |
[ | |
"Administrative law", | |
"000149.htm", | |
[ | |
"Administrative decision appeal", | |
"000163.htm" | |
], | |
[ | |
"Administrative decision review", | |
"000164.htm" | |
], | |
[ | |
"Censorship standards", | |
"000165.htm" | |
], | |
[ | |
"Copyright regulation", | |
"000166.htm" | |
], | |
[ | |
"Recordkeeping standards", | |
"000167.htm" | |
] | |
], | |
[ | |
"Associations and corporate law", | |
"000150.htm", | |
[ | |
"Bankruptcy proceedings", | |
"000168.htm" | |
], | |
[ | |
"Merger regulation", | |
"000169.htm" | |
] | |
], | |
[ | |
"Civil law", | |
"000151.htm", | |
[ | |
"Civil registration", | |
"000170.htm" | |
], | |
[ | |
"Conveyancing", | |
"000171.htm" | |
], | |
[ | |
"Dispute mediation programs", | |
"000174.htm" | |
], | |
[ | |
"Family law proceedings", | |
"000172.htm" | |
], | |
[ | |
"Probate applications", | |
"000173.htm" | |
] | |
], | |
[ | |
"Commissions of inquiry", | |
"000152.htm" | |
], | |
[ | |
"Coronial law", | |
"000153.htm" | |
], | |
[ | |
"Court reporting", | |
"000154.htm" | |
], | |
[ | |
"Criminal law", | |
"000155.htm" | |
], | |
[ | |
"Human rights obligations", | |
"000156.htm" | |
], | |
[ | |
"Juvenile justice", | |
"000157.htm" | |
], | |
[ | |
"Legal aid services", | |
"000158.htm" | |
], | |
[ | |
"Local laws and ordinances", | |
"000159.htm" | |
], | |
[ | |
"Native title claims", | |
"000160.htm", | |
[ | |
"Native title mediation programs", | |
"000180.htm" | |
], | |
[ | |
"Native title settlement negotiations", | |
"000181.htm" | |
] | |
], | |
[ | |
"Privacy guideline monitoring", | |
"000161.htm" | |
], | |
[ | |
"Prosecution services", | |
"000162.htm" | |
] | |
], | |
[ | |
"MARITIME SERVICES", | |
"000007.htm", | |
[ | |
"Cargo control", | |
"000198.htm" | |
], | |
[ | |
"Harbour management", | |
"000183.htm" | |
], | |
[ | |
"Marina management", | |
"000184.htm" | |
], | |
[ | |
"Navigation", | |
"000185.htm", | |
[ | |
"Charting sea lanes", | |
"000191.htm" | |
], | |
[ | |
"Light station maintenance", | |
"000192.htm" | |
], | |
[ | |
"Navigation systems development", | |
"000193.htm" | |
] | |
], | |
[ | |
"Pilotage management", | |
"000182.htm" | |
], | |
[ | |
"Port regulation", | |
"001471.htm" | |
], | |
[ | |
"Sea passengers", | |
"001487.htm" | |
], | |
[ | |
"Search and rescue", | |
"000187.htm", | |
[ | |
"Rescue coordination", | |
"000194.htm" | |
], | |
[ | |
"Search technology development", | |
"000195.htm" | |
] | |
], | |
[ | |
"Ship personnel", | |
"000188.htm", | |
[ | |
"Personnel safety standards", | |
"000196.htm" | |
], | |
[ | |
"Pilot licensing", | |
"000197.htm" | |
] | |
], | |
[ | |
"Ship safety", | |
"000189.htm", | |
[ | |
"Seaworthiness", | |
"000201.htm" | |
], | |
[ | |
"Ship commissioning", | |
"000199.htm" | |
], | |
[ | |
"Ship inspection", | |
"000200.htm" | |
] | |
] | |
], | |
[ | |
"NATURAL RESOURCES", | |
"000009.htm", | |
[ | |
"Crown land administration", | |
"000218.htm" | |
], | |
[ | |
"Energy resources", | |
"001451.htm", | |
[ | |
"Fossil fuel management", | |
"000226.htm" | |
], | |
[ | |
"Renewable energy development", | |
"000227.htm" | |
] | |
], | |
[ | |
"Land use planning", | |
"000220.htm", | |
[ | |
"Land use zoning", | |
"001429.htm" | |
] | |
], | |
[ | |
"Land valuation", | |
"000222.htm" | |
], | |
[ | |
"Mineral resources", | |
"000223.htm", | |
[ | |
"Land rehabilitation programs", | |
"000231.htm" | |
], | |
[ | |
"Mining regulations", | |
"000232.htm" | |
] | |
], | |
[ | |
"Pollution emission control", | |
"000224.htm" | |
], | |
[ | |
"Water resources", | |
"000225.htm", | |
[ | |
"Water conservation plans", | |
"000233.htm" | |
], | |
[ | |
"Water quality monitoring", | |
"000234.htm" | |
], | |
[ | |
"Water usage management", | |
"000235.htm" | |
], | |
[ | |
"Waterway management", | |
"000236.htm" | |
] | |
] | |
], | |
[ | |
"PRIMARY INDUSTRIES", | |
"000008.htm", | |
[ | |
"Chemical and pesticide regulation", | |
"000202.htm" | |
], | |
[ | |
"Marine and rural regulation", | |
"000204.htm", | |
[ | |
"Agricultural industry", | |
"000208.htm" | |
], | |
[ | |
"Fisheries industry", | |
"000209.htm" | |
], | |
[ | |
"Food quality assurance", | |
"000213.htm" | |
], | |
[ | |
"Forestry industry", | |
"000210.htm" | |
] | |
], | |
[ | |
"Marine and rural support", | |
"000205.htm", | |
[ | |
"Aquaculture industry", | |
"000212.htm" | |
], | |
[ | |
"Horticultural industry", | |
"000214.htm" | |
], | |
[ | |
"Pastoral industry", | |
"000215.htm" | |
], | |
[ | |
"Silvicultural industry", | |
"000216.htm" | |
], | |
[ | |
"Viticultural industry", | |
"000217.htm" | |
] | |
], | |
[ | |
"Quarantine", | |
"000211.htm" | |
], | |
[ | |
"Rural field day promotion", | |
"000206.htm" | |
], | |
[ | |
"Rural partnership programs", | |
"000207.htm" | |
] | |
], | |
[ | |
"SCIENCE", | |
"000010.htm", | |
[ | |
"Agricultural sciences", | |
"000237.htm" | |
], | |
[ | |
"Animal and veterinary sciences", | |
"000238.htm" | |
], | |
[ | |
"Applied sciences", | |
"000239.htm", | |
[ | |
"Engineering and technology sciences", | |
"000246.htm" | |
], | |
[ | |
"Weights and measures standards", | |
"000247.htm" | |
] | |
], | |
[ | |
"Biological sciences", | |
"000240.htm", | |
[ | |
"Biochemistry", | |
"000248.htm" | |
], | |
[ | |
"Biodiversity preservation", | |
"000249.htm" | |
], | |
[ | |
"Biotechnology development", | |
"000250.htm" | |
], | |
[ | |
"Botany", | |
"000251.htm" | |
], | |
[ | |
"Entomology", | |
"000252.htm" | |
], | |
[ | |
"Genetic engineering", | |
"000253.htm" | |
], | |
[ | |
"Physiology", | |
"000254.htm" | |
] | |
], | |
[ | |
"Earth sciences", | |
"000241.htm", | |
[ | |
"Atmospheric sciences", | |
"000255.htm" | |
], | |
[ | |
"Hydrology", | |
"000256.htm" | |
], | |
[ | |
"Mineral exploration", | |
"000257.htm" | |
], | |
[ | |
"Oceanography", | |
"000258.htm" | |
], | |
[ | |
"Seismology", | |
"000259.htm" | |
] | |
], | |
[ | |
"Mathematical sciences", | |
"000242.htm" | |
], | |
[ | |
"Medical and health sciences", | |
"001229.htm" | |
], | |
[ | |
"Physical sciences", | |
"000244.htm", | |
[ | |
"Astronomical sciences", | |
"000260.htm" | |
], | |
[ | |
"Atomic and molecular sciences", | |
"000261.htm" | |
], | |
[ | |
"Nuclear sciences", | |
"000262.htm" | |
] | |
], | |
[ | |
"Spatial information research", | |
"000245.htm" | |
] | |
], | |
[ | |
"SECURITY", | |
"000011.htm", | |
[ | |
"Corrective services", | |
"000263.htm", | |
[ | |
"Community based corrections", | |
"000270.htm" | |
], | |
[ | |
"Detention centre management", | |
"000271.htm" | |
] | |
], | |
[ | |
"External security", | |
"000264.htm", | |
[ | |
"Peacekeeping forces", | |
"000273.htm" | |
] | |
], | |
[ | |
"Information security", | |
"000265.htm" | |
], | |
[ | |
"Intelligence", | |
"000266.htm", | |
[ | |
"Forensic analysis", | |
"000275.htm" | |
], | |
[ | |
"Intelligence liaison", | |
"001159.htm" | |
], | |
[ | |
"Intelligence support", | |
"000277.htm" | |
] | |
], | |
[ | |
"Law enforcement", | |
"000267.htm", | |
[ | |
"Community policing", | |
"000278.htm" | |
], | |
[ | |
"Criminology", | |
"000279.htm" | |
], | |
[ | |
"Police administration", | |
"000280.htm" | |
], | |
[ | |
"Protective services", | |
"000281.htm" | |
] | |
], | |
[ | |
"National security", | |
"001548.htm", | |
[ | |
"Coastal surveillance", | |
"000269.htm" | |
] | |
] | |
], | |
[ | |
"SPORT AND RECREATION", | |
"000012.htm", | |
[ | |
"Caravan and camping services", | |
"000284.htm" | |
], | |
[ | |
"Community recreational programs", | |
"000285.htm", | |
[ | |
"Gambling support services", | |
"000290.htm" | |
], | |
[ | |
"Public fitness promotion", | |
"000291.htm" | |
], | |
[ | |
"Social club support", | |
"000292.htm" | |
], | |
[ | |
"Volunteer support programs", | |
"000293.htm" | |
] | |
], | |
[ | |
"Gaming industry regulation", | |
"000286.htm" | |
], | |
[ | |
"Park and reserve services", | |
"000289.htm" | |
], | |
[ | |
"Sport and fitness development", | |
"000287.htm", | |
[ | |
"Athlete scholarship programs", | |
"000295.htm" | |
], | |
[ | |
"Fundraising and donation schemes", | |
"000296.htm" | |
], | |
[ | |
"Games administration", | |
"000297.htm" | |
], | |
[ | |
"Games promotion", | |
"000298.htm" | |
], | |
[ | |
"Sporting grants administration", | |
"000299.htm" | |
] | |
], | |
[ | |
"Sports drugs monitoring", | |
"000288.htm", | |
[ | |
"Doping detection research", | |
"000300.htm" | |
] | |
] | |
], | |
[ | |
"TOURISM", | |
"000013.htm", | |
[ | |
"Tourism industry development", | |
"000301.htm" | |
], | |
[ | |
"Tourist event promotion", | |
"000302.htm", | |
[ | |
"Advertising campaigns", | |
"000305.htm" | |
] | |
], | |
[ | |
"Travel missions", | |
"000303.htm" | |
] | |
], | |
[ | |
"TRADE", | |
"000014.htm", | |
[ | |
"Export regulation", | |
"000311.htm", | |
[ | |
"Export promotion", | |
"000320.htm" | |
], | |
[ | |
"Prohibited export control", | |
"000321.htm" | |
] | |
], | |
[ | |
"Import regulation", | |
"000312.htm", | |
[ | |
"Prohibited import control", | |
"000323.htm" | |
], | |
[ | |
"Tariff regulation", | |
"000322.htm" | |
] | |
], | |
[ | |
"Intellectual property management", | |
"000910.htm", | |
[ | |
"Copyright registration", | |
"000308.htm" | |
], | |
[ | |
"Design registration", | |
"000310.htm" | |
], | |
[ | |
"Patent registration", | |
"000315.htm" | |
], | |
[ | |
"Trademark registration", | |
"000318.htm" | |
] | |
], | |
[ | |
"International trade agreements", | |
"000313.htm" | |
], | |
[ | |
"Interstate trade agreements", | |
"000314.htm" | |
], | |
[ | |
"Trade development programs", | |
"000316.htm" | |
], | |
[ | |
"Trade expositions", | |
"000317.htm" | |
] | |
], | |
[ | |
"TRANSPORT", | |
"000015.htm", | |
[ | |
"Air transport", | |
"000324.htm", | |
[ | |
"Air transport safety", | |
"000332.htm" | |
], | |
[ | |
"Aircraft standards", | |
"000330.htm" | |
], | |
[ | |
"Airport services", | |
"000331.htm" | |
] | |
], | |
[ | |
"Freight movement regulation", | |
"000325.htm" | |
], | |
[ | |
"Passenger services", | |
"000326.htm" | |
], | |
[ | |
"Rail transport", | |
"000327.htm", | |
[ | |
"Rail harmonisation standards", | |
"000333.htm" | |
], | |
[ | |
"Rail land acquisition regulation", | |
"000336.htm" | |
], | |
[ | |
"Rail transport safety", | |
"000337.htm" | |
], | |
[ | |
"Railway maintenance", | |
"000338.htm" | |
], | |
[ | |
"Rolling stock regulation", | |
"000339.htm" | |
] | |
], | |
[ | |
"Road transport", | |
"000328.htm", | |
[ | |
"Driving licences administration", | |
"000340.htm" | |
], | |
[ | |
"Road surface maintenance", | |
"000341.htm" | |
], | |
[ | |
"Road traffic regulation", | |
"000342.htm" | |
], | |
[ | |
"Road transport safety", | |
"000343.htm" | |
], | |
[ | |
"Vehicle registration", | |
"000344.htm" | |
], | |
[ | |
"Vehicle standards", | |
"000345.htm" | |
] | |
], | |
[ | |
"Transport infrastructure development", | |
"000329.htm" | |
] | |
] | |
] |
<!DOCTYPE html> | <!DOCTYPE html> |
<html xmlns="http://www.w3.org/1999/xhtml"> | <html xmlns="http://www.w3.org/1999/xhtml"> |
<head> | <head> |
<meta charset="UTF-8"/> | <meta charset="UTF-8"/> |
<title>Minimal BubbleTree Demo</title> | <title>Minimal BubbleTree Demo</title> |
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.js"></script> | <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.js"></script> |
<script type="text/javascript" src="javascripts/bubbletree/lib/jquery.history.js"></script> | <script type="text/javascript" src="javascripts/bubbletree/lib/jquery.history.js"></script> |
<script type="text/javascript" src="javascripts/bubbletree/lib/raphael.js"></script> | <script type="text/javascript" src="javascripts/bubbletree/lib/raphael.js"></script> |
<script type="text/javascript" src="javascripts/bubbletree/lib/vis4.js"></script> | <script type="text/javascript" src="javascripts/bubbletree/lib/vis4.js"></script> |
<script type="text/javascript" src="javascripts/bubbletree/lib/Tween.js"></script> | <script type="text/javascript" src="javascripts/bubbletree/lib/Tween.js"></script> |
<script type="text/javascript" src="javascripts/bubbletree/build/bubbletree.js"></script> | <script type="text/javascript" src="javascripts/bubbletree/build/bubbletree.js"></script> |
<link rel="stylesheet" type="text/css" href="javascripts/bubbletree/build/bubbletree.css" /> | <link rel="stylesheet" type="text/css" href="javascripts/bubbletree/build/bubbletree.css" /> |
<script type="text/javascript" src="javascripts/bubbletree/styles/cofog.js"></script> | <script type="text/javascript" src="javascripts/bubbletree/styles/cofog.js"></script> |
<script type="text/javascript"> | <script type="text/javascript"> |
$(function() { | $(function() { |
<?php | <?php |
include_once('include/common.inc.php'); | include_once('include/common.inc.php'); |
include("lib/Color.php"); | include("lib/Color.php"); |
$color = new Lux_Color(); | $color = new Lux_Color(); |
$portfolios = Array(); | $portfolios = Array(); |
$total = 0; | |
$db = $server->get_db('disclosr-agencies'); | $db = $server->get_db('disclosr-agencies'); |
try { | try { |
$rows = $db->get_view("app", "byDeptStateName", null, true)->rows; | $rows = $db->get_view("app", "byDeptStateName", null, true)->rows; |
foreach ($rows as $row) { | foreach ($rows as $row) { |
$portfolios[trim(str_replace(Array("Department of","Department","the","'","`"),"",$row->key))] = $row->value; | $portfolios[trim(str_replace(Array("Department of", "Department", "the", "'", "`"), "", $row->key))] = $row->value; |
} | } |
} catch (SetteeRestClientException $e) { | } catch (SetteeRestClientException $e) { |
setteErrorHandler($e); | setteErrorHandler($e); |
} | } |
$agencies = Array(); | $agencies = Array(); |
try { | try { |
$rows = $db->get_view("app", "byCanonicalName", null, true)->rows; | $rows = $db->get_view("app", "byCanonicalName", null, true)->rows; |
//print_r($rows); | //print_r($rows); |
foreach ($rows as $row) { | foreach ($rows as $row) { |
$employees = 0; | $employees = 0; |
$portfolioid = 0; | $portfolioid = 0; |
if ($row->value->employees) $employees = $row->value->employees; | if (isset($row->value->employees)) { |
if (isset($row->value->statistics->employees)) { | $employees = $row->value->employees; |
$agencyEmployeesArray = object_to_array($row->value->statistics->employees); | } |
$employees = $agencyEmployeesArray["2010-2011"]["value"]; | if (isset($row->value->statistics->employees)) { |
} | $agencyEmployeesArray = object_to_array($row->value->statistics->employees); |
if (!($employees > 0)) $employees =0; | if (isset($agencyEmployeesArray["2010-2011"]["value"])) { |
if (isset($row->value->parentOrg)) $portfolioid = $row->value->parentOrg; | $employees = $agencyEmployeesArray["2010-2011"]["value"]; |
if (isset($row->value->orgType) && $row->value->orgType == "FMA-DepartmentOfState") $portfolioid = $row->id; | } else { |
$agencies[$portfolioid][$row->value->name] = $employees; | // bailout for agencies that are closed for business |
continue; | |
} | |
} | |
if (!($employees > 0)) { | |
$employees = 0; | |
} | |
if (isset($row->value->parentOrg)) { | |
$portfolioid = $row->value->parentOrg; | |
} | |
if (isset($row->value->orgType) && $row->value->orgType == "FMA-DepartmentOfState") { | |
$portfolioid = $row->id; | |
} | |
$agencies[$portfolioid][$row->value->name] = $employees; | |
} | } |
} catch (SetteeRestClientException $e) { | } catch (SetteeRestClientException $e) { |
setteErrorHandler($e); | setteErrorHandler($e); |
} | } |
//print_r($portfolios); | //print_r($portfolios); |
//print_r($agencies); | //print_r($agencies); |
$i = 0; | |
// http://martin.ankerl.com/2009/12/09/how-to-create-random-colors-programmatically/ | |
$golden_ratio_conjugate = 0.618033988749895; | |
$h = 0.00+rand(0,10)/10; # use random start value | |
foreach ($portfolios as $portfolioName => $portfolioID) { | foreach ($portfolios as $portfolioName => $portfolioID) { |
$i++; | $h += $golden_ratio_conjugate; |
$portfolioColor = $color->hsv2hex(Array($i/10, .7, abs(($i*(1/10))-.5) + .5)); | |
$subnodes = Array(); | $h = fmod($h,1); |
$portfolioEmployees = 0; | $portfolioColor = $color->hsv2hex(Array($h, .3, .99)); |
foreach ($agencies[$portfolioID] as $agencyName => $agencyEmployees) { | $subnodes = Array(); |
$agencyColor = $color->hsv2hex(Array($i/10, rand(1,10)/10, abs(($i*(1/10))-.5) + .5)); | $portfolioEmployees = 0; |
$subnodes[] = Array( | foreach ($agencies[$portfolioID] as $agencyName => $agencyEmployees) { |
"label" => str_replace(Array("'","`"),"",$agencyName), | $agencyColor = $color->hsv2hex(Array($h / 10, rand(1, 10) / 10, abs(($h * (1 / 10)) - .5) + .5)); |
"amount" => $agencyEmployees, | $subnodes[] = Array( |
"color" => "#".$agencyColor | "label" => str_replace(Array("'", "`"), "", $agencyName), |
); | "amount" => $agencyEmployees, |
$portfolioEmployees += $agencyEmployees; | //"color" => "#" . $agencyColor |
} | ); |
$nodes[] = Array( | $portfolioEmployees += $agencyEmployees; |
"label" => $portfolioName, | } |
"amount" => $portfolioEmployees, | $nodes[] = Array( |
"color" => "#".$portfolioColor, | "label" => $portfolioName, |
"children" => $subnodes | "amount" => $portfolioEmployees, |
); | //"color" => "#" . $portfolioColor, |
$total += $portfolioEmployees; | "children" => $subnodes |
); | |
$total += $portfolioEmployees; | |
} | } |
$data = Array( | $data = Array( |
"label" => "Australian Federal Government", | "label" => "Australian Federal Government", |
"amount" => $total, | "amount" => $total, |
"color" => "#000000", | //"color" => "#000000", |
"children" => $nodes | "children" => $nodes |
); | ); |
echo "var data =eval('('+'" . json_encode($data) . "'+')');"; | echo "var data =eval('('+'" . json_encode($data) . "'+')');"; |
?> | ?> |
new BubbleTree({ | new BubbleTree({ |
data: data, | data: data, |
container: '.bubbletree' | container: '.bubbletree' |
}); | }); |
}); | }); |
</script> | </script> |
</head> | </head> |
<body> | <body> |
<div class="bubbletree-wrapper"> | <div class="bubbletree-wrapper"> |
<div class="bubbletree"></div> | <div class="bubbletree"></div> |
</div> | </div> |
</body> | </body> |
</html> | </html> |
<?php | <?php |
include_once('include/common.inc.php'); | include_once('include/common.inc.php'); |
include_header(); | include_header('Charts'); |
$db = $server->get_db('disclosr-agencies'); | $db = $server->get_db('disclosr-agencies'); |
?> | ?> |
<div class="foundation-header"> | <div class="foundation-header"> |
<h1><a href="about.php">Charts</a></h1> | <h1><a href="about.php">Charts</a></h1> |
<h4 class="subheader">Lorem ipsum.</h4> | <h4 class="subheader">Lorem ipsum.</h4> |
</div> | </div> |
<div id="scores" style="width:900px;height:500px;"></div> | <div id="scores" style="width:900px;height:500px;"></div> |
<div id="employees" style="width:1000px;height:900px;"></div> | <div id="employees" style="width:1000px;height:900px;"></div> |
<script id="source"> | <script id="source"> |
window.onload = function() { | window.onload = function() { |
$(document).ready(function() { | $(document).ready(function() { |
var d1 = []; | var d1 = []; |
var scorelabels = []; | var scorelabels = []; |
<?php | <?php |
try { | try { |
$rows = $db->get_view("app", "scoreHas?group=true", null, true)->rows; | $rows = $db->get_view("app", "scoreHas?group=true", null, true)->rows; |
$dataValues = Array(); | $dataValues = Array(); |
foreach ($rows as $row) { | foreach ($rows as $row) { |
$dataValues[$row->value] = $row->key; | $dataValues[$row->value] = $row->key; |
} | } |
$i = 0; | $i = 0; |
ksort($dataValues); | ksort($dataValues); |
foreach ($dataValues as $value => $key) { | foreach ($dataValues as $value => $key) { |
echo " d1.push([$i, $value]);" . PHP_EOL; | echo " d1.push([$i, $value]);" . PHP_EOL; |
echo " scorelabels.push('$key');" . PHP_EOL; | echo " scorelabels.push('$key');" . PHP_EOL; |
$i++; | $i++; |
} | } |
} catch (SetteeRestClientException $e) { | } catch (SetteeRestClientException $e) { |
setteErrorHandler($e); | setteErrorHandler($e); |
} | } |
?> | ?> |
function scoretrackformatter(obj) { | function scoretrackformatter(obj) { |
if (scorelabels[Math.floor(obj.x)]) { | if (scorelabels[Math.floor(obj.x)]) { |
return (scorelabels[Math.floor(obj.x)])+"="+obj.y; | return (scorelabels[Math.floor(obj.x)])+"="+obj.y; |
} else { | } else { |
return ""; | return ""; |
} | } |
} | } |
function scoretickformatter(val, axis) { | function scoretickformatter(val, axis) { |
if (scorelabels[Math.floor(val)]) { | if (scorelabels[Math.floor(val)]) { |
return '<p style="margin-top:8em;-webkit-transform:rotate(-90deg);">'+(scorelabels[Math.floor(val)])+"</b>"; | return '<p style="margin-top:8em;-webkit-transform:rotate(-90deg);">'+(scorelabels[Math.floor(val)])+"</b>"; |
} else { | } else { |
return ""; | return ""; |
} | } |
} | } |
Flotr.draw(document.getElementById("scores"), [ {data: d1}], { | Flotr.draw(document.getElementById("scores"), [ {data: d1}], { |
HtmlText: true, | HtmlText: true, |
bars : { | bars : { |
show : true | show : true |
}, | }, |
mouse : { | mouse : { |
track : true, | track : true, |
relative : true, | relative : true, |
trackFormatter: scoretrackformatter | trackFormatter: scoretrackformatter |
},yaxis: { | },yaxis: { |
autoscaling: true | autoscaling: true |
}, | }, |
xaxis: { | xaxis: { |
autoscaling: true, | autoscaling: true, |
minorTickFreq: 0.6, | minorTickFreq: 0.6, |
noTicks : scorelabels.length, | noTicks : scorelabels.length, |
tickFormatter: scoretickformatter | tickFormatter: scoretickformatter |
} | } |
}); | }); |
var emplabels = []; | var emplabels = []; |
function emptrackformatter(obj) { | function emptrackformatter(obj) { |
return (obj.series.label)+" = "+obj.y+" in "+emplabels[Math.floor(obj.x)]; | return (obj.series.label)+" = "+obj.y+" in "+emplabels[Math.floor(obj.x)]; |
} | } |
function emptickformatter(val, axis) { | function emptickformatter(val, axis) { |
if (emplabels[Math.floor(val)]) { | if (emplabels[Math.floor(val)]) { |
return '<p style="margin-top:8em;-webkit-transform:rotate(-90deg);">'+(emplabels[Math.floor(val)])+"</b>"; | return '<p style="margin-top:8em;-webkit-transform:rotate(-90deg);">'+(emplabels[Math.floor(val)])+"</b>"; |
} else { | } else { |
return ""; | return ""; |
} | } |
} | } |
function onDataReceived(series) { | function onDataReceived(series) { |
emplabels = series.labels; | emplabels = series.labels; |
Flotr.draw(document.getElementById("employees"), series.data, { | Flotr.draw(document.getElementById("employees"), series.data, { |
mouse : { | mouse : { |
track : true, | track : true, |
relative : true, | relative : true, |
trackFormatter: emptrackformatter | trackFormatter: emptrackformatter |
},yaxis: { | },yaxis: { |
max: 10000, | max: 10000, |
scaling: 'logarithmic' | scaling: 'logarithmic' |
}, | }, |
xaxis: { | xaxis: { |
minorTickFreq: 1, | minorTickFreq: 1, |
noTicks: emplabels.length, | noTicks: emplabels.length, |
showMinorLabels: true, | showMinorLabels: true, |
tickFormatter: emptickformatter | tickFormatter: emptickformatter |
}, | }, |
legend: { | legend: { |
show: false | show: false |
} | } |
}); | }); |
} | } |
$.ajax({ | $.ajax({ |
url: "admin/exportEmployees.csv.php?format=json", | url: "admin/exportEmployees.csv.php?format=json", |
method: 'GET', | method: 'GET', |
dataType: 'json', | dataType: 'json', |
success: onDataReceived | success: onDataReceived |
}); | }); |
}); | }); |
}; | }; |
</script> | </script> |
<?php | <?php |
include_footer(); | include_footer(); |
?> | ?> |
<?php | <?php |
include_once('include/common.inc.php'); | include_once('include/common.inc.php'); |
include_header(); | |
function displayValue($key, $value, $mode) { | function displayValue($key, $value, $mode) { |
global $db, $schemas; | global $db, $schemas; |
if ($mode == "view") { | if ($mode == "view") { |
if (strpos($key, "_") === 0 || $key== "metadata") return; | |
echo "<tr>"; | echo "<tr>"; |
echo "<td>" . $schemas['agency']["properties"][$key]['x-title'] . "<br><small>" . $schemas['agency']["properties"][$key]['description'] . "</small></td><td>"; | echo "<td>" . $schemas['agency']["properties"][$key]['x-title'] . "<br><small>" . $schemas['agency']["properties"][$key]['description'] . "</small></td><td>"; |
if (is_array($value)) { | if (is_array($value)) { |
echo "<ol>"; | echo "<ol>"; |
foreach ($value as $subkey => $subvalue) { | foreach ($value as $subkey => $subvalue) { |
if (isset($schemas['agency']["properties"][$key]['x-property'])) { | |
echo '<li property="' . $schemas['agency']["properties"][$key]['x-property'] . '">'; | echo "<li "; |
} else { | if (isset($schemas['agency']["properties"][$key]['x-property'])) { |
echo "<li>"; | echo ' property="' . $schemas['agency']["properties"][$key]['x-property'] . '" '; |
} | } if (isset($schemas['agency']["properties"][$key]['x-itemprop'])) { |
echo ' itemprop="' . $schemas['agency']["properties"][$key]['x-itemprop'] . '" '; | |
} | |
echo " >"; | |
echo "$subvalue</li>"; | echo "$subvalue</li>"; |
} | } |
echo "</ol></td></tr>"; | echo "</ol></td></tr>"; |
} else { | } else { |
if (isset($schemas['agency']["properties"][$key]['x-property'])) { | if (isset($schemas['agency']["properties"][$key]['x-property'])) { |
echo '<span property="' . $schemas['agency']["properties"][$key]['x-property'] . '">'; | echo '<span property="' . $schemas['agency']["properties"][$key]['x-property'] . '">'; |
} else { | } else { |
echo "<span>"; | echo "<span>"; |
} | } |
if ((strpos($key, "URL") > 0 || $key == 'website') && $value != "") { | if ((strpos($key, "URL") > 0 || $key == 'website') && $value != "") { |
echo "<a href='$value'>view</a></span>"; | echo "<a ".($key == 'website' ? 'itemprop="url"':'')." href='$value'>$value</a>"; |
} else { | } else { |
echo "$value</span>"; | echo "$value</span>"; |
} | } |
} | } |
echo "</td></tr>"; | echo "</td></tr>"; |
} | } |
if ($mode == "edit") { | if ($mode == "edit") { |
if (is_array($value)) { | if (is_array($value)) { |
echo '<div class="row"> | echo '<div class="row"> |
<div class="seven columns"> | <div class="seven columns"> |
<fieldset> | <fieldset> |
<h5>' . $key . '</h5>'; | <h5>' . $key . '</h5>'; |
foreach ($value as $subkey => $subvalue) { | foreach ($value as $subkey => $subvalue) { |
echo "<label>$subkey</label><input class='input-text' type='text' id='$key$subkey' name='$key" . '[' . $subkey . "]' value='$subvalue'/></tr>"; | echo "<label>$subkey</label><input class='input-text' type='text' id='$key$subkey' name='$key" . '[' . $subkey . "]' value='$subvalue'/></tr>"; |
} | } |
echo "</fieldset> | echo "</fieldset> |
</div> | </div> |
</div>"; | </div>"; |
} else { | } else { |
if (strpos($key, "_") === 0) { | if (strpos($key, "_") === 0) { |
echo"<input type='hidden' id='$key' name='$key' value='$value'/>"; | echo"<input type='hidden' id='$key' name='$key' value='$value'/>"; |
} else if ($key == "parentOrg") { | } else if ($key == "parentOrg") { |
echo "<label for='$key'>$key</label><select id='$key' name='$key'><option value=''> Select... </option>"; | echo "<label for='$key'>$key</label><select id='$key' name='$key'><option value=''> Select... </option>"; |
$rows = $db->get_view("app", "byDeptStateName")->rows; | $rows = $db->get_view("app", "byDeptStateName")->rows; |
//print_r($rows); | //print_r($rows); |
foreach ($rows as $row) { | foreach ($rows as $row) { |
echo "<option value='{$row->value}'" . (($row->value == $value) ? "SELECTED" : "") . " >" . str_replace("Department of ", "", $row->key) . "</option>"; | echo "<option value='{$row->value}'" . (($row->value == $value) ? "SELECTED" : "") . " >" . str_replace("Department of ", "", $row->key) . "</option>"; |
} | } |
echo" </select>"; | echo" </select>"; |
} else { | } else { |
echo "<label>$key</label><input class='input-text' type='text' id='$key' name='$key' value='$value'/>"; | echo "<label>$key</label><input class='input-text' type='text' id='$key' name='$key' value='$value'/>"; |
if ((strpos($key, "URL") > 0 || $key == 'website') && $value != "") { | if ((strpos($key, "URL") > 0 || $key == 'website') && $value != "") { |
echo "<a href='$value'>view</a>"; | echo "<a ".($key == 'website' ? 'itemprop="url"':'')." href='$value'>view</a>"; |
} | } |
if ($key == 'abn') { | if ($key == 'abn') { |
echo "<a href='http://www.abr.business.gov.au/SearchByAbn.aspx?SearchText=$value'>view abn</a>"; | echo "<a href='http://www.abr.business.gov.au/SearchByAbn.aspx?SearchText=$value'>view abn</a>"; |
} | } |
} | } |
} | } |
} | } |
// | // |
} | } |
function addDefaultFields($row) { | function addDefaultFields($row) { |
global $schemas; | global $schemas; |
$defaultFields = array_keys($schemas['agency']['properties']); | $defaultFields = array_keys($schemas['agency']['properties']); |
foreach ($defaultFields as $defaultField) { | foreach ($defaultFields as $defaultField) { |
if (!isset($row[$defaultField])) { | if (!isset($row[$defaultField])) { |
if ($schemas['agency']['properties'][$defaultField]['type'] == "string") { | if ($schemas['agency']['properties'][$defaultField]['type'] == "string") { |
$row[$defaultField] = ""; | $row[$defaultField] = ""; |
} | } |
if ($schemas['agency']['properties'][$defaultField]['type'] == "array") { | if ($schemas['agency']['properties'][$defaultField]['type'] == "array") { |
$row[$defaultField] = Array(""); | $row[$defaultField] = Array(""); |
} | } |
} else if ($schemas['agency']['properties'][$defaultField]['type'] == "array") { | } else if ($schemas['agency']['properties'][$defaultField]['type'] == "array") { |
if (is_array($row[$defaultField])) { | if (is_array($row[$defaultField])) { |
$row[$defaultField][] = ""; | $row[$defaultField][] = ""; |
$row[$defaultField][] = ""; | $row[$defaultField][] = ""; |
$row[$defaultField][] = ""; | $row[$defaultField][] = ""; |
} else { | } else { |
$value = $row[$defaultField]; | $value = $row[$defaultField]; |
$row[$defaultField] = Array($value); | $row[$defaultField] = Array($value); |
$row[$defaultField][] = ""; | $row[$defaultField][] = ""; |
$row[$defaultField][] = ""; | $row[$defaultField][] = ""; |
} | } |
} | } |
} | } |
return $row; | return $row; |
} | } |
$db = $server->get_db('disclosr-agencies'); | $db = $server->get_db('disclosr-agencies'); |
if (isset($_REQUEST['id'])) { | if (isset($_REQUEST['id'])) { |
//get an agency record as json/html, search by name/abn/id | //get an agency record as json/html, search by name/abn/id |
// by name = startkey="Ham"&endkey="Ham\ufff0" | // by name = startkey="Ham"&endkey="Ham\ufff0" |
// edit? | // edit? |
$obj = $db->get($_REQUEST['id']); | $obj = $db->get($_REQUEST['id']); |
include_header($obj->name); | |
//print_r($row); | //print_r($row); |
if (sizeof($_POST) > 0) { | if (sizeof($_POST) > 0) { |
//print_r($_POST); | //print_r($_POST); |
foreach ($_POST as $postkey => $postvalue) { | foreach ($_POST as $postkey => $postvalue) { |
if ($postvalue == "") { | if ($postvalue == "") { |
unset($_POST[$postkey]); | unset($_POST[$postkey]); |
} | } |
if (is_array($postvalue)) { | if (is_array($postvalue)) { |
if (count($postvalue) == 1 && $postvalue[0] == "") { | if (count($postvalue) == 1 && $postvalue[0] == "") { |
unset($_POST[$postkey]); | unset($_POST[$postkey]); |
} else { | } else { |
foreach ($_POST[$postkey] as $key => &$value) { | foreach ($_POST[$postkey] as $key => &$value) { |
if ($value == "") { | if ($value == "") { |
unset($_POST[$postkey][$key]); | unset($_POST[$postkey][$key]); |
} | } |
} | } |
} | } |
} | } |
} | } |
if (isset($_POST['_id']) && $db->get_rev($_POST['_id']) == $_POST['_rev']) { | if (isset($_POST['_id']) && $db->get_rev($_POST['_id']) == $_POST['_rev']) { |
echo "Edited version was latest version, continue saving"; | echo "Edited version was latest version, continue saving"; |
$newdoc = $_POST; | $newdoc = $_POST; |
$newdoc['metadata']['lastModified'] = time(); | $newdoc['metadata']['lastModified'] = time(); |
$obj = $db->save($newdoc); | $obj = $db->save($newdoc); |
} else { | } else { |
echo "ALERT doc revised by someone else while editing. Document not saved."; | echo "ALERT doc revised by someone else while editing. Document not saved."; |
} | } |
} | } |
$mode = "edit"; | $mode = "view"; |
$rowArray = object_to_array($obj); | $rowArray = object_to_array($obj); |
ksort($rowArray); | ksort($rowArray); |
if ($mode == "edit") { | if ($mode == "edit") { |
$row = addDefaultFields($rowArray); | $row = addDefaultFields($rowArray); |
} else { | } else { |
$row = $rowArray; | $row = $rowArray; |
} | } |
if ($mode == "view") { | if ($mode == "view") { |
echo '<div typeof="schema:GovernmentOrganisation" about="#' . $row['_id'] . '"><table width="100%">'; | echo '<div itemscope itemtype="http://schema.org/GovernmentOrganization" typeof="schema:GovernmentOrganization" about="#' . $row['_id'] . '"><table width="100%">'; |
echo '<tr> <td colspan="2"><h3>' . $row['name'] . "</h3></td></tr>"; | echo '<tr> <td colspan="2"><h3 itemprop="name">' . $row['name'] . "</h3></td></tr>"; |
echo "<tr><th>Field Name</th><th>Field Value</th></tr>"; | echo "<tr><th>Field Name</th><th>Field Value</th></tr>"; |
} | } |
if ($mode == "edit") { | if ($mode == "edit") { |
?> | ?> |
<input id="addfield" type="button" value="Add Field"/> | <input id="addfield" type="button" value="Add Field"/> |
<script> | <script> |
window.onload = function() { | window.onload = function() { |
$(document).ready(function() { | $(document).ready(function() { |
// put all your jQuery goodness in here. | // put all your jQuery goodness in here. |
// http://charlie.griefer.com/blog/2009/09/17/jquery-dynamically-adding-form-elements/ | // http://charlie.griefer.com/blog/2009/09/17/jquery-dynamically-adding-form-elements/ |
$('#addfield').click(function() { | $('#addfield').click(function() { |
var field_name=window.prompt("fieldname?",""); | var field_name=window.prompt("fieldname?",""); |
if (field_name !="") { | if (field_name !="") { |
$('#submitbutton').before($('<span></span>') | $('#submitbutton').before($('<span></span>') |
.append("<label>"+field_name+"</label>") | .append("<label>"+field_name+"</label>") |
.append("<input class='input-text' type='text' id='"+field_name+"' name='"+field_name+"'/>") | .append("<input class='input-text' type='text' id='"+field_name+"' name='"+field_name+"'/>") |
); | ); |
} | } |
}); | }); |
}); | }); |
}; | }; |
</script> | </script> |
<form id="editform" class="nice" method="post"> | <form id="editform" class="nice" method="post"> |
<?php | <?php |
} | } |
foreach ($row as $key => $value) { | foreach ($row as $key => $value) { |
echo displayValue($key, $value, $mode); | echo displayValue($key, $value, $mode); |
} | } |
if ($mode == "view") { | if ($mode == "view") { |
echo "</table></div>"; | echo "</table></div>"; |
} | } |
if ($mode == "edit") { | if ($mode == "edit") { |
echo '<input id="submitbutton" type="submit"/></form>'; | echo '<input id="submitbutton" type="submit"/></form>'; |
} | } |
} else { | } else { |
// show all list | |
include_header('Agencies'); | |
try { | try { |
/* $rows = $db->get_view("app", "showNamesABNs")->rows; | /* $rows = $db->get_view("app", "showNamesABNs")->rows; |
//print_r($rows); | //print_r($rows); |
foreach ($rows as $row) { | foreach ($rows as $row) { |
// print_r($row); | // print_r($row); |
echo '<li><a href="getAgency.php?id=' . $row->key . '">' . | echo '<li><a href="getAgency.php?id=' . $row->key . '">' . |
(isset($row->value->name) && $row->value->name != "" ? $row->value->name : "NO NAME " . $row->value->abn) | (isset($row->value->name) && $row->value->name != "" ? $row->value->name : "NO NAME " . $row->value->abn) |
. '</a></li>'; | . '</a></li>'; |
} */ | } */ |
$rows = $db->get_view("app", "byCanonicalName")->rows; | $rows = $db->get_view("app", "byCanonicalName")->rows; |
//print_r($rows); | //print_r($rows); |
echo '<ul>'; | echo '<ul>'; |
foreach ($rows as $row) { | foreach ($rows as $row) { |
// print_r($row); | // print_r($row); |
echo '<li typeof="schema:GovernmentOrganisation foaf:Organization" about="getAgency.php?id=' . $row->value->_id . '"> | echo '<li itemscope itemtype="http://schema.org/GovernmentOrganization" typeof="schema:GovernmentOrganization foaf:Organization" about="getAgency.php?id=' . $row->value->_id . '"> |
<a href="getAgency.php?id=' . $row->value->_id . '" rel="schema:url foaf:page" property="schema:name foaf:name">' . | <a href="getAgency.php?id=' . $row->value->_id . '" rel="schema:url foaf:page" property="schema:name foaf:name" itemprop="url"><span itemprop="name">' . |
$row->value->name | $row->value->name |
. '</a></li>'; | . '</span></a></li>'; |
} | } |
echo "</ul>"; | echo "</ul>"; |
} catch (SetteeRestClientException $e) { | } catch (SetteeRestClientException $e) { |
setteErrorHandler($e); | setteErrorHandler($e); |
} | } |
} | } |
include_footer(); | include_footer(); |
?> | ?> |
google-site-verification: google676a414ad086cefb.html | |
<?php | <?php |
date_default_timezone_set("Australia/Sydney"); | date_default_timezone_set("Australia/Sydney"); |
$basePath = ""; | $basePath = ""; |
if (strstr($_SERVER['PHP_SELF'], "alaveteli/") | if (strstr($_SERVER['PHP_SELF'], "alaveteli/") |
|| strstr($_SERVER['PHP_SELF'], "admin/") | || strstr($_SERVER['PHP_SELF'], "admin/") |
|| strstr($_SERVER['PHP_SELF'], "lib/") | || strstr($_SERVER['PHP_SELF'], "lib/") |
|| strstr($_SERVER['PHP_SELF'], "include/")) | || strstr($_SERVER['PHP_SELF'], "include/")) |
$basePath = "../"; | $basePath = "../"; |
include_once ('couchdb.inc.php'); | include_once ('couchdb.inc.php'); |
include_once ('template.inc.php'); | include_once ('template.inc.php'); |
require_once $basePath.'lib/Requests/library/Requests.php'; | require_once $basePath.'lib/Requests/library/Requests.php'; |
Requests::register_autoloader(); | Requests::register_autoloader(); |
# Convert a stdClass to an Array. http://www.php.net/manual/en/language.types.object.php#102735 | # Convert a stdClass to an Array. http://www.php.net/manual/en/language.types.object.php#102735 |
function object_to_array(stdClass $Class) { | function object_to_array(stdClass $Class) { |
# Typecast to (array) automatically converts stdClass -> array. | # Typecast to (array) automatically converts stdClass -> array. |
$Class = (array) $Class; | $Class = (array) $Class; |
# Iterate through the former properties looking for any stdClass properties. | # Iterate through the former properties looking for any stdClass properties. |
# Recursively apply (array). | # Recursively apply (array). |
foreach ($Class as $key => $value) { | foreach ($Class as $key => $value) { |
if (is_object($value) && get_class($value) === 'stdClass') { | if (is_object($value) && get_class($value) === 'stdClass') { |
$Class[$key] = object_to_array($value); | $Class[$key] = object_to_array($value); |
} | } |
} | } |
return $Class; | return $Class; |
} | } |
# Convert an Array to stdClass. http://www.php.net/manual/en/language.types.object.php#102735 | # Convert an Array to stdClass. http://www.php.net/manual/en/language.types.object.php#102735 |
function array_to_object(array $array) { | function array_to_object(array $array) { |
# Iterate through our array looking for array values. | # Iterate through our array looking for array values. |
# If found recurvisely call itself. | # If found recurvisely call itself. |
foreach ($array as $key => $value) { | foreach ($array as $key => $value) { |
if (is_array($value)) { | if (is_array($value)) { |
$array[$key] = array_to_object($value); | $array[$key] = array_to_object($value); |
} | } |
} | } |
# Typecast to (object) will automatically convert array -> stdClass | # Typecast to (object) will automatically convert array -> stdClass |
return (object) $array; | return (object) $array; |
} | } |
function dept_to_portfolio($deptName) { | function dept_to_portfolio($deptName) { |
return trim(str_replace("Department of", "", str_replace("Department of the", "Department of", $deptName))); | return trim(str_replace("Department of", "", str_replace("Department of the", "Department of", $deptName))); |
} | } |
function phrase_to_tag ($phrase) { | function phrase_to_tag ($phrase) { |
return str_replace(" ","_",str_replace("'","",str_replace(",","",strtolower($phrase)))); | return str_replace(" ","_",str_replace("'","",str_replace(",","",strtolower($phrase)))); |
} | } |
function local_url() { | |
return "http://" . $_SERVER['HTTP_HOST'] . rtrim(dirname($_SERVER['PHP_SELF']), '/\\') . "/"; | |
} | |
function GetDomain($url) | function GetDomain($url) |
{ | { |
$nowww = ereg_replace('www\.','',$url); | $nowww = ereg_replace('www\.','',$url); |
$domain = parse_url($nowww); | $domain = parse_url($nowww); |
if(!empty($domain["host"])) | if(!empty($domain["host"])) |
{ | { |
return $domain["host"]; | return $domain["host"]; |
} else | } else |
{ | { |
return $domain["path"]; | return $domain["path"]; |
} | } |
} | } |
<?php | <?php |
include $basePath . "schemas/schemas.inc.php"; | include $basePath . "schemas/schemas.inc.php"; |
require ($basePath . 'couchdb/settee/src/settee.php'); | require ($basePath . 'couchdb/settee/src/settee.php'); |
function createDocumentsDesignDoc() { | function createDocumentsDesignDoc() { |
/*"views": { | /* "views": { |
"web_server": { | "web_server": { |
"map": "function(doc) {\n emit(doc.web_server, 1);\n}", | "map": "function(doc) {\n emit(doc.web_server, 1);\n}", |
"reduce": "function (key, values, rereduce) {\n return sum(values);\n}" | "reduce": "function (key, values, rereduce) {\n return sum(values);\n}" |
}, | }, |
"byAgency": { | "byAgency": { |
"map": "function(doc) {\n emit(doc.agencyID, 1);\n}", | "map": "function(doc) {\n emit(doc.agencyID, 1);\n}", |
"reduce": "function (key, values, rereduce) {\n return sum(values);\n}" | "reduce": "function (key, values, rereduce) {\n return sum(values);\n}" |
}, | }, |
"byURL": { | "byURL": { |
"map": "function(doc) {\n emit(doc.url, doc);\n}" | "map": "function(doc) {\n emit(doc.url, doc);\n}" |
}, | }, |
"agency": { | "agency": { |
"map": "function(doc) {\n emit(doc.agencyID, doc);\n}" | "map": "function(doc) {\n emit(doc.agencyID, doc);\n}" |
}, | }, |
"byWebServer": { | "byWebServer": { |
"map": "function(doc) {\n emit(doc.web_server, doc);\n}" | "map": "function(doc) {\n emit(doc.web_server, doc);\n}" |
}, | }, |
"getValidationRequired": { | "getValidationRequired": { |
"map": "function(doc) {\nif (doc.mime_type == \"text/html\" \n&& typeof(doc.validation) == \"undefined\") {\n emit(doc._id, doc._attachments);\n}\n}" | "map": "function(doc) {\nif (doc.mime_type == \"text/html\" \n&& typeof(doc.validation) == \"undefined\") {\n emit(doc._id, doc._attachments);\n}\n}" |
} | } |
}*/ | } */ |
} | } |
function createAgencyDesignDoc() { | function createAgencyDesignDoc() { |
global $db; | global $db; |
$obj = new stdClass(); | $obj = new stdClass(); |
$obj->_id = "_design/" . urlencode("app"); | $obj->_id = "_design/" . urlencode("app"); |
$obj->language = "javascript"; | $obj->language = "javascript"; |
$obj->views->all->map = "function(doc) { emit(doc._id, doc); };"; | $obj->views->all->map = "function(doc) { emit(doc._id, doc); };"; |
$obj->views->byABN->map = "function(doc) { emit(doc.abn, doc); };"; | $obj->views->byABN->map = "function(doc) { emit(doc.abn, doc); };"; |
$obj->views->byCanonicalName->map = "function(doc) { | $obj->views->byCanonicalName->map = "function(doc) { |
if (doc.parentOrg || doc.orgType == 'FMA-DepartmentOfState') { | if (doc.parentOrg || doc.orgType == 'FMA-DepartmentOfState') { |
emit(doc.name, doc); | emit(doc.name, doc); |
} | } |
};"; | };"; |
$obj->views->byDeptStateName->map = "function(doc) { | $obj->views->byDeptStateName->map = "function(doc) { |
if (doc.orgType == 'FMA-DepartmentOfState') { | if (doc.orgType == 'FMA-DepartmentOfState') { |
emit(doc.name, doc._id); | emit(doc.name, doc._id); |
} | } |
};"; | };"; |
$obj->views->parentOrgs->map = "function(doc) { | $obj->views->parentOrgs->map = "function(doc) { |
if (doc.parentOrg) { | if (doc.parentOrg) { |
emit(doc._id, doc.parentOrg); | emit(doc._id, doc.parentOrg); |
} | } |
};"; | };"; |
$obj->views->byName->map = 'function(doc) { | $obj->views->byName->map = 'function(doc) { |
if (typeof(doc["status"]) == "undefined" || doc["status"] != "suspended") { | if (typeof(doc["status"]) == "undefined" || doc["status"] != "suspended") { |
emit(doc.name, doc._id); | emit(doc.name, doc._id); |
if (typeof(doc.shortName) != "undefined" && doc.shortName != doc.name) { | if (typeof(doc.shortName) != "undefined" && doc.shortName != doc.name) { |
emit(doc.shortName, doc._id); | emit(doc.shortName, doc._id); |
} | } |
for (name in doc.otherNames) { | for (name in doc.otherNames) { |
if (doc.otherNames[name] != "" && doc.otherNames[name] != doc.name) { | if (doc.otherNames[name] != "" && doc.otherNames[name] != doc.name) { |
emit(doc.otherNames[name], doc._id); | emit(doc.otherNames[name], doc._id); |
} | } |
} | } |
for (name in doc.foiBodies) { | for (name in doc.foiBodies) { |
if (doc.foiBodies[name] != "" && doc.foiBodies[name] != doc.name) { | if (doc.foiBodies[name] != "" && doc.foiBodies[name] != doc.name) { |
emit(doc.foiBodies[name], doc._id); | emit(doc.foiBodies[name], doc._id); |
} | } |
} | } |
} | } |
};'; | };'; |
$obj->views->foiEmails->map = "function(doc) { | $obj->views->foiEmails->map = "function(doc) { |
emit(doc._id, doc.foiEmail); | emit(doc._id, doc.foiEmail); |
};"; | };"; |
$obj->views->byLastModified->map = "function(doc) { emit(doc.metadata.lastModified, doc); }"; | $obj->views->byLastModified->map = "function(doc) { emit(doc.metadata.lastModified, doc); }"; |
$obj->views->getActive->map = 'function(doc) { if (doc.status == "active") { emit(doc._id, doc); } };'; | $obj->views->getActive->map = 'function(doc) { if (doc.status == "active") { emit(doc._id, doc); } };'; |
$obj->views->getSuspended->map = 'function(doc) { if (doc.status == "suspended") { emit(doc._id, doc); } };'; | $obj->views->getSuspended->map = 'function(doc) { if (doc.status == "suspended") { emit(doc._id, doc); } };'; |
$obj->views->getScrapeRequired->map = "function(doc) { | $obj->views->getScrapeRequired->map = "function(doc) { |
var lastScrape = Date.parse(doc.metadata.lastScraped); | var lastScrape = Date.parse(doc.metadata.lastScraped); |
var today = new Date(); | var today = new Date(); |
if (!lastScrape || lastScrape.getTime() + 1000 != today.getTime()) { | if (!lastScrape || lastScrape.getTime() + 1000 != today.getTime()) { |
emit(doc._id, doc); | emit(doc._id, doc); |
} | } |
};"; | };"; |
$obj->views->showNamesABNs->map = "function(doc) { emit(doc._id, {name: doc.name, abn: doc.abn}); };"; | $obj->views->showNamesABNs->map = "function(doc) { emit(doc._id, {name: doc.name, abn: doc.abn}); };"; |
$obj->views->getConflicts->map = "function(doc) { | $obj->views->getConflicts->map = "function(doc) { |
if (doc._conflicts) { | if (doc._conflicts) { |
emit(null, [doc._rev].concat(doc._conflicts)); | emit(null, [doc._rev].concat(doc._conflicts)); |
} | } |
}"; | }"; |
// http://stackoverflow.com/questions/646628/javascript-startswith | // http://stackoverflow.com/questions/646628/javascript-startswith |
$obj->views->score->map = 'if(!String.prototype.startsWith){ | $obj->views->score->map = 'if(!String.prototype.startsWith){ |
String.prototype.startsWith = function (str) { | String.prototype.startsWith = function (str) { |
return !this.indexOf(str); | return !this.indexOf(str); |
} | } |
} | } |
function(doc) { | function(doc) { |
count = 0; | count = 0; |
if (doc["status"] != "suspended") { | if (doc["status"] != "suspended") { |
for(var propName in doc) { | for(var propName in doc) { |
if(typeof(doc[propName]) != "undefined" && doc[propName] != "") { | if(typeof(doc[propName]) != "undefined" && doc[propName] != "") { |
count++; | count++; |
} | } |
} | } |
portfolio = doc.parentOrg; | portfolio = doc.parentOrg; |
if (doc.orgType == "FMA-DepartmentOfState") { | if (doc.orgType == "FMA-DepartmentOfState") { |
portfolio = doc._id; | portfolio = doc._id; |
} | } |
if (doc.orgType == "Court-Commonwealth" || doc.orgType == "FMA-DepartmentOfParliament") { | if (doc.orgType == "Court-Commonwealth" || doc.orgType == "FMA-DepartmentOfParliament") { |
portfolio = doc.orgType; | portfolio = doc.orgType; |
} | } |
emit(count+doc._id, {id:doc._id, name: doc.name, score:count, orgType: doc.orgType, portfolio:portfolio}); | emit(count+doc._id, {id:doc._id, name: doc.name, score:count, orgType: doc.orgType, portfolio:portfolio}); |
} | } |
}'; | }'; |
$obj->views->scoreHas->map = 'if(!String.prototype.startsWith){ | $obj->views->scoreHas->map = 'if(!String.prototype.startsWith){ |
String.prototype.startsWith = function (str) { | String.prototype.startsWith = function (str) { |
return !this.indexOf(str); | return !this.indexOf(str); |
} | } |
} | } |
if(!String.prototype.endsWith){ | if(!String.prototype.endsWith){ |
String.prototype.endsWith = function(suffix) { | String.prototype.endsWith = function(suffix) { |
return this.indexOf(suffix, this.length - suffix.length) !== -1; | return this.indexOf(suffix, this.length - suffix.length) !== -1; |
}; | }; |
} | } |
function(doc) { | function(doc) { |
if (typeof(doc["status"]) == "undefined" || doc["status"] != "suspended") { | if (typeof(doc["status"]) == "undefined" || doc["status"] != "suspended") { |
for(var propName in doc) { | for(var propName in doc) { |
if(typeof(doc[propName]) != "undefined" && (propName.startsWith("has") || propName.endsWith("URL"))) { | if(typeof(doc[propName]) != "undefined" && (propName.startsWith("has") || propName.endsWith("URL"))) { |
emit(propName, 1); | emit(propName, 1); |
} | } |
} | } |
emit("total", 1); | emit("total", 1); |
} | } |
}'; | }'; |
$obj->views->scoreHas->reduce = 'function (key, values, rereduce) { | $obj->views->scoreHas->reduce = 'function (key, values, rereduce) { |
return sum(values); | return sum(values); |
}'; | }'; |
$obj->views->fieldNames->map = ' | $obj->views->fieldNames->map = ' |
function(doc) { | function(doc) { |
for(var propName in doc) { | for(var propName in doc) { |
emit(propName, doc._id); | emit(propName, doc._id); |
} | } |
}'; | }'; |
$obj->views->fieldNames->reduce = 'function (key, values, rereduce) { | $obj->views->fieldNames->reduce = 'function (key, values, rereduce) { |
return values.length; | return values.length; |
}'; | }'; |
// allow safe updates (even if slightly slower due to extra: rev-detection check). | // allow safe updates (even if slightly slower due to extra: rev-detection check). |
return $db->save($obj, true); | return $db->save($obj, true); |
} | } |
if (php_uname('n') == "vanille") { | if (php_uname('n') == "vanille") { |
$serverAddr = 'http://192.168.178.21:5984/'; | $serverAddr = 'http://192.168.178.21:5984/'; |
} else | } else |
if (php_uname('n') == "KYUUBEY") { | if (php_uname('n') == "KYUUBEY") { |
$serverAddr = 'http://192.168.1.148:5984/'; | $serverAddr = 'http://192.168.1.148:5984/'; |
} else { | } else { |
$serverAddr = 'http://127.0.0.1:5984/'; | $serverAddr = 'http://127.0.0.1:5984/'; |
} | } |
$server = new SetteeServer($serverAddr); | $server = new SetteeServer($serverAddr); |
function setteErrorHandler($e) { | function setteErrorHandler($e) { |
echo $e->getMessage() . "<br>" . PHP_EOL; | echo $e->getMessage() . "<br>" . PHP_EOL; |
} | } |
<?php | <?php |
function include_header() { | function include_header($title) { |
global $basePath; | global $basePath; |
?> | ?> |
<!DOCTYPE html> | <!DOCTYPE html> |
<!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ --> | <!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ --> |
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]--> | <!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7" lang="en"> <![endif]--> |
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]--> | <!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8" lang="en"> <![endif]--> |
<!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]--> | <!--[if IE 8]> <html class="no-js lt-ie9" lang="en"> <![endif]--> |
<!--[if gt IE 8]><!--> <html lang="en"> <!--<![endif]--> | <!--[if gt IE 8]><!--> <html lang="en"> <!--<![endif]--> |
<head> | <head> |
<meta charset="utf-8" /> | <meta charset="utf-8" /> |
<!-- Set the viewport width to device width for mobile --> | <!-- Set the viewport width to device width for mobile --> |
<meta name="viewport" content="width=device-width" /> | <meta name="viewport" content="width=device-width" /> |
<title>Disclosr</title> | <title><?php echo $title; ?> - Disclosr</title> |
<!-- Included CSS Files --> | <!-- Included CSS Files --> |
<link rel="stylesheet" href="<?php echo $basePath ?>stylesheets/foundation.css"> | <link rel="stylesheet" href="<?php echo $basePath ?>stylesheets/foundation.css"> |
<link rel="stylesheet" href="<?php echo $basePath ?>stylesheets/app.css"> | <link rel="stylesheet" href="<?php echo $basePath ?>stylesheets/app.css"> |
<!--[if lt IE 9]> | <!--[if lt IE 9]> |
<link rel="stylesheet" href="<?php echo $basePath ?>stylesheets/ie.css"> | <link rel="stylesheet" href="<?php echo $basePath ?>stylesheets/ie.css"> |
<![endif]--> | <![endif]--> |
<!-- IE Fix for HTML5 Tags --> | <!-- IE Fix for HTML5 Tags --> |
<!--[if lt IE 9]> | <!--[if lt IE 9]> |
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script> | <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script> |
<![endif]--> | <![endif]--> |
</head> | </head> |
<body xmlns:schema="http://schema.org/" xmlns:foaf="http://xmlns.com/foaf/0.1/"> | <body xmlns:schema="http://schema.org/" xmlns:foaf="http://xmlns.com/foaf/0.1/"> |
<!-- navBar --> | <!-- navBar --> |
<div id="navbar" class="container"> | <div id="navbar" class="container"> |
<div class="row"> | <div class="row"> |
<div class="four columns"> | <div class="four columns"> |
<h1><a href="/">Disclosr</a></h1> | <h1><a href="/">Disclosr</a></h1> |
</div> | </div> |
<div class="eight columns hide-on-phones"> | <div class="eight columns hide-on-phones"> |
<strong class="right"> | <strong class="right"> |
<a href="getAgency.php">Agencies</a> | <a href="getAgency.php">Agencies</a> |
<a href="about.php">About/FAQ</a> | <a href="about.php">About/FAQ</a> |
</strong> | </strong> |
</div> | </div> |
</div> | </div> |
</div> | </div> |
<!-- /navBar --> | <!-- /navBar --> |
<!-- container --> | <!-- container --> |
<div class="container"> | <div class="container"> |
<?php } | <?php } |
function include_footer() { | function include_footer() { |
global $basePath; | global $basePath; |
?> | ?> |
</div> | </div> |
<!-- container --> | <!-- container --> |
<!-- Included JS Files --> | <!-- Included JS Files --> |
<script src="<?php echo $basePath; ?>javascripts/foundation.js"></script> | <script src="<?php echo $basePath; ?>javascripts/foundation.js"></script> |
<script src="<?php echo $basePath; ?>javascripts/app.js"></script> | <script src="<?php echo $basePath; ?>javascripts/app.js"></script> |
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script> | <script src="http://code.jquery.com/jquery-1.7.1.min.js"></script> |
<script type="text/javascript" src="javascripts/flotr2/flotr2.js"></script> | <script type="text/javascript" src="javascripts/flotr2/flotr2.js"></script> |
<?php | |
if (strpos($_SERVER['SERVER_NAME'], ".gs")) { | |
?> | |
<script type="text/javascript"> | |
var _gaq = _gaq || []; | |
_gaq.push(['_setAccount', 'UA-12341040-2']); | |
_gaq.push(['_trackPageview']); | |
(function() { | |
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true; | |
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js'; | |
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s); | |
})(); | |
</script> | |
</body> | </body> |
</html> | </html> |
<?php } | <?php } |
} | |
<?php | |
/* Redirect to a different page in the current directory that was requested */ | |
$host = $_SERVER['HTTP_HOST']; | |
$uri = rtrim(dirname($_SERVER['PHP_SELF']), '/\\'); | |
$extra = 'getAgency.php'; | |
header("Location: http://$host$uri/$extra"); | |
exit; | |
?> | |
/* sigmajs.org - an open-source light-weight JavaScript graph drawing library - Version: 0.1 - Author: Alexis Jacomy - License: MIT */ | // Define packages: |
var sigma={tools:{},classes:{},instances:{}}; | var sigma = {}; |
(function(){if(!Array.prototype.some)Array.prototype.some=function(i,n){var g=this.length;if("function"!=typeof i)throw new TypeError;for(var j=0;j<g;j++)if(j in this&&i.call(n,this[j],j,this))return!0;return!1};if(!Array.prototype.forEach)Array.prototype.forEach=function(i,n){var g=this.length;if("function"!=typeof i)throw new TypeError;for(var j=0;j<g;j++)j in this&&i.call(n,this[j],j,this)};if(!Array.prototype.map)Array.prototype.map=function(i,n){var g=this.length;if("function"!=typeof i)throw new TypeError; | sigma.tools = {}; |
for(var j=Array(g),m=0;m<g;m++)m in this&&(j[m]=i.call(n,this[m],m,this));return j};if(!Array.prototype.filter)Array.prototype.filter=function(i,n){var g=this.length;if("function"!=typeof i)throw new TypeError;for(var j=[],m=0;m<g;m++)if(m in this){var t=this[m];i.call(n,t,m,this)&&j.push(t)}return j};if(!Object.keys)Object.keys=function(){var i=Object.prototype.hasOwnProperty,n=!{toString:null}.propertyIsEnumerable("toString"),g="toString,toLocaleString,valueOf,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,constructor".split(","), | sigma.classes = {}; |
j=g.length;return function(m){if("object"!==typeof m&&"function"!==typeof m||null===m)throw new TypeError("Object.keys called on non-object");var t=[],p;for(p in m)i.call(m,p)&&t.push(p);if(n)for(p=0;p<j;p++)i.call(m,g[p])&&t.push(g[p]);return t}}()})();sigma.classes.Cascade=function(){this.p={};this.config=function(i,n){if("string"==typeof i&&void 0==n)return this.p[i];var g="object"==typeof i&&void 0==n?i:{};"string"==typeof i&&(g[i]=n);for(var j in g)void 0!=this.p[j]&&(this.p[j]=g[j]);return this}}; | sigma.instances = {}; |
sigma.classes.EventDispatcher=function(){var i={},n=this;this.one=function(g,j){if(!j||!g)return n;("string"==typeof g?g.split(" "):g).forEach(function(g){i[g]||(i[g]=[]);i[g].push({h:j,one:!0})});return n};this.bind=function(g,j){if(!j||!g)return n;("string"==typeof g?g.split(" "):g).forEach(function(g){i[g]||(i[g]=[]);i[g].push({h:j,one:!1})});return n};this.unbind=function(g,j){g||(i={});var m="string"==typeof g?g.split(" "):g;j?m.forEach(function(g){i[g]&&(i[g]=i[g].filter(function(g){return g.h!= | |
j}));i[g]&&0==i[g].length&&delete i[g]}):m.forEach(function(g){delete i[g]});return n};this.dispatch=function(g,j){i[g]&&(i[g].forEach(function(i){i.h({type:g,content:j,target:n})}),i[g]=i[g].filter(function(g){return!g.one}));return n}}; | // Adding Array helpers, if not present yet: |
(function(){var i;function n(){function b(a){return{x:a.x,y:a.y,size:a.size,degree:a.degree,displayX:a.displayX,displayY:a.displayY,displaySize:a.displaySize,label:a.label,id:a.id,color:a.color,fixed:a.fixed,active:a.active,hidden:a.hidden,attr:a.attr}}function h(a){return{source:a.source.id,target:a.target.id,size:a.size,type:a.type,weight:a.weight,displaySize:a.displaySize,label:a.label,id:a.id,attr:a.attr,color:a.color}}function e(){d.nodes=[];d.nodesIndex={};d.edges=[];d.edgesIndex={};return d} | (function() { |
sigma.classes.Cascade.call(this);sigma.classes.EventDispatcher.call(this);var d=this;this.p={minNodeSize:0,maxNodeSize:0,minEdgeSize:0,maxEdgeSize:0,scalingMode:"inside",nodesPowRatio:0.5,edgesPowRatio:0};this.borders={};e();this.addNode=function(a,b){if(d.nodesIndex[a])throw Error('Node "'+a+'" already exists.');var b=b||{},c={x:0,y:0,size:1,degree:0,fixed:!1,active:!1,hidden:!1,label:a.toString(),id:a.toString(),attr:{}},e;for(e in b)switch(e){case "id":break;case "x":case "y":case "size":c[e]= | if (!Array.prototype.some) { |
+b[e];break;case "fixed":case "active":case "hidden":c[e]=!!b[e];break;case "color":case "label":c[e]=b[e];break;default:c.attr[e]=b[e]}d.nodes.push(c);d.nodesIndex[a.toString()]=c;return d};this.addEdge=function(a,b,c,e){if(d.edgesIndex[a])throw Error('Edge "'+a+'" already exists.');if(!d.nodesIndex[b])throw Error("Edge's source \""+b+'" does not exist yet.');if(!d.nodesIndex[c])throw Error("Edge's target \""+c+'" does not exist yet.');e=e||{};b={source:d.nodesIndex[b],target:d.nodesIndex[c],size:1, | Array.prototype.some = function(fun /*, thisp*/) { |
weight:1,displaySize:0.5,label:a.toString(),id:a.toString(),attr:{}};b.source.degree++;b.target.degree++;for(var k in e)switch(k){case "id":case "source":case "target":break;case "size":b[k]=+e[k];break;case "color":b[k]=e[k].toString();break;case "type":b[k]=e[k].toString();break;case "label":b[k]=e[k];break;default:b.attr[k]=e[k]}d.edges.push(b);d.edgesIndex[a.toString()]=b;return d};this.dropNode=function(a){((a instanceof Array?a:[a])||[]).forEach(function(a){if(d.nodesIndex[a]){var c=null;d.nodes.some(function(b, | var len = this.length; |
d){return b.id==a?(c=d,!0):!1});null!=c&&d.nodes.splice(c,1);delete d.nodesIndex[a];d.edges=d.edges.filter(function(c){return c.source.id==a||c.target.id==a?(delete d.edgesIndex[c.id],!1):!0})}else sigma.log('Node "'+a+'" does not exist.')});return d};this.dropEdge=function(a){((a instanceof Array?a:[a])||[]).forEach(function(a){if(d.edgesIndex[a]){var c=null;d.edges.some(function(b,d){return b.id==a?(c=d,!0):!1});null!=c&&d.edges.splice(c,1);delete d.edgesIndex[a]}else sigma.log('Edge "'+a+'" does not exist.')}); | if (typeof fun != 'function') { |
return d};this.iterEdges=function(a,b){var c=b?b.map(function(a){return d.edgesIndex[a]}):d.edges,e=c.map(h);e.forEach(a);c.forEach(function(a,c){var b=e[c],l;for(l in b)switch(l){case "id":case "weight":case "displaySize":break;case "size":a[l]=+b[l];break;case "source":case "target":a[l]=d.nodesIndex[l]||a[l];break;case "color":case "label":case "type":a[l]=(b[l]||"").toString();break;default:a.attr[l]=b[l]}});return d};this.iterNodes=function(a,e){var c=e?e.map(function(a){return d.nodesIndex[a]}): | throw new TypeError(); |
d.nodes,h=c.map(b);h.forEach(a);c.forEach(function(a,c){var b=h[c],d;for(d in b)switch(d){case "id":case "attr":case "degree":case "displayX":case "displayY":case "displaySize":break;case "x":case "y":case "size":a[d]=+b[d];break;case "fixed":case "active":case "hidden":a[d]=!!b[d];break;case "color":case "label":a[d]=b[d].toString();break;default:a.attr[d]=b[d]}});return d};this.getEdges=function(a){var b=((a instanceof Array?a:[a])||[]).map(function(a){return h(d.edgesIndex[a])});return a instanceof | } |
Array?b:b[0]};this.getNodes=function(a){var e=((a instanceof Array?a:[a])||[]).map(function(a){return b(d.nodesIndex[a])});return a instanceof Array?e:e[0]};this.empty=e;this.rescale=function(a,b,c,e){var k=0,f=0;c&&d.nodes.forEach(function(a){f=Math.max(a.size,f)});e&&d.edges.forEach(function(a){k=Math.max(a.size,k)});var f=f||1,k=k||1,h,g,s,q;c&&d.nodes.forEach(function(a){g=Math.max(a.x,g||a.x);h=Math.min(a.x,h||a.x);q=Math.max(a.y,q||a.y);s=Math.min(a.y,s||a.y)});var z="outside"==d.p.scalingMode? | |
Math.max(a/Math.max(g-h,1),b/Math.max(q-s,1)):Math.min(a/Math.max(g-h,1),b/Math.max(q-s,1)),i,j;!d.p.maxNodeSize&&!d.p.minNodeSize?(i=1,j=0):d.p.maxNodeSize==d.p.minNodeSize?(i=0,j=d.p.maxNodeSize):(i=(d.p.maxNodeSize-d.p.minNodeSize)/f,j=d.p.minNodeSize);var m,w;!d.p.maxEdgeSize&&!d.p.minEdgeSize?(m=1,w=0):(m=d.p.maxEdgeSize==d.p.minEdgeSize?0:(d.p.maxEdgeSize-d.p.minEdgeSize)/k,w=d.p.minEdgeSize);c&&d.nodes.forEach(function(c){c.displaySize=c.size*i+j;if(!c.fixed)c.displayX=(c.x-(g+h)/2)*z+a/2, | var thisp = arguments[1]; |
c.displayY=(c.y-(q+s)/2)*z+b/2});e&&d.edges.forEach(function(a){a.displaySize=a.size*m+w});return d};this.translate=function(a,b,c,e,k){var f=Math.pow(c,d.p.nodesPowRatio);e&&d.nodes.forEach(function(d){if(!d.fixed)d.displayX=d.displayX*c+a,d.displayY=d.displayY*c+b;d.displaySize*=f});f=Math.pow(c,d.p.edgesPowRatio);k&&d.edges.forEach(function(a){a.displaySize*=f});return d};this.setBorders=function(){d.borders={};d.nodes.forEach(function(a){d.borders.minX=Math.min(void 0==d.borders.minX?a.displayX- | for (var i = 0; i < len; i++) { |
a.displaySize:d.borders.minX,a.displayX-a.displaySize);d.borders.maxX=Math.max(void 0==d.borders.maxX?a.displayX+a.displaySize:d.borders.maxX,a.displayX+a.displaySize);d.borders.minY=Math.min(void 0==d.borders.minY?a.displayY-a.displaySize:d.borders.minY,a.displayY-a.displaySize);d.borders.maxY=Math.max(void 0==d.borders.maxY?a.displayY-a.displaySize:d.borders.maxY,a.displayY-a.displaySize)})};this.checkHover=function(a,b){var c,e,k,f=[],h=[];d.nodes.forEach(function(d){if(d.hidden)d.hover=!1;else{c= | if (i in this && |
Math.abs(d.displayX-a);e=Math.abs(d.displayY-b);k=d.displaySize;var s=d.hover,q=c<k&&e<k&&Math.sqrt(c*c+e*e)<k;if(s&&!q)d.hover=!1,h.push(d.id);else if(q&&!s)d.hover=!0,f.push(d.id)}});f.length&&d.dispatch("overnodes",f);h.length&&d.dispatch("outnodes",h);return d}}function g(b,h){function e(){var a;a="<p>GLOBAL :</p>";for(var b in d.p.globalProbes)a+="<p>"+b+" : "+d.p.globalProbes[b]()+"</p>";a+="<br><p>LOCAL :</p>";for(b in d.p.localProbes)a+="<p>"+b+" : "+d.p.localProbes[b]()+"</p>";d.p.dom.innerHTML= | fun.call(thisp, this[i], i, this)) { |
a;return d}sigma.classes.Cascade.call(this);var d=this;this.instance=b;this.monitoring=!1;this.p={fps:40,dom:h,globalProbes:{"Time (ms)":sigma.chronos.getExecutionTime,Queue:sigma.chronos.getQueuedTasksCount,Tasks:sigma.chronos.getTasksCount,FPS:sigma.chronos.getFPS},localProbes:{"Nodes count":function(){return d.instance.graph.nodes.length},"Edges count":function(){return d.instance.graph.edges.length}}};this.activate=function(){if(!d.monitoring)d.monitoring=window.setInterval(e,1E3/d.p.fps);return d}; | return true; |
this.desactivate=function(){if(d.monitoring)window.clearInterval(d.monitoring),d.monitoring=null,d.p.dom.innerHTML="";return d}}function j(b){function h(b){if(a.p.mouseEnabled&&(e(a.mouseX,a.mouseY,a.ratio*(0<(void 0!=b.wheelDelta&&b.wheelDelta||void 0!=b.detail&&-b.detail)?a.p.zoomMultiply:1/a.p.zoomMultiply)),a.p.blockScroll))b.preventDefault?b.preventDefault():b.returnValue=!1}function e(b,c,e){if(!a.isMouseDown&&(window.clearInterval(a.interpolationID),n=void 0!=e,i=a.stageX,j=b,k=a.stageY,l= | } |
c,f=e||a.ratio,f=Math.min(Math.max(f,a.p.minRatio),a.p.maxRatio),u=a.p.directZooming?1-(n?a.p.zoomDelta:a.p.dragDelta):0,a.ratio!=f||a.stageX!=j||a.stageY!=l))d(),a.interpolationID=window.setInterval(d,50),a.dispatch("startinterpolate")}function d(){u+=n?a.p.zoomDelta:a.p.dragDelta;u=Math.min(u,1);var b=sigma.easing.quadratic.easeout(u),c=a.ratio;a.ratio=c*(1-b)+f*b;n?(a.stageX=j+(a.stageX-j)*a.ratio/c,a.stageY=l+(a.stageY-l)*a.ratio/c):(a.stageX=i*(1-b)+j*b,a.stageY=k*(1-b)+l*b);a.dispatch("interpolate"); | } |
if(1<=u)window.clearInterval(a.interpolationID),b=a.ratio,n?(a.ratio=f,a.stageX=j+(a.stageX-j)*a.ratio/b,a.stageY=l+(a.stageY-l)*a.ratio/b):(a.stageX=j,a.stageY=l),a.dispatch("stopinterpolate")}sigma.classes.Cascade.call(this);sigma.classes.EventDispatcher.call(this);var a=this;this.p={minRatio:1,maxRatio:32,marginRatio:1,zoomDelta:0.1,dragDelta:0.3,zoomMultiply:2,directZooming:!1,blockScroll:!0,inertia:1.1,mouseEnabled:!0};var g=0,c=0,i=0,k=0,f=1,j=0,l=0,s=0,q=0,z=0,m=0,u=0,n=!1;this.stageY=this.stageX= | |
0;this.ratio=1;this.mouseY=this.mouseX=0;this.isMouseDown=!1;b.addEventListener("DOMMouseScroll",h,!0);b.addEventListener("mousewheel",h,!0);b.addEventListener("mousemove",function(b){a.mouseX=void 0!=b.offsetX&&b.offsetX||void 0!=b.layerX&&b.layerX||void 0!=b.clientX&&b.clientX;a.mouseY=void 0!=b.offsetY&&b.offsetY||void 0!=b.layerY&&b.layerY||void 0!=b.clientY&&b.clientY;if(a.isMouseDown){var d=a.mouseX-g+i,f=a.mouseY-c+k;if(d!=a.stageX||f!=a.stageY)q=s,m=z,s=d,z=f,a.stageX=d,a.stageY=f,a.dispatch("drag")}a.dispatch("move"); | return false; |
b.preventDefault?b.preventDefault():b.returnValue=!1},!0);b.addEventListener("mousedown",function(b){if(a.p.mouseEnabled)a.isMouseDown=!0,a.dispatch("mousedown"),i=a.stageX,k=a.stageY,g=a.mouseX,c=a.mouseY,q=s=a.stageX,m=z=a.stageY,a.dispatch("startdrag"),b.preventDefault?b.preventDefault():b.returnValue=!1},!0);document.addEventListener("mouseup",function(b){if(a.p.mouseEnabled&&a.isMouseDown)a.isMouseDown=!1,a.dispatch("mouseup"),(i!=a.stageX||k!=a.stageY)&&e(a.stageX+a.p.inertia*(a.stageX-q),a.stageY+ | }; |
a.p.inertia*(a.stageY-m)),b.preventDefault?b.preventDefault():b.returnValue=!1},!0);this.checkBorders=function(){return a};this.interpolate=e}function m(b,h,e,d,a,g,c){function i(a){var b=d,c="fixed"==f.p.labelSize?f.p.defaultLabelSize:f.p.labelSizeRatio*a.displaySize;b.font=(f.p.hoverFontStyle||f.p.fontStyle||"")+" "+c+"px "+(f.p.hoverFont||f.p.font||"");b.fillStyle="node"==f.p.labelHoverBGColor?a.color||f.p.defaultNodeColor:f.p.defaultHoverLabelBGColor;b.beginPath();if(f.p.labelHoverShadow)b.shadowOffsetX= | } |
0,b.shadowOffsetY=0,b.shadowBlur=4,b.shadowColor=f.p.labelHoverShadowColor;sigma.tools.drawRoundRect(b,Math.round(a.displayX-c/2-2),Math.round(a.displayY-c/2-2),Math.round(b.measureText(a.label).width+1.5*a.displaySize+c/2+4),Math.round(c+4),Math.round(c/2+2),"left");b.closePath();b.fill();b.shadowOffsetX=0;b.shadowOffsetY=0;b.shadowBlur=0;b.beginPath();b.fillStyle="node"==f.p.nodeBorderColor?a.color||f.p.defaultNodeColor:f.p.defaultNodeBorderColor;b.arc(Math.round(a.displayX),Math.round(a.displayY), | |
a.displaySize+f.p.borderSize,0,2*Math.PI,!0);b.closePath();b.fill();b.beginPath();b.fillStyle="node"==f.p.nodeHoverColor?a.color||f.p.defaultNodeColor:f.p.defaultNodeHoverColor;b.arc(Math.round(a.displayX),Math.round(a.displayY),a.displaySize,0,2*Math.PI,!0);b.closePath();b.fill();b.fillStyle="node"==f.p.labelHoverColor?a.color||f.p.defaultNodeColor:f.p.defaultLabelHoverColor;b.fillText(a.label,Math.round(a.displayX+1.5*a.displaySize),Math.round(a.displayY+c/2-3));return f}function k(a){if(isNaN(a.x)|| | if (!Array.prototype.forEach) { |
isNaN(a.y))throw Error("A node's coordinate is not a number (id: "+a.id+")");return!a.hidden&&a.displayX+a.displaySize>-j/3&&a.displayX-a.displaySize<4*j/3&&a.displayY+a.displaySize>-l/3&&a.displayY-a.displaySize<4*l/3}sigma.classes.Cascade.call(this);var f=this;this.p={labelColor:"default",defaultLabelColor:"#000",labelHoverBGColor:"default",defaultHoverLabelBGColor:"#fff",labelHoverShadow:!0,labelHoverShadowColor:"#000",labelHoverColor:"default",defaultLabelHoverColor:"#000",labelActiveBGColor:"default", | Array.prototype.forEach = function(fun /*, thisp*/) { |
defaultActiveLabelBGColor:"#fff",labelActiveShadow:!0,labelActiveShadowColor:"#000",labelActiveColor:"default",defaultLabelActiveColor:"#000",labelSize:"fixed",defaultLabelSize:12,labelSizeRatio:2,labelThreshold:6,font:"Arial",hoverFont:"",activeFont:"",fontStyle:"",hoverFontStyle:"",activeFontStyle:"",edgeColor:"source",defaultEdgeColor:"#aaa",defaultEdgeType:"line",defaultNodeColor:"#aaa",nodeHoverColor:"node",defaultNodeHoverColor:"#fff",nodeActiveColor:"node",defaultNodeActiveColor:"#fff",borderSize:0, | var len = this.length; |
nodeBorderColor:"node",defaultNodeBorderColor:"#fff",edgesSpeed:200,nodesSpeed:200,labelsSpeed:200};var j=g,l=c;this.currentLabelIndex=this.currentNodeIndex=this.currentEdgeIndex=0;this.task_drawLabel=function(){for(var b=a.nodes.length,c=0;c++<f.p.labelsSpeed&&f.currentLabelIndex<b;)if(f.isOnScreen(a.nodes[f.currentLabelIndex])){var d=a.nodes[f.currentLabelIndex++],h=e;if(d.displaySize>=f.p.labelThreshold){var k="fixed"==f.p.labelSize?f.p.defaultLabelSize:f.p.labelSizeRatio*d.displaySize;h.font= | if (typeof fun != 'function') { |
f.p.fontStyle+k+"px "+f.p.font;h.fillStyle="node"==f.p.labelColor?d.color||f.p.defaultNodeColor:f.p.defaultLabelColor;h.fillText(d.label,Math.round(d.displayX+1.5*d.displaySize),Math.round(d.displayY+k/2-3))}}else f.currentLabelIndex++;return f.currentLabelIndex<b};this.task_drawEdge=function(){for(var b=a.edges.length,c,d,e=0;e++<f.p.edgesSpeed&&f.currentEdgeIndex<b;)if(c=a.edges[f.currentEdgeIndex].source,d=a.edges[f.currentEdgeIndex].target,c.hidden||d.hidden||!f.isOnScreen(c)&&!f.isOnScreen(d))f.currentEdgeIndex++; | throw new TypeError(); |
else{c=a.edges[f.currentEdgeIndex++];d=c.source.displayX;var k=c.source.displayY,g=c.target.displayX,i=c.target.displayY,j=c.color;if(!j)switch(f.p.edgeColor){case "source":j=c.source.color||f.p.defaultNodeColor;break;case "target":j=c.target.color||f.p.defaultNodeColor;break;default:j=f.p.defaultEdgeColor}var l=h;switch(c.type||f.p.defaultEdgeType){case "curve":l.strokeStyle=j;l.lineWidth=c.displaySize/3;l.beginPath();l.moveTo(d,k);l.quadraticCurveTo((d+g)/2+(i-k)/4,(k+i)/2+(d-g)/4,g,i);l.stroke(); | } |
break;default:l.strokeStyle=j,l.lineWidth=c.displaySize/3,l.beginPath(),l.moveTo(d,k),l.lineTo(g,i),l.stroke()}}return f.currentEdgeIndex<b};this.task_drawNode=function(){for(var c=a.nodes.length,d=0;d++<f.p.nodesSpeed&&f.currentNodeIndex<c;)if(f.isOnScreen(a.nodes[f.currentNodeIndex])){var e=a.nodes[f.currentNodeIndex++],k=Math.round(10*e.displaySize)/10,h=b;h.fillStyle=e.color;h.beginPath();h.arc(e.displayX,e.displayY,k,0,2*Math.PI,!0);h.closePath();h.fill();e.hover&&i(e)}else f.currentNodeIndex++; | |
return f.currentNodeIndex<c};this.drawActiveNode=function(a){var b=d;if(!k(a))return f;var c="fixed"==f.p.labelSize?f.p.defaultLabelSize:f.p.labelSizeRatio*a.displaySize;b.font=(f.p.activeFontStyle||f.p.fontStyle||"")+" "+c+"px "+(f.p.activeFont||f.p.font||"");b.fillStyle="node"==f.p.labelHoverBGColor?a.color||f.p.defaultNodeColor:f.p.defaultActiveLabelBGColor;b.beginPath();if(f.p.labelActiveShadow)b.shadowOffsetX=0,b.shadowOffsetY=0,b.shadowBlur=4,b.shadowColor=f.p.labelActiveShadowColor;sigma.tools.drawRoundRect(b, | var thisp = arguments[1]; |
Math.round(a.displayX-c/2-2),Math.round(a.displayY-c/2-2),Math.round(b.measureText(a.label).width+1.5*a.displaySize+c/2+4),Math.round(c+4),Math.round(c/2+2),"left");b.closePath();b.fill();b.shadowOffsetX=0;b.shadowOffsetY=0;b.shadowBlur=0;b.beginPath();b.fillStyle="node"==f.p.nodeBorderColor?a.color||f.p.defaultNodeColor:f.p.defaultNodeBorderColor;b.arc(Math.round(a.displayX),Math.round(a.displayY),a.displaySize+f.p.borderSize,0,2*Math.PI,!0);b.closePath();b.fill();b.beginPath();b.fillStyle="node"== | for (var i = 0; i < len; i++) { |
f.p.nodeActiveColor?a.color||f.p.defaultNodeColor:f.p.defaultNodeActiveColor;b.arc(Math.round(a.displayX),Math.round(a.displayY),a.displaySize,0,2*Math.PI,!0);b.closePath();b.fill();b.fillStyle="node"==f.p.labelActiveColor?a.color||f.p.defaultNodeColor:f.p.defaultLabelActiveColor;b.fillText(a.label,Math.round(a.displayX+1.5*a.displaySize),Math.round(a.displayY+c/2-3));return f};this.drawHoverNode=i;this.isOnScreen=k;this.resize=function(a,b){j=a;l=b;return f}}function t(b,h){function e(){sigma.chronos.removeTask("node_"+ | if (i in this) { |
c.id,2).removeTask("edge_"+c.id,2).removeTask("label_"+c.id,2).stopTasks();return c}function d(a,b){c.domElements[a]=document.createElement(b);c.domElements[a].style.position="absolute";c.domElements[a].setAttribute("id","sigma_"+a+"_"+c.id);c.domElements[a].setAttribute("class","sigma_"+a+"_"+b);c.domElements[a].setAttribute("width",c.width+"px");c.domElements[a].setAttribute("height",c.height+"px");c.domRoot.appendChild(c.domElements[a]);return c}function a(){c.p.drawHoverNodes&&(c.graph.checkHover(c.mousecaptor.mouseX, | fun.call(thisp, this[i], i, this); |
c.mousecaptor.mouseY),c.graph.nodes.forEach(function(a){a.hover&&!a.active&&c.plotter.drawHoverNode(a)}));return c}function A(){c.p.drawActiveNodes&&c.graph.nodes.forEach(function(a){a.active&&c.plotter.drawActiveNode(a)});return c}sigma.classes.Cascade.call(this);sigma.classes.EventDispatcher.call(this);var c=this;this.id=h.toString();this.p={auto:!0,drawNodes:2,drawEdges:1,drawLabels:2,lastNodes:2,lastEdges:0,lastLabels:2,drawHoverNodes:!0,drawActiveNodes:!0};this.domRoot=b;this.width=this.domRoot.offsetWidth; | } |
this.height=this.domRoot.offsetHeight;this.graph=new n;this.domElements={};d("edges","canvas");d("nodes","canvas");d("labels","canvas");d("hover","canvas");d("monitor","div");d("mouse","canvas");this.plotter=new m(this.domElements.nodes.getContext("2d"),this.domElements.edges.getContext("2d"),this.domElements.labels.getContext("2d"),this.domElements.hover.getContext("2d"),this.graph,this.width,this.height);this.monitor=new g(this,this.domElements.monitor);this.mousecaptor=new j(this.domElements.mouse, | } |
this.id);this.mousecaptor.bind("drag interpolate",function(){c.draw(c.p.auto?2:c.p.drawNodes,c.p.auto?0:c.p.drawEdges,c.p.auto?2:c.p.drawLabels,!0)}).bind("stopdrag stopinterpolate",function(){c.draw(c.p.auto?2:c.p.drawNodes,c.p.auto?1:c.p.drawEdges,c.p.auto?2:c.p.drawLabels,!0)}).bind("mousedown mouseup",function(a){var b=c.graph.nodes.filter(function(a){return!!a.hover}).map(function(a){return a.id});c.dispatch("mousedown"==a.type?"downgraph":"upgraph");b.length&&c.dispatch("mousedown"==a.type? | }; |
"downnodes":"upnodes",b)}).bind("move",function(){c.domElements.hover.getContext("2d").clearRect(0,0,c.domElements.hover.width,c.domElements.hover.height);a();A()});sigma.chronos.bind("startgenerators",function(){sigma.chronos.getGeneratorsIDs().some(function(a){return!!a.match(RegExp("_ext_"+c.id+"$",""))})&&c.draw(c.p.auto?2:c.p.drawNodes,c.p.auto?0:c.p.drawEdges,c.p.auto?2:c.p.drawLabels)}).bind("stopgenerators",function(){c.draw()});for(var B=0;B<i.length;B++)i[B](this);this.draw=function(a,b, | } |
d,h){if(h&&sigma.chronos.getGeneratorsIDs().some(function(a){return!!a.match(RegExp("_ext_"+c.id+"$",""))}))return c;a=void 0==a?c.p.drawNodes:a;b=void 0==b?c.p.drawEdges:b;d=void 0==d?c.p.drawLabels:d;h={nodes:a,edges:b,labels:d};c.p.lastNodes=a;c.p.lastEdges=b;c.p.lastLabels=d;e();c.graph.rescale(c.width,c.height,0<a,0<b).setBorders();c.mousecaptor.checkBorders(c.graph.borders,c.width,c.height);c.graph.translate(c.mousecaptor.stageX,c.mousecaptor.stageY,c.mousecaptor.ratio,0<a,0<b);c.dispatch("graphscaled"); | |
for(var g in c.domElements)"canvas"==c.domElements[g].nodeName.toLowerCase()&&(void 0==h[g]||0<=h[g])&&c.domElements[g].getContext("2d").clearRect(0,0,c.domElements[g].width,c.domElements[g].height);c.plotter.currentEdgeIndex=0;c.plotter.currentNodeIndex=0;c.plotter.currentLabelIndex=0;g=null;h=!1;if(a)if(1<a)for(;c.plotter.task_drawNode(););else sigma.chronos.addTask(c.plotter.task_drawNode,"node_"+c.id,!1),h=!0,g="node_"+c.id;if(d)if(1<d)for(;c.plotter.task_drawLabel(););else g?sigma.chronos.queueTask(c.plotter.task_drawLabel, | if (!Array.prototype.map) { |
"label_"+c.id,g):sigma.chronos.addTask(c.plotter.task_drawLabel,"label_"+c.id,!1),h=!0,g="label_"+c.id;if(b)if(1<b)for(;c.plotter.task_drawEdge(););else g?sigma.chronos.queueTask(c.plotter.task_drawEdge,"edge_"+c.id,g):sigma.chronos.addTask(c.plotter.task_drawEdge,"edge_"+c.id,!1),h=!0,g="edge_"+c.id;c.dispatch("draw");c.refresh();h&&sigma.chronos.runTasks();return c};this.resize=function(a,b){var d=c.width,e=c.height;void 0!=a&&void 0!=b?(c.width=a,c.height=b):(c.width=c.domRoot.offsetWidth,c.height= | Array.prototype.map = function(fun /*, thisp*/) { |
c.domRoot.offsetHeight);if(d!=c.width||e!=c.height){for(var h in c.domElements)c.domElements[h].setAttribute("width",c.width+"px"),c.domElements[h].setAttribute("height",c.height+"px");c.plotter.resize(c.width,c.height);c.draw(c.p.lastNodes,c.p.lastEdges,c.p.lastLabels,!0)}return c};this.refresh=function(){c.domElements.hover.getContext("2d").clearRect(0,0,c.domElements.hover.width,c.domElements.hover.height);a();A();return c};this.drawHover=a;this.drawActive=A;this.clearSchedule=e;window.addEventListener("resize", | var len = this.length; |
function(){c.resize()})}function p(b){var h=this;sigma.classes.EventDispatcher.call(this);this._core=b;this.kill=function(){};this.getID=function(){return b.id};this.configProperties=function(e,d){var a=b.config(e,d);return a==b?h:a};this.drawingProperties=function(e,d){var a=b.plotter.config(e,d);return a==b.plotter?h:a};this.mouseProperties=function(e,d){var a=b.mousecaptor.config(e,d);return a==b.mousecaptor?h:a};this.graphProperties=function(e,d){var a=b.graph.config(e,d);return a==b.graph?h: | if (typeof fun != 'function') { |
a};this.getMouse=function(){return{mouseX:b.mousecaptor.mouseX,mouseY:b.mousecaptor.mouseY,down:b.mousecaptor.isMouseDown}};this.position=function(e,d,a){if(0==arguments.length)return{stageX:b.mousecaptor.stageX,stageY:b.mousecaptor.stageY,ratio:b.mousecaptor.ratio};b.mousecaptor.stageX=void 0!=e?e:b.mousecaptor.stageX;b.mousecaptor.stageY=void 0!=d?d:b.mousecaptor.stageY;b.mousecaptor.ratio=void 0!=a?a:b.mousecaptor.ratio;return h};this.goTo=function(e,d,a){b.mousecaptor.interpolate(e,d,a);return h}; | throw new TypeError(); |
this.zoomTo=function(e,d,a){a=Math.min(Math.max(b.mousecaptor.config("minRatio"),a),b.mousecaptor.config("maxRatio"));a==b.mousecaptor.ratio?b.mousecaptor.interpolate(e-b.width/2+b.mousecaptor.stageX,d-b.height/2+b.mousecaptor.stageY):b.mousecaptor.interpolate((a*e-b.mousecaptor.ratio*b.width/2)/(a-b.mousecaptor.ratio),(a*d-b.mousecaptor.ratio*b.height/2)/(a-b.mousecaptor.ratio),a);return h};this.resize=function(e,d){b.resize(e,d);return h};this.draw=function(e,d,a,g){b.draw(e,d,a,g);return h};this.refresh= | } |
function(){b.refresh();return h};this.addGenerator=function(e,d,a){sigma.chronos.addGenerator(e+"_ext_"+b.id,d,a);return h};this.removeGenerator=function(e){sigma.chronos.removeGenerator(e+"_ext_"+b.id);return h};this.addNode=function(e,d){b.graph.addNode(e,d);return h};this.addEdge=function(e,d,a,g){b.graph.addEdge(e,d,a,g);return h};this.dropNode=function(e){b.graph.dropNode(e);return h};this.dropEdge=function(e){b.graph.dropEdge(e);return h};this.pushGraph=function(e,d){e.nodes&&e.nodes.forEach(function(a){a.id&& | |
(!d||!b.graph.nodesIndex[a.id])&&h.addNode(a.id,a)});e.edges&&e.edges.forEach(function(a){(validID=a.source&&a.target&&a.id)&&(!d||!b.graph.edgesIndex[a.id])&&h.addNode(a.id,a.source,a.target,a)});return h};this.emptyGraph=function(){b.graph.empty();return h};this.getNodesCount=function(){return b.graph.nodes.length};this.getEdgesCount=function(){return b.graph.edges.length};this.iterNodes=function(e,d){b.graph.iterNodes(e,d);return h};this.iterEdges=function(e,d){b.graph.iterEdges(e,d);return h}; | var res = new Array(len); |
this.getNodes=function(e){return b.graph.getNodes(e)};this.getEdges=function(e){return b.graph.getEdges(e)};this.activateMonitoring=function(){return b.monitor.activate()};this.desactivateMonitoring=function(){return b.monitor.desactivate()};b.bind("downnodes upnodes downgraph upgraph",function(b){h.dispatch(b.type,b.content)});b.graph.bind("overnodes outnodes",function(b){h.dispatch(b.type,b.content)})}var x=0;i=void 0;i=[];sigma.init=function(b){b=new t(b,(++x).toString());sigma.instances[x]=new p(b); | var thisp = arguments[1]; |
return sigma.instances[x]};sigma.addPlugin=function(b,h,e){p.prototype[b]=h;i.push(e)};sigma.chronos=new function(){function b(a){window.setTimeout(a,0);return f}function h(){for(f.dispatch("frameinserted");m&&r.length&&e(););!m||!r.length?a():(w=(new Date).getTime(),q++,C=u-p,t=p-C,f.dispatch("insertframe"),b(h))}function e(){y%=r.length;if(!r[y].task()){var a=r[y].taskName;v=v.filter(function(b){b.taskParent==a&&r.push({taskName:b.taskName,task:b.task});return b.taskParent!=a});f.dispatch("killed", | for (var i = 0; i < len; i++) { |
r.splice(y--,1)[0])}y++;u=(new Date).getTime()-w;return u<=t}function d(){m=!0;q=y=0;x=w=(new Date).getTime();f.dispatch("start");f.dispatch("insertframe");b(h);return f}function a(){f.dispatch("stop");m=!1;return f}function g(a,b,c){if("function"!=typeof a)throw Error('Task "'+b+'" is not a function');r.push({taskName:b,task:a});m=!(!m&&!(c&&d()||1));return f}function c(a){return a?Object.keys(o).filter(function(a){return!!o[a].on}).length:Object.keys(o).length}function i(){Object.keys(o).length? | if (i in this) { |
(f.dispatch("startgenerators"),f.unbind("killed",j),b(function(){for(var a in o)o[a].on=!0,g(o[a].task,a,!1)}),f.bind("killed",j).runTasks()):f.dispatch("stopgenerators");return f}function j(a){if(void 0!=o[a.content.taskName])o[a.content.taskName].del||!o[a.content.taskName].condition()?delete o[a.content.taskName]:o[a.content.taskName].on=!1,0==c(!0)&&i()}sigma.classes.EventDispatcher.call(this);var f=this,m=!1,l=80,n=0,q=0,p=1E3/l,t=p,u=0,x=0,w=0,C=0,o={},r=[],v=[],y=0;this.frequency=function(a){return void 0!= | res[i] = fun.call(thisp, this[i], i, this); |
a?(l=Math.abs(1*a),p=1E3/l,q=0,f):l};this.runTasks=d;this.stopTasks=a;this.insertFrame=b;this.addTask=g;this.queueTask=function(a,b,c){if("function"!=typeof a)throw Error('Task "'+b+'" is not a function');if(!r.concat(v).some(function(a){return a.taskName==c}))throw Error('Parent task "'+c+'" of "'+b+'" is not attached.');v.push({taskParent:c,taskName:b,task:a});return f};this.removeTask=function(b,c){if(void 0==b)r=[],1==c?v=[]:2==c&&(r=v,v=[]),a();else{var d="string"==typeof b?b:"";r=r.filter(function(a){return("string"== | } |
typeof b?a.taskName==b:a.task==b)?(d=a.taskName,!1):!0});0<c&&(v=v.filter(function(a){1==c&&a.taskParent==d&&r.push(a);return a.taskParent!=d}))}m=!(r.length&&(!a()||1));return f};this.addGenerator=function(a,b,d){if(void 0!=o[a])return f;o[a]={task:b,condition:d};0==c(!0)&&i();return f};this.removeGenerator=function(a){if(o[a])o[a].on=!1,o[a].del=!0;return f};this.startGenerators=i;this.getGeneratorsIDs=function(){return Object.keys(o)};this.getFPS=function(){m&&(n=Math.round(1E4*(q/((new Date).getTime()- | } |
x)))/10);return n};this.getTasksCount=function(){return r.length};this.getQueuedTasksCount=function(){return v.length};this.getExecutionTime=function(){return w-x};return this};sigma.debugMode=0;sigma.log=function(){if(1==sigma.debugMode)for(var b in arguments)console.log(arguments[b]);else if(1<sigma.debugMode)for(b in arguments)throw Error(arguments[b]);return sigma};sigma.easing={linear:{},quadratic:{}};sigma.easing.linear.easenone=function(b){return b};sigma.easing.quadratic.easein=function(b){return b* | |
b};sigma.easing.quadratic.easeout=function(b){return-b*(b-2)};sigma.easing.quadratic.easeinout=function(b){return 1>(b*=2)?0.5*b*b:-0.5*(--b*(b-2)-1)};sigma.tools.drawRoundRect=function(b,h,e,d,a,g,c){var g=g?g:0,i=c?c:[],i="string"==typeof i?i.split(" "):i,c=g&&(0<=i.indexOf("topleft")||0<=i.indexOf("top")||0<=i.indexOf("left")),j=g&&(0<=i.indexOf("topright")||0<=i.indexOf("top")||0<=i.indexOf("right")),f=g&&(0<=i.indexOf("bottomleft")||0<=i.indexOf("bottom")||0<=i.indexOf("left")),i=g&&(0<=i.indexOf("bottomright")|| | return res; |
0<=i.indexOf("bottom")||0<=i.indexOf("right"));b.moveTo(h,e+g);c?b.arcTo(h,e,h+g,e,g):b.lineTo(h,e);j?(b.lineTo(h+d-g,e),b.arcTo(h+d,e,h+d,e+g,g)):b.lineTo(h+d,e);i?(b.lineTo(h+d,e+a-g),b.arcTo(h+d,e+a,h+d-g,e+a,g)):b.lineTo(h+d,e+a);f?(b.lineTo(h+g,e+a),b.arcTo(h,e+a,h,e+a-g,g)):b.lineTo(h,e+a);b.lineTo(h,e+g)};sigma.tools.getRGB=function(b,g){var b=b.toString(),e={r:0,g:0,b:0};if(3<=b.length&&"#"==b.charAt(0)){var d=b.length-1;6==d?e={r:parseInt(b.charAt(1)+b.charAt(2),16),g:parseInt(b.charAt(3)+ | }; |
b.charAt(4),16),b:parseInt(b.charAt(5)+b.charAt(5),16)}:3==d&&(e={r:parseInt(b.charAt(1)+b.charAt(1),16),g:parseInt(b.charAt(2)+b.charAt(2),16),b:parseInt(b.charAt(3)+b.charAt(3),16)})}g&&(e=[e.r,e.g,e.b]);return e};sigma.tools.rgbToHex=function(b,g,e){return sigma.tools.toHex(b)+sigma.tools.toHex(g)+sigma.tools.toHex(e)};sigma.tools.toHex=function(b){b=parseInt(b,10);if(isNaN(b))return"00";b=Math.max(0,Math.min(b,255));return"0123456789ABCDEF".charAt((b-b%16)/16)+"0123456789ABCDEF".charAt(b%16)}; | } |
sigma.publicPrototype=p.prototype})(); | |
if (!Array.prototype.filter) { | |
Array.prototype.filter = function(fun /*, thisp*/) { | |
var len = this.length; | |
if (typeof fun != 'function') | |
throw new TypeError(); | |
var res = new Array(); | |
var thisp = arguments[1]; | |
for (var i = 0; i < len; i++) { | |
if (i in this) { | |
var val = this[i]; // in case fun mutates this | |
if (fun.call(thisp, val, i, this)) { | |
res.push(val); | |
} | |
} | |
} | |
return res; | |
}; | |
} | |
if (!Object.keys) { | |
Object.keys = (function() { | |
var hasOwnProperty = Object.prototype.hasOwnProperty, | |
hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'), | |
dontEnums = [ | |
'toString', | |
'toLocaleString', | |
'valueOf', | |
'hasOwnProperty', | |
'isPrototypeOf', | |
'propertyIsEnumerable', | |
'constructor' | |
], | |
dontEnumsLength = dontEnums.length; | |
return function(obj) { | |
if (typeof obj !== 'object' && | |
typeof obj !== 'function' || | |
obj === null | |
) { | |
throw new TypeError('Object.keys called on non-object'); | |
} | |
var result = []; | |
for (var prop in obj) { | |
if (hasOwnProperty.call(obj, prop)) result.push(prop); | |
} | |
if (hasDontEnumBug) { | |
for (var i = 0; i < dontEnumsLength; i++) { | |
if (hasOwnProperty.call(obj, dontEnums[i])) { | |
result.push(dontEnums[i]); | |
} | |
} | |
} | |
return result; | |
} | |
})(); | |
} | |
})(); | |
/** | |
* A jQuery like properties management class. It works like jQuery .css() | |
* method: You can call it with juste one string to get the corresponding | |
* property, with a string and anything else to set the corresponding property, | |
* or directly with an object, and then each pair string / object (or any type) | |
* will be set in the properties. | |
* @constructor | |
* @this {sigma.classes.Cascade} | |
*/ | |
sigma.classes.Cascade = function() { | |
/** | |
* This instance properties. | |
* @protected | |
* @type {Object} | |
*/ | |
this.p = {}; | |
/** | |
* The method to use to set/get any property of this instance. | |
* @param {(string|Object)} a1 If it is a string and if a2 is undefined, | |
* then it will return the corresponding | |
* property. | |
* If it is a string and if a2 is set, then it | |
* will set a2 as the property corresponding to | |
* a1, and return this. | |
* If it is an object, then each pair string / | |
* object (or any other type) will be set as a | |
* property. | |
* @param {*?} a2 The new property corresponding to a1 if a1 is | |
* a string. | |
* @return {(*|sigma.classes.Cascade)} Returns itself or the corresponding | |
* property. | |
*/ | |
this.config = function(a1, a2) { | |
if (typeof a1 == 'string' && a2 == undefined) { | |
return this.p[a1]; | |
} else { | |
var o = (typeof a1 == 'object' && a2 == undefined) ? a1 : {}; | |
if (typeof a1 == 'string') { | |
o[a1] = a2; | |
} | |
for (var k in o) { | |
if (this.p[k] != undefined) { | |
this.p[k] = o[k]; | |
} | |
} | |
return this; | |
} | |
}; | |
}; | |
/** | |
* sigma.js custom event dispatcher class. | |
* @constructor | |
* @this {sigma.classes.EventDispatcher} | |
*/ | |
sigma.classes.EventDispatcher = function() { | |
/** | |
* An object containing all the different handlers bound to one or many | |
* events, indexed by these events. | |
* @private | |
* @type {Object.<string,Object>} | |
*/ | |
var _h = {}; | |
/** | |
* Represents "this", without the well-known scope issue. | |
* @private | |
* @type {sigma.classes.EventDispatcher} | |
*/ | |
var _self = this; | |
/** | |
* Will execute the handler the next (and only the next) time that the | |
* indicated event (or the indicated events) will be triggered. | |
* @param {string} events The name of the event (or the events | |
* separated by spaces). | |
* @param {function(Object)} handler The handler to bind. | |
* @return {sigma.classes.EventDispatcher} Returns itself. | |
*/ | |
function one(events, handler) { | |
if (!handler || !events) { | |
return _self; | |
} | |
var eArray = ((typeof events) == 'string') ? events.split(' ') : events; | |
eArray.forEach(function(event) { | |
if (!_h[event]) { | |
_h[event] = []; | |
} | |
_h[event].push({ | |
'h': handler, | |
'one': true | |
}); | |
}); | |
return _self; | |
} | |
/** | |
* Will execute the handler everytime that the indicated event (or the | |
* indicated events) will be triggered. | |
* @param {string} events The name of the event (or the events | |
* separated by spaces). | |
* @param {function(Object)} handler The handler to bind. | |
* @return {sigma.classes.EventDispatcher} Returns itself. | |
*/ | |
function bind(events, handler) { | |
if (!handler || !events) { | |
return _self; | |
} | |
var eArray = ((typeof events) == 'string') ? events.split(' ') : events; | |
eArray.forEach(function(event) { | |
if (!_h[event]) { | |
_h[event] = []; | |
} | |
_h[event].push({ | |
'h': handler, | |
'one': false | |
}); | |
}); | |
return _self; | |
} | |
/** | |
* Unbinds the handler from a specified event (or specified events). | |
* @param {?string} events The name of the event (or the events | |
* separated by spaces). If undefined, | |
* then all handlers are unbound. | |
* @param {?function(Object)} handler The handler to unbind. If undefined, | |
* each handler bound to the event or the | |
* events will be unbound. | |
* @return {sigma.classes.EventDispatcher} Returns itself. | |
*/ | |
function unbind(events, handler) { | |
if (!events) { | |
_h = {}; | |
} | |
var eArray = typeof events == 'string' ? events.split(' ') : events; | |
if (handler) { | |
eArray.forEach(function(event) { | |
if (_h[event]) { | |
_h[event] = _h[event].filter(function(e) { | |
return e['h'] != handler; | |
}); | |
} | |
if (_h[event] && _h[event].length == 0) { | |
delete _h[event]; | |
} | |
}); | |
}else { | |
eArray.forEach(function(event) { | |
delete _h[event]; | |
}); | |
} | |
return _self; | |
} | |
/** | |
* Executes each handler bound to the event | |
* @param {string} type The type of the event. | |
* @param {?Object} content The content of the event (optional). | |
* @return {sigma.classes.EventDispatcher} Returns itself. | |
*/ | |
function dispatch(type, content) { | |
if (_h[type]) { | |
_h[type].forEach(function(e) { | |
e['h']({ | |
'type': type, | |
'content': content, | |
'target': _self | |
}); | |
}); | |
_h[type] = _h[type].filter(function(e) { | |
return !e['one']; | |
}); | |
} | |
return _self; | |
} | |
/* PUBLIC INTERFACE: */ | |
this.one = one; | |
this.bind = bind; | |
this.unbind = unbind; | |
this.dispatch = dispatch; | |
}; | |
(function() { | |
// Define local shortcut: | |
var id = 0; | |
// Define local package: | |
var local = {}; | |
local.plugins = []; | |
sigma.init = function(dom) { | |
var inst = new Sigma(dom, (++id).toString()); | |
sigma.instances[id] = new SigmaPublic(inst); | |
return sigma.instances[id]; | |
}; | |
/** | |
* This class listen to all the different mouse events, to normalize them and | |
* dispatch action events instead (from "startinterpolate" to "isdragging", | |
* etc). | |
* @constructor | |
* @extends sigma.classes.Cascade | |
* @extends sigma.classes.EventDispatcher | |
* @param {element} dom The DOM element to bind the handlers on. | |
* @this {MouseCaptor} | |
*/ | |
function MouseCaptor(dom) { | |
sigma.classes.Cascade.call(this); | |
sigma.classes.EventDispatcher.call(this); | |
/** | |
* Represents "this", without the well-known scope issue. | |
* @private | |
* @type {MouseCaptor} | |
*/ | |
var self = this; | |
/** | |
* The DOM element to bind the handlers on. | |
* @type {element} | |
*/ | |
var dom = dom; | |
/** | |
* The different parameters that define how this instance should work. | |
* @see sigma.classes.Cascade | |
* @type {Object} | |
*/ | |
this.p = { | |
minRatio: 1, | |
maxRatio: 32, | |
marginRatio: 1, | |
zoomDelta: 0.1, | |
dragDelta: 0.3, | |
zoomMultiply: 2, | |
directZooming: false, | |
blockScroll: true, | |
inertia: 1.1, | |
mouseEnabled: true | |
}; | |
var oldMouseX = 0; | |
var oldMouseY = 0; | |
var startX = 0; | |
var startY = 0; | |
var oldStageX = 0; | |
var oldStageY = 0; | |
var oldRatio = 1; | |
var targetRatio = 1; | |
var targetStageX = 0; | |
var targetStageY = 0; | |
var lastStageX = 0; | |
var lastStageX2 = 0; | |
var lastStageY = 0; | |
var lastStageY2 = 0; | |
var progress = 0; | |
var isZooming = false; | |
this.stageX = 0; | |
this.stageY = 0; | |
this.ratio = 1; | |
this.mouseX = 0; | |
this.mouseY = 0; | |
this.isMouseDown = false; | |
/** | |
* Extract the local X position from a mouse event. | |
* @private | |
* @param {event} e A mouse event. | |
* @return {number} The local X value of the mouse. | |
*/ | |
function getX(e) { | |
return e.offsetX != undefined && e.offsetX || | |
e.layerX != undefined && e.layerX || | |
e.clientX != undefined && e.clientX; | |
}; | |
/** | |
* Extract the local Y position from a mouse event. | |
* @private | |
* @param {event} e A mouse event. | |
* @return {number} The local Y value of the mouse. | |
*/ | |
function getY(e) { | |
return e.offsetY != undefined && e.offsetY || | |
e.layerY != undefined && e.layerY || | |
e.clientY != undefined && e.clientY; | |
}; | |
/** | |
* Extract the wheel delta from a mouse event. | |
* @private | |
* @param {event} e A mouse event. | |
* @return {number} The wheel delta of the mouse. | |
*/ | |
function getDelta(e) { | |
return e.wheelDelta != undefined && e.wheelDelta || | |
e.detail != undefined && -e.detail; | |
}; | |
/** | |
* The handler listening to the 'move' mouse event. It will set the mouseX | |
* and mouseY values as the mouse position values, prevent the default event, | |
* and dispatch a 'move' event. | |
* @private | |
* @param {event} event A 'move' mouse event. | |
*/ | |
function moveHandler(event) { | |
oldMouseX = self.mouseX; | |
oldMouseY = self.mouseY; | |
self.mouseX = getX(event); | |
self.mouseY = getY(event); | |
self.isMouseDown && drag(event); | |
self.dispatch('move'); | |
if (event.preventDefault) { | |
event.preventDefault(); | |
} else { | |
event.returnValue = false; | |
} | |
}; | |
/** | |
* The handler listening to the 'up' mouse event. It will set the isMouseDown | |
* value as false, dispatch a 'mouseup' event, and trigger stopDrag(). | |
* @private | |
* @param {event} event A 'up' mouse event. | |
*/ | |
function upHandler(event) { | |
if (self.p.mouseEnabled && self.isMouseDown) { | |
self.isMouseDown = false; | |
self.dispatch('mouseup'); | |
stopDrag(); | |
if (event.preventDefault) { | |
event.preventDefault(); | |
} else { | |
event.returnValue = false; | |
} | |
} | |
}; | |
/** | |
* The handler listening to the 'down' mouse event. It will set the | |
* isMouseDown value as true, dispatch a 'mousedown' event, and trigger | |
* startDrag(). | |
* @private | |
* @param {event} event A 'down' mouse event. | |
*/ | |
function downHandler(event) { | |
if (self.p.mouseEnabled) { | |
self.isMouseDown = true; | |
oldMouseX = self.mouseX; | |
oldMouseY = self.mouseY; | |
self.dispatch('mousedown'); | |
startDrag(); | |
if (event.preventDefault) { | |
event.preventDefault(); | |
} else { | |
event.returnValue = false; | |
} | |
} | |
}; | |
/** | |
* The handler listening to the 'wheel' mouse event. It will trigger | |
* {@link startInterpolate} with the event delta as parameter. | |
* @private | |
* @param {event} event A 'wheel' mouse event. | |
*/ | |
function wheelHandler(event) { | |
if (self.p.mouseEnabled) { | |
startInterpolate( | |
self.mouseX, | |
self.mouseY, | |
self.ratio * (getDelta(event) > 0 ? | |
self.p.zoomMultiply : | |
1 / self.p.zoomMultiply) | |
); | |
if (self.p['blockScroll']) { | |
if (event.preventDefault) { | |
event.preventDefault(); | |
} else { | |
event.returnValue = false; | |
} | |
} | |
} | |
}; | |
/** | |
* Will start computing the scene X and Y, until {@link stopDrag} is | |
* triggered. | |
*/ | |
function startDrag() { | |
oldStageX = self.stageX; | |
oldStageY = self.stageY; | |
startX = self.mouseX; | |
startY = self.mouseY; | |
lastStageX = self.stageX; | |
lastStageX2 = self.stageX; | |
lastStageY = self.stageY; | |
lastStageY2 = self.stageY; | |
self.dispatch('startdrag'); | |
}; | |
/** | |
* Stops computing the scene position. | |
*/ | |
function stopDrag() { | |
if (oldStageX != self.stageX || oldStageY != self.stageY) { | |
startInterpolate( | |
self.stageX + self.p.inertia * (self.stageX - lastStageX2), | |
self.stageY + self.p.inertia * (self.stageY - lastStageY2) | |
); | |
} | |
}; | |
/** | |
* Computes the position of the scene, relatively to the mouse position, and | |
* dispatches a "drag" event. | |
*/ | |
function drag() { | |
var newStageX = self.mouseX - startX + oldStageX; | |
var newStageY = self.mouseY - startY + oldStageY; | |
if (newStageX != self.stageX || newStageY != self.stageY) { | |
lastStageX2 = lastStageX; | |
lastStageY2 = lastStageY; | |
lastStageX = newStageX; | |
lastStageY = newStageY; | |
self.stageX = newStageX; | |
self.stageY = newStageY; | |
self.dispatch('drag'); | |
} | |
}; | |
/** | |
* Will start computing the scene zoom ratio, until {@link stopInterpolate} is | |
* triggered. | |
* @param {number} x The new stage X. | |
* @param {number} y The new stage Y. | |
* @param {number} ratio The new zoom ratio. | |
*/ | |
function startInterpolate(x, y, ratio) { | |
if (self.isMouseDown) { | |
return; | |
} | |
window.clearInterval(self.interpolationID); | |
isZooming = ratio != undefined; | |
oldStageX = self.stageX; | |
targetStageX = x; | |
oldStageY = self.stageY; | |
targetStageY = y; | |
oldRatio = self.ratio; | |
targetRatio = ratio || self.ratio; | |
targetRatio = Math.min( | |
Math.max(targetRatio, self.p.minRatio), | |
self.p.maxRatio | |
); | |
progress = | |
self.p.directZooming ? | |
1 - (isZooming ? self.p.zoomDelta : self.p.dragDelta) : | |
0; | |
if ( | |
self.ratio != targetRatio || | |
self.stageX != targetStageX || | |
self.stageY != targetStageY | |
) { | |
interpolate(); | |
self.interpolationID = window.setInterval(interpolate, 50); | |
self.dispatch('startinterpolate'); | |
} | |
}; | |
/** | |
* Stops the move interpolation. | |
*/ | |
function stopInterpolate() { | |
var oldRatio = self.ratio; | |
if (isZooming) { | |
self.ratio = targetRatio; | |
self.stageX = targetStageX + | |
(self.stageX - targetStageX) * | |
self.ratio / | |
oldRatio; | |
self.stageY = targetStageY + | |
(self.stageY - targetStageY) * | |
self.ratio / | |
oldRatio; | |
}else { | |
self.stageX = targetStageX; | |
self.stageY = targetStageY; | |
} | |
self.dispatch('stopinterpolate'); | |
}; | |
/** | |
* Computes the interpolate ratio and the position of the scene, relatively | |
* to the last mouse event delta received, and dispatches a "interpolate" | |
* event. | |
*/ | |
function interpolate() { | |
progress += (isZooming ? self.p.zoomDelta : self.p.dragDelta); | |
progress = Math.min(progress, 1); | |
var k = sigma.easing.quadratic.easeout(progress); | |
var oldRatio = self.ratio; | |
self.ratio = oldRatio * (1 - k) + targetRatio * k; | |
if (isZooming) { | |
self.stageX = targetStageX + | |
(self.stageX - targetStageX) * | |
self.ratio / | |
oldRatio; | |
self.stageY = targetStageY + | |
(self.stageY - targetStageY) * | |
self.ratio / | |
oldRatio; | |
} else { | |
self.stageX = oldStageX * (1 - k) + targetStageX * k; | |
self.stageY = oldStageY * (1 - k) + targetStageY * k; | |
} | |
self.dispatch('interpolate'); | |
if (progress >= 1) { | |
window.clearInterval(self.interpolationID); | |
stopInterpolate(); | |
} | |
}; | |
/** | |
* Checks that there is always a part of the graph that is displayed, to | |
* avoid the user to drag the graph out of the stage. | |
* @param {Object} b An object containing the borders of the graph. | |
* @param {number} width The width of the stage. | |
* @param {number} height The height of the stage. | |
* @return {MouseCaptor} Returns itself. | |
*/ | |
function checkBorders(b, width, height) { | |
// TODO : Find the good formula | |
/*if (!isNaN(b.minX) && !isNaN(b.maxX)) { | |
self.stageX = Math.min( | |
self.stageX = Math.max( | |
self.stageX, | |
(b.minX - width) * self.ratio + | |
self.p.marginRatio*(b.maxX - b.minX) | |
), | |
(b.maxX - width) * self.ratio + | |
width - | |
self.p.marginRatio*(b.maxX - b.minX) | |
); | |
} | |
if (!isNaN(b.minY) && !isNaN(b.maxY)) { | |
self.stageY = Math.min( | |
self.stageY = Math.max( | |
self.stageY, | |
(b.minY - height) * self.ratio + | |
self.p.marginRatio*(b.maxY - b.minY) | |
), | |
(b.maxY - height) * self.ratio + | |
height - | |
self.p.marginRatio*(b.maxY - b.minY) | |
); | |
}*/ | |
return self; | |
}; | |
// ADD CALLBACKS | |
dom.addEventListener('DOMMouseScroll', wheelHandler, true); | |
dom.addEventListener('mousewheel', wheelHandler, true); | |
dom.addEventListener('mousemove', moveHandler, true); | |
dom.addEventListener('mousedown', downHandler, true); | |
document.addEventListener('mouseup', upHandler, true); | |
this.checkBorders = checkBorders; | |
this.interpolate = startInterpolate; | |
} | |
/** | |
* A class to monitor some local / global probes directly on an instance, | |
* inside a div DOM element. | |
* It executes different methods (called "probes") regularly, and displays | |
* the results on the element. | |
* @constructor | |
* @extends sigma.classes.Cascade | |
* @param {Sigma} instance The instance to monitor. | |
* @param {element} dom The div DOM element to draw write on. | |
* @this {Monitor} | |
*/ | |
function Monitor(instance, dom) { | |
sigma.classes.Cascade.call(this); | |
/** | |
* Represents "this", without the well-known scope issue. | |
* @private | |
* @type {Monitor} | |
*/ | |
var self = this; | |
/** | |
* {@link Sigma} instance owning this Monitor instance. | |
* @type {Sigma} | |
*/ | |
this.instance = instance; | |
/** | |
* Determines if the monitoring is activated or not. | |
* @type {Boolean} | |
*/ | |
this.monitoring = false; | |
/** | |
* The different parameters that define how this instance should work. It | |
* also contains the different probes. | |
* @see sigma.classes.Cascade | |
* @type {Object} | |
*/ | |
this.p = { | |
fps: 40, | |
dom: dom, | |
globalProbes: { | |
'Time (ms)': sigma.chronos.getExecutionTime, | |
'Queue': sigma.chronos.getQueuedTasksCount, | |
'Tasks': sigma.chronos.getTasksCount, | |
'FPS': sigma.chronos.getFPS | |
}, | |
localProbes: { | |
'Nodes count': function() { return self.instance.graph.nodes.length; }, | |
'Edges count': function() { return self.instance.graph.edges.length; } | |
} | |
}; | |
/** | |
* Activates the monitoring: Some texts describing some values about sigma.js | |
* or the owning {@link Sigma} instance will appear over the graph, but | |
* beneath the mouse sensible DOM element. | |
* @return {Monitor} Returns itself. | |
*/ | |
function activate() { | |
if (!self.monitoring) { | |
self.monitoring = window.setInterval(routine, 1000 / self.p.fps); | |
} | |
return self; | |
} | |
/** | |
* Desactivates the monitoring: Will disappear, and stop computing the | |
* different probes. | |
* @return {Monitor} Returns itself. | |
*/ | |
function desactivate() { | |
if (self.monitoring) { | |
window.clearInterval(self.monitoring); | |
self.monitoring = null; | |
self.p.dom.innerHTML = ''; | |
} | |
return self; | |
} | |
/** | |
* The private method dedicated to compute the different values to observe. | |
* @private | |
* @return {Monitor} Returns itself. | |
*/ | |
function routine() { | |
var s = ''; | |
s += '<p>GLOBAL :</p>'; | |
for (var k in self.p.globalProbes) { | |
s += '<p>' + k + ' : ' + self.p.globalProbes[k]() + '</p>'; | |
} | |
s += '<br><p>LOCAL :</p>'; | |
for (var k in self.p.localProbes) { | |
s += '<p>' + k + ' : ' + self.p.localProbes[k]() + '</p>'; | |
} | |
self.p.dom.innerHTML = s; | |
return self; | |
} | |
this.activate = activate; | |
this.desactivate = desactivate; | |
} | |
/** | |
* Sigma is the main class. It represents the core of any instance id sigma.js. | |
* It is private and can be initialized only from inside sigma.js. To see its | |
* public interface, see {@link SigmaPublic}. | |
* It owns its own {@link Graph}, {@link MouseCaptor}, {@link Plotter} | |
* and {@link Monitor}. | |
* @constructor | |
* @extends sigma.classes.Cascade | |
* @extends sigma.classes.EventDispatcher | |
* @param {element} root The DOM root of this instance (a div, for example). | |
* @param {string} id The ID of this instance. | |
* @this {Sigma} | |
*/ | |
function Sigma(root, id) { | |
sigma.classes.Cascade.call(this); | |
sigma.classes.EventDispatcher.call(this); | |
/** | |
* Represents "this", without the well-known scope issue. | |
* @private | |
* @type {Sigma} | |
*/ | |
var self = this; | |
/** | |
* The ID of the instance. | |
* @type {string} | |
*/ | |
this.id = id.toString(); | |
/** | |
* The different parameters that define how this instance should work. | |
* @see sigma.classes.Cascade | |
* @type {Object} | |
*/ | |
this.p = { | |
auto: true, | |
drawNodes: 2, | |
drawEdges: 1, | |
drawLabels: 2, | |
lastNodes: 2, | |
lastEdges: 0, | |
lastLabels: 2, | |
drawHoverNodes: true, | |
drawActiveNodes: true | |
}; | |
/** | |
* The root DOM element of this instance, containing every other elements. | |
* @type {element} | |
*/ | |
this.domRoot = root; | |
/** | |
* The width of this instance - initially, the root's width. | |
* @type {number} | |
*/ | |
this.width = this.domRoot.offsetWidth; | |
/** | |
* The height of this instance - initially, the root's height. | |
* @type {number} | |
*/ | |
this.height = this.domRoot.offsetHeight; | |
/** | |
* The graph of this instance - initiallyempty. | |
* @type {Graph} | |
*/ | |
this.graph = new Graph(); | |
/** | |
* An object referencing every DOM elements used by this instance. | |
* @type {Object} | |
*/ | |
this.domElements = {}; | |
initDOM('edges', 'canvas'); | |
initDOM('nodes', 'canvas'); | |
initDOM('labels', 'canvas'); | |
initDOM('hover', 'canvas'); | |
initDOM('monitor', 'div'); | |
initDOM('mouse', 'canvas'); | |
/** | |
* The class dedicated to manage the drawing process of the graph of the | |
* different canvas. | |
* @type {Plotter} | |
*/ | |
this.plotter = new Plotter( | |
this.domElements.nodes.getContext('2d'), | |
this.domElements.edges.getContext('2d'), | |
this.domElements.labels.getContext('2d'), | |
this.domElements.hover.getContext('2d'), | |
this.graph, | |
this.width, | |
this.height | |
); | |
/** | |
* The class dedicated to monitor different probes about the running | |
* processes or the data, such as the number of nodes or edges, or how | |
* many times the graph is drawn per second. | |
* @type {Monitor} | |
*/ | |
this.monitor = new Monitor( | |
this, | |
this.domElements.monitor | |
); | |
/** | |
* The class dedicated to manage the different mouse events. | |
* @type {MouseCaptor} | |
*/ | |
this.mousecaptor = new MouseCaptor( | |
this.domElements.mouse, | |
this.id | |
); | |
// Interaction listeners: | |
this.mousecaptor.bind('drag interpolate', function(e) { | |
self.draw( | |
self.p.auto ? 2 : self.p.drawNodes, | |
self.p.auto ? 0 : self.p.drawEdges, | |
self.p.auto ? 2 : self.p.drawLabels, | |
true | |
); | |
}).bind('stopdrag stopinterpolate', function(e) { | |
self.draw( | |
self.p.auto ? 2 : self.p.drawNodes, | |
self.p.auto ? 1 : self.p.drawEdges, | |
self.p.auto ? 2 : self.p.drawLabels, | |
true | |
); | |
}).bind('mousedown mouseup', function(e) { | |
var targeted = self.graph.nodes.filter(function(n) { | |
return !!n['hover']; | |
}).map(function(n) { | |
return n.id; | |
}); | |
self.dispatch( | |
e['type'] == 'mousedown' ? | |
'downgraph' : | |
'upgraph' | |
); | |
if (targeted.length) { | |
self.dispatch( | |
e['type'] == 'mousedown' ? | |
'downnodes' : | |
'upnodes', | |
targeted | |
); | |
} | |
}).bind('move', function() { | |
self.domElements.hover.getContext('2d').clearRect( | |
0, | |
0, | |
self.domElements.hover.width, | |
self.domElements.hover.height | |
); | |
drawHover(); | |
drawActive(); | |
}); | |
sigma.chronos.bind('startgenerators', function() { | |
if (sigma.chronos.getGeneratorsIDs().some(function(id) { | |
return !!id.match(new RegExp('_ext_' + self.id + '$', '')); | |
})) { | |
self.draw( | |
self.p.auto ? 2 : self.p.drawNodes, | |
self.p.auto ? 0 : self.p.drawEdges, | |
self.p.auto ? 2 : self.p.drawLabels | |
); | |
} | |
}).bind('stopgenerators', function() { | |
self.draw(); | |
}); | |
/** | |
* Resizes the element, and redraws the graph with the last settings. | |
* @param {?number} w The new width (if undefined, it will use the root | |
* width). | |
* @param {?number} h The new height (if undefined, it will use the root | |
* height). | |
* @return {Sigma} Returns itself. | |
*/ | |
function resize(w, h) { | |
var oldW = self.width, oldH = self.height; | |
if (w != undefined && h != undefined) { | |
self.width = w; | |
self.height = h; | |
}else { | |
self.width = self.domRoot.offsetWidth; | |
self.height = self.domRoot.offsetHeight; | |
} | |
if (oldW != self.width || oldH != self.height) { | |
for (var k in self.domElements) { | |
self.domElements[k].setAttribute('width', self.width + 'px'); | |
self.domElements[k].setAttribute('height', self.height + 'px'); | |
} | |
self.plotter.resize(self.width, self.height); | |
self.draw( | |
self.p.lastNodes, | |
self.p.lastEdges, | |
self.p.lastLabels, | |
true | |
); | |
} | |
return self; | |
}; | |
/** | |
* Kills every drawing task currently running. Basically, it stops this | |
* instance's drawing process. | |
* @return {Sigma} Returns itself. | |
*/ | |
function clearSchedule() { | |
sigma.chronos.removeTask( | |
'node_' + self.id, 2 | |
).removeTask( | |
'edge_' + self.id, 2 | |
).removeTask( | |
'label_' + self.id, 2 | |
).stopTasks(); | |
return self; | |
}; | |
/** | |
* Initialize a DOM element, that will be stores by this instance, to make | |
* automatic these elements resizing. | |
* @private | |
* @param {string} id The element's ID. | |
* @param {string} type The element's nodeName (Example : canvas, div, ...). | |
* @return {Sigma} Returns itself. | |
*/ | |
function initDOM(id, type) { | |
self.domElements[id] = document.createElement(type); | |
self.domElements[id].style.position = 'absolute'; | |
self.domElements[id].setAttribute('id', 'sigma_' + id + '_' + self.id); | |
self.domElements[id].setAttribute('class', 'sigma_' + id + '_' + type); | |
self.domElements[id].setAttribute('width', self.width + 'px'); | |
self.domElements[id].setAttribute('height', self.height + 'px'); | |
self.domRoot.appendChild(self.domElements[id]); | |
return self; | |
}; | |
/** | |
* Starts the graph drawing process. The three first parameters indicate | |
* how the different layers have to be drawn: | |
* . -1: The layer is not drawn, but it is not erased. | |
* . 0: The layer is not drawn. | |
* . 1: The layer is drawn progressively. | |
* . 2: The layer is drawn directly. | |
* @param {?number} nodes Determines if and how the nodes must be drawn. | |
* @param {?number} edges Determines if and how the edges must be drawn. | |
* @param {?number} labels Determines if and how the labels must be drawn. | |
* @param {?boolean} safe If true, nothing will happen if any generator | |
* affiliated to this instance is currently running | |
* (an iterative layout, for example). | |
* @return {Sigma} Returns itself. | |
*/ | |
function draw(nodes, edges, labels, safe) { | |
if (safe && sigma.chronos.getGeneratorsIDs().some(function(id) { | |
return !!id.match(new RegExp('_ext_' + self.id + '$', '')); | |
})) { | |
return self; | |
} | |
var n = (nodes == undefined) ? self.p.drawNodes : nodes; | |
var e = (edges == undefined) ? self.p.drawEdges : edges; | |
var l = (labels == undefined) ? self.p.drawLabels : labels; | |
var params = { | |
nodes: n, | |
edges: e, | |
labels: l | |
}; | |
self.p.lastNodes = n; | |
self.p.lastEdges = e; | |
self.p.lastLabels = l; | |
// Remove tasks: | |
clearSchedule(); | |
// Rescale graph: | |
self.graph.rescale( | |
self.width, | |
self.height, | |
n > 0, | |
e > 0 | |
).setBorders(); | |
self.mousecaptor.checkBorders( | |
self.graph.borders, | |
self.width, | |
self.height | |
); | |
self.graph.translate( | |
self.mousecaptor.stageX, | |
self.mousecaptor.stageY, | |
self.mousecaptor.ratio, | |
n > 0, | |
e > 0 | |
); | |
self.dispatch( | |
'graphscaled' | |
); | |
// Clear scene: | |
for (var k in self.domElements) { | |
if ( | |
self.domElements[k].nodeName.toLowerCase() == 'canvas' && | |
(params[k] == undefined || params[k] >= 0) | |
) { | |
self.domElements[k].getContext('2d').clearRect( | |
0, | |
0, | |
self.domElements[k].width, | |
self.domElements[k].height | |
); | |
} | |
} | |
self.plotter.currentEdgeIndex = 0; | |
self.plotter.currentNodeIndex = 0; | |
self.plotter.currentLabelIndex = 0; | |
var previous = null; | |
var start = false; | |
if (n) { | |
if (n > 1) { | |
while (self.plotter.task_drawNode()) {} | |
}else { | |
sigma.chronos.addTask( | |
self.plotter.task_drawNode, | |
'node_' + self.id, | |
false | |
); | |
start = true; | |
previous = 'node_' + self.id; | |
} | |
} | |
if (l) { | |
if (l > 1) { | |
while (self.plotter.task_drawLabel()) {} | |
} else { | |
if (previous) { | |
sigma.chronos.queueTask( | |
self.plotter.task_drawLabel, | |
'label_' + self.id, | |
previous | |
); | |
} else { | |
sigma.chronos.addTask( | |
self.plotter.task_drawLabel, | |
'label_' + self.id, | |
false | |
); | |
} | |
start = true; | |
previous = 'label_' + self.id; | |
} | |
} | |
if (e) { | |
if (e > 1) { | |
while (self.plotter.task_drawEdge()) {} | |
}else { | |
if (previous) { | |
sigma.chronos.queueTask( | |
self.plotter.task_drawEdge, | |
'edge_' + self.id, | |
previous | |
); | |
}else { | |
sigma.chronos.addTask( | |
self.plotter.task_drawEdge, | |
'edge_' + self.id, | |
false | |
); | |
} | |
start = true; | |
previous = 'edge_' + self.id; | |
} | |
} | |
self.dispatch( | |
'draw' | |
); | |
self.refresh(); | |
start && sigma.chronos.runTasks(); | |
return self; | |
}; | |
/** | |
* Draws the hover and active nodes labels. | |
* @return {Sigma} Returns itself. | |
*/ | |
function refresh() { | |
self.domElements.hover.getContext('2d').clearRect( | |
0, | |
0, | |
self.domElements.hover.width, | |
self.domElements.hover.height | |
); | |
drawHover(); | |
drawActive(); | |
return self; | |
} | |
/** | |
* Draws the hover nodes labels. This method is applied directly, and does | |
* not use the pseudo-asynchronous tasks process. | |
* @return {Sigma} Returns itself. | |
*/ | |
function drawHover() { | |
if (self.p.drawHoverNodes) { | |
self.graph.checkHover( | |
self.mousecaptor.mouseX, | |
self.mousecaptor.mouseY | |
); | |
self.graph.nodes.forEach(function(node) { | |
if (node.hover && !node.active) { | |
self.plotter.drawHoverNode(node); | |
} | |
}); | |
} | |
return self; | |
} | |
/** | |
* Draws the active nodes labels. This method is applied directly, and does | |
* not use the pseudo-asynchronous tasks process. | |
* @return {Sigma} Returns itself. | |
*/ | |
function drawActive() { | |
if (self.p.drawActiveNodes) { | |
self.graph.nodes.forEach(function(node) { | |
if (node.active) { | |
self.plotter.drawActiveNode(node); | |
} | |
}); | |
} | |
return self; | |
} | |
// Apply plugins: | |
for (var i = 0; i < local.plugins.length; i++) { | |
local.plugins[i](this); | |
} | |
this.draw = draw; | |
this.resize = resize; | |
this.refresh = refresh; | |
this.drawHover = drawHover; | |
this.drawActive = drawActive; | |
this.clearSchedule = clearSchedule; | |
window.addEventListener('resize', function() { | |
self.resize(); | |
}); | |
} | |
/** | |
* This class draws the graph on the different canvas DOM elements. It just | |
* contains all the different methods to draw the graph, synchronously or | |
* pseudo-asynchronously. | |
* @constructor | |
* @param {CanvasRenderingContext2D} nodesCtx Context dedicated to draw nodes. | |
* @param {CanvasRenderingContext2D} edgesCtx Context dedicated to draw edges. | |
* @param {CanvasRenderingContext2D} labelsCtx Context dedicated to draw | |
* labels. | |
* @param {CanvasRenderingContext2D} hoverCtx Context dedicated to draw hover | |
* nodes labels. | |
* @param {Graph} graph A reference to the graph to | |
* draw. | |
* @param {number} w The width of the DOM root | |
* element. | |
* @param {number} h The width of the DOM root | |
* element. | |
* @extends sigma.classes.Cascade | |
* @this {Plotter} | |
*/ | |
function Plotter(nodesCtx, edgesCtx, labelsCtx, hoverCtx, graph, w, h) { | |
sigma.classes.Cascade.call(this); | |
/** | |
* Represents "this", without the well-known scope issue. | |
* @private | |
* @type {Plotter} | |
*/ | |
var self = this; | |
/** | |
* The different parameters that define how this instance should work. | |
* @see sigma.classes.Cascade | |
* @type {Object} | |
*/ | |
this.p = { | |
// ------- | |
// LABELS: | |
// ------- | |
// Label color: | |
// - 'node' | |
// - default (then defaultLabelColor | |
// will be used instead) | |
labelColor: 'default', | |
defaultLabelColor: '#000', | |
// Label hover background color: | |
// - 'node' | |
// - default (then defaultHoverLabelBGColor | |
// will be used instead) | |
labelHoverBGColor: 'default', | |
defaultHoverLabelBGColor: '#fff', | |
// Label hover shadow: | |
labelHoverShadow: true, | |
labelHoverShadowColor: '#000', | |
// Label hover color: | |
// - 'node' | |
// - default (then defaultLabelHoverColor | |
// will be used instead) | |
labelHoverColor: 'default', | |
defaultLabelHoverColor: '#000', | |
// Label active background color: | |
// - 'node' | |
// - default (then defaultActiveLabelBGColor | |
// will be used instead) | |
labelActiveBGColor: 'default', | |
defaultActiveLabelBGColor: '#fff', | |
// Label active shadow: | |
labelActiveShadow: true, | |
labelActiveShadowColor: '#000', | |
// Label active color: | |
// - 'node' | |
// - default (then defaultLabelActiveColor | |
// will be used instead) | |
labelActiveColor: 'default', | |
defaultLabelActiveColor: '#000', | |
// Label size: | |
// - 'fixed' | |
// - 'proportional' | |
// Label size: | |
// - 'fixed' | |
// - 'proportional' | |
labelSize: 'fixed', | |
defaultLabelSize: 12, // for fixed display only | |
labelSizeRatio: 2, // for proportional display only | |
labelThreshold: 6, | |
font: 'Arial', | |
hoverFont: '', | |
activeFont: '', | |
fontStyle: '', | |
hoverFontStyle: '', | |
activeFontStyle: '', | |
// ------ | |
// EDGES: | |
// ------ | |
// Edge color: | |
// - 'source' | |
// - 'target' | |
// - default (then defaultEdgeColor or edge['color'] | |
// will be used instead) | |
edgeColor: 'source', | |
defaultEdgeColor: '#aaa', | |
defaultEdgeType: 'line', | |
// ------ | |
// NODES: | |
// ------ | |
defaultNodeColor: '#aaa', | |
// HOVER: | |
// Node hover color: | |
// - 'node' | |
// - default (then defaultNodeHoverColor | |
// will be used instead) | |
nodeHoverColor: 'node', | |
defaultNodeHoverColor: '#fff', | |
// ACTIVE: | |
// Node active color: | |
// - 'node' | |
// - default (then defaultNodeActiveColor | |
// will be used instead) | |
nodeActiveColor: 'node', | |
defaultNodeActiveColor: '#fff', | |
// Node border color: | |
// - 'node' | |
// - default (then defaultNodeBorderColor | |
// will be used instead) | |
borderSize: 0, | |
nodeBorderColor: 'node', | |
defaultNodeBorderColor: '#fff', | |
// -------- | |
// PROCESS: | |
// -------- | |
edgesSpeed: 200, | |
nodesSpeed: 200, | |
labelsSpeed: 200 | |
}; | |
/** | |
* The canvas context dedicated to draw the nodes. | |
* @type {CanvasRenderingContext2D} | |
*/ | |
var nodesCtx = nodesCtx; | |
/** | |
* The canvas context dedicated to draw the edges. | |
* @type {CanvasRenderingContext2D} | |
*/ | |
var edgesCtx = edgesCtx; | |
/** | |
* The canvas context dedicated to draw the labels. | |
* @type {CanvasRenderingContext2D} | |
*/ | |
var labelsCtx = labelsCtx; | |
/** | |
* The canvas context dedicated to draw the hover nodes. | |
* @type {CanvasRenderingContext2D} | |
*/ | |
var hoverCtx = hoverCtx; | |
/** | |
* A reference to the graph to draw. | |
* @type {Graph} | |
*/ | |
var graph = graph; | |
/** | |
* The width of the stage to draw on. | |
* @type {number} | |
*/ | |
var width = w; | |
/** | |
* The height of the stage to draw on. | |
* @type {number} | |
*/ | |
var height = h; | |
/** | |
* The index of the next edge to draw. | |
* @type {number} | |
*/ | |
this.currentEdgeIndex = 0; | |
/** | |
* The index of the next node to draw. | |
* @type {number} | |
*/ | |
this.currentNodeIndex = 0; | |
/** | |
* The index of the next label to draw. | |
* @type {number} | |
*/ | |
this.currentLabelIndex = 0; | |
/** | |
* An atomic function to drawn the N next edges, with N as edgesSpeed. | |
* The counter is {@link this.currentEdgeIndex}. | |
* This function has been designed to work with {@link sigma.chronos}, that | |
* will insert frames at the middle of the calls, to make the edges drawing | |
* process fluid for the user. | |
* @see sigma.chronos | |
* @return {boolean} Returns true if all the edges are drawn and false else. | |
*/ | |
function task_drawEdge() { | |
var c = graph.edges.length; | |
var s, t, i = 0; | |
while (i++< self.p.edgesSpeed && self.currentEdgeIndex < c) { | |
e = graph.edges[self.currentEdgeIndex]; | |
s = e['source']; | |
t = e['target']; | |
if (e['hidden'] || | |
s['hidden'] || | |
t['hidden'] || | |
(!self.isOnScreen(s) && !self.isOnScreen(t))) { | |
self.currentEdgeIndex++; | |
}else { | |
drawEdge(graph.edges[self.currentEdgeIndex++]); | |
} | |
} | |
return self.currentEdgeIndex < c; | |
}; | |
/** | |
* An atomic function to drawn the N next nodes, with N as nodesSpeed. | |
* The counter is {@link this.currentEdgeIndex}. | |
* This function has been designed to work with {@link sigma.chronos}, that | |
* will insert frames at the middle of the calls, to make the nodes drawing | |
* process fluid for the user. | |
* @see sigma.chronos | |
* @return {boolean} Returns true if all the nodes are drawn and false else. | |
*/ | |
function task_drawNode() { | |
var c = graph.nodes.length; | |
var i = 0; | |
while (i++< self.p.nodesSpeed && self.currentNodeIndex < c) { | |
if (!self.isOnScreen(graph.nodes[self.currentNodeIndex])) { | |
self.currentNodeIndex++; | |
}else { | |
drawNode(graph.nodes[self.currentNodeIndex++]); | |
} | |
} | |
return self.currentNodeIndex < c; | |
}; | |
/** | |
* An atomic function to drawn the N next labels, with N as labelsSpeed. | |
* The counter is {@link this.currentEdgeIndex}. | |
* This function has been designed to work with {@link sigma.chronos}, that | |
* will insert frames at the middle of the calls, to make the labels drawing | |
* process fluid for the user. | |
* @see sigma.chronos | |
* @return {boolean} Returns true if all the labels are drawn and false else. | |
*/ | |
function task_drawLabel() { | |
var c = graph.nodes.length; | |
var i = 0; | |
while (i++< self.p.labelsSpeed && self.currentLabelIndex < c) { | |
if (!self.isOnScreen(graph.nodes[self.currentLabelIndex])) { | |
self.currentLabelIndex++; | |
}else { | |
drawLabel(graph.nodes[self.currentLabelIndex++]); | |
} | |
} | |
return self.currentLabelIndex < c; | |
}; | |
/** | |
* Draws one node to the corresponding canvas. | |
* @param {Object} node The node to draw. | |
* @return {Plotter} Returns itself. | |
*/ | |
function drawNode(node) { | |
var size = Math.round(node['displaySize'] * 10) / 10; | |
var ctx = nodesCtx; | |
ctx.fillStyle = node['color']; | |
ctx.beginPath(); | |
ctx.arc(node['displayX'], | |
node['displayY'], | |
size, | |
0, | |
Math.PI * 2, | |
true); | |
ctx.closePath(); | |
ctx.fill(); | |
node['hover'] && drawHoverNode(node); | |
return self; | |
}; | |
/** | |
* Draws one edge to the corresponding canvas. | |
* @param {Object} edge The edge to draw. | |
* @return {Plotter} Returns itself. | |
*/ | |
function drawEdge(edge) { | |
var x1 = edge['source']['displayX']; | |
var y1 = edge['source']['displayY']; | |
var x2 = edge['target']['displayX']; | |
var y2 = edge['target']['displayY']; | |
var color = edge['color']; | |
if (!color) { | |
switch (self.p.edgeColor) { | |
case 'source': | |
color = edge['source']['color'] || | |
self.p.defaultNodeColor; | |
break; | |
case 'target': | |
color = edge['target']['color'] || | |
self.p.defaultNodeColor; | |
break; | |
default: | |
color = self.p.defaultEdgeColor; | |
break; | |
} | |
} | |
var ctx = edgesCtx; | |
switch (edge['type'] || self.p.defaultEdgeType) { | |
case 'curve': | |
ctx.strokeStyle = color; | |
ctx.lineWidth = edge['displaySize'] / 3; | |
ctx.beginPath(); | |
ctx.moveTo(x1, y1); | |
ctx.quadraticCurveTo((x1 + x2) / 2 + (y2 - y1) / 4, | |
(y1 + y2) / 2 + (x1 - x2) / 4, | |
x2, | |
y2); | |
ctx.stroke(); | |
break; | |
case 'line': | |
default: | |
ctx.strokeStyle = color; | |
ctx.lineWidth = edge['displaySize'] / 3; | |
ctx.beginPath(); | |
ctx.moveTo(x1, y1); | |
ctx.lineTo(x2, y2); | |
ctx.stroke(); | |
break; | |
} | |
return self; | |
}; | |
/** | |
* Draws one label to the corresponding canvas. | |
* @param {Object} node The label to draw. | |
* @return {Plotter} Returns itself. | |
*/ | |
function drawLabel(node) { | |
var ctx = labelsCtx; | |
if (node['displaySize'] >= self.p.labelThreshold || node['forceLabel']) { | |
var fontSize = self.p.labelSize == 'fixed' ? | |
self.p.defaultLabelSize : | |
self.p.labelSizeRatio * node['displaySize']; | |
ctx.font = self.p.fontStyle + fontSize + 'px ' + self.p.font; | |
ctx.fillStyle = self.p.labelColor == 'node' ? | |
(node['color'] || self.p.defaultNodeColor) : | |
self.p.defaultLabelColor; | |
ctx.fillText( | |
node['label'], | |
Math.round(node['displayX'] + node['displaySize'] * 1.5), | |
Math.round(node['displayY'] + fontSize / 2 - 3) | |
); | |
} | |
return self; | |
}; | |
/** | |
* Draws one hover node to the corresponding canvas. | |
* @param {Object} node The hover node to draw. | |
* @return {Plotter} Returns itself. | |
*/ | |
function drawHoverNode(node) { | |
var ctx = hoverCtx; | |
var fontSize = self.p.labelSize == 'fixed' ? | |
self.p.defaultLabelSize : | |
self.p.labelSizeRatio * node['displaySize']; | |
ctx.font = (self.p.hoverFontStyle || self.p.fontStyle || '') + ' ' + | |
fontSize + 'px ' + | |
(self.p.hoverFont || self.p.font || ''); | |
ctx.fillStyle = self.p.labelHoverBGColor == 'node' ? | |
(node['color'] || self.p.defaultNodeColor) : | |
self.p.defaultHoverLabelBGColor; | |
// Label background: | |
ctx.beginPath(); | |
if (self.p.labelHoverShadow) { | |
ctx.shadowOffsetX = 0; | |
ctx.shadowOffsetY = 0; | |
ctx.shadowBlur = 4; | |
ctx.shadowColor = self.p.labelHoverShadowColor; | |
} | |
sigma.tools.drawRoundRect( | |
ctx, | |
Math.round(node['displayX'] - fontSize / 2 - 2), | |
Math.round(node['displayY'] - fontSize / 2 - 2), | |
Math.round(ctx.measureText(node['label']).width + | |
node['displaySize'] * 1.5 + | |
fontSize / 2 + 4), | |
Math.round(fontSize + 4), | |
Math.round(fontSize / 2 + 2), | |
'left' | |
); | |
ctx.closePath(); | |
ctx.fill(); | |
ctx.shadowOffsetX = 0; | |
ctx.shadowOffsetY = 0; | |
ctx.shadowBlur = 0; | |
// Node border: | |
ctx.beginPath(); | |
ctx.fillStyle = self.p.nodeBorderColor == 'node' ? | |
(node['color'] || self.p.defaultNodeColor) : | |
self.p.defaultNodeBorderColor; | |
ctx.arc(Math.round(node['displayX']), | |
Math.round(node['displayY']), | |
node['displaySize'] + self.p.borderSize, | |
0, | |
Math.PI * 2, | |
true); | |
ctx.closePath(); | |
ctx.fill(); | |
// Node: | |
ctx.beginPath(); | |
ctx.fillStyle = self.p.nodeHoverColor == 'node' ? | |
(node['color'] || self.p.defaultNodeColor) : | |
self.p.defaultNodeHoverColor; | |
ctx.arc(Math.round(node['displayX']), | |
Math.round(node['displayY']), | |
node['displaySize'], | |
0, | |
Math.PI * 2, | |
true); | |
ctx.closePath(); | |
ctx.fill(); | |
// Label: | |
ctx.fillStyle = self.p.labelHoverColor == 'node' ? | |
(node['color'] || self.p.defaultNodeColor) : | |
self.p.defaultLabelHoverColor; | |
ctx.fillText( | |
node['label'], | |
Math.round(node['displayX'] + node['displaySize'] * 1.5), | |
Math.round(node['displayY'] + fontSize / 2 - 3) | |
); | |
return self; | |
}; | |
/** | |
* Draws one active node to the corresponding canvas. | |
* @param {Object} node The active node to draw. | |
* @return {Plotter} Returns itself. | |
*/ | |
function drawActiveNode(node) { | |
var ctx = hoverCtx; | |
if (!isOnScreen(node)) { | |
return self; | |
} | |
var fontSize = self.p.labelSize == 'fixed' ? | |
self.p.defaultLabelSize : | |
self.p.labelSizeRatio * node['displaySize']; | |
ctx.font = (self.p.activeFontStyle || self.p.fontStyle || '') + ' ' + | |
fontSize + 'px ' + | |
(self.p.activeFont || self.p.font || ''); | |
ctx.fillStyle = self.p.labelHoverBGColor == 'node' ? | |
(node['color'] || self.p.defaultNodeColor) : | |
self.p.defaultActiveLabelBGColor; | |
// Label background: | |
ctx.beginPath(); | |
if (self.p.labelActiveShadow) { | |
ctx.shadowOffsetX = 0; | |
ctx.shadowOffsetY = 0; | |
ctx.shadowBlur = 4; | |
ctx.shadowColor = self.p.labelActiveShadowColor; | |
} | |
sigma.tools.drawRoundRect( | |
ctx, | |
Math.round(node['displayX'] - fontSize / 2 - 2), | |
Math.round(node['displayY'] - fontSize / 2 - 2), | |
Math.round(ctx.measureText(node['label']).width + | |
node['displaySize'] * 1.5 + | |
fontSize / 2 + 4), | |
Math.round(fontSize + 4), | |
Math.round(fontSize / 2 + 2), | |
'left' | |
); | |
ctx.closePath(); | |
ctx.fill(); | |
ctx.shadowOffsetX = 0; | |
ctx.shadowOffsetY = 0; | |
ctx.shadowBlur = 0; | |
// Node border: | |
ctx.beginPath(); | |
ctx.fillStyle = self.p.nodeBorderColor == 'node' ? | |
(node['color'] || self.p.defaultNodeColor) : | |
self.p.defaultNodeBorderColor; | |
ctx.arc(Math.round(node['displayX']), | |
Math.round(node['displayY']), | |
node['displaySize'] + self.p.borderSize, | |
0, | |
Math.PI * 2, | |
true); | |
ctx.closePath(); | |
ctx.fill(); | |
// Node: | |
ctx.beginPath(); | |
ctx.fillStyle = self.p.nodeActiveColor == 'node' ? | |
(node['color'] || self.p.defaultNodeColor) : | |
self.p.defaultNodeActiveColor; | |
ctx.arc(Math.round(node['displayX']), | |
Math.round(node['displayY']), | |
node['displaySize'], | |
0, | |
Math.PI * 2, | |
true); | |
ctx.closePath(); | |
ctx.fill(); | |
// Label: | |
ctx.fillStyle = self.p.labelActiveColor == 'node' ? | |
(node['color'] || self.p.defaultNodeColor) : | |
self.p.defaultLabelActiveColor; | |
ctx.fillText( | |
node['label'], | |
Math.round(node['displayX'] + node['displaySize'] * 1.5), | |
Math.round(node['displayY'] + fontSize / 2 - 3) | |
); | |
return self; | |
}; | |
/** | |
* Determines if a node is on the screen or not. The limits here are | |
* bigger than the actual screen, to avoid seeing labels disappear during | |
* the graph manipulation. | |
* @param {Object} node The node to check if it is on or out the screen. | |
* @return {boolean} Returns false if the node is hidden or not on the screen | |
* or true else. | |
*/ | |
function isOnScreen(node) { | |
if (isNaN(node['x']) || isNaN(node['y'])) { | |
throw (new Error('A node\'s coordinate is not a ' + | |
'number (id: ' + node['id'] + ')') | |
); | |
} | |
return !node['hidden'] && | |
(node['displayX'] + node['displaySize'] > -width / 3) && | |
(node['displayX'] - node['displaySize'] < width * 4 / 3) && | |
(node['displayY'] + node['displaySize'] > -height / 3) && | |
(node['displayY'] - node['displaySize'] < height * 4 / 3); | |
}; | |
/** | |
* Resizes this instance. | |
* @param {number} w The new width. | |
* @param {number} h The new height. | |
* @return {Plotter} Returns itself. | |
*/ | |
function resize(w, h) { | |
width = w; | |
height = h; | |
return self; | |
} | |
this.task_drawLabel = task_drawLabel; | |
this.task_drawEdge = task_drawEdge; | |
this.task_drawNode = task_drawNode; | |
this.drawActiveNode = drawActiveNode; | |
this.drawHoverNode = drawHoverNode; | |
this.isOnScreen = isOnScreen; | |
this.resize = resize; | |
} | |
function SigmaPublic(sigmaInstance) { | |
var s = sigmaInstance; | |
var self = this; | |
sigma.classes.EventDispatcher.call(this); | |
this._core = sigmaInstance; | |
this.kill = function() { | |
// TODO | |
}; | |
this.getID = function() { | |
return s.id; | |
}; | |
// Config: | |
this.configProperties = function(a1, a2) { | |
var res = s.config(a1, a2); | |
return res == s ? self : res; | |
}; | |
this.drawingProperties = function(a1, a2) { | |
var res = s.plotter.config(a1, a2); | |
return res == s.plotter ? self : res; | |
}; | |
this.mouseProperties = function(a1, a2) { | |
var res = s.mousecaptor.config(a1, a2); | |
return res == s.mousecaptor ? self : res; | |
}; | |
this.graphProperties = function(a1, a2) { | |
var res = s.graph.config(a1, a2); | |
return res == s.graph ? self : res; | |
}; | |
this.getMouse = function() { | |
return { | |
mouseX: s.mousecaptor.mouseX, | |
mouseY: s.mousecaptor.mouseY, | |
down: s.mousecaptor.isMouseDown | |
}; | |
}; | |
// Actions: | |
this.position = function(stageX, stageY, ratio) { | |
if (arguments.length == 0) { | |
return { | |
stageX: s.mousecaptor.stageX, | |
stageY: s.mousecaptor.stageY, | |
ratio: s.mousecaptor.ratio | |
}; | |
}else { | |
s.mousecaptor.stageX = stageX != undefined ? | |
stageX : | |
s.mousecaptor.stageX; | |
s.mousecaptor.stageY = stageY != undefined ? | |
stageY : | |
s.mousecaptor.stageY; | |
s.mousecaptor.ratio = ratio != undefined ? | |
ratio : | |
s.mousecaptor.ratio; | |
return self; | |
} | |
}; | |
this.goTo = function(stageX, stageY, ratio) { | |
s.mousecaptor.interpolate(stageX, stageY, ratio); | |
return self; | |
}; | |
this.zoomTo = function(x, y, ratio) { | |
ratio = Math.min( | |
Math.max(s.mousecaptor.config('minRatio'), ratio), | |
s.mousecaptor.config('maxRatio') | |
); | |
if (ratio == s.mousecaptor.ratio) { | |
s.mousecaptor.interpolate( | |
x - s.width / 2 + s.mousecaptor.stageX, | |
y - s.height / 2 + s.mousecaptor.stageY | |
); | |
}else { | |
s.mousecaptor.interpolate( | |
(ratio * x - s.mousecaptor.ratio * s.width/2) / | |
(ratio - s.mousecaptor.ratio), | |
(ratio * y - s.mousecaptor.ratio * s.height/2) / | |
(ratio - s.mousecaptor.ratio), | |
ratio | |
); | |
} | |
return self; | |
}; | |
this.resize = function(w, h) { | |
s.resize(w, h); | |
return self; | |
}; | |
this.draw = function(nodes, edges, labels, safe) { | |
s.draw(nodes, edges, labels, safe); | |
return self; | |
}; | |
this.refresh = function() { | |
s.refresh(); | |
return self; | |
}; | |
// Tasks methods: | |
this.addGenerator = function(id, task, condition) { | |
sigma.chronos.addGenerator(id + '_ext_' + s.id, task, condition); | |
return self; | |
}; | |
this.removeGenerator = function(id) { | |
sigma.chronos.removeGenerator(id + '_ext_' + s.id); | |
return self; | |
}; | |
// Graph methods: | |
this.addNode = function(id, params) { | |
s.graph.addNode(id, params); | |
return self; | |
}; | |
this.addEdge = function(id, source, target, params) { | |
s.graph.addEdge(id, source, target, params); | |
return self; | |
} | |
this.dropNode = function(v) { | |
s.graph.dropNode(v); | |
return self; | |
}; | |
this.dropEdge = function(v) { | |
s.graph.dropEdge(v); | |
return self; | |
}; | |
this.pushGraph = function(object, safe) { | |
object.nodes && object.nodes.forEach(function(node) { | |
node['id'] && (!safe || !s.graph.nodesIndex[node['id']]) && | |
self.addNode(node['id'], node); | |
}); | |
var isEdgeValid; | |
object.edges && object.edges.forEach(function(edge) { | |
validID = edge['source'] && edge['target'] && edge['id']; | |
validID && | |
(!safe || !s.graph.edgesIndex[edge['id']]) && | |
self.addNode( | |
edge['id'], | |
edge['source'], | |
edge['target'], | |
edge | |
); | |
}); | |
return self; | |
}; | |
this.emptyGraph = function() { | |
s.graph.empty(); | |
return self; | |
}; | |
this.getNodesCount = function() { | |
return s.graph.nodes.length; | |
}; | |
this.getEdgesCount = function() { | |
return s.graph.edges.length; | |
}; | |
this.iterNodes = function(fun, ids) { | |
s.graph.iterNodes(fun, ids); | |
return self; | |
}; | |
this.iterEdges = function(fun, ids) { | |
s.graph.iterEdges(fun, ids); | |
return self; | |
}; | |
this.getNodes = function(ids) { | |
return s.graph.getNodes(ids); | |
}; | |
this.getEdges = function(ids) { | |
return s.graph.getEdges(ids); | |
}; | |
// Monitoring | |
this.activateMonitoring = function() { | |
return s.monitor.activate(); | |
}; | |
this.desactivateMonitoring = function() { | |
return s.monitor.desactivate(); | |
}; | |
// Events | |
s.bind('downnodes upnodes downgraph upgraph', function(e) { | |
self.dispatch(e.type, e.content); | |
}); | |
s.graph.bind('overnodes outnodes', function(e) { | |
self.dispatch(e.type, e.content); | |
}); | |
} | |
/** | |
* The graph data model used in sigma.js. | |
* @constructor | |
* @extends sigma.classes.Cascade | |
* @extends sigma.classes.EventDispatcher | |
* @this {Graph} | |
*/ | |
function Graph() { | |
sigma.classes.Cascade.call(this); | |
sigma.classes.EventDispatcher.call(this); | |
/** | |
* Represents "this", without the well-known scope issue. | |
* @private | |
* @type {Graph} | |
*/ | |
var self = this; | |
/** | |
* The different parameters that determine how the nodes and edges should be | |
* translated and rescaled. | |
* @type {Object} | |
*/ | |
this.p = { | |
minNodeSize: 0, | |
maxNodeSize: 0, | |
minEdgeSize: 0, | |
maxEdgeSize: 0, | |
// Scaling mode: | |
// - 'inside' (default) | |
// - 'outside' | |
scalingMode: 'inside', | |
nodesPowRatio: 0.5, | |
edgesPowRatio: 0 | |
}; | |
/** | |
* Contains the borders of the graph. These are useful to avoid the user to | |
* drag the graph out of the canvas. | |
* @type {Object} | |
*/ | |
this.borders = {}; | |
/** | |
* Inserts a node in the graph. | |
* @param {string} id The node's ID. | |
* @param {object} params An object containing the different parameters | |
* of the node. | |
* @return {Graph} Returns itself. | |
*/ | |
function addNode(id, params) { | |
if (self.nodesIndex[id]) { | |
throw new Error('Node "' + id + '" already exists.'); | |
} | |
params = params || {}; | |
var n = { | |
// Numbers : | |
'x': 0, | |
'y': 0, | |
'size': 1, | |
'degree': 0, | |
'inDegree': 0, | |
'outDegree': 0, | |
// Flags : | |
'fixed': false, | |
'active': false, | |
'hidden': false, | |
'forceLabel': false, | |
// Strings : | |
'label': id.toString(), | |
'id': id.toString(), | |
// Custom attributes : | |
'attr': {} | |
}; | |
for (var k in params) { | |
switch (k) { | |
case 'id': | |
break; | |
case 'x': | |
case 'y': | |
case 'size': | |
n[k] = +params[k]; | |
break; | |
case 'fixed': | |
case 'active': | |
case 'hidden': | |
case 'forceLabel': | |
n[k] = !!params[k]; | |
break; | |
case 'color': | |
case 'label': | |
n[k] = params[k]; | |
break; | |
default: | |
n['attr'][k] = params[k]; | |
} | |
} | |
self.nodes.push(n); | |
self.nodesIndex[id.toString()] = n; | |
return self; | |
}; | |
/** | |
* Generates the clone of a node, to make it easier to be exported. | |
* @private | |
* @param {Object} node The node to clone. | |
* @return {Object} The clone of the node. | |
*/ | |
function cloneNode(node) { | |
return { | |
'x': node['x'], | |
'y': node['y'], | |
'size': node['size'], | |
'degree': node['degree'], | |
'inDegree': node['inDegree'], | |
'outDegree': node['outDegree'], | |
'displayX': node['displayX'], | |
'displayY': node['displayY'], | |
'displaySize': node['displaySize'], | |
'label': node['label'], | |
'id': node['id'], | |
'color': node['color'], | |
'fixed': node['fixed'], | |
'active': node['active'], | |
'hidden': node['hidden'], | |
'forceLabel': node['forceLabel'], | |
'attr': node['attr'] | |
}; | |
}; | |
/** | |
* Checks the clone of a node, and inserts its values when possible. For | |
* example, it is possible to modify the size or the color of a node, but it | |
* is not possible to modify its display values or its id. | |
* @private | |
* @param {Object} node The original node. | |
* @param {Object} copy The clone. | |
* @return {Graph} Returns itself. | |
*/ | |
function checkNode(node, copy) { | |
for (var k in copy) { | |
switch (k) { | |
case 'id': | |
case 'attr': | |
case 'degree': | |
case 'inDegree': | |
case 'outDegree': | |
case 'displayX': | |
case 'displayY': | |
case 'displaySize': | |
break; | |
case 'x': | |
case 'y': | |
case 'size': | |
node[k] = +copy[k]; | |
break; | |
case 'fixed': | |
case 'active': | |
case 'hidden': | |
case 'forceLabel': | |
node[k] = !!copy[k]; | |
break; | |
case 'color': | |
case 'label': | |
node[k] = (copy[k] || '').toString(); | |
break; | |
default: | |
node['attr'][k] = copy[k]; | |
} | |
} | |
return self; | |
}; | |
/** | |
* Deletes one or several nodes from the graph, and the related edges. | |
* @param {(string|Array.<string>)} v A string ID, or an Array of several | |
* IDs. | |
* @return {Graph} Returns itself. | |
*/ | |
function dropNode(v) { | |
var a = (v instanceof Array ? v : [v]) || []; | |
a.forEach(function(id) { | |
if (self.nodesIndex[id]) { | |
var index = null; | |
self.nodes.some(function(n, i) { | |
if (n['id'] == id) { | |
index = i; | |
return true; | |
} | |
return false; | |
}); | |
index != null && self.nodes.splice(index, 1); | |
delete self.nodesIndex[id]; | |
var edgesToRemove = []; | |
self.edges = self.edges.filter(function(e) { | |
if (e['source']['id'] == id) { | |
delete self.edgesIndex[e['id']]; | |
e['target']['degree']--; | |
e['target']['inDegree']--; | |
return false; | |
}else if (e['target']['id'] == id) { | |
delete self.edgesIndex[e['id']]; | |
e['source']['degree']--; | |
e['source']['outDegree']--; | |
return false; | |
} | |
return true; | |
}); | |
}else { | |
sigma.log('Node "' + id + '" does not exist.'); | |
} | |
}); | |
return self; | |
}; | |
/** | |
* Inserts an edge in the graph. | |
* @param {string} id The edge ID. | |
* @param {string} source The ID of the edge source. | |
* @param {string} target The ID of the edge target. | |
* @param {object} params An object containing the different parameters | |
* of the edge. | |
* @return {Graph} Returns itself. | |
*/ | |
function addEdge(id, source, target, params) { | |
if (self.edgesIndex[id]) { | |
throw new Error('Edge "' + id + '" already exists.'); | |
} | |
if (!self.nodesIndex[source]) { | |
var s = 'Edge\'s source "' + source + '" does not exist yet.'; | |
throw new Error(s); | |
} | |
if (!self.nodesIndex[target]) { | |
var s = 'Edge\'s target "' + target + '" does not exist yet.'; | |
throw new Error(s); | |
} | |
params = params || {}; | |
var e = { | |
'source': self.nodesIndex[source], | |
'target': self.nodesIndex[target], | |
'size': 1, | |
'weight': 1, | |
'displaySize': 0.5, | |
'label': id.toString(), | |
'id': id.toString(), | |
'hidden': false, | |
'attr': {} | |
}; | |
e['source']['degree']++; | |
e['source']['outDegree']++; | |
e['target']['degree']++; | |
e['target']['inDegree']++; | |
for (var k in params) { | |
switch (k) { | |
case 'id': | |
case 'source': | |
case 'target': | |
break; | |
case 'hidden': | |
e[k] = !!params[k]; | |
break; | |
case 'size': | |
case 'weight': | |
e[k] = +params[k]; | |
break; | |
case 'color': | |
e[k] = params[k].toString(); | |
break; | |
case 'type': | |
e[k] = params[k].toString(); | |
break; | |
case 'label': | |
e[k] = params[k]; | |
break; | |
default: | |
e['attr'][k] = params[k]; | |
} | |
} | |
self.edges.push(e); | |
self.edgesIndex[id.toString()] = e; | |
return self; | |
}; | |
/** | |
* Generates the clone of a edge, to make it easier to be exported. | |
* @private | |
* @param {Object} edge The edge to clone. | |
* @return {Object} The clone of the edge. | |
*/ | |
function cloneEdge(edge) { | |
return { | |
'source': edge['source']['id'], | |
'target': edge['target']['id'], | |
'size': edge['size'], | |
'type': edge['type'], | |
'weight': edge['weight'], | |
'displaySize': edge['displaySize'], | |
'label': edge['label'], | |
'hidden': edge['hidden'], | |
'id': edge['id'], | |
'attr': edge['attr'], | |
'color': edge['color'] | |
}; | |
}; | |
/** | |
* Checks the clone of an edge, and inserts its values when possible. For | |
* example, it is possible to modify the label or the type of an edge, but it | |
* is not possible to modify its display values or its id. | |
* @private | |
* @param {Object} edge The original edge. | |
* @param {Object} copy The clone. | |
* @return {Graph} Returns itself. | |
*/ | |
function checkEdge(edge, copy) { | |
for (var k in copy) { | |
switch (k) { | |
case 'id': | |
case 'displaySize': | |
break; | |
case 'weight': | |
case 'size': | |
edge[k] = +copy[k]; | |
break; | |
case 'source': | |
case 'target': | |
edge[k] = self.nodesIndex[k] || edge[k]; | |
break; | |
case 'hidden': | |
edge[k] = !!copy[k]; | |
break; | |
case 'color': | |
case 'label': | |
case 'type': | |
edge[k] = (copy[k] || '').toString(); | |
break; | |
default: | |
edge['attr'][k] = copy[k]; | |
} | |
} | |
return self; | |
}; | |
/** | |
* Deletes one or several edges from the graph. | |
* @param {(string|Array.<string>)} v A string ID, or an Array of several | |
* IDs. | |
* @return {Graph} Returns itself. | |
*/ | |
function dropEdge(v) { | |
var a = (v instanceof Array ? v : [v]) || []; | |
a.forEach(function(id) { | |
if (self.edgesIndex[id]) { | |
self.edgesIndex[id]['source']['degree']--; | |
self.edgesIndex[id]['source']['outDegree']--; | |
self.edgesIndex[id]['target']['degree']--; | |
self.edgesIndex[id]['target']['inDegree']--; | |
var index = null; | |
self.edges.some(function(n, i) { | |
if (n['id'] == id) { | |
index = i; | |
return true; | |
} | |
return false; | |
}); | |
index != null && self.edges.splice(index, 1); | |
delete self.edgesIndex[id]; | |
}else { | |
sigma.log('Edge "' + id + '" does not exist.'); | |
} | |
}); | |
return self; | |
}; | |
/** | |
* Deletes every nodes and edges from the graph. | |
* @return {Graph} Returns itself. | |
*/ | |
function empty() { | |
self.nodes = []; | |
self.nodesIndex = {}; | |
self.edges = []; | |
self.edgesIndex = {}; | |
return self; | |
}; | |
/** | |
* Computes the display x, y and size of each node, relatively to the | |
* original values and the borders determined in the parameters, such as | |
* each node is in the described area. | |
* @param {number} w The area width (actually the width of the DOM | |
* root). | |
* @param {number} h The area height (actually the height of the | |
* DOM root). | |
* @param {boolean} parseNodes Indicates if the nodes have to be parsed. | |
* @param {boolean} parseEdges Indicates if the edges have to be parsed. | |
* @return {Graph} Returns itself. | |
*/ | |
function rescale(w, h, parseNodes, parseEdges) { | |
var weightMax = 0, sizeMax = 0; | |
parseNodes && self.nodes.forEach(function(node) { | |
sizeMax = Math.max(node['size'], sizeMax); | |
}); | |
parseEdges && self.edges.forEach(function(edge) { | |
weightMax = Math.max(edge['size'], weightMax); | |
}); | |
sizeMax = sizeMax || 1; | |
weightMax = weightMax || 1; | |
// Recenter the nodes: | |
var xMin, xMax, yMin, yMax; | |
parseNodes && self.nodes.forEach(function(node) { | |
xMax = Math.max(node['x'], xMax || node['x']); | |
xMin = Math.min(node['x'], xMin || node['x']); | |
yMax = Math.max(node['y'], yMax || node['y']); | |
yMin = Math.min(node['y'], yMin || node['y']); | |
}); | |
// First, we compute the scaling ratio, without considering the sizes | |
// of the nodes : Each node will have its center in the canvas, but might | |
// be partially out of it. | |
var scale = self.p.scalingMode == 'outside' ? | |
Math.max(w / Math.max(xMax - xMin, 1), | |
h / Math.max(yMax - yMin, 1)) : | |
Math.min(w / Math.max(xMax - xMin, 1), | |
h / Math.max(yMax - yMin, 1)); | |
// Then, we correct that scaling ratio considering a margin, which is | |
// basically the size of the biggest node. | |
// This has to be done as a correction since to compare the size of the | |
// biggest node to the X and Y values, we have to first get an | |
// approximation of the scaling ratio. | |
var margin = (self.p.maxNodeSize || sizeMax) / scale; | |
xMax += margin; | |
xMin -= margin; | |
yMax += margin; | |
yMin -= margin; | |
scale = self.p.scalingMode == 'outside' ? | |
Math.max(w / Math.max(xMax - xMin, 1), | |
h / Math.max(yMax - yMin, 1)) : | |
Math.min(w / Math.max(xMax - xMin, 1), | |
h / Math.max(yMax - yMin, 1)); | |
// Size homothetic parameters: | |
var a, b; | |
if (!self.p.maxNodeSize && !self.p.minNodeSize) { | |
a = 1; | |
b = 0; | |
}else if (self.p.maxNodeSize == self.p.minNodeSize) { | |
a = 0; | |
b = self.p.maxNodeSize; | |
}else { | |
a = (self.p.maxNodeSize - self.p.minNodeSize) / sizeMax; | |
b = self.p.minNodeSize; | |
} | |
var c, d; | |
if (!self.p.maxEdgeSize && !self.p.minEdgeSize) { | |
c = 1; | |
d = 0; | |
}else if (self.p.maxEdgeSize == self.p.minEdgeSize) { | |
c = 0; | |
d = self.p.minEdgeSize; | |
}else { | |
c = (self.p.maxEdgeSize - self.p.minEdgeSize) / weightMax; | |
d = self.p.minEdgeSize; | |
} | |
// Rescale the nodes: | |
parseNodes && self.nodes.forEach(function(node) { | |
node['displaySize'] = node['size'] * a + b; | |
if (!node['fixed']) { | |
node['displayX'] = (node['x'] - (xMax + xMin) / 2) * scale + w / 2; | |
node['displayY'] = (node['y'] - (yMax + yMin) / 2) * scale + h / 2; | |
} | |
}); | |
parseEdges && self.edges.forEach(function(edge) { | |
edge['displaySize'] = edge['size'] * c + d; | |
}); | |
return self; | |
}; | |
/** | |
* Translates the display values of the nodes and edges relatively to the | |
* scene position and zoom ratio. | |
* @param {number} sceneX The x position of the scene. | |
* @param {number} sceneY The y position of the scene. | |
* @param {number} ratio The zoom ratio of the scene. | |
* @param {boolean} parseNodes Indicates if the nodes have to be parsed. | |
* @param {boolean} parseEdges Indicates if the edges have to be parsed. | |
* @return {Graph} Returns itself. | |
*/ | |
function translate(sceneX, sceneY, ratio, parseNodes, parseEdges) { | |
var sizeRatio = Math.pow(ratio, self.p.nodesPowRatio); | |
parseNodes && self.nodes.forEach(function(node) { | |
if (!node['fixed']) { | |
node['displayX'] = node['displayX'] * ratio + sceneX; | |
node['displayY'] = node['displayY'] * ratio + sceneY; | |
} | |
node['displaySize'] = node['displaySize'] * sizeRatio; | |
}); | |
sizeRatio = Math.pow(ratio, self.p.edgesPowRatio); | |
parseEdges && self.edges.forEach(function(edge) { | |
edge['displaySize'] = edge['displaySize'] * sizeRatio; | |
}); | |
return self; | |
}; | |
/** | |
* Determines the borders of the graph as it will be drawn. It is used to | |
* avoid the user to drag the graph out of the canvas. | |
*/ | |
function setBorders() { | |
self.borders = {}; | |
self.nodes.forEach(function(node) { | |
self.borders.minX = Math.min( | |
self.borders.minX == undefined ? | |
node['displayX'] - node['displaySize'] : | |
self.borders.minX, | |
node['displayX'] - node['displaySize'] | |
); | |
self.borders.maxX = Math.max( | |
self.borders.maxX == undefined ? | |
node['displayX'] + node['displaySize'] : | |
self.borders.maxX, | |
node['displayX'] + node['displaySize'] | |
); | |
self.borders.minY = Math.min( | |
self.borders.minY == undefined ? | |
node['displayY'] - node['displaySize'] : | |
self.borders.minY, | |
node['displayY'] - node['displaySize'] | |
); | |
self.borders.maxY = Math.max( | |
self.borders.maxY == undefined ? | |
node['displayY'] - node['displaySize'] : | |
self.borders.maxY, | |
node['displayY'] - node['displaySize'] | |
); | |
}); | |
} | |
/** | |
* Checks which nodes are under the (mX, mY) points, representing the mouse | |
* position. | |
* @param {number} mX The mouse X position. | |
* @param {number} mY The mouse Y position. | |
* @return {Graph} Returns itself. | |
*/ | |
function checkHover(mX, mY) { | |
var dX, dY, s, over = [], out = []; | |
self.nodes.forEach(function(node) { | |
if (node['hidden']) { | |
node['hover'] = false; | |
return; | |
} | |
dX = Math.abs(node['displayX'] - mX); | |
dY = Math.abs(node['displayY'] - mY); | |
s = node['displaySize']; | |
var oldH = node['hover']; | |
var newH = dX < s && dY < s && Math.sqrt(dX * dX + dY * dY) < s; | |
if (oldH && !newH) { | |
node['hover'] = false; | |
out.push(node.id); | |
} else if (newH && !oldH) { | |
node['hover'] = true; | |
over.push(node.id); | |
} | |
}); | |
over.length && self.dispatch('overnodes', over); | |
out.length && self.dispatch('outnodes', out); | |
return self; | |
}; | |
/** | |
* Applies a function to a clone of each node (or indicated nodes), and then | |
* tries to apply the modifications made on the clones to the original nodes. | |
* @param {function(Object)} fun The function to execute. | |
* @param {?Array.<string>} ids An Array of node IDs (optional). | |
* @return {Graph} Returns itself. | |
*/ | |
function iterNodes(fun, ids) { | |
var a = ids ? ids.map(function(id) { | |
return self.nodesIndex[id]; | |
}) : self.nodes; | |
var aCopies = a.map(cloneNode); | |
aCopies.forEach(fun); | |
a.forEach(function(n, i) { | |
checkNode(n, aCopies[i]); | |
}); | |
return self; | |
}; | |
/** | |
* Applies a function to a clone of each edge (or indicated edges), and then | |
* tries to apply the modifications made on the clones to the original edges. | |
* @param {function(Object)} fun The function to execute. | |
* @param {?Array.<string>} ids An Array of edge IDs (optional). | |
* @return {Graph} Returns itself. | |
*/ | |
function iterEdges(fun, ids) { | |
var a = ids ? ids.map(function(id) { | |
return self.edgesIndex[id]; | |
}) : self.edges; | |
var aCopies = a.map(cloneEdge); | |
aCopies.forEach(fun); | |
a.forEach(function(e, i) { | |
checkEdge(e, aCopies[i]); | |
}); | |
return self; | |
}; | |
/** | |
* Returns a specific node clone or an array of specified node clones. | |
* @param {(string|Array.<string>)} ids The ID or an array of node IDs. | |
* @return {(Object|Array.<Object>)} The clone or the array of clones. | |
*/ | |
function getNodes(ids) { | |
var a = ((ids instanceof Array ? ids : [ids]) || []).map(function(id) { | |
return cloneNode(self.nodesIndex[id]); | |
}); | |
return (ids instanceof Array ? a : a[0]); | |
}; | |
/** | |
* Returns a specific edge clone or an array of specified edge clones. | |
* @param {(string|Array.<string>)} ids The ID or an array of edge IDs. | |
* @return {(Object|Array.<Object>)} The clone or the array of clones. | |
*/ | |
function getEdges(ids) { | |
var a = ((ids instanceof Array ? ids : [ids]) || []).map(function(id) { | |
return cloneEdge(self.edgesIndex[id]); | |
}); | |
return (ids instanceof Array ? a : a[0]); | |
}; | |
empty(); | |
this.addNode = addNode; | |
this.addEdge = addEdge; | |
this.dropNode = dropNode; | |
this.dropEdge = dropEdge; | |
this.iterEdges = iterEdges; | |
this.iterNodes = iterNodes; | |
this.getEdges = getEdges; | |
this.getNodes = getNodes; | |
this.empty = empty; | |
this.rescale = rescale; | |
this.translate = translate; | |
this.setBorders = setBorders; | |
this.checkHover = checkHover; | |
} | |
sigma.easing = { | |
linear: {}, | |
quadratic: {} | |
}; | |
sigma.easing.linear.easenone = function(k) { | |
return k; | |
}; | |
sigma.easing.quadratic.easein = function(k) { | |
return k * k; | |
}; | |
sigma.easing.quadratic.easeout = function(k) { | |
return - k * (k - 2); | |
}; | |
sigma.easing.quadratic.easeinout = function(k) { | |
if ((k *= 2) < 1) return 0.5 * k * k; | |
return - 0.5 * (--k * (k - 2) - 1); | |
}; | |
sigma.debugMode = 0; | |
sigma.log = function() { | |
if (sigma.debugMode == 1) { | |
for (var k in arguments) { | |
console.log(arguments[k]); | |
} | |
}else if (sigma.debugMode > 1) { | |
for (var k in arguments) { | |
throw new Error(arguments[k]); | |
} | |
} | |
return sigma; | |
}; | |
/** | |
* Add a function to the prototype of SigmaPublic, but with access to the | |
* Sigma class properties. | |
* @param {string} pluginName [description]. | |
* @param {function} caller [description]. | |
* @param {function(Sigma)} launcher [description]. | |
*/ | |
sigma.addPlugin = function(pluginName, caller, launcher) { | |
SigmaPublic.prototype[pluginName] = caller; | |
local.plugins.push(launcher); | |
}; | |
sigma.tools.drawRoundRect = function(ctx, x, y, w, h, ellipse, corners) { | |
var e = ellipse ? ellipse : 0; | |
var c = corners ? corners : []; | |
c = ((typeof c) == 'string') ? c.split(' ') : c; | |
var tl = e && (c.indexOf('topleft') >= 0 || | |
c.indexOf('top') >= 0 || | |
c.indexOf('left') >= 0); | |
var tr = e && (c.indexOf('topright') >= 0 || | |
c.indexOf('top') >= 0 || | |
c.indexOf('right') >= 0); | |
var bl = e && (c.indexOf('bottomleft') >= 0 || | |
c.indexOf('bottom') >= 0 || | |
c.indexOf('left') >= 0); | |
var br = e && (c.indexOf('bottomright') >= 0 || | |
c.indexOf('bottom') >= 0 || | |
c.indexOf('right') >= 0); | |
ctx.moveTo(x, y + e); | |
if (tl) { | |
ctx.arcTo(x, y, x + e, y, e); | |
}else { | |
ctx.lineTo(x, y); | |
} | |
if (tr) { | |
ctx.lineTo(x + w - e, y); | |
ctx.arcTo(x + w, y, x + w, y + e, e); | |
}else { | |
ctx.lineTo(x + w, y); | |
} | |
if (br) { | |
ctx.lineTo(x + w, y + h - e); | |
ctx.arcTo(x + w, y + h, x + w - e, y + h, e); | |
}else { | |
ctx.lineTo(x + w, y + h); | |
} | |
if (bl) { | |
ctx.lineTo(x + e, y + h); | |
ctx.arcTo(x, y + h, x, y + h - e, e); | |
}else { | |
ctx.lineTo(x, y + h); | |
} | |
ctx.lineTo(x, y + e); | |
}; | |
sigma.tools.getRGB = function(s, asArray) { | |
s = s.toString(); | |
var res = { | |
'r': 0, | |
'g': 0, | |
'b': 0 | |
}; | |
if (s.length >= 3) { | |
if (s.charAt(0) == '#') { | |
var l = s.length - 1; | |
if (l == 6) { | |
res = { | |
'r': parseInt(s.charAt(1) + s.charAt(2), 16), | |
'g': parseInt(s.charAt(3) + s.charAt(4), 16), | |
'b': parseInt(s.charAt(5) + s.charAt(5), 16) | |
}; | |
}else if (l == 3) { | |
res = { | |
'r': parseInt(s.charAt(1) + s.charAt(1), 16), | |
'g': parseInt(s.charAt(2) + s.charAt(2), 16), | |
'b': parseInt(s.charAt(3) + s.charAt(3), 16) | |
}; | |
} | |
} | |
} | |
if (asArray) { | |
res = [ | |
res['r'], | |
res['g'], | |
res['b'] | |
]; | |
} | |
return res; | |
}; | |
sigma.tools.rgbToHex = function(R, G, B) { | |
return sigma.tools.toHex(R) + sigma.tools.toHex(G) + sigma.tools.toHex(B); | |
}; | |
sigma.tools.toHex = function(n) { | |
n = parseInt(n, 10); | |
if (isNaN(n)) { | |
return '00'; | |
} | |
n = Math.max(0, Math.min(n, 255)); | |
return '0123456789ABCDEF'.charAt((n - n % 16) / 16) + | |
'0123456789ABCDEF'.charAt(n % 16); | |
}; | |
/** | |
* sigma.chronos manages frames insertion to simulate asynchronous computing. | |
* It has been designed to make possible to execute heavy computing tasks | |
* for the browser, without freezing it. | |
* @constructor | |
* @extends sigma.classes.Cascade | |
* @extends sigma.classes.EventDispatcher | |
* @this {sigma.chronos} | |
*/ | |
sigma.chronos = new (function() { | |
sigma.classes.EventDispatcher.call(this); | |
/** | |
* Represents "this", without the well-known scope issue. | |
* @private | |
* @type {sigma.chronos} | |
*/ | |
var self = this; | |
/** | |
* Indicates whether any task is actively running or not. | |
* @private | |
* @type {boolean} | |
*/ | |
var isRunning = false; | |
/** | |
* Indicates the FPS "goal", that will define the theoretical | |
* frame length. | |
* @private | |
* @type {number} | |
*/ | |
var fpsReq = 80; | |
/** | |
* Stores the last computed FPS value (FPS is computed only when any | |
* task is running). | |
* @private | |
* @type {number} | |
*/ | |
var lastFPS = 0; | |
/** | |
* The number of frames inserted since the last start. | |
* @private | |
* @type {number} | |
*/ | |
var framesCount = 0; | |
/** | |
* The theoretical frame time. | |
* @private | |
* @type {number} | |
*/ | |
var frameTime = 1000 / fpsReq; | |
/** | |
* The theoretical frame length, minus the last measured delay. | |
* @private | |
* @type {number} | |
*/ | |
var correctedFrameTime = frameTime; | |
/** | |
* The measured length of the last frame. | |
* @private | |
* @type {number} | |
*/ | |
var effectiveTime = 0; | |
/** | |
* The time passed since the last runTasks action. | |
* @private | |
* @type {number} | |
*/ | |
var currentTime = 0; | |
/** | |
* The time when the last frame was inserted. | |
* @private | |
* @type {number} | |
*/ | |
var startTime = 0; | |
/** | |
* The difference between the theoretical frame length and the | |
* last measured frame length. | |
* @private | |
* @type {number} | |
*/ | |
var delay = 0; | |
/** | |
* The container of all active generators. | |
* @private | |
* @type {Object.<string, Object>} | |
*/ | |
var generators = {}; | |
/** | |
* The array of all the referenced and active tasks. | |
* @private | |
* @type {Array.<Object>} | |
*/ | |
var tasks = []; | |
/** | |
* The array of all the referenced and queued tasks. | |
* @private | |
* @type {Array.<Object>} | |
*/ | |
var queuedTasks = []; | |
/** | |
* The index of the next task to execute. | |
* @private | |
* @type {number} | |
*/ | |
var taskIndex = 0; | |
/** | |
* Inserts a frame before executing the callback. | |
* @param {function()} callback The callback to execute after having | |
* inserted the frame. | |
* @return {sigma.chronos} Returns itself. | |
*/ | |
function insertFrame(callback) { | |
window.setTimeout(callback, 0); | |
return self; | |
} | |
/** | |
* The local method that executes routine, and inserts frames when needed. | |
* It dispatches a "frameinserted" event after having inserted any frame, | |
* and an "insertframe" event before. | |
* @private | |
*/ | |
function frameInserter() { | |
self.dispatch('frameinserted'); | |
while (isRunning && tasks.length && routine()) {} | |
if (!isRunning || !tasks.length) { | |
stopTasks(); | |
} else { | |
startTime = (new Date()).getTime(); | |
framesCount++; | |
delay = effectiveTime - frameTime; | |
correctedFrameTime = frameTime - delay; | |
self.dispatch('insertframe'); | |
insertFrame(frameInserter); | |
} | |
}; | |
/** | |
* The local method that executes the tasks, and compares the current frame | |
* length to the ideal frame length. | |
* @private | |
* @return {boolean} Returns false if the current frame should be ended, | |
* and true else. | |
*/ | |
function routine() { | |
taskIndex = taskIndex % tasks.length; | |
if (!tasks[taskIndex].task()) { | |
var n = tasks[taskIndex].taskName; | |
queuedTasks = queuedTasks.filter(function(e) { | |
(e.taskParent == n) && tasks.push({ | |
taskName: e.taskName, | |
task: e.task | |
}); | |
return e.taskParent != n; | |
}); | |
self.dispatch('killed', tasks.splice(taskIndex--, 1)[0]); | |
} | |
taskIndex++; | |
effectiveTime = (new Date()).getTime() - startTime; | |
return effectiveTime <= correctedFrameTime; | |
}; | |
/** | |
* Starts tasks execution. | |
* @return {sigma.chronos} Returns itself. | |
*/ | |
function runTasks() { | |
isRunning = true; | |
taskIndex = 0; | |
framesCount = 0; | |
startTime = (new Date()).getTime(); | |
currentTime = startTime; | |
self.dispatch('start'); | |
self.dispatch('insertframe'); | |
insertFrame(frameInserter); | |
return self; | |
}; | |
/** | |
* Stops tasks execution, and dispatch a "stop" event. | |
* @return {sigma.chronos} Returns itself. | |
*/ | |
function stopTasks() { | |
self.dispatch('stop'); | |
isRunning = false; | |
return self; | |
}; | |
/** | |
* A task is a function that will be executed continuously while it returns | |
* true. As soon as it return false, the task will be removed. | |
* If several tasks are present, they will be executed in parallele. | |
* This method will add the task to this execution process. | |
* @param {function(): boolean} task The task to add. | |
* @param {string} name The name of the worker, used for | |
* managing the different tasks. | |
* @param {boolean} autostart If true, sigma.chronos will start | |
* automatically if it is not working | |
* yet. | |
* @return {sigma.chronos} Returns itself. | |
*/ | |
function addTask(task, name, autostart) { | |
if (typeof task != 'function') { | |
throw new Error('Task "' + name + '" is not a function'); | |
} | |
tasks.push({ | |
taskName: name, | |
task: task | |
}); | |
isRunning = !!(isRunning || (autostart && runTasks()) || true); | |
return self; | |
}; | |
/** | |
* Will add a task that will be start to be executed as soon as a task | |
* named as the parent will be removed. | |
* @param {function(): boolean} task The task to add. | |
* @param {string} name The name of the worker, used for | |
* managing the different tasks. | |
* @param {string} parent The name of the parent task. | |
* @return {sigma.chronos} Returns itself. | |
*/ | |
function queueTask(task, name, parent) { | |
if (typeof task != 'function') { | |
throw new Error('Task "' + name + '" is not a function'); | |
} | |
if (!tasks.concat(queuedTasks).some(function(e) { | |
return e.taskName == parent; | |
})) { | |
throw new Error( | |
'Parent task "' + parent + '" of "' + name + '" is not attached.' | |
); | |
} | |
queuedTasks.push({ | |
taskParent: parent, | |
taskName: name, | |
task: task | |
}); | |
return self; | |
}; | |
/** | |
* Removes a task. | |
* @param {string} v If v is undefined, then every tasks will | |
* be removed. If not, each task named v will | |
* be removed. | |
* @param {number} queueStatus Determines the queued tasks behaviour. If 0, | |
* then nothing will happen. If 1, the tasks | |
* queued to any removed task will be triggered. | |
* If 2, the tasks queued to any removed task | |
* will be removed as well. | |
* @return {sigma.chronos} Returns itself. | |
*/ | |
function removeTask(v, queueStatus) { | |
if (v == undefined) { | |
tasks = []; | |
if (queueStatus == 1) { | |
queuedTasks = []; | |
}else if (queueStatus == 2) { | |
tasks = queuedTasks; | |
queuedTasks = []; | |
} | |
stopTasks(); | |
} else { | |
var n = (typeof v == 'string') ? v : ''; | |
tasks = tasks.filter(function(e) { | |
if ((typeof v == 'string') ? e.taskName == v : e.task == v) { | |
n = e.taskName; | |
return false; | |
} | |
return true; | |
}); | |
if (queueStatus > 0) { | |
queuedTasks = queuedTasks.filter(function(e) { | |
if (queueStatus == 1 && e.taskParent == n) { | |
tasks.push(e); | |
} | |
return e.taskParent != n; | |
}); | |
} | |
} | |
isRunning = !!(!tasks.length || (stopTasks() && false)); | |
return self; | |
}; | |
/** | |
* A generator is a pair task/condition. The task will be executed | |
* while it returns true. | |
* When it returns false, the condition will be tested. If | |
* the condition returns true, the task will be executed | |
* again at the next process iteration. If not, the generator | |
* is removed. | |
* If several generators are present, they will be executed one | |
* by one: When the first stops, the second will start, etc. When | |
* they are all ended, then the conditions will be tested to know | |
* which generators have to be started again. | |
* @param {string} id The generators ID. | |
* @param {function(): boolean} task The generator's task. | |
* @param {function(): boolean} condition The generator's condition. | |
* @return {sigma.chronos} Returns itself. | |
*/ | |
function addGenerator(id, task, condition) { | |
if (generators[id] != undefined) { | |
return self; | |
} | |
generators[id] = { | |
task: task, | |
condition: condition | |
}; | |
getGeneratorsCount(true) == 0 && startGenerators(); | |
return self; | |
}; | |
/** | |
* Removes a generator. It means that the task will continue being eecuted | |
* until it returns false, but then the | |
* condition will not be tested. | |
* @param {string} id The generator's ID. | |
* @return {sigma.chronos} Returns itself. | |
*/ | |
function removeGenerator(id) { | |
if (generators[id]) { | |
generators[id].on = false; | |
generators[id].del = true; | |
} | |
return self; | |
}; | |
/** | |
* Returns the number of generators. | |
* @private | |
* @param {boolean} running If true, returns the number of active | |
* generators instead. | |
* @return {sigma.chronos} Returns itself. | |
*/ | |
function getGeneratorsCount(running) { | |
return running ? | |
Object.keys(generators).filter(function(id) { | |
return !!generators[id].on; | |
}).length : | |
Object.keys(generators).length; | |
}; | |
/** | |
* Returns the array of the generators IDs. | |
* @return {array.<string>} The array of IDs. | |
*/ | |
function getGeneratorsIDs() { | |
return Object.keys(generators); | |
} | |
/** | |
* startGenerators is the method that manages which generator | |
* is the next to start when another one stops. It will dispatch | |
* a "stopgenerators" event if there is no more generator to start, | |
* and a "startgenerators" event else. | |
* @return {sigma.chronos} Returns itself. | |
*/ | |
function startGenerators() { | |
if (!Object.keys(generators).length) { | |
self.dispatch('stopgenerators'); | |
}else { | |
self.dispatch('startgenerators'); | |
self.unbind('killed', onTaskEnded); | |
insertFrame(function() { | |
for (var k in generators) { | |
generators[k].on = true; | |
addTask( | |
generators[k].task, | |
k, | |
false | |
); | |
} | |
}); | |
self.bind('killed', onTaskEnded).runTasks(); | |
} | |
return self; | |
}; | |
/** | |
* A callback triggered everytime the task of a generator stops, that will | |
* test the related generator's condition, and see if there is still any | |
* generator to start. | |
* @private | |
* @param {Object} e The sigma.chronos "killed" event. | |
*/ | |
function onTaskEnded(e) { | |
if (generators[e['content'].taskName] != undefined) { | |
if (generators[e['content'].taskName].del || | |
!generators[e['content'].taskName].condition()) { | |
delete generators[e['content'].taskName]; | |
}else { | |
generators[e['content'].taskName].on = false; | |
} | |
if (getGeneratorsCount(true) == 0) { | |
startGenerators(); | |
} | |
} | |
}; | |
/** | |
* Either set or returns the fpsReq property. This property determines | |
* the number of frames that should be inserted per second. | |
* @param {?number} v The frequency asked. | |
* @return {(Chronos|number)} Returns the frequency if v is undefined, and | |
* itself else. | |
*/ | |
function frequency(v) { | |
if (v != undefined) { | |
fpsReq = Math.abs(1 * v); | |
frameTime = 1000 / fpsReq; | |
framesCount = 0; | |
return self; | |
} else { | |
return fpsReq; | |
} | |
}; | |
/** | |
* Returns the actual average number of frames that are inserted per | |
* second. | |
* @return {number} The actual average FPS. | |
*/ | |
function getFPS() { | |
if (isRunning) { | |
lastFPS = | |
Math.round( | |
framesCount / | |
((new Date()).getTime() - currentTime) * | |
10000 | |
) / 10; | |
} | |
return lastFPS; | |
}; | |
/** | |
* Returns the number of tasks. | |
* @return {number} The number of tasks. | |
*/ | |
function getTasksCount() { | |
return tasks.length; | |
} | |
/** | |
* Returns the number of queued tasks. | |
* @return {number} The number of queued tasks. | |
*/ | |
function getQueuedTasksCount() { | |
return queuedTasks.length; | |
} | |
/** | |
* Returns how long sigma.chronos has active tasks running | |
* without interuption for, in ms. | |
* @return {number} The time chronos is running without interuption for. | |
*/ | |
function getExecutionTime() { | |
return startTime - currentTime; | |
} | |
this.frequency = frequency; | |
this.runTasks = runTasks; | |
this.stopTasks = stopTasks; | |
this.insertFrame = insertFrame; | |
this.addTask = addTask; | |
this.queueTask = queueTask; | |
this.removeTask = removeTask; | |
this.addGenerator = addGenerator; | |
this.removeGenerator = removeGenerator; | |
this.startGenerators = startGenerators; | |
this.getGeneratorsIDs = getGeneratorsIDs; | |
this.getFPS = getFPS; | |
this.getTasksCount = getTasksCount; | |
this.getQueuedTasksCount = getQueuedTasksCount; | |
this.getExecutionTime = getExecutionTime; | |
return this; | |
})(); | |
sigma.publicPrototype = SigmaPublic.prototype; | |
})(); | |
# www.robotstxt.org/ | # www.robotstxt.org/ |
# www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449 | # www.google.com/support/webmasters/bin/answer.py?hl=en&answer=156449 |
User-agent: * | User-agent: * |
Disallow: /admin/ | Disallow: /admin/ |
Sitemap: http://orgs.disclosurelo.gs/sitemap.xml.php |
<?php | <?php |
$schemas['agency'] = Array( | $schemas['agency'] = Array( |
"description" => "Representation of government agency and online transparency measures", | "description" => "Representation of government agency and online transparency measures", |
"type" => "object", | "type" => "object", |
"properties" => Array( | "properties" => Array( |
"name" => Array("type" => "string", "required" => true, "x-property" => "schema:name foaf:name", "x-title" => "Name", "description" => "Name, most recent and broadest"), | "name" => Array("type" => "string", "required" => true, "x-itemprop" => "name", "x-property" => "schema:name foaf:name", "x-title" => "Name", "description" => "Name, most recent and broadest"), |
"shortName" => Array("type" => "string", "required" => false, "x-title" => "Short Name", "description" => "Name shortened, usually to an acronym"), | "shortName" => Array("type" => "string", "required" => false, "x-title" => "Short Name", "description" => "Name shortened, usually to an acronym"), |
"foiEmail" => Array("type" => "string", "required" => false, "x-title" => "FOI Contact Email", "description" => "FOI contact email if not foi@"), | "foiEmail" => Array("type" => "string", "required" => false, "x-title" => "FOI Contact Email", "x-itemprop" => "email", "description" => "FOI contact email if not foi@"), |
"sameAs" => Array("type" => "array", "required" => false, "x-property"=>"owl:sameAs","x-title" => "Same As", "description" => "Same as other URLs/URIs for this entity", | "sameAs" => Array("type" => "array", "required" => false, "x-property"=>"owl:sameAs","x-title" => "Same As", "description" => "Same as other URLs/URIs for this entity", |
"items" => Array("type" => "string")), | "items" => Array("type" => "string")), |
"otherNames" => Array("type" => "array", "required" => true, "x-title" => "Past/Other Names", "description" => "Other names for organisation", | "otherNames" => Array("type" => "array", "required" => true, "x-title" => "Past/Other Names", "description" => "Other names for organisation", |
"items" => Array("type" => "string")), | "items" => Array("type" => "string")), |
"foiBodies" => Array("type" => "array", "required" => true, "x-title" => "FOI Bodies","x-property"=>"schema:members foaf:knows", "description" => "Organisational units within this agency that are subject to FOI Act but are not autonomous", | "foiBodies" => Array("type" => "array", "required" => true, "x-title" => "FOI Bodies","x-property"=>"schema:members foaf:knows", "description" => "Organisational units within this agency that are subject to FOI Act but are not autonomous", |
"items" => Array("type" => "string")), | "items" => Array("type" => "string")), |
"orgType" => Array("type" => "string", "required" => true, "x-title" => "Organisation Type", "description" => "Org type based on legal formation via FMA/CAC legislation etc."), | "orgType" => Array("type" => "string", "required" => true, "x-title" => "Organisation Type", "description" => "Org type based on legal formation via FMA/CAC legislation etc."), |
"parentOrg" => Array("type" => "string", "required" => true, "x-title" => "Parent Organisation", "description" => "Parent organisation, usually a department of state"), | "parentOrg" => Array("type" => "string", "required" => true, "x-title" => "Parent Organisation", "description" => "Parent organisation, usually a department of state"), |
"website" => Array("type" => "string", "required" => true, "x-title" => "Website", "x-property" => "schema:url foaf:homepage", "description" => "Website URL"), | "website" => Array("type" => "string", "required" => true, "x-title" => "Website", "x-itemprop" => "url", "x-property" => "schema:url foaf:homepage", "description" => "Website URL"), |
"abn" => Array("type" => "string", "required" => true, "x-title" => "Australian Business Number", "description" => "ABN from business register"), | "abn" => Array("type" => "string", "required" => true, "x-title" => "Australian Business Number", "description" => "ABN from business register"), |
"employees" => Array("type" => "string", "required" => true, "x-title" => "2010-2011 employees", "description" => "2010-2011 employees"), | "employees" => Array("type" => "string", "required" => true, "x-title" => "2010-2011 employees", "description" => "2010-2011 employees"), |
"contractListURL" => Array("type" => "string", "required" => true, "x-title" => "Contract Listing", "description" => "Departmental and agency contracts, <a href='http://www.aph.gov.au/senate/pubs/standing_orders/d05.htm'>mandated by the Senate</a>" ), | "contractListURL" => Array("type" => "string", "required" => true, "x-title" => "Contract Listing", "description" => "Departmental and agency contracts, <a href='http://www.aph.gov.au/senate/pubs/standing_orders/d05.htm'>mandated by the Senate</a>" ), |
"budgetURL" => Array("type" => "string", "required" => true,"x-title" => "Budget", "description" => "Portfolio Budget Statements and Portfolio Additional Estimates Statements"), | "budgetURL" => Array("type" => "string", "required" => true,"x-title" => "Budget", "description" => "Portfolio Budget Statements and Portfolio Additional Estimates Statements"), |
"grantsReportingURL" => Array("type" => "string", "required" => true, "x-title" => "Grants Awarded", | "grantsReportingURL" => Array("type" => "string", "required" => true, "x-title" => "Grants Awarded", |
"description" => "Departmental and agency grants <a href='http://www.aph.gov.au/senate/pubs/standing_orders/d05.htm'>mandated by the Senate</a> and <a href='http://www.finance.gov.au/publications/fmg-series/23-commonwealth-grant-guidelines.html'>Commonwealth grants guidelines</a> "), | "description" => "Departmental and agency grants <a href='http://www.aph.gov.au/senate/pubs/standing_orders/d05.htm'>mandated by the Senate</a> and <a href='http://www.finance.gov.au/publications/fmg-series/23-commonwealth-grant-guidelines.html'>Commonwealth grants guidelines</a> "), |
"annualReportURL" => Array("type" => "string", "required" => true, "x-title" => "Annual Report(s)", "description" => ""), | "annualReportURL" => Array("type" => "string", "required" => true, "x-title" => "Annual Report(s)", "description" => ""), |
"consultanciesURL" => Array("type" => "string", "required" => true, "x-title" => "Consultants Hired", "description" => ""), | "consultanciesURL" => Array("type" => "string", "required" => true, "x-title" => "Consultants Hired", "description" => ""), |
"legalExpenditureURL" => Array("type" => "string", "required" => true, "x-title" => "Legal Services Expenditure", "description" => "Legal Services Expenditure mandated by Legal Services Directions 2005"), | "legalExpenditureURL" => Array("type" => "string", "required" => true, "x-title" => "Legal Services Expenditure", "description" => "Legal Services Expenditure mandated by Legal Services Directions 2005"), |
"recordsListURL" => Array("type" => "string", "required" => true, "x-title" => "Files/Records Held", "description" => "Indexed lists of departmental and agency files, <a href='http://www.aph.gov.au/senate/pubs/standing_orders/d05.htm'>mandated by the Senate</a>"), | "recordsListURL" => Array("type" => "string", "required" => true, "x-title" => "Files/Records Held", "description" => "Indexed lists of departmental and agency files, <a href='http://www.aph.gov.au/senate/pubs/standing_orders/d05.htm'>mandated by the Senate</a>"), |
"FOIDocumentsURL" => Array("type" => "string", "required" => true, "x-title" => "FOI Documents Released", "description" => "FOI Disclosure Log URL"), | "FOIDocumentsURL" => Array("type" => "string", "required" => true, "x-title" => "FOI Documents Released", "description" => "FOI Disclosure Log URL"), |
"FOIDocumentsRSSURL" => Array("type" => "string", "required" => false, "x-title" => "RSS Feed of FOI Documents Released", "description" => "FOI Disclosure Log in RSS format"), | "FOIDocumentsRSSURL" => Array("type" => "string", "required" => false, "x-title" => "RSS Feed of FOI Documents Released", "description" => "FOI Disclosure Log in RSS format"), |
"hasFOIPDF" => Array("type" => "array", "required" => false, "x-title" => "Has FOI Documents Released in PDF", "description" => "FOI Disclosure Log contains any PDFs", | "hasFOIPDF" => Array("type" => "array", "required" => false, "x-title" => "Has FOI Documents Released in PDF", "description" => "FOI Disclosure Log contains any PDFs", |
"items" => Array("type" => "string")), | "items" => Array("type" => "string")), |
"infoPublicationSchemeURL" => Array("type" => "string", "required" => true, "x-title" => "Information Publication Scheme", "description" => ""), | "infoPublicationSchemeURL" => Array("type" => "string", "required" => true, "x-title" => "Information Publication Scheme", "description" => ""), |
"appointmentsURL" => Array("type" => "string", "required" => true, "x-title" => "Agency Appointments/Boards", "description" => "Departmental and agency appointments and vacancies , <a href='http://www.aph.gov.au/senate/pubs/standing_orders/d05.htm'>mandated by the Senate</a>"), | "appointmentsURL" => Array("type" => "string", "required" => true, "x-title" => "Agency Appointments/Boards", "description" => "Departmental and agency appointments and vacancies , <a href='http://www.aph.gov.au/senate/pubs/standing_orders/d05.htm'>mandated by the Senate</a>"), |
"advertisingURL" => Array("type" => "string", "required" => true, "x-title" => "Approved Advertising Campaigns", "description" => " Agency advertising and public information projects, <a href='http://www.aph.gov.au/senate/pubs/standing_orders/d05.htm'>mandated by the Senate</a> "), | "advertisingURL" => Array("type" => "string", "required" => true, "x-title" => "Approved Advertising Campaigns", "description" => " Agency advertising and public information projects, <a href='http://www.aph.gov.au/senate/pubs/standing_orders/d05.htm'>mandated by the Senate</a> "), |
"hasRSS" => Array("type" => "array", "required" => true, "x-title" => "Has RSS", "description" => ""), | "hasRSS" => Array("type" => "array", "required" => true, "x-title" => "Has RSS", "description" => ""), |
"hasBlog" => Array("type" => "array", "required" => true, "x-title" => "Has Blog", "description" => ""), | "hasBlog" => Array("type" => "array", "required" => true, "x-title" => "Has Blog", "description" => ""), |
"hasMobileApp" => Array("type" => "array", "required" => true, "x-title" => "Has Mobile App", "description" => ""), | "hasMobileApp" => Array("type" => "array", "required" => true, "x-title" => "Has Mobile App", "description" => ""), |
"hasMailingList" => Array("type" => "array", "required" => true, "x-title" => "Has Mailing List", "description" => "", | "hasMailingList" => Array("type" => "array", "required" => true, "x-title" => "Has Mailing List", "description" => "", |
"items" => Array("type" => "string")), | "items" => Array("type" => "string")), |
"hasTwitter" => Array("type" => "array", "required" => true, "x-title" => "Has Twitter", "description" => "", | "hasTwitter" => Array("type" => "array", "required" => true, "x-title" => "Has Twitter", "description" => "", |
"items" => Array("type" => "string")), | "items" => Array("type" => "string")), |
"hasFacebook" => Array("type" => "array", "required" => true, "x-title" => "Has Facebook", "description" => "", | "hasFacebook" => Array("type" => "array", "required" => true, "x-title" => "Has Facebook", "description" => "", |
"items" => Array("type" => "string")), | "items" => Array("type" => "string")), |
"hasYouTube" => Array("type" => "array", "required" => true, "x-title" => "Has YouTube", "description" => "", | "hasYouTube" => Array("type" => "array", "required" => true, "x-title" => "Has YouTube", "description" => "", |
"items" => Array("type" => "string")), | "items" => Array("type" => "string")), |
"hasFlickr" => Array("type" => "array", "required" => true, "x-title" => "Has Flickr", "description" => "", | "hasFlickr" => Array("type" => "array", "required" => true, "x-title" => "Has Flickr", "description" => "", |
"items" => Array("type" => "string")), | "items" => Array("type" => "string")), |
"hasCCBY" => Array("type" => "array", "required" => true, "x-title" => "Has CC-BY", "description" => "Has any page licenced Creative Commons - Attribution", | "hasCCBY" => Array("type" => "array", "required" => true, "x-title" => "Has CC-BY", "description" => "Has any page licenced Creative Commons - Attribution", |
"items" => Array("type" => "string")), | "items" => Array("type" => "string")), |
"hasRestrictiveLicence" => Array("type" => "array","required" => true, "x-title" => "Has Restrictive Licence", "description" => "Has any page licenced under terms more restrictive than Crown Copyright", | "hasRestrictiveLicence" => Array("type" => "array","required" => true, "x-title" => "Has Restrictive Licence", "description" => "Has any page licenced under terms more restrictive than Crown Copyright", |
"items" => Array("type" => "string")), | "items" => Array("type" => "string")), |
"hasPermissiveLicence" => Array("type" => "array","required" => true, "x-title" => "Has Permissive Licence", "description" => "Has any page licenced under terms more permissive than Crown Copyright but not clear CCBY", | "hasPermissiveLicence" => Array("type" => "array","required" => true, "x-title" => "Has Permissive Licence", "description" => "Has any page licenced under terms more permissive than Crown Copyright but not clear CCBY", |
"items" => Array("type" => "string")), | "items" => Array("type" => "string")), |
"hasCrownCopyright" => Array("type" => "array", "required" => true, "x-title" => "Has Standard Crown Copyright licence", "description" => "Has any page still licenced under the former Commonwealth Copyright Administration", | "hasCrownCopyright" => Array("type" => "array", "required" => true, "x-title" => "Has Standard Crown Copyright licence", "description" => "Has any page still licenced under the former Commonwealth Copyright Administration", |
"items" => Array("type" => "string")), | "items" => Array("type" => "string")), |
), | ), |
/* "org":{"type":"object", | /* "org":{"type":"object", |
"properties":{ | "properties":{ |
"organizationName":{"type":"string"}, | "organizationName":{"type":"string"}, |
"organizationUnit":{"type":"string"}}, | "organizationUnit":{"type":"string"}}, |
} | } |
} */ | } */ |
); | ); |
?> | ?> |
<?php | <?php |
include_once('include/common.inc.php'); | include_once('include/common.inc.php'); |
include_header(); | include_header('Scores'); |
$db = $server->get_db('disclosr-agencies'); | $db = $server->get_db('disclosr-agencies'); |
try { | try { |
$rows = $db->get_view("score", "score", null, true)->rows; | $rows = $db->get_view("score", "score", null, true)->rows; |
//print_r($rows); | //print_r($rows); |
foreach ($rows as $row) { | foreach ($rows as $row) { |
echo '<a href="getAgency.php?id='.$row->value->id.'">'.$row->value->name." ".$row->value->score."</a><br>"; | echo '<a href="getAgency.php?id='.$row->value->id.'">'.$row->value->name." ".$row->value->score."</a><br>"; |
} | } |
} catch (SetteeRestClientException $e) { | } catch (SetteeRestClientException $e) { |
setteErrorHandler($e); | setteErrorHandler($e); |
} | } |
include_footer(); | include_footer(); |
?> | ?> |
<?php | <?php |
include_once('include/common.inc.php'); | include_once('include/common.inc.php'); |
include_header(); | include_header('Search'); |
?> | ?> |
<div class="foundation-header"> | <div class="foundation-header"> |
<h1><a href="search.php">Search</a></h1> | <h1><a href="search.php">Search</a></h1> |
</div> | </div> |
<form> | <form> |
<input type="text" name="q" value="<?php if (isset($_REQUEST['q']))echo $_REQUEST['q'];?>"/> | <input type="text" name="q" value="<?php if (isset($_REQUEST['q']))echo $_REQUEST['q'];?>"/> |
<input type="submit"/> | <input type="submit"/> |
</form> | </form> |
<?php | <?php |
if (isset($_REQUEST['q'])) { | if (isset($_REQUEST['q'])) { |
$request = Requests::get($serverAddr."disclosr-documents/_fti/_design/lucene/by_all?include_docs=true&q=".$_REQUEST['q']); | $request = Requests::get($serverAddr."disclosr-documents/_fti/_design/lucene/by_all?include_docs=true&q=".$_REQUEST['q']); |
$results = json_decode($request->body); | $results = json_decode($request->body); |
$db = $server->get_db('disclosr-documents'); | $db = $server->get_db('disclosr-documents'); |
foreach ($results->rows as $result) { | foreach ($results->rows as $result) { |
//print_r($result); | //print_r($result); |
//$row = $db->get($result->id); | //$row = $db->get($result->id); |
echo $result->doc->_id." ".$result->doc->url."<br>".PHP_EOL; | echo $result->doc->_id." ".$result->doc->url."<br>".PHP_EOL; |
} | } |
} | } |
include_footer(); | include_footer(); |
?> | ?> |
<?php | |
include ('include/common.inc.php'); | |
$last_updated = date('Y-m-d', @filemtime('cbrfeed.zip')); | |
header("Content-Type: text/xml"); | |
echo "<?xml version='1.0' encoding='UTF-8'?>"; | |
echo '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">' . "\n"; | |
echo " <url><loc>" . local_url() . "index.php</loc><priority>1.0</priority></url>\n"; | |
foreach (scandir("./") as $file) { | |
if (strpos($file, ".php") !== false && $file != "index.php" && $file != "sitemap.xml.php") | |
echo " <url><loc>" . local_url() . "$file</loc><priority>0.3</priority></url>\n"; | |
} | |
$db = $server->get_db('disclosr-agencies'); | |
try { | |
$rows = $db->get_view("app", "byCanonicalName")->rows; | |
foreach ($rows as $row) { | |
echo '<url><loc>' . local_url() . 'getAgency.php?id=' . $row->value->_id . "</loc><priority>0.6</priority></url>\n"; | |
} | |
} catch (SetteeRestClientException $e) { | |
setteErrorHandler($e); | |
} | |
echo '</urlset>'; | |
?> | |
<?php | |
include_once('include/common.inc.php'); | |
include_header('Webserver and Accessiblity'); | |
echo "<table> | |
<tr><th>name</th><th>webserver</th><th>accessiblity errors</th></tr>"; | |
$agenciesdb = $server->get_db('disclosr-agencies'); | |
$docsdb = $server->get_db('disclosr-documents'); | |
try { | |
$rows = $agenciesdb->get_view("app", "all", null, true)->rows; | |
if ($rows) { | |
foreach ($rows as $row) { | |
echo "<tr><td>" . $row->value->name . "</td>"; | |
if (isset($row->value->website)) { | |
try { | |
$website = $docsdb->get(md5($row->value->website)); | |
$serverParts = explode(" ",$website->web_server); | |
echo "<td>" . $serverParts[0] . "</td>"; | |
if (!isset($website->validation)) { | |
echo "<td>?</td>"; | |
} else { | |
if ($website->validation == "") { | |
echo "<td>No error</td>"; | |
} else { | |
echo "<td><pre>" . str_replace("<", "<", $website->validation) . "</pre></td>"; | |
} | |
} | |
} catch (SetteeRestClientException $e) { | |
// setteErrorHandler($e); | |
} | |
} | |
echo "</tr>"; | |
} | |
} | |
} catch (SetteeRestClientException $e) { | |
setteErrorHandler($e); | |
} | |
include_footer(); | |
?> |