mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-02-05 15:02:26 +01:00
Added geolocations to query results
This commit is contained in:
parent
19dc55ad26
commit
8ee28e07dd
@ -36,6 +36,7 @@ import com.djrapitops.plan.storage.database.queries.analysis.NetworkActivityInde
|
||||
import com.djrapitops.plan.storage.database.queries.filter.Filter;
|
||||
import com.djrapitops.plan.storage.database.queries.filter.FilterQuery;
|
||||
import com.djrapitops.plan.storage.database.queries.filter.QueryFilters;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.GeoInfoQueries;
|
||||
import com.djrapitops.plan.storage.database.queries.objects.playertable.QueryTablePlayersQuery;
|
||||
import com.djrapitops.plan.storage.json.JSONStorage;
|
||||
import com.djrapitops.plan.utilities.java.Maps;
|
||||
@ -146,12 +147,21 @@ public class QueryJSONResolver implements Resolver {
|
||||
long before = dateFormat.parse(viewJSON.beforeDate + " " + viewJSON.beforeTime).getTime();
|
||||
|
||||
Database database = dbSystem.getDatabase();
|
||||
|
||||
return Maps.builder(String.class, Object.class)
|
||||
.put("players", getPlayersTableData(playerUUIDs, after, before))
|
||||
.put("activity", getActivityGraphData(playerUUIDs, after, before))
|
||||
.put("geolocation", getGeolocationData(playerUUIDs))
|
||||
.build();
|
||||
}
|
||||
|
||||
private Map<String, Object> getGeolocationData(Set<UUID> playerUUIDs) {
|
||||
Database database = dbSystem.getDatabase();
|
||||
return graphJSONCreator.createGeolocationJSON(
|
||||
database.query(GeoInfoQueries.networkGeolocationCounts(playerUUIDs))
|
||||
);
|
||||
}
|
||||
|
||||
private Map<String, Object> getActivityGraphData(Set<UUID> playerUUIDs, long after, long before) {
|
||||
Database database = dbSystem.getDatabase();
|
||||
Long threshold = config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD);
|
||||
@ -164,8 +174,7 @@ public class QueryJSONResolver implements Resolver {
|
||||
activityData.put(time, database.query(NetworkActivityIndexQueries.fetchActivityIndexGroupingsOn(time, threshold, playerUUIDs)));
|
||||
}
|
||||
|
||||
Map<String, Object> activityGraphJSON = graphJSONCreator.createActivityGraphJSON(activityData);
|
||||
return activityGraphJSON;
|
||||
return graphJSONCreator.createActivityGraphJSON(activityData);
|
||||
}
|
||||
|
||||
private Map<String, Object> getPlayersTableData(Set<UUID> playerUUIDs, long after, long before) {
|
||||
|
@ -23,6 +23,7 @@ import com.djrapitops.plan.storage.database.queries.QueryStatement;
|
||||
import com.djrapitops.plan.storage.database.sql.tables.GeoInfoTable;
|
||||
import com.djrapitops.plan.storage.database.sql.tables.UserInfoTable;
|
||||
import com.djrapitops.plan.utilities.java.Lists;
|
||||
import org.apache.commons.text.TextStringBuilder;
|
||||
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
@ -157,6 +158,37 @@ public class GeoInfoQueries {
|
||||
};
|
||||
}
|
||||
|
||||
public static Query<Map<String, Integer>> networkGeolocationCounts(Collection<UUID> playerUUIDs) {
|
||||
String subQuery1 = SELECT +
|
||||
GeoInfoTable.USER_UUID + ", " +
|
||||
GeoInfoTable.GEOLOCATION + ", " +
|
||||
GeoInfoTable.LAST_USED +
|
||||
FROM + GeoInfoTable.TABLE_NAME +
|
||||
WHERE + GeoInfoTable.USER_UUID + " IN ('" +
|
||||
new TextStringBuilder().appendWithSeparators(playerUUIDs, "','").build() + "')";
|
||||
String subQuery2 = SELECT +
|
||||
GeoInfoTable.USER_UUID + ", " +
|
||||
"MAX(" + GeoInfoTable.LAST_USED + ") as m" +
|
||||
FROM + GeoInfoTable.TABLE_NAME +
|
||||
GROUP_BY + GeoInfoTable.USER_UUID;
|
||||
String sql = SELECT + GeoInfoTable.GEOLOCATION + ", COUNT(1) as c FROM " +
|
||||
"(" + subQuery1 + ") AS q1" +
|
||||
INNER_JOIN + "(" + subQuery2 + ") AS q2 ON q1.uuid = q2.uuid" +
|
||||
WHERE + GeoInfoTable.LAST_USED + "=m" +
|
||||
GROUP_BY + GeoInfoTable.GEOLOCATION;
|
||||
|
||||
return new QueryAllStatement<Map<String, Integer>>(sql) {
|
||||
@Override
|
||||
public Map<String, Integer> processResults(ResultSet set) throws SQLException {
|
||||
Map<String, Integer> geolocationCounts = new HashMap<>();
|
||||
while (set.next()) {
|
||||
geolocationCounts.put(set.getString(GeoInfoTable.GEOLOCATION), set.getInt("c"));
|
||||
}
|
||||
return geolocationCounts;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static Query<Map<String, Integer>> serverGeolocationCounts(UUID serverUUID) {
|
||||
String selectGeolocations = SELECT +
|
||||
GeoInfoTable.USER_UUID + ", " +
|
||||
|
@ -313,6 +313,10 @@ function runQuery() {
|
||||
data: json.data.players.data,
|
||||
order: [[5, "desc"]]
|
||||
});
|
||||
const activityIndexHeader = document.querySelector("#DataTables_Table_0 thead th:nth-of-type(2)");
|
||||
const lastSeenHeader = document.querySelector("#DataTables_Table_0 thead th:nth-of-type(6)");
|
||||
activityIndexHeader.innerHTML += ` (${json.view.beforeDate})`
|
||||
lastSeenHeader.innerHTML += ` (view)`
|
||||
|
||||
// Activity graphs
|
||||
const activity_data = json.data.activity;
|
||||
@ -320,13 +324,31 @@ function runQuery() {
|
||||
name: 'Players', colorByPoint: true, data: activity_data.activity_pie_series
|
||||
});
|
||||
stackChart('activityStackGraph', activity_data.activity_labels, activity_data.activity_series, 'Players');
|
||||
|
||||
const activityIndexHeader = document.querySelector("#DataTables_Table_0 thead th:nth-of-type(2)");
|
||||
const lastSeenHeader = document.querySelector("#DataTables_Table_0 thead th:nth-of-type(6)");
|
||||
|
||||
document.querySelector("#activity-date").innerHTML = json.view.beforeDate;
|
||||
activityIndexHeader.innerHTML += ` (${json.view.beforeDate})`
|
||||
lastSeenHeader.innerHTML += ` (view)`
|
||||
|
||||
// Geolocations
|
||||
const geolocation_data = json.data.geolocation;
|
||||
const geolocationSeries = {
|
||||
name: 'Players',
|
||||
type: 'map',
|
||||
mapData: Highcharts.maps['custom/world'],
|
||||
data: geolocation_data.geolocation_series,
|
||||
joinBy: ['iso-a3', 'code']
|
||||
};
|
||||
const geolocationBarSeries = {
|
||||
color: geolocation_data.colors.bars,
|
||||
name: 'Players',
|
||||
data: geolocation_data.geolocation_bar_series.map(function (bar) {
|
||||
return bar.value
|
||||
})
|
||||
};
|
||||
const geolocationBarCategories = geolocation_data.geolocation_bar_series.map(function (bar) {
|
||||
return bar.label
|
||||
});
|
||||
worldMap('worldMap', geolocation_data.colors.low, geolocation_data.colors.high, geolocationSeries);
|
||||
horizontalBarChart('countryBarChart', geolocationBarCategories, [geolocationBarSeries], 'Players');
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
@ -337,12 +359,12 @@ function renderDataResultScreen(resultCount, view) {
|
||||
const beforeTime = filterView.beforeTime ? filterView.beforeTime : view.beforeTime;
|
||||
document.querySelector('#content .tab').innerHTML =
|
||||
`<div class="container-fluid mt-4">
|
||||
<!-- Page Heading -->
|
||||
<div class="d-sm-flex align-items-center justify-content-between mb-4">
|
||||
<h1 class="h3 mb-0 text-gray-800"><i class="sidebar-toggler fa fa-fw fa-bars"></i>Plan ·
|
||||
Query Results</h1>
|
||||
<p class="mb-0 text-gray-800">(matched ${resultCount} players)</p>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-12 col-lg-12">
|
||||
<div class="card shadow mb-4">
|
||||
@ -361,6 +383,7 @@ function renderDataResultScreen(resultCount, view) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xl-8 col-lg-8 col-sm-12">
|
||||
<div class="card shadow mb-4">
|
||||
@ -372,7 +395,6 @@ function renderDataResultScreen(resultCount, view) {
|
||||
<div class="chart-area" id="activityStackGraph"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-xl-4 col-lg-4 col-sm-12">
|
||||
<div class="card shadow mb-4">
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
@ -384,5 +406,25 @@ function renderDataResultScreen(resultCount, view) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-xl-12 col-lg-12 col-sm-12">
|
||||
<div class="card shadow mb-4">
|
||||
<div class="card-header py-3 d-flex flex-row align-items-center justify-content-between">
|
||||
<h6 class="m-0 font-weight-bold col-black"><i
|
||||
class="fas fa-fw fa-globe col-green"></i>
|
||||
Geolocations</h6>
|
||||
</div>
|
||||
<div class="chart-area row" style="height: 100%;">
|
||||
<div class="col-xs-12 col-sm-12 col-md-3 col-lg-3">
|
||||
<div id="countryBarChart"></div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-12 col-md-9 col-lg-9">
|
||||
<div id="worldMap"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
}
|
@ -946,7 +946,7 @@
|
||||
joinBy: ['iso-a3', 'code']
|
||||
};
|
||||
var geolocationBarSeries = {
|
||||
color: '#4CAF50',
|
||||
color: json.colors.bars,
|
||||
name: 'Players',
|
||||
data: json.geolocation_bar_series.map(function (bar) {
|
||||
return bar.value
|
||||
@ -955,7 +955,7 @@
|
||||
var geolocationBarCategories = json.geolocation_bar_series.map(function (bar) {
|
||||
return bar.label
|
||||
});
|
||||
worldMap('worldMap', v.colors.geolocationsLow, v.colors.geolocationsHigh, geolocationSeries);
|
||||
worldMap('worldMap', json.colors.low, json.colors.high, geolocationSeries);
|
||||
horizontalBarChart('countryBarChart', geolocationBarCategories, [geolocationBarSeries], 'Players');
|
||||
} else if (error) {
|
||||
$('#worldMap').text("Failed to load graph data: " + error);
|
||||
|
Loading…
Reference in New Issue
Block a user