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::arango;
|
||||
|
||||
struct WeightInfo {
|
||||
string keyWeight;
|
||||
double defaultWeight;
|
||||
bool usesWeight;
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief callback to weight an edge
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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,
|
||||
double defaultWeight
|
||||
) :
|
||||
keyWeight(keyWeight), defaultWeight(defaultWeight), usesWeight(true)
|
||||
double defaultWeight,
|
||||
TRI_shaper_t* shaper
|
||||
) : _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 {
|
||||
|
@ -90,33 +143,20 @@ class SimpleEdgeExpander {
|
|||
CollectionNameResolver* resolver;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief this is the information required to compute weight by a given
|
||||
/// attribute. It contains an indicator if weight should be used.
|
||||
/// Also it includes a default weight and the name of the weight
|
||||
/// attribute.
|
||||
/// @brief the weight calculation function
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
WeightInfo weightInfo;
|
||||
WeightCalculatorFunction weighter;
|
||||
|
||||
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,
|
||||
TRI_document_collection_t* edgeCollection,
|
||||
string edgeCollectionName,
|
||||
CollectionNameResolver* resolver,
|
||||
WeightInfo weightInfo)
|
||||
WeightCalculatorFunction weighter)
|
||||
: direction(direction), edgeCollection(edgeCollection),
|
||||
resolver(resolver), weightInfo(weightInfo)
|
||||
resolver(resolver), weighter(weighter)
|
||||
{
|
||||
edgeIdPrefix = edgeCollectionName + "/";
|
||||
};
|
||||
|
@ -170,17 +210,16 @@ class SimpleEdgeExpander {
|
|||
unordered_map<Traverser::VertexId, size_t> candidates;
|
||||
Traverser::VertexId from;
|
||||
Traverser::VertexId to;
|
||||
if (weightInfo.usesWeight) {
|
||||
for (size_t j = 0; j < edges.size(); ++j) {
|
||||
from = extractFromId(edges[j]);
|
||||
to = extractToId(edges[j]);
|
||||
double currentWeight = weightInfo.defaultWeight;
|
||||
if (from != source) {
|
||||
auto cand = candidates.find(from);
|
||||
double currentWeight = weighter(edges[j]);
|
||||
auto inserter = [&](Traverser::VertexId s, Traverser::VertexId t) {
|
||||
auto cand = candidates.find(t);
|
||||
if (cand == candidates.end()) {
|
||||
// Add weight
|
||||
result.emplace_back(to, from, currentWeight, extractEdgeId(edges[j]));
|
||||
candidates.emplace(from, result.size() - 1);
|
||||
result.emplace_back(t, s, currentWeight, extractEdgeId(edges[j]));
|
||||
candidates.emplace(t, result.size() - 1);
|
||||
} else {
|
||||
// Compare weight
|
||||
auto oldWeight = result[cand->second].weight();
|
||||
|
@ -188,40 +227,12 @@ class SimpleEdgeExpander {
|
|||
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) {
|
||||
auto cand = candidates.find(from);
|
||||
if (cand == candidates.end()) {
|
||||
result.emplace_back(from, to, 1, extractEdgeId(edges[j]));
|
||||
candidates.emplace(from, result.size()-1);
|
||||
}
|
||||
inserter(to, from);
|
||||
}
|
||||
else if (to != source) {
|
||||
auto cand = candidates.find(to);
|
||||
if (cand == candidates.end()) {
|
||||
result.emplace_back(to, from, 1, extractEdgeId(edges[j]));
|
||||
candidates.emplace(to, result.size()-1);
|
||||
}
|
||||
}
|
||||
inserter(from, to);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -283,7 +294,7 @@ void TRI_RunDijkstraSearch (const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|||
vector<string> writeCollections;
|
||||
|
||||
double lockTimeout = (double) (TRI_TRANSACTION_DEFAULT_LOCK_TIMEOUT / 1000000ULL);
|
||||
bool embed = false;
|
||||
bool embed = true;
|
||||
bool waitForSync = false;
|
||||
|
||||
// get the vertex collection
|
||||
|
@ -409,15 +420,16 @@ void TRI_RunDijkstraSearch (const v8::FunctionCallbackInfo<v8::Value>& args) {
|
|||
|
||||
unique_ptr<SimpleEdgeExpander> forwardExpander;
|
||||
unique_ptr<SimpleEdgeExpander> backwardExpander;
|
||||
WeightCalculatorFunction weighter;
|
||||
if (useWeight) {
|
||||
forwardExpander.reset(new SimpleEdgeExpander(forward, ecol, edgeCollectionName,
|
||||
&resolver1, WeightInfo(weightAttribute, defaultWeight)));
|
||||
backwardExpander.reset(new SimpleEdgeExpander(backward, ecol, edgeCollectionName,
|
||||
&resolver2, WeightInfo(weightAttribute, defaultWeight)));
|
||||
weighter = AttributeWeightCalculator(
|
||||
weightAttribute, defaultWeight, ecol->getShaper()
|
||||
);
|
||||
} else {
|
||||
forwardExpander.reset(new SimpleEdgeExpander(forward, ecol, edgeCollectionName, &resolver1));
|
||||
backwardExpander.reset(new SimpleEdgeExpander(backward, ecol, edgeCollectionName, &resolver2));
|
||||
weighter = HopWeightCalculator();
|
||||
}
|
||||
forwardExpander.reset(new SimpleEdgeExpander(forward, ecol, edgeCollectionName, &resolver1, weighter));
|
||||
backwardExpander.reset(new SimpleEdgeExpander(backward, ecol, edgeCollectionName, &resolver2, weighter));
|
||||
|
||||
|
||||
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_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; } }
|
||||
|
||||
div.centralRow {
|
||||
margin-top: 65px;
|
||||
margin-bottom: 65px; }
|
||||
margin-top: 40px;
|
||||
margin-bottom: 40px; }
|
||||
|
||||
div.centralContent {
|
||||
background-color: rgba(0, 0, 0, 0.0675);
|
||||
|
|
|
@ -7,7 +7,8 @@
|
|||
|
||||
window.Airports = Backbone.Collection.extend({
|
||||
|
||||
initialize: function() {
|
||||
initialize: function(options) {
|
||||
this.collectionName = options.collectionName;
|
||||
},
|
||||
|
||||
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) {
|
||||
var self = this;
|
||||
|
||||
|
@ -42,9 +87,12 @@
|
|||
type: "POST",
|
||||
url: "/_api/cursor",
|
||||
data: JSON.stringify({
|
||||
query: "for f in flights12 filter f.Origin == @airport COLLECT dest = f.Dest " +
|
||||
"WITH COUNT INTO n SORT n RETURN {Dest: dest, count: n}",
|
||||
bindVars: {"airport": airport}
|
||||
query: "for f in @@flights filter f._from == @airport COLLECT dest = f._to " +
|
||||
"WITH COUNT INTO n SORT n RETURN {Dest: SPLIT(dest, '/')[1], count: n}",
|
||||
bindVars: {
|
||||
"airport": "airports/" + airport,
|
||||
"@flights": this.collectionName
|
||||
}
|
||||
}),
|
||||
contentType: "application/json",
|
||||
processData: false,
|
||||
|
|
|
@ -26,13 +26,18 @@
|
|||
"userManagement": "userManagement",
|
||||
"userProfile": "userProfile",
|
||||
"logs": "logs",
|
||||
"demo": "demo"
|
||||
"demo": "demo",
|
||||
"demo/:collection": "demo"
|
||||
},
|
||||
|
||||
demo: function () {
|
||||
|
||||
demo: function (collection) {
|
||||
if (!collection) {
|
||||
collection = "flights";
|
||||
}
|
||||
if (!this.demoView) {
|
||||
this.demoView = new window.DemoView({});
|
||||
this.demoView = new window.DemoView({
|
||||
collectionName: collection
|
||||
});
|
||||
}
|
||||
|
||||
this.demoView.render();
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
</div>
|
||||
<div class="search-field">
|
||||
<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 class="styled-select">
|
||||
<select id="flightQuerySelect" class="query-select" style="margin-top: 5px; height: 25px">
|
||||
|
|
|
@ -35,22 +35,25 @@
|
|||
*/
|
||||
|
||||
lineColors: [
|
||||
'rgb(255,255,229)',
|
||||
'rgb(255,247,188)',
|
||||
'rgb(254,227,145)',
|
||||
'rgb(254,196,79)',
|
||||
'rgb(254,153,41)',
|
||||
'rgb(236,112,20)',
|
||||
'rgb(204,76,2)',
|
||||
'rgb(153,52,4)',
|
||||
'rgb(102,37,6)'
|
||||
'rgb(255,255,229)'
|
||||
/*
|
||||
- 'rgb(255,255,229)',
|
||||
- 'rgb(255,247,188)',
|
||||
- 'rgb(254,227,145)',
|
||||
- 'rgb(254,196,79)',
|
||||
- 'rgb(254,153,41)',
|
||||
- 'rgb(236,112,20)',
|
||||
- 'rgb(204,76,2)',
|
||||
- 'rgb(153,52,4)',
|
||||
- 'rgb(102,37,6)'
|
||||
*/
|
||||
],
|
||||
|
||||
airportColor: "#222222",
|
||||
airportHighlightColor: "#FF4E4E",
|
||||
airportHoverColor: "#ff8f35",
|
||||
|
||||
airportScale: 0.5,
|
||||
airportScale: 0.7,
|
||||
airportHighligthScale: 0.95,
|
||||
|
||||
imageData: [],
|
||||
|
@ -73,19 +76,32 @@
|
|||
},
|
||||
{
|
||||
name: "All Flights from CWA"
|
||||
},
|
||||
{
|
||||
name: "Flight distribution"
|
||||
}
|
||||
],
|
||||
|
||||
el: '#content',
|
||||
|
||||
initialize: function () {
|
||||
this.airportCollection = new window.Airports();
|
||||
window.HASS = this; // <--- BITTE ?!? ;) <-- zu viel Kontakt mit Jan
|
||||
initialize: function (options) {
|
||||
var collectionName = options.collectionName;
|
||||
this.airportCollection = new window.Airports({
|
||||
collectionName: collectionName
|
||||
});
|
||||
},
|
||||
|
||||
events: {
|
||||
"change #flightQuerySelect" : "runSelectedQuery",
|
||||
"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"),
|
||||
|
@ -152,7 +168,7 @@
|
|||
var self = this, airports = this.index.search($(e.currentTarget).val());
|
||||
|
||||
self.resetDataHighlighting();
|
||||
self.removeFlightLines(false);
|
||||
self.removeFlightLines(true);
|
||||
|
||||
_.each(airports, function(airport) {
|
||||
self.setAirportColor(airport.ref, self.airportHighlightColor, false);
|
||||
|
@ -164,16 +180,32 @@
|
|||
//self.zoomToAirport(airports[0].ref);
|
||||
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();
|
||||
},
|
||||
|
||||
|
||||
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() {
|
||||
this.resetDataHighlighting();
|
||||
this.removeFlightLines(true);
|
||||
|
||||
var currentQueryPos = $( "#flightQuerySelect option:selected" ).attr('position');
|
||||
if (currentQueryPos === "0") {
|
||||
this.loadAirportData("SFO");
|
||||
|
@ -190,6 +222,10 @@
|
|||
if (currentQueryPos === "4") {
|
||||
this.loadAirportData("CWA");
|
||||
}
|
||||
if (currentQueryPos === "5") {
|
||||
delete this.startPoint;
|
||||
this.loadFlightDistData();
|
||||
}
|
||||
},
|
||||
|
||||
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) {
|
||||
$("#flightQuerySelect :nth-child(1)").prop("selected", true);
|
||||
var self = this;
|
||||
var timer = new Date();
|
||||
|
||||
|
@ -256,13 +355,25 @@
|
|||
|
||||
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 count = list[i].count^3;
|
||||
var toSize = distribute(count);
|
||||
toSize += 0.625;
|
||||
self.addFlightLine(
|
||||
airport,
|
||||
list[i].Dest,
|
||||
list[i].count,
|
||||
self.calculateFlightColor(list.length, i),
|
||||
self.calculateFlightWidth(list.length, i)
|
||||
self.calculateFlightWidth(list.length, i),
|
||||
toSize,
|
||||
(i > list.length - 6)
|
||||
);
|
||||
allFlights += list[i].count;
|
||||
}
|
||||
|
@ -272,15 +383,15 @@
|
|||
}
|
||||
|
||||
var tempHTML = "";
|
||||
tempHTML = "<b>" + airportData.get("Name") + "</b> - " + airport + "<br>" +
|
||||
"Query needed: <b>" + (timeTaken/1000) + "sec" + "</b><br>" +
|
||||
tempHTML = "<b>" + airportData.get("Name").substr(0,25) + "</b> - " + airport + "<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) {
|
||||
for (i = (list.length - 1); i >= Math.max(list.length - 5, 0); --i) {
|
||||
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)) {
|
||||
tempHTML += "<br>";
|
||||
}
|
||||
|
@ -296,12 +407,11 @@
|
|||
//var intervallWidth = length/2;
|
||||
// return Math.floor(pos/intervallWidth) + 2;
|
||||
//TODO: no custom width for lines wanted?
|
||||
return 1.5;
|
||||
return 2;
|
||||
},
|
||||
|
||||
calculateFlightColor: function(length, pos) {
|
||||
var intervallColor = length/this.lineColors.length;
|
||||
return this.lineColors[Math.floor(pos/intervallColor)];
|
||||
return this.lineColors[0];
|
||||
},
|
||||
|
||||
zoomToAirport: function (id) {
|
||||
|
@ -309,6 +419,7 @@
|
|||
},
|
||||
|
||||
showAirportBalloon: function (id) {
|
||||
this.map.allowMultipleDescriptionWindows = true;
|
||||
var mapObject = this.map.getObjectById(id);
|
||||
this.map.rollOverMapObject(mapObject);
|
||||
},
|
||||
|
@ -354,6 +465,7 @@
|
|||
airport.color = self.airportColor;
|
||||
airport.scale = self.airportScale;
|
||||
});
|
||||
$("#demo-mapdiv-info").html("");
|
||||
},
|
||||
|
||||
prepareData: function (data) {
|
||||
|
@ -368,7 +480,7 @@
|
|||
svgPath: self.MAPtarget,
|
||||
color: self.airportColor,
|
||||
scale: self.airportScale,
|
||||
selectedScale: 2.5,
|
||||
selectedScale: 1,
|
||||
title: airport.City + " [" + airport._key + "]<br>" + airport.Name,
|
||||
rollOverColor: self.airportHoverColor,
|
||||
selectable: true
|
||||
|
@ -389,6 +501,8 @@
|
|||
},
|
||||
|
||||
createFlightEntry: function(from, to, weight, lineColor, lineWidth) {
|
||||
if (this.keyToLongLat.hasOwnProperty(from)
|
||||
&& this.keyToLongLat.hasOwnProperty(to)) {
|
||||
return {
|
||||
longitudes: [
|
||||
this.keyToLongLat[from].lon,
|
||||
|
@ -402,6 +516,44 @@
|
|||
color: lineColor,
|
||||
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() {
|
||||
|
@ -422,9 +574,17 @@
|
|||
images: self.imageData,
|
||||
getAreasFromMap: true
|
||||
},
|
||||
clickMapObject: function(mapObject) {
|
||||
//console.log(mapObject);
|
||||
clickMapObject: function(mapObject, event) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
},
|
||||
balloon: {
|
||||
adjustBorderColor: true,
|
||||
|
@ -468,21 +628,19 @@
|
|||
});
|
||||
},
|
||||
|
||||
addFlightLine: function(from, to, count, lineColor, lineWidth, shouldRender) {
|
||||
//console.log("Adding", from, to, count, lineColor, lineWidth);
|
||||
|
||||
this.lines.push(this.createFlightEntry(from, to, count, lineColor, lineWidth));
|
||||
addFlightLine: function(from, to, count, lineColor, lineWidth, toSize, highlight, shouldRender) {
|
||||
var f = this.createFlightEntry(from, to, count, lineColor, lineWidth);
|
||||
if (f !== undefined) {
|
||||
this.lines.push(f);
|
||||
}
|
||||
|
||||
this.setAirportColor(from, "#FFFFFF");
|
||||
this.setAirportColor(to, this.airportHighlightColor);
|
||||
this.setAirportSize(from, 1.5);
|
||||
|
||||
var toSize = count * 0.001;
|
||||
if (toSize <= 0.25) {
|
||||
toSize = 0.25;
|
||||
}
|
||||
|
||||
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 {
|
||||
margin: {
|
||||
top: 65px;
|
||||
bottom: 65px;
|
||||
top: 40px;
|
||||
bottom: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -87,4 +87,4 @@
|
|||
@import 'uploadfile';
|
||||
|
||||
// Demo
|
||||
//@import 'demo';
|
||||
@import 'demo';
|
||||
|
|
|
@ -5598,6 +5598,17 @@ function AQL_SHORTEST_PATH (vertexCollection,
|
|||
params) {
|
||||
'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);
|
||||
|
||||
return TRAVERSAL_FUNC("SHORTEST_PATH",
|
||||
|
|
Loading…
Reference in New Issue