Se actualizan librerias de RGraph y cambios menores

This commit is contained in:
Exequiel Aramburu 2026-09-27 23:33:38 -03:00
parent 99264aba3d
commit 5221b6fb19
11 changed files with 3751 additions and 3300 deletions

View File

@ -1,4 +1,5 @@
** Mejoras de interfaz y configuración (Septiembre 27, 2026) ** Mejoras de interfaz y configuración (Septiembre 27, 2026)
+ Se actualizó RGraph 7.01 → 7.21
+ NW.js 0.117.0 centralizado en runtime.json para desarrollo y empaquetado x64. + NW.js 0.117.0 centralizado en runtime.json para desarrollo y empaquetado x64.
+ Formulario compartido con controles nativos, validación y aviso de cambios sin guardar. + Formulario compartido con controles nativos, validación y aviso de cambios sin guardar.
+ Guardado atómico y POST con confirmación; el núcleo recibe la configuración nueva. + Guardado atómico y POST con confirmación; el núcleo recibe la configuración nueva.

View File

@ -84,7 +84,6 @@
</span> </span>
</nav> </nav>
<section id="estado-estacion" class="estado-estacion" aria-label="Estado de la estación"></section> <section id="estado-estacion" class="estado-estacion" aria-label="Estado de la estación"></section>
<br><br>
<div id="superior" class="container"> <div id="superior" class="container">
<div class="row"> <div class="row">
<div class="col-2 text-center vertical-align-top"> <div class="col-2 text-center vertical-align-top">

View File

@ -96,7 +96,7 @@
} }
.container { .container {
max-width: 1800px !important; max-width: 100% !important;
} }
h1 { h1 {
@ -499,7 +499,6 @@ hr.style18:before {
z-index: 1031; z-index: 1031;
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100%;
height: 2px; height: 2px;
} }

View File

@ -1,15 +1,16 @@
'version:2025-10-08 (7.01)'; 'version:2026-08-11 (7.21)';
// //
// o---------------------------------------------------------------------------------o // o---------------------------------------------------------------------------o
// | This file is part of the RGraph package - you can learn more at: | // | This file is part of the RGraph package - you can learn more at: |
// | | // | |
// | https://www.rgraph.net/license.html | // | https://www.rgraph.net |
// | | // | |
// | RGraph is dual-licensed under the Open Source GPL license. That means that it's | // | RGraph is dual-licensed under the Open Source GPL license. This means |
// | free to use and there are no restrictions on what you can use RGraph for! | // | that it's free to use for any purpose. The GPL license does have |
// | If the GPL license does not suit you however, then there's an inexpensive | // | consequences on the license of the software that you include it in, |
// | commercial license option available. See the URL above for more details. | // | however. If this is not desirable, then there's an inexpensive commercial |
// o---------------------------------------------------------------------------------o // | license option available. See the RGraph website for more details. |
// o---------------------------------------------------------------------------o
RGraph = window.RGraph || {isrgraph:true,isRGraph: true,rgraph:true}; RGraph = window.RGraph || {isrgraph:true,isRGraph: true,rgraph:true};
@ -47,16 +48,16 @@
this.properties = this.properties =
{ {
backgroundBarsCount: null, backgroundBarsCount: null,
backgroundBarsColor1: 'rgba(0,0,0,0)', backgroundBarsColor1: 'transparent',
backgroundBarsColor2: 'rgba(0,0,0,0)', backgroundBarsColor2: 'transparent',
backgroundGrid: true, backgroundGrid: true,
backgroundGridColor: '#ddd', backgroundGridColor: '#eee',
backgroundGridLinewidth: 1, backgroundGridLinewidth: 1,
backgroundGridHsize: 20, backgroundGridHsize: 20,
backgroundGridVsize: 20, backgroundGridVsize: 20,
backgroundGridVlines: true, backgroundGridVlines: false,
backgroundGridHlines: true, backgroundGridHlines: true,
backgroundGridBorder: true, backgroundGridBorder: false,
backgroundGridAutofit: true, backgroundGridAutofit: true,
backgroundGridAutofitAlign: true, backgroundGridAutofitAlign: true,
backgroundGridHlinesCount: 5, backgroundGridHlinesCount: 5,
@ -115,7 +116,7 @@
labelsAboveUnitsPost:'', labelsAboveUnitsPost:'',
labelsAboveFormatter:null, labelsAboveFormatter:null,
yaxis: true, yaxis: false,
yaxisLinewidth: 1, yaxisLinewidth: 1,
yaxisColor: 'black', yaxisColor: 'black',
yaxisTickmarks: true, yaxisTickmarks: true,
@ -162,7 +163,8 @@
yaxisTitleValign: null, yaxisTitleValign: null,
yaxisTitleAccessible: null, yaxisTitleAccessible: null,
xaxis: true, xaxis: false,
xaxisPosition: 'bottom',
xaxisLinewidth: 1, xaxisLinewidth: 1,
xaxisColor: 'black', xaxisColor: 'black',
xaxisTickmarks: true, xaxisTickmarks: true,
@ -235,22 +237,28 @@
titleSubtitleOffsetx: 0, titleSubtitleOffsetx: 0,
titleSubtitleOffsety: 0, titleSubtitleOffsety: 0,
colorsStroke: 'rgba(0,0,0,0)', colorsStroke: 'transparent',
colors: ['red','#0f0','blue','pink','orange','cyan','black','white','green','magenta'], colors: RGraph.getColors(),
colorsSequential: false, colorsSequential: false,
colorsReverse: false, colorsReverse: false,
grouping: 'grouped', grouping: 'grouped',
variant: 'bar', variant: 'bar',
variantSketchVerticals: true, variantSketchVerticals: true,
variantThreedXaxis: true, variantThreedXaxis: true,
variantThreedYaxis: true, variantThreedYaxis: true,
variantThreedAngle: 0.1, variantThreedAngle: 0.1,
variantThreedOffsetx: 10, variantThreedOffsetx: 10,
variantThreedOffsety: 5, variantThreedOffsety: 5,
variantThreedXaxisColor: '#ddd', variantThreedXaxisColor: '#ddd',
variantThreedYaxisColor: '#ddd', variantThreedYaxisColor: '#ddd',
variantDumbbellLinewidth: 8,
variantDumbbellEndTop: true,
variantDumbbellEndBottom: true,
variantDumbbellEndRadius: 13,
variantDumbbellEndTopRadius: null,
variantDumbbellEndBottomRadius: null,
shadow: false, shadow: false,
shadowColor: '#aaa', shadowColor: '#aaa',
@ -284,8 +292,9 @@
tooltipsPointerOffsety: 0, tooltipsPointerOffsety: 0,
tooltipsPositionStatic: true, tooltipsPositionStatic: true,
highlightStroke: 'rgba(0,0,0,0)', highlightStroke: 'transparent',
highlightFill: 'rgba(255,255,255,0.7)', highlightFill: 'rgba(255,255,255,0.7)',
highlightFade: true,
key: null, key: null,
keyBackground: 'white', keyBackground: 'white',
@ -345,17 +354,17 @@
beveled: false, beveled: false,
errorbars: false, errorbars: false,
errorbarsColor: 'black', errorbarsColor: 'black',
errorbarsCapped: true, errorbarsCapped: true,
errorbarsCappedWidth: 14, errorbarsCappedWidth: 14,
errorbarsLinewidth: 1, errorbarsLinewidth: 1,
combinedEffect: null, combinedEffect: null,
combinedEffectOptions: null, combinedEffectOptions: null,
combinedEffectCallback: null, combinedEffectCallback: null,
corners: 'square', corners: 'round',
cornersRoundRadius: 10, cornersRoundRadius: 5,
cornersRoundLeft: true, cornersRoundLeft: true,
cornersRoundRight: true, cornersRoundRight: true,
cornersRoundLeftRadius: null, cornersRoundLeftRadius: null,
@ -363,13 +372,18 @@
responsive: null, responsive: null,
clearto: 'rgba(0,0,0,0)', clearto: 'transparent',
style: null,
events: {}, events: {},
clip: null,
scale: true, scale: true,
scaleFactor: 2, scaleFactor: 2,
antialiasTranslate: false antialiasTranslate: false,
style: []
}; };
@ -434,6 +448,10 @@
'titleSubtitleOffsety', 'titleSubtitleOffsety',
'variantThreedOffsetx', 'variantThreedOffsetx',
'variantThreedOffsety', 'variantThreedOffsety',
'variantDumbbellLinewidth',
'variantDumbbellEndRadius',
'variantDumbbellEndTopRadius',
'variantDumbbellEndBottomRadius',
'shadowOffsetx', 'shadowOffsetx',
'shadowOffsety', 'shadowOffsety',
'shadowBlur', 'shadowBlur',
@ -674,7 +692,15 @@
//
// Add any CSS that has been specified to the document.
// This is general CSS and does not necessarily have to
// pertain to the canvas tag. It only gets added once
// to the document no matter how many times this draw
// function is called.
//
// Add the CSS to a <style> block in the <head>.
RGraph.addConfigurationBasedCSS(this);
@ -693,8 +719,40 @@
} }
// MUST be the THIRD thing done! // MUST be the THIRD thing done!
if (typeof properties.backgroundImage === 'string') { if (typeof properties.backgroundImage === 'string' && properties.backgroundImage) {
//
// Install clipping for the background image. This
// is not the main installation of clipping - it's
// just for the background image.
//
// The this.scale2 check means that clipping is only
// installed if that variable is present - ie this
// is most likely a redraw and the necessary things
// have been calculated so clipping can be
// installed correctly.
//
if (!RGraph.isNullish(this.properties.clip) && this.scale2) {
RGraph.clipTo.start(this, this.properties.clip);
}
RGraph.drawBackgroundImage(this); RGraph.drawBackgroundImage(this);
if (!RGraph.isNullish(this.properties.clip) && this.scale2) {
RGraph.clipTo.end();
}
}
// If 3D is enabled then turn off rounded corners
// because it doesn't look correct.
if (this.properties.variant === '3d' && this.properties.corners === 'round') {
this.properties.corners = 'square'
} }
@ -797,10 +855,24 @@
// If a dumbbell chart is being drawn then a few
// properties need to be massaged
if (!this.properties.colorsDumbbell && this.properties.variant === 'dumbbell') {
this.set({
colorsDumbbell: this.get('colors')
});
this.set({
colors: ['#0000']
});
};
// //
// Work out the max value // Work out the max value
// //
if (properties.yaxisScaleMax) { if (this.properties.yaxisScaleMax) {
this.scale2 = RGraph.getScale({object: this, options: { this.scale2 = RGraph.getScale({object: this, options: {
'scale.max': properties.yaxisScaleMax, 'scale.max': properties.yaxisScaleMax,
@ -878,6 +950,12 @@
this.scale2 = RGraph.getScale({object: this, options: { this.scale2 = RGraph.getScale({object: this, options: {
'scale.max': this.max, 'scale.max': this.max,
'scale.min': properties.yaxisScaleMin, 'scale.min': properties.yaxisScaleMin,
@ -928,9 +1006,19 @@
// this.drawAxes(); // this.drawAxes();
// this.drawbars(); // this.drawbars();
//} else { //} else {
this.drawbars(); this.drawbars();
this.drawAxes(); this.drawAxes();
//} //}
//
// Draw the dumbbell bars variant Draw this here
// so that the dumbells are drawn over the axes.
//
if (this.properties.variant === 'dumbbell') {
this.drawdumbbell();
}
this.drawLabels(); this.drawLabels();
@ -1092,11 +1180,11 @@
// //
if (properties.xaxisLabels && properties.xaxisLabels.length) { if (properties.xaxisLabels && properties.xaxisLabels.length) {
if (typeof properties.xaxisLabels === 'string') { if (typeof properties.xaxisLabels === 'string') {
properties.xaxisLabels = RGraph.arrayPad({ properties.xaxisLabels = RGraph.arrayPad(
array: [], [],
length: this.data.length, this.data.length,
value: properties.xaxisLabels properties.xaxisLabels
}); );
} }
// Label substitution // Label substitution
@ -1164,7 +1252,7 @@
RGraph.drawBars(this); RGraph.drawBars(this);
} }
var variant = properties.variant; var variant = this.properties.variant;
// //
// Draw the 3D axes is necessary // Draw the 3D axes is necessary
@ -1300,7 +1388,7 @@
this.context.fillStyle = colors[i]; this.context.fillStyle = colors[i];
} }
if (variant == 'sketch') { if (variant === 'sketch') {
this.context.lineCap = 'round'; this.context.lineCap = 'round';
@ -1360,21 +1448,21 @@
this.context.stroke(); this.context.stroke();
// Regular bar // Regular bar
} else if (variant == 'bar' || variant == '3d' || variant == 'glass' || variant == 'bevel') { } else if (variant === 'bar' || variant === '3d' || variant === 'glass' || variant === 'bevel' || variant === 'dumbbell') {
if (variant == 'glass') { if (variant == 'glass') {
RGraph.roundedRect({ RGraph.roundedRect(
context: this.context, this.context,
x: x + hmargin, x + hmargin,
y: y, y,
width: barWidth, barWidth,
height: height, height,
radius: RGraph.isNumber(properties.cornersRoundRadius) ? properties.cornersRoundRadius : 5, RGraph.isNumber(properties.cornersRoundRadius) ? properties.cornersRoundRadius : 5,
roundtl: this.data[i] > 0, this.data[i] > 0,
roundtr: this.data[i] > 0, this.data[i] > 0,
roundbl: this.data[i] < 0, this.data[i] < 0,
roundbr: this.data[i] < 0 this.data[i] < 0
}); );
this.context.stroke(); this.context.stroke();
this.context.fill(); this.context.fill();
} else { } else {
@ -1546,7 +1634,7 @@ this.context.lineTo(
// Dot chart // Dot chart
} else if (variant == 'dot') { } else if (variant === 'dot') {
var scaleFactor = RGraph.getScaleFactor(this); var scaleFactor = RGraph.getScaleFactor(this);
@ -2439,66 +2527,101 @@ this.context.lineTo(
// //
// Each object type has its own Highlight() function which highlights the appropriate shape // Each object type has its own Highlight() function which
// highlights the appropriate shape.
// //
// @param object shape The shape to highlight // @param object shape The shape to highlight.
// //
this.highlight = function (shape) this.highlight = function (shape)
{ {
if (typeof properties.highlightStyle === 'function') { // If the highlightFade property is not set then call
(properties.highlightStyle)(shape); // the highlight function multiple times when the
// globalAlpha is set at varying levels of transparency
// to fade the highlight in. If the variable is set,
// however, then this call is probably a part of said
// highlighting process so don't call ourselves
// again - just highlight the chart.
if (this.properties.highlightFade && !this.highlight.highlighting) {
// Highlight all of the rects except this one - essentially // Add a variable to the highlight function (this
// an inverted highlight // function) to indicate that we're currently in
} else if (typeof properties.highlightStyle === 'string' && properties.highlightStyle === 'invert') { // the process of highlighting.
for (var i=0; i<this.coords.length; ++i) { this.highlight.highlighting = true;
if (i !== shape.sequentialIndex) {
this.path(
'b r % % % % s % f %',
this.coords[i][0],this.coords[i][1],this.coords[i][2],this.coords[i][3],
properties.highlightStroke,
properties.highlightFill
);
}
}
// Redraw the X axis so the highlight doesn't var obj = this;
// appear over the X axis. But not the X axis setTimeout(function() {obj.context.globalAlpha = 0.2; obj.highlight(shape); obj.context.globalAlpha = 1;}, 20);
// labels or the title. This is new in setTimeout(function() {obj.context.globalAlpha = 0.2; obj.highlight(shape); obj.context.globalAlpha = 1;}, 40);
// September 2024. setTimeout(function() {obj.context.globalAlpha = 0.2; obj.highlight(shape); obj.context.globalAlpha = 1;}, 60);
RGraph.drawXAxis(this, { setTimeout(function() {obj.context.globalAlpha = 0.2; obj.highlight(shape); obj.context.globalAlpha = 1;}, 80);
labels: false, setTimeout(function() {obj.context.globalAlpha = 0.2; obj.highlight(shape); obj.context.globalAlpha = 1;}, 100);
title: false setTimeout(function() {obj.context.globalAlpha = 0.2; obj.highlight(shape); obj.context.globalAlpha = 1;}, 120);
}); setTimeout(function() {obj.context.globalAlpha = 0.2; obj.highlight(shape); obj.context.globalAlpha = 1;}, 140);
} else { setTimeout(function() {obj.highlight.highlighting = false;}, 400);
if (properties.grouping === 'stacked' && shape.index === 0 && properties.xaxisPosition === 'bottom') {
return;
this.context.beginPath(); }
this.context.strokeStyle = properties.highlightStroke;
this.context.fillStyle = properties.highlightFill;
if (properties.corners === 'round') {
this.roundedCornersRect(shape.x,shape.y,shape.width,shape.height);
} else {
this.context.rect(shape.x, shape.y, shape.width, shape.height);
}
this.context.stroke(); RGraph.clipTo.callback(this, function (obj)
this.context.fill(); {
} else { if (typeof obj.properties.highlightStyle === 'function') {
// Add the new highlight (obj.properties.highlightStyle)(shape);
RGraph.Highlight.rect(this, shape);
// Highlight all of the rects except this one - essentially
// an inverted highlight
} else if (typeof obj.properties.highlightStyle === 'string' && obj.properties.highlightStyle === 'invert') {
for (var i=0; i<obj.coords.length; ++i) {
if (i !== shape.sequentialIndex) {
obj.path(
'b r % % % % s % f %',
obj.coords[i][0],obj.coords[i][1],obj.coords[i][2],obj.coords[i][3],
obj.properties.highlightStroke,
obj.properties.highlightFill
);
}
}
// Redraw the X axis so the highlight doesn't // Redraw the X axis so the highlight doesn't
// appear over the X axis. But not the X axis // appear over the X axis. But not the X axis
// labels or the title. This is new in // labels or the title. This is new in
// September 2024. // September 2024.
RGraph.drawXAxis(this, { if (obj.properties.variant !== 'dumbbell') {
labels: false, RGraph.drawXAxis(obj, {
title: false labels: false,
}); title: false
});
}
} else {
if (properties.grouping === 'stacked' && shape.index === 0 && obj.properties.xaxisPosition === 'bottom') {
obj.context.beginPath();
obj.context.strokeStyle = obj.properties.highlightStroke;
obj.context.fillStyle = obj.properties.highlightFill;
if (obj.properties.corners === 'round') {
obj.roundedCornersRect(shape.x,shape.y,shape.width,shape.height);
} else {
obj.context.rect(shape.x, shape.y, shape.width, shape.height);
}
obj.context.stroke();
obj.context.fill();
} else {
// Add the new highlight
RGraph.Highlight.rect(obj, shape);
// Redraw the X axis so the highlight doesn't
// appear over the X axis. But not the X axis
// labels or the title. This is new in
// September 2024.
if (obj.properties.variant !== 'dumbbell') {
RGraph.drawXAxis(obj, {
labels: false,
title: false
});
}
}
} }
} }); // End of clipping callback function.
}; };
@ -2523,13 +2646,19 @@ this.context.lineTo(
mouseXY[1] -= adjustment; mouseXY[1] -= adjustment;
} }
var dbEndTopradius = 0;
var dbEndBottomradius = 0;
if (this.properties.variant === 'dumbbell') {
dbEndTopradius = this.properties.variantDumbbellEndTopRadius || this.properties.variantDumbbellEndRadius;
dbEndBottomradius = this.properties.variantDumbbellEndBottomRadius || this.properties.variantDumbbellEndRadius;
}
if ( if (
mouseXY[0] >= properties.marginLeft mouseXY[0] >= this.properties.marginLeft
&& mouseXY[0] <= (this.canvas.width - properties.marginRight) && mouseXY[0] <= (this.canvas.width - this.properties.marginRight)
&& mouseXY[1] >= properties.marginTop && mouseXY[1] >= this.properties.marginTop - dbEndTopradius
&& mouseXY[1] <= (this.canvas.height - properties.marginBottom) && mouseXY[1] <= (this.canvas.height - this.properties.marginBottom + dbEndBottomradius)
) { ) {
return this; return this;
@ -2679,7 +2808,10 @@ this.context.lineTo(
// Allow for JSON gradients // Allow for JSON gradients
if (color.match(/^gradient\(({.*})\)$/i)) { if (color.match(/^gradient\(({.*})\)$/i)) {
return RGraph.parseJSONGradient({object: this, def: RegExp.$1}); return RGraph.parseJSONGradient({
object: this,
def: RegExp.$1
});
} }
@ -3409,7 +3541,7 @@ this.context.lineTo(
// Callback // Callback
var opt = arguments[0] || {}, var opt = arguments[0] || {},
frames = opt.frames || 30, frames = opt.frames || 60,
frame = 0, frame = 0,
callback = arguments[1] || function () {}, callback = arguments[1] || function () {},
obj = this, obj = this,
@ -3796,7 +3928,35 @@ this.context.lineTo(
{ {
var indexes = RGraph.sequentialIndexToGrouped(opt.index, this.data); var indexes = RGraph.sequentialIndexToGrouped(opt.index, this.data);
var values = this.data[indexes[0]]; var values = this.data[indexes[0]];
// This makes dumbbell charts work correctly
//
// Match the current index with the correct group/index
// values by looking through the coords2 array using the
// current mouse position.
if (this.properties.variant === 'dumbbell') {
var mouseXY = RGraph.getMouseXY(window.event);
outer:
for (var i=0; i<this.coords2.length; ++i) {
for (var j=0; j<this.coords2[i].length; ++j) {
if (
mouseXY[0] > this.coords2[i][j][0]
&& mouseXY[0] < (this.coords2[i][j][0] + this.coords2[i][j][2])
&& mouseXY[1] > this.coords2[i][j][1]
&& mouseXY[1] < (this.coords2[i][j][1] + this.coords2[i][j][3])
) {
indexes = [i, j];
break outer;
}
}
}
}
if (typeof values === 'number') { if (typeof values === 'number') {
values = [values]; values = [values];
} }
@ -4323,6 +4483,261 @@ this.context.lineTo(
//
// Draw a dumbbell chart
//
this.drawdumbbell = function ()
{
var dumbbellCoords = [];
var obj = this;
var seq = 0;
//var y = obj.getYCoord(this.data[0]);
this.coords = [];
this.coords2 = [];
this.data.forEach(function (v, k, arr)
{
var section = ((obj.canvas.width - obj.properties.marginLeft - obj.properties.marginRight) / obj.data.length);
var coordX = (section * k) + obj.properties.marginLeft + (section / 2);
var coordW = obj.properties.variantDumbbellEndRadius;
if (obj.properties.shadow) {
RGraph.setShadow(
obj,
obj.properties.shadowColor,
obj.properties.shadowOffsetx,
obj.properties.shadowOffsety,
obj.properties.shadowBlur
);
}
//
// TODO Need to convert this if condition
//
if (v.length > 2) {
obj.coords2[k] = [];
for (var j=1; j<v.length; ++j) {
var coordY = obj.getYCoord(v[j]);
var coordH = obj.getYCoord(v[j - 1]) - obj.getYCoord(v[j]);
obj.path('b r % % % %',
coordX,
coordY,
coordW,
coordH//(coordH * 2) + (2 * obj.properties.shadowOffsety)
);
obj.pathDumbbell(
coordX,
coordY,
coordW,
coordH,
j === (v.length - 1) && (RGraph.isNull(obj.properties.variantDumbbellEndTop) || obj.properties.variantDumbbellEndTop),
j === 1 && (RGraph.isNull(obj.properties.variantDumbbellEndBottom) || obj.properties.variantDumbbellEndBottom)
);
// Add the rect to the canvas
if (obj.properties.colorsSequential) {
obj.path('f ' + obj.properties.colorsDumbbell[seq]);
} else {
obj.path('f ' + obj.properties.colorsDumbbell[j - 1]);
}
// Determine the height of the
// hotspot
var radius = Math.max(
(obj.properties.variantDumbbellEndTopRadius || obj.properties.variantDumbbellEndTopRadius || 0),
(obj.properties.variantDumbbellEndBottomRadius || obj.properties.variantDumbbellEndBottomRadius || 0)
);
radius = Math.max(coordW, radius);
//
// Calculate the shadowOffset so that the
// highlight covers the shadow as well.
//
var shadowOffset = Math.max(
Math.abs(obj.properties.shadowOffsetx),
Math.abs(obj.properties.shadowOffsety)
);
var coords = [
coordX - radius,
coordY - (j === (v.length - 1) ? radius : 0),
coordW + (2 * radius),
coordH + (j === 1 || (j === v.length - 1) ? radius : 0),
];
// Modify the coords so that the
// shadowOffset is taken into account when
// the highlight is added.
/*
// First segment
if (j === 1) {
// Horizontal offset manglement
if (obj.properties.shadowOffsetx < 0) {
coords[0] -= shadowOffset;
coords[2] += shadowOffset;
} else {
coords[2] += shadowOffset;
}
// Vertical offset manglement
if (obj.properties.shadowOffsety > 0) {
coords[3] += shadowOffset;
}
// Last segment
} else if (j === (v.length - 1) ) {
// Horizontal offset manglement
if (obj.properties.shadowOffsetx > 0) {
coords[2] += shadowOffset;
} else {
coords[0] -= shadowOffset;
coords[2] += shadowOffset;
}
// Vertical offset manglement
if (obj.properties.shadowOffsety > 0) {
//coords[3] += shadowOffset;
} else if (obj.properties.shadowOffsety < 0) {
coords[1] -= shadowOffset;
coords[3] += shadowOffset;
}
// Middle segments
} else {
// Vertical offset manglement
if (obj.properties.shadowOffsetx > 0) {
coords[2] += shadowOffset;
} else {
coords[0] -= shadowOffset;
coords[2] += shadowOffset;
}
}
*/
obj.coords.push(coords);
obj.coords2[k].push(coords);
seq++;
}
// //
// Need this so that the colors are
// used in the coorect order
//
seq--;
// Only TWO Y values - so a minimum and a
// maximum.
} else {
obj.coords2[k] = [];
var coordH = obj.getYCoord(v[0]) - obj.getYCoord(v[1]);
var coordY = obj.getYCoord(v[0]) - coordH;
obj.pathDumbbell(
coordX,
coordY,
coordW,
coordH
);
if (obj.properties.colorsSequential) {
obj.path('f ' + obj.properties.colorsDumbbell[k]);
} else {
obj.path('f ' + obj.properties.colorsDumbbell[0]);
}
// Store the dumbbell coordinates
var coords = [
coordX - obj.properties.variantDumbbellEndRadius - obj.properties.shadowOffsetx,
coordY - obj.properties.shadowOffsety - obj.properties.variantDumbbellEndRadius,
coordW + (2 * obj.properties.variantDumbbellEndRadius) + (2 * obj.properties.shadowOffsetx),
coordH + (2 * obj.properties.variantDumbbellEndRadius) + (2 * obj.properties.shadowOffsety)
];
obj.coords.push(coords);
obj.coords2[k].push(coords);
}
seq++;
RGraph.noShadow(obj);
});
};
//
// Paths a dumbbell bar
//
this.pathDumbbell = function (x, y, w, h, topEnd = true, bottomEnd = true)
{
this.path(
'b r % % % %',
x + (this.properties.variantDumbbellLinewidth / 2) - 2,
y,
this.properties.variantDumbbellLinewidth,
h
);
if (this.properties.variantDumbbellEndTop && topEnd) {
this.path(
'm % % a % % % 0 6.29 false',
x + (w/2), y,
x + (w/2), y, (RGraph.isNumber(this.properties.variantDumbbellEndTopRadius) ? this.properties.variantDumbbellEndTopRadius : this.properties.variantDumbbellEndRadius)
);
}
if (this.properties.variantDumbbellEndBottom && bottomEnd) {
this.path(
'm % % a % % % 0 6.29 false',
x + (w/2), y+h,
x + (w/2), y+h, (RGraph.isNumber(this.properties.variantDumbbellEndBottomRadius) ? this.properties.variantDumbbellEndBottomRadius : this.properties.variantDumbbellEndRadius)
);
}
};
// //

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,16 @@
'version:2025-10-08 (7.01)'; 'version:2026-08-11 (7.21)';
// //
// o---------------------------------------------------------------------------------o // o---------------------------------------------------------------------------o
// | This file is part of the RGraph package - you can learn more at: | // | This file is part of the RGraph package - you can learn more at: |
// | | // | |
// | https://www.rgraph.net/license.html | // | https://www.rgraph.net |
// | | // | |
// | RGraph is dual-licensed under the Open Source GPL license. That means that it's | // | RGraph is dual-licensed under the Open Source GPL license. This means |
// | free to use and there are no restrictions on what you can use RGraph for! | // | that it's free to use for any purpose. The GPL license does have |
// | If the GPL license does not suit you however, then there's an inexpensive | // | consequences on the license of the software that you include it in, |
// | commercial license option available. See the URL above for more details. | // | however. If this is not desirable, then there's an inexpensive commercial |
// o---------------------------------------------------------------------------------o // | license option available. See the RGraph website for more details. |
// o---------------------------------------------------------------------------o
// //
// Having this here means that the RGraph libraries can be included in any order, instead of you having // Having this here means that the RGraph libraries can be included in any order, instead of you having
@ -93,7 +94,6 @@
width: null, width: null,
height: null, height: null,
halign: 'left', halign: 'left',
valign: 'top', valign: 'top',
@ -121,9 +121,12 @@
tooltipsPointerOffsetx: 0, tooltipsPointerOffsetx: 0,
tooltipsPointerOffsety: 0, tooltipsPointerOffsety: 0,
tooltipsPositionStatic: true, tooltipsPositionStatic: true,
tooltipsOffsetx: 0,
tooltipsOffsety: 0,
highlightStroke: 'rgba(0,0,0,0)', highlightStroke: 'transparent',
highlightFill: 'rgba(255,255,255,0.7)', highlightFill: 'rgba(255,255,255,0.7)',
highlightFade: true,
colorsAlpha: 1, colorsAlpha: 1,
@ -132,19 +135,20 @@
borderLinewidth: 1, borderLinewidth: 1,
borderRadius: 0, borderRadius: 0,
backgroundColor: 'rgba(0,0,0,0)', backgroundColor: 'transparent',
text: null, text: null,
clearto: 'rgba(0,0,0,0)', clearto: 'transparent',
clip: null, clip: null,
events: {}, events: {},
responsive: null,
scale: true, scale: true,
scaleFactor: 2, scaleFactor: 2,
antialiasTranslate: false antialiasTranslate: false,
style: []
}; };
@ -323,6 +327,18 @@
// Fire the onbeforedraw event // Fire the onbeforedraw event
// //
RGraph.fireCustomEvent(this, 'onbeforedraw'); RGraph.fireCustomEvent(this, 'onbeforedraw');
//
// Add any CSS that has been specified to the document.
// This is general CSS and does not necessarily have to
// pertain to the canvas tag. It only gets added once
// to the document no matter how many times this draw
// function is called.
//
// Add the CSS to a <style> block in the <head>.
RGraph.addConfigurationBasedCSS(this);
var scaleFactor = RGraph.getScaleFactor(this); var scaleFactor = RGraph.getScaleFactor(this);
@ -406,7 +422,7 @@
obj.alignmentProcessed = true; obj.alignmentProcessed = true;
} }
} }
@ -439,12 +455,13 @@
// Need this to stop a rectangle being drawn around
// the llast path that was added to the canvas.
this.context.beginPath();
// //
// Draw a border around the image // Draw a border around the image
// //
/// !!!!!!
if (properties.border) { if (properties.border) {
this.context.strokeStyle = properties.borderColor; this.context.strokeStyle = properties.borderColor;
@ -478,7 +495,8 @@
); );
} }
this.context.stroke(); this.context.stroke();
if (borderRadius) { if (borderRadius) {
this.context.save(); this.context.save();
@ -722,33 +740,62 @@
// //
// Each object type has its own Highlight() function which highlights the appropriate shape // Each object type has its own Highlight() function
// which highlights the appropriate shape.
// //
// @param object shape The shape to highlight // @param object shape The shape to highlight.
// //
this.highlight = function (shape) this.highlight = function (shape)
{ {
if (properties.tooltipsHighlight) { // If the highlightFade property is not set then call
if (typeof properties.highlightStyle === 'function') { // the highlight function multiple times when the
(properties.highlightStyle)(shape); // globalAlpha is set at varying levels of transparency
} else { // to fade the highlight in. If the variable is set,
this.path('b'); // however, then this call is probably a part of said
// highlighting process so don't call ourselves
// again - just highlight the chart.
if (this.properties.highlightFade && !this.highlight.highlighting) {
// Add a variable to the highlight function (this
// function) to indicate that we're currently in
// the process of highlighting.
this.highlight.highlighting = true;
var obj = this;
setTimeout(function() {obj.context.globalAlpha = 0.2; obj.highlight(shape); obj.context.globalAlpha = 1;}, 20);
setTimeout(function() {obj.context.globalAlpha = 0.2; obj.highlight(shape); obj.context.globalAlpha = 1;}, 40);
setTimeout(function() {obj.context.globalAlpha = 0.2; obj.highlight(shape); obj.context.globalAlpha = 1;}, 60);
setTimeout(function() {obj.context.globalAlpha = 0.2; obj.highlight(shape); obj.context.globalAlpha = 1;}, 80);
setTimeout(function() {obj.context.globalAlpha = 0.2; obj.highlight(shape); obj.context.globalAlpha = 1;}, 100);
setTimeout(function() {obj.context.globalAlpha = 0.2; obj.highlight(shape); obj.context.globalAlpha = 1;}, 120);
setTimeout(function() {obj.context.globalAlpha = 0.2; obj.highlight(shape); obj.context.globalAlpha = 1;}, 140);
setTimeout(function() {obj.highlight.highlighting = false;}, 400);
return;
}
this.roundedRect( RGraph.clipTo.callback(this, function (obj)
this.coords[0][0], {
this.coords[0][1], if (typeof obj.properties.highlightStyle === 'function') {
this.coords[0][2], (obj.properties.highlightStyle)(shape);
this.coords[0][3], } else {
this.properties.borderRadius obj.path('b');
obj.roundedRect(
obj.coords[0][0],
obj.coords[0][1],
obj.coords[0][2],
obj.coords[0][3],
obj.properties.borderRadius
); );
this.path( obj.path(
'f % s %', 'f % s %',
properties.highlightFill, obj.properties.highlightFill,
properties.highlightStroke obj.properties.highlightStroke
); );
} }
} });// End of clipping callback.
}; };

View File

@ -1,15 +1,16 @@
'version:2025-10-08 (7.01)'; 'version:2026-08-11 (7.21)';
// //
// o---------------------------------------------------------------------------------o // o---------------------------------------------------------------------------o
// | This file is part of the RGraph package - you can learn more at: | // | This file is part of the RGraph package - you can learn more at: |
// | | // | |
// | https://www.rgraph.net/license.html | // | https://www.rgraph.net |
// | | // | |
// | RGraph is dual-licensed under the Open Source GPL license. That means that it's | // | RGraph is dual-licensed under the Open Source GPL license. This means |
// | free to use and there are no restrictions on what you can use RGraph for! | // | that it's free to use for any purpose. The GPL license does have |
// | If the GPL license does not suit you however, then there's an inexpensive | // | consequences on the license of the software that you include it in, |
// | commercial license option available. See the URL above for more details. | // | however. If this is not desirable, then there's an inexpensive commercial |
// o---------------------------------------------------------------------------------o // | license option available. See the RGraph website for more details. |
// o---------------------------------------------------------------------------o
RGraph = window.RGraph || {isrgraph:true,isRGraph:true,rgraph:true}; RGraph = window.RGraph || {isrgraph:true,isRGraph:true,rgraph:true};
@ -100,7 +101,6 @@
titleTopPos: null, titleTopPos: null,
titleTopOffsetx: 0, titleTopOffsetx: 0,
titleTopOffsety: 0, titleTopOffsety: 0,
titleTopSubtitle: null, titleTopSubtitle: null,
titleTopSubtitleFont: null, titleTopSubtitleFont: null,
titleTopSubtitleSize: null, titleTopSubtitleSize: null,
@ -129,27 +129,26 @@
scaleThousand: ',', scaleThousand: ',',
scaleUnitsPre: '', scaleUnitsPre: '',
scaleUnitsPost: '', scaleUnitsPost: '',
scalePoint: '.',
scaleThousand: ',',
labelsCount: 5, labelsCount: 5,
labelsCentered: false, labelsCentered: false,
labelsOffsetRadius: 0, labelsOffsetRadius: 0,
labelsOffsetAngle: 0, labelsOffsetAngle: 0,
labelsOffsetx: 0,
labelsOffsety: 0,
labelsSpecific: null, labelsSpecific: null,
labelsSpecificFormattedDecimals: 0, labelsSpecificFormattedDecimals: 0,
labelsSpecificFormattedPoint: '.', labelsSpecificFormattedPoint: '.',
labelsSpecificFormattedThousand: ',', labelsSpecificFormattedThousand: ',',
labelsSpecificFormattedUnitsPre: '', labelsSpecificFormattedUnitsPre: '',
labelsSpecificFormattedUnitsPost: '', labelsSpecificFormattedUnitsPost: '',
labelsOffsetx: 0,
labelsOffsety: 0,
labelsFont: null, labelsFont: null,
labelsSize: null, labelsSize: null,
labelsColor: null, labelsColor: null,
labelsBold: null, labelsBold: null,
labelsItalic: null, labelsItalic: null,
labelsValue: false,
labelsValue: false,
labelsValueYPos: 0.5, labelsValueYPos: 0.5,
labelsValueUnitsPre: '', labelsValueUnitsPre: '',
labelsValueUnitsPost: '', labelsValueUnitsPost: '',
@ -167,12 +166,12 @@
colorsRedStart: 0.9 * this.max, colorsRedStart: 0.9 * this.max,
colorsRedColor: '#DC3912', colorsRedColor: '#dc3912',
colorsRedWidth: 5, colorsRedWidth: 5,
colorsYellowColor: '#FF9900', colorsYellowColor: '#ff9900',
colorsYellowWidth: 5, colorsYellowWidth: 5,
colorsGreenEnd: 0.7 * this.max, colorsGreenEnd: 0.7 * this.max,
colorsGreenColor: 'rgba(0,0,0,0)', colorsGreenColor: 'transparent',
colorsGreenWidth: 5, colorsGreenWidth: 5,
colorsRanges: null, colorsRanges: null,
@ -187,8 +186,9 @@
borderOutline: 'black', borderOutline: 'black',
borderGradient: false, borderGradient: false,
centerpinColor: 'blue', centerpinColor: 'black',
centerpinRadius: null, centerpinGradient: false,
centerpinRadius: null,
tickmarksSmall: 25, tickmarksSmall: 25,
tickmarksSmallColor: 'black', tickmarksSmallColor: 'black',
@ -203,19 +203,22 @@
annotatableLinewidth: 1, annotatableLinewidth: 1,
annotatableColor: 'black', annotatableColor: 'black',
shadow: true, shadow: false,
shadowColor: 'gray', shadowColor: 'gray',
shadowOffsetx: 0, shadowOffsetx: 0,
shadowOffsety: 0, shadowOffsety: 0,
shadowBlur: 15, shadowBlur: 15,
clearto: 'rgba(0,0,0,0)', clearto: 'transparent',
events: {},
events: {},
clip: null,
responsive: null,
scale: true, scale: true,
scaleFactor: 2, scaleFactor: 2,
antialiasTranslate: false antialiasTranslate: false,
style: []
}; };
@ -428,6 +431,18 @@
//
// Add any CSS that has been specified to the document.
// This is general CSS and does not necessarily have to
// pertain to the canvas tag. It only gets added once
// to the document no matter how many times this draw
// function is called.
//
// Add the CSS to a <style> block in the <head>.
RGraph.addConfigurationBasedCSS(this);
@ -932,17 +947,24 @@
var scaleFactor = RGraph.getScaleFactor(this); var scaleFactor = RGraph.getScaleFactor(this);
var offset = (6 * scaleFactor); var offset = (6 * scaleFactor);
var grad = this.context.createRadialGradient( //
this.centerx + offset, // Gradient or not
this.centery - offset, //
0, if (this.properties.centerpinGradient) {
this.centerx + offset, var grad = this.context.createRadialGradient(
this.centery - offset, this.centerx + offset,
(25 * scaleFactor) this.centery - offset,
); 0,
grad.addColorStop(0, '#ddf'); this.centerx + offset,
grad.addColorStop(1, properties.centerpinColor); this.centery - offset,
(25 * scaleFactor)
);
grad.addColorStop(0, '#ddf');
grad.addColorStop(1, this.properties.centerpinColor);
} else {
grad = this.properties.centerpinColor;
}
this.context.beginPath(); this.context.beginPath();
this.context.fillStyle = grad; this.context.fillStyle = grad;
@ -997,11 +1019,7 @@
// If the labelsSpecific option is a string then turn it // If the labelsSpecific option is a string then turn it
// into an array. // into an array.
if (typeof properties.labelsSpecific === 'string' ) { if (typeof properties.labelsSpecific === 'string' ) {
properties.labelsSpecific = RGraph.arrayPad({ properties.labelsSpecific = RGraph.arrayPad([], properties.labelsCount, properties.labelsSpecific);
array: [],
length: properties.labelsCount,
value: properties.labelsSpecific
});
} }
@ -1090,11 +1108,7 @@
valign: vAlign, valign: vAlign,
tag: properties.labelsSpecific ? 'labels.specific' : 'labels', tag: properties.labelsSpecific ? 'labels.specific' : 'labels',
cssClass: properties.labelsSpecific cssClass: properties.labelsSpecific
? RGraph.getLabelsCSSClassName({ ? RGraph.getLabelsCSSClassName(this, 'labelsClass', i)
object: this,
name: 'labelsClass',
index: i
})
: '' : ''
}); });
} }
@ -1207,13 +1221,13 @@
// Move the Y coord up if there's a subtitle // Move the Y coord up if there's a subtitle
if (typeof properties.titleTopSubtitle === 'string' || typeof properties.titleTopSubtitle === 'number') { if (typeof properties.titleTopSubtitle === 'string' || typeof properties.titleTopSubtitle === 'number') {
var titleTopSubtitleDim = RGraph.measureText({ var titleTopSubtitleDim = RGraph.measureText(
bold: properties.titleTopSubtitleBold, 'Mg',
italic: properties.titleTopSubtitleItalic, properties.titleTopSubtitleItalic,
size: properties.titleTopSubtitleSize, properties.titleTopSubtitleBold,
font: properties.titleTopSubtitleFont, properties.titleTopSubtitleFont,
text: 'Mg' properties.titleTopSubtitleSize
}); );
y -= titleTopSubtitleDim[1]; y -= titleTopSubtitleDim[1];
} }
@ -1906,7 +1920,7 @@
var obj = this, var obj = this,
opt = arguments[0] ? arguments[0] : {}, opt = arguments[0] ? arguments[0] : {},
callback = arguments[1] ? arguments[1] : function () {}, callback = arguments[1] ? arguments[1] : function () {},
frames = opt.frames || 30, frames = opt.frames || 60,
frame = 0; frame = 0;
// Don't want any strings // Don't want any strings

View File

@ -1,15 +1,16 @@
'version:2025-10-08 (7.01)'; 'version:2026-08-11 (7.21)';
// //
// o---------------------------------------------------------------------------------o // o---------------------------------------------------------------------------o
// | This file is part of the RGraph package - you can learn more at: | // | This file is part of the RGraph package - you can learn more at: |
// | | // | |
// | https://www.rgraph.net/license.html | // | https://www.rgraph.net |
// | | // | |
// | RGraph is dual-licensed under the Open Source GPL license. That means that it's | // | RGraph is dual-licensed under the Open Source GPL license. This means |
// | free to use and there are no restrictions on what you can use RGraph for! | // | that it's free to use for any purpose. The GPL license does have |
// | If the GPL license does not suit you however, then there's an inexpensive | // | consequences on the license of the software that you include it in, |
// | commercial license option available. See the URL above for more details. | // | however. If this is not desirable, then there's an inexpensive commercial |
// o---------------------------------------------------------------------------------o // | license option available. See the RGraph website for more details. |
// o---------------------------------------------------------------------------o
RGraph = window.RGraph || {isrgraph:true,isRGraph:true,rgraph:true}; RGraph = window.RGraph || {isrgraph:true,isRGraph:true,rgraph:true};
@ -49,13 +50,14 @@
this.properties = this.properties =
{ {
backgroundBorder: 'black', backgroundBorder: 'black',
backgroundColor: '#eee', backgroundColor: 'white',
backgroundLinesColor: '#ddd', backgroundLinesColor: '#ddd',
centerx: null, centerx: null,
centery: null, centery: null,
radius: null, radius: null,
labels: null,
labelsMargin: 35, labelsMargin: 35,
labelsFont: null, labelsFont: null,
labelsSize: null, labelsSize: null,
@ -81,7 +83,7 @@
needleLength: null, needleLength: null,
needleWidth: 2, needleWidth: 2,
needleHead: true, needleHead: true,
needleTail: true, needleTail: false,
needleType: 'pointer', needleType: 'pointer',
needleTriangleBorder: '#aaa', needleTriangleBorder: '#aaa',
@ -96,10 +98,10 @@
text: null, text: null,
colorsGreenMax: max * 0.75, colorsGreenMax: max * 0.75,
colorsGreenColor: '#0c0', colorsGreenColor: '#00cc0088',
colorsYellowColor: '#cc0', colorsYellowColor: '#ffff0088',
colorsRedMin: max * 0.9, colorsRedMin: max * 0.9,
colorsRedColor: '#c00', colorsRedColor: '#ff000088',
marginLeft: 35, marginLeft: 35,
marginRight: 35, marginRight: 35,
@ -144,6 +146,7 @@
annotatable: false, annotatable: false,
annotatableColor: 'black', annotatableColor: 'black',
annotatableLinewidth: 1,
scaleDecimals: 0, scaleDecimals: 0,
scalePoint: '.', scalePoint: '.',
@ -152,7 +155,7 @@
scaleUnitsPost: '', scaleUnitsPost: '',
scaleZerostart: false, scaleZerostart: false,
border: true, border: false,
borderColor1: '#BEBCB0', borderColor1: '#BEBCB0',
borderColor2: '#F0EFEA', borderColor2: '#F0EFEA',
borderColor3: '#BEBCB0', borderColor3: '#BEBCB0',
@ -161,8 +164,6 @@
tickmarksHighlighted: true, tickmarksHighlighted: true,
tickmarksLargeColor: '#999', tickmarksLargeColor: '#999',
labels: null,
key: null, key: null,
keyBackground: 'white', keyBackground: 'white',
keyPosition: 'graph', keyPosition: 'graph',
@ -196,13 +197,16 @@
adjustable: false, adjustable: false,
clearto: 'rgba(0,0,0,0)', clearto: 'transparent',
events: {}, events: {},
clip: null,
responsive: null,
scale: true, scale: true,
scaleFactor: 2, scaleFactor: 2,
antialiasTranslate: false antialiasTranslate: false,
style: []
}; };
@ -385,6 +389,18 @@
//
// Add any CSS that has been specified to the document.
// This is general CSS and does not necessarily have to
// pertain to the canvas tag. It only gets added once
// to the document no matter how many times this draw
// function is called.
//
// Add the CSS to a <style> block in the <head>.
RGraph.addConfigurationBasedCSS(this);
// Translate half a pixel for antialiasing purposes - but // Translate half a pixel for antialiasing purposes - but
// only if it hasn't been done already // only if it hasn't been done already
// //
@ -1593,7 +1609,7 @@
var obj = this; var obj = this;
var opt = arguments[0] || {}; var opt = arguments[0] || {};
var frames = opt.frames || 30; var frames = opt.frames || 60;
var frame = 0; var frame = 0;
var current = this.currentValue || 0; var current = this.currentValue || 0;
var origValue = Number(obj.currentValue); var origValue = Number(obj.currentValue);

View File

@ -1,15 +1,16 @@
'version:2025-10-08 (7.01)'; 'version:2026-08-11 (7.21)';
// //
// o---------------------------------------------------------------------------------o // o---------------------------------------------------------------------------o
// | This file is part of the RGraph package - you can learn more at: | // | This file is part of the RGraph package - you can learn more at: |
// | | // | |
// | https://www.rgraph.net/license.html | // | https://www.rgraph.net |
// | | // | |
// | RGraph is dual-licensed under the Open Source GPL license. That means that it's | // | RGraph is dual-licensed under the Open Source GPL license. This means |
// | free to use and there are no restrictions on what you can use RGraph for! | // | that it's free to use for any purpose. The GPL license does have |
// | If the GPL license does not suit you however, then there's an inexpensive | // | consequences on the license of the software that you include it in, |
// | commercial license option available. See the URL above for more details. | // | however. If this is not desirable, then there's an inexpensive commercial |
// o---------------------------------------------------------------------------------o // | license option available. See the RGraph website for more details. |
// o---------------------------------------------------------------------------o
RGraph = window.RGraph || {isrgraph:true,isRGraph:true,rgraph:true}; RGraph = window.RGraph || {isrgraph:true,isRGraph:true,rgraph:true};
@ -47,8 +48,8 @@
backgroundColor: 'white', backgroundColor: 'white',
colorsStroke: 'black', colorsStroke: '#666',
colors: ['red'], colors: RGraph.getColors(),
marginLeft: 35, marginLeft: 35,
marginRight: 35, marginRight: 35,
@ -56,7 +57,7 @@
marginBottom: 35, marginBottom: 35,
tickmarksSize: 2, tickmarksSize: 2,
tickmarksCount: 10, tickmarksCount: 0,
textColor: 'black', textColor: 'black',
textFont: 'Arial, Verdana, sans-serif', textFont: 'Arial, Verdana, sans-serif',
@ -102,14 +103,11 @@
titleSideOffsetx: 0, titleSideOffsetx: 0,
titleSideOffsety: 0, titleSideOffsety: 0,
shadow: true, shadow: false,
shadowOffsetx: 0, shadowOffsetx: 0,
shadowOffsety: 0, shadowOffsety: 0,
shadowBlur: 15, shadowBlur: 15,
shadowColor: '#ddd', shadowColor: '#ddd',
resizable: false,
resizableHandleBackground: null,
contextmenu: null, contextmenu: null,
@ -172,19 +170,23 @@
tooltipsPositionStatic: true, tooltipsPositionStatic: true,
tooltipsHotspotIgnore: null, tooltipsHotspotIgnore: null,
highlightStroke: 'rgba(0,0,0,0)', highlightStroke: 'transparent',
highlightFill: 'rgba(255,255,255,0.7)', highlightFill: 'rgba(255,255,255,0.7)',
highlightFade: true,
clearto: 'rgba(0,0,0,0)', clearto: 'transparent',
bulbBottomRadiusAdjust: 0, bulbBottomRadiusAdjust: 0,
bulbBottomRadius: null, bulbBottomRadius: null,
events: {}, events: {},
clip: null,
responsive: null,
scale: true, scale: true,
scaleFactor: 2, scaleFactor: 2,
antialiasTranslate: false antialiasTranslate: false,
style: []
}; };
@ -407,6 +409,18 @@
//
// Add any CSS that has been specified to the document.
// This is general CSS and does not necessarily have to
// pertain to the canvas tag. It only gets added once
// to the document no matter how many times this draw
// function is called.
//
// Add the CSS to a <style> block in the <head>.
RGraph.addConfigurationBasedCSS(this);
// Translate half a pixel for antialiasing purposes - but // Translate half a pixel for antialiasing purposes - but
// only if it hasn't been done already // only if it hasn't been done already
// //
@ -1124,20 +1138,50 @@
// //
this.highlight = function (shape) this.highlight = function (shape)
{ {
if (properties.tooltipsHighlight) { // If the highlightFade property is not set then call
// the highlight function multiple times when the
// globalAlpha is set at varying levels of transparency
// to fade the highlight in. If the variable is set,
// however, then this call is probably a part of said
// highlighting process so don't call ourselves
// again - just highlight the chart.
if (this.properties.highlightFade && !this.highlight.highlighting) {
if (typeof properties.highlightStyle === 'function') { // Add a variable to the highlight function (this
(properties.highlightStyle)(shape); // function) to indicate that we're currently in
return; // the process of highlighting.
} this.highlight.highlighting = true;
this.pathBar(); var obj = this;
setTimeout(function() {obj.context.globalAlpha = 0.2; obj.highlight(shape); obj.context.globalAlpha = 1;}, 20);
setTimeout(function() {obj.context.globalAlpha = 0.2; obj.highlight(shape); obj.context.globalAlpha = 1;}, 40);
setTimeout(function() {obj.context.globalAlpha = 0.2; obj.highlight(shape); obj.context.globalAlpha = 1;}, 60);
setTimeout(function() {obj.context.globalAlpha = 0.2; obj.highlight(shape); obj.context.globalAlpha = 1;}, 80);
setTimeout(function() {obj.context.globalAlpha = 0.2; obj.highlight(shape); obj.context.globalAlpha = 1;}, 100);
setTimeout(function() {obj.context.globalAlpha = 0.2; obj.highlight(shape); obj.context.globalAlpha = 1;}, 120);
setTimeout(function() {obj.context.globalAlpha = 0.2; obj.highlight(shape); obj.context.globalAlpha = 1;}, 140);
setTimeout(function() {obj.highlight.highlighting = false;}, 400);
this.path( return;
's % f %',
properties.highlightStroke, properties.highlightFill
);
} }
RGraph.clipTo.callback(this, function (obj)
{
if (obj.properties.tooltipsHighlight) {
if (typeof obj.properties.highlightStyle === 'function') {
(obj.properties.highlightStyle)(shape);
return;
}
obj.pathBar();
obj.path(
's % f %',
obj.properties.highlightStroke, obj.properties.highlightFill
);
}
});
}; };

View File

@ -70,8 +70,6 @@
</span> </span>
</nav> </nav>
<section id="estado-estacion" class="estado-estacion" aria-label="Estado de la estación"></section> <section id="estado-estacion" class="estado-estacion" aria-label="Estado de la estación"></section>
<br><br>
<div id="superior" class="container"> <div id="superior" class="container">
<div class="row"> <div class="row">
<div class="col-2" align="center" style="vertical-align:top;"> <div class="col-2" align="center" style="vertical-align:top;">

View File

@ -1,5 +1,12 @@
27/09/2026 23:00:15 - 1|PURGADO|Archivo de Debug 27/09/2026 23:13:40 - 1|PURGADO|Archivo de Debug
27/09/2026 23:00:44 - 0|CORE|⚙️ RECONFIGURANDO: Se reconfigura el recolectorde EMA LIBRE. 27/09/2026 23:13:41 - 1|PURGADO|Archivo de Pendientes
27/09/2026 23:01:01 - 0|CORE|⚙️ RECONFIGURANDO: Se reconfigura el recolectorde EMA LIBRE. 27/09/2026 23:18:43 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
27/09/2026 23:01:10 - 0|CORE|⚙️ RECONFIGURANDO: Se reconfigura el recolectorde EMA LIBRE. 27/09/2026 23:18:43 - 0|CORE|✅ Modulo node-hid cargado correctamente.
27/09/2026 23:01:42 - 0|CORE|⚙️ RECONFIGURANDO: Se reconfigura el recolectorde EMA LIBRE. 27/09/2026 23:18:43 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
27/09/2026 23:20:26 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
27/09/2026 23:20:26 - 0|CORE|✅ Modulo node-hid cargado correctamente.
27/09/2026 23:20:26 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
27/09/2026 23:21:09 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
27/09/2026 23:21:09 - 0|CORE|✅ Modulo node-hid cargado correctamente.
27/09/2026 23:21:09 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
27/09/2026 23:23:30 - 0|CORE|🔚 SALIR: Se cerro el core de EMA LIBRE. Hasta luego!!!.