Skip to content

Commit

Permalink
WIP: Rating statistics from game collection
Browse files Browse the repository at this point in the history
  • Loading branch information
Tellmarch committed May 5, 2024
1 parent b51a890 commit 3b70362
Show file tree
Hide file tree
Showing 13 changed files with 521 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.playshogi.website.gwt.client.activity;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AcceptsOneWidget;
import com.google.web.bindery.event.shared.EventBus;
import com.google.web.bindery.event.shared.binder.EventBinder;
import com.playshogi.website.gwt.client.SessionInformation;
import com.playshogi.website.gwt.client.events.collections.CollectionStatisticsEvent;
import com.playshogi.website.gwt.client.place.GameCollectionStatisticsPlace;
import com.playshogi.website.gwt.client.ui.GameCollectionStatisticsView;
import com.playshogi.website.gwt.shared.models.GameCollectionStatisticsDetails;
import com.playshogi.website.gwt.shared.services.KifuService;
import com.playshogi.website.gwt.shared.services.KifuServiceAsync;

public class GameCollectionStatisticsActivity extends MyAbstractActivity {
private final KifuServiceAsync kifuService = GWT.create(KifuService.class);
private EventBus eventBus;

interface MyEventBinder extends EventBinder<GameCollectionStatisticsActivity> {
}

private final MyEventBinder eventBinder = GWT.create(MyEventBinder.class);

private final GameCollectionStatisticsPlace place;
private final GameCollectionStatisticsView view;
private final SessionInformation sessionInformation;

public GameCollectionStatisticsActivity(final GameCollectionStatisticsPlace place,
final GameCollectionStatisticsView view,
final SessionInformation sessionInformation) {
this.place = place;
this.view = view;
this.sessionInformation = sessionInformation;
}

@Override
public void start(final AcceptsOneWidget containerWidget, final EventBus eventBus) {
GWT.log("Starting game collection statistics activity");
this.eventBus = eventBus;
eventBinder.bindEventHandlers(this, eventBus);
view.activate(eventBus);

fetchData();

containerWidget.setWidget(view.asWidget());
}

private void fetchData() {
GWT.log("Querying for collection games");
kifuService.getGameSetStatistics(sessionInformation.getSessionId(), place.getCollectionId(),
new AsyncCallback<GameCollectionStatisticsDetails>() {
@Override
public void onFailure(Throwable throwable) {
GWT.log("GameCollectionStatisticsActivity: error retrieving collection stats");
}

@Override
public void onSuccess(GameCollectionStatisticsDetails result) {
GWT.log("GameCollectionStatisticsActivity: retrieved collection stats");
eventBus.fireEvent(new CollectionStatisticsEvent(result));
}
});
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.playshogi.website.gwt.client.events.collections;

import com.google.web.bindery.event.shared.binder.GenericEvent;
import com.playshogi.website.gwt.shared.models.GameCollectionStatisticsDetails;

public class CollectionStatisticsEvent extends GenericEvent {
private final GameCollectionStatisticsDetails statistics;

public CollectionStatisticsEvent(final GameCollectionStatisticsDetails statistics) {
this.statistics = statistics;
}

public GameCollectionStatisticsDetails getStatistics() {
return statistics;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ public class AppActivityMapper implements ActivityMapper {
AdminCollectionsView adminCollectionsView;
@Inject
ProblemsRaceView problemsRaceView;
@Inject
GameCollectionStatisticsView gameCollectionStatisticsView;

@Override
public Activity getActivity(final Place place) {
Expand Down Expand Up @@ -143,6 +145,9 @@ public Activity getActivity(final Place place) {
sessionInformation);
} else if (place instanceof ProblemsRacePlace) {
return new ProblemsRaceActivity((ProblemsRacePlace) place, problemsRaceView, sessionInformation);
} else if (place instanceof GameCollectionStatisticsPlace) {
return new GameCollectionStatisticsActivity((GameCollectionStatisticsPlace) place,
gameCollectionStatisticsView, sessionInformation);
}

return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
MyCollectionsPlace.Tokenizer.class, CollectionHelpPlace.Tokenizer.class, GameCollectionPlace.Tokenizer.class,
LessonsPlace.Tokenizer.class, TournamentPlace.Tokenizer.class, ManageLessonsPlace.Tokenizer.class,
ProblemCollectionsPlace.Tokenizer.class, ProblemCollectionPlace.Tokenizer.class,
ViewLessonPlace.Tokenizer.class, AdminCollectionsPlace.Tokenizer.class, ProblemsRacePlace.Tokenizer.class})
ViewLessonPlace.Tokenizer.class, AdminCollectionsPlace.Tokenizer.class, ProblemsRacePlace.Tokenizer.class,
GameCollectionStatisticsPlace.Tokenizer.class})
public interface AppPlaceHistoryMapper extends PlaceHistoryMapper {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.playshogi.website.gwt.client.place;

import com.google.gwt.place.shared.Place;
import com.google.gwt.place.shared.PlaceTokenizer;
import com.google.gwt.place.shared.Prefix;

public class GameCollectionStatisticsPlace extends Place {

private final String collectionId;

public GameCollectionStatisticsPlace(final String collectionId) {
this.collectionId = collectionId;
}

public String getCollectionId() {
return collectionId;
}

@Prefix("GameCollectionStatistics")
public static class Tokenizer implements PlaceTokenizer<GameCollectionStatisticsPlace> {

@Override
public String getToken(final GameCollectionStatisticsPlace place) {
return place.collectionId;
}

@Override
public GameCollectionStatisticsPlace getPlace(final String token) {
return new GameCollectionStatisticsPlace(token);
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
package com.playshogi.website.gwt.client.ui;

import com.google.gwt.core.client.GWT;
import com.google.gwt.place.shared.PlaceController;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.ScrollPanel;
import com.google.web.bindery.event.shared.EventBus;
import com.google.web.bindery.event.shared.binder.EventBinder;
import com.google.web.bindery.event.shared.binder.EventHandler;
import com.googlecode.gwt.charts.client.ColumnType;
import com.googlecode.gwt.charts.client.DataTable;
import com.googlecode.gwt.charts.client.corechart.LineChart;
import com.googlecode.gwt.charts.client.corechart.LineChartOptions;
import com.googlecode.gwt.charts.client.options.HAxis;
import com.googlecode.gwt.charts.client.options.VAxis;
import com.playshogi.website.gwt.client.SessionInformation;
import com.playshogi.website.gwt.client.events.collections.CollectionStatisticsEvent;
import com.playshogi.website.gwt.client.mvp.AppPlaceHistoryMapper;
import com.playshogi.website.gwt.client.util.ElementWidget;
import com.playshogi.website.gwt.client.util.MyChartLoader;
import com.playshogi.website.gwt.shared.models.GameCollectionStatisticsDetails;
import elemental2.dom.HTMLDivElement;
import elemental2.dom.HTMLHeadingElement;
import elemental2.dom.Node;
import jsinterop.base.Js;
import org.dominokit.domino.ui.Typography.Paragraph;
import org.dominokit.domino.ui.icons.Icons;
import org.dominokit.domino.ui.style.Styles;
import org.dominokit.domino.ui.tabs.Tab;
import org.dominokit.domino.ui.tabs.TabsPanel;
import org.jboss.elemento.Elements;
import org.jboss.elemento.HtmlContentBuilder;

import javax.inject.Inject;
import javax.inject.Singleton;

import static org.jboss.elemento.Elements.b;

@Singleton
public class GameCollectionStatisticsView extends Composite {

interface MyEventBinder extends EventBinder<GameCollectionStatisticsView> {
}

private final MyEventBinder eventBinder = GWT.create(MyEventBinder.class);

private final SessionInformation sessionInformation;
private final AppPlaceHistoryMapper historyMapper;

private final HtmlContentBuilder<HTMLHeadingElement> collectionHeading;
private final HtmlContentBuilder<HTMLHeadingElement> collectionDescription;

private final Tab ratingTab;

private LineChart ratingOverTimeGraph;
private LineChart ratingOverGamesGraph;
private EventBus eventBus;

private GameCollectionStatisticsDetails statistics;

@Inject
public GameCollectionStatisticsView(final SessionInformation sessionInformation,
final AppPlaceHistoryMapper historyMapper,
final PlaceController placeController) {
this.sessionInformation = sessionInformation;
this.historyMapper = historyMapper;

HtmlContentBuilder<HTMLDivElement> root = Elements.div();
root.css(Styles.padding_20);
collectionHeading = Elements.h(2).textContent("");
collectionDescription = Elements.h(4).textContent("");
root.add(collectionHeading);
root.add(collectionDescription);


ratingTab = Tab.create(Icons.ALL.face(), " RATING")
.appendChild(b().textContent("Profile Content"));

String SAMPLE_TEXT = "TO DO";
root.add(
TabsPanel.create()
.appendChild(
Tab.create(Icons.ALL.home_mdi(), " GENERAL")
.appendChild(b().textContent("Home Content"))
.appendChild(Paragraph.create(SAMPLE_TEXT)))
.appendChild(ratingTab.activate())
.appendChild(
Tab.create(Icons.ALL.email(), " OPENINGS")
.appendChild(b().textContent("Messages Content"))
.appendChild(Paragraph.create(SAMPLE_TEXT)))
.appendChild(
Tab.create(Icons.ALL.settings(), " ENDGAME")
.appendChild(b().textContent("Settings Content"))
.appendChild(Paragraph.create(SAMPLE_TEXT)))
.element());


ScrollPanel scrollPanel = new ScrollPanel();
scrollPanel.add(new ElementWidget(root.element()));
scrollPanel.setSize("100%", "100%");


createChartWhenReady();
initWidget(scrollPanel);
}

private void createChartWhenReady() {
MyChartLoader.INSTANCE.runWhenReady(() -> {
GWT.log("*** START GameCollectionStatisticsView INITIALIZATION");
ratingOverTimeGraph = new LineChart();
ratingTab.appendChild(Js.<Node>uncheckedCast(ratingOverTimeGraph.getElement()));
ratingOverGamesGraph = new LineChart();
ratingTab.appendChild(Js.<Node>uncheckedCast(ratingOverGamesGraph.getElement()));
draw();
});
}


private void draw() {
if (ratingOverTimeGraph == null || ratingOverGamesGraph == null) {
return;
}
if (statistics == null) {
ratingOverTimeGraph.clearChart();
ratingOverGamesGraph.clearChart();
return;
}


ratingOverGamesGraph.draw(getRatingOverGamesData(), getRatingOverGamesChartOptions());
ratingOverTimeGraph.draw(getRatingOverTimeData(), getRatingOverTimeChartOptions());
}

private static LineChartOptions getRatingOverGamesChartOptions() {
LineChartOptions options = LineChartOptions.create();
options.setBackgroundColor("#f0f0f0");
options.setFontName("Tahoma");
options.setTitle("Rating over games");
options.setHAxis(HAxis.create("Game"));
options.setVAxis(VAxis.create("Rating"));
options.setWidth(800);
options.setHeight(400);
return options;
}

private static LineChartOptions getRatingOverTimeChartOptions() {
LineChartOptions options = LineChartOptions.create();
options.setBackgroundColor("#f0f0f0");
options.setFontName("Tahoma");
options.setTitle("Rating over time");
options.setHAxis(HAxis.create("Date"));
options.setVAxis(VAxis.create("Rating"));
options.setWidth(800);
options.setHeight(400);
return options;
}

private DataTable getRatingOverTimeData() {
DataTable dataTable = DataTable.create();
dataTable.addColumn(ColumnType.DATE, "Date");
for (int i = 0; i < statistics.getRatingType().length; i++) {
dataTable.addColumn(ColumnType.NUMBER, statistics.getRatingType()[i]);
}
dataTable.addRows(statistics.getRatingDates().length);
for (int i = 0; i < statistics.getRatingDates().length; i++) {
dataTable.setValue(i, 0, statistics.getRatingDates()[i]);
}
for (int col = 0; col < statistics.getRatingValues().length; col++) {
for (int row = 0; row < statistics.getRatingValues()[col].length; row++) {
dataTable.setValue(row, col + 1, statistics.getRatingValues()[col][row]);
}
}
return dataTable;
}

private DataTable getRatingOverGamesData() {
DataTable dataTable = DataTable.create();
dataTable.addColumn(ColumnType.NUMBER, "Game");
for (int i = 0; i < statistics.getRatingType().length; i++) {
dataTable.addColumn(ColumnType.NUMBER, statistics.getRatingType()[i]);
}
dataTable.addRows(statistics.getRatingDates().length);
for (int i = 0; i < statistics.getRatingDates().length; i++) {
dataTable.setValue(i, 0, i);
}
for (int col = 0; col < statistics.getRatingValues().length; col++) {
for (int row = 0; row < statistics.getRatingValues()[col].length; row++) {
dataTable.setValue(row, col + 1, statistics.getRatingValues()[col][row]);
}
}
return dataTable;
}


public void activate(final EventBus eventBus) {
GWT.log("Activating CollectionView");
this.eventBus = eventBus;
this.statistics = null;
eventBinder.bindEventHandlers(this, eventBus);
draw();
}


@EventHandler
public void onCollectionStatistics(final CollectionStatisticsEvent event) {
GWT.log("CollectionView: handle CollectionStatisticsEvent");
statistics = event.getStatistics();
collectionHeading.textContent(statistics.getDetails().getName());
collectionDescription.textContent(statistics.getDetails().getDescription());
draw();
}
}
Loading

0 comments on commit 3b70362

Please sign in to comment.