(function() { const colors = { white: "#ffffff", navy: "#202565", blue: "#4a56ee", red: "#d76645", yellow: "#f0a742", purple: "#aeb1fd", indicatoHighlight: "#626693", indicatoInitial: "#363a74", }; const content = { heading: "Measuring progress towards a bolder Canadian future.", "fa-c-1": { heading: "Growing to 100 million", subHeading: `A bigger Canada is a bolder Canada. With 100 million people, we will have the skills, ingenuity and drive to build a tax base and economy that can sustain our quality of life and grow our influence.`, link: "/scorecard/growing-to-100-million", }, "ind-c-0": { link: "/scorecard/growing-to-100-million?detailsId=population-growth", }, "ind-c-1": { link: "/scorecard/growing-to-100-million?detailsId=immigrant-admissions", }, "ind-c-2": { link: "/scorecard/growing-to-100-million?detailsId=fertility-rate", }, "ind-c-3": { link: "/scorecard/growing-to-100-million?detailsId=life-expectancy", }, "ind-c-4": { link: "/scorecard/immigration?detailsId=global-reputation", }, "fa-c-2": { heading: "Immigration", subHeading: `New Canadians bring their drive, their grit and their ingenuity to meet Canada's labour market needs, catalyze innovation in our economy and strengthen the fabric of our society.`, link: "/scorecard/immigration", }, "ind-c-5": { link: "/scorecard/immigration?detailsId=public-support-for-immigration", }, "ind-c-6": { link: "/scorecard/immigration?detailsId=provincial-retention-of-immigrants", }, "ind-c-7": { link: "/scorecard/immigration?detailsId=migrant-integration-policy", }, "ind-c-8": { link: "/scorecard/immigration?detailsId=immigrant-income-gap", }, "ind-c-9": { link: "/scorecard/immigration?detailsId=international-students-transitioning", }, "ind-c-10": { link: "/scorecard/immigration?detailsId=temporary-foreign-workers", }, "fa-c-3": { heading: "Economy, innovation and entrepreneurship", subHeading: `The modern economy rewards innovation, creativity and the willingness to build something new. This is a critical foundation for sustainable and shared prosperity.`, link: "/scorecard/economy-innovation-entrepreneurship", }, "ind-c-11": { link: "/scorecard/economy-innovation-entrepreneurship?detailsId=early-stage-entrepreneurship", }, "ind-c-12": { link: "/scorecard/economy-innovation-entrepreneurship?detailsId=business-spending-on-rd", }, "ind-c-13": { link: "/scorecard/economy-innovation-entrepreneurship?detailsId=innovation", }, "ind-c-14": { link: "/scorecard/economy-innovation-entrepreneurship?detailsId=productivity", }, "ind-c-15": { link: "/scorecard/economy-innovation-entrepreneurship?detailsId=business-growth", }, "ind-c-16": { link: "/scorecard/economy-innovation-entrepreneurship?detailsId=diversity", }, "ind-c-17": { link: "/scorecard/economy-innovation-entrepreneurship?detailsId=strength-of-indigenous-economy", }, "ind-c-18": { link: "/scorecard/economy-innovation-entrepreneurship?detailsId=gdp-per-capita", }, "ind-c-19": { link: "/scorecard/economy-innovation-entrepreneurship?detailsId=household-debt", }, "ind-c-20": { link: "/scorecard/economy-innovation-entrepreneurship?detailsId=income-inequality", }, "ind-c-21": { link: "/scorecard/economy-innovation-entrepreneurship?detailsId=global-competitiveness", }, "fa-c-4": { heading: "Education skills & employment", subHeading: `Canadians need the skills that tomorrow's economy requires if Canada is to compete and prosper. And they need to be able to use them. This means high-performing education and training systems, supports for lifelong learning, and creating good jobs.`, link: "/scorecard/education-skills-employment", }, "ind-c-22": { link: "/scorecard/education-skills-employment?detailsId=performance-in-reading", }, "ind-c-23": { link: "/scorecard/education-skills-employment?detailsId=post-secondary-attainment", }, "ind-c-24": { link: "/scorecard/education-skills-employment?detailsId=youth-not-in-employment", }, "ind-c-25": { link: "/scorecard/education-skills-employment?detailsId=participation-in-adult-learning", }, "ind-c-26": { link: "/scorecard/education-skills-employment?detailsId=employment-rate", }, "ind-c-27": { link: "/scorecard/education-skills-employment?detailsId=low-wage-work", }, "fa-c-5": { heading: "Support for children and families", subHeading: `A growing Canada means supports for Canadian families who choose to have children. Robust family supports mean more people working, more jobs, and more economic growth.`, link: "/scorecard/support-for-children-and-families", }, "ind-c-28": { link: "/scorecard/support-for-children-and-families?detailsId=child-care", }, "ind-c-29": { link: "/scorecard/support-for-children-and-families?detailsId=parental-leave", }, "ind-c-30": { link: "/scorecard/support-for-children-and-families?detailsId=employment-rate-for-mothers", }, "ind-c-31": { link: "/scorecard/support-for-children-and-families?detailsId=child-poverty", }, "ind-c-32": { link: "/scorecard/support-for-children-and-families?detailsId=youth-well-being", }, "fa-c-6": { heading: "Infrastructure and environment", subHeading: `A bigger and bolder future for Canada requires infrastructure to support it. It must keep pace with a growing population and be resilient to climate change.`, link: "/scorecard/infrastructure-and-environment", }, "ind-c-33": { link: "/scorecard/infrastructure-and-environment?detailsId=investment-in-infrastructure", }, "ind-c-34": { link: "/scorecard/infrastructure-and-environment?detailsId=housing-affordability", }, "ind-c-35": { link: "/scorecard/infrastructure-and-environment?detailsId=rural-broadband-coverage", }, "ind-c-36": { link: "/scorecard/infrastructure-and-environment?detailsId=population-density", }, "ind-c-37": { link: "/scorecard/infrastructure-and-environment?detailsId=climate-change-performance", }, "ind-c-38": { link: "/scorecard/infrastructure-and-environment?detailsId=resilience", }, "fa-c-7": { heading: "Growing well", subHeading: `Population growth must be environmentally sustainable; and the benefits of growth must be broadly shared by all Canadians.`, link: "/scorecard/growing-well", }, "ind-c-39": { link: "/scorecard/growing-well??detailsId=freedom", }, "ind-c-40": { link: "/scorecard/growing-well??detailsId=social-progress", }, [colors.blue]: { id: "leading", el: document.getElementById("leading"), }, [colors.purple]: { id: "on-track", el: document.getElementById("on-track"), }, [colors.yellow]: { id: "needs-attention", el: document.getElementById("needs-attention"), }, [colors.red]: { id: "falling-behind", el: document.getElementById("falling-behind"), }, }; const defs = ` `; const clickedWheel = localStorage.getItem("clickedWheel"); const overlay = clickedWheel ? "" : `
${window.innerWidth < 800 ? `` : `` }
`; const svg = window.innerWidth < 800 ? ` ${defs} ${overlay}` : // WHEEL ON LARGE SCREENS //this is the overarching SVG the clicked wheel terninary is to see if there's a blur overlaying ` ${defs} // circle background // national scorecard title ${overlay} `; // JS BEGINS const wheelContainer = document.getElementById( window.innerWidth < 800 ? "mobile-wheel" : "wheel-container" ); const scoreWrap = document.getElementById("score-wrap"); const buttonWrap = document.getElementById("button-wrap"); wheelContainer.innerHTML = svg; //this animates the wheel in over time wheelContainer.animate( [ { transform: "scale(0)", opacity: 0 }, { transform: "scale(0.2)" }, { transform: "scale(0.4)" }, { transform: "scale(0.6)" }, { transform: "scale(0.8)" }, { transform: "scale(1)", opacity: 1 }, { transform: "scale(1.05)" }, { transform: "scale(1)" }, ], 1000 ); const heading = document.getElementById("heading"); const subHeading = document.getElementById("sub-heading"); const leftContent = document.getElementById("leftContent"); const filteringTypes = { INDICATOR: "INDICATOR", FOCUSAREA: "FOCUSAREA", RATE: "RATE", }; let lastFilteringType = ""; //this is to fade things in on the left side function fadeInUp(el) { el.animate( [ { opacity: 0, transform: "translateY(50px)" }, { opacity: 1, transform: "translateY(0px)" }, ], 500 ); } //functions to set headings function setHeading(text) { heading.innerHTML = text; } function setSubHeading(text) { subHeading.innerHTML = text; } setHeading(content.heading); fadeInUp(leftContent); //function to set the left subhead text function setIndicatorText(color) { let t = ""; if (colors.yellow === color) t = `This indicator needs attention, but Canada could still meet its target in future years with intervention and support.`; if (colors.purple === color) t = `Canada is on track to meet the target for this indicator or has already achieved the set target. `; if (colors.red === color) t = `Canada is falling behind on this indicator compared to similar countries, or failing to meet its target. Significant work is needed.`; if (colors.blue === color) t = `Canada is leading on this indicator, either ranking among the best internationally or performing well against national goals.`; setSubHeading(t); } if (clickedWheel) { heading.style.transition = "none"; scoreWrap.style.transition = "none"; scoreWrap.style.opacity = 1; scoreWrap.style.maxHeight = window.innerWidth < 800 ? "780px" : "500px"; heading.style.fontSize = window.innerWidth < 800 ? "28px" : "32px"; } setTimeout(function () { const focusAreas = [1, 2, 3, 4, 5, 6].map((i) => document.getElementById(`fa-c-${i}`) ); const indicators = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, ].map((i) => document.getElementById(`ind-c-${i}`)); //if you have not clicked the wheel if (!clickedWheel) { const overlayElem = document.getElementsByClassName("overlay")[0]; //add a click listener to the overlay element overlayElem.addEventListener("click", function () { heading.style.transition = "none"; localStorage.setItem("clickedWheel", true); this.style.display = "none"; this.previousElementSibling.style.filter = ""; scoreWrap.style.maxHeight = window.innerWidth < 800 ? "600px" : "500px"; scoreWrap.style.opacity = 1; heading.style.fontSize = window.innerWidth < 800 ? "28px" : "32px"; if (window.innerWidth < 800) scoreWrap.style.paddingBottom = "40px"; fadeInUp(leftContent); }); } //functio for checking active status function isActive(el) { return el.getAttribute("data-active") === "true"; } //function for highlighting indicators, you pass in the first and last index yo want highlighted function highlightIndicators(firstIndex, lastIndex) { //if there is a last index if (lastIndex) //loop through the indexes for (let i = firstIndex; i <= lastIndex; i++) { // get the current fill const currentFill = indicators[i].getAttribute("fill"); //if the currentFill does not equal the initial indicator and the highlight if ( currentFill !== colors.indicatoInitial && currentFill !== colors.indicatoHighlight ) continue; // set the fill attirbute to the highlight indicators[i].setAttribute("fill", colors.indicatoHighlight); } else { indicators[firstIndex].setAttribute("fill", colors.indicatoHighlight); } } //the highlightFocusArea function takes in an element, it sets that elements fill to white, then finds sibling elements, loops function highlightFocusArea(el) { el.setAttribute("fill", colors.white); const texts = el.nextElementSibling.getElementsByTagName("path"); for (let i = 0; i < texts.length; i++) texts[i].setAttribute("fill", colors.navy); highlightIndicators( parseInt(el.getAttribute("data-first-ind")), parseInt(el.getAttribute("data-last-ind")) ); } function toggleIndicators(active, firstIndex, lastIndex, color) { for (let i = firstIndex; i <= lastIndex; i++) { const indicator = indicators[i]; const activeFill = indicator.getAttribute("data-active-fill"); // set each indicator // if a color was passed // if the slice is active set it to activeFill otherwise set it to colors.indicatoHighlight indicator.setAttribute( "fill", color || (active ? activeFill : colors.indicatoHighlight) ); // ADDED CODE if (active && activeFill !== "#4a56ee") { const sliceTextVectors = indicators[i].nextElementSibling.getElementsByTagName("path"); for (let i = 0; i < sliceTextVectors.length; i++) { sliceTextVectors[i].setAttribute("fill", colors.navy); } } const sliceTextVectors = indicators[i].nextElementSibling.getElementsByTagName("path"); if (!active) { for (let i = 0; i < sliceTextVectors.length; i++) { sliceTextVectors[i].setAttribute("fill", "white"); } } else { for (let i = 0; i < sliceTextVectors.length; i++) { // sliceTextVectors[i].setAttribute("fill", "white"); } } // ADDED CODE } } function toggleFocusArea( el, newActive = isActive(el) ? null : true, indicatorColor ) { //If active, get the currently clicked attribute by the ID and set the heading/subheading and reruns the fade in animation //it also displays the button when appropriate if (newActive) { const cont = content[el.getAttribute("id")]; setHeading(cont.heading); setSubHeading(cont.subHeading); buttonWrap.style.display = "block"; buttonWrap.firstElementChild.setAttribute("href", cont.link); fadeInUp(leftContent); } //set the data-active attribute to the new active variable el.setAttribute("data-active", newActive); if (newActive) highlightFocusArea(el); else unhighlightFocusArea(el); toggleIndicators( newActive, parseInt(el.getAttribute("data-first-ind")), parseInt(el.getAttribute("data-last-ind")), indicatorColor ); } function unhighlightIndicators(firstIndex, lastIndex) { if (lastIndex) { for (let i = firstIndex; i <= lastIndex; i++) { const currentFill = indicators[i].getAttribute("fill"); if ( currentFill !== colors.indicatoInitial && currentFill !== colors.indicatoHighlight ) continue; indicators[i].setAttribute("fill", colors.indicatoInitial); const sliceTextVectors = indicators[i].nextElementSibling.getElementsByTagName("path"); for (let i = 0; i < sliceTextVectors.length; i++) { sliceTextVectors[i].setAttribute("fill", "white"); } } } else { indicators[firstIndex].setAttribute("fill", colors.indicatoInitial); } } function unhighlightFocusArea(el) { el.setAttribute("fill", colors.indicatoHighlight); const texts = el.nextElementSibling.getElementsByTagName("path"); for (let i = 0; i < texts.length; i++) texts[i].setAttribute("fill", colors.white); // here unhighlightIndicators( parseInt(el.getAttribute("data-first-ind")), parseInt(el.getAttribute("data-last-ind")) ); } //when the page loads loop through the focus areas focusAreas.forEach((elem) => { //add an event listener for mouseOvers //add the highlight color if the element does not already have an active state elem.addEventListener("mouseenter", function () { if (isActive(this)) return; highlightFocusArea(this); }); //add a click event listener //if it's already clicked do nothing //if the last filtering type is different from the current filteringtype //reset the wheel and set the last filtering type to the current filtering type // then run the toggleFocusArea function, which elem.addEventListener("click", function () { if (isActive(this)) return; if (lastFilteringType !== filteringTypes.FOCUSAREA) { resetWheel(); lastFilteringType = filteringTypes.FOCUSAREA; } toggleFocusArea(this); resetButtons(); }); elem.addEventListener("mouseleave", function () { if (isActive(this)) return; unhighlightFocusArea(this); }); }); function resetButtons() { ["blue", "red", "yellow", "purple"].forEach((color) => { const className = content[colors[color]].el .getAttribute("class") .replace("active", ""); content[colors[color]].el.setAttribute("class", className); }); scoreWrap.setAttribute("class", ""); } function resetIndicators() { indicators.forEach((indicator, i) => { indicator.setAttribute("fill", colors.indicatoInitial); const sliceTextVectors = indicators[i].nextElementSibling.getElementsByTagName("path"); for (let i = 0; i < sliceTextVectors.length; i++) { sliceTextVectors[i].setAttribute("fill", "white"); } }); } function resetFocusAreas() { focusAreas.forEach((el) => { unhighlightFocusArea(el); el.setAttribute("data-active", false); }); } function resetWheel() { resetButtons(); buttonWrap.style.display = "none"; subHeading.innerText = ""; setHeading(content.heading); for (let i = 0; i < focusAreas.length; i++) { const focusArea = focusAreas[i]; toggleFocusArea(focusArea, false, colors.indicatoInitial); } fadeInUp(leftContent); } indicators.forEach((elem, i) => { elem.addEventListener("mouseenter", function () { if (this.getAttribute("fill").toLowerCase() !== colors.indicatoInitial) return; highlightIndicators(i); }); elem.addEventListener("click", function () { if (lastFilteringType !== filteringTypes.INDICATOR) { lastFilteringType = filteringTypes.INDICATOR; } resetFocusAreas(); resetIndicators(); resetButtons(); const activeFill = this.getAttribute("data-active-fill").toLowerCase(); this.setAttribute("fill", activeFill); const sliceTextVectors = this.nextElementSibling.getElementsByTagName("path"); for (let i = 0; i < sliceTextVectors.length; i++) { if (activeFill !== "#4a56ee") { sliceTextVectors[i].setAttribute("fill", "black"); } else { sliceTextVectors[i].setAttribute("fill", "white"); } } buttonWrap.style.display = "block"; const id = this.getAttribute("id"); buttonWrap.firstElementChild.setAttribute("href", content[id].link); setHeading(this.getAttribute("data-name")); setIndicatorText(activeFill); fadeInUp(leftContent); }); elem.addEventListener("mouseleave", function () { if (this.getAttribute("fill") !== colors.indicatoHighlight) return; unhighlightIndicators(i); }); }); document.getElementById("reset-btn").addEventListener("click", resetWheel); ["leading", "on-track", "needs-attention", "falling-behind"].forEach((id) => { const el = document.getElementById(id); el.addEventListener("click", function () { if (lastFilteringType !== filteringTypes.RATE) { resetWheel(); lastFilteringType = filteringTypes.RATE; } const className = this.getAttribute("class") || ""; const active = className.includes("active"); const newActive = !active; const newClassName = active ? className.replace("active", "") : className + " active"; this.setAttribute("class", newClassName); const colorMap = { leading: colors.blue, "on-track": colors.purple, "needs-attention": colors.yellow, "falling-behind": colors.red, }; const buttonFill = colorMap[id]; setHeading(content.heading); subHeading.innerHTML = ""; buttonWrap.style.display = "none"; indicators.forEach((indicator, i) => { const sliceTextVectors = indicator.nextElementSibling.getElementsByTagName("path"); const indActiveFill = indicator .getAttribute("data-active-fill") .toLowerCase(); if (indActiveFill === buttonFill) { indicator.setAttribute( "fill", newActive ? buttonFill : colors.indicatoInitial ); for (let i = 0; i < sliceTextVectors.length; i++) { if (indActiveFill !== "#4a56ee") { sliceTextVectors[i].setAttribute("fill", newActive ? "black" : "white"); } else { sliceTextVectors[i].setAttribute("fill", newActive ? "white" : "white"); } } } }); const scoreClassName = scoreWrap.getAttribute("class") || ""; const currentActive = scoreClassName.includes("active"); if (newActive && !currentActive) scoreWrap.setAttribute("class", scoreClassName + " active"); else if (currentActive && !newActive) { if (!document.querySelector(".button-container.active")) scoreWrap.setAttribute("class", ""); } if (newActive) scoreWrap.setAttribute("class", scoreClassName + " active"); }); }); }, 500); })()