Chart and graph improvements

-jqPlot has been completely removed and replaced with chart.js on all remaining charts and graphs (richlist pie chart and market candlestick chart)
-chart.js has been updated to v4.4.0
-chartjs-plugin-crosshair has been updated to v2.0.0
-Added 2 new small libraries to enable the chart.js candlestick chart: chartjs-chart-financial v0.1.1 and chartjs-adapter-luxon v1.3.1
This commit is contained in:
Joe Uhren
2023-10-09 19:28:42 -06:00
parent 7349560bfa
commit 74c85a4df3
4 changed files with 148 additions and 100 deletions
+8 -16
View File
@@ -15,8 +15,6 @@ html(lang='en')
link(rel='icon', href='/' + settings.shared_pages.favicons.favicon192, sizes='192x192')
link(rel='stylesheet', href='/css/themes/' + settings.shared_pages.theme.toLowerCase() + '/bootstrap.min.css' + (themeHash == null ? '' : '?h=' + themeHash))
link(rel='stylesheet', href='https://use.fontawesome.com/releases/v5.15.4/css/all.css')
if active == 'markets' || active == 'richlist'
link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/jqPlot/1.0.9/jquery.jqplot.min.css')
if active == 'network'
link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/flag-icon-css/4.1.4/css/flag-icons.min.css')
link(rel='stylesheet', type='text/css', href='https://cdn.datatables.net/v/bs5/dt-1.11.3/datatables.min.css')
@@ -26,14 +24,6 @@ html(lang='en')
script(type='text/javascript', src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js', integrity='sha512-894YE6QWD5I59HgZOGReFYm4dnWc1Qt5NtvYSaNcOP+u1T9qYdvdihz0PPSiiqn/+/3e7Jo4EaG7TubfWGUrMQ==', crossorigin='anonymous', referrerpolicy='no-referrer')
script(type='text/javascript', src='https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js', integrity='sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p', crossorigin='anonymous')
script(type='text/javascript', src='/js/custom.js')
if active == 'markets' || active == 'richlist'
script(type='text/javascript', src='https://cdnjs.cloudflare.com/ajax/libs/jqPlot/1.0.9/jquery.jqplot.min.js')
if active == 'markets'
script(type='text/javascript', src='https://cdnjs.cloudflare.com/ajax/libs/jqPlot/1.0.9/plugins/jqplot.dateAxisRenderer.min.js')
script(type='text/javascript', src='https://cdnjs.cloudflare.com/ajax/libs/jqPlot/1.0.9/plugins/jqplot.ohlcRenderer.min.js')
script(type='text/javascript', src='https://cdnjs.cloudflare.com/ajax/libs/jqPlot/1.0.9/plugins/jqplot.highlighter.min.js')
if active == 'richlist'
script(type='text/javascript', src='https://cdnjs.cloudflare.com/ajax/libs/jqPlot/1.0.9/plugins/jqplot.pieRenderer.min.js')
script(type='text/javascript', src='https://cdn.datatables.net/v/bs5/dt-1.11.3/datatables.min.js')
script(type='text/javascript', src='https://cdnjs.cloudflare.com/ajax/libs/overlayscrollbars/1.13.3/js/jquery.overlayScrollbars.min.js', integrity="sha512-PviP63d43OXLyLjCv3TawK1Rw4LQQsnH6yschHgK63LBvLpd1U1+7LM/OESlV/cSze5lFI3+f7JwKFEBEWNp1w==", crossorigin="anonymous", referrerpolicy="no-referrer")
- var showPanels = false
@@ -138,10 +128,12 @@ html(lang='en')
- showNethashChart = true
if settings.error_page.show_difficulty_chart == true
- showDifficultyChart = true
if active == 'reward' || (settings.network_history.enabled == true && ((showNethashChart == true && settings.shared_pages.page_header.network_charts.nethash_chart.enabled == true && settings.shared_pages.show_hashrate == true) || (showDifficultyChart == true && settings.shared_pages.page_header.network_charts.difficulty_chart.enabled == true)))
script(type='text/javascript', src='https://cdn.jsdelivr.net/npm/chart.js@3.6.1/dist/chart.min.js')
if settings.network_history.enabled == true && ((showNethashChart == true && settings.shared_pages.page_header.network_charts.nethash_chart.enabled == true && settings.shared_pages.show_hashrate == true) || (showDifficultyChart == true && settings.shared_pages.page_header.network_charts.difficulty_chart.enabled == true))
script(type='text/javascript', src='https://cdn.jsdelivr.net/npm/chartjs-plugin-crosshair@1.2.0')
if active == 'markets' || active == 'richlist' || active == 'reward' || (settings.network_history.enabled == true && ((showNethashChart == true && settings.shared_pages.page_header.network_charts.nethash_chart.enabled == true && settings.shared_pages.show_hashrate == true) || (showDifficultyChart == true && settings.shared_pages.page_header.network_charts.difficulty_chart.enabled == true)))
script(type='text/javascript', src='https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.js')
if active == 'markets'
script(type='text/javascript', src='https://cdn.jsdelivr.net/npm/chartjs-chart-financial@0.1.1/dist/chartjs-chart-financial.min.js')
if active == 'markets' || (settings.network_history.enabled == true && ((showNethashChart == true && settings.shared_pages.page_header.network_charts.nethash_chart.enabled == true && settings.shared_pages.show_hashrate == true) || (showDifficultyChart == true && settings.shared_pages.page_header.network_charts.difficulty_chart.enabled == true)))
script(type='text/javascript', src='https://cdn.jsdelivr.net/npm/chartjs-plugin-crosshair@2.0.0')
- var sideBarClasses = [];
if settings.shared_pages.page_header.bgcolor != null && settings.shared_pages.page_header.bgcolor != ''
- sideBarClasses.push('bg-' + settings.shared_pages.page_header.bgcolor);
@@ -440,7 +432,7 @@ html(lang='en')
}
},
scales: {
yAxis: {
y: {
title: {
display: true,
text: 'Network ' + getNetHashUnits(),
@@ -558,7 +550,7 @@ html(lang='en')
}
},
scales: {
yAxis: {
y: {
title: {
display: true,
text: 'Difficulty',
+102 -41
View File
@@ -2,6 +2,7 @@ extends layout
block content
include ./includes/common.pug
script(type='text/javascript', src='https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon@1.3.1')
script.
$(document).ready(function() {
if ('#{settings.markets_page.page_header.show_last_updated}' == 'true') {
@@ -169,55 +170,115 @@ block content
block market_view
script.
$(document).ready(function() {
var jqplot = null;
var chartData = !{(marketdata.data.chartdata == null || marketdata.data.chartdata == 'null' || marketdata.data.chartdata == '' || marketdata.data.chartdata == '[]' ? 'null' : marketdata.data.chartdata)};
if (chartData != null && chartData.length > 0) {
jqplot = $.jqplot('chart', [chartData], {
seriesDefaults: {
yaxis: 'y2axis'
if (chartData != null) {
chartData = chartData.map(function(item) {
return {
x: item[0],
o: item[1],
h: item[2],
l: item[3],
c: item[4]
};
});
const backgroundPlugin = {
id: 'backgroundFill',
beforeDraw(chart) {
const ctx = chart.ctx;
ctx.save();
ctx.fillStyle = '#FFFFFF'; // Change chart background color
const chartArea = chart.chartArea;
ctx.fillRect(chartArea.left, chartArea.top, chartArea.right - chartArea.left, chartArea.bottom - chartArea.top);
ctx.restore();
}
};
Chart.register(backgroundPlugin);
var ohlcvChart = new Chart('chart', {
type: 'candlestick',
data: {
datasets: [{
label: 'Market Data',
data: chartData,
borderColor: {
up: 'rgba(80, 160, 115, 1)',
down: 'rgba(215, 85, 65, 1)',
unchanged: 'rgba(90, 90, 90, 1)'
},
color: {
up: 'rgba(80, 160, 115, 1)',
down: 'rgba(215, 85, 65, 1)',
unchanged: 'rgba(90, 90, 90, 1)'
}
}]
},
axes: {
xaxis: {
renderer: $.jqplot.DateAxisRenderer,
tickOptions: { formatString: '%R' },
tickInterval: '2 hours'
options: {
maintainAspectRatio: true,
aspectRatio: 3,
scales: {
x: {
type: 'time',
offset: true,
ticks: {
padding: 10
}
},
y: {
position: 'right',
grace: '10%',
ticks: {
callback: function(value, index, values) {
return parseFloat(value).toFixed(8);
}
}
}
},
y2axis: {
tickOptions: { formatString: '%.8f' },
}
},
series: [
{
renderer: $.jqplot.OHLCRenderer,
rendererOptions: {
candleStick: true,
upBodyColor: '#2aa3a3',
downBodyColor: '#e2595b',
fillUpBody: true,
fillDownBody: true
plugins: {
legend: {
display: false
},
tooltip: {
mode: 'nearest',
callbacks: {
title: function(context) {
return format_unixtime(context[0].raw.x / 1000);
},
beforeBody: function(context) {
const dataset = context[0].dataset;
const data = dataset.data[context[0].dataIndex];
return [
'Open: ' + data.o.toFixed(8),
'High: ' + data.h.toFixed(8),
'Low: ' + data.l.toFixed(8),
'Close: ' + data.c.toFixed(8)
];
},
label: function(context) {
// Suppress the default body content
return null;
}
}
},
crosshair: {
line: {
color: '#000000',
width: 1
},
sync: {
enabled: false
},
zoom: {
enabled: false
}
}
}
],
highlighter: {
show: true,
showMarker: false,
tooltipAxes: 'xy',
yvalues: 4,
formatString: '<table class="jqplot-highlighter"> \
<tr><td>time:</td><td>%s</td></tr> \
<tr><td>open:</td><td>%s</td></tr> \
<tr><td>hi:</td><td>%s</td></tr> \
<tr><td>low:</td><td>%s</td></tr> \
<tr><td>close:</td><td>%s</td></tr></table>'
}
});
$('#chart').css('width', '100%');
}
$(window).resize(function () {
if (jqplot != null && $('#chart').is(':visible'))
jqplot.replot({ resetAxes: false });
});
});
.row
.col-md-12.cardSpacer
@@ -351,7 +412,7 @@ block content
img.align-top.market-logo(src='data:image/png;base64,' + marketdata.market_logo, title=marketdata.market_name + ' Logo', alt=marketdata.market_name + ' Logo')
strong #{marketdata.market_name} - #{marketdata.coin}/#{marketdata.exchange} - #{settings.locale.mkt_hours}
.card-body
div#chart(style='height:300px;')
canvas#chart(style='height:300px;')
.row
.col-md-6.col-xs-12.cardSpacer
.card.card-default.border-0.wrapper-border-0(class=theadClasses)
+34 -40
View File
@@ -6,39 +6,42 @@ block content
if settings.richlist_page.wealth_distribution.show_distribution_chart == true
script.
$(document).ready(function() {
var data = [
['Top 1-25', !{dista.percent}],
['Top 26-50', !{distb.percent}],
['Top 51-75', !{distc.percent}],
['Top 76-100', !{distd.percent}],
['101+', !{diste.percent}]
];
var xValues = ['Top 1-25', 'Top 26-50', 'Top 51-75', 'Top 76-100', '101+'];
var yValues = [!{dista.total}, !{distb.total}, !{distc.total}, !{distd.total}, !{diste.total}];
var percentages = [!{dista.percent}, !{distb.percent}, !{distc.percent}, !{distd.percent}, !{diste.percent}];
var burned = '!{burned}';
if ('#{settings.richlist_page.burned_coins.include_burned_coins_in_distribution}' == 'true' && burned != 'null' && burned != '' && burned != '0')
data.push(['Burned Coins', parseFloat(((burned / 100000000) / !{stats.supply}) * 100)]);
var piePlot = $.jqplot('pieChart', [data],
{
seriesColors: !{JSON.stringify(settings.richlist_page.wealth_distribution.colors)},
series: [{
renderer: $.jqplot.PieRenderer,
rendererOptions: {
diameter: 260,
padding: 0,
sliceMargin: 4,
showDataLabels: false
}
}],
grid: {borderWidth:0, shadow:false},
legend: {
show: false,
rendererOptions: {
numberRows: 1,
border: 'none'
if ('#{settings.richlist_page.burned_coins.include_burned_coins_in_distribution}' == 'true' && burned != 'null' && burned != '' && burned != '0') {
xValues.push('Burned Coins');
yValues.push(burned / 100000000);
percentages.push(Number(parseFloat(((burned / 100000000) / !{stats.supply}) * 100).toFixed(2)));
}
new Chart("pieChart", {
type: "pie",
data: {
labels: xValues,
datasets: [{
backgroundColor: !{JSON.stringify(settings.richlist_page.wealth_distribution.colors)},
data: yValues
}]
},
options: {
responsive: true,
plugins: {
legend: {
display: false
},
location: 's'
tooltip: {
callbacks: {
label: function(context) {
return `${context.label}: ${Number((context.parsed || 0)).toLocaleString('en',{'minimumFractionDigits':0,'maximumFractionDigits':20,'useGrouping':true})} (${percentages[xValues.indexOf(context.label)]}%)`;
}
}
}
}
}
);
}
});
if ('#{settings.richlist_page.page_header.show_last_updated}' == 'true') {
var lastUpdatedDate = #{(last_updated == null || last_updated == '0' ? 0 : last_updated)};
@@ -55,15 +58,6 @@ block content
}
if (#{settings.shared_pages.page_header.page_title_image.enable_animation} == true && #{settings.richlist_page.page_header.show_img} == true)
startRotateElement('img#header-img');
$(window).resize(function () {
if (piePlot != null && $('#pieChart').is(':visible')) {
let parentWidth = $('#pieChart').parent().outerWidth();
$('#pieChart').css('height', (parentWidth <= 300 ? parentWidth + 5 : 305).toString() + 'px');
$('#pieChart').css('width', (parentWidth <= 300 ? parentWidth : 300).toString() + 'px');
piePlot.replot({ resetAxes: false });
}
});
});
- var theadClasses = [];
if settings.shared_pages.table_header_bgcolor != null && settings.shared_pages.table_header_bgcolor != ''
@@ -279,4 +273,4 @@ block content
td.fw-bold.text-center #{percentParts[0]}.
span.decimal #{percentParts[1]}
if settings.richlist_page.wealth_distribution.show_distribution_chart == true
div#pieChart(style="max-width:300px;max-height:305px;margin:0 auto;")
canvas#pieChart(style="margin-top:10px;max-height:305px;")