Добавлена логика для отображения стрелок и раскраски | Изменена ширина первого столбца таблицы

This commit is contained in:
ARLakhin
2026-04-21 00:30:22 +03:00
parent bc095da738
commit e54299c13b
4 changed files with 137 additions and 7 deletions
+2 -1
View File
@@ -22,4 +22,5 @@
@use "application_settings"; @use "application_settings";
@use "main"; @use "main";
@use "header"; @use "header";
@use "nav"; @use "nav";
@use "organisation";
+4
View File
@@ -81,6 +81,10 @@ a.link:hover {
border: 3px solid black; border: 3px solid black;
} }
.information-table tr :is(td, th):first-child {
width: 35%;
}
.type_doc_header#tabs { .type_doc_header#tabs {
width: 75%; width: 75%;
margin: 0 auto; margin: 0 auto;
+115
View File
@@ -1,2 +1,117 @@
module OrganisationsHelper module OrganisationsHelper
# Функции для раскраски
def group_key(code)
return nil if code.nil? || code.size < 2
prefix = code[0, 2]
case prefix
when '21', '22', '23', '24'
'21-24'
else
prefix
end
end
def keep_code?(code, type_data: 'min_max')
return false if code.nil? || code.size < 2
prefix = code[0, 2]
return false unless prefix.match?(/\A\d{2}\z/)
if type_data == 'min_max'
return false if %w[16 17].include?(prefix)
return true if %w[21 22 23 24 25 29].include?(prefix)
return !code.end_with?('00')
elsif type_data == 'comparsion'
return code.end_with?('00')
end
end
def parse_number(value)
return 0 if value.empty? || ['-', '(-)', 'X'].include?(value)
negative = value.start_with?('(') && value.end_with?(')')
value = value.tr('()', '') if negative
value = value.delete(' ')
return 0 unless value.match?(/\A\d+\z/)
number = value.to_i
negative ? -number : number
end
def prepare_data(data, type_data: 'min_max')
return {} if data.nil?
filtered_data = data.reject do |(_, _), values|
values.all? { |value| ['-', '(-)', 'X'].include?(value) }
end
if type_data == 'min_max'
prepared_data = filtered_data.each_with_object({}) do |((_, code), values), result|
next if code.nil? || !keep_code?(code)
group = group_key(code)
result[group] ||= Hash.new { |h, k| h[k] = [] }
values.each_with_index do |value, index|
result[group][index + 1] << parse_number(value)
end
end
min_max_data = prepared_data.transform_values do |columns|
columns.transform_values do |values|
sorted = values.sort
size = sorted.size
p50 = size.odd? ? sorted[size / 2] : (sorted[size / 2 - 1] + sorted[size / 2]) / 2.0
{ min: sorted.first, p50: p50, max: sorted.last }
end
end
elsif type_data == 'comparsion'
prepared_data = filtered_data.each_with_object({}) do |((_, code), values), result|
next if code.nil? || !keep_code?(code, type_data: 'comparsion')
result[code] ||= []
(0...values.size - 1).each do |index|
if parse_number(values[index]) == parse_number(values[index + 1])
result[code] << nil
elsif
result[code] << (parse_number(values[index]) > parse_number(values[index + 1]))
end
end
result[code] << nil
end
end
end
def get_color_for_cell(value, min:, median:, max:)
value = parse_number(value)
return rgb_to_hex(WHITE) if value.nil? || min.nil? || max.nil? || median.nil?
return rgb_to_hex(GREEN) if min == max
if value <= median
ratio = median == min ? 0.0 : (value - min).to_f / (median - min)
rgb = interpolate_color(RED, YELLOW, clamp(ratio))
else
ratio = max == median ? 0.0 : (value - median).to_f / (max - median)
rgb = interpolate_color(YELLOW, GREEN, clamp(ratio))
end
rgb_to_hex(rgb)
end
def get_arrow_for_cell(value, condition)
return content_tag(:td, value) if condition.nil?
css_class = condition ? 'up': 'down'
content_tag(:td, value, class: css_class)
end
private
def interpolate_color(from, to, ratio)
from.zip(to).map { |a, b| (a + (b - a) * ratio).round }
end
def rgb_to_hex(rgb)
format("#%02X%02X%02X", *rgb)
end
def clamp(value)
[[value, 0.0].max, 1.0].min
end
RED = [248, 105, 107].freeze
YELLOW = [255, 235, 132].freeze
GREEN = [99, 190, 123].freeze
WHITE = [255, 255, 255].freeze
end end
+16 -6
View File
@@ -5,6 +5,8 @@
- unless @info_about_organisation.any? - unless @info_about_organisation.any?
= 'У данной организации пока не загружена отчетность' = 'У данной организации пока не загружена отчетность'
- else - else
- min_max_data = prepare_data(@current_doc_info1)
- comparsion_data = prepare_data(@current_doc_info1, type_data: 'comparsion')
.informations-data .informations-data
h2 h2
= "Сведения об организации" = "Сведения об организации"
@@ -27,10 +29,18 @@
tr tr
td = key[0] td = key[0]
td = key[1] td = key[1]
- @current_doc_info1[key].each do |value| - @current_doc_info1[key].each_with_index do |value, index|
td = value - key_group = key[1].nil? ? nil : group_key(key[1])
- if min_max_data.has_key?(key_group) && keep_code?(key[1])
- min_value = min_max_data[key_group][index + 1][:min]
- max_value = min_max_data[key_group][index + 1][:max]
- p50 = min_max_data[key_group][index + 1][:p50]
- color = get_color_for_cell(value, min: min_value, median: p50, max: max_value)
td style="background-color: #{color}" = value
- elsif comparsion_data.has_key?(key[1]) && keep_code?(key[1], type_data: 'comparsion')
- condition = comparsion_data[key[1]][index]
= get_arrow_for_cell(value, condition)
- else
td = value
- else - else
h3 h3 = "Нет данных"
= "Нет данных"