Style: Unify formatting, add .editorconfig (#88)

This commit is contained in:
Thaddeus Crews
2024-07-28 16:28:09 -05:00
committed by GitHub
parent 375cec369a
commit b8827a41b2
12 changed files with 364 additions and 310 deletions

23
.editorconfig Normal file
View File

@@ -0,0 +1,23 @@
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = tab
insert_final_newline = true
trim_trailing_whitespace = true
[*.{csproj,sln}]
charset = utf-8-bom
end_of_line = crlf
[*.{cs,py}]
indent_style = space
[*.{csproj,yml,yaml}]
indent_size = 2
indent_style = space
[*.md]
trim_trailing_whitespace = false

7
.gitattributes vendored
View File

@@ -1 +1,8 @@
# Properly detect languages on Github
web/static/thirdparty/* linguist-vendored web/static/thirdparty/* linguist-vendored
# Normalize EOL for all files that Git considers text files
* text=auto eol=lf
# Except for Visual Studio files
*.sln eol=crlf
*.csproj eol=crlf

32
.gitignore vendored
View File

@@ -16,5 +16,35 @@ mono_crash.*.json
.directory .directory
*~ *~
# IDE-specific ignores
.fleet/
.history/
.idea/
.vs/
.vscode/
*.code-workspace
# Python-specific ignores
__pycache__/
*_cache/
*.pyc
.venv
venv
# Godot Git repository clone (run-benchmarks.sh) # Godot Git repository clone (run-benchmarks.sh)
/godot/ godot/
# Output HTML files
web/public/
# Temporary lock file while building
web/.hugo_build.lock
# Generated files
web/content/benchmark/*.md
web/content/graph/*.md
web/data/data.json
# Untracked source files
web/src-data/benchmarks/*.json
web/src-data/benchmarks/*.md

View File

@@ -1,4 +1,4 @@
<Project Sdk="Godot.NET.Sdk/4.3.0-dev.2"> <Project Sdk="Godot.NET.Sdk/4.3.0-dev.2">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net6.0</TargetFramework> <TargetFramework>net6.0</TargetFramework>
<TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net7.0</TargetFramework> <TargetFramework Condition=" '$(GodotTargetPlatform)' == 'android' ">net7.0</TargetFramework>

View File

@@ -1,12 +1,15 @@
Microsoft Visual Studio Solution File, Format Version 12.00 
# Visual Studio 2012 Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.10.35027.167
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Godot Benchmarks", "Godot Benchmarks.csproj", "{A7FD1DC6-AE2B-4F17-B4BA-2FD940E01B47}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Godot Benchmarks", "Godot Benchmarks.csproj", "{A7FD1DC6-AE2B-4F17-B4BA-2FD940E01B47}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU Debug|Any CPU = Debug|Any CPU
ExportDebug|Any CPU = ExportDebug|Any CPU ExportDebug|Any CPU = ExportDebug|Any CPU
ExportRelease|Any CPU = ExportRelease|Any CPU ExportRelease|Any CPU = ExportRelease|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A7FD1DC6-AE2B-4F17-B4BA-2FD940E01B47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A7FD1DC6-AE2B-4F17-B4BA-2FD940E01B47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@@ -16,4 +19,10 @@ Global
{A7FD1DC6-AE2B-4F17-B4BA-2FD940E01B47}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU {A7FD1DC6-AE2B-4F17-B4BA-2FD940E01B47}.ExportRelease|Any CPU.ActiveCfg = ExportRelease|Any CPU
{A7FD1DC6-AE2B-4F17-B4BA-2FD940E01B47}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU {A7FD1DC6-AE2B-4F17-B4BA-2FD940E01B47}.ExportRelease|Any CPU.Build.0 = ExportRelease|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {0C32B76F-38AD-4A1A-80F4-46FFBBB4BFB2}
EndGlobalSection
EndGlobal EndGlobal

View File

@@ -20,19 +20,19 @@ export DISPLAY=":0"
ARG1="${1:-''}" ARG1="${1:-''}"
if ! command -v git &> /dev/null; then if ! command -v git &> /dev/null; then
echo "ERROR: git must be installed and in PATH." echo "ERROR: git must be installed and in PATH."
exit 1 exit 1
fi fi
if [[ "$ARG1" == "--help" || "$ARG1" == "-h" ]]; then if [[ "$ARG1" == "--help" || "$ARG1" == "-h" ]]; then
echo "Usage: $0 [--skip-build]" echo "Usage: $0 [--skip-build]"
exit exit
fi fi
GODOT_REPO_DIR="$DIR/godot" GODOT_REPO_DIR="$DIR/godot"
if [[ ! -d "$GODOT_REPO_DIR/.git" ]]; then if [[ ! -d "$GODOT_REPO_DIR/.git" ]]; then
git clone https://github.com/godotengine/godot.git "$GODOT_REPO_DIR" git clone https://github.com/godotengine/godot.git "$GODOT_REPO_DIR"
fi fi
pushd "$GODOT_REPO_DIR" pushd "$GODOT_REPO_DIR"
@@ -48,64 +48,64 @@ latest_commit="$(git -C "$GODOT_REPO_DIR" rev-parse HEAD)"
pushd /tmp/godot-benchmarks-results/ pushd /tmp/godot-benchmarks-results/
for result in 2*.md; do for result in 2*.md; do
if [[ "${result:11:9}" == "${latest_commit:0:9}" ]]; then if [[ "${result:11:9}" == "${latest_commit:0:9}" ]]; then
echo "godot-benchmarks: Skipping benchmark run as the latest Godot commit is already present in the results repository." echo "godot-benchmarks: Skipping benchmark run as the latest Godot commit is already present in the results repository."
exit exit
fi fi
done done
popd popd
GODOT_EMPTY_PROJECT_DIR="$DIR/web/godot-empty-project" GODOT_EMPTY_PROJECT_DIR="$DIR/web/godot-empty-project"
if [[ "$ARG1" != "--skip-build" ]]; then if [[ "$ARG1" != "--skip-build" ]]; then
cd "$GODOT_REPO_DIR" cd "$GODOT_REPO_DIR"
if command -v ccache &> /dev/null; then if command -v ccache &> /dev/null; then
# Clear ccache to avoid skewing the build time results. # Clear ccache to avoid skewing the build time results.
ccache --clear ccache --clear
fi fi
touch .gdignore touch .gdignore
# Measure clean build times for debug and release builds (in milliseconds). # Measure clean build times for debug and release builds (in milliseconds).
# Also create a `.gdignore` file to prevent Godot from importing resources # Also create a `.gdignore` file to prevent Godot from importing resources
# within the Godot Git clone. # within the Godot Git clone.
# WARNING: Any untracked and ignored files included in the repository will be removed! # WARNING: Any untracked and ignored files included in the repository will be removed!
BEGIN="$(date +%s%3N)" BEGIN="$(date +%s%3N)"
PEAK_MEMORY_BUILD_DEBUG=$( (/usr/bin/time -f "%M" scons platform=linuxbsd target=editor optimize=debug module_mono_enabled=no progress=no debug_symbols=yes -j$(nproc) 2>&1 || true) | tail -1) PEAK_MEMORY_BUILD_DEBUG=$( (/usr/bin/time -f "%M" scons platform=linuxbsd target=editor optimize=debug module_mono_enabled=no progress=no debug_symbols=yes -j$(nproc) 2>&1 || true) | tail -1)
END="$(date +%s%3N)" END="$(date +%s%3N)"
TIME_TO_BUILD_DEBUG="$((END - BEGIN))" TIME_TO_BUILD_DEBUG="$((END - BEGIN))"
git clean -qdfx --exclude bin git clean -qdfx --exclude bin
if command -v ccache &> /dev/null; then if command -v ccache &> /dev/null; then
# Clear ccache to avoid skewing the build time results. # Clear ccache to avoid skewing the build time results.
ccache --clear ccache --clear
fi fi
touch .gdignore touch .gdignore
BEGIN="$(date +%s%3N)" BEGIN="$(date +%s%3N)"
PEAK_MEMORY_BUILD_RELEASE=$( (/usr/bin/time -f "%M" scons platform=linuxbsd target=template_release optimize=speed lto=full module_mono_enabled=no progress=no debug_symbols=yes -j$(nproc) 2>&1 || true) | tail -1) PEAK_MEMORY_BUILD_RELEASE=$( (/usr/bin/time -f "%M" scons platform=linuxbsd target=template_release optimize=speed lto=full module_mono_enabled=no progress=no debug_symbols=yes -j$(nproc) 2>&1 || true) | tail -1)
END="$(date +%s%3N)" END="$(date +%s%3N)"
TIME_TO_BUILD_RELEASE="$((END - BEGIN))" TIME_TO_BUILD_RELEASE="$((END - BEGIN))"
# FIXME: C# is disabled because the engine crashes on exit after running benchmarks. # FIXME: C# is disabled because the engine crashes on exit after running benchmarks.
# #
# Generate Mono glue for C# build to work. # Generate Mono glue for C# build to work.
# echo "Generating .NET glue." # echo "Generating .NET glue."
# bin/godot.linuxbsd.editor.x86_64.mono --headless --generate-mono-glue modules/mono/glue # bin/godot.linuxbsd.editor.x86_64.mono --headless --generate-mono-glue modules/mono/glue
# echo "Building .NET assemblies." # echo "Building .NET assemblies."
# # https://docs.godotengine.org/en/stable/contributing/development/compiling/compiling_with_dotnet.html#nuget-packages # # https://docs.godotengine.org/en/stable/contributing/development/compiling/compiling_with_dotnet.html#nuget-packages
# mkdir -p "$HOME/MyLocalNugetSource" # mkdir -p "$HOME/MyLocalNugetSource"
# # Source may already exist, so allow failure for the command below. # # Source may already exist, so allow failure for the command below.
# dotnet nuget add source "$HOME/MyLocalNugetSource" --name MyLocalNugetSource || true # dotnet nuget add source "$HOME/MyLocalNugetSource" --name MyLocalNugetSource || true
# modules/mono/build_scripts/build_assemblies.py --godot-output-dir=./bin --push-nupkgs-local "$HOME/MyLocalNugetSource" # modules/mono/build_scripts/build_assemblies.py --godot-output-dir=./bin --push-nupkgs-local "$HOME/MyLocalNugetSource"
cd "$DIR" cd "$DIR"
else else
echo "run-benchmarks: Skipping engine build as requested on the command line." echo "run-benchmarks: Skipping engine build as requested on the command line."
TIME_TO_BUILD_DEBUG=1 TIME_TO_BUILD_DEBUG=1
TIME_TO_BUILD_RELEASE=1 TIME_TO_BUILD_RELEASE=1
PEAK_MEMORY_BUILD_DEBUG=1 PEAK_MEMORY_BUILD_DEBUG=1
PEAK_MEMORY_BUILD_RELEASE=1 PEAK_MEMORY_BUILD_RELEASE=1
fi fi
# Path to the Godot debug binary to run. Used for CPU debug benchmarks. # Path to the Godot debug binary to run. Used for CPU debug benchmarks.
@@ -128,7 +128,7 @@ $GODOT_DEBUG --audio-driver Dummy --gpu-index 1 --path "$GODOT_EMPTY_PROJECT_DIR
TOTAL=0 TOTAL=0
for _ in {0..19}; do for _ in {0..19}; do
BEGIN="$(date +%s%3N)" BEGIN="$(date +%s%3N)"
echo "Performing benchmark debug startup/shutdown run." echo "Performing benchmark debug startup/shutdown run."
$GODOT_DEBUG --audio-driver Dummy --gpu-index 1 --path "$GODOT_EMPTY_PROJECT_DIR" --quit || true $GODOT_DEBUG --audio-driver Dummy --gpu-index 1 --path "$GODOT_EMPTY_PROJECT_DIR" --quit || true
END="$(date +%s%3N)" END="$(date +%s%3N)"
TOTAL="$((TOTAL + END - BEGIN))" TOTAL="$((TOTAL + END - BEGIN))"
@@ -144,7 +144,7 @@ $GODOT_RELEASE --audio-driver Dummy --path "$GODOT_EMPTY_PROJECT_DIR" --quit ||
TOTAL=0 TOTAL=0
for _ in {0..19}; do for _ in {0..19}; do
BEGIN="$(date +%s%3N)" BEGIN="$(date +%s%3N)"
echo "Performing benchmark release startup/shutdown run." echo "Performing benchmark release startup/shutdown run."
$GODOT_RELEASE --audio-driver Dummy --path "$GODOT_EMPTY_PROJECT_DIR" --quit || true $GODOT_RELEASE --audio-driver Dummy --path "$GODOT_EMPTY_PROJECT_DIR" --quit || true
END="$(date +%s%3N)" END="$(date +%s%3N)"
TOTAL="$((TOTAL + END - BEGIN))" TOTAL="$((TOTAL + END - BEGIN))"
@@ -199,24 +199,24 @@ BINARY_SIZE_RELEASE="$(stat --printf="%s" "$GODOT_RELEASE")"
echo "Appending extra JSON at the end of the merged JSON." echo "Appending extra JSON at the end of the merged JSON."
EXTRA_JSON=$(cat << EOF EXTRA_JSON=$(cat << EOF
"binary_size": { "binary_size": {
"debug": $BINARY_SIZE_DEBUG, "debug": $BINARY_SIZE_DEBUG,
"release": $BINARY_SIZE_RELEASE "release": $BINARY_SIZE_RELEASE
}, },
"build_time": { "build_time": {
"debug": $TIME_TO_BUILD_DEBUG, "debug": $TIME_TO_BUILD_DEBUG,
"release": $TIME_TO_BUILD_RELEASE "release": $TIME_TO_BUILD_RELEASE
}, },
"build_peak_memory_usage": { "build_peak_memory_usage": {
"debug": $PEAK_MEMORY_BUILD_DEBUG, "debug": $PEAK_MEMORY_BUILD_DEBUG,
"release": $PEAK_MEMORY_BUILD_RELEASE "release": $PEAK_MEMORY_BUILD_RELEASE
}, },
"empty_project_startup_shutdown_time": { "empty_project_startup_shutdown_time": {
"debug": $TIME_TO_STARTUP_SHUTDOWN_DEBUG, "debug": $TIME_TO_STARTUP_SHUTDOWN_DEBUG,
"release": $TIME_TO_STARTUP_SHUTDOWN_RELEASE "release": $TIME_TO_STARTUP_SHUTDOWN_RELEASE
}, },
"empty_project_startup_shutdown_peak_memory_usage": { "empty_project_startup_shutdown_peak_memory_usage": {
"debug": $PEAK_MEMORY_STARTUP_SHUTDOWN_DEBUG, "debug": $PEAK_MEMORY_STARTUP_SHUTDOWN_DEBUG,
"release": $PEAK_MEMORY_STARTUP_SHUTDOWN_RELEASE "release": $PEAK_MEMORY_STARTUP_SHUTDOWN_RELEASE
} }
EOF EOF
) )

View File

@@ -1,27 +1,27 @@
Section "ServerLayout" Section "ServerLayout"
Identifier "default-layout" Identifier "default-layout"
Screen 0 "screen" Screen 0 "screen"
EndSection EndSection
Section "Device" Section "Device"
Identifier "amd" Identifier "amd"
Driver "amdgpu" Driver "amdgpu"
BusID "PCI:1:0:0" BusID "PCI:1:0:0"
EndSection EndSection
Section "Monitor" Section "Monitor"
Identifier "monitor" Identifier "monitor"
Modeline "1920x1200_60.00" 193.25 1920 2056 2256 2592 1200 1203 1209 1245 -hsync +vsync Modeline "1920x1200_60.00" 193.25 1920 2056 2256 2592 1200 1203 1209 1245 -hsync +vsync
Option "PreferredMode" "1920x1080_60.00" Option "PreferredMode" "1920x1080_60.00"
EndSection EndSection
Section "Screen" Section "Screen"
Identifier "screen" Identifier "screen"
Device "amd" Device "amd"
Monitor "monitor" Monitor "monitor"
DefaultDepth 24 DefaultDepth 24
SubSection "Display" SubSection "Display"
Depth 24 Depth 24
Modes "1920x1080" Modes "1920x1080"
EndSubSection EndSubSection
EndSection EndSection

1
web/.gitattributes vendored
View File

@@ -1 +0,0 @@
static/thirdparty/* linguist-vendored

14
web/.gitignore vendored
View File

@@ -1,14 +0,0 @@
# Output HTML files
public/
# Temporary lock file while building
.hugo_build.lock
# Generated files
content/benchmark/*.md
content/graph/*.md
data/data.json
# Untracked source files
src-data/benchmarks/*.md
src-data/benchmarks/*.json

View File

@@ -1,209 +1,209 @@
function getAllowedMetrics() { function getAllowedMetrics() {
const allowedMetrics = new Set(); const allowedMetrics = new Set();
Database.benchmarks.forEach((benchmark) => { Database.benchmarks.forEach((benchmark) => {
benchmark.benchmarks.forEach((instance) => { benchmark.benchmarks.forEach((instance) => {
Object.entries(instance.results).forEach(([key, value]) => { Object.entries(instance.results).forEach(([key, value]) => {
allowedMetrics.add(key); allowedMetrics.add(key);
}); });
}); });
}); });
return allowedMetrics; return allowedMetrics;
} }
function displayGraph(targetDivID, graphID, type = "full", filter = "") { function displayGraph(targetDivID, graphID, type = "full", filter = "") {
if (!["full", "compact"].includes(type)) { if (!["full", "compact"].includes(type)) {
throw Error("Unknown chart type"); throw Error("Unknown chart type");
} }
// Include benchmark data JSON to generate graphs. // Include benchmark data JSON to generate graphs.
const allBenchmarks = Database.benchmarks.sort( const allBenchmarks = Database.benchmarks.sort(
(a, b) => `${a.date}.${a.commit}` > `${b.date}.${b.commit}`, (a, b) => `${a.date}.${a.commit}` > `${b.date}.${b.commit}`,
); );
const graph = Database.graphs.find((g) => g.id == graphID); const graph = Database.graphs.find((g) => g.id == graphID);
if (!graph) { if (!graph) {
throw new Error("Invalid graph ID"); throw new Error("Invalid graph ID");
} }
// Group by series. // Group by series.
const xAxis = []; const xAxis = [];
const series = new Map(); const series = new Map();
const processResult = (path, data, process) => { const processResult = (path, data, process) => {
Object.entries(data).forEach(([key, value]) => { Object.entries(data).forEach(([key, value]) => {
if (typeof value === "object") { if (typeof value === "object") {
processResult(path + "/" + key, value, process); processResult(path + "/" + key, value, process);
} else { } else {
// Number // Number
process(path + "/" + key, value); process(path + "/" + key, value);
} }
}); });
}; };
// Get list all series and fill it in. // Get list all series and fill it in.
allBenchmarks.forEach((benchmark, count) => { allBenchmarks.forEach((benchmark, count) => {
// Process a day/commit // Process a day/commit
xAxis.push(benchmark.date + "." + benchmark.commit); xAxis.push(benchmark.date + "." + benchmark.commit);
// Get all series. // Get all series.
benchmark.benchmarks.forEach((instance) => { benchmark.benchmarks.forEach((instance) => {
let instanceKey = instance.path.join("/"); let instanceKey = instance.path.join("/");
if (!instanceKey.startsWith(graph["benchmark-path-prefix"])) { if (!instanceKey.startsWith(graph["benchmark-path-prefix"])) {
return; return;
} }
instanceKey = instanceKey.slice( instanceKey = instanceKey.slice(
graph["benchmark-path-prefix"].length + 1, graph["benchmark-path-prefix"].length + 1,
); );
processResult(instanceKey, instance.results, (path, value) => { processResult(instanceKey, instance.results, (path, value) => {
// Filter out paths that do not fit the filter // Filter out paths that do not fit the filter
if (filter && !path.includes(filter)) { if (filter && !path.includes(filter)) {
return; return;
} }
if (!series.has(path)) { if (!series.has(path)) {
series.set(path, Array(count).fill(null)); series.set(path, Array(count).fill(null));
} }
series.get(path).push(value); series.get(path).push(value);
}); });
}); });
}); });
let customColor = undefined; let customColor = undefined;
if (type === "compact") { if (type === "compact") {
// Kind of "normalize" the series, dividing by the average. // Kind of "normalize" the series, dividing by the average.
series.forEach((serie, key) => { series.forEach((serie, key) => {
let count = 0; let count = 0;
let mean = 0.0; let mean = 0.0;
serie.forEach((el) => { serie.forEach((el) => {
if (el != null) { if (el != null) {
mean += el; mean += el;
count += 1; count += 1;
} }
}); });
mean = mean / count; mean = mean / count;
//const std = Math.sqrt(input.map(x => Math.pow(x - mean, 2)).reduce((a, b) => a + b) / n) //const std = Math.sqrt(input.map(x => Math.pow(x - mean, 2)).reduce((a, b) => a + b) / n)
series.set( series.set(
key, key,
serie.map((v) => { serie.map((v) => {
if (v != null) { if (v != null) {
return v / mean; // Devide by the mean. return v / mean; // Devide by the mean.
} }
return null; return null;
}), }),
); );
}); });
// Combine all into a single, averaged serie. // Combine all into a single, averaged serie.
const outputSerie = []; const outputSerie = [];
for (let i = 0; i < allBenchmarks.length; i++) { for (let i = 0; i < allBenchmarks.length; i++) {
let count = 0; let count = 0;
let sum = 0; let sum = 0;
series.forEach((serie, key) => { series.forEach((serie, key) => {
if (serie[i] != null) { if (serie[i] != null) {
count += 1; count += 1;
sum += serie[i]; sum += serie[i];
} }
}); });
let point = null; let point = null;
if (count >= 1) { if (count >= 1) {
point = Math.round((sum * 1000) / count) / 10; // Round to 3 decimals. point = Math.round((sum * 1000) / count) / 10; // Round to 3 decimals.
} }
outputSerie.push(point); outputSerie.push(point);
} }
series.clear(); series.clear();
series.set("Average", outputSerie); series.set("Average", outputSerie);
// Detect whether we went down or not on the last 10 benchmarks. // Detect whether we went down or not on the last 10 benchmarks.
const lastElementsCount = 3; const lastElementsCount = 3;
const totalConsideredCount = 10; const totalConsideredCount = 10;
const lastElements = outputSerie.slice(-lastElementsCount); const lastElements = outputSerie.slice(-lastElementsCount);
const comparedTo = outputSerie.slice( const comparedTo = outputSerie.slice(
-totalConsideredCount, -totalConsideredCount,
-lastElementsCount, -lastElementsCount,
); );
const avgLast = lastElements.reduce((a, b) => a + b) / lastElements.length; const avgLast = lastElements.reduce((a, b) => a + b) / lastElements.length;
const avgComparedTo = const avgComparedTo =
comparedTo.reduce((a, b) => a + b) / comparedTo.length; comparedTo.reduce((a, b) => a + b) / comparedTo.length;
const trend = avgLast - avgComparedTo; const trend = avgLast - avgComparedTo;
if (trend > 10) { if (trend > 10) {
customColor = "#E20000"; customColor = "#E20000";
} else if (trend < -10) { } else if (trend < -10) {
customColor = "#00E200"; customColor = "#00E200";
} }
} }
var options = { var options = {
series: Array.from(series.entries()).map(([key, value]) => ({ series: Array.from(series.entries()).map(([key, value]) => ({
name: key, name: key,
data: value, data: value,
})), })),
chart: { chart: {
foreColor: "var(--text-bright)", foreColor: "var(--text-bright)",
background: "var(--background)", background: "var(--background)",
height: type === "compact" ? 200 : 600, height: type === "compact" ? 200 : 600,
type: "line", type: "line",
zoom: { zoom: {
enabled: false, enabled: false,
}, },
toolbar: { toolbar: {
show: false, show: false,
}, },
animations: { animations: {
enabled: false, enabled: false,
}, },
}, },
tooltip: { tooltip: {
theme: "dark", theme: "dark",
y: { y: {
formatter: (value, opts) => (type === "compact" ? value + "%" : value), formatter: (value, opts) => (type === "compact" ? value + "%" : value),
}, },
}, },
dataLabels: { dataLabels: {
enabled: false, enabled: false,
}, },
stroke: { stroke: {
curve: "straight", curve: "straight",
width: 2, width: 2,
}, },
theme: { theme: {
palette: "palette4", palette: "palette4",
}, },
fill: fill:
type === "compact" type === "compact"
? { ? {
type: "gradient", type: "gradient",
gradient: { gradient: {
shade: "dark", shade: "dark",
gradientToColors: ["#4ecdc4"], gradientToColors: ["#4ecdc4"],
shadeIntensity: 1, shadeIntensity: 1,
type: "horizontal", type: "horizontal",
opacityFrom: 1, opacityFrom: 1,
opacityTo: 1, opacityTo: 1,
stops: [0, 100], stops: [0, 100],
}, },
} }
: {}, : {},
colors: colors:
type === "compact" type === "compact"
? customColor ? customColor
? [customColor] ? [customColor]
: ["#4ecdc4"] : ["#4ecdc4"]
: undefined, : undefined,
xaxis: { xaxis: {
categories: xAxis, categories: xAxis,
labels: { labels: {
show: type !== "compact", show: type !== "compact",
}, },
}, },
yaxis: { yaxis: {
tickAmount: 4, tickAmount: 4,
min: type === "compact" ? 0 : undefined, min: type === "compact" ? 0 : undefined,
max: type === "compact" ? 200 : undefined, max: type === "compact" ? 200 : undefined,
}, },
legend: { legend: {
show: type !== "compact", show: type !== "compact",
}, },
}; };
var chart = new ApexCharts(document.querySelector(targetDivID), options); var chart = new ApexCharts(document.querySelector(targetDivID), options);
chart.render(); chart.render();
} }

View File

@@ -1,39 +1,39 @@
/* See `thirdparty/water.css` for CSS variables that can be used here. */ /* See `thirdparty/water.css` for CSS variables that can be used here. */
p, li { p, li {
line-height: 1.6; line-height: 1.6;
} }
footer { footer {
text-align: center; text-align: center;
} }
header { header {
background-color: var(--background); background-color: var(--background);
border-radius: 0 0 6px 6px; border-radius: 0 0 6px 6px;
padding: .75rem 2rem; padding: .75rem 2rem;
margin-top: -1.25rem; margin-top: -1.25rem;
margin-bottom: 2rem; margin-bottom: 2rem;
} }
.site-title { .site-title {
color: var(--text-bright); color: var(--text-bright);
font-weight: bold; font-weight: bold;
font-size: 1.25rem; font-size: 1.25rem;
border-radius: 6px; border-radius: 6px;
} }
/* Automatically resize the left column to take as little space as required. */ /* Automatically resize the left column to take as little space as required. */
.table-first-column-align-right { .table-first-column-align-right {
width: auto; width: auto;
} }
/* Align first column to the right to improve readability in some situations. */ /* Align first column to the right to improve readability in some situations. */
.table-first-column-align-right tr td:first-of-type { .table-first-column-align-right tr td:first-of-type {
text-align: right; text-align: right;
width: 1%; width: 1%;
white-space: nowrap; white-space: nowrap;
/* Style the first column as headings. */ /* Style the first column as headings. */
font-weight: bold; font-weight: bold;
} }