Jauge tolerance

This commit is contained in:
2026-05-17 19:12:46 +02:00
parent 991a875b94
commit 66ac2d0e0a
4 changed files with 740 additions and 0 deletions

View File

@@ -19840,6 +19840,169 @@ function eval_pyson(value){
}
});
Sao.View.ToleranceGaugeMixin = {
_number: function(value) {
if ((value === null) || (value === undefined) || (value === '')) {
return null;
}
value = Number(value);
if (isNaN(value)) {
return null;
}
return value;
},
_field_value: function(record, name) {
if (!name || !record || !record.model.fields[name]) {
return null;
}
return this._number(record.model.fields[name].get(record));
},
_bound_value: function(record, literal, field_name, fallback) {
var value = this._field_value(record, field_name);
if (value === null) {
value = this._number(literal);
}
if (value === null) {
value = fallback;
}
return value;
},
_bounds: function(record) {
var min = this._bound_value(
record, this.attributes.min, this.attributes.min_field, null);
var max = this._bound_value(
record, this.attributes.max, this.attributes.max_field, null);
if ((min === null) && (max !== null)) {
min = -Math.abs(max);
}
if ((max === null) && (min !== null)) {
max = Math.abs(min);
}
if (min === null) {
min = -1;
}
if (max === null) {
max = 1;
}
if (min == max) {
min -= 1;
max += 1;
}
if (min > max) {
var swap = min;
min = max;
max = swap;
}
return [min, max];
},
_position: function(value, min, max) {
return Math.max(0, Math.min(100, ((value - min) / (max - min)) * 100));
},
_format_number: function(value) {
if ((value === null) || (value === undefined) || isNaN(value)) {
return '';
}
return (value * Number(this.attributes.factor || 1)).toLocaleString(
Sao.i18n.BC47(Sao.i18n.getlang()), {
maximumFractionDigits: Number(
this.attributes.digits || 6),
useGrouping: true
});
},
_set_gauge: function(record, value, text) {
var bounds = this._bounds(record);
var min = bounds[0];
var max = bounds[1];
var center = this._number(this.attributes.center);
if (center === null) {
center = 0;
}
var current = this._number(value);
if (current === null) {
current = center;
}
var current_position = this._position(current, min, max);
var center_position = this._position(center, min, max);
var fill_left = Math.min(current_position, center_position);
var fill_width = Math.abs(current_position - center_position);
var outside = (current < min) || (current > max);
var title = text || this._format_number(current);
this.el.toggleClass('outside', outside);
this.el.toggleClass('under', current < min);
this.el.toggleClass('over', current > max);
this.el.css('--tolerance-gauge-value', current_position + '%');
this.el.css('--tolerance-gauge-center', center_position + '%');
this.el.css('--tolerance-gauge-fill-left', fill_left + '%');
this.el.css('--tolerance-gauge-fill-width', fill_width + '%');
this.min_label.text(this._format_number(min));
this.center_label.text(this._format_number(center));
this.max_label.text(this._format_number(max));
this.value_label.text(title);
this.track.attr('aria-valuemin', min);
this.track.attr('aria-valuemax', max);
this.track.attr('aria-valuenow', current);
this.track.attr('aria-valuetext', title);
this.el.attr('title', title);
}
};
Sao.View.Form.ToleranceGauge = Sao.class_(Sao.View.Form.Widget, {
class_: 'form-tolerance-gauge',
init: function(view, attributes) {
Sao.View.Form.ToleranceGauge._super.init.call(
this, view, attributes);
this.el = jQuery('<div/>', {
'class': this.class_
});
var labels = jQuery('<div/>', {
'class': this.class_ + '-labels'
}).appendTo(this.el);
this.min_label = jQuery('<span/>', {
'class': this.class_ + '-label ' + this.class_ + '-label-min'
}).appendTo(labels);
this.center_label = jQuery('<span/>', {
'class': this.class_ + '-label ' + this.class_ + '-label-center'
}).appendTo(labels);
this.max_label = jQuery('<span/>', {
'class': this.class_ + '-label ' + this.class_ + '-label-max'
}).appendTo(labels);
this.track = jQuery('<div/>', {
'class': this.class_ + '-track',
'role': 'meter',
'tabindex': 0
}).appendTo(this.el);
jQuery('<div/>', {
'class': this.class_ + '-fill'
}).appendTo(this.track);
jQuery('<div/>', {
'class': this.class_ + '-center-tick'
}).appendTo(this.track);
jQuery('<div/>', {
'class': this.class_ + '-marker'
}).appendTo(this.track);
this.value_label = jQuery('<div/>', {
'class': this.class_ + '-value'
}).appendTo(this.el);
},
display: function() {
Sao.View.Form.ToleranceGauge._super.display.call(this);
var record = this.record;
var field = this.field;
var value = 0;
var text = '';
if (field) {
value = field.get(record);
text = field.get_client(record);
}
this._set_gauge(record, value, text);
}
});
jQuery.extend(
Sao.View.Form.ToleranceGauge.prototype,
Sao.View.ToleranceGaugeMixin);
Sao.View.Form.Dict = Sao.class_(Sao.View.Form.Widget, {
class_: 'form-dict',
expand: true,
@@ -21685,6 +21848,7 @@ function eval_pyson(value){
'time': Sao.View.Form.Time,
'timedelta': Sao.View.Form.TimeDelta,
'timestamp': Sao.View.Form.DateTime,
'tolerance_gauge': Sao.View.Form.ToleranceGauge,
'url': Sao.View.Form.URL,
};
Sao.View.FormXMLViewParser.WIDGETS['html_viewer'] = Sao.View.Form.HTMLViewer;
@@ -29510,6 +29674,61 @@ function eval_pyson(value){
}
});
Sao.View.Tree.ToleranceGauge = Sao.class_(Sao.View.Tree.CharColumn, {
class_: 'column-tolerance-gauge form-tolerance-gauge',
get_cell: function() {
var cell = jQuery('<div/>', {
'class': this.class_,
'tabindex': 0
});
var labels = jQuery('<div/>', {
'class': 'form-tolerance-gauge-labels'
}).appendTo(cell);
jQuery('<span/>', {
'class': 'form-tolerance-gauge-label form-tolerance-gauge-label-min'
}).appendTo(labels);
jQuery('<span/>', {
'class': 'form-tolerance-gauge-label form-tolerance-gauge-label-center'
}).appendTo(labels);
jQuery('<span/>', {
'class': 'form-tolerance-gauge-label form-tolerance-gauge-label-max'
}).appendTo(labels);
var track = jQuery('<div/>', {
'class': 'form-tolerance-gauge-track',
'role': 'meter'
}).appendTo(cell);
jQuery('<div/>', {
'class': 'form-tolerance-gauge-fill'
}).appendTo(track);
jQuery('<div/>', {
'class': 'form-tolerance-gauge-center-tick'
}).appendTo(track);
jQuery('<div/>', {
'class': 'form-tolerance-gauge-marker'
}).appendTo(track);
jQuery('<div/>', {
'class': 'form-tolerance-gauge-value'
}).appendTo(cell);
return cell;
},
get_textual_value: function(record) {
return this.field.get_client(record);
},
update_text: function(cell, record) {
this.el = cell;
this.min_label = cell.find('.form-tolerance-gauge-label-min');
this.center_label = cell.find('.form-tolerance-gauge-label-center');
this.max_label = cell.find('.form-tolerance-gauge-label-max');
this.track = cell.find('.form-tolerance-gauge-track');
this.value_label = cell.find('.form-tolerance-gauge-value');
this._set_gauge(
record, this.field.get(record), this.get_textual_value(record));
}
});
jQuery.extend(
Sao.View.Tree.ToleranceGauge.prototype,
Sao.View.ToleranceGaugeMixin);
Sao.View.Tree.ButtonColumn = Sao.class_(Object, {
init: function(view, attributes) {
this.view = view;
@@ -29597,6 +29816,7 @@ function eval_pyson(value){
'text': Sao.View.Tree.TextColum,
'time': Sao.View.Tree.TimeColumn,
'timedelta': Sao.View.Tree.TimeDeltaColumn,
'tolerance_gauge': Sao.View.Tree.ToleranceGauge,
'url': Sao.View.Tree.URLColumn,
};