{"id":21522,"date":"2026-06-03T12:23:07","date_gmt":"2026-06-03T12:23:07","guid":{"rendered":"https:\/\/www.greenpeace.org\/india\/?page_id=21522"},"modified":"2026-06-29T10:06:09","modified_gmt":"2026-06-29T10:06:09","slug":"br-thank-you","status":"publish","type":"page","link":"https:\/\/www.greenpeace.org\/india\/en\/br-thank-you\/","title":{"rendered":"BR thank you"},"content":{"rendered":"\n <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/d3\/7.8.5\/d3.min.js\"><\/script>\n        <script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/d3-cloud\/1.2.7\/d3.layout.cloud.min.js\"><\/script>\n        <style>\n            @import url('https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;800 &display=swap');\n\n            body {\n                font-family: 'Inter', sans-serif;\n                background-color: #f8f9fa; \/* Equivalent to bg-slate-50 *\/\n            }\n\n            \/* Custom aspect-ratio container with max-width *\/\n            .cloud-wrapper {\n                width: 100%;\n                max-width: 672px; \/* Equivalent to max-w-2xl *\/\n                aspect-ratio: 16 \/ 10;\n                border-radius: 1.5rem; \/* Equivalent to rounded-3xl *\/\n                border: 1px solid #f1f5f9;\n                position: relative;\n            }\n\n            \/* Float the settings trigger on top of the container cleanly *\/\n            .settings-trigger {\n                position: absolute;\n                top: 1rem;\n                right: 1rem;\n                z-index: 10;\n                opacity: 0.4;\n                transition: opacity 0.2s ease-in-out;\n            }\n\n            .settings-trigger:hover {\n                opacity: 1;\n            }\n        <\/style>\n\n <div\n            id=\"word-cloud-container\" class=\"cloud-wrapper d-flex align-items-center justify-content-center bg-white shadow-sm p-4 p-sm-5\"><!-- SVG will render here dynamically -->\n        <\/div>\n\n        <!-- API Settings Modal -->\n        <div class=\"modal fade\" id=\"apiSettingsModal\" tabindex=\"-1\" aria-labelledby=\"apiSettingsModalLabel\" aria-hidden=\"true\">\n            <div class=\"modal-dialog modal-dialog-centered\">\n                <div class=\"modal-content rounded-4 border-0 shadow-lg\">\n                    <div class=\"modal-header border-0 pb-0\">\n                        <h5 class=\"modal-title font-weight-bold\" id=\"apiSettingsModalLabel\">API Source Settings<\/h5>\n                        <button type=\"button\" class=\"btn-close\" data-bs-shadow=\"none\" data-bs-dismiss=\"modal\" aria-label=\"Close\"><\/button>\n                    <\/div>\n                    <div\n                        class=\"modal-body\">\n                        <!-- Error Feedback Box -->\n                        <div id=\"apiErrorAlert\" class=\"alert alert-danger d-none py-2 px-3 mb-3 text-xs\" style=\"font-size: 0.85rem;\" role=\"alert\"><\/div>\n\n                        <form\n                            id=\"apiSettingsForm\" onsubmit=\"handleApiSubmit(event)\">\n                            <!-- API URL -->\n                            <div class=\"mb-3\">\n                                <label for=\"apiUrl\" class=\"form-label text-secondary small fw-medium\">GET Request URL<\/label>\n                                <input type=\"url\" class=\"form-control rounded-3\" id=\"apiUrl\" placeholder=\"https:\/\/api.example.com\/data\" required>\n                            <\/div>\n\n                            <div\n                                class=\"row\">\n                                <!-- Auth Header Name -->\n                                <div class=\"col-md-5 mb-3\">\n                                    <label for=\"authHeader\" class=\"form-label text-secondary small fw-medium\">Auth Header Name<\/label>\n                                    <input type=\"text\" class=\"form-control rounded-3\" id=\"authHeader\" placeholder=\"Authorization\" value=\"Authorization\">\n                                <\/div>\n                                <!-- Auth Key Value -->\n                                <div class=\"col-md-7 mb-3\">\n                                    <label for=\"authValue\" class=\"form-label text-secondary small fw-medium\">Auth Key \/ Token<\/label>\n                                    <input type=\"text\" class=\"form-control rounded-3\" id=\"authValue\" placeholder=\"Bearer your-token-here\">\n                                <\/div>\n                            <\/div>\n\n                            <div class=\"d-grid mt-2\">\n                                <button type=\"submit\" id=\"fetchButton\" class=\"btn btn-primary rounded-3 py-2 fw-medium\">\n                                    <span id=\"fetchBtnSpinner\" class=\"spinner-border spinner-border-sm d-none me-2\" role=\"status\" aria-hidden=\"true\"><\/span>\n                                    Fetch and Generate Cloud\n                                <\/button>\n                            <\/div>\n                        <\/form>\n                    <\/div>\n                <\/div>\n            <\/div>\n        <\/div>\n\n        <!-- Bootstrap JS -->\n        <script src=\"https:\/\/cdn.jsdelivr.net\/npm\/bootstrap@5.3.3\/dist\/js\/bootstrap.bundle.min.js\"><\/script>\n\n        <script>\n            \/\/ Default Source JSON Object (used as fallback\/initial render)\n            fetchSourceData()\n            const defaultSourceData = {\n                \"entry_count\": 5,\n                \"field_data\": {\n                    \"2\": 3,\n                    \"1\": {\n                        \"First Choice\": 3,\n                        \"Second Choice\": 2,\n                        \"Third Choice\": 0\n                    }\n                },\n                \"status\": \"complete\",\n                \"timestamp\": 1780485060,\n                \"labels\": {\n                    \"2\": \"Email\",\n                    \"1\": {\n                        \"label\": \"word cloud\",\n                        \"choices\": {\n                            \"First Choice\": \"First Choice\",\n                            \"Second Choice\": \"Second Choice\",\n                            \"Third Choice\": \"Third Choice\"\n                        }\n                    }\n                }\n            };\n\n            \/\/ This will store our working dataset\n            let dataset = [];\n\n            \/\/ Extract dataset from standard JSON layout safely\n            function parseJsonToDataset(rawJson) {\n                try {\n                    let rawChoices = null;\n\n                    \/\/ Check standard structure: field_data[\"1\"]\n                    if (rawJson && rawJson.field_data && rawJson.field_data[\"1\"]) {\n                        rawChoices = rawJson.field_data[\"1\"];\n                    } else if (rawJson && typeof rawJson === 'object') { \/\/ Fallback to checking if the object is already a flat dictionary of weights\n                        rawChoices = rawJson;\n                    }\n\n                    if (! rawChoices || typeof rawChoices !== 'object') {\n                        throw new Error(\"Unable to locate valid choice mapping in the JSON response.\");\n                    }\n                    console.log(rawChoices)\n                    return Object.entries(rawChoices).map(([text, value]) => ({text: text, size: Number(value)}));\n                } catch (err) {\n                    throw new Error(\"Data parsing failed. Check if JSON matches schema: \" + err.message);\n                }\n            }\n\n            \/\/ Initialize with default fallback dataset\n            \/\/ dataset = parseJsonToDataset(defaultSourceData);\n\n            \/\/ Modern, vibrant color palette\n            const colors = [\"#6366f1\", \"#a855f7\", \"#ec4899\"];\n\n            let maxFontSize = 70; \/\/ High starting target font size\n\n            function renderCloud() {\n                const container = document.getElementById('word-cloud-container');\n\n                \/\/ Retain the settings button while clearing SVGs\n                const svgs = container.querySelectorAll('svg:not(.bi-gear-fill)');\n                svgs.forEach(svg => svg.remove());\n\n                const width = container.clientWidth;\n                const height = container.clientHeight;\n\n                \/\/ Map dataset sizes to dynamic font-size bounds\n                const sizes = dataset.map(w => w.size);\n                const minSize = Math.min(... sizes);\n                const maxSize = Math.max(... sizes);\n\n                const fontSizeScale = d3.scaleLinear().domain([minSize, maxSize]).range([24, maxFontSize]); \/\/ Keeps the lowest value (0) readable at 24px\n\n                const layoutWords = dataset.map(w => ({\n                    text: w.text,\n                    size: fontSizeScale(w.size)\n                }));\n\n                \/\/ Instantiate d3-cloud layout engine\n                const cloudLayout = d3.layout.cloud().size([width, height]).words(layoutWords).padding(15).rotate(() => 0).fontSize(d => d.size).on(\"end\", (renderedWords) => {\n                    \/\/ Fail-safe to ensure all choices are rendered.\n                    \/\/ If a word is too big to fit, D3-cloud silent-drops it.\n                    if (renderedWords.length<dataset.length) {\n                        maxFontSize -= 4; \/\/ Decrement and recalculate scale\n                        renderCloud();\n                        return;\n                    }\n                    draw(renderedWords, width, height);\n                });\n\n                cloudLayout.start();\n            }\n\n            \/\/ Render calculated words into SVG\n            function draw(words, width, height) {\n                const svg = d3.select(\"#word-cloud-container\").append(\"svg\").attr(\"width\", width).attr(\"height\", height).attr(\"viewBox\", `0 0 ${width} ${height}`).attr(\"class\", \"w-100 h-100\").append(\"g\").attr(\"transform\", `translate(${\n                    width \/ 2\n                }, ${\n                    height \/ 2\n                })`);\n\n                svg.selectAll(\"text\").data(words).enter().append(\"text\").style(\"font-size\", d => d.size + \"px\").style(\"font-family\", \"Inter\").style(\"font-weight\", \"800\").style(\"fill\", (d, i) => colors[i % colors.length]).attr(\"text-anchor\", \"middle\").attr(\"transform\", d => `translate(${\n                    d.x\n                }, ${\n                    d.y\n                })`).text(d => d.text);\n            }\n\n            \/\/ Asynchronous GET Request to fetch remote dataset\n            async function fetchSourceData() {\n                const url = \"https:\/\/www.greenpeace.org\/india\/wp-json\/gf\/v2\/forms\/7\/results\/?nocache=1\"\n                const headerName = \"Authorization\"\n                const headerValue = \"Basic Y2tfYzUwYTg2MGRlNjZiYWUwMmY5MDNmNzBlM2RmMmY1N2M0ODZhYTljNzpjc19lMWZlMjkzZjJlNWFhZDg1ZjBkYjRkYWIwYjE3MTE5NGUyOTEwYTMx\"\n\n                try {\n                    const headers = new Headers();\n                    \/\/ Attach authorization header if provided\n                    if (headerName && headerValue) {\n                        headers.append(headerName.trim(), headerValue.trim());\n                    }\n\n                    const response = await fetch(url, {\n                        method: 'GET',\n                        headers: headers\n                    });\n\n                    if (! response.ok) {\n                        throw new Error(`Server responded with status code: ${\n                            response.status\n                        } (${\n                            response.statusText\n                        })`);\n                    }\n\n                    const jsonResult = await response.json();\n\n                    \/\/ Parse extracted records\n                    const parsedDataset = parseJsonToDataset(jsonResult);\n\n                    \/\/ Assign and reset layout font parameters\n                    dataset = parsedDataset;\n                    maxFontSize = 70;\n\n                    \/\/ Rerender cloud with new dataset\n                    renderCloud();\n\n                    \/\/ Close settings modal on successful fetch\n                    const modalEl = document.getElementById('apiSettingsModal');\n                    const modalInstance = bootstrap.Modal.getInstance(modalEl);\n                    if (modalInstance) {\n                        modalInstance.hide();\n                    }\n                } catch (error) { \/\/ Show localized error messages on the modal cleanly\n                    errorAlert.innerText = `Fetch Failed: ${\n                        error.message\n                    }`;\n                    errorAlert.classList.remove('d-none');\n                }\n            }\n\n            \/\/ Handle settings form submissions\n\n            \/\/ Initialize rendering\n            window.onload = renderCloud;\n\n            \/\/ Automatically recalculate on window resize\n            let resizeTimer;\n            window.addEventListener('resize', () => {\n                clearTimeout(resizeTimer);\n                resizeTimer = setTimeout(() => {\n                    maxFontSize = 70; \/\/ Reset starting size on window resize\n                    renderCloud();\n                }, 200);\n            });\n        <\/script>\n","protected":false},"excerpt":{"rendered":"<p>API Source Settings GET Request URL Auth Header Name Auth Key \/ Token Fetch and Generate Cloud<\/p>\n","protected":false},"author":65,"featured_media":21450,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"ep_exclude_from_search":false,"p4_hide_page_title_checkbox":"","p4_title":"","p4_subtitle":"","p4_description":"","background_image_id":"","background_image":"","p4_button_title":"","p4_button_link":"","p4_button_link_checkbox":"","p4_og_title":"","p4_og_description":"","p4_og_image":"","p4_og_image_id":"","p4_seo_canonical_url":"","p4_campaign_name":"","p4_local_project":"","p4_basket_name":"","p4_department":"","footnotes":""},"categories":[],"tags":[],"class_list":["post-21522","page","type-page","status-publish","has-post-thumbnail","hentry"],"_links":{"self":[{"href":"https:\/\/www.greenpeace.org\/india\/en\/wp-json\/wp\/v2\/pages\/21522","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.greenpeace.org\/india\/en\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.greenpeace.org\/india\/en\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.greenpeace.org\/india\/en\/wp-json\/wp\/v2\/users\/65"}],"replies":[{"embeddable":true,"href":"https:\/\/www.greenpeace.org\/india\/en\/wp-json\/wp\/v2\/comments?post=21522"}],"version-history":[{"count":3,"href":"https:\/\/www.greenpeace.org\/india\/en\/wp-json\/wp\/v2\/pages\/21522\/revisions"}],"predecessor-version":[{"id":21525,"href":"https:\/\/www.greenpeace.org\/india\/en\/wp-json\/wp\/v2\/pages\/21522\/revisions\/21525"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.greenpeace.org\/india\/en\/wp-json\/wp\/v2\/media\/21450"}],"wp:attachment":[{"href":"https:\/\/www.greenpeace.org\/india\/en\/wp-json\/wp\/v2\/media?parent=21522"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.greenpeace.org\/india\/en\/wp-json\/wp\/v2\/categories?post=21522"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.greenpeace.org\/india\/en\/wp-json\/wp\/v2\/tags?post=21522"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}