mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'cppTrav' of ssh://github.com/arangodb/arangodb into cppTrav
This commit is contained in:
commit
cb9fa2a342
|
@ -45,22 +45,75 @@ using namespace std;
|
||||||
using namespace triagens::basics;
|
using namespace triagens::basics;
|
||||||
using namespace triagens::arango;
|
using namespace triagens::arango;
|
||||||
|
|
||||||
struct WeightInfo {
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
string keyWeight;
|
/// @brief callback to weight an edge
|
||||||
double defaultWeight;
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
bool usesWeight;
|
|
||||||
|
|
||||||
WeightInfo(
|
typedef function<double(TRI_doc_mptr_copy_t& edge)> WeightCalculatorFunction;
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief Define edge weight by the number of hops.
|
||||||
|
/// Respectively 1 for any edge.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
class HopWeightCalculator {
|
||||||
|
public:
|
||||||
|
HopWeightCalculator() {};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief Callable weight calculator for edge
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
double operator() (TRI_doc_mptr_copy_t& edge) {
|
||||||
|
return 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief Define edge weight by ony special attribute.
|
||||||
|
/// Respectively 1 for any edge.
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
class AttributeWeightCalculator {
|
||||||
|
|
||||||
|
TRI_shape_pid_t _shape_pid;
|
||||||
|
double _defaultWeight;
|
||||||
|
TRI_shaper_t* _shaper;
|
||||||
|
|
||||||
|
public:
|
||||||
|
AttributeWeightCalculator(
|
||||||
string keyWeight,
|
string keyWeight,
|
||||||
double defaultWeight
|
double defaultWeight,
|
||||||
) :
|
TRI_shaper_t* shaper
|
||||||
keyWeight(keyWeight), defaultWeight(defaultWeight), usesWeight(true)
|
) : _defaultWeight(defaultWeight),
|
||||||
|
_shaper(shaper)
|
||||||
{
|
{
|
||||||
|
_shape_pid = _shaper->lookupAttributePathByName(_shaper, keyWeight.c_str());
|
||||||
};
|
};
|
||||||
|
|
||||||
WeightInfo() : usesWeight(false) {
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief Callable weight calculator for edge
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
double operator() (TRI_doc_mptr_copy_t& edge) {
|
||||||
|
if (_shape_pid == 0) {
|
||||||
|
return _defaultWeight;
|
||||||
|
}
|
||||||
|
TRI_shape_sid_t sid;
|
||||||
|
TRI_EXTRACT_SHAPE_IDENTIFIER_MARKER(sid, edge.getDataPtr());
|
||||||
|
TRI_shape_access_t const* accessor = TRI_FindAccessorVocShaper(_shaper, sid, _shape_pid);
|
||||||
|
TRI_shaped_json_t shapedJson;
|
||||||
|
TRI_EXTRACT_SHAPED_JSON_MARKER(shapedJson, edge.getDataPtr());
|
||||||
|
TRI_shaped_json_t resultJson;
|
||||||
|
TRI_ExecuteShapeAccessor(accessor, &shapedJson, &resultJson);
|
||||||
|
if (resultJson._sid != TRI_SHAPE_NUMBER) {
|
||||||
|
return _defaultWeight;
|
||||||
|
}
|
||||||
|
TRI_json_t* json = TRI_JsonShapedJson(_shaper, &resultJson);
|
||||||
|
if (json == nullptr) {
|
||||||
|
return _defaultWeight;
|
||||||
|
}
|
||||||
|
double realResult = json->_value._number;
|
||||||
|
TRI_FreeJson(_shaper->_memoryZone, json);
|
||||||
|
return realResult ;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class SimpleEdgeExpander {
|
class SimpleEdgeExpander {
|
||||||
|
@ -90,33 +143,20 @@ class SimpleEdgeExpander {
|
||||||
CollectionNameResolver* resolver;
|
CollectionNameResolver* resolver;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief this is the information required to compute weight by a given
|
/// @brief the weight calculation function
|
||||||
/// attribute. It contains an indicator if weight should be used.
|
|
||||||
/// Also it includes a default weight and the name of the weight
|
|
||||||
/// attribute.
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
WeightInfo weightInfo;
|
WeightCalculatorFunction weighter;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
SimpleEdgeExpander(TRI_edge_direction_e direction,
|
|
||||||
TRI_document_collection_t* edgeCollection,
|
|
||||||
string edgeCollectionName,
|
|
||||||
CollectionNameResolver* resolver)
|
|
||||||
: direction(direction), edgeCollection(edgeCollection),
|
|
||||||
resolver(resolver)
|
|
||||||
{
|
|
||||||
edgeIdPrefix = edgeCollectionName + "/";
|
|
||||||
};
|
|
||||||
|
|
||||||
SimpleEdgeExpander(TRI_edge_direction_e direction,
|
SimpleEdgeExpander(TRI_edge_direction_e direction,
|
||||||
TRI_document_collection_t* edgeCollection,
|
TRI_document_collection_t* edgeCollection,
|
||||||
string edgeCollectionName,
|
string edgeCollectionName,
|
||||||
CollectionNameResolver* resolver,
|
CollectionNameResolver* resolver,
|
||||||
WeightInfo weightInfo)
|
WeightCalculatorFunction weighter)
|
||||||
: direction(direction), edgeCollection(edgeCollection),
|
: direction(direction), edgeCollection(edgeCollection),
|
||||||
resolver(resolver), weightInfo(weightInfo)
|
resolver(resolver), weighter(weighter)
|
||||||
{
|
{
|
||||||
edgeIdPrefix = edgeCollectionName + "/";
|
edgeIdPrefix = edgeCollectionName + "/";
|
||||||
};
|
};
|
||||||
|
@ -170,17 +210,16 @@ class SimpleEdgeExpander {
|
||||||
unordered_map<Traverser::VertexId, size_t> candidates;
|
unordered_map<Traverser::VertexId, size_t> candidates;
|
||||||
Traverser::VertexId from;
|
Traverser::VertexId from;
|
||||||
Traverser::VertexId to;
|
Traverser::VertexId to;
|
||||||
if (weightInfo.usesWeight) {
|
|
||||||
for (size_t j = 0; j < edges.size(); ++j) {
|
for (size_t j = 0; j < edges.size(); ++j) {
|
||||||
from = extractFromId(edges[j]);
|
from = extractFromId(edges[j]);
|
||||||
to = extractToId(edges[j]);
|
to = extractToId(edges[j]);
|
||||||
double currentWeight = weightInfo.defaultWeight;
|
double currentWeight = weighter(edges[j]);
|
||||||
if (from != source) {
|
auto inserter = [&](Traverser::VertexId s, Traverser::VertexId t) {
|
||||||
auto cand = candidates.find(from);
|
auto cand = candidates.find(t);
|
||||||
if (cand == candidates.end()) {
|
if (cand == candidates.end()) {
|
||||||
// Add weight
|
// Add weight
|
||||||
result.emplace_back(to, from, currentWeight, extractEdgeId(edges[j]));
|
result.emplace_back(t, s, currentWeight, extractEdgeId(edges[j]));
|
||||||
candidates.emplace(from, result.size() - 1);
|
candidates.emplace(t, result.size() - 1);
|
||||||
} else {
|
} else {
|
||||||
// Compare weight
|
// Compare weight
|
||||||
auto oldWeight = result[cand->second].weight();
|
auto oldWeight = result[cand->second].weight();
|
||||||
|
@ -188,40 +227,12 @@ class SimpleEdgeExpander {
|
||||||
result[cand->second].setWeight(currentWeight);
|
result[cand->second].setWeight(currentWeight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
else if (to != source) {
|
|
||||||
auto cand = candidates.find(to);
|
|
||||||
if (cand == candidates.end()) {
|
|
||||||
// Add weight
|
|
||||||
result.emplace_back(to, from, currentWeight, extractEdgeId(edges[j]));
|
|
||||||
candidates.emplace(to, result.size() - 1);
|
|
||||||
} else {
|
|
||||||
auto oldWeight = result[cand->second].weight();
|
|
||||||
if (currentWeight < oldWeight) {
|
|
||||||
result[cand->second].setWeight(currentWeight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (size_t j = 0; j < edges.size(); ++j) {
|
|
||||||
from = extractFromId(edges[j]);
|
|
||||||
to = extractToId(edges[j]);
|
|
||||||
if (from != source) {
|
if (from != source) {
|
||||||
auto cand = candidates.find(from);
|
inserter(to, from);
|
||||||
if (cand == candidates.end()) {
|
|
||||||
result.emplace_back(from, to, 1, extractEdgeId(edges[j]));
|
|
||||||
candidates.emplace(from, result.size()-1);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (to != source) {
|
else if (to != source) {
|
||||||
auto cand = candidates.find(to);
|
inserter(from, to);
|
||||||
if (cand == candidates.end()) {
|
|
||||||
result.emplace_back(to, from, 1, extractEdgeId(edges[j]));
|
|
||||||
candidates.emplace(to, result.size()-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -283,7 +294,7 @@ void TRI_RunDijkstraSearch (const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||||
vector<string> writeCollections;
|
vector<string> writeCollections;
|
||||||
|
|
||||||
double lockTimeout = (double) (TRI_TRANSACTION_DEFAULT_LOCK_TIMEOUT / 1000000ULL);
|
double lockTimeout = (double) (TRI_TRANSACTION_DEFAULT_LOCK_TIMEOUT / 1000000ULL);
|
||||||
bool embed = false;
|
bool embed = true;
|
||||||
bool waitForSync = false;
|
bool waitForSync = false;
|
||||||
|
|
||||||
// get the vertex collection
|
// get the vertex collection
|
||||||
|
@ -409,15 +420,16 @@ void TRI_RunDijkstraSearch (const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||||
|
|
||||||
unique_ptr<SimpleEdgeExpander> forwardExpander;
|
unique_ptr<SimpleEdgeExpander> forwardExpander;
|
||||||
unique_ptr<SimpleEdgeExpander> backwardExpander;
|
unique_ptr<SimpleEdgeExpander> backwardExpander;
|
||||||
|
WeightCalculatorFunction weighter;
|
||||||
if (useWeight) {
|
if (useWeight) {
|
||||||
forwardExpander.reset(new SimpleEdgeExpander(forward, ecol, edgeCollectionName,
|
weighter = AttributeWeightCalculator(
|
||||||
&resolver1, WeightInfo(weightAttribute, defaultWeight)));
|
weightAttribute, defaultWeight, ecol->getShaper()
|
||||||
backwardExpander.reset(new SimpleEdgeExpander(backward, ecol, edgeCollectionName,
|
);
|
||||||
&resolver2, WeightInfo(weightAttribute, defaultWeight)));
|
|
||||||
} else {
|
} else {
|
||||||
forwardExpander.reset(new SimpleEdgeExpander(forward, ecol, edgeCollectionName, &resolver1));
|
weighter = HopWeightCalculator();
|
||||||
backwardExpander.reset(new SimpleEdgeExpander(backward, ecol, edgeCollectionName, &resolver2));
|
|
||||||
}
|
}
|
||||||
|
forwardExpander.reset(new SimpleEdgeExpander(forward, ecol, edgeCollectionName, &resolver1, weighter));
|
||||||
|
backwardExpander.reset(new SimpleEdgeExpander(backward, ecol, edgeCollectionName, &resolver2, weighter));
|
||||||
|
|
||||||
|
|
||||||
Traverser traverser(*forwardExpander, *backwardExpander, bidirectional);
|
Traverser traverser(*forwardExpander, *backwardExpander, bidirectional);
|
||||||
|
|
|
@ -2806,7 +2806,7 @@ void TRI_InitV8VocBridge (v8::Isolate* isolate,
|
||||||
TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("AQL_QUERY_SLEEP"), JS_QuerySleepAql, true);
|
TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("AQL_QUERY_SLEEP"), JS_QuerySleepAql, true);
|
||||||
TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("AQL_QUERY_IS_KILLED"), JS_QueryIsKilledAql, true);
|
TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("AQL_QUERY_IS_KILLED"), JS_QueryIsKilledAql, true);
|
||||||
|
|
||||||
TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("AQL_SHORTEST_PATH"), JS_QueryShortestPath, true);
|
TRI_AddGlobalFunctionVocbase(isolate, context, TRI_V8_ASCII_STRING("CPP_SHORTEST_PATH"), JS_QueryShortestPath, true);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4328,8 +4328,8 @@ div.resizecontainer {
|
||||||
width: 2258px; } }
|
width: 2258px; } }
|
||||||
|
|
||||||
div.centralRow {
|
div.centralRow {
|
||||||
margin-top: 65px;
|
margin-top: 40px;
|
||||||
margin-bottom: 65px; }
|
margin-bottom: 40px; }
|
||||||
|
|
||||||
div.centralContent {
|
div.centralContent {
|
||||||
background-color: rgba(0, 0, 0, 0.0675);
|
background-color: rgba(0, 0, 0, 0.0675);
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
|
|
||||||
window.Airports = Backbone.Collection.extend({
|
window.Airports = Backbone.Collection.extend({
|
||||||
|
|
||||||
initialize: function() {
|
initialize: function(options) {
|
||||||
|
this.collectionName = options.collectionName;
|
||||||
},
|
},
|
||||||
|
|
||||||
getAirports: function(callback) {
|
getAirports: function(callback) {
|
||||||
|
@ -35,6 +36,50 @@
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getShortestFlight: function(from, to, callback) {
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "/_api/cursor",
|
||||||
|
data: JSON.stringify({
|
||||||
|
query: "RETURN SHORTEST_PATH(@@airports,@@flights,@start,@dest,'outbound',{})",
|
||||||
|
bindVars: {
|
||||||
|
"@flights": this.collectionName,
|
||||||
|
"@airports": "airports",
|
||||||
|
"start": "airports/" + from,
|
||||||
|
"dest": "airports/" + to
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
contentType: "application/json",
|
||||||
|
processData: false,
|
||||||
|
success: function (data) {
|
||||||
|
callback(data.result[0]);
|
||||||
|
},
|
||||||
|
error: function (data) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
getFlightDistribution: function(callback) {
|
||||||
|
$.ajax({
|
||||||
|
type: "POST",
|
||||||
|
url: "/_api/cursor",
|
||||||
|
data: JSON.stringify({
|
||||||
|
query: "FOR f IN @@flights COLLECT dest = f._to " +
|
||||||
|
"WITH COUNT INTO n SORT n RETURN {Dest: SPLIT(dest, '/')[1], count: n}",
|
||||||
|
bindVars: {
|
||||||
|
"@flights": this.collectionName
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
contentType: "application/json",
|
||||||
|
processData: false,
|
||||||
|
success: function (data) {
|
||||||
|
callback(data.result);
|
||||||
|
},
|
||||||
|
error: function (data) {
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
getFlightsForAirport: function(airport, callback) {
|
getFlightsForAirport: function(airport, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
|
@ -42,9 +87,12 @@
|
||||||
type: "POST",
|
type: "POST",
|
||||||
url: "/_api/cursor",
|
url: "/_api/cursor",
|
||||||
data: JSON.stringify({
|
data: JSON.stringify({
|
||||||
query: "for f in flights12 filter f.Origin == @airport COLLECT dest = f.Dest " +
|
query: "for f in @@flights filter f._from == @airport COLLECT dest = f._to " +
|
||||||
"WITH COUNT INTO n SORT n RETURN {Dest: dest, count: n}",
|
"WITH COUNT INTO n SORT n RETURN {Dest: SPLIT(dest, '/')[1], count: n}",
|
||||||
bindVars: {"airport": airport}
|
bindVars: {
|
||||||
|
"airport": "airports/" + airport,
|
||||||
|
"@flights": this.collectionName
|
||||||
|
}
|
||||||
}),
|
}),
|
||||||
contentType: "application/json",
|
contentType: "application/json",
|
||||||
processData: false,
|
processData: false,
|
||||||
|
|
|
@ -26,13 +26,18 @@
|
||||||
"userManagement": "userManagement",
|
"userManagement": "userManagement",
|
||||||
"userProfile": "userProfile",
|
"userProfile": "userProfile",
|
||||||
"logs": "logs",
|
"logs": "logs",
|
||||||
"demo": "demo"
|
"demo": "demo",
|
||||||
|
"demo/:collection": "demo"
|
||||||
},
|
},
|
||||||
|
|
||||||
demo: function () {
|
demo: function (collection) {
|
||||||
|
if (!collection) {
|
||||||
|
collection = "flights";
|
||||||
|
}
|
||||||
if (!this.demoView) {
|
if (!this.demoView) {
|
||||||
this.demoView = new window.DemoView({});
|
this.demoView = new window.DemoView({
|
||||||
|
collectionName: collection
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.demoView.render();
|
this.demoView.render();
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="search-field">
|
<div class="search-field">
|
||||||
<input type="text" id="demoSearchInput" class="search-input" placeholder="Search..."><img id="demoSearchSubmit" class="search-submit-icon">
|
<input type="text" id="demoSearchInput" class="search-input" placeholder="Search..."><img id="demoSearchSubmit" class="search-submit-icon">
|
||||||
|
<!--<div id="searchResults" class="demo-dropdown-menu"><ul></ul></div>-->
|
||||||
</div>
|
</div>
|
||||||
<div class="styled-select">
|
<div class="styled-select">
|
||||||
<select id="flightQuerySelect" class="query-select" style="margin-top: 5px; height: 25px">
|
<select id="flightQuerySelect" class="query-select" style="margin-top: 5px; height: 25px">
|
||||||
|
|
|
@ -35,22 +35,25 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
lineColors: [
|
lineColors: [
|
||||||
'rgb(255,255,229)',
|
'rgb(255,255,229)'
|
||||||
'rgb(255,247,188)',
|
/*
|
||||||
'rgb(254,227,145)',
|
- 'rgb(255,255,229)',
|
||||||
'rgb(254,196,79)',
|
- 'rgb(255,247,188)',
|
||||||
'rgb(254,153,41)',
|
- 'rgb(254,227,145)',
|
||||||
'rgb(236,112,20)',
|
- 'rgb(254,196,79)',
|
||||||
'rgb(204,76,2)',
|
- 'rgb(254,153,41)',
|
||||||
'rgb(153,52,4)',
|
- 'rgb(236,112,20)',
|
||||||
'rgb(102,37,6)'
|
- 'rgb(204,76,2)',
|
||||||
|
- 'rgb(153,52,4)',
|
||||||
|
- 'rgb(102,37,6)'
|
||||||
|
*/
|
||||||
],
|
],
|
||||||
|
|
||||||
airportColor: "#222222",
|
airportColor: "#222222",
|
||||||
airportHighlightColor: "#FF4E4E",
|
airportHighlightColor: "#FF4E4E",
|
||||||
airportHoverColor: "#ff8f35",
|
airportHoverColor: "#ff8f35",
|
||||||
|
|
||||||
airportScale: 0.5,
|
airportScale: 0.7,
|
||||||
airportHighligthScale: 0.95,
|
airportHighligthScale: 0.95,
|
||||||
|
|
||||||
imageData: [],
|
imageData: [],
|
||||||
|
@ -73,19 +76,32 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "All Flights from CWA"
|
name: "All Flights from CWA"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Flight distribution"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
||||||
el: '#content',
|
el: '#content',
|
||||||
|
|
||||||
initialize: function () {
|
initialize: function (options) {
|
||||||
this.airportCollection = new window.Airports();
|
var collectionName = options.collectionName;
|
||||||
window.HASS = this; // <--- BITTE ?!? ;) <-- zu viel Kontakt mit Jan
|
this.airportCollection = new window.Airports({
|
||||||
|
collectionName: collectionName
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
events: {
|
events: {
|
||||||
"change #flightQuerySelect" : "runSelectedQuery",
|
"change #flightQuerySelect" : "runSelectedQuery",
|
||||||
"keyup #demoSearchInput" : "searchInput"
|
"keyup #demoSearchInput" : "searchInput"
|
||||||
|
// "click #searchResults ul li": "selectAirport"
|
||||||
|
},
|
||||||
|
|
||||||
|
selectAirport: function (e) {
|
||||||
|
this.showAirportBalloon(e.currentTarget.id);
|
||||||
|
$("#searchResults").slideUp(function() {
|
||||||
|
$("#searchResults ul").html("");
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
template: templateEngine.createTemplate("demoView.ejs"),
|
template: templateEngine.createTemplate("demoView.ejs"),
|
||||||
|
@ -152,7 +168,7 @@
|
||||||
var self = this, airports = this.index.search($(e.currentTarget).val());
|
var self = this, airports = this.index.search($(e.currentTarget).val());
|
||||||
|
|
||||||
self.resetDataHighlighting();
|
self.resetDataHighlighting();
|
||||||
self.removeFlightLines(false);
|
self.removeFlightLines(true);
|
||||||
|
|
||||||
_.each(airports, function(airport) {
|
_.each(airports, function(airport) {
|
||||||
self.setAirportColor(airport.ref, self.airportHighlightColor, false);
|
self.setAirportColor(airport.ref, self.airportHighlightColor, false);
|
||||||
|
@ -164,16 +180,32 @@
|
||||||
//self.zoomToAirport(airports[0].ref);
|
//self.zoomToAirport(airports[0].ref);
|
||||||
self.showAirportBalloon(airports[0].ref); // <-- only works with single map object, not multiple :(
|
self.showAirportBalloon(airports[0].ref); // <-- only works with single map object, not multiple :(
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
//if (airports.length <= 10) {
|
if (airports.length < 6 && airports.length > 1) {
|
||||||
//}
|
self.insertAirportSelection(airports);
|
||||||
|
} else {
|
||||||
|
$("#searchResults").slideUp();
|
||||||
|
}
|
||||||
|
*/
|
||||||
self.map.validateData();
|
self.map.validateData();
|
||||||
|
},
|
||||||
|
|
||||||
|
insertAirportSelection: function (list) {
|
||||||
|
return;
|
||||||
|
/*
|
||||||
|
$("#searchResults ul").html("");
|
||||||
|
var i = 0;
|
||||||
|
for (i = 0; i < list.length; ++i) {
|
||||||
|
$("#searchResults ul").append("<li id='" + list[i].ref + "'>" + list[i].ref + "</li>");
|
||||||
|
}
|
||||||
|
$("#searchResults").slideDown();
|
||||||
|
*/
|
||||||
},
|
},
|
||||||
|
|
||||||
runSelectedQuery: function() {
|
runSelectedQuery: function() {
|
||||||
|
this.resetDataHighlighting();
|
||||||
|
this.removeFlightLines(true);
|
||||||
|
|
||||||
var currentQueryPos = $( "#flightQuerySelect option:selected" ).attr('position');
|
var currentQueryPos = $( "#flightQuerySelect option:selected" ).attr('position');
|
||||||
if (currentQueryPos === "0") {
|
if (currentQueryPos === "0") {
|
||||||
this.loadAirportData("SFO");
|
this.loadAirportData("SFO");
|
||||||
|
@ -190,6 +222,10 @@
|
||||||
if (currentQueryPos === "4") {
|
if (currentQueryPos === "4") {
|
||||||
this.loadAirportData("CWA");
|
this.loadAirportData("CWA");
|
||||||
}
|
}
|
||||||
|
if (currentQueryPos === "5") {
|
||||||
|
delete this.startPoint;
|
||||||
|
this.loadFlightDistData();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
calculateAirportSize: function(airport, airports) {
|
calculateAirportSize: function(airport, airports) {
|
||||||
|
@ -239,7 +275,70 @@
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
loadFlightDistData: function() {
|
||||||
|
var self = this;
|
||||||
|
var timer = new Date();
|
||||||
|
|
||||||
|
this.airportCollection.getFlightDistribution(function(list) {
|
||||||
|
|
||||||
|
var timeTaken = new Date() - timer;
|
||||||
|
|
||||||
|
self.removeFlightLines(false);
|
||||||
|
|
||||||
|
var allFlights = 0;
|
||||||
|
|
||||||
|
var i = 0;
|
||||||
|
|
||||||
|
self.resetDataHighlighting();
|
||||||
|
var least = list[0].count^3;
|
||||||
|
var best = list[list.length - 1].count^3;
|
||||||
|
var m = 2.625 /(best - least);
|
||||||
|
var distribute = function(x) {
|
||||||
|
return m * x - m * least;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i = 0; i < list.length; ++i) {
|
||||||
|
var to = list[i].Dest;
|
||||||
|
var count = list[i].count^3;
|
||||||
|
self.setAirportColor(to, self.airportHighlightColor);
|
||||||
|
|
||||||
|
var toSize = distribute(count);
|
||||||
|
toSize += 0.625;
|
||||||
|
|
||||||
|
self.setAirportSize(to, toSize);
|
||||||
|
if (i > list.length - 6) {
|
||||||
|
// Top 10 Color
|
||||||
|
self.setAirportColor(to,'rgb(153,52,4)');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($("#demo-mapdiv-info").length === 0) {
|
||||||
|
$("#demo-mapdiv").append("<div id='demo-mapdiv-info'></div>");
|
||||||
|
}
|
||||||
|
|
||||||
|
var tempHTML = "";
|
||||||
|
tempHTML = "<b>Aggregation</b> - Flight distribution<br>" +
|
||||||
|
"Query needed: <b>" + (timeTaken/1000).toFixed(3) + " sec" + "</b><br>" +
|
||||||
|
"Number destinations: <b>" + list.length + "</b><br>" +
|
||||||
|
"Number flights: <b>" + allFlights + "</b><br>" +
|
||||||
|
"Top 5:<br>";
|
||||||
|
|
||||||
|
for (i = (list.length - 1); i > Math.max(list.length - 6, 0); --i) {
|
||||||
|
var airportData = self.airportCollection.findWhere({_key: list[i].Dest});
|
||||||
|
tempHTML += airportData.get("Name") + " - " + airportData.get("_key") + ": <b>" + list[i].count + "</b>";
|
||||||
|
if (i > (list.length - 5)) {
|
||||||
|
tempHTML += "<br>";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#demo-mapdiv-info").html(tempHTML);
|
||||||
|
|
||||||
|
self.map.validateData();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
loadAirportData: function(airport) {
|
loadAirportData: function(airport) {
|
||||||
|
$("#flightQuerySelect :nth-child(1)").prop("selected", true);
|
||||||
var self = this;
|
var self = this;
|
||||||
var timer = new Date();
|
var timer = new Date();
|
||||||
|
|
||||||
|
@ -256,13 +355,25 @@
|
||||||
|
|
||||||
self.resetDataHighlighting();
|
self.resetDataHighlighting();
|
||||||
|
|
||||||
|
var least = list[0].count^3;
|
||||||
|
var best = list[list.length - 1].count^3;
|
||||||
|
var m = 2.625 /(best - least);
|
||||||
|
var distribute = function(x) {
|
||||||
|
return m * x - m * least;
|
||||||
|
};
|
||||||
|
|
||||||
for (i = 0; i < list.length; ++i) {
|
for (i = 0; i < list.length; ++i) {
|
||||||
|
var count = list[i].count^3;
|
||||||
|
var toSize = distribute(count);
|
||||||
|
toSize += 0.625;
|
||||||
self.addFlightLine(
|
self.addFlightLine(
|
||||||
airport,
|
airport,
|
||||||
list[i].Dest,
|
list[i].Dest,
|
||||||
list[i].count,
|
list[i].count,
|
||||||
self.calculateFlightColor(list.length, i),
|
self.calculateFlightColor(list.length, i),
|
||||||
self.calculateFlightWidth(list.length, i)
|
self.calculateFlightWidth(list.length, i),
|
||||||
|
toSize,
|
||||||
|
(i > list.length - 6)
|
||||||
);
|
);
|
||||||
allFlights += list[i].count;
|
allFlights += list[i].count;
|
||||||
}
|
}
|
||||||
|
@ -272,15 +383,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
var tempHTML = "";
|
var tempHTML = "";
|
||||||
tempHTML = "<b>" + airportData.get("Name") + "</b> - " + airport + "<br>" +
|
tempHTML = "<b>" + airportData.get("Name").substr(0,25) + "</b> - " + airport + "<br>" +
|
||||||
"Query needed: <b>" + (timeTaken/1000) + "sec" + "</b><br>" +
|
"Query needed: <b>" + (timeTaken/1000).toFixed(3) + " sec" + "</b><br>" +
|
||||||
"Number destinations: <b>" + list.length + "</b><br>" +
|
"Number destinations: <b>" + list.length + "</b><br>" +
|
||||||
"Number flights: <b>" + allFlights + "</b><br>" +
|
"Number flights: <b>" + allFlights + "</b><br>" +
|
||||||
"Top 5:<br>";
|
"Top 5:<br>";
|
||||||
|
|
||||||
for (i = (list.length - 1); i > Math.max(list.length - 6, 0); --i) {
|
for (i = (list.length - 1); i >= Math.max(list.length - 5, 0); --i) {
|
||||||
airportData = self.airportCollection.findWhere({_key: list[i].Dest});
|
airportData = self.airportCollection.findWhere({_key: list[i].Dest});
|
||||||
tempHTML += airportData.get("Name") + " - " + airportData.get("_key") + ": <b>" + list[i].count + "</b>";
|
tempHTML += airportData.get("Name").substr(0, 25) + " - " + airportData.get("_key") + ": <b>" + list[i].count + "</b>";
|
||||||
if (i > (list.length - 5)) {
|
if (i > (list.length - 5)) {
|
||||||
tempHTML += "<br>";
|
tempHTML += "<br>";
|
||||||
}
|
}
|
||||||
|
@ -296,12 +407,11 @@
|
||||||
//var intervallWidth = length/2;
|
//var intervallWidth = length/2;
|
||||||
// return Math.floor(pos/intervallWidth) + 2;
|
// return Math.floor(pos/intervallWidth) + 2;
|
||||||
//TODO: no custom width for lines wanted?
|
//TODO: no custom width for lines wanted?
|
||||||
return 1.5;
|
return 2;
|
||||||
},
|
},
|
||||||
|
|
||||||
calculateFlightColor: function(length, pos) {
|
calculateFlightColor: function(length, pos) {
|
||||||
var intervallColor = length/this.lineColors.length;
|
return this.lineColors[0];
|
||||||
return this.lineColors[Math.floor(pos/intervallColor)];
|
|
||||||
},
|
},
|
||||||
|
|
||||||
zoomToAirport: function (id) {
|
zoomToAirport: function (id) {
|
||||||
|
@ -309,6 +419,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
showAirportBalloon: function (id) {
|
showAirportBalloon: function (id) {
|
||||||
|
this.map.allowMultipleDescriptionWindows = true;
|
||||||
var mapObject = this.map.getObjectById(id);
|
var mapObject = this.map.getObjectById(id);
|
||||||
this.map.rollOverMapObject(mapObject);
|
this.map.rollOverMapObject(mapObject);
|
||||||
},
|
},
|
||||||
|
@ -354,6 +465,7 @@
|
||||||
airport.color = self.airportColor;
|
airport.color = self.airportColor;
|
||||||
airport.scale = self.airportScale;
|
airport.scale = self.airportScale;
|
||||||
});
|
});
|
||||||
|
$("#demo-mapdiv-info").html("");
|
||||||
},
|
},
|
||||||
|
|
||||||
prepareData: function (data) {
|
prepareData: function (data) {
|
||||||
|
@ -368,7 +480,7 @@
|
||||||
svgPath: self.MAPtarget,
|
svgPath: self.MAPtarget,
|
||||||
color: self.airportColor,
|
color: self.airportColor,
|
||||||
scale: self.airportScale,
|
scale: self.airportScale,
|
||||||
selectedScale: 2.5,
|
selectedScale: 1,
|
||||||
title: airport.City + " [" + airport._key + "]<br>" + airport.Name,
|
title: airport.City + " [" + airport._key + "]<br>" + airport.Name,
|
||||||
rollOverColor: self.airportHoverColor,
|
rollOverColor: self.airportHoverColor,
|
||||||
selectable: true
|
selectable: true
|
||||||
|
@ -389,6 +501,8 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
createFlightEntry: function(from, to, weight, lineColor, lineWidth) {
|
createFlightEntry: function(from, to, weight, lineColor, lineWidth) {
|
||||||
|
if (this.keyToLongLat.hasOwnProperty(from)
|
||||||
|
&& this.keyToLongLat.hasOwnProperty(to)) {
|
||||||
return {
|
return {
|
||||||
longitudes: [
|
longitudes: [
|
||||||
this.keyToLongLat[from].lon,
|
this.keyToLongLat[from].lon,
|
||||||
|
@ -402,6 +516,44 @@
|
||||||
color: lineColor,
|
color: lineColor,
|
||||||
thickness: lineWidth
|
thickness: lineWidth
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
},
|
||||||
|
|
||||||
|
loadShortestPath: function(from, to) {
|
||||||
|
var self = this;
|
||||||
|
var timer = new Date();
|
||||||
|
this.airportCollection.getShortestFlight(from, to, function(list) {
|
||||||
|
var timeTaken = new Date() - timer;
|
||||||
|
if (!list.vertices) {
|
||||||
|
alert("Sorry there is no flight");
|
||||||
|
}
|
||||||
|
var vertices = list.vertices;
|
||||||
|
for (var i = 0; i < vertices.length - 1; ++i) {
|
||||||
|
var from = vertices[i].split("/")[1];
|
||||||
|
var to = vertices[i+1].split("/")[1];
|
||||||
|
self.addFlightLine(from, to, 1,
|
||||||
|
self.calculateFlightColor(vertices.length, i),
|
||||||
|
self.calculateFlightWidth(vertices.length, i),
|
||||||
|
2,
|
||||||
|
true,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
var tempHTML = "";
|
||||||
|
tempHTML = "<b>Path</b> - Shortest Flight<br>" +
|
||||||
|
"Query needed: <b>" + (timeTaken/1000).toFixed(3) + " sec" + "</b><br>" +
|
||||||
|
"Number switches: <b>" + (vertices.length - 2) + "</b><br>" +
|
||||||
|
"Number flights: <b>" + list.edges.length + "</b><br>" +
|
||||||
|
"Airports:<br>";
|
||||||
|
for (i = 0; i < vertices.length; ++i) {
|
||||||
|
var airportData = self.airportCollection.findWhere({_key: vertices[i].split("/")[1]});
|
||||||
|
tempHTML += airportData.get("Name") + " - " + airportData.get("_key") + "<br>";
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#demo-mapdiv-info").html(tempHTML);
|
||||||
|
self.map.validateData();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
renderMap: function() {
|
renderMap: function() {
|
||||||
|
@ -422,9 +574,17 @@
|
||||||
images: self.imageData,
|
images: self.imageData,
|
||||||
getAreasFromMap: true
|
getAreasFromMap: true
|
||||||
},
|
},
|
||||||
clickMapObject: function(mapObject) {
|
clickMapObject: function(mapObject, event) {
|
||||||
//console.log(mapObject);
|
if (mapObject.id !== undefined && mapObject.id.length === 3) {
|
||||||
|
if (event.shiftKey && self.hasOwnProperty("startPoint")) {
|
||||||
|
self.resetDataHighlighting();
|
||||||
|
self.removeFlightLines(true);
|
||||||
|
self.loadShortestPath(self.startPoint, mapObject.id);
|
||||||
|
} else {
|
||||||
|
self.startPoint = mapObject.id;
|
||||||
self.loadAirportData(mapObject.id);
|
self.loadAirportData(mapObject.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
balloon: {
|
balloon: {
|
||||||
adjustBorderColor: true,
|
adjustBorderColor: true,
|
||||||
|
@ -468,21 +628,19 @@
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
addFlightLine: function(from, to, count, lineColor, lineWidth, shouldRender) {
|
addFlightLine: function(from, to, count, lineColor, lineWidth, toSize, highlight, shouldRender) {
|
||||||
//console.log("Adding", from, to, count, lineColor, lineWidth);
|
var f = this.createFlightEntry(from, to, count, lineColor, lineWidth);
|
||||||
|
if (f !== undefined) {
|
||||||
this.lines.push(this.createFlightEntry(from, to, count, lineColor, lineWidth));
|
this.lines.push(f);
|
||||||
|
}
|
||||||
|
|
||||||
this.setAirportColor(from, "#FFFFFF");
|
this.setAirportColor(from, "#FFFFFF");
|
||||||
this.setAirportColor(to, this.airportHighlightColor);
|
this.setAirportColor(to, this.airportHighlightColor);
|
||||||
this.setAirportSize(from, 1.5);
|
this.setAirportSize(from, 1.5);
|
||||||
|
|
||||||
var toSize = count * 0.001;
|
|
||||||
if (toSize <= 0.25) {
|
|
||||||
toSize = 0.25;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.setAirportSize(to, toSize);
|
this.setAirportSize(to, toSize);
|
||||||
|
if (highlight) {
|
||||||
|
this.setAirportColor(to, 'rgb(153,52,4)');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
div.demo-dropdown-menu {
|
||||||
|
@extend %clickable;
|
||||||
|
@include border-radius(0 0 5px 5px);
|
||||||
|
background-color: $c-bar-bg;
|
||||||
|
margin-bottom: 5px;
|
||||||
|
margin-left: 5px;
|
||||||
|
position: absolute;
|
||||||
|
top: 32px;
|
||||||
|
width: 222px;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
#flightQuerySelect.query-select {
|
||||||
|
height: 25px;
|
||||||
|
margin-top: 6px;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 1.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#demo-mapdiv {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#demo-mapdiv-info {
|
||||||
|
position: absolute;
|
||||||
|
right: 20px;
|
||||||
|
width: 225px;
|
||||||
|
height: 150px;
|
||||||
|
bottom: 20px;
|
||||||
|
border: 1.5px solid #222;
|
||||||
|
border-radius: 4px;
|
||||||
|
background-color: rgba(255,255,255, 0.75);
|
||||||
|
padding: 6px 6px 3px 6px;
|
||||||
|
font-size: 11px;
|
||||||
|
line-height: 1.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.amcharts-balloon-div {
|
||||||
|
line-height: 1.1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -504,8 +504,8 @@ div.resizecontainer {
|
||||||
|
|
||||||
div.centralRow {
|
div.centralRow {
|
||||||
margin: {
|
margin: {
|
||||||
top: 65px;
|
top: 40px;
|
||||||
bottom: 65px;
|
bottom: 40px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -87,4 +87,4 @@
|
||||||
@import 'uploadfile';
|
@import 'uploadfile';
|
||||||
|
|
||||||
// Demo
|
// Demo
|
||||||
//@import 'demo';
|
@import 'demo';
|
||||||
|
|
|
@ -5598,6 +5598,17 @@ function AQL_SHORTEST_PATH (vertexCollection,
|
||||||
params) {
|
params) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
if (typeof startVertex === "string" && typeof endVertex === "string") {
|
||||||
|
var opts = {
|
||||||
|
direction: direction
|
||||||
|
};
|
||||||
|
if (params.hasOwnProperty("distance") && params.hasOwnProperty("defaultDistance")) {
|
||||||
|
opts.distance = params.distance;
|
||||||
|
opts.defaultDistance = params.defaultDistance;
|
||||||
|
}
|
||||||
|
return CPP_SHORTEST_PATH(vertexCollection, edgeCollection, startVertex, endVertex, opts);
|
||||||
|
}
|
||||||
|
|
||||||
params = SHORTEST_PATH_PARAMS(params);
|
params = SHORTEST_PATH_PARAMS(params);
|
||||||
|
|
||||||
return TRAVERSAL_FUNC("SHORTEST_PATH",
|
return TRAVERSAL_FUNC("SHORTEST_PATH",
|
||||||
|
|
Loading…
Reference in New Issue