diff --git a/app/assets/stylesheets/tpi.scss b/app/assets/stylesheets/tpi.scss index 614daf86d..d3605b988 100644 --- a/app/assets/stylesheets/tpi.scss +++ b/app/assets/stylesheets/tpi.scss @@ -26,6 +26,7 @@ @import "tpi/navbar"; @import "tpi/publications"; @import "tpi/bubble-chart"; +@import "tpi/bubble-chart-countries"; @import "tpi/charts"; @import "tpi/base-tooltip"; @import "tpi/info-tooltip"; diff --git a/app/assets/stylesheets/tpi/_bubble-chart-countries.scss b/app/assets/stylesheets/tpi/_bubble-chart-countries.scss new file mode 100644 index 000000000..f1faf39ee --- /dev/null +++ b/app/assets/stylesheets/tpi/_bubble-chart-countries.scss @@ -0,0 +1,195 @@ +@import "colors"; +@import "typography"; +$tape-height: 8px; +$tape-color: rgba(25, 25, 25, 0.1); +$cell-height: 80px; +$cell-height-banks: 100px; +$legend-image-width: 60px; + +.bubble-chart__container__grid { + display: none; + @include desktop { + grid-template-columns: 0.5fr 0.5fr 1.5fr 1fr 1fr 1fr; + padding: 0; + display: grid; + } +} + +.bubble-chart__container__mobile { + display: block; + width: 100%; + padding: 10px; + + .country-bubble-mobile { + width: 100%; + border: 1px solid $ascor-background-color; + + > ul > li:last-of-type .country-bubble-mobile__item { + border-bottom: none; + } + + &__item { + width: 100%; + display: flex; + justify-content: space-between; + font-size: 16px; + font-style: normal; + + &.--pillar { + font-weight: 700; + font-family: $font-family-bold; + background: $ascor-background-color; + color: #fff; + padding: 20px 10px; + cursor: pointer; + border-bottom: 1px solid $grey-medium; + &.--open { + border-bottom: none; + } + } + &.--area { + color: #000; + padding: 10px; + font-family: $font-family-regular; + border-top: 1px solid $ascor-background-color; + cursor: pointer; + &.--open { + border-bottom: 1px solid $grey-medium; + } + } + + .chevron-icon { + width: 12px; + } + + &__result { + font-family: $font-family-regular; + font-size: 16px; + + &__title { + display: flex; + align-items: center; + gap: 12px; + width: 100%; + padding: 10px; + border-bottom: 1px solid $grey-medium; + cursor: pointer; + min-height: 45px; + position: relative; + + div { + width: 20px; + height: 20px; + border-radius: 50%; + } + } + + &:not(:last-of-type) .country-bubble-mobile__item__result__title { + border-bottom-style: dashed; + } + + &.--open { + .country-bubble-mobile__item__result__title { + border-bottom: none; + position: absolute; + } + .country-bubble-mobile__item__result__countries { + border-bottom: 1px solid $grey-medium; + border-bottom-style: dashed; + } + } + + &:last-of-type { + .country-bubble-mobile__item__result__countries { + border-bottom: none; + } + } + + &__countries { + padding: 10px 0px 10px 42px; + min-height: 45px; + li:not(:last-of-type) { + padding-bottom: 10px; + } + } + } + } + } +} + +.bubble-chart__cell-country { + position: relative; + height: $cell-height-banks; + display: flex; + align-items: center; + border-right: calc(#{$tape-height / 2}) dashed $tape-color; + + & > *:first-child { + margin: auto; + z-index: 1; + } + + &::before { + background-color: $tape-color; + content: ""; + position: absolute; + top: calc(50% - #{$tape-height / 2}); + height: $tape-height; + width: calc(100% + #{$tape-height / 2}); + } +} + +.bubble-chart_circle_country { + circle:hover { + stroke-width: 3; + stroke: $black !important; + } +} + +.bubble-chart__level-country { + border-right: calc(#{$tape-height / 2}) dashed $tape-color; + position: relative; + padding-left: 20px; + height: 100%; +} + +.bubble-chart__level-title-country { + height: 100%; + font-family: $font-family-bold; + font-size: 16px; + color: $black; + margin-bottom: 20px; +} + +.bubble-chart__level-area-country { + font-family: $font-family-bold; + font-size: 16px; + background-color: $ascor-background-color; + color: white; + padding: 10px; + width: 100%; + display: flex; + align-items: center; + + color: $black; + text-align: end; + margin-right: 14px; + grid-column: span 2; + height: 100%; + padding: 46px 0 46px; + gap: 16px; + background-color: white; + + &__line { + border: 8px solid #e8e8e8; + border-right: none; + height: 100%; + flex: 1; + } + + &__area { + text-align: end; + padding-right: 14px; + flex: 1; + } +} diff --git a/app/assets/stylesheets/tpi/_bubble-chart.scss b/app/assets/stylesheets/tpi/_bubble-chart.scss index b290bdca1..67189583b 100644 --- a/app/assets/stylesheets/tpi/_bubble-chart.scss +++ b/app/assets/stylesheets/tpi/_bubble-chart.scss @@ -2,7 +2,7 @@ @import "typography"; $tape-height: 8px; -$tape-color: rgba(25,25,25,0.1); +$tape-color: rgba(25, 25, 25, 0.1); $cell-height: 80px; $cell-height-banks: 100px; $legend-image-width: 60px; @@ -21,7 +21,6 @@ $legend-image-width: 60px; .last { border-right: none; } - } &--banks { @@ -62,28 +61,6 @@ $legend-image-width: 60px; } } -.bubble-chart__cell-country { - position: relative; - height: $cell-height-banks; - display: flex; - align-items: center; - border-right: calc(#{$tape-height / 2}) dashed $tape-color; - - & > *:first-child { - margin: auto; - z-index: 1; - } - - &::before { - background-color: $tape-color; - content: ""; - position: absolute; - top: calc(50% - #{$tape-height / 2}); - height: $tape-height; - width: calc(100% + #{$tape-height / 2}); - } -} - .bubble-chart_circle { circle:hover { stroke-width: 14; @@ -91,13 +68,6 @@ $legend-image-width: 60px; } } -.bubble-chart_circle_country { - circle:hover { - stroke-width: 3; - stroke: $black!important; - } -} - .bubble-tip { font-size: 14px; padding: 10px; @@ -201,28 +171,6 @@ $legend-image-width: 60px; } } -.bubble-chart__level-country { - border-right: calc(#{$tape-height / 2}) dotted $tape-color; - position: relative; - padding-left: 20px; - height: 100%; -} - -.bubble-chart__level-title-country { - height: 100%; - font-family: $font-family-bold; - font-size: 16px; - color: $black; -} - -.bubble-chart__level-area-country { - font-family: $font-family-bold; - font-size: 16px; - color: $black; - text-align: end; - margin-right: 14px; -} - .bubble-chart__container--banks { .bubble-chart__level-title { font-family: $font-family-bold; diff --git a/app/javascript/components/tpi/charts/ascor-bubble/Chart.js b/app/javascript/components/tpi/charts/ascor-bubble/Chart.js index 914f40829..c24b6a9ef 100644 --- a/app/javascript/components/tpi/charts/ascor-bubble/Chart.js +++ b/app/javascript/components/tpi/charts/ascor-bubble/Chart.js @@ -1,8 +1,13 @@ -import React, { useEffect } from 'react'; +import React, { useEffect, useMemo } from 'react'; import PropTypes from 'prop-types'; import SingleCell from './SingleCell'; -import { SCORE_RANGES } from './constants'; +import { SCORE_RANGES, VALUES } from './constants'; +import { groupBy, keys, pickBy, values } from 'lodash'; + +import ChartMobile from './chart-mobile'; + +const DESKTOP_MIN_WIDTH = 992; const SCALE = 1.25; @@ -18,55 +23,76 @@ const SINGLE_CELL_SVG_HEIGHT = 100; let tooltip = null; -const BubbleChart = ({ results, disabled_bubbles_areas }) => { +const BubbleChart = ({ results }) => { const tooltipEl = '
'; useEffect(() => { document.body.insertAdjacentHTML('beforeend', tooltipEl); tooltip = document.getElementById('bubble-chart-tooltip'); }, []); - const ranges = SCORE_RANGES.map((range) => range.value); + const ranges = keys(SCORE_RANGES); + + const parsedData = useMemo( + () => values(values(groupBy(results, 'pillar'))).map((value) => ({ + pillar: value[0].pillar, + values: values(groupBy(value, 'area')).map((areaValues) => { + const vValues = pickBy( + groupBy(areaValues, 'result'), + (_value, key) => key in VALUES + ); + const v = { + ...VALUES, + ...vValues + }; + return { + area: areaValues[0].area, + values: values(v) + }; + }) + })), + [results] + ); - const parsedData = {}; - const pillars = {}; + const [isMobile, setIsMobile] = React.useState(true); - results.forEach((result) => { - if (parsedData[result.area] === undefined) { - parsedData[result.area] = Array.from({ length: ranges.length }, () => []); - } - const rangeIndex = SCORE_RANGES.findIndex( - (range) => result.result === range.value - ); - if (rangeIndex >= 0) { - parsedData[result.area][rangeIndex].push({ - ...result, - color: SCORE_RANGES[rangeIndex].color - }); + const handleResize = () => { + if (window.innerWidth < DESKTOP_MIN_WIDTH) { + setIsMobile(true); } else { - console.error('WRONG INDEX', result); + setIsMobile(false); } - if (pillars[result.pillar] === undefined) { - pillars[result.pillar] = [result.area]; - } else { - pillars[result.pillar] = pillars[result.pillar].includes(result.area) - ? pillars[result.pillar] - : [...pillars[result.pillar], result.area]; + }; + + useEffect(() => { + if (typeof window !== 'undefined') { + handleResize(); + window.addEventListener('resize', handleResize); } - }); + return () => { + window.removeEventListener('resize', handleResize); + }; + }, []); return ( -