\n\n
\n\n \n <\script>\n var elChart = document.querySelector(\".js-chart\")\n var elAxisX = document.querySelector(\".axis-x\")\n var elsText = elAxisX ? elAxisX.querySelectorAll(\".axis-x-text\") : []\n var indentL = elAxisX ? parseInt(elAxisX.dataset.lIndent, 10) : 0\n var extendR = elAxisX ? parseInt(elAxisX.dataset.rIndent, 10) : 0\n var isBarBased = elChart.getAttribute(\"data-id\").toLowerCase().indexOf(\"bar\") > -1\n\n // responsive\n function responsive() {\n iframeMessenger.resize() // 1\n rescaleSvgElements() // 2\n updateYLabelWidths() // 3\n updateXAxisTextPosition() // 4\n updateChartHeight() // 5\n }\n responsive()\n\n // handle event\n var timeout = null\n window.addEventListener('resize', function(evt) {\n if (timeout) window.clearTimeout(timeout)\n timeout = window.setTimeout(function() {\n responsive()\n timeout = null\n }, 200)\n });\n\n /* 1. iframe resize */\n // iframeMessenger for embed in guardian's page\n\n /* 2. svg path or circle rescale */\n function rescaleSvgElements() {\n var width = 300\n var elSvg = document.querySelector(\"svg\")\n if (elSvg) {\n var svgWidth = elSvg.getBoundingClientRect().width\n // line chart\n var strokeWidth = Math.round(2*width*10/svgWidth)/10\n var paths = Array.prototype.slice.call(document.querySelectorAll(\"path\"))\n paths.forEach(function(path) { path.setAttribute(\"stroke-width\", strokeWidth); })\n // plot chart\n var r = Math.round(3*width*10/svgWidth)/10\n var circles = Array.prototype.slice.call(document.querySelectorAll(\"circle\"))\n circles.forEach(function(circle) { circle.setAttribute(\"r\", r); })\n }}\n\n /* 3. y label width update */\n function updateYLabelWidths() {\n if (elChart.getAttribute(\"data-res-y\") === \"false\") return\n\n const elRows = [...elChart.querySelectorAll(\".row\")]\n const elGroups = [...elChart.querySelectorAll(\".group\")]\n const elLegend = document.querySelector(\".legend\")\n const labelWidth = elChart.querySelector(\".label\").offsetWidth\n const chartWidth = elChart.offsetWidth\n const isInline = labelWidth <= chartWidth/3\n\n elRows.forEach(el => {\n el.style.height = isInline ? \"24px\" : \"auto\"\n })\n elGroups.forEach(el => {\n el.style.width = isInline ? \"calc(\" + 100 + \"% - \" + labelWidth + \"px)\" : \"100%\"\n el.style.display = isInline ? \"inline-block\" : \"block\"\n })\n\n elAxisX.style.width = \"calc(100% - \" + ((isInline ? labelWidth : 0) + indentL + extendR + 1) + \"px)\"\n elLegend.style.marginLeft = isInline ? labelWidth + \"px\" : 0\n }\n\n /* 4. x axis text position update */\n function updateXAxisTextPosition() {\n if (!elAxisX) return\n\n var elsTick = elAxisX.querySelectorAll(\".axis-x-tick\")\n var elTest = document.querySelector(\".js-test-res\")\n\n // a. default width / left\n var axisXWidth = elAxisX.offsetWidth\n var maxWidth = elsTick[1].offsetLeft - elsTick[0].offsetLeft\n var txtWidths = [].slice.call(elsText).map((el, i) => {\n elTest.textContent = el.textContent\n var txtWidth = elTest.offsetWidth + 2\n var resWidth = Math.min(txtWidth, maxWidth)\n el.style.width = resWidth + \"px\"\n el.style.left = (elsTick[i].offsetLeft - resWidth / 2) * 100 / axisXWidth + \"%\"\n el.style.textAlign = \"center\"\n return txtWidth\n })\n elTest.textContent = \"\"\n\n // b. adjust width if multi lines\n var isMultiLine = txtWidths.find(w => w > maxWidth)\n if (isMultiLine) {\n [].slice.call(elsText).forEach((el, i) => {\n var txtWidth = el.querySelector(\"span\").offsetWidth + 1\n var resWidth = Math.min(txtWidth, maxWidth)\n el.style.width = resWidth + \"px\"\n el.style.left = (elsTick[i].offsetLeft - resWidth / 2) * 100 / axisXWidth + \"%\"\n })\n }\n\n // c. adjust two ends if out of frame\n var iLast = elsTick.length - 1\n var indent = parseInt(elAxisX.dataset.yIndent, 10) + indentL\n var textStrLeft = (indent + elsTick[0].offsetLeft) - elsText[0].offsetWidth / 2\n var textEndRight = (axisXWidth + extendR - elsTick[iLast].offsetLeft) - elsText[iLast].offsetWidth / 2\n if (textStrLeft < 0) {\n elsText[0].style.left = ((isBarBased ? 0 : 1) - indent) + \"px\"\n elsText[0].style.textAlign = \"left\"\n }\n if (textEndRight < 0) {\n elsText[iLast].style.left = \"auto\"\n elsText[iLast].style.right = (-1) - extendR + \"px\"\n elsText[iLast].style.textAlign = \"right\"\n }\n }\n\n /* chart height update */\n function updateChartHeight() {\n var elsLabel = document.querySelectorAll(\".label-x .label\")\n var isAxisXBottom = elAxisX ? (elAxisX.dataset.xBottom===\"true\") : false\n if (isAxisXBottom || elsLabel.length > 0) {\n var elsAll = [].slice.call(elsText).concat([].slice.call(elsLabel))\n var heights = elsAll.map(el => Math.ceil(el.offsetHeight))\n var maxHeight = Math.max.apply(null, heights)\n elChart.style.marginBottom = (maxHeight + 14) + \"px\"\n }\n }\n <\/script>\n
\n