diff --git a/cgi/search.pl b/cgi/search.pl
index 3d3294167add9..c393ab001e658 100755
--- a/cgi/search.pl
+++ b/cgi/search.pl
@@ -94,7 +94,8 @@
}
my @search_fields
- = qw(brands categories packaging labels origins manufacturing_places emb_codes purchase_places stores countries ingredients additives allergens traces nutrition_grades nova_groups languages creator editors states);
+ = qw(brands categories packaging labels origins manufacturing_places emb_codes purchase_places stores countries
+ ingredients additives allergens traces nutrition_grades nova_groups ecoscore languages creator editors states);
$admin and push @search_fields, "lang";
@@ -109,6 +110,8 @@
allergens => 1,
traces => 1,
nutrition_grades => 1,
+ nova_groups => 1,
+ eco_score => 1,
purchase_places => 1,
stores => 1,
countries => 1,
@@ -322,16 +325,28 @@
$axis_labels{$nid} = display_taxonomy_tag($lc, "nutrients", "zz:$nid");
$log->debug("nutriments", {nid => $nid, value => $axis_labels{$nid}}) if $log->is_debug();
}
- push @axis_values, "additives_n", "ingredients_n", "known_ingredients_n", "unknown_ingredients_n";
- push @axis_values, "fruits-vegetables-nuts-estimate-from-ingredients";
- push @axis_values, "forest_footprint";
- $axis_labels{additives_n} = lang("number_of_additives");
- $axis_labels{ingredients_n} = lang("ingredients_n_s");
- $axis_labels{known_ingredients_n} = lang("known_ingredients_n_s");
- $axis_labels{unknown_ingredients_n} = lang("unknown_ingredients_n_s");
+
+ my @other_search_fields = (
+ "additives_n", "ingredients_n", "known_ingredients_n", "unknown_ingredients_n",
+ "fruits-vegetables-nuts-estimate-from-ingredients",
+ "forest_footprint", "product_quantity", "nova_group", 'ecoscore_score',
+ );
+
+ # Add the fields related to packaging
+ foreach my $material ("all", "en:plastic", "en:glass", "en:metal", "en:paper-or-cardboard", "en:unknown") {
+ foreach my $subfield ("weight", "weight_100g", "weight_percent") {
+ push @other_search_fields, "packagings_materials.$material.$subfield";
+ }
+ }
+
$axis_labels{search_nutriment} = lang("search_nutriment");
$axis_labels{products_n} = lang("number_of_products");
- $axis_labels{forest_footprint} = lang("forest_footprint");
+
+ foreach my $field (@other_search_fields) {
+ my ($title, $unit, $unit2, $allow_decimals) = get_search_field_title_and_details($field);
+ push @axis_values, $field;
+ $axis_labels{$field} = $title;
+ }
my @sorted_axis_values = ("", sort({lc($axis_labels{$a}) cmp lc($axis_labels{$b})} @axis_values));
@@ -738,13 +753,13 @@
# We want existing values for axis fields
foreach my $axis ('x', 'y') {
- if ( ($graph_ref->{"axis_$axis"} ne "")
- and ($graph_ref->{"axis_$axis"} ne "forest_footprint")
- and ($graph_ref->{"axis_$axis"} !~ /_n$/))
- {
- (defined $query_ref->{"nutriments." . $graph_ref->{"axis_$axis"} . "_100g"})
- or $query_ref->{"nutriments." . $graph_ref->{"axis_$axis"} . "_100g"} = {};
- $query_ref->{"nutriments." . $graph_ref->{"axis_$axis"} . "_100g"}{'$exists'} = 1;
+
+ if ($graph_ref->{"axis_$axis"} ne "") {
+ my $field = $graph_ref->{"axis_$axis"};
+ # Get the field path components
+ my @fields = get_search_field_path_components($field);
+ # Convert to dot notation to get the MongoDB field
+ $query_ref->{join(".", @fields)} = {'$exists' => 1};
}
}
diff --git a/lib/ProductOpener/Display.pm b/lib/ProductOpener/Display.pm
index 46aac7b8e75d1..6bc6ed536fc2a 100644
--- a/lib/ProductOpener/Display.pm
+++ b/lib/ProductOpener/Display.pm
@@ -76,6 +76,8 @@ BEGIN {
&display_product_history
&display_preferences_api
&display_attribute_groups_api
+ &get_search_field_path_components
+ &get_search_field_title_and_details
&search_and_display_products
&search_and_export_products
&search_and_graph_products
@@ -5802,63 +5804,150 @@ my %nutrition_grades_colors = (
unknown => {r => 128, g => 128, b => 128},
);
-sub display_scatter_plot ($graph_ref, $products_ref) {
+# Return the path (list of nodes) to the search field
- my @products = @{$products_ref};
- my $count = @products;
+# field name from the search form
+# it can be:
+# - a nutrient id like "saturated-fat"
+# - a direct field like ingredients_n
+# - an indirect field like packagings_materials.all.weight_100g
- my $html = '';
+sub get_search_field_path_components ($field) {
+ my @fields;
+ # direct fields
+ if (($field =~ /_n$/) or ($field eq "product_quantity") or ($field eq "nova_group") or ($field eq "ecoscore_score"))
+ {
+ @fields = ($field);
+ }
+ # indirect fields separated with the . character
+ elsif ($field =~ /\./) {
+ @fields = split(/\./, $field);
+ }
+ # forest footprint
+ elsif ($field eq "forest_footprint") {
+ @fields = ('forest_footprint_data', 'footprint_per_kg');
+ }
+ # we assume other fields are nutrients ids
+ else {
+ @fields = ("nutriments", $field . "_100g");
+ }
+ return @fields;
+}
+
+sub get_search_field_title_and_details ($field) {
- my $x_allowDecimals = '';
- my $y_allowDecimals = '';
- my $x_title;
- my $y_title;
- my $x_unit = '';
- my $y_unit = '';
- my $x_unit2 = '';
- my $y_unit2 = '';
+ my ($title, $unit, $unit2, $allow_decimals) = ('', '', '', '');
- if ($graph_ref->{axis_x} eq 'additives_n') {
- $x_allowDecimals = "allowDecimals:false,\n";
- $x_title = escape_single_quote(lang("number_of_additives"));
+ if ($field eq 'additives_n') {
+ $allow_decimals = "allowDecimals:false,\n";
+ $title = escape_single_quote(lang("number_of_additives"));
}
- elsif ($graph_ref->{axis_x} eq "forest_footprint") {
- $x_allowDecimals = "allowDecimals:true,\n";
- $x_title = escape_single_quote(lang($graph_ref->{axis_x}));
+ elsif ($field eq "forest_footprint") {
+ $allow_decimals = "allowDecimals:true,\n";
+ $title = escape_single_quote(lang($field));
}
- elsif ($graph_ref->{axis_x} =~ /ingredients_n/) {
- $x_allowDecimals = "allowDecimals:false,\n";
- $x_title = escape_single_quote(lang($graph_ref->{axis_x} . "_s"));
+ elsif ($field =~ /_n$/) {
+ $allow_decimals = "allowDecimals:false,\n";
+ $title = escape_single_quote(lang($field . "_s"));
}
- else {
- $x_title = display_taxonomy_tag($lc, "nutrients", "zz:" . $graph_ref->{axis_x});
- $x_unit
- = " ("
- . (get_property("nutrients", "zz:" . $graph_ref->{axis_x}, "unit:en") // 'g') . " "
- . lang("nutrition_data_per_100g") . ")";
- $x_unit =~ s/\ / /g;
- $x_unit2 = display_taxonomy_tag($lc, "nutrients", "zz:" . $graph_ref->{axis_x});
+ elsif ($field eq "product_quantity") {
+ $allow_decimals = "allowDecimals:false,\n";
+ $title = escape_single_quote(lang("quantity"));
+ $unit = ' (g)';
+ $unit2 = 'g';
}
- if ($graph_ref->{axis_y} eq 'additives_n') {
- $y_allowDecimals = "allowDecimals:false,\n";
- $y_title = escape_single_quote(lang("number_of_additives"));
+ elsif ($field eq "nova_group") {
+ $allow_decimals = "allowDecimals:false,\n";
+ $title = escape_single_quote(lang("nova_groups_s"));
}
- elsif ($graph_ref->{axis_y} eq "forest_footprint") {
- $y_allowDecimals = "allowDecimals:true,\n";
- $y_title = escape_single_quote(lang($graph_ref->{axis_y}));
+ elsif ($field eq "ecoscore_score") {
+ $allow_decimals = "allowDecimals:false,\n";
+ $title = escape_single_quote(lang("ecoscore_score"));
}
- elsif ($graph_ref->{axis_y} =~ /ingredients_n/) {
- $y_allowDecimals = "allowDecimals:false,\n";
- $y_title = escape_single_quote(lang($graph_ref->{axis_y} . "_s"));
+ elsif ($field =~ /^packagings_materials\.([^.]+)\.([^.]+)$/) {
+ my $material = $1;
+ my $subfield = $2;
+ $title = lang("packaging") . " - ";
+ if ($material eq "all") {
+ $title .= lang("packagings_materials_all");
+ }
+ else {
+ $title .= display_taxonomy_tag($lc, "packaging_materials", $material);
+ }
+ $title .= ' - ' . lang($subfield);
+ if ($subfield =~ /_percent$/) {
+ $unit = ' %';
+ $unit2 = '%';
+ }
+ elsif ($subfield =~ /_100g$/) {
+ $unit = ' (g/100g)';
+ $unit2 = 'g/100g';
+ }
+ else {
+ $unit = ' (g)';
+ $unit2 = 'g';
+ }
}
else {
- $y_title = display_taxonomy_tag($lc, "nutrients", "zz:" . $graph_ref->{axis_y});
- $y_unit
+ $title = display_taxonomy_tag($lc, "nutrients", "zz:" . $field);
+ $unit2 = $title; # displayed in the tooltip
+ $unit
= " ("
- . (get_property("nutrients", "zz:" . $graph_ref->{axis_y}, "unit:en") // 'g') . " "
+ . (get_property("nutrients", "zz:" . $field, "unit:en") // 'g') . " "
. lang("nutrition_data_per_100g") . ")";
- $y_unit =~ s/\ / /g;
- $y_unit2 = display_taxonomy_tag($lc, "nutrients", "zz:" . $graph_ref->{axis_y});
+ $unit =~ s/\ / /g;
+ }
+
+ return ($title, $unit, $unit2, $allow_decimals);
+}
+
+=head2 display_scatter_plot ($graph_ref, $products_ref)
+
+Called by search_and_graph_products() to display a scatter plot of products on 2 axis
+
+=head3 Arguments
+
+=head4 $graph_ref
+
+Options for the graph, set by /cgi/search.pl
+
+=head4 $products_ref
+
+List of search results from search_and_graph_products()
+
+=cut
+
+sub display_scatter_plot ($graph_ref, $products_ref) {
+
+ my @products = @{$products_ref};
+ my $count = scalar @products;
+
+ my $html = '';
+
+ my %axis_details = ();
+ my %min = (); # Minimum for the axis, 0 except -15 for Nutri-Score score
+ my %fields = (); # fields path components for each axis, to use with deep_get()
+
+ foreach my $axis ("x", "y") {
+ # Set the titles and details of each axis
+ my $field = $graph_ref->{"axis_" . $axis};
+ my ($title, $unit, $unit2, $allow_decimals) = get_search_field_title_and_details($field);
+ $axis_details{$axis} = {
+ title => $title,
+ unit => $unit,
+ unit2 => $unit2,
+ allow_decimals => $allow_decimals,
+ };
+
+ # Set the minimum value for the axis (0 in most cases, except for Nutri-Score)
+ $min{$axis} = 0;
+
+ if ($field =~ /^nutrition-score/) {
+ $min{$axis} = -15;
+ }
+
+ # Store the field path components
+ $fields{$field} = [get_search_field_path_components($field)];
}
my %nutriments = ();
@@ -5867,122 +5956,100 @@ sub display_scatter_plot ($graph_ref, $products_ref) {
my %series = ();
my %series_n = ();
- my %min = (); # Minimum for the axis, 0 except -15 for Nutri-Score score
foreach my $product_ref (@products) {
- # Keep only products that have known values for both x and y
+ # Gather the data for the 2 axis
- if (
- (
- (
- (($graph_ref->{axis_x} eq 'additives_n') or ($graph_ref->{axis_x} =~ /ingredients_n$/))
- and (defined $product_ref->{$graph_ref->{axis_x}})
- )
- or (($graph_ref->{axis_x} eq 'forest_footprint') and (defined $product_ref->{forest_footprint_data}))
- or (defined $product_ref->{nutriments}{$graph_ref->{axis_x} . "_100g"})
- and ($product_ref->{nutriments}{$graph_ref->{axis_x} . "_100g"} ne '')
- )
- and (
- (
- (($graph_ref->{axis_y} eq 'additives_n') or ($graph_ref->{axis_y} =~ /ingredients_n$/))
- and (defined $product_ref->{$graph_ref->{axis_y}})
- )
- or (($graph_ref->{axis_y} eq 'forest_footprint') and (defined $product_ref->{forest_footprint_data}))
- or (defined $product_ref->{nutriments}{$graph_ref->{axis_y} . "_100g"})
- and ($product_ref->{nutriments}{$graph_ref->{axis_y} . "_100g"} ne '')
- )
- )
- {
+ my %data;
- my $url = $formatted_subdomain . product_url($product_ref->{code});
+ foreach my $axis ('x', 'y') {
- # Identify the series id
- my $seriesid = 0;
- my $s = 1000000;
+ my $field = $graph_ref->{"axis_" . $axis};
+ my $value = deep_get($product_ref, @{$fields{$field}});
- # default, organic, fairtrade, with_sweeteners
- # order: organic, organic+fairtrade, organic+fairtrade+sweeteners, organic+sweeteners, fairtrade, fairtrade + sweeteners
- #
+ # For nutrients except energy-kcal, convert to the default nutrient unit
+ if ((defined $value) and ($fields{$field}[0] eq "nutriments") and ($field !~ /energy-kcal/)) {
+ $value = g_to_unit($value, (get_property("nutrients", "zz:$field", "unit:en") // 'g'));
+ }
- # Colors for nutrition grades
- if ($graph_ref->{"series_nutrition_grades"}) {
- if (defined $product_ref->{"nutrition_grade_fr"}) {
- $seriesid = $product_ref->{"nutrition_grade_fr"};
- }
- else {
- $seriesid = 'unknown';
- }
+ if (defined $value) {
+ $value = $value + 0; # Make sure the value is a number
}
- else {
- # Colors for labels and labels combinations
- foreach my $series (@search_series) {
- # Label?
- if ($graph_ref->{"series_$series"}) {
- if (defined lang("search_series_${series}_label")) {
- if (has_tag($product_ref, "labels", 'en:' . lc($Lang{"search_series_${series}_label"}{en})))
- {
- $seriesid += $s;
- }
- else {
- }
- }
- if ($product_ref->{$series}) {
+ $data{$axis} = $value;
+ }
+
+ # Keep only products that have known values for both x and y
+ if ((not defined $data{x}) or (not defined $data{y})) {
+ $log->debug("Skipping product with unknown values ", {data => \%data}) if $log->is_debug();
+ next;
+ }
+
+ # Add values to stats, and set min axis
+ foreach my $axis ('x', 'y') {
+ my $field = $graph_ref->{"axis_" . $axis};
+ add_product_nutriment_to_stats(\%nutriments, $field, $data{$axis});
+ }
+
+ # Identify the series id
+ my $seriesid = 0;
+ # series value, we start high for first series
+ # and second series value will have s / 10, etc.
+ my $s = 1000000;
+
+ # default, organic, fairtrade, with_sweeteners
+ # order: organic, organic+fairtrade, organic+fairtrade+sweeteners, organic+sweeteners, fairtrade, fairtrade + sweeteners
+ #
+
+ # Colors for nutrition grades
+ if ($graph_ref->{"series_nutrition_grades"}) {
+ if (defined $product_ref->{"nutrition_grade_fr"}) {
+ $seriesid = $product_ref->{"nutrition_grade_fr"};
+ }
+ else {
+ $seriesid = 'unknown';
+ }
+ }
+ else {
+ # Colors for labels and labels combinations
+ foreach my $series (@search_series) {
+ # Label?
+ if ($graph_ref->{"series_$series"}) {
+ if (defined lang("search_series_${series}_label")) {
+ if (has_tag($product_ref, "labels", 'en:' . lc($Lang{"search_series_${series}_label"}{en}))) {
$seriesid += $s;
}
+ else {
+ }
}
- if (($series eq 'default') and ($seriesid == 0)) {
+ if ($product_ref->{$series}) {
$seriesid += $s;
}
- $s = $s / 10;
}
- }
- defined $series{$seriesid} or $series{$seriesid} = '';
-
- # print STDERR "Display::search_and_graph_products: i: $i - axis_x: $graph_ref->{axis_x} - axis_y: $graph_ref->{axis_y}\n";
-
- my %data;
-
- foreach my $axis ('x', 'y') {
- my $nid = $graph_ref->{"axis_" . $axis};
+ if (($series eq 'default') and ($seriesid == 0)) {
+ $seriesid += $s;
+ }
+ $s = $s / 10;
+ }
+ }
- $min{$axis} = 0;
+ $series{$seriesid} = $series{$seriesid} // '';
- # number of ingredients, additives etc. (ingredients_n)
- if ($nid =~ /_n$/) {
- $data{$axis} = $product_ref->{$nid};
- }
- elsif ($nid eq "forest_footprint") {
- $data{$axis} = $product_ref->{forest_footprint_data}{footprint_per_kg};
- }
- # energy-kcal is already in kcal
- elsif ($nid eq 'energy-kcal') {
- $data{$axis} = $product_ref->{nutriments}{"${nid}_100g"};
- }
- elsif ($nid =~ /^nutrition-score/) {
- $data{$axis} = $product_ref->{nutriments}{"${nid}_100g"};
- $min{$axis} = -15;
- }
- else {
- $data{$axis} = g_to_unit($product_ref->{nutriments}{"${nid}_100g"},
- (get_property("nutrients", "zz:$nid", "unit:en") // 'g'));
- }
+ $data{product_name} = $product_ref->{product_name};
+ $data{url} = $formatted_subdomain . product_url($product_ref->{code});
+ $data{img} = display_image_thumb($product_ref, 'front');
- add_product_nutriment_to_stats(\%nutriments, $nid, $product_ref->{nutriments}{"${nid}_100g"});
- }
- $data{product_name} = $product_ref->{product_name};
- $data{url} = $url;
- $data{img} = display_image_thumb($product_ref, 'front');
+ # create data entry for series
+ defined $series{$seriesid} or $series{$seriesid} = '';
+ $series{$seriesid} .= JSON::PP->new->encode(\%data) . ',';
+ # count entries / series
+ defined $series_n{$seriesid} or $series_n{$seriesid} = 0;
+ $series_n{$seriesid}++;
+ $i++;
- defined $series{$seriesid} or $series{$seriesid} = '';
- $series{$seriesid} .= JSON::PP->new->encode(\%data) . ',';
- defined $series_n{$seriesid} or $series_n{$seriesid} = 0;
- $series_n{$seriesid}++;
- $i++;
- }
}
my $series_data = '';
@@ -6102,21 +6169,21 @@ JS
text: '$Lang{data_source}{$lc}$sep: $formatted_subdomain'
},
xAxis: {
- $x_allowDecimals
+ $axis_details{x}{allow_decimals}
min:$min{x},
title: {
enabled: true,
- text: '${x_title}${x_unit}'
+ text: '$axis_details{x}{title}$axis_details{x}{unit}'
},
startOnTick: true,
endOnTick: true,
showLastLabel: true
},
yAxis: {
- $y_allowDecimals
+ $axis_details{y}{allow_decimals}
min:$min{y},
title: {
- text: '${y_title}${y_unit}'
+ text: '$axis_details{y}{title}$axis_details{y}{unit}'
}
},
tooltip: {
@@ -6127,8 +6194,8 @@ JS
return '' + this.point.product_name + '
'
+ this.point.img + '
'
+ '$Lang{nutrition_data_per_100g}{$lc} :'
- + '
$x_title$sep: '+ this.x + ' $x_unit2'
- + '
$y_title$sep: ' + this.y + ' $y_unit2';
+ + '
$axis_details{x}{title}$sep: '+ this.x + ' $axis_details{x}{unit2}'
+ + '
$axis_details{y}{title}$sep: ' + this.y + ' $axis_details{y}{unit2}';
}
},
@@ -6190,6 +6257,22 @@ HTML
}
+=head2 display_histogram ($graph_ref, $products_ref)
+
+Called by search_and_graph_products() to display an histogram of products on 1 axis
+
+=head3 Arguments
+
+=head4 $graph_ref
+
+Options for the graph, set by /cgi/search.pl
+
+=head4 $products_ref
+
+List of search results from search_and_graph_products()
+
+=cut
+
sub display_histogram ($graph_ref, $products_ref) {
my @products = @{$products_ref};
@@ -6197,41 +6280,34 @@ sub display_histogram ($graph_ref, $products_ref) {
my $html = '';
- my $x_allowDecimals = '';
- my $y_allowDecimals = '';
- my $x_title;
- my $y_title;
- my $x_unit = '';
- my $y_unit = '';
- my $x_unit2 = '';
- my $y_unit2 = '';
+ my %axis_details = ();
+ my %min = (); # Minimum for the axis, 0 except -15 for Nutri-Score score
- if ($graph_ref->{axis_x} eq 'additives_n') {
- $x_allowDecimals = "allowDecimals:false,\n";
- $x_title = escape_single_quote(lang("number_of_additives"));
- }
- elsif ($graph_ref->{axis_x} eq "forest_footprint") {
- $x_allowDecimals = "allowDecimals:true,\n";
- $x_title = escape_single_quote(lang($graph_ref->{axis_x}));
- }
- elsif ($graph_ref->{axis_x} =~ /ingredients_n$/) {
- $x_allowDecimals = "allowDecimals:false,\n";
- $x_title = escape_single_quote(lang($graph_ref->{axis_x} . "_s"));
- }
- else {
- $x_title = display_taxonomy_tag($lc, "nutrients", "zz:" . $graph_ref->{axis_x});
- $x_unit
- = " ("
- . (get_property("nutrients", "zz:" . $graph_ref->{axis_x}, "unit:en") // 'g') . " "
- . lang("nutrition_data_per_100g") . ")";
- $x_unit =~ s/\ / /g;
- $x_unit2 = (get_property("nutrients", "zz:" . $graph_ref->{axis_x}, "unit:en") // 'g');
- }
+ foreach my $axis ("x") {
+ # Set the titles and details of each axis
+ my $field = $graph_ref->{"axis_" . $axis};
+ my ($title, $unit, $unit2, $allow_decimals) = get_search_field_title_and_details($field);
+ $axis_details{$axis} = {
+ title => $title,
+ unit => $unit,
+ unit2 => $unit2,
+ allow_decimals => $allow_decimals,
+ };
- $y_allowDecimals = "allowDecimals:false,\n";
- $y_title = escape_single_quote(lang("number_of_products"));
+ # Set the minimum value for the axis (0 in most cases, except for Nutri-Score)
+ $min{$axis} = 0;
+
+ if ($field =~ /^nutrition-score/) {
+ $min{$axis} = -15;
+ }
+ }
- my $nid = $graph_ref->{"axis_x"};
+ $axis_details{"y"} = {
+ title => escape_single_quote(lang("number_of_products")),
+ allow_decimals => "allowDecimals:false,\n",
+ unit => '',
+ unit2 => '',
+ };
my $i = 0;
@@ -6242,92 +6318,71 @@ sub display_histogram ($graph_ref, $products_ref) {
my $min = 10000000000000;
my $max = -10000000000000;
+ my $field = $graph_ref->{"axis_x"};
+ my @fields = get_search_field_path_components($field);
+
foreach my $product_ref (@products) {
- # Keep only products that have known values for x
+ my $value = deep_get($product_ref, @fields);
- if (
- (
- (
- (($graph_ref->{axis_x} eq 'additives_n') or ($graph_ref->{axis_x} =~ /ingredients_n$/))
- and (defined $product_ref->{$graph_ref->{axis_x}})
- )
- or (($graph_ref->{axis_x} eq 'forest_footprint') and (defined $product_ref->{forest_footprint_data}))
- or (defined $product_ref->{nutriments}{$graph_ref->{axis_x} . "_100g"})
- and ($product_ref->{nutriments}{$graph_ref->{axis_x} . "_100g"} ne '')
- )
- )
- {
+ # For nutrients except energy-kcal, convert to the default nutrient unit
+ if ((defined $value) and ($fields[0] eq "nutriments") and ($field !~ /energy-kcal/)) {
+ $value = g_to_unit($value, (get_property("nutrients", "zz:$field", "unit:en") // 'g'));
+ }
- # Identify the series id
- my $seriesid = 0;
- my $s = 1000000;
+ # Keep only products that have known values for both x and y
+ if (not defined $value) {
+ next;
+ }
- # default, organic, fairtrade, with_sweeteners
- # order: organic, organic+fairtrade, organic+fairtrade+sweeteners, organic+sweeteners, fairtrade, fairtrade + sweeteners
- #
+ $value = $value + 0; # Make sure the value is a number
- foreach my $series (@search_series) {
- # Label?
- if ($graph_ref->{"series_$series"}) {
- if (defined lang("search_series_${series}_label")) {
- if (has_tag($product_ref, "labels", 'en:' . lc($Lang{"search_series_${series}_label"}{en}))) {
- $seriesid += $s;
- }
- else {
- }
- }
+ if ($value < $min) {
+ $min = $value;
+ }
+ if ($value > $max) {
+ $max = $value;
+ }
- if ($product_ref->{$series}) {
+ # Identify the series id
+ my $seriesid = 0;
+ my $s = 1000000;
+
+ # default, organic, fairtrade, with_sweeteners
+ # order: organic, organic+fairtrade, organic+fairtrade+sweeteners, organic+sweeteners, fairtrade, fairtrade + sweeteners
+ #
+
+ foreach my $series (@search_series) {
+ # Label?
+ if ($graph_ref->{"series_$series"}) {
+ if (defined lang("search_series_${series}_label")) {
+ if (has_tag($product_ref, "labels", 'en:' . lc($Lang{"search_series_${series}_label"}{en}))) {
$seriesid += $s;
}
+ else {
+ }
}
- if (($series eq 'default') and ($seriesid == 0)) {
+ if ($product_ref->{$series}) {
$seriesid += $s;
}
- $s = $s / 10;
}
- # print STDERR "Display::search_and_graph_products: i: $i - axis_x: $graph_ref->{axis_x} - axis_y: $graph_ref->{axis_y}\n";
-
- my $value = 0;
-
- # number of ingredients, additives etc. (ingredients_n)
- if ($nid =~ /_n$/) {
- $value = $product_ref->{$nid};
- }
- elsif ($nid eq "forest_footprint") {
- $value = $product_ref->{forest_footprint_data}{footprint_per_kg};
- }
- # energy-kcal is already in kcal
- elsif ($nid eq 'energy-kcal') {
- $value = $product_ref->{nutriments}{"${nid}_100g"};
- }
- elsif ($nid =~ /^nutrition-score/) {
- $value = $product_ref->{nutriments}{"${nid}_100g"};
- }
- else {
- $value = g_to_unit($product_ref->{nutriments}{"${nid}_100g"},
- (get_property("nutrients", "zz:$nid", "unit:en") // 'g'));
+ if (($series eq 'default') and ($seriesid == 0)) {
+ $seriesid += $s;
}
+ $s = $s / 10;
+ }
- if ($value < $min) {
- $min = $value;
- }
- if ($value > $max) {
- $max = $value;
- }
+ push @all_values, $value;
- push @all_values, $value;
+ defined $series{$seriesid} or $series{$seriesid} = [];
+ push @{$series{$seriesid}}, $value;
- defined $series{$seriesid} or $series{$seriesid} = [];
- push @{$series{$seriesid}}, $value;
+ defined $series_n{$seriesid} or $series_n{$seriesid} = 0;
+ $series_n{$seriesid}++;
+ $i++;
- defined $series_n{$seriesid} or $series_n{$seriesid} = 0;
- $series_n{$seriesid}++;
- $i++;
- }
}
# define intervals
@@ -6349,7 +6404,7 @@ sub display_histogram ($graph_ref, $products_ref) {
push @intervals, [$min, $max, "$min"];
}
else {
- if (($nid =~ /_n$/) or ($nid =~ /^nutrition-score/)) {
+ if (($field =~ /_n$/) or ($field =~ /^nutrition-score/)) {
$interval = 1;
$intervals = 0;
for (my $j = $min; $j <= $max; $j++) {
@@ -6486,7 +6541,7 @@ JS
xAxis: {
title: {
enabled: true,
- text: '${x_title}${x_unit}'
+ text: '$axis_details{x}{title}$axis_details{x}{unit}'
},
categories: [
$categories
@@ -6494,10 +6549,10 @@ JS
},
yAxis: {
- $y_allowDecimals
+ $axis_details{y}{allow_decimals}
min:0,
title: {
- text: '${y_title}${y_unit}'
+ text: '$axis_details{y}{title}'
},
stackLabels: {
enabled: true,
@@ -6508,14 +6563,14 @@ JS
}
},
tooltip: {
- headerFormat: '${x_title} {point.key}
${x_unit}
',
+ headerFormat: '$axis_details{x}{title} {point.key}
$axis_details{x}{unit}',
pointFormat: '{series.name}: | ' +
'{point.y} |
',
footerFormat: '
Total: {point.total}',
shared: true,
useHTML: true,
formatter: function() {
- var points='${x_title} ' + this.x + '
${x_unit}';
+ var points='$axis_details{x}{title} ' + this.x + '
$axis_details{x}{unit}';
//loop each point in this.points
\$.each(this.points,function(i,point){
points+=''+point.series.name+': | '
@@ -6607,18 +6662,13 @@ sub search_and_graph_products ($request_ref, $query_ref, $graph_ref) {
}
}
+ # Add fields for the axis
foreach my $axis ('x', 'y') {
- if ($graph_ref->{"axis_$axis"} ne "products_n") {
- if ($graph_ref->{"axis_$axis"} eq "forest_footprint") {
- $fields_ref->{"forest_footprint_data.footprint_per_kg"} = 1;
- }
- elsif ($graph_ref->{"axis_$axis"} =~ /_n$/) {
- $fields_ref->{$graph_ref->{"axis_$axis"}} = 1;
- }
- else {
- $fields_ref->{"nutriments." . $graph_ref->{"axis_$axis"} . "_100g"} = 1;
- }
- }
+ my $field = $graph_ref->{"axis_$axis"};
+ # Get the field path components
+ my @fields = get_search_field_path_components($field);
+ # Convert to dot notation to get the MongoDB field
+ $fields_ref->{join(".", @fields)} = 1;
}
if ($graph_ref->{"series_nutrition_grades"}) {
diff --git a/po/common/common.pot b/po/common/common.pot
index b8ea301eee0b4..f192cf5de7cfe 100644
--- a/po/common/common.pot
+++ b/po/common/common.pot
@@ -6591,3 +6591,26 @@ msgctxt "relative_to_all_products"
msgid "relative to all products"
msgstr "relative to all products"
+msgctxt "packagings_n_p"
+msgid "Numbers of packaging components"
+msgstr "Numbers of packaging components"
+
+msgctxt "packagings_n_s"
+msgid "Number of packaging components"
+msgstr "Number of packaging components"
+
+msgctxt "packagings_materials_all"
+msgid "All materials"
+msgstr "All materials"
+
+msgctxt "weight"
+msgid "Weight"
+msgstr "Weight"
+
+msgctxt "weight_100g"
+msgid "Weight per 100g of product"
+msgstr "Weight per 100g of product"
+
+msgctxt "weight_percent"
+msgid "Weight percent"
+msgstr "Weight percent"
\ No newline at end of file
diff --git a/po/common/en.po b/po/common/en.po
index 85dcb121ee9c5..fea79ee0e10b9 100644
--- a/po/common/en.po
+++ b/po/common/en.po
@@ -6615,3 +6615,26 @@ msgctxt "relative_to_all_products"
msgid "relative to all products"
msgstr "relative to all products"
+msgctxt "packagings_n_p"
+msgid "Numbers of packaging components"
+msgstr "Numbers of packaging components"
+
+msgctxt "packagings_n_s"
+msgid "Number of packaging components"
+msgstr "Number of packaging components"
+
+msgctxt "packagings_materials_all"
+msgid "All materials"
+msgstr "All materials"
+
+msgctxt "weight"
+msgid "Weight"
+msgstr "Weight"
+
+msgctxt "weight_100g"
+msgid "Weight per 100g of product"
+msgstr "Weight per 100g of product"
+
+msgctxt "weight_percent"
+msgid "Weight percent"
+msgstr "Weight percent"
\ No newline at end of file
---|