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
+4 -3
View File
@@ -76,9 +76,10 @@ Table of Contents
- DataTables v1.11.3 - DataTables v1.11.3
- FontAwesome v5.15.4 - FontAwesome v5.15.4
- Luxon v2.1.1 - Luxon v2.1.1
- jqPlot v1.0.9 - Chart.js v4.4.0
- Chart.js v3.6.1 - chartjs-plugin-crosshair v2.0.0 ([https://github.com/abelheinsbroek/chartjs-plugin-crosshair](https://github.com/abelheinsbroek/chartjs-plugin-crosshair))
- chartjs-plugin-crosshair v1.2.0 ([https://github.com/abelheinsbroek/chartjs-plugin-crosshair](https://github.com/abelheinsbroek/chartjs-plugin-crosshair)) - chartjs-chart-financial v0.1.1 ([https://github.com/chartjs/chartjs-chart-financial](https://github.com/chartjs/chartjs-chart-financial))
- chartjs-adapter-luxon v1.3.1 ([https://github.com/chartjs/chartjs-adapter-luxon](https://github.com/chartjs/chartjs-adapter-luxon))
- OverlayScrollbars v1.13.3 - OverlayScrollbars v1.13.3
- flag-icon-css v4.1.4 ([https://github.com/lipis/flag-icon-css](https://github.com/lipis/flag-icon-css)) - flag-icon-css v4.1.4 ([https://github.com/lipis/flag-icon-css](https://github.com/lipis/flag-icon-css))
- Intl.js (uses the v3.111.0 polyfill service to only download if using a browser that doesn't already support the ECMAScript Internationalization API) - Intl.js (uses the v3.111.0 polyfill service to only download if using a browser that doesn't already support the ECMAScript Internationalization API)
+8 -16
View File
@@ -15,8 +15,6 @@ html(lang='en')
link(rel='icon', href='/' + settings.shared_pages.favicons.favicon192, sizes='192x192') 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='/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') 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' 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', 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') 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://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='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') 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://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") 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 - var showPanels = false
@@ -138,10 +128,12 @@ html(lang='en')
- showNethashChart = true - showNethashChart = true
if settings.error_page.show_difficulty_chart == true if settings.error_page.show_difficulty_chart == true
- showDifficultyChart = 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))) 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@3.6.1/dist/chart.min.js') script(type='text/javascript', src='https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.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)) if active == 'markets'
script(type='text/javascript', src='https://cdn.jsdelivr.net/npm/chartjs-plugin-crosshair@1.2.0') 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 = []; - var sideBarClasses = [];
if settings.shared_pages.page_header.bgcolor != null && settings.shared_pages.page_header.bgcolor != '' if settings.shared_pages.page_header.bgcolor != null && settings.shared_pages.page_header.bgcolor != ''
- sideBarClasses.push('bg-' + settings.shared_pages.page_header.bgcolor); - sideBarClasses.push('bg-' + settings.shared_pages.page_header.bgcolor);
@@ -440,7 +432,7 @@ html(lang='en')
} }
}, },
scales: { scales: {
yAxis: { y: {
title: { title: {
display: true, display: true,
text: 'Network ' + getNetHashUnits(), text: 'Network ' + getNetHashUnits(),
@@ -558,7 +550,7 @@ html(lang='en')
} }
}, },
scales: { scales: {
yAxis: { y: {
title: { title: {
display: true, display: true,
text: 'Difficulty', text: 'Difficulty',
+102 -41
View File
@@ -2,6 +2,7 @@ extends layout
block content block content
include ./includes/common.pug include ./includes/common.pug
script(type='text/javascript', src='https://cdn.jsdelivr.net/npm/chartjs-adapter-luxon@1.3.1')
script. script.
$(document).ready(function() { $(document).ready(function() {
if ('#{settings.markets_page.page_header.show_last_updated}' == 'true') { if ('#{settings.markets_page.page_header.show_last_updated}' == 'true') {
@@ -169,55 +170,115 @@ block content
block market_view block market_view
script. script.
$(document).ready(function() { $(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)}; 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) { if (chartData != null) {
jqplot = $.jqplot('chart', [chartData], { chartData = chartData.map(function(item) {
seriesDefaults: { return {
yaxis: 'y2axis' 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: { options: {
xaxis: { maintainAspectRatio: true,
renderer: $.jqplot.DateAxisRenderer, aspectRatio: 3,
tickOptions: { formatString: '%R' }, scales: {
tickInterval: '2 hours' 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: { plugins: {
tickOptions: { formatString: '%.8f' }, legend: {
} display: false
}, },
series: [ tooltip: {
{ mode: 'nearest',
renderer: $.jqplot.OHLCRenderer, callbacks: {
rendererOptions: { title: function(context) {
candleStick: true, return format_unixtime(context[0].raw.x / 1000);
upBodyColor: '#2aa3a3', },
downBodyColor: '#e2595b', beforeBody: function(context) {
fillUpBody: true, const dataset = context[0].dataset;
fillDownBody: true 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 .row
.col-md-12.cardSpacer .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') 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} strong #{marketdata.market_name} - #{marketdata.coin}/#{marketdata.exchange} - #{settings.locale.mkt_hours}
.card-body .card-body
div#chart(style='height:300px;') canvas#chart(style='height:300px;')
.row .row
.col-md-6.col-xs-12.cardSpacer .col-md-6.col-xs-12.cardSpacer
.card.card-default.border-0.wrapper-border-0(class=theadClasses) .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 if settings.richlist_page.wealth_distribution.show_distribution_chart == true
script. script.
$(document).ready(function() { $(document).ready(function() {
var data = [ var xValues = ['Top 1-25', 'Top 26-50', 'Top 51-75', 'Top 76-100', '101+'];
['Top 1-25', !{dista.percent}], var yValues = [!{dista.total}, !{distb.total}, !{distc.total}, !{distd.total}, !{diste.total}];
['Top 26-50', !{distb.percent}], var percentages = [!{dista.percent}, !{distb.percent}, !{distc.percent}, !{distd.percent}, !{diste.percent}];
['Top 51-75', !{distc.percent}],
['Top 76-100', !{distd.percent}],
['101+', !{diste.percent}]
];
var burned = '!{burned}'; 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)]); if ('#{settings.richlist_page.burned_coins.include_burned_coins_in_distribution}' == 'true' && burned != 'null' && burned != '' && burned != '0') {
var piePlot = $.jqplot('pieChart', [data], xValues.push('Burned Coins');
{ yValues.push(burned / 100000000);
seriesColors: !{JSON.stringify(settings.richlist_page.wealth_distribution.colors)}, percentages.push(Number(parseFloat(((burned / 100000000) / !{stats.supply}) * 100).toFixed(2)));
series: [{ }
renderer: $.jqplot.PieRenderer,
rendererOptions: { new Chart("pieChart", {
diameter: 260, type: "pie",
padding: 0, data: {
sliceMargin: 4, labels: xValues,
showDataLabels: false datasets: [{
} backgroundColor: !{JSON.stringify(settings.richlist_page.wealth_distribution.colors)},
}], data: yValues
grid: {borderWidth:0, shadow:false}, }]
legend: { },
show: false, options: {
rendererOptions: { responsive: true,
numberRows: 1, plugins: {
border: 'none' 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') { if ('#{settings.richlist_page.page_header.show_last_updated}' == 'true') {
var lastUpdatedDate = #{(last_updated == null || last_updated == '0' ? 0 : last_updated)}; 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) if (#{settings.shared_pages.page_header.page_title_image.enable_animation} == true && #{settings.richlist_page.page_header.show_img} == true)
startRotateElement('img#header-img'); 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 = []; - var theadClasses = [];
if settings.shared_pages.table_header_bgcolor != null && settings.shared_pages.table_header_bgcolor != '' 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]}. td.fw-bold.text-center #{percentParts[0]}.
span.decimal #{percentParts[1]} span.decimal #{percentParts[1]}
if settings.richlist_page.wealth_distribution.show_distribution_chart == true 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;")