{"id":357,"date":"2025-01-12T18:16:36","date_gmt":"2025-01-12T17:16:36","guid":{"rendered":"https:\/\/huguesg.fr\/site\/?p=357"},"modified":"2025-01-12T18:16:37","modified_gmt":"2025-01-12T17:16:37","slug":"budget-de-la-ville-de-paris","status":"publish","type":"post","link":"https:\/\/huguesg.fr\/site\/index.php\/2025\/01\/12\/budget-de-la-ville-de-paris\/","title":{"rendered":"Budget de la ville de Paris"},"content":{"rendered":"\n<p>Bienvenue sur notre visualisation interactive des comptes de la ville de Paris pour l&#8217;ann\u00e9e 2023. Ce graphique est con\u00e7u pour offrir une perspective claire et d\u00e9taill\u00e9e des montants allou\u00e9s \u00e0 diff\u00e9rents niveaux de fonctionnement. Gr\u00e2ce \u00e0 une navigation intuitive, vous pouvez explorer les donn\u00e9es en profondeur, de mani\u00e8re \u00e0 mieux comprendre comment les fonds publics sont r\u00e9partis.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Utilisation du Graphique<\/h4>\n\n\n\n<p>Le graphique ci-dessous est interactif et permet une exploration progressive des cr\u00e9dits de paiement. En cliquant sur l\u2019une des barres, vous pouvez zoomer pour r\u00e9v\u00e9ler des informations plus d\u00e9taill\u00e9es sur les montants pr\u00e9vus. Le bouton &#8220;Retour&#8221; en haut de la page vous permet de revenir au niveau pr\u00e9c\u00e9dent.<\/p>\n\n\n\n<p>Les niveaux d&#8217;exploration sont organis\u00e9s comme suit :<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Section <\/strong>: Le budget de la ville est s\u00e9par\u00e9 en 2 sections : une section de fonctionnement, qui doit \u00eatre \u00e0 l&#8217;\u00e9quilibre, et une section d&#8217;investissement.<\/li>\n\n\n\n<li><strong>Sens <\/strong>: Ce graphique pr\u00e9sente de mani\u00e8re distincte les recettes et les d\u00e9penses.<\/li>\n\n\n\n<li><strong>Chapitre <\/strong>: Les comptes sont divis\u00e9s en grands chapitres accessibles ici<\/li>\n\n\n\n<li><strong>Nature budg\u00e9taire<\/strong> : Un niveau de d\u00e9tail en dessous des chapitres<\/li>\n\n\n\n<li><strong>Fonction<\/strong> : La fonction de la d\u00e9pense, plus ou moins pr\u00e9cise en fonction des cas.<\/li>\n<\/ol>\n\n\n\n<h4 class=\"wp-block-heading\">Pourquoi cette visualisation est importante<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Transparence<\/strong> : Permet aux citoyens de voir o\u00f9 et comment l&#8217;argent public est d\u00e9pens\u00e9.<\/li>\n\n\n\n<li><strong>Responsabilit\u00e9<\/strong> : Aide \u00e0 s&#8217;assurer que les ressources sont utilis\u00e9es efficacement et conform\u00e9ment aux priorit\u00e9s nationales.<\/li>\n\n\n\n<li><strong>Engagement<\/strong> : Encourage une participation citoyenne inform\u00e9e et active dans le processus budg\u00e9taire.<\/li>\n<\/ul>\n\n\n\n<h4 class=\"wp-block-heading\">Comment naviguer dans le graphique<\/h4>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Zoomer<\/strong> : Cliquez sur une barre pour voir les d\u00e9tails du niveau inf\u00e9rieur.<\/li>\n\n\n\n<li><strong>Retour<\/strong> : Utilisez le bouton &#8220;Retour&#8221; pour remonter au niveau sup\u00e9rieur.<\/li>\n\n\n\n<li><strong>Interpr\u00e9tation des valeurs<\/strong> : Les montants sont affich\u00e9s en milliards (B), millions (M), ou en valeur r\u00e9elle avec des arrondis \u00e0 trois chiffres significatifs pour une meilleure clart\u00e9.<\/li>\n<\/ul>\n\n\n\n<button id=\"backButton\" onclick=\"goBack()\">Retour<\/button>\n  <div id=\"chart\"><\/div>\n  <script>\n\n\/\/ URL du fichier CSV en ligne\nconst csvUrl = 'https:\/\/huguesg.fr\/docs\/paris2023.csv';\n\nconst codeTitreMapping = {\n};\n\n\nconst categoriesMapping = {\n};\n\n\n\/\/ Fonction pour parser les donn\u00e9es CSV\nfunction parseCSV(csv) {\n  const lines = csv.split('\\n');\n  const headers = lines[0].split(';');\n  const data = lines.slice(1).map(line => {\n    const values = line.split(';');\n    if (values.length === headers.length) {\n      let obj = {};\n      headers.forEach((header, index) => {\n        obj[header.trim()] = values[index] ? values[index].trim() : '';\n      });\n      return obj;\n    }\n    return null;\n  }).filter(line => line !== null);\n  return data;\n}\n\n\/\/ Charger Google Charts\ngoogle.charts.load('current', {packages: ['corechart']});\ngoogle.charts.setOnLoadCallback(loadCSV);\n\nlet rawData = [];\nlet currentLevel = 'Section Budg\u00e9taire (I\/F)';\nlet currentData = [];\nlet dataStack = [];\nlet breadcrumb = [];\n\nfunction loadCSV() {\n  fetch(csvUrl)\n    .then(response => response.text())\n    .then(csv => {\n      rawData = parseCSV(csv);\n      if (Array.isArray(rawData) && rawData.length > 0) {\n        currentData = rawData;\n        drawInitialChart();\n      } else {\n        console.error('Error: Parsed data is not a valid array.');\n      }\n    })\n    .catch(error => console.error('Error loading CSV:', error));\n}\n\nfunction drawInitialChart() {\n  breadcrumb = [];\n  drawChart('Section Budg\u00e9taire (I\/F)', rawData, 'Comptes de la ville de Paris');\n}\n\nfunction drawChart(level, data, title) {\n  if (dataStack.length === 0 || dataStack[dataStack.length - 1].level !== level) {\n    dataStack.push({level: level, data: data});\n  }\n  currentLevel = level;\n  currentData = data;\n\n  if (!Array.isArray(data)) {\n    console.error('Error: Data is not an array.');\n    return;\n  }\n\n\n  const groupedData = groupBy(data, level);\n\n  const mappedGroupedDataTemp = (level === 'Code Titre')\n    ? Object.fromEntries(Object.entries(groupedData).map(([key, value]) => {\n        const label = codeTitreMapping[key] || key; \/\/ Utilise la correspondance ou conserve la cl\u00e9 originale si elle n'existe pas\n        return [label, value];\n      }))\n    : groupedData;\n\nconst mappedGroupedDataTemp2 = (level === 'Cat\u00e9gorie')\n    ? Object.fromEntries(Object.entries(mappedGroupedDataTemp).map(([key, value]) => {\n        const label = categoriesMapping [key] || key; \/\/ Utilise la correspondance ou conserve la cl\u00e9 originale si elle n'existe pas\n        return [label, value];\n      }))\n    : mappedGroupedDataTemp;\n\n\n\/\/ Si le niveau est \"Libell\u00e9 Programme\", concat\u00e9ner le code et le libell\u00e9\n  const mappedGroupedDataTemp3 = (level === 'Libell\u00e9 Programme')\n    ? Object.fromEntries(Object.entries(mappedGroupedDataTemp2).map(([key, value]) => {\n        const concatKey = `${value[0]['Programme']} - ${key}`;\n        return [concatKey, value];\n      }))\n    : mappedGroupedDataTemp2;\n\n\/\/ Si le niveau est \"Libell\u00e9 Action\", concat\u00e9ner le code et le libell\u00e9\n  const mappedGroupedData = (level === 'Libell\u00e9 Action')\n    ? Object.fromEntries(Object.entries(mappedGroupedDataTemp3).map(([key, value]) => {\n        const concatKey = `${value[0]['Action']} - ${key}`;\n        return [concatKey, value];\n      }))\n    : mappedGroupedDataTemp3;\n\n  const chartData = new google.visualization.DataTable();\n  \n  const labelMapping = {\n    'Section Budg\u00e9taire (I\/F)': 'Section',\n    'Sens (D\u00e9pense \/ Recette)': 'Sens',\n    'Chapitre Niveau vote - Texte descriptif': 'Chapitre',\n    'Nature Budg\u00e9taire - Texte': 'Nature budg\u00e9taire',\n    'Fonction - Texte': 'Fonction',\n    'Mandat\u00e9 \/ Titr\u00e9 apr\u00e8s r\u00e9gul.': 'Montant'\n  };\n  const displayLabel = labelMapping[level] || level;\n  chartData.addColumn('string', displayLabel);\n  chartData.addColumn('number', 'Montant');\n\n  const sortedData = Object.entries(mappedGroupedData).sort((a, b) => {\n  \tconst sumA = a[1].reduce((acc, row) => acc + parseFloat(row['Mandat\u00e9 \/ Titr\u00e9 apr\u00e8s r\u00e9gul.'].replace(\/\\s+\/g, \"\") || 0), 0);\n  \tconst sumB = b[1].reduce((acc, row) => acc + parseFloat(row['Mandat\u00e9 \/ Titr\u00e9 apr\u00e8s r\u00e9gul.'].replace(\/\\s+\/g, \"\") || 0), 0);\n  \treturn sumB - sumA; \/\/ tri d\u00e9croissant\n  });\n\n  chartData.addColumn({ type: 'string', role: 'annotation' });\n\n  for (let [key, group] of sortedData) {\nconsole.log(group);\n    const sum = group.reduce((acc, row) => acc + parseFloat(row['Mandat\u00e9 \/ Titr\u00e9 apr\u00e8s r\u00e9gul.'].replace(\/\\s+\/g, \"\") || 0), 0);\n    chartData.addRow([key, {v: sum, f: formatValue(sum)}, formatValue(sum)]);\n  }\n\n  const options = {\n    title: title,\n    width: 800,\n    height: 800,\n    hAxis: { title: displayLabel, minValue: 0 },\n    vAxis: { title: 'Montant', format: 'short'},\n    legend: { position: 'none' },\n    annotations: {\n      alwaysOutside: true,\n      textStyle: {\n        fontSize: 12,\n        auraColor: 'none',\n        color: '#555'\n      }\n    }\n  };\n\n  const chart = new google.visualization.BarChart(document.getElementById('chart'));\n  chart.draw(chartData, options);\n\n  google.visualization.events.addListener(chart, 'select', () => {\n    const selection = chart.getSelection();\n    if (selection.length > 0) {\n      const selectedItem = chartData.getValue(selection[0].row, 0);\n      const nextLevel = getNextLevel(level);\n      if (nextLevel) {\n        breadcrumb.push(selectedItem);\n        currentData = mappedGroupedData[selectedItem];\n        drawChart(nextLevel, currentData, 'Budget de la ville de Paris 2023 - ' + breadcrumb.join(' > '));\n      }\n    }\n  });\n\n  if (dataStack.length > 1) {\n    document.getElementById('backButton').style.display = 'block';\n  } else {\n    document.getElementById('backButton').style.display = 'none';\n  }\n}\n\nfunction groupBy(data, key) {\n  if (!Array.isArray(data)) {\n    console.error('Error: Data is not an array.');\n    return {};\n  }\n\n  return data.reduce((result, currentValue) => {\n    (result[currentValue[key]] = result[currentValue[key]] || []).push(currentValue);\n    return result;\n  }, {});\n}\n\nfunction getNextLevel(currentLevel) {\n  switch (currentLevel) {\n    case 'Section Budg\u00e9taire (I\/F)': return 'Sens (D\u00e9pense \/ Recette)';\n    case 'Sens (D\u00e9pense \/ Recette)': return 'Chapitre Niveau vote - Texte descriptif';\n    case 'Chapitre Niveau vote - Texte descriptif': return 'Nature Budg\u00e9taire - Texte';\n    case 'Nature Budg\u00e9taire - Texte': return 'Fonction - Texte';\n    default: return null;\n  }\n}\n\nfunction goBack() {\n  if (dataStack.length > 1) {\n    dataStack.pop(); \/\/ Remove current level\n    breadcrumb.pop(); \/\/ Remove last breadcrumb\n    const previous = dataStack.pop(); \/\/ Get previous level\n    currentLevel = previous.level;\n    currentData = previous.data;\n    drawChart(currentLevel, currentData, 'Budget de la ville de Paris 2023 - ' + breadcrumb.join(' > '));\n  }\n}\n\n\nfunction formatValue(value) {\n  if (Number(value) >= 1e9) {\n    return (Number(value)\/ 1e9).toPrecision(3) + 'B\u20ac';\n  } else if (Number(value) >= 1e6) {\n    return (Number(value)\/ 1e6).toPrecision(3) + 'M\u20ac';\n  } else {\n    return Number(value).toPrecision(3) + '\u20ac';\n  }\n}\n\n\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>Bienvenue sur notre visualisation interactive des comptes de la ville de Paris pour l&#8217;ann\u00e9e 2023. Ce graphique est con\u00e7u pour offrir une perspective claire et d\u00e9taill\u00e9e des montants allou\u00e9s \u00e0 diff\u00e9rents niveaux de fonctionnement. Gr\u00e2ce \u00e0 une navigation intuitive, vous pouvez explorer les donn\u00e9es en profondeur, de mani\u00e8re \u00e0 mieux comprendre comment les fonds publics [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ocean_post_layout":"","ocean_both_sidebars_style":"","ocean_both_sidebars_content_width":0,"ocean_both_sidebars_sidebars_width":0,"ocean_sidebar":"","ocean_second_sidebar":"","ocean_disable_margins":"enable","ocean_add_body_class":"","ocean_shortcode_before_top_bar":"","ocean_shortcode_after_top_bar":"","ocean_shortcode_before_header":"","ocean_shortcode_after_header":"","ocean_has_shortcode":"","ocean_shortcode_after_title":"","ocean_shortcode_before_footer_widgets":"","ocean_shortcode_after_footer_widgets":"","ocean_shortcode_before_footer_bottom":"","ocean_shortcode_after_footer_bottom":"","ocean_display_top_bar":"default","ocean_display_header":"default","ocean_header_style":"","ocean_center_header_left_menu":"","ocean_custom_header_template":"","ocean_custom_logo":0,"ocean_custom_retina_logo":0,"ocean_custom_logo_max_width":0,"ocean_custom_logo_tablet_max_width":0,"ocean_custom_logo_mobile_max_width":0,"ocean_custom_logo_max_height":0,"ocean_custom_logo_tablet_max_height":0,"ocean_custom_logo_mobile_max_height":0,"ocean_header_custom_menu":"","ocean_menu_typo_font_family":"","ocean_menu_typo_font_subset":"","ocean_menu_typo_font_size":0,"ocean_menu_typo_font_size_tablet":0,"ocean_menu_typo_font_size_mobile":0,"ocean_menu_typo_font_size_unit":"px","ocean_menu_typo_font_weight":"","ocean_menu_typo_font_weight_tablet":"","ocean_menu_typo_font_weight_mobile":"","ocean_menu_typo_transform":"","ocean_menu_typo_transform_tablet":"","ocean_menu_typo_transform_mobile":"","ocean_menu_typo_line_height":0,"ocean_menu_typo_line_height_tablet":0,"ocean_menu_typo_line_height_mobile":0,"ocean_menu_typo_line_height_unit":"","ocean_menu_typo_spacing":0,"ocean_menu_typo_spacing_tablet":0,"ocean_menu_typo_spacing_mobile":0,"ocean_menu_typo_spacing_unit":"","ocean_menu_link_color":"","ocean_menu_link_color_hover":"","ocean_menu_link_color_active":"","ocean_menu_link_background":"","ocean_menu_link_hover_background":"","ocean_menu_link_active_background":"","ocean_menu_social_links_bg":"","ocean_menu_social_hover_links_bg":"","ocean_menu_social_links_color":"","ocean_menu_social_hover_links_color":"","ocean_disable_title":"default","ocean_disable_heading":"default","ocean_post_title":"","ocean_post_subheading":"","ocean_post_title_style":"","ocean_post_title_background_color":"","ocean_post_title_background":0,"ocean_post_title_bg_image_position":"","ocean_post_title_bg_image_attachment":"","ocean_post_title_bg_image_repeat":"","ocean_post_title_bg_image_size":"","ocean_post_title_height":0,"ocean_post_title_bg_overlay":0.5,"ocean_post_title_bg_overlay_color":"","ocean_disable_breadcrumbs":"default","ocean_breadcrumbs_color":"","ocean_breadcrumbs_separator_color":"","ocean_breadcrumbs_links_color":"","ocean_breadcrumbs_links_hover_color":"","ocean_display_footer_widgets":"default","ocean_display_footer_bottom":"default","ocean_custom_footer_template":"","ocean_post_oembed":"","ocean_post_self_hosted_media":"","ocean_post_video_embed":"","ocean_link_format":"","ocean_link_format_target":"self","ocean_quote_format":"","ocean_quote_format_link":"post","ocean_gallery_link_images":"on","ocean_gallery_id":[],"footnotes":""},"categories":[1],"tags":[],"class_list":["post-357","post","type-post","status-publish","format-standard","hentry","category-non-classe","entry"],"_links":{"self":[{"href":"https:\/\/huguesg.fr\/site\/index.php\/wp-json\/wp\/v2\/posts\/357","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/huguesg.fr\/site\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/huguesg.fr\/site\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/huguesg.fr\/site\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/huguesg.fr\/site\/index.php\/wp-json\/wp\/v2\/comments?post=357"}],"version-history":[{"count":8,"href":"https:\/\/huguesg.fr\/site\/index.php\/wp-json\/wp\/v2\/posts\/357\/revisions"}],"predecessor-version":[{"id":365,"href":"https:\/\/huguesg.fr\/site\/index.php\/wp-json\/wp\/v2\/posts\/357\/revisions\/365"}],"wp:attachment":[{"href":"https:\/\/huguesg.fr\/site\/index.php\/wp-json\/wp\/v2\/media?parent=357"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/huguesg.fr\/site\/index.php\/wp-json\/wp\/v2\/categories?post=357"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/huguesg.fr\/site\/index.php\/wp-json\/wp\/v2\/tags?post=357"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}