enum STAT_OPERATOR { _sum, _average, _median, _max, _min } #region create global.node_statistic_keys = [ "sum", "mean", "median", "min", "max" ]; array_append(global.node_statistic_keys, [ "average" ]); function Node_create_Statistic(_x, _y, _group = noone, _param = {}) { var query = struct_try_get(_param, "query", ""); var node = new Node_Statistic(_x, _y, _group).skipDefault(); var ind = -1; switch(query) { default : ind = array_find(global.node_statistic_keys, query); } if(ind >= 0) node.inputs[0].setValue(ind); return node; } #endregion function Node_Statistic(_x, _y, _group = noone) : Node(_x, _y, _group) constructor { name = "Statistic"; setDimension(96, 48); newInput(0, nodeValue_Enum_Scroll("Type", self, 0, [ "Sum", "Mean", "Median", "Max", "Min" ])) .rejectArray(); static createNewInput = function() { var index = array_length(inputs); newInput(index, nodeValue_Float("Input", self, -1 )) .setVisible(false, true); return inputs[index]; } setDynamicInput(1, true, VALUE_TYPE.float); newOutput(0, nodeValue_Output("Statistic", self, VALUE_TYPE.float, -1)); static onValueUpdate = function(index = 0) { if(index != 0) return; var _type = inputs[0].getValue(); switch(_type) { case STAT_OPERATOR._sum : setDisplayName("Sum") break; case STAT_OPERATOR._average : setDisplayName("Average"); break; case STAT_OPERATOR._median : setDisplayName("Median"); break; case STAT_OPERATOR._max : setDisplayName("Max"); break; case STAT_OPERATOR._min : setDisplayName("Min"); break; } } static update = function(frame = CURRENT_FRAME) { #region var type = getInputData(0); var res = 0; switch(type) { case STAT_OPERATOR._sum : for( var i = input_fix_len; i < array_length(inputs); i++ ) { var val = getInputData(i); if(is_array(val)) { for( var j = 0; j < array_length(val); j++ ) res += val[j]; } else res += val; } break; case STAT_OPERATOR._average : if(array_length(inputs) <= input_fix_len + 1) { res = 0; break; } var amo = 0; for( var i = input_fix_len; i < array_length(inputs); i++ ) { var val = getInputData(i); if(is_array(val)) { for( var j = 0; j < array_length(val); j++ ) { res += val[j]; amo++; } } else { res += val; amo++; } } res /= amo; break; case STAT_OPERATOR._median : if(array_length(inputs) - input_fix_len == 0) { res = 0; break; } var vals = []; var amo = 0; for( var i = input_fix_len; i < array_length(inputs); i++ ) { var val = getInputData(i); if(is_array(val)) { for( var j = 0; j < array_length(val); j++ ) { array_push(vals, val[j]); amo++; } } else { array_push(vals, val); amo++; } } if(amo == 1) { res = vals[0]; break; } array_sort(vals, true); if(amo % 2 == 0) res = (vals[amo / 2 - 1] + vals[amo / 2]) / 2; else res = vals[(amo - 1) / 2]; break; case STAT_OPERATOR._min : var _min = 9999999999; for( var i = input_fix_len; i < array_length(inputs); i++ ) { var val = getInputData(i); if(is_array(val)) { for( var j = 0; j < array_length(val); j++ ) _min = min(_min, val[j]); } else _min = min(_min, val); } res = _min; break; case STAT_OPERATOR._max : var _max = -9999999999; for( var i = input_fix_len; i < array_length(inputs); i++ ) { var val = getInputData(i); if(is_array(val)) { for( var j = 0; j < array_length(val); j++ ) _max = max(_max, val[j]); } else _max = max(_max, val); } res = _max; break; } outputs[0].setValue(res); } #endregion static onDrawNode = function(xx, yy, _mx, _my, _s, _hover, _focus) { #region draw_set_text(f_sdf, fa_center, fa_center, COLORS._main_text); var str = ""; switch(getInputData(0)) { case STAT_OPERATOR._average : str = "Avg"; break; case STAT_OPERATOR._sum : str = "Sum"; break; case STAT_OPERATOR._median : str = "Med"; break; case STAT_OPERATOR._min : str = "Min"; break; case STAT_OPERATOR._max : str = "Max"; break; } var bbox = drawGetBbox(xx, yy, _s); var ss = string_scale(str, bbox.w, bbox.h); draw_text_transformed(bbox.xc, bbox.yc, str, ss, ss, 0); } #endregion }