Rating graph on perfStat page, closes #2425

On each perfStat page, a rating graph is drawn for the specific perf (in the same color as its line on the complete profile rating graph). If there is no data for a certain perf, `lichess.ratingHistoryChart` will take care of hiding the assigned `<div>` as to not have a big white space on top of the perfStat page.

`ratingHistoryChart` also takes care of filtering out the non-perf lines -- this cannot happen on the server side because the rating graph cache contains all graphs.
pull/4608/head
ProgramFOX 2018-09-05 22:18:34 +02:00
parent 731833c303
commit 86b455edd6
4 changed files with 38 additions and 7 deletions

View File

@ -327,10 +327,11 @@ object User extends LilaController {
distribution <- u.perfs(perfType).established ?? {
Env.user.cached.ratingDistribution(perfType) map some
}
ratingChart <- Env.history.ratingChartApi.apply(u)
_ <- Env.user.lightUserApi preloadMany { u.id :: perfStat.userIds.map(_.value) }
data = Env.perfStat.jsonView(u, perfStat, ranks get perfType.key, distribution)
response <- negotiate(
html = Ok(html.user.perfStat(u, ranks, perfType, data)).fuccess,
html = Ok(html.user.perfStat(u, ranks, perfType, data, ratingChart)).fuccess,
api = _ => getBool("graph").?? {
Env.history.ratingChartApi.singlePerf(u, perfType).map(_.some)
} map {

View File

@ -1,6 +1,11 @@
@(u: User, rankMap: lila.rating.UserRankMap, perfType: lila.rating.PerfType, data: play.api.libs.json.JsObject)(implicit ctx: Context)
@(u: User, rankMap: lila.rating.UserRankMap, perfType: lila.rating.PerfType, data: play.api.libs.json.JsObject, ratingChart: Option[String])(implicit ctx: Context)
@moreJs = {
@ratingChart.map { rc =>
@jsTag("chart/ratingHistory.js")
@embedJsUnsafe(s"lichess.ratingHistoryChart($rc,'${perfType.name}');")
}
@jsAt(s"compiled/lichess.perfStat${isProd??(".min")}.js")
@embedJs {
$(function() {
@ -35,6 +40,11 @@ evenMoreCss = moreCss) {
</a>
</h1>
</div>
@if(ratingChart.isDefined){
<div class="rating_history">
@base.spinner()
</div>
}
<div class="content_box_content" id="perfStatContent"></div>
</div>
}

View File

@ -1,4 +1,9 @@
lichess.ratingHistoryChart = function(data) {
lichess.ratingHistoryChart = function(data, singlePerfName) {
var singlePerfIndex = data.findIndex(x => x.name === singlePerfName);
if (singlePerfName && data[singlePerfIndex].points.length === 0) {
$('div.rating_history').hide();
return;
}
lichess.loadScript('javascripts/chart/common.js').done(function() {
lichess.chartCommon('highstock').done(function() {
var disabled = {
@ -26,7 +31,7 @@ lichess.ratingHistoryChart = function(data) {
'Dash',
// UltraBullet
'ShortDot'
];
].filter((_, i) => !singlePerfName || i === singlePerfIndex);
$(this).highcharts('StockChart', {
yAxis: {
title: noText
@ -35,7 +40,7 @@ lichess.ratingHistoryChart = function(data) {
legend: disabled,
colors: ["#56B4E9", "#0072B2", "#009E73", "#459F3B", "#F0E442", "#E69F00", "#D55E00",
"#CC79A7", "#DF5353", "#66558C", "#99E699", "#FFAEAA"
],
].filter((_, i) => !singlePerfName || i === singlePerfIndex),
rangeSelector: {
enabled: true,
selected: 1,
@ -51,7 +56,7 @@ lichess.ratingHistoryChart = function(data) {
tickWidth: 0
},
scrollbar: disabled,
series: data.map(function(serie, i) {
series: data.filter(v => !singlePerfName || v.name === singlePerfName).map(function(serie, i) {
return {
name: serie.name,
type: 'line',
@ -61,7 +66,11 @@ lichess.ratingHistoryChart = function(data) {
radius: 2
},
data: serie.points.map(function(r) {
return [Date.UTC(r[0], r[1], r[2]), r[3]];
if (singlePerfName && serie.name !== singlePerfName) {
return [];
} else {
return [Date.UTC(r[0], r[1], r[2]), r[3]];
}
})
};
})

View File

@ -137,3 +137,14 @@
#perfStat .playStreak {
white-space: nowrap;
}
#perfStat .rating_history {
left: -10px;
display: block;
width: 100%;
height: 339px;
}
#perfStat .rating_history .spinner {
width: 90px;
height: 90px;
margin: 120px auto 0 auto;
}