diff --git a/Gemfile.lock b/Gemfile.lock index fbafef674..bd1c07330 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,40 +1,40 @@ GEM remote: https://rubygems.org/ specs: - actioncable (6.1.7.8) - actionpack (= 6.1.7.8) - activesupport (= 6.1.7.8) + actioncable (6.1.7.9) + actionpack (= 6.1.7.9) + activesupport (= 6.1.7.9) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.1.7.8) - actionpack (= 6.1.7.8) - activejob (= 6.1.7.8) - activerecord (= 6.1.7.8) - activestorage (= 6.1.7.8) - activesupport (= 6.1.7.8) + actionmailbox (6.1.7.9) + actionpack (= 6.1.7.9) + activejob (= 6.1.7.9) + activerecord (= 6.1.7.9) + activestorage (= 6.1.7.9) + activesupport (= 6.1.7.9) mail (>= 2.7.1) - actionmailer (6.1.7.8) - actionpack (= 6.1.7.8) - actionview (= 6.1.7.8) - activejob (= 6.1.7.8) - activesupport (= 6.1.7.8) + actionmailer (6.1.7.9) + actionpack (= 6.1.7.9) + actionview (= 6.1.7.9) + activejob (= 6.1.7.9) + activesupport (= 6.1.7.9) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (6.1.7.8) - actionview (= 6.1.7.8) - activesupport (= 6.1.7.8) + actionpack (6.1.7.9) + actionview (= 6.1.7.9) + activesupport (= 6.1.7.9) rack (~> 2.0, >= 2.0.9) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.1.7.8) - actionpack (= 6.1.7.8) - activerecord (= 6.1.7.8) - activestorage (= 6.1.7.8) - activesupport (= 6.1.7.8) + actiontext (6.1.7.9) + actionpack (= 6.1.7.9) + activerecord (= 6.1.7.9) + activestorage (= 6.1.7.9) + activesupport (= 6.1.7.9) nokogiri (>= 1.8.5) - actionview (6.1.7.8) - activesupport (= 6.1.7.8) + actionview (6.1.7.9) + activesupport (= 6.1.7.9) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) @@ -60,28 +60,28 @@ GEM sassc sassc-rails xdan-datetimepicker-rails (~> 2.5.1) - activejob (6.1.7.8) - activesupport (= 6.1.7.8) + activejob (6.1.7.9) + activesupport (= 6.1.7.9) globalid (>= 0.3.6) - activemodel (6.1.7.8) - activesupport (= 6.1.7.8) + activemodel (6.1.7.9) + activesupport (= 6.1.7.9) activemodel-serializers-xml (1.0.2) activemodel (> 5.x) activesupport (> 5.x) builder (~> 3.1) - activerecord (6.1.7.8) - activemodel (= 6.1.7.8) - activesupport (= 6.1.7.8) + activerecord (6.1.7.9) + activemodel (= 6.1.7.9) + activesupport (= 6.1.7.9) activerecord-import (1.4.0) activerecord (>= 4.2) - activestorage (6.1.7.8) - actionpack (= 6.1.7.8) - activejob (= 6.1.7.8) - activerecord (= 6.1.7.8) - activesupport (= 6.1.7.8) + activestorage (6.1.7.9) + actionpack (= 6.1.7.9) + activejob (= 6.1.7.9) + activerecord (= 6.1.7.9) + activesupport (= 6.1.7.9) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (6.1.7.8) + activesupport (6.1.7.9) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) @@ -251,7 +251,7 @@ GEM activesupport (>= 5.2) htmlentities (4.3.4) httpclient (2.8.3) - i18n (1.14.5) + i18n (1.14.6) concurrent-ruby (~> 1.0) image_processing (1.12.2) mini_magick (>= 4.9.5, < 5) @@ -301,7 +301,7 @@ GEM minitest (5.25.1) msgpack (1.5.3) multi_json (1.15.0) - net-imap (0.4.14) + net-imap (0.4.17) date net-protocol net-pop (0.1.2) @@ -341,27 +341,27 @@ GEM puma (5.6.9) nio4r (~> 2.0) racc (1.8.1) - rack (2.2.9) + rack (2.2.10) rack-cors (1.1.1) rack (>= 2.0.0) rack-proxy (0.7.2) rack rack-test (2.1.0) rack (>= 1.3) - rails (6.1.7.8) - actioncable (= 6.1.7.8) - actionmailbox (= 6.1.7.8) - actionmailer (= 6.1.7.8) - actionpack (= 6.1.7.8) - actiontext (= 6.1.7.8) - actionview (= 6.1.7.8) - activejob (= 6.1.7.8) - activemodel (= 6.1.7.8) - activerecord (= 6.1.7.8) - activestorage (= 6.1.7.8) - activesupport (= 6.1.7.8) + rails (6.1.7.9) + actioncable (= 6.1.7.9) + actionmailbox (= 6.1.7.9) + actionmailer (= 6.1.7.9) + actionpack (= 6.1.7.9) + actiontext (= 6.1.7.9) + actionview (= 6.1.7.9) + activejob (= 6.1.7.9) + activemodel (= 6.1.7.9) + activerecord (= 6.1.7.9) + activestorage (= 6.1.7.9) + activesupport (= 6.1.7.9) bundler (>= 1.15.0) - railties (= 6.1.7.8) + railties (= 6.1.7.9) sprockets-rails (>= 2.0.0) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) @@ -374,9 +374,9 @@ GEM rails-html-sanitizer (1.6.0) loofah (~> 2.21) nokogiri (~> 1.14) - railties (6.1.7.8) - actionpack (= 6.1.7.8) - activesupport (= 6.1.7.8) + railties (6.1.7.9) + actionpack (= 6.1.7.9) + activesupport (= 6.1.7.9) method_source rake (>= 12.2) thor (~> 1.0) @@ -506,7 +506,7 @@ GEM diff-lcs patience_diff test-prof (1.0.9) - thor (1.3.1) + thor (1.3.2) tilt (2.0.10) timecop (0.9.5) timeout (0.4.1) @@ -547,7 +547,7 @@ GEM rails (>= 3.2.16) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.6.17) + zeitwerk (2.6.18) PLATFORMS ruby diff --git a/app/assets/images/icons/hover-cursor.svg b/app/assets/images/icons/hover-cursor.svg new file mode 100644 index 000000000..508d5dd9d --- /dev/null +++ b/app/assets/images/icons/hover-cursor.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/app/assets/images/tpi/sectors-bubble-chart-legend.svg b/app/assets/images/tpi/sectors-bubble-chart-legend.svg new file mode 100644 index 000000000..dbb387ebc --- /dev/null +++ b/app/assets/images/tpi/sectors-bubble-chart-legend.svg @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/app/assets/stylesheets/tpi/_bubble-chart.scss b/app/assets/stylesheets/tpi/_bubble-chart.scss index c8dbfa980..5eadb3e46 100644 --- a/app/assets/stylesheets/tpi/_bubble-chart.scss +++ b/app/assets/stylesheets/tpi/_bubble-chart.scss @@ -7,6 +7,14 @@ $cell-height: 80px; $cell-height-banks: 100px; $legend-image-width: 60px; +.mq-sector-pie-chart-title { + display: flex; + gap: 8px; + color: $blue-darker; + margin-top: 28px; + line-height: 20px; +} + .bubble-chart__container { width: 100%; padding: 50px 0; @@ -63,11 +71,59 @@ $legend-image-width: 60px; .bubble-chart_circle { circle:hover { - stroke-width: 14; - stroke: $black; + stroke-width: 2; + stroke: #FFDD49; + } +} +.bubble-chart_tooltip { + z-index: 10; + background-color: $white; + border: 1.5px solid $black; + padding: 20px; + font-size: 14px; + width: max-content; + max-width: 430px; + min-width: 400px; + + h4 { + color: $blue-dark; + font-size: 12px !important; + text-transform: uppercase; + font-weight: 400; + } + &_header { + font-size: 20px !important; + line-height: 24px; + font-weight: 700; + margin-block: 8px 20px; + } + &_text { + display: grid; + grid-template-columns: repeat(2, 1fr); + margin-block: 12px; + font-size: 16px; + max-height: 200px; + overflow-y: auto; + gap: 12px 20px; + + .bubble-chart_tooltip_list_item { + margin-left: 20px; + a { + text-decoration: underline; + color: black; + } + } + + } + button { + float: right; + margin-top: 20px; + height: 40px !important; + width: 62px !important; } } + .bubble-tip { font-size: 14px; padding: 10px; @@ -115,6 +171,10 @@ $legend-image-width: 60px; } } +.bubble-chart_circle { + cursor: pointer; +} + .bubble-chart__title { color: $grey-dark; font-size: $size-6; @@ -139,14 +199,15 @@ $legend-image-width: 60px; .bubble-chart__legend-titles-container { position: absolute; color: $dark; - left: calc(#{$legend-image-width} + 10px); - top: -10px; + left: calc(#{$legend-image-width} + 6px); + top: -7.5px; } .bubble-chart__legend-title { font-size: 12px; + line-height: 15px; font-family: $font-family-regular; - margin: 2px 0; + // margin: 2px 0; display: block; } diff --git a/app/assets/stylesheets/tpi/charts/companies_accordion.scss b/app/assets/stylesheets/tpi/charts/companies_accordion.scss index 48a2188de..e336446e6 100644 --- a/app/assets/stylesheets/tpi/charts/companies_accordion.scss +++ b/app/assets/stylesheets/tpi/charts/companies_accordion.scss @@ -5,7 +5,11 @@ $tpi-level-chart-colors: #86A9F9 #5587F7 #2465F5 #0A4BDC #083AAB #9747FF; .mobile_bubble-chart__container { margin: 0 -0.75rem; - padding: 50px 0 0; + padding: 0; + + .mq-sector-pie-chart-title { + margin: 16px 12px 20px 12px; + } .accordions-list { color: $white; @@ -72,10 +76,11 @@ $tpi-level-chart-colors: #86A9F9 #5587F7 #2465F5 #0A4BDC #083AAB #9747FF; .go-to-button__container { padding-top: 1.5rem; text-align: center; - width: 100%; - + margin-inline: 12px; + a { border-width: 2px; + width: 100%; font-size: $size-5; border-radius: 0; height: 30px; diff --git a/app/assets/stylesheets/tpi/charts/mq-sector-pie-chart.scss b/app/assets/stylesheets/tpi/charts/mq-sector-pie-chart.scss index 09525a77a..41a96d68d 100644 --- a/app/assets/stylesheets/tpi/charts/mq-sector-pie-chart.scss +++ b/app/assets/stylesheets/tpi/charts/mq-sector-pie-chart.scss @@ -1,60 +1,130 @@ -@import '../variables'; +@import "../variables"; -$tpi-pie-chart-colors: #86A9F9 #5587F7 #2465F5 #0A4BDC #083AAB #9747FF; +$tpi-pie-chart-colors: #86a9f9 #5587f7 #2465f5 #0a4bdc #083aab #9747ff; -.chart--mq-sector-pie-chart { - margin: 0 auto; - min-height: 400px; - display: flex; - align-items: center; +.mq-sector-pie-chart { + margin-top: 16px; + margin-bottom: 60px; + .mq-sector-pie-chart-title { + display: flex; + gap: 8px; + color: $blue-darker; - // remove overflow hidden from the chart - div[data-highcharts-chart], .highcharts-container, svg { - overflow: unset !important; - - @include until($desktop) { - tspan { - &:not(.highcharts-strong) { - font-size: $size-7; - font-family: $font-family-bold; - } + .--mobile { + display: none; + @include until($desktop) { + display: inline-block; } } - } - - @for $i from 1 through length($tpi-pie-chart-colors) { - $color: nth($tpi-pie-chart-colors, $i); - .highcharts-color-#{$i - 1} { - fill: $color; - stroke: $color; + .--desktop { + display: inline-block; + @include until($desktop) { + display: none; + } } - } - .highcharts-data-label { - font-size: 1rem; - font-family: $font-family-bold; - font-weight: unset; } - .highcharts-data-label-connector { - stroke: $black; - fill: none; - } + .chart--mq-sector-pie-chart { + min-height: 320px; + width: 850px; + display: flex; + align-items: center; + justify-content: space-between; + flex-wrap: wrap; + @include until($desktop) { + gap: 32px; + justify-content: center; + width: 100%; + } - .chart-title { - font-family: $font-family-regular; - font-size: 16px; + .highcharts-container { + width: 320px; + @include until($desktop) { + width: 290px; + } + } + // remove overflow hidden from the chart + div[data-highcharts-chart], + .highcharts-container, + svg { + overflow: unset !important; - .companies-size { - font-size: 36px; - font-family: $font-family-bold; + @include until($desktop) { + tspan { + &:not(.highcharts-strong) { + font-size: $size-7; + font-family: $font-family-bold; + } + } + } } - @include until($desktop) { - font-size: 14px; + @for $i from 1 through length($tpi-pie-chart-colors) { + $color: nth($tpi-pie-chart-colors, $i); + .highcharts-color-#{$i - 1} { + fill: $color; + stroke: $color; + } + } + .chart--mq-sector-pie-chart-title { + font-family: $font-family-regular; + font-size: 16px; + text-align: center; + transform: translateY(-16px); + .companies-size { - font-size: 24px; + font-size: 36px; + line-height: 40px; + font-family: $font-family-bold; + } + &.--selected { + transform: translateY(-35%); + } + + @include until($desktop) { + font-size: 14px; + + .companies-size { + font-size: 24px; + } + } + } + + .chart-legends { + display: grid; + width: 372px; + grid-template-rows: repeat(3, min-content); + grid-auto-flow: column; + column-gap: 80px; + row-gap: 20px; + @include until($desktop) { + column-gap: 32px; + width: auto; + } + .chart-legend-item { + display: flex; + gap: 8px; + .chart-legend-item__name { + .chart-legend-item__color { + height: 12px; + width: 12px; + border-radius: 50%; + } + display: flex; + align-items: center; + gap: 8px; + font-size: 16px; + font-family: $font-family-bold; + } + .chart-legend-item__value { + margin-left: 20px; + margin-top: 4px; + font-size: 12px; + font-family: $font-family-regular; + min-width: max-content; + } } } } diff --git a/app/assets/stylesheets/tpi/pages/sector.scss b/app/assets/stylesheets/tpi/pages/sector.scss index 31b33102f..baf4ea746 100644 --- a/app/assets/stylesheets/tpi/pages/sector.scss +++ b/app/assets/stylesheets/tpi/pages/sector.scss @@ -1,6 +1,6 @@ @import "../variables"; -$tape-color: rgba(25,25,25,0.1); +$tape-color: rgba(25, 25, 25, 0.1); .sector-page { .dropdown-selector-sector-page-wrapper { @@ -26,7 +26,7 @@ $tape-color: rgba(25,25,25,0.1); } @include until($desktop) { - padding: 0 0.75rem; + padding-inline: 0 0.75rem; font-size: $size-7; height: 60px; font-family: $font-family-regular; @@ -60,36 +60,53 @@ $tape-color: rgba(25,25,25,0.1); margin-top: 50px; .sector-level { - display: flex; - flex-direction: column; - - padding-bottom: 0; + &.column { + display: flex; + justify-content: space-between; + flex-direction: column; + padding-bottom: 0; + } &:not(:last-child) { - border-right: 5px dotted $tape-color; + border-right: 2px dashed $tape-color; } &__title { position: relative; - height: 60px; - margin-bottom: 50px; + margin-bottom: 20px; + h5 { + font-size: 16px; + line-height: 20px; + font-weight: 700; + margin-bottom: 6px; + } + p { + font-size: 12px; + line-height: 18px; + color: $grey-dark; + } } &__companies { - flex: 1; line-height: 1.25; + // height: 150px; - padding: 12px 24px; color: white; - a { - color: white; - } + display: flex; + align-items: end; - li { - padding: 3px 0; + > div:first-child { + width: 100%; + text-align: center; + padding-top: 20px; + font-size: 32px; + font-weight: 700; + cursor: pointer; } + + .mq-level-trend { @include mq-level-trend(20px); background-color: rgba(0, 0, 0, 0.4); @@ -129,14 +146,14 @@ $tape-color: rgba(25,25,25,0.1); justify-content: space-between; margin-bottom: 15px; - >p { + > p { display: none; } @include until($desktop) { display: block; - >p { + > p { display: block; margin-top: 15px; font-size: $size-6; @@ -147,7 +164,7 @@ $tape-color: rgba(25,25,25,0.1); display: block; color: $grey-dark; font-size: $size-5; - margin-top: 20px; + margin-top: 20px; max-width: 280px; #show-by-dropdown-placeholder { @@ -169,3 +186,55 @@ $tape-color: rgba(25,25,25,0.1); } } } + +.sector-level__popover { + z-index: 10; + background-color: $white; + border: 1.5px solid $black; + padding: 20px; + font-size: 14px; + width: 430px; + max-width: 430px; + min-width: 400px; + color: black; + + h4 { + color: $blue-dark; + font-size: 12px !important; + text-transform: uppercase; + font-weight: 400; + } + p { + font-size: 12px; + line-height: 18px; + color: $grey-dark; + } + &_header { + font-size: 20px !important; + line-height: 24px; + font-weight: 700; + margin-block: 8px 20px; + } + &_text { + display: grid; + grid-template-columns: repeat(2, 1fr); + margin-block: 12px; + font-size: 16px; + max-height: 200px; + overflow-y: auto; + gap: 12px 20px; + padding-left: 2rem; + } + &_list_item { + a { + text-decoration: underline; + color: black; + } + } + button { + float: right; + margin-top: 20px; + height: 40px !important; + width: 62px !important; + } +} diff --git a/app/assets/stylesheets/tpi/pages/sectors-index.scss b/app/assets/stylesheets/tpi/pages/sectors-index.scss index 1a25a0cf9..dcdbb9415 100644 --- a/app/assets/stylesheets/tpi/pages/sectors-index.scss +++ b/app/assets/stylesheets/tpi/pages/sectors-index.scss @@ -43,7 +43,20 @@ margin-top: 30px; } + h3.title-blue { + color: $blue; + font-weight: bold; + line-height: 40px; + margin-bottom: 80px; + } + @include until($desktop) { + h3.title-blue { + font-size: $size-4 !important; + line-height: 28px; + margin-bottom: 80px; + } + h4 { font-size: $size-5 !important; } diff --git a/app/javascript/components/tpi/charts/bubble/Chart.js b/app/javascript/components/tpi/charts/bubble/Chart.js index 261879e34..7c604688d 100644 --- a/app/javascript/components/tpi/charts/bubble/Chart.js +++ b/app/javascript/components/tpi/charts/bubble/Chart.js @@ -1,16 +1,16 @@ -import React, {useEffect} from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; -import legendImage from 'images/bubble-chart-legend.svg'; +import legendImage from 'images/tpi/sectors-bubble-chart-legend.svg'; import SingleCell from './SingleCell'; -import BaseTooltip from 'components/tpi/BaseTooltip'; +import hoverIcon from 'images/icons/hover-cursor.svg'; -const SCALE = 5; +const SCALE = 1; // radius of bubbles const COMPANIES_MARKET_CAP_GROUPS = { - large: 10 * SCALE, - medium: 5 * SCALE, - small: 3 * SCALE + '50-70': 10 * SCALE, + '11-50': 5 * SCALE, + '1-10': 3 * SCALE }; const SINGLE_CELL_SVG_WIDTH = 120 * SCALE; @@ -34,20 +34,60 @@ const LEVELS_SUBTITLES = { 5: 'Transition planning and implementation' }; -const tooltipDisclaimer = 'Companies have to answer “yes” to all questions on a level to move to the next one'; -let tooltip = null; +const Row = ({ dataRow, title, sectors }) => { + const sector = sectors.find((s) => s.name === title); -const BubbleChart = ({ levels, sectors }) => { - const tooltipEl = ''; - useEffect(() => { - document.body.insertAdjacentHTML('beforeend', tooltipEl); - tooltip = document.getElementById('bubble-chart-tooltip'); - }, []); - const parsedData = Object.keys(levels).map(sectorName => ({ - sector: sectorName, - data: Object.values(levels[sectorName]) - })); + return ( + +
+ {title} +
+ {dataRow.map((el, i) => { + const companies = el.map((company) => ({ + name: company.name, + url: company.path + })); + + const companiesBubble = { + value: el.length, + color: LEVELS_COLORS[i], + tooltipContent: { + level: `Level ${i} - ${LEVELS_SUBTITLES[i]}`, + title, + companies + } + }; + // Remove special characters from the key to be able to use d3-select as it uses querySelector + const cleanKey = title.replace(/[^a-zA-Z0-9\-_:.]/g, ''); + const uniqueKey = `${cleanKey}-${el.length}-${i}`; + return ( +
+ +
+ ); + })} +
+ ); +}; + +Row.propTypes = { + dataRow: PropTypes.array.isRequired, + title: PropTypes.string.isRequired, + sectors: PropTypes.array.isRequired +}; + +const BubbleChart = ({ levels, sectors }) => { /** Parsed data has this format - * [ * { sector: 'Sector1', data: [ [ {}, {}, {} ], [], [], [], [], [] ] }, @@ -60,121 +100,80 @@ const BubbleChart = ({ levels, sectors }) => { * { sector: 'Sector8', data: [ [], [], [], [], [], [] ] } * ] */ + const parsedData = Object.entries(levels).map( + ([sectorName, sectorValue]) => ({ + sector: sectorName, + data: Object.values(sectorValue) + }) + ); const levelsSignature = levels && Object.keys(levels[Object.keys(levels)[0]]); return ( -
-
-
- Market cap - {tooltipDisclaimer}} - /> -
-
- Bubble size description -
- {Object.keys(COMPANIES_MARKET_CAP_GROUPS).map((companySize, i) => ( - - {companySize} - - ))} -
-
+
+
+ Hover icon +

+ Click on the bubbles to see the detailed list of companies for each sector. +

- {levelsSignature.map((el, i) => ( -
-
-
{`Level ${el === '5' ? '5 [BETA]' : el}`}
-
{LEVELS_SUBTITLES[el]}
+ +
+
+
+ No. of companies +
+
+ Bubble size description +
+ {Object.keys(COMPANIES_MARKET_CAP_GROUPS).map( + (companySize, i) => ( + + {companySize} + + ) + )} +
- ))} - {parsedData.map(dataRow => createRow(dataRow.data, dataRow.sector, sectors))} -
- ); -}; - -const ForceLayoutBubbleChart = (companiesBubbles, uniqueKey) => { - const handleBubbleClick = (company) => window.open(company.path, '_blank'); - - return ( - - ); -}; - -const getTooltipText = ({ tooltipContent }) => { - if (tooltipContent) { - return ` -
${tooltipContent.header}
-
${tooltipContent.value}
- `; - } - return ''; -}; - -const showTooltip = (node, u) => { - const bubble = u._groups[0][node.index]; - - tooltip.innerHTML = getTooltipText(node); - tooltip.removeAttribute('hidden'); - const bubbleBoundingRect = bubble.getBoundingClientRect(); - const topOffset = bubbleBoundingRect.top - tooltip.offsetHeight + window.pageYOffset; - const leftOffset = bubbleBoundingRect.left + (bubbleBoundingRect.width - tooltip.offsetWidth) / 2 + window.pageXOffset; - - tooltip.style.left = `${leftOffset}px`; - tooltip.style.top = `${topOffset}px`; -}; - -const hideTooltip = () => { - tooltip.setAttribute('hidden', true); -}; - -const createRow = (dataRow, title, sectors) => { - const sector = sectors.find(s => s.name === title); - - return ( - -
- {title} -
- {dataRow.map((el, i) => { - const companiesBubbles = el.map(company => ({ - value: COMPANIES_MARKET_CAP_GROUPS[company.market_cap_group], - tooltipContent: { - header: company.name, - value: `Level ${company.level}` - }, - path: company.path, - color: LEVELS_COLORS[i] - })); - - // Remove special characters from the key to be able to use d3-select as it uses querySelector - const cleanKey = title.replace(/[^a-zA-Z0-9\-_:.]/g, ''); - const uniqueKey = `${cleanKey}-${el.length}-${i}`; - - return ( -
- {ForceLayoutBubbleChart(companiesBubbles, uniqueKey)} + {levelsSignature.map((el, i) => ( +
+
+
{`Level ${el}`} +
+
+ {LEVELS_SUBTITLES[el]} +
+
- ); - })} - + ))} + {parsedData.map((dataRow) => ( + + ))} +
+
); }; diff --git a/app/javascript/components/tpi/charts/bubble/CompaniesAccordion.js b/app/javascript/components/tpi/charts/bubble/CompaniesAccordion.js index fa38541bc..0f2222934 100644 --- a/app/javascript/components/tpi/charts/bubble/CompaniesAccordion.js +++ b/app/javascript/components/tpi/charts/bubble/CompaniesAccordion.js @@ -4,6 +4,7 @@ import Select, { components } from 'react-select'; import chevronDownIconBlack from 'images/icon_chevron_dark/chevron_down_black-1.svg'; import chevronUpIconBlack from 'images/icon_chevron_dark/chevron-up.svg'; +import hoverIcon from 'images/icons/hover-cursor.svg'; const LEVELS_SUBTITLES = { 0: 'Unaware', @@ -75,6 +76,12 @@ const CompaniesAccordion = ({ levels, by_sector }) => { return (
+
+ Hover icon +

+ Click to see the detailed list of companies for each sector. +

+
{by_sector && (