moved all charts to a module. part of #495

This commit is contained in:
Miodec 2021-03-14 00:06:36 +00:00
parent 9e93688778
commit c9626396d8
9 changed files with 780 additions and 862 deletions

View file

@ -101,6 +101,7 @@ const refactoredSrc = [
"./src/js/test/test-stats.js",
"./src/js/theme-colors.js",
"./src/js/test/out-of-focus.js",
"./src/js/chart-controller.js",
];
//legacy files

View file

@ -478,543 +478,71 @@ function getAccountDataAndInit() {
});
}
var resultHistoryChart = new Chart($(".pageAccount #resultHistoryChart"), {
animationSteps: 60,
type: "line",
data: {
datasets: [
{
yAxisID: "wpm",
label: "wpm",
fill: false,
data: [],
borderColor: "#f44336",
borderWidth: 2,
trendlineLinear: {
style: "rgba(255,105,180, .8)",
lineStyle: "dotted",
width: 4,
},
},
{
yAxisID: "acc",
label: "acc",
fill: false,
data: [],
borderColor: "#cccccc",
borderWidth: 2,
},
],
},
options: {
tooltips: {
// Disable the on-canvas tooltip
enabled: true,
intersect: false,
custom: function (tooltip) {
if (!tooltip) return;
// disable displaying the color box;
tooltip.displayColors = false;
},
callbacks: {
// HERE YOU CUSTOMIZE THE LABELS
title: function () {
return;
},
beforeLabel: function (tooltipItem, data) {
let resultData =
data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
if (tooltipItem.datasetIndex !== 0) {
return `error rate: ${Misc.roundTo2(
resultData.y
)}%\nacc: ${Misc.roundTo2(100 - resultData.y)}%`;
}
let label =
`${data.datasets[tooltipItem.datasetIndex].label}: ${
tooltipItem.yLabel
}` +
"\n" +
`raw: ${resultData.raw}` +
"\n" +
`acc: ${resultData.acc}` +
"\n\n" +
`mode: ${resultData.mode} `;
if (resultData.mode == "time") {
label += resultData.mode2;
} else if (resultData.mode == "words") {
label += resultData.mode2;
}
let diff = resultData.difficulty;
if (diff == undefined) {
diff = "normal";
}
label += "\n" + `difficulty: ${diff}`;
label +=
"\n" +
`punctuation: ${resultData.punctuation}` +
"\n" +
`language: ${resultData.language}` +
"\n\n" +
`date: ${moment(resultData.timestamp).format("DD MMM YYYY HH:mm")}`;
return label;
},
label: function () {
return;
},
afterLabel: function () {
return;
},
},
},
animation: {
duration: 250,
},
legend: {
display: false,
labels: {
fontColor: "#ffffff",
},
},
responsive: true,
maintainAspectRatio: false,
hover: {
mode: "nearest",
intersect: false,
},
scales: {
xAxes: [
{
ticks: {},
type: "time",
bounds: "ticks",
distribution: "series",
display: false,
offset: true,
scaleLabel: {
display: false,
labelString: "Date",
},
},
],
yAxes: [
{
id: "wpm",
ticks: {
beginAtZero: true,
min: 0,
stepSize: 10,
},
display: true,
scaleLabel: {
display: true,
labelString: "Words per Minute",
},
},
{
id: "acc",
ticks: {
beginAtZero: true,
max: 100,
},
display: true,
position: "right",
scaleLabel: {
display: true,
labelString: "Error rate (100 - accuracy)",
},
gridLines: {
display: false,
},
},
],
},
},
});
let activityChart = new Chart($(".pageAccount #activityChart"), {
animationSteps: 60,
type: "bar",
data: {
datasets: [
{
yAxisID: "count",
label: "Seconds",
data: [],
trendlineLinear: {
style: "rgba(255,105,180, .8)",
lineStyle: "dotted",
width: 2,
},
order: 3,
},
{
yAxisID: "avgWpm",
label: "Average Wpm",
data: [],
type: "line",
order: 2,
lineTension: 0,
fill: false,
},
],
},
options: {
tooltips: {
callbacks: {
// HERE YOU CUSTOMIZE THE LABELS
title: function (tooltipItem, data) {
let resultData =
data.datasets[tooltipItem[0].datasetIndex].data[
tooltipItem[0].index
];
return moment(resultData.x).format("DD MMM YYYY");
},
beforeLabel: function (tooltipItem, data) {
let resultData =
data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
if (tooltipItem.datasetIndex === 0) {
return `Time Typing: ${Misc.secondsToString(
resultData.y
)}\nTests Completed: ${resultData.amount}`;
} else if (tooltipItem.datasetIndex === 1) {
return `Average Wpm: ${Misc.roundTo2(resultData.y)}`;
}
},
label: function () {
return;
},
},
},
animation: {
duration: 250,
},
legend: {
display: false,
labels: {
fontColor: "#ffffff",
},
},
responsive: true,
maintainAspectRatio: false,
hover: {
mode: "nearest",
intersect: false,
},
scales: {
xAxes: [
{
ticks: {
autoSkip: true,
autoSkipPadding: 40,
},
type: "time",
time: {
unit: "day",
displayFormats: {
day: "D MMM",
},
},
bounds: "ticks",
distribution: "series",
display: true,
scaleLabel: {
display: false,
labelString: "Date",
},
offset: true,
},
],
yAxes: [
{
id: "count",
ticks: {
beginAtZero: true,
min: 0,
autoSkip: true,
autoSkipPadding: 40,
stepSize: 10,
},
display: true,
scaleLabel: {
display: true,
labelString: "Time Typing",
},
},
{
id: "avgWpm",
ticks: {
beginAtZero: true,
min: 0,
autoSkip: true,
autoSkipPadding: 40,
stepSize: 10,
},
display: true,
position: "right",
scaleLabel: {
display: true,
labelString: "Average Wpm",
},
gridLines: {
display: false,
},
},
],
},
},
});
let hoverChart = new Chart($(".pageAccount #hoverChart"), {
type: "line",
data: {
labels: [],
datasets: [
{
label: "wpm",
data: [],
borderColor: "rgba(125, 125, 125, 1)",
borderWidth: 2,
yAxisID: "wpm",
order: 2,
radius: 2,
},
{
label: "raw",
data: [],
borderColor: "rgba(125, 125, 125, 1)",
borderWidth: 2,
yAxisID: "raw",
order: 3,
radius: 2,
},
{
label: "errors",
data: [],
borderColor: "rgba(255, 125, 125, 1)",
pointBackgroundColor: "rgba(255, 125, 125, 1)",
borderWidth: 2,
order: 1,
yAxisID: "error",
maxBarThickness: 10,
type: "scatter",
pointStyle: "crossRot",
radius: function (context) {
var index = context.dataIndex;
var value = context.dataset.data[index];
return value <= 0 ? 0 : 3;
},
pointHoverRadius: function (context) {
var index = context.dataIndex;
var value = context.dataset.data[index];
return value <= 0 ? 0 : 5;
},
},
],
},
options: {
tooltips: {
mode: "index",
intersect: false,
},
legend: {
display: false,
labels: {},
},
responsive: true,
maintainAspectRatio: false,
scales: {
xAxes: [
{
ticks: {
autoSkip: true,
autoSkipPadding: 40,
},
display: true,
scaleLabel: {
display: false,
labelString: "Seconds",
},
},
],
yAxes: [
{
id: "wpm",
display: true,
scaleLabel: {
display: true,
labelString: "Words per Minute",
},
ticks: {
beginAtZero: true,
min: 0,
autoSkip: true,
autoSkipPadding: 40,
},
gridLines: {
display: true,
},
},
{
id: "raw",
display: false,
scaleLabel: {
display: true,
labelString: "Raw Words per Minute",
},
ticks: {
beginAtZero: true,
min: 0,
autoSkip: true,
autoSkipPadding: 40,
},
gridLines: {
display: false,
},
},
{
id: "error",
display: true,
position: "right",
scaleLabel: {
display: true,
labelString: "Errors",
},
ticks: {
precision: 0,
beginAtZero: true,
autoSkip: true,
autoSkipPadding: 40,
},
gridLines: {
display: false,
},
},
],
},
annotation: {
annotations: [
{
enabled: false,
type: "line",
mode: "horizontal",
scaleID: "wpm",
value: "-30",
borderColor: "red",
borderWidth: 1,
borderDash: [2, 2],
label: {
// Background color of label, default below
backgroundColor: "blue",
// Font size of text, inherits from global
fontSize: 11,
// Font style of text, default below
fontStyle: "normal",
// Font color of text, default below
fontColor: "#fff",
// Padding of label to add left/right, default below
xPadding: 6,
// Padding of label to add top/bottom, default below
yPadding: 6,
// Radius of label rectangle, default below
cornerRadius: 3,
// Anchor position of label on line, can be one of: top, bottom, left, right, center. Default below.
position: "center",
// Whether the label is enabled and should be displayed
enabled: true,
// Text to display in label - default is null. Provide an array to display values on a new line
content: "PB",
},
},
],
},
},
});
function updateHoverChart(filteredId) {
function updateMiniResultChart(filteredId) {
let data = filteredResults[filteredId].chartData;
let labels = [];
for (let i = 1; i <= data.wpm.length; i++) {
labels.push(i.toString());
}
hoverChart.data.labels = labels;
hoverChart.data.datasets[0].data = data.wpm;
hoverChart.data.datasets[1].data = data.raw;
hoverChart.data.datasets[2].data = data.err;
ChartController.miniResult.data.labels = labels;
ChartController.miniResult.data.datasets[0].data = data.wpm;
ChartController.miniResult.data.datasets[1].data = data.raw;
ChartController.miniResult.data.datasets[2].data = data.err;
hoverChart.options.scales.xAxes[0].ticks.minor.fontColor = ThemeColors.sub;
hoverChart.options.scales.xAxes[0].scaleLabel.fontColor = ThemeColors.sub;
hoverChart.options.scales.yAxes[0].ticks.minor.fontColor = ThemeColors.sub;
hoverChart.options.scales.yAxes[2].ticks.minor.fontColor = ThemeColors.sub;
hoverChart.options.scales.yAxes[0].scaleLabel.fontColor = ThemeColors.sub;
hoverChart.options.scales.yAxes[2].scaleLabel.fontColor = ThemeColors.sub;
hoverChart.data.datasets[0].borderColor = ThemeColors.main;
hoverChart.data.datasets[0].pointBackgroundColor = ThemeColors.main;
hoverChart.data.datasets[1].borderColor = ThemeColors.sub;
hoverChart.data.datasets[1].pointBackgroundColor = ThemeColors.sub;
hoverChart.options.annotation.annotations[0].borderColor = ThemeColors.sub;
hoverChart.options.annotation.annotations[0].label.backgroundColor =
ThemeColors.sub;
hoverChart.options.annotation.annotations[0].label.fontColor = ThemeColors.bg;
ChartController.miniResult.updateColors();
let maxChartVal = Math.max(...[Math.max(...data.wpm), Math.max(...data.raw)]);
let minChartVal = Math.min(...[Math.min(...data.wpm), Math.min(...data.raw)]);
hoverChart.options.scales.yAxes[0].ticks.max = Math.round(maxChartVal);
hoverChart.options.scales.yAxes[1].ticks.max = Math.round(maxChartVal);
ChartController.miniResult.options.scales.yAxes[0].ticks.max = Math.round(
maxChartVal
);
ChartController.miniResult.options.scales.yAxes[1].ticks.max = Math.round(
maxChartVal
);
if (!config.startGraphsAtZero) {
hoverChart.options.scales.yAxes[0].ticks.min = Math.round(minChartVal);
hoverChart.options.scales.yAxes[1].ticks.min = Math.round(minChartVal);
ChartController.miniResult.options.scales.yAxes[0].ticks.min = Math.round(
minChartVal
);
ChartController.miniResult.options.scales.yAxes[1].ticks.min = Math.round(
minChartVal
);
} else {
hoverChart.options.scales.yAxes[0].ticks.min = 0;
hoverChart.options.scales.yAxes[1].ticks.min = 0;
ChartController.miniResult.options.scales.yAxes[0].ticks.min = 0;
ChartController.miniResult.options.scales.yAxes[1].ticks.min = 0;
}
hoverChart.update({ duration: 0 });
ChartController.miniResult.update({ duration: 0 });
}
function showHoverChart() {
$(".pageAccount .hoverChartWrapper").stop(true, true).fadeIn(125);
$(".pageAccount .hoverChartBg").stop(true, true).fadeIn(125);
function showMiniResultChart() {
$(".pageAccount .miniResultChartWrapper").stop(true, true).fadeIn(125);
$(".pageAccount .miniResultChartBg").stop(true, true).fadeIn(125);
}
function hideHoverChart() {
$(".pageAccount .hoverChartWrapper").stop(true, true).fadeOut(125);
$(".pageAccount .hoverChartBg").stop(true, true).fadeOut(125);
function hideMiniResultChart() {
$(".pageAccount .miniResultChartWrapper").stop(true, true).fadeOut(125);
$(".pageAccount .miniResultChartBg").stop(true, true).fadeOut(125);
}
function updateHoverChartPosition(x, y) {
$(".pageAccount .hoverChartWrapper").css({ top: y, left: x });
function updateMiniResultChartPosition(x, y) {
$(".pageAccount .miniResultChartWrapper").css({ top: y, left: x });
}
$(document).on("click", ".pageAccount .hoverChartButton", (event) => {
$(document).on("click", ".pageAccount .miniResultChartButton", (event) => {
console.log("updating");
let filterid = $(event.currentTarget).attr("filteredResultsId");
if (filterid === undefined) return;
updateHoverChart(filterid);
showHoverChart();
updateHoverChartPosition(
event.pageX - $(".pageAccount .hoverChartWrapper").outerWidth(),
updateMiniResultChart(filterid);
showMiniResultChart();
updateMiniResultChartPosition(
event.pageX - $(".pageAccount .miniResultChartWrapper").outerWidth(),
event.pageY + 30
);
});
$(document).on("click", ".pageAccount .hoverChartBg", (event) => {
hideHoverChart();
$(document).on("click", ".pageAccount .miniResultChartBg", (event) => {
hideMiniResultChart();
});
Misc.getLanguageList().then((languages) => {
@ -1641,11 +1169,11 @@ function loadMoreLines() {
}
if (result.chartData === undefined) {
icons += `<span class="hoverChartButton" aria-label="No chart data found" data-balloon-pos="up"><i class="fas fa-chart-line"></i></span>`;
icons += `<span class="miniResultChartButton" aria-label="No chart data found" data-balloon-pos="up"><i class="fas fa-chart-line"></i></span>`;
} else if (result.chartData === "toolong") {
icons += `<span class="hoverChartButton" aria-label="Chart history is not available for long tests" data-balloon-pos="up"><i class="fas fa-chart-line"></i></span>`;
icons += `<span class="miniResultChartButton" aria-label="Chart history is not available for long tests" data-balloon-pos="up"><i class="fas fa-chart-line"></i></span>`;
} else {
icons += `<span class="hoverChartButton" aria-label="View graph" data-balloon-pos="up" filteredResultsId="${i}" style="opacity: 1"><i class="fas fa-chart-line"></i></span>`;
icons += `<span class="miniResultChartButton" aria-label="View graph" data-balloon-pos="up" filteredResultsId="${i}" style="opacity: 1"><i class="fas fa-chart-line"></i></span>`;
}
let tagNames = "";
@ -1767,7 +1295,8 @@ let totalSecondsFiltered = 0;
function refreshAccountPage() {
function cont() {
ThemeColors.update();
updateChartColors();
ChartController.accountHistory.updateColors();
ChartController.accountActivity.updateColors();
refreshGlobalStats();
fillPbTables();
@ -2116,63 +1645,26 @@ function refreshAccountPage() {
lastTimestamp = date;
});
activityChart.data.datasets[0].data = activityChartData_time;
activityChart.data.datasets[1].data = activityChartData_avgWpm;
ChartController.accountActivity.data.datasets[0].data = activityChartData_time;
ChartController.accountActivity.data.datasets[1].data = activityChartData_avgWpm;
activityChart.options.legend.labels.fontColor = ThemeColors.sub;
activityChart.options.scales.xAxes[0].ticks.minor.fontColor =
ThemeColors.sub;
activityChart.options.scales.yAxes[0].ticks.minor.fontColor =
ThemeColors.sub;
activityChart.options.scales.yAxes[0].scaleLabel.fontColor =
ThemeColors.sub;
activityChart.data.datasets[0].borderColor = ThemeColors.main;
activityChart.data.datasets[0].backgroundColor = ThemeColors.main;
activityChart.data.datasets[0].trendlineLinear.style = ThemeColors.sub;
activityChart.options.scales.yAxes[1].ticks.minor.fontColor =
ThemeColors.sub;
activityChart.options.scales.yAxes[1].scaleLabel.fontColor =
ThemeColors.sub;
activityChart.data.datasets[1].borderColor = ThemeColors.sub;
activityChart.options.legend.labels.fontColor = ThemeColors.sub;
resultHistoryChart.options.scales.xAxes[0].ticks.minor.fontColor =
ThemeColors.sub;
resultHistoryChart.options.scales.yAxes[0].ticks.minor.fontColor =
ThemeColors.sub;
resultHistoryChart.options.scales.yAxes[0].scaleLabel.fontColor =
ThemeColors.sub;
resultHistoryChart.options.scales.yAxes[1].ticks.minor.fontColor =
ThemeColors.sub;
resultHistoryChart.options.scales.yAxes[1].scaleLabel.fontColor =
ThemeColors.sub;
resultHistoryChart.data.datasets[0].borderColor = ThemeColors.main;
resultHistoryChart.data.datasets[1].borderColor = ThemeColors.sub;
resultHistoryChart.options.legend.labels.fontColor = ThemeColors.sub;
resultHistoryChart.data.datasets[0].trendlineLinear.style = ThemeColors.sub;
resultHistoryChart.data.datasets[0].data = chartData;
resultHistoryChart.data.datasets[1].data = accChartData;
ChartController.accountHistory.data.datasets[0].data = chartData;
ChartController.accountHistory.data.datasets[1].data = accChartData;
let wpms = chartData.map((r) => r.y);
let minWpmChartVal = Math.min(...wpms);
let maxWpmChartVal = Math.max(...wpms);
// let accuracies = accChartData.map((r) => r.y);
resultHistoryChart.options.scales.yAxes[0].ticks.max =
ChartController.accountHistory.options.scales.yAxes[0].ticks.max =
Math.floor(maxWpmChartVal) + (10 - (Math.floor(maxWpmChartVal) % 10));
if (!config.startGraphsAtZero) {
resultHistoryChart.options.scales.yAxes[0].ticks.min = Math.floor(
ChartController.accountHistory.options.scales.yAxes[0].ticks.min = Math.floor(
minWpmChartVal
);
} else {
resultHistoryChart.options.scales.yAxes[0].ticks.min = 0;
ChartController.accountHistory.options.scales.yAxes[0].ticks.min = 0;
}
if (chartData == [] || chartData.length == 0) {
@ -2254,16 +1746,16 @@ function refreshAccountPage() {
(testRestarts / testCount).toFixed(1)
);
if (resultHistoryChart.data.datasets[0].data.length > 0) {
resultHistoryChart.options.plugins.trendlineLinear = true;
if (ChartController.accountHistory.data.datasets[0].data.length > 0) {
ChartController.accountHistory.options.plugins.trendlineLinear = true;
} else {
resultHistoryChart.options.plugins.trendlineLinear = false;
ChartController.accountHistory.options.plugins.trendlineLinear = false;
}
if (activityChart.data.datasets[0].data.length > 0) {
activityChart.options.plugins.trendlineLinear = true;
if (ChartController.accountActivity.data.datasets[0].data.length > 0) {
ChartController.accountActivity.options.plugins.trendlineLinear = true;
} else {
activityChart.options.plugins.trendlineLinear = false;
ChartController.accountActivity.options.plugins.trendlineLinear = false;
}
let wpmPoints = filteredResults.map((r) => r.wpm).reverse();
@ -2282,8 +1774,8 @@ function refreshAccountPage() {
} wpm.`
);
resultHistoryChart.update({ duration: 0 });
activityChart.update({ duration: 0 });
ChartController.accountHistory.update({ duration: 0 });
ChartController.accountActivity.update({ duration: 0 });
swapElements($(".pageAccount .preloader"), $(".pageAccount .content"), 250);
}

666
src/js/chart-controller.js Normal file
View file

@ -0,0 +1,666 @@
import Chart from "chart.js";
import * as TestStats from "./test-stats";
import * as ThemeColors from "./theme-colors";
import * as Misc from "./misc";
export let result = new Chart($("#wpmChart"), {
type: "line",
data: {
labels: [],
datasets: [
{
label: "wpm",
data: [],
borderColor: "rgba(125, 125, 125, 1)",
borderWidth: 2,
yAxisID: "wpm",
order: 2,
radius: 2,
},
{
label: "raw",
data: [],
borderColor: "rgba(125, 125, 125, 1)",
borderWidth: 2,
yAxisID: "raw",
order: 3,
radius: 2,
},
{
label: "errors",
data: [],
borderColor: "rgba(255, 125, 125, 1)",
pointBackgroundColor: "rgba(255, 125, 125, 1)",
borderWidth: 2,
order: 1,
yAxisID: "error",
maxBarThickness: 10,
type: "scatter",
pointStyle: "crossRot",
radius: function (context) {
var index = context.dataIndex;
var value = context.dataset.data[index];
return value <= 0 ? 0 : 3;
},
pointHoverRadius: function (context) {
var index = context.dataIndex;
var value = context.dataset.data[index];
return value <= 0 ? 0 : 5;
},
},
],
},
options: {
tooltips: {
mode: "index",
intersect: false,
callbacks: {
afterLabel: function (ti) {
try {
$(".wordInputAfter").remove();
let wordsToHighlight =
TestStats.keypressPerSecond[parseInt(ti.xLabel) - 1].words;
let unique = [...new Set(wordsToHighlight)];
unique.forEach((wordIndex) => {
let wordEl = $($("#resultWordsHistory .words .word")[wordIndex]);
let input = wordEl.attr("input");
if (input != undefined)
wordEl.append(`<div class="wordInputAfter">${input}</div>`);
});
} catch {}
},
},
},
legend: {
display: false,
labels: {},
},
responsive: true,
maintainAspectRatio: false,
scales: {
xAxes: [
{
ticks: {
autoSkip: true,
autoSkipPadding: 40,
},
display: true,
scaleLabel: {
display: false,
labelString: "Seconds",
},
},
],
yAxes: [
{
id: "wpm",
display: true,
scaleLabel: {
display: true,
labelString: "Words per Minute",
},
ticks: {
beginAtZero: true,
min: 0,
autoSkip: true,
autoSkipPadding: 40,
},
gridLines: {
display: true,
},
},
{
id: "raw",
display: false,
scaleLabel: {
display: true,
labelString: "Raw Words per Minute",
},
ticks: {
beginAtZero: true,
min: 0,
autoSkip: true,
autoSkipPadding: 40,
},
gridLines: {
display: false,
},
},
{
id: "error",
display: true,
position: "right",
scaleLabel: {
display: true,
labelString: "Errors",
},
ticks: {
precision: 0,
beginAtZero: true,
autoSkip: true,
autoSkipPadding: 40,
},
gridLines: {
display: false,
},
},
],
},
annotation: {
annotations: [],
},
},
});
export let accountHistory = new Chart($(".pageAccount #accountHistoryChart"), {
animationSteps: 60,
type: "line",
data: {
datasets: [
{
yAxisID: "wpm",
label: "wpm",
fill: false,
data: [],
borderColor: "#f44336",
borderWidth: 2,
trendlineLinear: {
style: "rgba(255,105,180, .8)",
lineStyle: "dotted",
width: 4,
},
},
{
yAxisID: "acc",
label: "acc",
fill: false,
data: [],
borderColor: "#cccccc",
borderWidth: 2,
},
],
},
options: {
tooltips: {
// Disable the on-canvas tooltip
enabled: true,
intersect: false,
custom: function (tooltip) {
if (!tooltip) return;
// disable displaying the color box;
tooltip.displayColors = false;
},
callbacks: {
// HERE YOU CUSTOMIZE THE LABELS
title: function () {
return;
},
beforeLabel: function (tooltipItem, data) {
let resultData =
data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
if (tooltipItem.datasetIndex !== 0) {
return `error rate: ${Misc.roundTo2(
resultData.y
)}%\nacc: ${Misc.roundTo2(100 - resultData.y)}%`;
}
let label =
`${data.datasets[tooltipItem.datasetIndex].label}: ${
tooltipItem.yLabel
}` +
"\n" +
`raw: ${resultData.raw}` +
"\n" +
`acc: ${resultData.acc}` +
"\n\n" +
`mode: ${resultData.mode} `;
if (resultData.mode == "time") {
label += resultData.mode2;
} else if (resultData.mode == "words") {
label += resultData.mode2;
}
let diff = resultData.difficulty;
if (diff == undefined) {
diff = "normal";
}
label += "\n" + `difficulty: ${diff}`;
label +=
"\n" +
`punctuation: ${resultData.punctuation}` +
"\n" +
`language: ${resultData.language}` +
"\n\n" +
`date: ${moment(resultData.timestamp).format("DD MMM YYYY HH:mm")}`;
return label;
},
label: function () {
return;
},
afterLabel: function () {
return;
},
},
},
animation: {
duration: 250,
},
legend: {
display: false,
labels: {
fontColor: "#ffffff",
},
},
responsive: true,
maintainAspectRatio: false,
hover: {
mode: "nearest",
intersect: false,
},
scales: {
xAxes: [
{
ticks: {},
type: "time",
bounds: "ticks",
distribution: "series",
display: false,
offset: true,
scaleLabel: {
display: false,
labelString: "Date",
},
},
],
yAxes: [
{
id: "wpm",
ticks: {
beginAtZero: true,
min: 0,
stepSize: 10,
},
display: true,
scaleLabel: {
display: true,
labelString: "Words per Minute",
},
},
{
id: "acc",
ticks: {
beginAtZero: true,
max: 100,
},
display: true,
position: "right",
scaleLabel: {
display: true,
labelString: "Error rate (100 - accuracy)",
},
gridLines: {
display: false,
},
},
],
},
},
});
export let accountActivity = new Chart(
$(".pageAccount #accountActivityChart"),
{
animationSteps: 60,
type: "bar",
data: {
datasets: [
{
yAxisID: "count",
label: "Seconds",
data: [],
trendlineLinear: {
style: "rgba(255,105,180, .8)",
lineStyle: "dotted",
width: 2,
},
order: 3,
},
{
yAxisID: "avgWpm",
label: "Average Wpm",
data: [],
type: "line",
order: 2,
lineTension: 0,
fill: false,
},
],
},
options: {
tooltips: {
callbacks: {
// HERE YOU CUSTOMIZE THE LABELS
title: function (tooltipItem, data) {
let resultData =
data.datasets[tooltipItem[0].datasetIndex].data[
tooltipItem[0].index
];
return moment(resultData.x).format("DD MMM YYYY");
},
beforeLabel: function (tooltipItem, data) {
let resultData =
data.datasets[tooltipItem.datasetIndex].data[tooltipItem.index];
if (tooltipItem.datasetIndex === 0) {
return `Time Typing: ${Misc.secondsToString(
resultData.y
)}\nTests Completed: ${resultData.amount}`;
} else if (tooltipItem.datasetIndex === 1) {
return `Average Wpm: ${Misc.roundTo2(resultData.y)}`;
}
},
label: function () {
return;
},
},
},
animation: {
duration: 250,
},
legend: {
display: false,
labels: {
fontColor: "#ffffff",
},
},
responsive: true,
maintainAspectRatio: false,
hover: {
mode: "nearest",
intersect: false,
},
scales: {
xAxes: [
{
ticks: {
autoSkip: true,
autoSkipPadding: 40,
},
type: "time",
time: {
unit: "day",
displayFormats: {
day: "D MMM",
},
},
bounds: "ticks",
distribution: "series",
display: true,
scaleLabel: {
display: false,
labelString: "Date",
},
offset: true,
},
],
yAxes: [
{
id: "count",
ticks: {
beginAtZero: true,
min: 0,
autoSkip: true,
autoSkipPadding: 40,
stepSize: 10,
},
display: true,
scaleLabel: {
display: true,
labelString: "Time Typing",
},
},
{
id: "avgWpm",
ticks: {
beginAtZero: true,
min: 0,
autoSkip: true,
autoSkipPadding: 40,
stepSize: 10,
},
display: true,
position: "right",
scaleLabel: {
display: true,
labelString: "Average Wpm",
},
gridLines: {
display: false,
},
},
],
},
},
}
);
export let miniResult = new Chart($(".pageAccount #miniResultChart"), {
type: "line",
data: {
labels: [],
datasets: [
{
label: "wpm",
data: [],
borderColor: "rgba(125, 125, 125, 1)",
borderWidth: 2,
yAxisID: "wpm",
order: 2,
radius: 2,
},
{
label: "raw",
data: [],
borderColor: "rgba(125, 125, 125, 1)",
borderWidth: 2,
yAxisID: "raw",
order: 3,
radius: 2,
},
{
label: "errors",
data: [],
borderColor: "rgba(255, 125, 125, 1)",
pointBackgroundColor: "rgba(255, 125, 125, 1)",
borderWidth: 2,
order: 1,
yAxisID: "error",
maxBarThickness: 10,
type: "scatter",
pointStyle: "crossRot",
radius: function (context) {
var index = context.dataIndex;
var value = context.dataset.data[index];
return value <= 0 ? 0 : 3;
},
pointHoverRadius: function (context) {
var index = context.dataIndex;
var value = context.dataset.data[index];
return value <= 0 ? 0 : 5;
},
},
],
},
options: {
tooltips: {
mode: "index",
intersect: false,
},
legend: {
display: false,
labels: {},
},
responsive: true,
maintainAspectRatio: false,
scales: {
xAxes: [
{
ticks: {
autoSkip: true,
autoSkipPadding: 40,
},
display: true,
scaleLabel: {
display: false,
labelString: "Seconds",
},
},
],
yAxes: [
{
id: "wpm",
display: true,
scaleLabel: {
display: true,
labelString: "Words per Minute",
},
ticks: {
beginAtZero: true,
min: 0,
autoSkip: true,
autoSkipPadding: 40,
},
gridLines: {
display: true,
},
},
{
id: "raw",
display: false,
scaleLabel: {
display: true,
labelString: "Raw Words per Minute",
},
ticks: {
beginAtZero: true,
min: 0,
autoSkip: true,
autoSkipPadding: 40,
},
gridLines: {
display: false,
},
},
{
id: "error",
display: true,
position: "right",
scaleLabel: {
display: true,
labelString: "Errors",
},
ticks: {
precision: 0,
beginAtZero: true,
autoSkip: true,
autoSkipPadding: 40,
},
gridLines: {
display: false,
},
},
],
},
annotation: {
annotations: [
{
enabled: false,
type: "line",
mode: "horizontal",
scaleID: "wpm",
value: "-30",
borderColor: "red",
borderWidth: 1,
borderDash: [2, 2],
label: {
// Background color of label, default below
backgroundColor: "blue",
// Font size of text, inherits from global
fontSize: 11,
// Font style of text, default below
fontStyle: "normal",
// Font color of text, default below
fontColor: "#fff",
// Padding of label to add left/right, default below
xPadding: 6,
// Padding of label to add top/bottom, default below
yPadding: 6,
// Radius of label rectangle, default below
cornerRadius: 3,
// Anchor position of label on line, can be one of: top, bottom, left, right, center. Default below.
position: "center",
// Whether the label is enabled and should be displayed
enabled: true,
// Text to display in label - default is null. Provide an array to display values on a new line
content: "PB",
},
},
],
},
},
});
Chart.prototype.updateColors = function () {
updateColors(this);
};
export function updateColors(chart) {
if (ThemeColors.main == "") {
ThemeColors.update();
}
chart.data.datasets[0].borderColor = ThemeColors.main;
chart.data.datasets[0].pointBackgroundColor = ThemeColors.main;
chart.data.datasets[1].borderColor = ThemeColors.sub;
chart.data.datasets[1].pointBackgroundColor = ThemeColors.sub;
try {
chart.options.scales.xAxes[0].ticks.minor.fontColor = ThemeColors.sub;
chart.options.scales.xAxes[0].scaleLabel.fontColor = ThemeColors.sub;
} catch {}
try {
chart.options.scales.yAxes[0].ticks.minor.fontColor = ThemeColors.sub;
chart.options.scales.yAxes[0].scaleLabel.fontColor = ThemeColors.sub;
} catch {}
try {
chart.options.scales.yAxes[2].ticks.minor.fontColor = ThemeColors.sub;
chart.options.scales.yAxes[2].scaleLabel.fontColor = ThemeColors.sub;
} catch {}
try {
chart.options.scales.yAxes[2].ticks.minor.fontColor = ThemeColors.sub;
chart.options.scales.yAxes[2].scaleLabel.fontColor = ThemeColors.sub;
} catch {}
chart.update();
}
export function updateAllChartColors() {
ThemeColors.update();
accountHistory.updateColors();
result.updateColors();
accountActivity.updateColors();
miniResult.updateColors();
}

View file

@ -39,3 +39,4 @@ import * as ShiftTracker from "./shift-tracker";
import * as TestStats from "./test-stats";
import * as ThemeColors from "./theme-colors";
import * as OutOfFocus from "./out-of-focus";
import * as ChartController from "./chart-controller";

View file

@ -1705,7 +1705,7 @@ function showResult(difficultyFailed = false) {
let afkseconds = TestStats.calculateAfkSeconds();
let afkSecondsPercent = Misc.roundTo2((afkseconds / testtime) * 100);
wpmOverTimeChart.options.annotation.annotations = [];
ChartController.result.options.annotation.annotations = [];
$("#result #resultWordsHistory").addClass("hidden");
@ -1856,24 +1856,9 @@ function showResult(difficultyFailed = false) {
}
}
if (ThemeColors.main == "") {
ThemeColors.update();
}
ChartController.result.updateColors();
wpmOverTimeChart.options.scales.xAxes[0].ticks.minor.fontColor =
ThemeColors.sub;
wpmOverTimeChart.options.scales.xAxes[0].scaleLabel.fontColor =
ThemeColors.sub;
wpmOverTimeChart.options.scales.yAxes[0].ticks.minor.fontColor =
ThemeColors.sub;
wpmOverTimeChart.options.scales.yAxes[2].ticks.minor.fontColor =
ThemeColors.sub;
wpmOverTimeChart.options.scales.yAxes[0].scaleLabel.fontColor =
ThemeColors.sub;
wpmOverTimeChart.options.scales.yAxes[2].scaleLabel.fontColor =
ThemeColors.sub;
wpmOverTimeChart.data.labels = labels;
ChartController.result.data.labels = labels;
let rawWpmPerSecondRaw = TestStats.keypressPerSecond.map((f) =>
Math.round((f.count / 5) * 60)
@ -1914,26 +1899,21 @@ function showResult(difficultyFailed = false) {
);
}
wpmOverTimeChart.data.datasets[0].borderColor = ThemeColors.main;
wpmOverTimeChart.data.datasets[0].pointBackgroundColor = ThemeColors.main;
wpmOverTimeChart.data.datasets[0].data = TestStats.wpmHistory;
wpmOverTimeChart.data.datasets[1].borderColor = ThemeColors.sub;
wpmOverTimeChart.data.datasets[1].pointBackgroundColor = ThemeColors.sub;
wpmOverTimeChart.data.datasets[1].data = rawWpmPerSecond;
ChartController.result.data.datasets[1].data = rawWpmPerSecond;
let maxChartVal = Math.max(
...[Math.max(...rawWpmPerSecond), Math.max(...TestStats.wpmHistory)]
);
if (!config.startGraphsAtZero) {
wpmOverTimeChart.options.scales.yAxes[0].ticks.min = Math.min(
ChartController.result.options.scales.yAxes[0].ticks.min = Math.min(
...TestStats.wpmHistory
);
wpmOverTimeChart.options.scales.yAxes[1].ticks.min = Math.min(
ChartController.result.options.scales.yAxes[1].ticks.min = Math.min(
...TestStats.wpmHistory
);
} else {
wpmOverTimeChart.options.scales.yAxes[0].ticks.min = 0;
wpmOverTimeChart.options.scales.yAxes[1].ticks.min = 0;
ChartController.result.options.scales.yAxes[0].ticks.min = 0;
ChartController.result.options.scales.yAxes[1].ticks.min = 0;
}
// let errorsNoZero = [];
@ -1950,7 +1930,7 @@ function showResult(difficultyFailed = false) {
errorsArray.push(TestStats.keypressPerSecond[i].errors);
}
wpmOverTimeChart.data.datasets[2].data = errorsArray;
ChartController.result.data.datasets[2].data = errorsArray;
let kps = TestStats.keypressPerSecond.slice(
Math.max(TestStats.keypressPerSecond.length - 5, 0)
@ -2133,7 +2113,7 @@ function showResult(difficultyFailed = false) {
}
}
if (lpb > 0) {
wpmOverTimeChart.options.annotation.annotations.push({
ChartController.result.options.annotation.annotations.push({
enabled: false,
type: "line",
mode: "horizontal",
@ -2159,13 +2139,13 @@ function showResult(difficultyFailed = false) {
if (maxChartVal >= lpb - 15 && maxChartVal <= lpb + 15) {
maxChartVal = lpb + 15;
}
wpmOverTimeChart.options.scales.yAxes[0].ticks.max = Math.round(
ChartController.result.options.scales.yAxes[0].ticks.max = Math.round(
maxChartVal
);
wpmOverTimeChart.options.scales.yAxes[1].ticks.max = Math.round(
ChartController.result.options.scales.yAxes[1].ticks.max = Math.round(
maxChartVal
);
wpmOverTimeChart.update({ duration: 0 });
ChartController.result.update({ duration: 0 });
}
if (config.mode === "time" && (mode2 === 15 || mode2 === 60)) {
$("#result .stats .leaderboards").removeClass("hidden");
@ -2215,7 +2195,7 @@ function showResult(difficultyFailed = false) {
);
// console.log("new pb for tag " + tag.name);
} else {
wpmOverTimeChart.options.annotation.annotations.push({
ChartController.result.options.annotation.annotations.push({
enabled: false,
type: "line",
mode: "horizontal",
@ -2650,15 +2630,15 @@ function showResult(difficultyFailed = false) {
$("#result .stats .source").addClass("hidden");
}
wpmOverTimeChart.options.scales.yAxes[0].ticks.max = maxChartVal;
wpmOverTimeChart.options.scales.yAxes[1].ticks.max = maxChartVal;
ChartController.result.options.scales.yAxes[0].ticks.max = maxChartVal;
ChartController.result.options.scales.yAxes[1].ticks.max = maxChartVal;
wpmOverTimeChart.update({ duration: 0 });
wpmOverTimeChart.resize();
ChartController.result.update({ duration: 0 });
ChartController.result.resize();
swapElements($("#typingTest"), $("#result"), 250, () => {
resultCalculating = false;
$("#words").empty();
wpmOverTimeChart.resize();
ChartController.result.resize();
if (config.alwaysShowWordsHistory) {
toggleResultWordsDisplay();
}
@ -2822,6 +2802,7 @@ function restartTest(withSameWordset = false, nosave = false, event) {
// }
// }
// }
if (testRestarting || resultCalculating) {
try {
event.preventDefault();
@ -3032,7 +3013,7 @@ function restartTest(withSameWordset = false, nosave = false, event) {
hideCrown();
clearTimeout(timer);
if ($("#commandLineWrapper").hasClass("hidden")) focusWords();
wpmOverTimeChart.update();
ChartController.result.update();
updateTestModesNotice();
pageTransition = false;
// console.log(TestStats.incompleteSeconds);
@ -5978,155 +5959,3 @@ async function setupChallenge(challengeName) {
Notifications.add("Something went wrong: " + e, -1);
}
}
let ctx = $("#wpmChart");
let wpmOverTimeChart = new Chart(ctx, {
type: "line",
data: {
labels: [],
datasets: [
{
label: "wpm",
data: [],
borderColor: "rgba(125, 125, 125, 1)",
borderWidth: 2,
yAxisID: "wpm",
order: 2,
radius: 2,
},
{
label: "raw",
data: [],
borderColor: "rgba(125, 125, 125, 1)",
borderWidth: 2,
yAxisID: "raw",
order: 3,
radius: 2,
},
{
label: "errors",
data: [],
borderColor: "rgba(255, 125, 125, 1)",
pointBackgroundColor: "rgba(255, 125, 125, 1)",
borderWidth: 2,
order: 1,
yAxisID: "error",
maxBarThickness: 10,
type: "scatter",
pointStyle: "crossRot",
radius: function (context) {
var index = context.dataIndex;
var value = context.dataset.data[index];
return value <= 0 ? 0 : 3;
},
pointHoverRadius: function (context) {
var index = context.dataIndex;
var value = context.dataset.data[index];
return value <= 0 ? 0 : 5;
},
},
],
},
options: {
tooltips: {
mode: "index",
intersect: false,
callbacks: {
afterLabel: function (ti) {
try {
$(".wordInputAfter").remove();
let wordsToHighlight =
TestStats.keypressPerSecond[parseInt(ti.xLabel) - 1].words;
let unique = [...new Set(wordsToHighlight)];
unique.forEach((wordIndex) => {
let wordEl = $($("#resultWordsHistory .words .word")[wordIndex]);
let input = wordEl.attr("input");
if (input != undefined)
wordEl.append(`<div class="wordInputAfter">${input}</div>`);
});
} catch {}
},
},
},
legend: {
display: false,
labels: {},
},
responsive: true,
maintainAspectRatio: false,
scales: {
xAxes: [
{
ticks: {
autoSkip: true,
autoSkipPadding: 40,
},
display: true,
scaleLabel: {
display: false,
labelString: "Seconds",
},
},
],
yAxes: [
{
id: "wpm",
display: true,
scaleLabel: {
display: true,
labelString: "Words per Minute",
},
ticks: {
beginAtZero: true,
min: 0,
autoSkip: true,
autoSkipPadding: 40,
},
gridLines: {
display: true,
},
},
{
id: "raw",
display: false,
scaleLabel: {
display: true,
labelString: "Raw Words per Minute",
},
ticks: {
beginAtZero: true,
min: 0,
autoSkip: true,
autoSkipPadding: 40,
},
gridLines: {
display: false,
},
},
{
id: "error",
display: true,
position: "right",
scaleLabel: {
display: true,
labelString: "Errors",
},
ticks: {
precision: 0,
beginAtZero: true,
autoSkip: true,
autoSkipPadding: 40,
},
gridLines: {
display: false,
},
},
],
},
annotation: {
annotations: [],
},
},
});

View file

@ -1013,8 +1013,7 @@ $(".pageSettings #loadCustomColorsFromPreset").click((e) => {
});
setTimeout(() => {
ThemeColors.update();
updateChartColors();
ChartController.updateAllChartColors();
colorVars.forEach((colorName) => {
let color;

View file

@ -261,20 +261,21 @@ function setBlindMode(blind, nosave) {
}
function updateChartAccuracy() {
resultHistoryChart.data.datasets[1].hidden = !config.chartAccuracy;
resultHistoryChart.options.scales.yAxes[1].display = config.chartAccuracy;
resultHistoryChart.update();
ChartController.accountHistory.data.datasets[1].hidden = !config.chartAccuracy;
ChartController.accountHistory.options.scales.yAxes[1].display =
config.chartAccuracy;
ChartController.accountHistory.update();
}
function updateChartStyle() {
if (config.chartStyle == "scatter") {
resultHistoryChart.data.datasets[0].showLine = false;
resultHistoryChart.data.datasets[1].showLine = false;
ChartController.accountHistory.data.datasets[0].showLine = false;
ChartController.accountHistory.data.datasets[1].showLine = false;
} else {
resultHistoryChart.data.datasets[0].showLine = true;
resultHistoryChart.data.datasets[1].showLine = true;
ChartController.accountHistory.data.datasets[0].showLine = true;
ChartController.accountHistory.data.datasets[1].showLine = true;
}
resultHistoryChart.update();
ChartController.accountHistory.update();
}
function toggleChartAccuracy() {
@ -1060,66 +1061,6 @@ function setIndicateTypos(it, nosave) {
if (!nosave) saveConfigToCookie();
}
function updateChartColors() {
hoverChart.options.scales.xAxes[0].ticks.minor.fontColor = ThemeColors.sub;
hoverChart.options.scales.xAxes[0].scaleLabel.fontColor = ThemeColors.sub;
hoverChart.options.scales.yAxes[0].ticks.minor.fontColor = ThemeColors.sub;
hoverChart.options.scales.yAxes[2].ticks.minor.fontColor = ThemeColors.sub;
hoverChart.options.scales.yAxes[0].scaleLabel.fontColor = ThemeColors.sub;
hoverChart.options.scales.yAxes[2].scaleLabel.fontColor = ThemeColors.sub;
hoverChart.data.datasets[0].borderColor = ThemeColors.main;
hoverChart.data.datasets[0].pointBackgroundColor = ThemeColors.main;
hoverChart.data.datasets[1].borderColor = ThemeColors.sub;
hoverChart.data.datasets[1].pointBackgroundColor = ThemeColors.sub;
hoverChart.options.annotation.annotations[0].borderColor = ThemeColors.sub;
hoverChart.options.annotation.annotations[0].label.backgroundColor =
ThemeColors.sub;
hoverChart.options.annotation.annotations[0].label.fontColor = ThemeColors.bg;
activityChart.options.legend.labels.fontColor = ThemeColors.sub;
activityChart.options.scales.xAxes[0].ticks.minor.fontColor = ThemeColors.sub;
activityChart.options.scales.yAxes[0].ticks.minor.fontColor = ThemeColors.sub;
activityChart.options.scales.yAxes[0].scaleLabel.fontColor = ThemeColors.sub;
activityChart.data.datasets[0].borderColor = ThemeColors.main;
activityChart.data.datasets[0].backgroundColor = ThemeColors.main;
activityChart.data.datasets[0].trendlineLinear.style = ThemeColors.sub;
activityChart.options.scales.yAxes[1].ticks.minor.fontColor = ThemeColors.sub;
activityChart.options.scales.yAxes[1].scaleLabel.fontColor = ThemeColors.sub;
activityChart.data.datasets[1].borderColor = ThemeColors.sub;
activityChart.options.legend.labels.fontColor = ThemeColors.sub;
resultHistoryChart.options.scales.xAxes[0].ticks.minor.fontColor =
ThemeColors.sub;
resultHistoryChart.options.scales.yAxes[0].ticks.minor.fontColor =
ThemeColors.sub;
resultHistoryChart.options.scales.yAxes[0].scaleLabel.fontColor =
ThemeColors.sub;
resultHistoryChart.options.scales.yAxes[1].ticks.minor.fontColor =
ThemeColors.sub;
resultHistoryChart.options.scales.yAxes[1].scaleLabel.fontColor =
ThemeColors.sub;
resultHistoryChart.data.datasets[0].borderColor = ThemeColors.main;
resultHistoryChart.data.datasets[1].borderColor = ThemeColors.sub;
resultHistoryChart.options.legend.labels.fontColor = ThemeColors.sub;
resultHistoryChart.data.datasets[0].trendlineLinear.style = ThemeColors.sub;
wpmOverTimeChart.data.datasets[0].borderColor = ThemeColors.main;
wpmOverTimeChart.data.datasets[0].pointBackgroundColor = ThemeColors.main;
wpmOverTimeChart.data.datasets[1].borderColor = ThemeColors.sub;
wpmOverTimeChart.data.datasets[1].pointBackgroundColor = ThemeColors.sub;
hoverChart.update();
wpmOverTimeChart.update();
resultHistoryChart.update();
activityChart.update();
}
let isPreviewingTheme = false;
function previewTheme(name, setIsPreviewingVar = true) {
if (
@ -1133,8 +1074,7 @@ function previewTheme(name, setIsPreviewingVar = true) {
clearCustomTheme();
$("#currentTheme").attr("href", `themes/${name}.css`);
setTimeout(() => {
ThemeColors.update();
updateChartColors();
ChartController.updateAllChartColors();
}, 500);
}
@ -1166,8 +1106,7 @@ function setTheme(name, nosave) {
// applyCustomThemeColors();
setTimeout(() => {
$(".keymap-key").attr("style", "");
ThemeColors.update();
updateChartColors();
ChartController.updateAllChartColors();
$("#metaThemeColor").attr("content", ThemeColors.main);
}, 500);
@ -1232,8 +1171,7 @@ function applyCustomThemeColors() {
clearCustomTheme();
}
setTimeout(() => {
ThemeColors.update();
updateChartColors();
ChartController.updateAllChartColors();
updateFavicon(32, 14);
$(".keymap-key").attr("style", "");
}, 500);

View file

@ -110,7 +110,7 @@ body {
background: var(--bg-color);
font-family: var(--font);
color: var(--main-color);
// overflow-x: hidden;
overflow-x: hidden;
}
html {
@ -2878,17 +2878,7 @@ key {
}
}
// .hoverChartWrapper {
// z-index: 999;
// display: none;
// width: 100%;
// height: 100%;
// background: rgba(0, 0, 0, 0.25);
// position: fixed;
// left: 0;
// top: 0;
// }
.hoverChartWrapper {
.miniResultChartWrapper {
// pointer-events: none;
z-index: 999;
display: none;
@ -2901,7 +2891,7 @@ key {
// box-shadow: 0 0 1rem rgba(0, 0, 0, 0.25);
}
.hoverChartBg {
.miniResultChartBg {
display: none;
z-index: 998;
width: 100%;
@ -3061,7 +3051,7 @@ key {
td.infoIcons span {
margin: 0 0.1rem;
}
.hoverChartButton {
.miniResultChartButton {
opacity: 0.25;
transition: 0.25s;
cursor: pointer;

View file

@ -151,26 +151,28 @@
<div id="quoteSearchPopupWrapper" class="hidden">
<div id="quoteSearchPopup" mode="">
<div class="title">Quote Search</div>
<input id="searchBox" class="searchBox" type="text" maxLength="200" autocomplete="off"/>
<input
id="searchBox"
class="searchBox"
type="text"
maxlength="200"
autocomplete="off"
/>
<table class="searchResultTable">
<thead>
<tr>
<td class="alignRight" width="5%">#</td>
<td class="alignRight" width="10%">length</td>
<td>
text
</td>
<td width="30%">
source
</td>
<td>text</td>
<td width="30%">source</td>
<td width="1%"></td>
</tr>
</thead>
<tbody id="searchResultList">
</tbody>
<tbody id="searchResultList"></tbody>
</table>
<div id="extraResults" class="quoteSearchResults">No search results</div>
<div id="extraResults" class="quoteSearchResults">
No search results
</div>
<div class="button">ok</div>
</div>
</div>
@ -3268,10 +3270,10 @@
<i class="fas fa-fw fa-spin fa-circle-notch"></i>
</div>
<div class="content hidden">
<div class="hoverChartWrapper">
<canvas id="hoverChart"></canvas>
<div class="miniResultChartWrapper">
<canvas id="miniResultChart"></canvas>
</div>
<div class="hoverChartBg"></div>
<div class="miniResultChartBg"></div>
<div class="triplegroup">
<div class="group globalTestsStarted">
<div class="title">tests started</div>
@ -3494,7 +3496,7 @@
</div> -->
<div class="above"></div>
<div class="chart" style="height: 400px">
<canvas id="resultHistoryChart"></canvas>
<canvas id="accountHistoryChart"></canvas>
</div>
<div class="below">
<div class="text"></div>
@ -3512,7 +3514,7 @@
</div>
<div class="group dailyActivityChart">
<div class="chart" style="height: 200px">
<canvas id="activityChart"></canvas>
<canvas id="accountActivityChart"></canvas>
</div>
</div>
<div class="triplegroup stats">