From af7b9d85dda221d5aa04a93706c27b67d9b58f58 Mon Sep 17 00:00:00 2001 From: Corson-Dosch <hcorson-dosch@usgs.gov> Date: Tue, 10 Dec 2024 09:49:21 -0600 Subject: [PATCH] switch to axis with title for scatter plot --- src/components/WildfireAerosolsViz.vue | 86 ++++++++++++++++++++++---- 1 file changed, 73 insertions(+), 13 deletions(-) diff --git a/src/components/WildfireAerosolsViz.vue b/src/components/WildfireAerosolsViz.vue index 4d88688..4ab8924 100644 --- a/src/components/WildfireAerosolsViz.vue +++ b/src/components/WildfireAerosolsViz.vue @@ -104,6 +104,8 @@ let scatterChartWrapper; let scatterChartBounds; let scatterXScale; + let scatterXAxis; + const scatterXAxisPosition = 'top'; let scatterColorCategories; const scatterColors = {hardwood: '#c49051', softwood: '#729C9D'}; let scatterColorScale; @@ -463,6 +465,15 @@ // Initialize scales initScatterXScale() + // Initialize axes + initScatterXAxis( + { + bounds: scatterChartBounds, + chartDims: scatterChartDimensions, + axisPosition: scatterXAxisPosition + } + ) + // Add groups for visual elements scatterChartBounds.append("g") .attr("class", "points"); @@ -499,6 +510,19 @@ .attr("aria-hidden", true); // hide from screen reader } + function initScatterXAxis({ + bounds, + chartDims, + axisPosition = 'bottom' + }) { + // add group for x axis + scatterXAxis = bounds.append("g") + .attr("id", "x-axis") + .attr("class", "axis") + .attr("transform", `translate(0,${axisPosition === 'bottom' ? chartDims.boundedHeight : 0})`) + .attr("aria-hidden", true); // hide from screen reader + } + function initYScale() { // scale for the y axis (domain set in `drawTileChart()`) yScale = d3.scaleLinear() @@ -528,6 +552,8 @@ titleTextAnchor = "middle", titleBaseline = "hanging", titleAngle = -90, + titleWidth = chartDims.boundedWidth, + wrapTitle = false, nticks = null, tickSize = 0, tickPadding = 5, @@ -536,6 +562,7 @@ customSuffix = null, textAngle = 0, keepDomain = true, + keepLabels = true }) { // generate axis // if numeric ticks, include specification of format @@ -545,6 +572,9 @@ } else if (tickType == "numeric" && customSuffix) { axis .call(d3[axisFxn](axisScale).ticks(nticks).tickSize(tickSize).tickPadding(tickPadding).tickFormat(d => d3.format(tickFormat)(d) + ' ' + customSuffix)); + } else if (!keepLabels) { + axis + .call(d3[axisFxn](axisScale).tickValues([])); } else { axis .call(d3[axisFxn](axisScale).tickSize(tickSize).tickPadding(tickPadding)); @@ -569,9 +599,11 @@ .attr("transform", `rotate(${titleAngle})`) .attr("text-anchor", titleTextAnchor) .attr("dominant-baseline", titleBaseline) + .attr("text-width", titleWidth) .attr("role", "presentation") .attr("aria-hidden", true) - .text(axisTitle); + .text(axisTitle) + .call(d => wrapTitle ? wrap(d) : d); if (axisSubtitle) { axisTitle.append("tspan") @@ -601,6 +633,8 @@ titleTextAnchor = "middle", titleBaseline = axisPosition === 'bottom' ? "ideographic" : "hanging", titleAngle = 0, + titleWidth = chartDims.boundedWidth, + wrapTitle = false, nticks = null, tickSize = 0, tickPadding = 5, @@ -609,6 +643,7 @@ customSuffix = null, textAngle = 0, keepDomain = true, + keepLabels = true }) { drawAxis({ axis: axis, @@ -622,6 +657,8 @@ titleTextAnchor: titleTextAnchor, titleBaseline: titleBaseline, titleAngle: titleAngle, + titleWidth: titleWidth, + wrapTitle: wrapTitle, nticks: nticks, tickSize: tickSize, tickPadding: tickPadding, @@ -630,6 +667,7 @@ customSuffix: customSuffix, textAngle: textAngle, keepDomain: keepDomain, + keepLabels: keepLabels }) } @@ -645,6 +683,8 @@ titleTextAnchor = "middle", titleBaseline = "hanging", titleAngle = -90, + titleWidth = chartDims.boundedWidth, + wrapTitle = false, nticks = null, tickSize = 0, tickPadding = 5, @@ -653,6 +693,7 @@ customSuffix = null, textAngle = 0, keepDomain = true, + keepLabels = true }) { drawAxis({ axis: axis, @@ -667,6 +708,8 @@ titleTextAnchor: titleTextAnchor, titleBaseline: titleBaseline, titleAngle: titleAngle, + titleWidth: titleWidth, + wrapTitle: wrapTitle, nticks: nticks, tickSize: tickSize, tickPadding: tickPadding, @@ -675,6 +718,7 @@ tickFormat: tickFormat, customSuffix: customSuffix, keepDomain: keepDomain, + keepLabels: keepLabels }) } @@ -1083,6 +1127,21 @@ // set domain for xScale scatterXScale .domain([... new Set(filteredData.map(d => xAccessor(d)))]); + drawXAxis( + { + axis: scatterXAxis, + axisScale: scatterXScale, + chartDims: scatterChartDimensions + }, + { + axisPosition: scatterXAxisPosition, + axisTitle: 'Burned vegetation type', + wrapTitle: true, + tickType: 'string', + keepDomain: false, + keepLabels: false + } + ) /////////////////////////////////// ///// SET UP COLOR SCALE ///// @@ -1159,18 +1218,19 @@ .attr("id", "bar-chart-legend") // Add legend title - scatterLegendGroup.append("text") - .attr("id", "legend-title") - .attr("class", "axis-title") - .attr("x", scatterChartDimensions.boundedWidth / 2) - .attr("y", -scatterChartDimensions.margin.top) - .attr("dx", 0) - .attr("dy", 0) - .attr("text-anchor", "middle") - .attr("dominant-baseline", "hanging") - .attr("text-width", scatterChartDimensions.boundedWidth) - .text('Burned vegetation type') - .call(d => wrap(d)) + // add axis title + // scatterLegendGroup.append("text") + // .attr("id", "legend-title") + // .attr("class", "axis-title") + // .attr("x", scatterChartDimensions.boundedWidth / 2) + // .attr("y", -scatterChartDimensions.margin.top + 10) + // .attr("dx", 0) + // .attr("dy", 0) + // .attr("text-anchor", "middle") + // .attr("dominant-baseline", "hanging") + // .attr("text-width", scatterChartDimensions.boundedWidth) + // .text('Burned vegetation type') + // .call(d => wrap(d)) const legendPointSize = barYScale.bandwidth() / 2 * 0.95; // const interItemSpacing = mobileView ? 15 : 10; -- GitLab