{
  "type": "object",
  "x-exports": [
    "types"
  ],
  "required": [
    "datasets",
    "chart"
  ],
  "allOf": [
    {
      "title": "Source de données",
      "properties": {
        "datasets": {
          "$ref": "#/$defs/datasets"
        },
        "staticFilters": {
          "$ref": "#/$defs/filters"
        },
        "staticFiltersParams": {
          "type": "string",
          "default": "",
          "layout": "none"
        }
      }
    },
    {
      "title": "Type de visualisation",
      "properties": {
        "chart": {
          "type": "object",
          "default": {
            "type": "line"
          },
          "required": [
            "type",
            "config"
          ],
          "discriminator": {
            "propertyName": "type"
          },
          "oneOfLayout": {
            "emptyData": true
          },
          "oneOf": [
            {
              "title": "Courbe",
              "additionalProperties": false,
              "required": [
                "type"
              ],
              "properties": {
                "type": {
                  "const": "line"
                },
                "tension": {
                  "$ref": "#/$defs/tension"
                },
                "lineDash": {
                  "$ref": "#/$defs/lineDash"
                },
                "area": {
                  "type": "boolean",
                  "title": "Remplir l'aire en dessous",
                  "default": false
                },
                "yAxisStartsZero": {
                  "type": "boolean",
                  "title": "Commencer à partir de 0 pour l'axe des ordonnées"
                },
                "hidePoints": {
                  "type": "boolean",
                  "title": "Cacher les points"
                },
                "config": {
                  "type": "object",
                  "title": "Préparation des données",
                  "description": "Choisissez la manière de traiter les données.\n\n**Lire les lignes une par une, couleur unique** :\nles valeurs sont lues directement depuis chaque ligne du jeu de données et représentées avec une couleur unique.\n\n**Grouper les lignes** :\nles lignes sont groupées selon un critère pour former les libellés sur l'axe des X. Les valeurs affichées sont obtenues par calcul (nombre de lignes, somme, moyenne, etc.) pour chaque groupe.",
                  "oneOfLayout": {
                    "emptyData": true
                  },
                  "oneOf": [
                    {
                      "$ref": "#/$defs/rowsDataSingle"
                    },
                    {
                      "$ref": "#/$defs/aggsDataSingle"
                    }
                  ]
                }
              }
            },
            {
              "title": "Histogramme",
              "additionalProperties": false,
              "required": [
                "type"
              ],
              "properties": {
                "type": {
                  "const": "bar"
                },
                "hideYAxis": {
                  "$ref": "#/$defs/hideYAxis"
                },
                "yAxisStartsZero": {
                  "type": "boolean",
                  "title": "Commencer à partir de 0 pour l'axe des ordonnées",
                  "default": true
                },
                "horizontal": {
                  "$ref": "#/$defs/horizontal"
                },
                "config": {
                  "type": "object",
                  "title": "Préparation des données",
                  "description": "Choisissez la manière de traiter les données.\n\n**Lire les lignes une par une, couleur unique** :\nles valeurs sont lues directement depuis chaque ligne du jeu de données et représentées avec une couleur unique.\n\n**Lire les lignes une par une, plusieurs couleurs** :\nles valeurs sont lues directement depuis chaque ligne du jeu de données. Les différentes séries (affichées dans la légende) correspondent aux valeurs d'une colonne de catégories.\n\n**Grouper les lignes** :\nles lignes sont groupées selon un critère pour former les libellés sur l'axe des X. Les valeurs affichées sont obtenues par calcul (nombre de lignes, somme, moyenne, etc.) pour chaque groupe.",
                  "oneOfLayout": {
                    "emptyData": true
                  },
                  "oneOf": [
                    {
                      "$ref": "#/$defs/rowsDataSingle"
                    },
                    {
                      "$ref": "#/$defs/rowsDataSingleCategories"
                    },
                    {
                      "$ref": "#/$defs/aggsDataSingle"
                    }
                  ]
                }
              }
            },
            {
              "title": "Plusieurs courbes",
              "additionalProperties": false,
              "required": [
                "type"
              ],
              "properties": {
                "type": {
                  "const": "multi-line"
                },
                "tension": {
                  "$ref": "#/$defs/tension"
                },
                "lineDash": {
                  "$ref": "#/$defs/lineDash"
                },
                "stacked": {
                  "type": "boolean",
                  "title": "Aires empilées"
                },
                "percentage": {
                  "type": "boolean",
                  "title": "Pourcentages"
                },
                "disableDynamicStack": {
                  "type": "boolean",
                  "title": "Désactiver la bascule d'empilement"
                },
                "yAxisStartsZero": {
                  "type": "boolean",
                  "title": "Commencer à partir de 0 pour l'axe des ordonnées"
                },
                "hidePoints": {
                  "type": "boolean",
                  "title": "Cacher les points"
                },
                "config": {
                  "$ref": "#/$defs/multipleDataType"
                }
              }
            },
            {
              "title": "Histogramme multivalué",
              "additionalProperties": false,
              "required": [
                "type"
              ],
              "properties": {
                "type": {
                  "const": "multi-bar"
                },
                "hideYAxis": {
                  "$ref": "#/$defs/hideYAxis"
                },
                "yAxisStartsZero": {
                  "type": "boolean",
                  "title": "Commencer à partir de 0 pour l'axe des ordonnées",
                  "default": true
                },
                "horizontal": {
                  "$ref": "#/$defs/horizontal"
                },
                "stacked": {
                  "type": "boolean",
                  "title": "Empiler les barres"
                },
                "percentage": {
                  "type": "boolean",
                  "title": "Pourcentages"
                },
                "disableDynamicStack": {
                  "type": "boolean",
                  "title": "Désactiver la bascule d'empilement"
                },
                "config": {
                  "$ref": "#/$defs/multipleDataType"
                }
              }
            },
            {
              "title": "Radar",
              "additionalProperties": false,
              "required": [
                "type"
              ],
              "properties": {
                "type": {
                  "const": "radar"
                },
                "tension": {
                  "$ref": "#/$defs/tension"
                },
                "lineDash": {
                  "$ref": "#/$defs/lineDash"
                },
                "config": {
                  "$ref": "#/$defs/multipleDataType"
                }
              }
            },
            {
              "title": "Camembert",
              "additionalProperties": false,
              "required": [
                "type"
              ],
              "properties": {
                "type": {
                  "const": "pie"
                },
                "cutout": {
                  "type": "integer",
                  "title": "Trou au milieu",
                  "minimum": 0,
                  "maximum": 80,
                  "default": 0,
                  "layout": "slider"
                },
                "rotation": {
                  "type": "integer",
                  "title": "Rotation",
                  "minimum": 0,
                  "maximum": 360,
                  "default": 0,
                  "layout": "slider"
                },
                "display": {
                  "type": "string",
                  "title": "Affichage",
                  "oneOf": [
                    {
                      "const": "label",
                      "title": "Libellé uniquement"
                    },
                    {
                      "const": "values",
                      "title": "Valeurs"
                    },
                    {
                      "const": "percentages",
                      "title": "Pourcentages"
                    },
                    {
                      "const": "both",
                      "title": "Valeurs et pourcentages"
                    }
                  ],
                  "default": "values"
                },
                "sumInTitle": {
                  "type": "boolean",
                  "title": "Afficher la somme dans le titre"
                },
                "config": {
                  "type": "object",
                  "title": "Préparation des données",
                  "description": "Choisissez la manière de traiter les données.\n\n**Lire les lignes une par une** :\nles valeurs sont lues directement depuis chaque ligne du jeu de données.\n\n**Grouper les lignes** :\nles lignes sont groupées selon un critère. Les valeurs affichées sont obtenues par calcul (nombre de lignes, somme, moyenne, etc.) pour chaque groupe.\n\n**Sommes calculées sur plusieurs colonnes** :\nles valeurs affichées sont obtenues en faisant la somme de plusieurs colonnes numériques ou booléennes sur l'ensemble du jeu de données. Chaque colonne devient une part du graphique.",
                  "oneOfLayout": {
                    "emptyData": true
                  },
                  "oneOf": [
                    {
                      "$ref": "#/$defs/rowsCategories"
                    },
                    {
                      "$ref": "#/$defs/aggsCategories"
                    },
                    {
                      "$ref": "#/$defs/aggsLabels"
                    }
                  ]
                }
              }
            },
            {
              "title": "Paire d'histogrammes",
              "additionalProperties": false,
              "required": [
                "type"
              ],
              "properties": {
                "type": {
                  "const": "paired-histogram",
                  "title": "Type de visualisation"
                },
                "config": {
                  "$ref": "#/$defs/multipleDataType"
                }
              }
            }
          ]
        }
      }
    },
    {
      "title": "Options",
      "properties": {
        "title": {
          "title": "Titre du graphique",
          "type": "string"
        },
        "xTitle": {
          "title": "Titre des abscisses",
          "type": "string"
        },
        "yTitle": {
          "title": "Titre des ordonnées",
          "type": "string"
        },
        "disableTooltip": {
          "type": "boolean",
          "title": "Désactiver l'infobulle",
          "default": false
        },
        "selection": {
          "type": "boolean",
          "title": "Activer la sélection au clic",
          "description": "Un clic sur une barre, une part ou un point émet une sélection (clé _c_/_d_ de son champ d'abscisse) vers les autres visualisations de la page. Désactivé par défaut : une sélection reçue est toujours mise en évidence.",
          "default": false
        },
        "labelsMaxWidth": {
          "type": "integer",
          "title": "Longueur maximum des libellés",
          "minimum": 20,
          "maximum": 60,
          "default": 30,
          "layout": "slider"
        },
        "valueLabels": {
          "title": "Renommer des libellés",
          "description": "Remplace des valeurs (libellés d'axes et de légende) ou des colonnes de valeurs par un libellé personnalisé dans le graphique. La correspondance se fait sur la valeur brute ou la clé de colonne.",
          "type": "array",
          "items": {
            "type": "object",
            "required": [
              "value",
              "label"
            ],
            "additionalProperties": false,
            "properties": {
              "value": {
                "type": "string",
                "title": "Valeur ou colonne à renommer"
              },
              "label": {
                "type": "string",
                "title": "Libellé affiché"
              }
            }
          },
          "layout": {
            "comp": "list",
            "itemTitle": "data.label ? data.label + ' (' + data.value + ')' : data.value",
            "listActions": [
              "add",
              "edit",
              "delete",
              "sort"
            ],
            "messages": {
              "addItem": "Ajouter un libellé"
            }
          }
        },
        "unit": {
          "type": "string",
          "title": "Unité"
        },
        "multiplier": {
          "type": "number",
          "title": "Multiplicateur",
          "description": "Multiplicateur appliqué aux valeurs du graphique, pour changer d'unité (ex : 100 pour exprimer un ratio en pourcentage, 0,001 pour des milliers)",
          "default": 1
        },
        "legendPosition": {
          "type": "string",
          "title": "Position de la légende",
          "default": "top",
          "oneOf": [
            {
              "const": "top",
              "title": "Haut"
            },
            {
              "const": "bottom",
              "title": "Bas"
            },
            {
              "const": "left",
              "title": "Gauche"
            },
            {
              "const": "right",
              "title": "Droite"
            }
          ]
        }
      }
    }
  ],
  "$defs": {
    "datasets": {
      "type": "array",
      "items": [
        {
          "title": "Jeu de données",
          "description": "Ce jeu doit contenir au moins une colonne avec valeur numérique",
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "href": {
              "type": "string"
            },
            "title": {
              "type": "string"
            },
            "id": {
              "type": "string"
            },
            "schema": {
              "type": "array"
            },
            "finalizedAt": {
              "type": "string"
            }
          },
          "layout": {
            "getItems": {
              "url": "api/v1/datasets?status=finalized&size=100&q={q}&select=id,title,schema&${context.datasetFilter}",
              "itemKey": "data[\"href\"]",
              "itemTitle": "data[\"title\"]",
              "itemsResults": "data[\"results\"]"
            }
          }
        }
      ]
    },
    "size": {
      "type": "integer",
      "title": "Nombre maximal d'éléments",
      "minimum": 1,
      "maximum": 200,
      "default": 10
    },
    "horizontal": {
      "type": "boolean",
      "title": "Affichage horizontal"
    },
    "hideYAxis": {
      "type": "boolean",
      "title": "Cacher l'axe Y",
      "description": "Les valeurs apparaîtront au-dessus ou à droite des barres. Cache l'axe des X en affichage horizontal"
    },
    "labelsField": {
      "type": "string",
      "title": "Colonne de libellés",
      "description": "Choisissez la colonne contenant les libellés à présenter en légende. Dans le cas d'un diagramme en ligne, cette colonne va correspondre aux valeurs présentées en abscisse.",
      "layout": {
        "getItems": {
          "url": "${rootData.datasets[0].href}/schema?calculated=false",
          "itemKey": "data[\"key\"]",
          "itemTitle": "data[\"label\"]"
        }
      }
    },
    "valuesField": {
      "type": "string",
      "title": "Colonne de valeurs",
      "description": "Choisissez une colonne de valeurs numériques à présenter dans le graphique.",
      "layout": {
        "getItems": {
          "url": "${rootData.datasets[0].href}/schema?calculated=false&type=integer,number",
          "itemKey": "data[\"key\"]",
          "itemTitle": "data[\"label\"]"
        }
      }
    },
    "valuesFields": {
      "type": "array",
      "title": "Colonnes de valeurs",
      "description": "Choisissez les colonnes de valeurs numériques à présenter dans le graphique.",
      "minItems": 1,
      "maxItems": 12,
      "items": {
        "type": "string"
      },
      "layout": {
        "getItems": {
          "url": "${rootData.datasets[0].href}/schema?calculated=false&type=integer,number",
          "itemKey": "data[\"key\"]",
          "itemTitle": "data[\"label\"]"
        }
      }
    },
    "valuesCalcFields": {
      "type": "array",
      "title": "Colonnes de valeurs",
      "description": "Choisissez les colonnes de valeurs à présenter dans le graphique. Les colonnes booléennes sont agrégées : somme = nombre de « oui », moyenne = proportion de « oui ».",
      "minItems": 1,
      "maxItems": 12,
      "items": {
        "type": "string"
      },
      "layout": {
        "getItems": {
          "url": "${rootData.datasets[0].href}/schema?calculated=false&type=integer,number,boolean",
          "itemKey": "data[\"key\"]",
          "itemTitle": "data[\"label\"]"
        }
      }
    },
    "labelsValues": {
      "type": "array",
      "title": "Colonnes de libellés",
      "description": "Choisissez les colonnes de valeurs à agréger pour former les libellés de l'axe des X. Les colonnes numériques ou booléennes sont acceptées (booléen : somme = nombre de « oui », moyenne = proportion de « oui »).",
      "items": {
        "type": "string"
      },
      "layout": {
        "getItems": {
          "url": "${rootData.datasets[0].href}/schema?calculated=false",
          "itemKey": "data[\"key\"]",
          "itemTitle": "data[\"label\"]"
        }
      }
    },
    "valuesLabel": {
      "type": "string",
      "title": "Colonne de libellé des séries",
      "description": "Choisissez une colonne des libellés des différentes séries.",
      "layout": {
        "getItems": {
          "url": "${rootData.datasets[0].href}/schema?calculated=false",
          "itemKey": "data[\"key\"]",
          "itemTitle": "data[\"label\"]"
        }
      }
    },
    "rowSort": {
      "type": "string",
      "title": "Trier par",
      "default": "row",
      "oneOf": [
        {
          "const": "row",
          "title": "Ligne"
        },
        {
          "const": "value",
          "title": "Valeur"
        },
        {
          "const": "label",
          "title": "Libellé"
        }
      ]
    },
    "fillMissingLabels": {
      "type": "boolean",
      "title": "Afficher les abscisses sans données",
      "description": "Ajoute les abscisses numériques intermédiaires absentes (ex. une année sans ligne). Aucun point ni valeur 0 : la courbe relie les points de part et d'autre.",
      "default": false,
      "layout": {
        "if": "parent.data.rowSortBy === 'label'"
      }
    },
    "aggSort": {
      "type": "string",
      "title": "Trier par",
      "default": "label",
      "oneOf": [
        {
          "const": "value",
          "title": "Valeur calculée"
        },
        {
          "const": "label",
          "title": "Libellé"
        }
      ]
    },
    "sortOrder": {
      "type": "string",
      "title": "Ordre",
      "default": "asc",
      "oneOf": [
        {
          "const": "asc",
          "title": "Ascendant"
        },
        {
          "const": "desc",
          "title": "Descendant"
        }
      ]
    },
    "dynamicSort": {
      "type": "boolean",
      "title": "Trier dynamiquement",
      "description": "Si cette option est activée, l'utilisateur pourra choisir la colonne de tri et l'ordre de tri dans le formulaire de filtres interactifs.",
      "default": false
    },
    "tension": {
      "type": "integer",
      "title": "Courbure",
      "minimum": 0,
      "maximum": 4,
      "default": 1,
      "layout": "slider"
    },
    "lineDash": {
      "type": "string",
      "title": "Motif de trait",
      "default": "solid",
      "oneOf": [
        {
          "const": "solid",
          "title": "Trait plein"
        },
        {
          "const": "dashed",
          "title": "Tirets"
        },
        {
          "const": "dotted",
          "title": "Pointillés"
        }
      ]
    },
    "hexColor": {
      "type": "string",
      "title": "Couleur",
      "default": "#828282",
      "layout": "color-picker"
    },
    "defaultColor": {
      "type": "string",
      "title": "Couleur par défaut",
      "default": "#828282",
      "layout": "color-picker"
    },
    "color": {
      "type": "object",
      "title": "Couleur",
      "required": [],
      "discriminator": {
        "propertyName": "type"
      },
      "oneOfLayout": {
        "emptyData": true
      },
      "oneOf": [
        {
          "title": "Thème",
          "additionalProperties": false,
          "required": [
            "type"
          ],
          "properties": {
            "type": {
              "const": "theme"
            },
            "strValue": {
              "title": "Couleur",
              "type": "string",
              "oneOf": [
                {
                  "const": "primary",
                  "title": "Primaire"
                },
                {
                  "const": "secondary",
                  "title": "Secondaire"
                },
                {
                  "const": "accent",
                  "title": "Accent"
                }
              ]
            }
          }
        },
        {
          "title": "Personnalisée",
          "additionalProperties": false,
          "required": [
            "type"
          ],
          "properties": {
            "type": {
              "const": "custom"
            },
            "hexValue": {
              "$ref": "#/$defs/hexColor"
            }
          }
        }
      ],
      "default": {
        "type": "theme",
        "strValue": "primary"
      }
    },
    "groupBy": {
      "type": "object",
      "required": [],
      "default": {
        "type": "value"
      },
      "oneOf": [
        {
          "title": "Valeurs exactes d'une colonne",
          "required": [
            "type",
            "field"
          ],
          "additionalProperties": false,
          "properties": {
            "type": {
              "const": "value",
              "title": "Grouper par"
            },
            "field": {
              "type": "string",
              "title": "Grouper en fonction de cette colonne",
              "layout": {
                "getItems": {
                  "url": "${rootData.datasets[0].href}/schema?calculated=false",
                  "itemKey": "data[\"key\"]",
                  "itemTitle": "data[\"label\"]"
                }
              }
            },
            "interval": {
              "const": ""
            }
          }
        },
        {
          "title": "Intervalles d'une colonne de type date",
          "required": [
            "type",
            "field",
            "interval"
          ],
          "additionalProperties": false,
          "properties": {
            "type": {
              "const": "date"
            },
            "field": {
              "type": "string",
              "title": "Grouper en fonction de cette colonne",
              "layout": {
                "getItems": {
                  "url": "${rootData.datasets[0].href}/schema?calculated=false&format=date,date-time",
                  "itemKey": "data[\"key\"]",
                  "itemTitle": "data[\"label\"]"
                }
              }
            },
            "interval": {
              "type": "string",
              "title": "Taille des intervalles",
              "default": "day",
              "oneOf": [
                {
                  "const": "hour",
                  "title": "Heure"
                },
                {
                  "const": "day",
                  "title": "Jour"
                },
                {
                  "const": "week",
                  "title": "Semaine"
                },
                {
                  "const": "month",
                  "title": "Mois"
                },
                {
                  "const": "year",
                  "title": "Année"
                }
              ]
            }
          }
        },
        {
          "title": "Intervalles d'une colonne numérique",
          "required": [
            "type",
            "field",
            "interval"
          ],
          "additionalProperties": false,
          "properties": {
            "type": {
              "const": "number"
            },
            "field": {
              "type": "string",
              "title": "Grouper en fonction de cette colonne",
              "layout": {
                "getItems": {
                  "url": "${rootData.datasets[0].href}/schema?calculated=false&type=integer,number",
                  "itemKey": "data[\"key\"]",
                  "itemTitle": "data[\"label\"]"
                }
              }
            },
            "interval": {
              "type": "integer",
              "title": "Taille des intervalles",
              "default": 100
            }
          }
        }
      ],
      "oneOfLayout": {
        "label": "Grouper par",
        "emptyData": true
      }
    },
    "valueCalc": {
      "title": "Calcul de la valeur",
      "type": "object",
      "default": {
        "type": "count"
      },
      "oneOfLayout": {
        "emptyData": true
      },
      "oneOf": [
        {
          "title": "Nombre de lignes",
          "required": [
            "type"
          ],
          "additionalProperties": false,
          "properties": {
            "type": {
              "const": "count"
            }
          }
        },
        {
          "title": "Calcul depuis les valeurs d'une colonne",
          "required": [
            "type",
            "field",
            "metric"
          ],
          "additionalProperties": false,
          "properties": {
            "type": {
              "const": "metric"
            },
            "field": {
              "type": "string",
              "title": "Colonne",
              "layout": {
                "getItems": {
                  "url": "${rootData.datasets[0].href}/schema?calculated=false&type=integer,number",
                  "itemKey": "data[\"key\"]",
                  "itemTitle": "data[\"label\"]"
                }
              }
            },
            "metric": {
              "type": "string",
              "title": "Type de calcul",
              "default": "sum",
              "oneOf": [
                {
                  "const": "avg",
                  "title": "Moyenne"
                },
                {
                  "const": "min",
                  "title": "Valeur minimale"
                },
                {
                  "const": "max",
                  "title": "Valeur maximale"
                },
                {
                  "const": "sum",
                  "title": "Somme"
                },
                {
                  "const": "cardinality",
                  "title": "Cardinalité"
                }
              ]
            },
            "dynamicMetric": {
              "type": "boolean",
              "title": "Choix dynamique de la métrique",
              "default": false
            }
          }
        }
      ]
    },
    "divider": {
      "title": "Diviseur",
      "type": "object",
      "description": "Valeur par laquelle diviser les valeurs du graphique (ex : diviser une somme par un nombre de lignes ou d'habitants pour obtenir un ratio). Une division par une constante peut être réalisée avec le multiplicateur.",
      "discriminator": {
        "propertyName": "type"
      },
      "oneOfLayout": {
        "emptyData": true
      },
      "default": {
        "type": "none"
      },
      "oneOf": [
        {
          "title": "Pas de diviseur",
          "required": [
            "type"
          ],
          "additionalProperties": false,
          "properties": {
            "type": {
              "const": "none"
            }
          }
        },
        {
          "title": "Nombre de lignes du groupe",
          "description": "Divise chaque valeur par le nombre de lignes de son groupe (ex : une somme rapportée au nombre de lignes de la catégorie). Sur les graphiques qui lisent les lignes une par une ou qui comparent des valeurs globales, le nombre total de lignes est utilisé.",
          "required": [
            "type"
          ],
          "additionalProperties": false,
          "properties": {
            "type": {
              "const": "groupCount"
            }
          }
        },
        {
          "title": "Nombre total de lignes",
          "description": "Divise toutes les valeurs par le nombre total de lignes du jeu de données (filtres appliqués).",
          "required": [
            "type"
          ],
          "additionalProperties": false,
          "properties": {
            "type": {
              "const": "totalCount"
            }
          }
        },
        {
          "title": "Calculée depuis une colonne",
          "required": [
            "type",
            "field",
            "metric"
          ],
          "additionalProperties": false,
          "properties": {
            "type": {
              "const": "column"
            },
            "field": {
              "type": "string",
              "title": "Colonne de division",
              "layout": {
                "getItems": {
                  "url": "${rootData.datasets[0].href}/schema?calculated=false&type=integer,number",
                  "itemKey": "data[\"key\"]",
                  "itemTitle": "data[\"label\"]"
                }
              }
            },
            "metric": {
              "type": "string",
              "title": "Type de calcul",
              "description": "Calcul appliqué à la colonne pour chaque groupe du graphique. En lecture ligne par ligne, la valeur brute de la colonne est utilisée.",
              "default": "sum",
              "oneOf": [
                {
                  "const": "avg",
                  "title": "Moyenne"
                },
                {
                  "const": "min",
                  "title": "Valeur minimale"
                },
                {
                  "const": "max",
                  "title": "Valeur maximale"
                },
                {
                  "const": "sum",
                  "title": "Somme"
                }
              ]
            }
          }
        }
      ]
    },
    "rowsDataSingle": {
      "title": "Lire les lignes une par une, couleur unique",
      "type": "object",
      "required": [
        "type",
        "rowSortBy",
        "sortOrder",
        "size",
        "labelsField",
        "valuesField"
      ],
      "additionalProperties": false,
      "properties": {
        "type": {
          "const": "rowsBased"
        },
        "labelsField": {
          "$ref": "#/$defs/labelsField"
        },
        "size": {
          "$ref": "#/$defs/size"
        },
        "valuesField": {
          "$ref": "#/$defs/valuesField"
        },
        "divider": {
          "$ref": "#/$defs/divider"
        },
        "rowSortBy": {
          "$ref": "#/$defs/rowSort"
        },
        "fillMissingLabels": {
          "$ref": "#/$defs/fillMissingLabels"
        },
        "sortOrder": {
          "$ref": "#/$defs/sortOrder"
        },
        "dynamicSort": {
          "$ref": "#/$defs/dynamicSort"
        },
        "color": {
          "$ref": "#/$defs/color"
        }
      }
    },
    "aggsDataSingle": {
      "title": "Grouper les lignes",
      "type": "object",
      "required": [
        "type",
        "aggSortBy",
        "sortOrder",
        "size",
        "groupBy",
        "valueCalc"
      ],
      "additionalProperties": false,
      "properties": {
        "type": {
          "const": "aggsBased"
        },
        "groupBy": {
          "$ref": "#/$defs/groupBy"
        },
        "size": {
          "$ref": "#/$defs/size"
        },
        "valueCalc": {
          "$ref": "#/$defs/valueCalc"
        },
        "divider": {
          "$ref": "#/$defs/divider"
        },
        "missingLabel": {
          "type": "string",
          "title": "Groupe pour les éléments non renseignés",
          "default": ""
        },
        "aggSortBy": {
          "$ref": "#/$defs/aggSort"
        },
        "sortOrder": {
          "$ref": "#/$defs/sortOrder"
        },
        "dynamicSort": {
          "$ref": "#/$defs/dynamicSort"
        },
        "color": {
          "$ref": "#/$defs/color"
        }
      }
    },
    "rowsDataSingleCategories": {
      "title": "Lire les lignes une par une, plusieurs couleurs",
      "type": "object",
      "required": [
        "type",
        "rowSortBy",
        "sortOrder",
        "size",
        "labelsField",
        "valuesField",
        "categoriesField"
      ],
      "additionalProperties": false,
      "properties": {
        "type": {
          "const": "rowsBasedCategories"
        },
        "labelsField": {
          "$ref": "#/$defs/labelsField"
        },
        "size": {
          "$ref": "#/$defs/size"
        },
        "valuesField": {
          "$ref": "#/$defs/valuesField"
        },
        "divider": {
          "$ref": "#/$defs/divider"
        },
        "categoriesField": {
          "type": "string",
          "title": "Champ de catégorie",
          "layout": {
            "getItems": {
              "url": "${rootData.datasets[0].href}/schema?calculated=false&maxCardinality=12&${rootData.staticFiltersParams}",
              "itemKey": "data[\"key\"]",
              "itemTitle": "data[\"label\"]"
            }
          }
        },
        "rowSortBy": {
          "$ref": "#/$defs/rowSort"
        },
        "fillMissingLabels": {
          "$ref": "#/$defs/fillMissingLabels"
        },
        "sortOrder": {
          "$ref": "#/$defs/sortOrder"
        },
        "dynamicSort": {
          "$ref": "#/$defs/dynamicSort"
        },
        "colorOrder": {
          "type": "object",
          "title": "Couleurs et ordre",
          "oneOfLayout": {
            "emptyData": true
          },
          "oneOf": [
        {
          "title": "Palette précalculée",
          "allOf": [
            {
              "$ref": "#/$defs/colorPalette"
                }
              ],
              "properties": {
                "seriesOrder": {
                  "type": "array",
                  "title": "Ordre des séries",
                  "items": {
                    "type": "string",
                    "readOnly": true,
                    "layout": "none"
                  },
                  "layout": {
                    "comp": "list",
                    "itemTitle": "rootData.datasets?.[0]?.schema?.find(f => f.key === rootData.chart?.config?.categoriesField)?.['x-labels']?.[data] || data",
                    "listActions": ["sort"],
                    "if": "rootData.chart.config.categoriesField",
                    "getItems": {
                      "url": "${rootData.datasets[0].href}/values_agg?field=${rootData.chart.config.categoriesField}&agg_size=12&size=0&${rootData.staticFiltersParams}",
                      "itemKey": "data[\"value\"]",
                      "itemValue": "data[\"value\"]",
                      "itemsResults": "data[\"aggs\"].map(a => ({ value: a.value + '' }))"
                    }
                  }
                }
              }
            },
            {
              "title": "Palette personnalisée",
              "required": [
                "type",
                "entries"
              ],
              "additionalProperties": false,
              "properties": {
                "type": {
                  "const": "manual"
                },
                "entries": {
                  "title":"Valeurs",
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "key"
                    ],
                    "additionalProperties": false,
                    "properties": {
                      "key": {
                        "type": "string",
                        "layout": "none"
                      },
                      "color": {
                        "$ref": "#/$defs/hexColor"
                      }
                    }
                  },
                  "layout": {
                    "comp": "list",
                    "itemTitle": "rootData.datasets?.[0]?.schema?.find(f => f.key === rootData.chart?.config?.categoriesField)?.['x-labels']?.[data.key] || data.key",
                    "listActions": ["edit", "sort"],
                    "if": "rootData.chart.config.categoriesField",
                    "getItems": {
                      "url": "${rootData.datasets[0].href}/values_agg?field=${rootData.chart.config.categoriesField}&agg_size=12&size=0&${rootData.staticFiltersParams}",
                      "itemKey": "data['key']",
                      "itemTitle": "data['key']",
                      "itemsResults": "data['aggs'].map(a => ({ key: a.value + '' }))"
                    }
                  }
                }
              }
            }
          ],
          "default": {
            "type": "palette",
            "name": "Accent",
            "offset": 0
          }
        }
      }
    },
    "rowsDataMultiple": {
      "title": "Lire les lignes une par une",
      "type": "object",
      "required": [
        "type",
        "rowSortBy",
        "sortOrder",
        "size",
        "labelsField",
        "valuesFields"
      ],
      "additionalProperties": false,
      "properties": {
        "type": {
          "const": "rowsBased"
        },
        "labelsField": {
          "$ref": "#/$defs/labelsField"
        },
        "size": {
          "$ref": "#/$defs/size"
        },
        "valuesFields": {
          "$ref": "#/$defs/valuesFields"
        },
        "divider": {
          "$ref": "#/$defs/divider"
        },
        "removeFromLabels": {
          "title": "Texte à retirer des libellés",
          "type": "string",
          "default": ""
        },
        "rowSortBy": {
          "$ref": "#/$defs/rowSort"
        },
        "fillMissingLabels": {
          "$ref": "#/$defs/fillMissingLabels"
        },
        "sortOrder": {
          "$ref": "#/$defs/sortOrder"
        },
        "dynamicSort": {
          "$ref": "#/$defs/dynamicSort"
        },
        "colorOrder": {
          "type": "object",
          "title": "Couleurs et ordre",
          "oneOfLayout": {
            "emptyData": true
          },
          "oneOf": [
        {
          "title": "Palette précalculée",
          "allOf": [
            {
              "$ref": "#/$defs/colorPalette"
                }
              ],
              "properties": {
                "seriesOrder": {
                  "type": "array",
                  "title": "Ordre des séries",
                  "items": {
                    "type": "string",
                    "readOnly": true
                  },
                  "layout": {
                    "itemTitle":"rootData.datasets[0].schema.find(f => f.key === data).title",
                    "comp": "list",
                    "listActions": ["sort"],
                    "if": "rootData.chart.config.valuesFields?.length",
                    "getItems": {
                      "url": "${rootData.datasets[0].href}/schema?calculated=false&t=${rootData.chart.config.valuesFields?.length}",
                      "itemKey": "data['key']",
                      "itemValue": "data['key']",
                      "itemsResults": "data.filter(f => rootData.chart.config.valuesFields.includes(f.key))"
                    }
                  }
                }
              }
            },
            {
              "title": "Palette personnalisée",
              "required": [
                "type",
                "entries"
              ],
              "additionalProperties": false,
              "properties": {
                "type": {
                  "const": "manual"
                },
                "entries": {
                  "title":"Valeurs",
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "key"
                    ],
                    "additionalProperties": false,
                    "properties": {
                      "key": {
                        "type": "string",
                        "layout": "none"
                      },
                      "label": {
                        "type": "string",
                        "layout": "none"
                      },
                      "color": {
                        "$ref": "#/$defs/hexColor"
                      }
                    }
                  },
                  "layout": {
                    "comp": "list",
                    "listActions": ["edit", "sort"],
                    "if": "rootData.chart.config.valuesFields?.length",
                    "getItems": {
                      "url": "${rootData.datasets[0].href}/schema?calculated=false&t=${rootData.chart.config.valuesFields?.length}",
                      "itemKey": "data['key']",
                      "itemTitle": "data['label']",
                      "itemsResults": "data.filter(f => rootData.chart.config.valuesFields.includes(f.key))"
                    }
                  }
                }
              }
            }
          ],
          "default": {
            "type": "palette",
            "name": "Accent",
            "offset": 0
          }
        }
      }
    },
    "aggsDataMultiple": {
      "title": "Grouper les lignes, séries définies par une colonne de catégories",
      "type": "object",
      "required": [
        "type",
        "aggSortBy",
        "sortOrder",
        "size",
        "groupBy",
        "groupsField",
        "valueCalc"
      ],
      "additionalProperties": false,
      "properties": {
        "type": {
          "const": "aggsBased"
        },
        "groupBy": {
          "$ref": "#/$defs/groupBy"
        },
        "groupsField": {
          "type": "string",
          "title": "Grouper les valeurs en fonction de cette colonne",
          "layout": {
            "getItems": {
              "url": "${rootData.datasets[0].href}/schema?calculated=false&maxCardinality=12&${rootData.staticFiltersParams}",
              "itemKey": "data[\"key\"]",
              "itemTitle": "data[\"label\"]"
            }
          }
        },
        "size": {
          "$ref": "#/$defs/size"
        },
        "valueCalc": {
          "$ref": "#/$defs/valueCalc"
        },
        "divider": {
          "$ref": "#/$defs/divider"
        },
        "missingLabel": {
          "type": "string",
          "title": "Groupe pour les éléments non renseignés",
          "default": ""
        },
        "aggSortBy": {
          "$ref": "#/$defs/aggSort"
        },
        "sortOrder": {
          "$ref": "#/$defs/sortOrder"
        },
        "dynamicSort": {
          "$ref": "#/$defs/dynamicSort"
        },
        "colorOrder": {
          "type": "object",
          "title": "Couleurs et ordre",
          "oneOfLayout": {
            "emptyData": true
          },
          "oneOf": [
        {
          "title": "Palette précalculée",
          "allOf": [
            {
              "$ref": "#/$defs/colorPalette"
                }
              ],
              "properties": {
                "seriesOrder": {
                  "type": "array",
                  "title": "Ordre des séries",
                  "items": {
                    "type": "string",
                    "readOnly": true,
                    "layout": "none"
                  },
                  "layout": {
                    "comp": "list",
                    "itemTitle": "rootData.datasets?.[0]?.schema?.find(f => f.key === rootData.chart?.config?.groupsField)?.['x-labels']?.[data] || data",
                    "listActions": ["sort"],
                    "if": "rootData.chart.config.groupsField",
                    "getItems": {
                      "url": "${rootData.datasets[0].href}/values_agg?field=${rootData.chart.config.groupsField}&agg_size=12&size=0&missing=${rootData.chart.config.missingLabel}&${rootData.staticFiltersParams}",
                      "itemKey": "data[\"value\"]",
                      "itemValue": "data[\"value\"]",
                      "itemsResults": "data[\"aggs\"].map(a => ({ value: a.value + '' }))"
                    }
                  }
                }
              }
            },
            {
              "title": "Palette personnalisée",
              "required": [
                "type",
                "entries"
              ],
              "additionalProperties": false,
              "properties": {
                "type": {
                  "const": "manual"
                },
                "entries": {
                  "title":"Valeurs",
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "key"
                    ],
                    "additionalProperties": false,
                    "properties": {
                      "key": {
                        "type": "string",
                        "layout": "none"
                      },
                      "color": {
                        "$ref": "#/$defs/hexColor"
                      }
                    }
                  },
                  "layout": {
                    "comp": "list",
                    "itemTitle": "rootData.datasets?.[0]?.schema?.find(f => f.key === rootData.chart?.config?.groupsField)?.['x-labels']?.[data.key] || data.key",
                    "listActions": ["edit", "sort"],
                    "if": "rootData.chart.config.groupsField",
                    "getItems": {
                      "url": "${rootData.datasets[0].href}/values_agg?field=${rootData.chart.config.groupsField}&agg_size=12&size=0&missing=${rootData.chart.config.missingLabel}&${rootData.staticFiltersParams}",
                      "itemKey": "data['key']",
                      "itemTitle": "data['key']",
                      "itemsResults": "data['aggs'].map(a => ({ key: a.value + '' }))"
                    }
                  }
                }
              }
            }
          ],
          "default": {
            "type": "palette",
            "name": "Accent",
            "offset": 0
          }
        }
      }
    },
    "aggsDataMultipleCategories": {
      "title": "Grouper les lignes, séries définies par plusieurs colonnes numériques ou booléennes",
      "type": "object",
      "required": [
        "type",
        "aggSortBy",
        "sortOrder",
        "size",
        "groupBy",
        "valuesCalc"
      ],
      "additionalProperties": false,
      "properties": {
        "type": {
          "const": "aggsBasedCategories"
        },
        "groupBy": {
          "$ref": "#/$defs/groupBy"
        },
        "valuesCalc": {
          "$ref": "#/$defs/valuesCalcFields"
        },
        "divider": {
          "$ref": "#/$defs/divider"
        },
        "removeFromLabels": {
          "title": "Texte à retirer des libellés",
          "type": "string",
          "default": ""
        },
        "metric": {
          "type": "string",
          "title": "Type de calcul",
          "default": "sum",
          "oneOf": [
            {
              "const": "avg",
              "title": "Moyenne"
            },
            {
              "const": "min",
              "title": "Valeur minimale"
            },
            {
              "const": "max",
              "title": "Valeur maximale"
            },
            {
              "const": "sum",
              "title": "Somme"
            },
            {
              "const": "cardinality",
              "title": "Cardinalité"
            }
          ]
        },
        "dynamicMetric": {
          "type": "boolean",
          "title": "Choix dynamique de la métrique",
          "default": false
        },
        "size": {
          "$ref": "#/$defs/size"
        },
        "aggSortBy": {
          "$ref": "#/$defs/aggSort"
        },
        "sortField": {
          "type": "string",
          "title": "Champ de tri",
          "description": "Champ utilisé pour le tri par valeur. Par défaut le premier champ de la liste des valeurs est utilisé.",
          "layout": {
            "if": "parent.data.aggSortBy === 'value'",
            "getItems": {
              "url": "${rootData.datasets[0].href}/schema?calculated=false&type=integer,number,boolean",
              "itemKey": "data[\"key\"]",
              "itemTitle": "data[\"label\"]"
            }
          }
        },
        "sortOrder": {
          "$ref": "#/$defs/sortOrder"
        },
        "dynamicSort": {
          "$ref": "#/$defs/dynamicSort"
        },
        "colorOrder": {
          "type": "object",
          "title": "Couleurs et ordre",
          "oneOfLayout": {
            "emptyData": true
          },
          "oneOf": [
        {
          "title": "Palette précalculée",
          "allOf": [
            {
              "$ref": "#/$defs/colorPalette"
                }
              ],
              "properties": {
                "seriesOrder": {
                  "type": "array",
                  "title": "Ordre des séries",
                  "items": {
                    "type": "string",
                    "readOnly": true
                  },
                  "layout": {
                    "itemTitle":"rootData.datasets[0].schema.find(f => f.key === data).title",
                    "comp": "list",
                    "listActions": ["sort"],
                    "if": "rootData.chart.config.valuesCalc?.length",
                    "getItems": {
                      "url": "${rootData.datasets[0].href}/schema?calculated=false&t=${rootData.chart.config.valuesCalc?.length}",
                      "itemKey": "data['key']",
                      "itemValue": "data['key']",
                      "itemsResults": "data.filter(f => rootData.chart.config.valuesCalc.includes(f.key))"
                    }
                  }
                }
              }
            },
            {
              "title": "Palette personnalisée",
              "required": [
                "type",
                "entries"
              ],
              "additionalProperties": false,
              "properties": {
                "type": {
                  "const": "manual"
                },
                "entries": {
                  "title":"Valeurs",
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "key", "label"
                    ],
                    "additionalProperties": false,
                    "properties": {
                      "key": {
                        "type": "string",
                        "layout": "none"
                      },
                      "label": {
                        "type": "string",
                        "layout": "none"
                      },
                      "color": {
                        "$ref": "#/$defs/hexColor"
                      }
                    }
                  },
                  "layout": {
                    "comp": "list",
                    "listActions": ["edit", "sort"],
                    "if": "rootData.chart.config.valuesCalc?.length",
                    "getItems": {
                      "url": "${rootData.datasets[0].href}/schema?calculated=false&t=${rootData.chart.config.valuesCalc?.length}",
                      "itemKey": "data['key']",
                      "itemTitle": "data['label']",
                      "itemsResults": "data.filter(f => rootData.chart.config.valuesCalc.includes(f.key))"
                    }
                  }
                }
              }
            }
          ],
          "default": {
            "type": "palette",
            "name": "Accent",
            "offset": 0
          }
        }
      }
    },
    "aggsDataMultipleLabels": {
      "title": "Grouper les lignes, abscisses définies par plusieurs colonnes",
      "type": "object",
      "required": [
        "type",
        "size",
        "labelsValues",
        "valuesLabel"
      ],
      "additionalProperties": false,
      "properties": {
        "type": {
          "const": "aggsBasedLabels"
        },
        "labelsValues": {
          "$ref": "#/$defs/labelsValues"
        },
        "removeFromLabels": {
          "title": "Texte à retirer des libellés",
          "type": "string",
          "default": ""
        },
        "valuesLabel": {
          "$ref": "#/$defs/valuesLabel"
        },
        "divider": {
          "$ref": "#/$defs/divider"
        },
        "missingLabel": {
          "type": "string",
          "title": "Groupe pour les éléments non renseignés",
          "default": ""
        },
        "metric": {
          "type": "string",
          "title": "Type de calcul",
          "default": "sum",
          "oneOf": [
            {
              "const": "avg",
              "title": "Moyenne"
            },
            {
              "const": "min",
              "title": "Valeur minimale"
            },
            {
              "const": "max",
              "title": "Valeur maximale"
            },
            {
              "const": "sum",
              "title": "Somme"
            },
            {
              "const": "cardinality",
              "title": "Cardinalité"
            }
          ]
        },
        "dynamicMetric": {
          "type": "boolean",
          "title": "Choix dynamique de la métrique",
          "default": false
        },
        "size": {
          "$ref": "#/$defs/size"
        },
        "colorOrder": {
          "type": "object",
          "title": "Couleurs et ordre",
          "oneOfLayout": {
            "emptyData": true
          },
          "oneOf": [
        {
          "title": "Palette précalculée",
          "allOf": [
            {
              "$ref": "#/$defs/colorPalette"
                }
              ],
              "properties": {
                "seriesOrder": {
                  "type": "array",
                  "title": "Ordre des séries",
                  "items": {
                    "type": "string",
                    "readOnly": true,
                    "layout": "none"
                  },
                  "layout": {
                    "comp": "list",
                    "itemTitle": "rootData.datasets?.[0]?.schema?.find(f => f.key === rootData.chart?.config?.valuesLabel)?.['x-labels']?.[data] || data",
                    "listActions": ["sort"],
                    "if": "rootData.chart.config.valuesLabel",
                    "getItems": {
                      "url": "${rootData.datasets[0].href}/values_agg?field=${rootData.chart.config.valuesLabel}&agg_size=12&size=0&${rootData.staticFiltersParams}",
                      "itemKey": "data[\"value\"]",
                      "itemValue": "data[\"value\"]",
                      "itemsResults": "data[\"aggs\"].map(a => ({ value: a.value + '' }))"
                    }
                  }
                }
              }
            },
            {
              "title": "Palette personnalisée",
              "required": [
                "type",
                "entries"
              ],
              "additionalProperties": false,
              "properties": {
                "type": {
                  "const": "manual"
                },
                "entries": {
                  "title":"Valeurs",
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "key"
                    ],
                    "additionalProperties": false,
                    "properties": {
                      "key": {
                        "type": "string",
                        "layout": "none"
                      },
                      "color": {
                        "$ref": "#/$defs/hexColor"
                      }
                    }
                  },
                  "layout": {
                    "comp": "list",
                    "itemTitle": "rootData.datasets?.[0]?.schema?.find(f => f.key === rootData.chart?.config?.valuesLabel)?.['x-labels']?.[data.key] || data.key",
                    "listActions": ["edit", "sort"],
                    "if": "rootData.chart.config.valuesLabel",
                    "getItems": {
                      "url": "${rootData.datasets[0].href}/values_agg?field=${rootData.chart.config.valuesLabel}&agg_size=12&size=0&${rootData.staticFiltersParams}",
                      "itemKey": "data['key']",
                      "itemTitle": "data['key']",
                      "itemsResults": "data['aggs'].map(a => ({ key: a.value + '' }))"
                    }
                  }
                }
              }
            }
          ],
          "default": {
            "type": "palette",
            "name": "Accent",
            "offset": 0
          }
        }
      }
    },
    "multipleDataType": {
      "type": "object",
      "title": "Préparation des données",
      "description": "Choisissez la manière de traiter les données.\n\n**Lire les lignes une par une** :\nles valeurs sont lues directement depuis chaque ligne du jeu de données. Les différentes séries (affichées dans la légende) correspondent aux colonnes numériques sélectionnées.\n\n**Grouper les lignes, séries définies par une colonne de catégories** :\nles lignes sont groupées selon un critère pour former les libellés sur l'axe des X. Les différentes séries (affichées dans la légende) correspondent aux valeurs d'une colonne de catégories.\n\n**Grouper les lignes, séries définies par plusieurs colonnes numériques ou booléennes** :\nles lignes sont groupées selon un critère pour former les libellés sur l'axe des X. Les différentes séries (affichées dans la légende) correspondent à plusieurs colonnes numériques ou booléennes, agrégées indépendamment.\n\n**Grouper les lignes, abscisses définies par plusieurs colonnes** :\nles lignes sont groupées selon une colonne de catégories pour former les séries (affichées dans la légende). Les libellés sur l'axe des X correspondent à plusieurs colonnes numériques ou booléennes.",
      "oneOfLayout": {
        "emptyData": true
      },
      "oneOf": [
        {
          "$ref": "#/$defs/rowsDataMultiple"
        },
        {
          "$ref": "#/$defs/aggsDataMultiple"
        },
        {
          "$ref": "#/$defs/aggsDataMultipleCategories"
        },
        {
          "$ref": "#/$defs/aggsDataMultipleLabels"
        }
      ]
    },
    "rowsCategories": {
      "title": "Lire les lignes une par une",
      "type": "object",
      "required": [
        "type",
        "size",
        "labelsField",
        "valuesField"
      ],
      "additionalProperties": false,
      "properties": {
        "type": {
          "const": "rowsBased"
        },
        "labelsField": {
          "$ref": "#/$defs/labelsField"
        },
        "size": {
          "type": "integer",
          "title": "Nombre maximal d'éléments",
          "default": 5,
          "minimum": 1,
          "maximum": 12
        },
        "valuesField": {
          "$ref": "#/$defs/valuesField"
        },
        "divider": {
          "$ref": "#/$defs/divider"
        },
        "colorOrder": {
          "type": "object",
          "title": "Couleurs et ordre",
          "oneOfLayout": {
            "emptyData": true
          },
          "oneOf": [
        {
          "title": "Palette précalculée",
          "allOf": [
            {
              "$ref": "#/$defs/colorPalette"
                }
              ],
              "properties": {
                "seriesOrder": {
                  "type": "array",
                  "title": "Ordre des séries",
                  "items": {
                    "type": "string",
                    "readOnly": true,
                    "layout": "none"
                  },
                  "layout": {
                    "comp": "list",
                    "itemTitle": "rootData.datasets?.[0]?.schema?.find(f => f.key === rootData.chart?.config?.labelsField)?.['x-labels']?.[data] || data",
                    "listActions": ["sort"],
                    "if": "rootData.chart.config.labelsField",
                    "getItems": {
                      "url": "${rootData.datasets[0].href}/values_agg?field=${rootData.chart.config.labelsField}&agg_size=12&size=0&${rootData.staticFiltersParams}",
                      "itemKey": "data[\"value\"]",
                      "itemValue": "data[\"value\"]",
                      "itemsResults": "data[\"aggs\"].map(a => ({ value: a.value + '' }))"
                    }
                  }
                }
              }
            },
            {
              "title": "Palette personnalisée",
              "required": [
                "type",
                "entries"
              ],
              "additionalProperties": false,
              "properties": {
                "type": {
                  "const": "manual"
                },
                "entries": {
                  "title":"Valeurs",
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "key"
                    ],
                    "additionalProperties": false,
                    "properties": {
                      "key": {
                        "type": "string",
                        "layout": "none"
                      },
                      "color": {
                        "$ref": "#/$defs/hexColor"
                      }
                    }
                  },
                  "layout": {
                    "comp": "list",
                    "itemTitle": "rootData.datasets?.[0]?.schema?.find(f => f.key === rootData.chart?.config?.labelsField)?.['x-labels']?.[data.key] || data.key",
                    "listActions": ["edit", "sort"],
                    "if": "rootData.chart.config.labelsField",
                    "getItems": {
                      "url": "${rootData.datasets[0].href}/values_agg?field=${rootData.chart.config.labelsField}&agg_size=12&size=0&${rootData.staticFiltersParams}",
                      "itemKey": "data['key']",
                      "itemTitle": "data['key']",
                      "itemsResults": "data['aggs'].map(a => ({ key: a.value + '' }))"
                    }
                  }
                }
              }
            }
          ],
          "default": {
            "type": "palette",
            "name": "Accent",
            "offset": 0
          }
        }
      }
    },
    "aggsCategories": {
      "title": "Grouper les lignes",
      "type": "object",
      "required": [
        "type",
        "size",
        "groupBy",
        "valueCalc"
      ],
      "additionalProperties": false,
      "properties": {
        "type": {
          "const": "aggsBased"
        },
        "groupBy": {
          "$ref": "#/$defs/groupBy"
        },
        "size": {
          "type": "integer",
          "title": "Nombre maximal d'éléments",
          "default": 5,
          "minimum": 1,
          "maximum": 12
        },
        "valueCalc": {
          "$ref": "#/$defs/valueCalc"
        },
        "divider": {
          "$ref": "#/$defs/divider"
        },
        "missingLabel": {
          "type": "string",
          "title": "Groupe pour les éléments non renseignés",
          "default": ""
        },
        "colorOrder": {
          "type": "object",
          "title": "Couleurs et ordre",
          "oneOfLayout": {
            "emptyData": true
          },
          "oneOf": [
        {
          "title": "Palette précalculée",
          "allOf": [
            {
              "$ref": "#/$defs/colorPalette"
                }
              ],
              "properties": {
                "seriesOrder": {
                  "type": "array",
                  "title": "Ordre des séries",
                  "items": {
                    "type": "string",
                    "readOnly": true,
                    "layout": "none"
                  },
                  "layout": {
                    "comp": "list",
                    "itemTitle": "rootData.datasets?.[0]?.schema?.find(f => f.key === rootData.chart?.config?.groupBy?.field)?.['x-labels']?.[data] || data",
                    "listActions": ["sort"],
                    "if": "rootData.chart.config.groupBy?.field",
                    "getItems": {
                      "url": "${rootData.datasets[0].href}/values_agg?field=${rootData.chart.config.groupBy.field}&interval=${rootData.chart.config.groupBy.interval}&agg_size=12&size=0&missing=${rootData.chart.config.missingLabel}&${rootData.staticFiltersParams}",
                      "itemKey": "data[\"value\"]",
                      "itemValue": "data[\"value\"]",
                      "itemsResults": "data[\"aggs\"].map(a => ({ value: a.value + '' }))"
                    }
                  }
                }
              }
            },
            {
              "title": "Palette personnalisée",
              "required": [
                "type",
                "entries"
              ],
              "additionalProperties": false,
              "properties": {
                "type": {
                  "const": "manual"
                },
                "entries": {
                  "title":"Valeurs",
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "key"
                    ],
                    "additionalProperties": false,
                    "properties": {
                      "key": {
                        "type": "string",
                        "layout": "none"
                      },
                      "color": {
                        "$ref": "#/$defs/hexColor"
                      }
                    }
                  },
                  "layout": {
                    "comp": "list",
                    "itemTitle": "rootData.datasets?.[0]?.schema?.find(f => f.key === rootData.chart?.config?.groupBy?.field)?.['x-labels']?.[data.key] || data.key",
                    "listActions": ["edit", "sort"],
                    "if": "rootData.chart.config.groupBy?.field",
                    "getItems": {
                      "url": "${rootData.datasets[0].href}/values_agg?field=${rootData.chart.config.groupBy.field}&interval=${rootData.chart.config.groupBy.interval}&agg_size=12&size=0&missing=${rootData.chart.config.missingLabel}&${rootData.staticFiltersParams}",
                      "itemKey": "data['key']",
                      "itemTitle": "data['key']",
                      "itemsResults": "data['aggs'].map(a => ({ key: a.value + '' }))"
                    }
                  }
                },
                "defaultColor": {
                  "$ref": "#/$defs/defaultColor"
                }
              }
            }
          ],
          "default": {
            "type": "palette",
            "name": "Accent",
            "offset": 0
          }
        }
      }
    },
    "aggsLabels": {
      "title": "Sommes calculées sur plusieurs colonnes",
      "type": "object",
      "required": [
        "type",
        "valuesFields"
      ],
      "additionalProperties": false,
      "properties": {
        "type": {
          "const": "aggsLabels"
        },
        "valuesFields": {
          "$ref": "#/$defs/valuesCalcFields"
        },
        "divider": {
          "$ref": "#/$defs/divider"
        },
        "removeFromLabels": {
          "title": "Texte à retirer des libellés",
          "type": "string",
          "default": ""
        },
        "colorOrder": {
          "type": "object",
          "title": "Couleurs et ordre",
          "oneOfLayout": {
            "emptyData": true
          },
          "oneOf": [
        {
          "title": "Palette précalculée",
          "allOf": [
            {
              "$ref": "#/$defs/colorPalette"
                }
              ],
              "properties": {
                "seriesOrder": {
                  "type": "array",
                  "title": "Ordre des séries",
                  "items": {
                    "type": "string",
                    "readOnly": true
                  },
                  "layout": {
                    "itemTitle":"rootData.datasets[0].schema.find(f => f.key === data).title",
                    "comp": "list",
                    "listActions": ["sort"],
                    "if": "rootData.chart.config.valuesFields?.length",
                    "getItems": {
                      "url": "${rootData.datasets[0].href}/schema?calculated=false&t=${rootData.chart.config.valuesFields?.length}",
                      "itemKey": "data['key']",
                      "itemValue": "data['key']",
                      "itemsResults": "data.filter(f => rootData.chart.config.valuesFields.includes(f.key))"
                    }
                  }
                }
              }
            },
            {
              "title": "Palette personnalisée",
              "required": [
                "type",
                "entries"
              ],
              "additionalProperties": false,
              "properties": {
                "type": {
                  "const": "manual"
                },
                "entries": {
                  "title":"Valeurs",
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "key"
                    ],
                    "additionalProperties": false,
                    "properties": {
                      "key": {
                        "type": "string",
                        "layout": "none"
                      },
                      "label": {
                        "type": "string",
                        "layout": "none"
                      },
                      "color": {
                        "$ref": "#/$defs/hexColor"
                      }
                    }
                  },
                  "layout": {
                    "comp": "list",
                    "listActions": ["edit", "sort"],
                    "if": "rootData.chart.config.valuesFields?.length",
                    "getItems": {
                      "url": "${rootData.datasets[0].href}/schema?calculated=false&t=${rootData.chart.config.valuesFields?.length}",
                      "itemKey": "data['key']",
                      "itemTitle": "data['label']",
                      "itemsResults": "data.filter(f => rootData.chart.config.valuesFields.includes(f.key))"
                    }
                  }
                },
                "defaultColor": {
                  "$ref": "#/$defs/defaultColor"
                }
              }
            }
          ],
          "default": {
            "type": "palette",
            "name": "Accent",
            "offset": 0
          }
        }
      }
    },

    "filters": {
      "title": "Filtres prédéfinis",
      "type": "array",
      "items": {
        "type": "object",
        "default": {
          "type": "in"
        },
        "oneOfLayout": {
          "emptyData": true
        },
        "oneOf": [
          {
            "title": "Restreindre à des valeurs",
            "required": [
              "type",
              "field",
              "values"
            ],
            "additionalProperties": false,
            "properties": {
              "type": {
                "const": "in"
              },
              "field": {
                "$ref": "#/$defs/filterField"
              },
              "values": {
                "type": "array",
                "title": "Valeurs",
                "items": {
                  "type": "string"
                },
                "layout": {
                  "getItems": {
                    "url": "${rootData.datasets[0].href}/values-labels/${parent.data.field?.key || parent.data.field || ''}?q={q}&q_mode=complete&size=100&stringify=true",
                    "itemKey": "data[\"value\"]",
                    "itemTitle": "data[\"label\"]"
                  }
                }
              }
            }
          },
          {
            "title": "Restreindre à un interval de valeurs",
            "required": [
              "type",
              "field"
            ],
            "additionalProperties": false,
            "properties": {
              "type": {
                "const": "interval"
              },
              "field": {
                "$ref": "#/$defs/filterField"
              },
              "minValue": {
                "type": "string",
                "title": "Valeur min",
                "layout": {
                  "getItems": {
                    "url": "${rootData.datasets[0].href}/values-labels/${parent.data.field?.key || parent.data.field || ''}?sort=asc&${parent.data.field?.key || parent.data.field || ''}_gte={q}&stringify=true&size=20",
                    "itemKey": "data[\"value\"]",
                    "itemTitle": "data[\"label\"]"
                  }
                }
              },
              "maxValue": {
                "type": "string",
                "title": "Valeur max",
                "layout": {
                  "getItems": {
                    "url": "${rootData.datasets[0].href}/values-labels/${parent.data.field?.key || parent.data.field || ''}?sort=desc&${parent.data.field?.key || parent.data.field || ''}_lte={q}&stringify=true&size=20",
                    "itemKey": "data[\"value\"]",
                    "itemTitle": "data[\"label\"]"
                  }
                }
              }
            }
          },
          {
            "title": "Exclure des valeurs",
            "required": [
              "type",
              "field",
              "values"
            ],
            "additionalProperties": false,
            "properties": {
              "type": {
                "const": "out"
              },
              "field": {
                "$ref": "#/$defs/filterField"
              },
              "values": {
                "type": "array",
                "title": "Valeurs à exclure",
                "items": {
                  "type": "string"
                },
                "layout": {
                  "getItems": {
                    "url": "${rootData.datasets[0].href}/values-labels/${parent.data.field?.key || parent.data.field || ''}?q={q}&q_mode=complete&size=100&stringify=true",
                    "itemKey": "data[\"value\"]",
                    "itemTitle": "data[\"label\"]"
                  }
                }
              }
            }
          },
          {
            "title": "Commence par",
            "required": [
              "type",
              "field",
              "value"
            ],
            "additionalProperties": false,
            "properties": {
              "type": {
                "const": "starts"
              },
              "field": {
                "$ref": "#/$defs/filterField"
              },
              "value": {
                "type": "string",
                "title": "Valeur",
                "layout": {
                  "if": "parent.data.field"
                }
              }
            }
          },
          {
            "title": "Exclure les valeurs vides ou non définies",
            "required": [
              "type",
              "field"
            ],
            "additionalProperties": false,
            "properties": {
              "type": {
                "const": "exists"
              },
              "field": {
                "$ref": "#/$defs/filterField"
              }
            }
          },
          {
            "title": "Restreindre aux valeurs vides ou non définies",
            "required": [
              "type",
              "field"
            ],
            "additionalProperties": false,
            "properties": {
              "type": {
                "const": "notExists"
              },
              "field": {
                "$ref": "#/$defs/filterField"
              }
            }
          }
        ]
      }
    },
    "filterField": {
      "type": "string",
      "title": "Colonne de filtre",
      "layout": {
        "getItems": {
          "url": "${rootData.datasets[0].href}/schema?calculated=false",
          "itemKey": "data[\"key\"]",
          "itemTitle": "data[\"label\"]"
        }
      }
    },
    "colorPalette": {
      "title": "Palette précalculée",
      "required": [
        "type",
        "name"
      ],
      "properties": {
        "type": {
          "const": "palette"
        },
        "name": {
          "type": "string",
          "oneOf": [
            {
              "const": "Accent",
              "title": "Accent"
            },
            {
              "const": "Dark2",
              "title": "Foncé"
            },
            {
              "const": "Paired",
              "title": "Paires"
            },
            {
              "const": "Set1",
              "title": "Ensemble 1"
            },
            {
              "const": "Set2",
              "title": "Ensemble 2"
            },
            {
              "const": "Set3",
              "title": "Ensemble 3"
            },
            {
              "const": "Pastel1",
              "title": "Pastel 1"
            },
            {
              "const": "Pastel2",
              "title": "Pastel 2"
            }
          ],
          "default": "Accent"
        },
        "offset": {
          "type": "integer",
          "title": "Décalage",
          "default": 0
        }
      }
    }
  },
  "$id": "_jl"
}
