From ff16df1f90ee384d31bfa5d39eccb9a0405485a0 Mon Sep 17 00:00:00 2001 From: Nicolas Riesco Date: Thu, 28 Apr 2016 16:12:42 +0100 Subject: [PATCH 01/19] Move setup of legend trace toggle into a function --- src/components/legend/draw.js | 96 +++++++++++++++++++---------------- 1 file changed, 51 insertions(+), 45 deletions(-) diff --git a/src/components/legend/draw.js b/src/components/legend/draw.js index 26641cff7bd..0dc1de4577c 100644 --- a/src/components/legend/draw.js +++ b/src/components/legend/draw.js @@ -124,51 +124,7 @@ module.exports = function draw(gd) { }) .each(function(d, i) { drawTexts(this, gd, d, i, traces); - - var traceToggle = d3.select(this).selectAll('rect') - .data([0]); - - traceToggle.enter().append('rect') - .classed('legendtoggle', true) - .style('cursor', 'pointer') - .attr('pointer-events', 'all') - .call(Color.fill, 'rgba(0,0,0,0)'); - - traceToggle.on('click', function() { - if(gd._dragged) return; - - var fullData = gd._fullData, - trace = d[0].trace, - legendgroup = trace.legendgroup, - traceIndicesInGroup = [], - tracei, - newVisible; - - if(Plots.traceIs(trace, 'pie')) { - var thisLabel = d[0].label, - newHiddenSlices = hiddenSlices.slice(), - thisLabelIndex = newHiddenSlices.indexOf(thisLabel); - - if(thisLabelIndex === -1) newHiddenSlices.push(thisLabel); - else newHiddenSlices.splice(thisLabelIndex, 1); - - Plotly.relayout(gd, 'hiddenlabels', newHiddenSlices); - } else { - if(legendgroup === '') { - traceIndicesInGroup = [trace.index]; - } else { - for(var i = 0; i < fullData.length; i++) { - tracei = fullData[i]; - if(tracei.legendgroup === legendgroup) { - traceIndicesInGroup.push(tracei.index); - } - } - } - - newVisible = trace.visible === true ? 'legendonly' : true; - Plotly.restyle(gd, 'visible', newVisible, traceIndicesInGroup); - } - }); + setupTraceToggle(gd, this, d[0]); }); // Position and size the legend @@ -400,6 +356,56 @@ function drawTexts(context, gd, d, i, traces) { else text.call(textLayout); } +function setupTraceToggle(gd, container, legendItem) { + var hiddenSlices = gd._fullLayout.hiddenlabels ? + gd._fullLayout.hiddenlabels.slice() : + []; + + var traceToggle = d3.select(container).selectAll('rect') + .data([0]); + + traceToggle.enter().append('rect') + .classed('legendtoggle', true) + .style('cursor', 'pointer') + .attr('pointer-events', 'all') + .call(Color.fill, 'rgba(0,0,0,0)'); + + traceToggle.on('click', function() { + if(gd._dragged) return; + + var fullData = gd._fullData, + trace = legendItem.trace, + legendgroup = trace.legendgroup, + traceIndicesInGroup = [], + tracei, + newVisible; + + if(Plots.traceIs(trace, 'pie')) { + var thisLabel = legendItem.label, + thisLabelIndex = hiddenSlices.indexOf(thisLabel); + + if(thisLabelIndex === -1) hiddenSlices.push(thisLabel); + else hiddenSlices.splice(thisLabelIndex, 1); + + Plotly.relayout(gd, 'hiddenlabels', hiddenSlices); + } else { + if(legendgroup === '') { + traceIndicesInGroup = [trace.index]; + } else { + for(var i = 0; i < fullData.length; i++) { + tracei = fullData[i]; + if(tracei.legendgroup === legendgroup) { + traceIndicesInGroup.push(tracei.index); + } + } + } + + newVisible = trace.visible === true ? 'legendonly' : true; + Plotly.restyle(gd, 'visible', newVisible, traceIndicesInGroup); + } + }); +} + function computeLegendDimensions(gd, traces) { var fullLayout = gd._fullLayout, opts = fullLayout.legend, From ddc6d71d0ae1402afb3e413a408c19650e603241 Mon Sep 17 00:00:00 2001 From: Nicolas Riesco Date: Thu, 28 Apr 2016 16:24:02 +0100 Subject: [PATCH 02/19] Simplify signature of drawTexts in legend * Removed unused `i`. * Passed `legendItem` directly. --- src/components/legend/draw.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/components/legend/draw.js b/src/components/legend/draw.js index 0dc1de4577c..657046c32aa 100644 --- a/src/components/legend/draw.js +++ b/src/components/legend/draw.js @@ -122,8 +122,8 @@ module.exports = function draw(gd) { return trace.visible === 'legendonly' ? 0.5 : 1; } }) - .each(function(d, i) { - drawTexts(this, gd, d, i, traces); + .each(function(d) { + drawTexts(gd, this, d[0], traces); setupTraceToggle(gd, this, d[0]); }); @@ -312,12 +312,12 @@ module.exports = function draw(gd) { } }; -function drawTexts(context, gd, d, i, traces) { +function drawTexts(gd, context, legendItem, traces) { var fullLayout = gd._fullLayout, - trace = d[0].trace, + trace = legendItem.trace, isPie = Plots.traceIs(trace, 'pie'), traceIndex = trace.index, - name = isPie ? d[0].label : trace.name; + name = isPie ? legendItem.label : trace.name; var text = d3.select(context).selectAll('text.legendtext') .data([0]); From f40dbd4b2511395c25263079c9ac1d9557780b20 Mon Sep 17 00:00:00 2001 From: Nicolas Riesco Date: Thu, 12 May 2016 10:55:08 +0100 Subject: [PATCH 03/19] Legend: add attribute `orientation` --- src/components/legend/attributes.js | 7 +++++++ src/components/legend/defaults.js | 1 + 2 files changed, 8 insertions(+) diff --git a/src/components/legend/attributes.js b/src/components/legend/attributes.js index 99ac85bdf33..2920f1ba6f4 100644 --- a/src/components/legend/attributes.js +++ b/src/components/legend/attributes.js @@ -35,6 +35,13 @@ module.exports = { font: extendFlat({}, fontAttrs, { description: 'Sets the font used to text the legend items.' }), + orientation: { + valType: 'enumerated', + values: ['v', 'h'], + dflt: 'v', + role: 'info', + description: 'Sets the orientation of the legend.' + }, traceorder: { valType: 'flaglist', flags: ['reversed', 'grouped'], diff --git a/src/components/legend/defaults.js b/src/components/legend/defaults.js index eb95148ce13..605e66d234e 100644 --- a/src/components/legend/defaults.js +++ b/src/components/legend/defaults.js @@ -57,6 +57,7 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) { coerce('bordercolor'); coerce('borderwidth'); Lib.coerceFont(coerce, 'font', layoutOut.font); + coerce('orientation'); coerce('traceorder', defaultOrder); if(helpers.isGrouped(layoutOut.legend)) coerce('tracegroupgap'); From 92ff54054d5b8991b6c61f62fb3733bddae4d18f Mon Sep 17 00:00:00 2001 From: Nicolas Riesco Date: Thu, 12 May 2016 11:37:35 +0100 Subject: [PATCH 04/19] Legend: add helper.isVertical(legendLayout) --- src/components/legend/helpers.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/components/legend/helpers.js b/src/components/legend/helpers.js index cf300a4a9da..5a481fca152 100644 --- a/src/components/legend/helpers.js +++ b/src/components/legend/helpers.js @@ -20,6 +20,10 @@ exports.isGrouped = function isGrouped(legendLayout) { return (legendLayout.traceorder || '').indexOf('grouped') !== -1; }; +exports.isVertical = function isVertical(legendLayout) { + return legendLayout.orientation !== 'h'; +}; + exports.isReversed = function isReversed(legendLayout) { return (legendLayout.traceorder || '').indexOf('reversed') !== -1; }; From 869538c409a3f6621a5543261abb15b3321ad83a Mon Sep 17 00:00:00 2001 From: Nicolas Riesco Date: Thu, 12 May 2016 17:50:08 +0100 Subject: [PATCH 05/19] Legend: refactor computation of text dimensions * Checked that all jasmine and image tests still pass. --- src/components/legend/draw.js | 88 +++++++++++++++++++++-------------- 1 file changed, 53 insertions(+), 35 deletions(-) diff --git a/src/components/legend/draw.js b/src/components/legend/draw.js index 657046c32aa..3cdcbe60c01 100644 --- a/src/components/legend/draw.js +++ b/src/components/legend/draw.js @@ -406,6 +406,51 @@ function setupTraceToggle(gd, container, legendItem) { }); } +function computeTextDimensions(gd, container, legendItem) { + var opts = gd._fullLayout.legend, + g = d3.select(container), + bg = g.selectAll('.legendtoggle'), + mathjaxGroup = g.select('g[class*=math-group]'), + lineHeight = opts.font.size * 1.3, + height, + width; + + if(!legendItem.trace.showlegend) { + g.remove(); + return; + } + + if(mathjaxGroup.node()) { + var mathjaxBB = Drawing.bBox(mathjaxGroup.node()); + + height = mathjaxBB.height; + width = mathjaxBB.width; + + mathjaxGroup.attr('transform','translate(0,' + (height / 4) + ')'); + } + else { + var text = g.selectAll('.legendtext'), + textSpans = g.selectAll('.legendtext>tspan'), + textLines = textSpans[0].length || 1; + + height = lineHeight * textLines; + width = text.node() && Drawing.bBox(text.node()).width; + + // approximation to height offset to center the font + // to avoid getBoundingClientRect + var textY = lineHeight * (0.3 + (1 - textLines) / 2); + text.attr('y', textY); + textSpans.attr('y', textY); + } + + height = Math.max(height, 16) + 3; + + bg.attr({x: 0, y: -height / 2, height: height}); + + legendItem.height = height; + legendItem.width = width; +} + function computeLegendDimensions(gd, traces) { var fullLayout = gd._fullLayout, opts = fullLayout.legend, @@ -415,48 +460,21 @@ function computeLegendDimensions(gd, traces) { opts.height = 0; traces.each(function(d) { - var trace = d[0].trace, - g = d3.select(this), - bg = g.selectAll('.legendtoggle'), - text = g.selectAll('.legendtext'), - tspans = g.selectAll('.legendtext>tspan'), - tHeight = opts.font.size * 1.3, - tLines = tspans[0].length || 1, - tWidth = text.node() && Drawing.bBox(text.node()).width, - mathjaxGroup = g.select('g[class*=math-group]'), - textY, - tHeightFull; - - if(!trace.showlegend) { - g.remove(); - return; - } + var legendItem = d[0]; - if(mathjaxGroup.node()) { - var mathjaxBB = Drawing.bBox(mathjaxGroup.node()); - tHeight = mathjaxBB.height; - tWidth = mathjaxBB.width; - mathjaxGroup.attr('transform','translate(0,' + (tHeight / 4) + ')'); - } - else { - // approximation to height offset to center the font - // to avoid getBoundingClientRect - textY = tHeight * (0.3 + (1 - tLines) / 2); - text.attr('y', textY); - tspans.attr('y', textY); - } + computeTextDimensions(gd, this, legendItem); - tHeightFull = Math.max(tHeight * tLines, 16) + 3; + var textHeight = legendItem.height, + textWidth = legendItem.width; - g.attr('transform', + d3.select(this).attr('transform', 'translate(' + borderwidth + ',' + - (5 + borderwidth + opts.height + tHeightFull / 2) + + (5 + borderwidth + opts.height + textHeight / 2) + ')' ); - bg.attr({x: 0, y: -tHeightFull / 2, height: tHeightFull}); - opts.height += tHeightFull; - opts.width = Math.max(opts.width, tWidth || 0); + opts.height += textHeight; + opts.width = Math.max(opts.width, textWidth); }); opts.width += 45 + borderwidth * 2; From b2538e1d5e2894b97cde2fcdf34f20ecf114f459 Mon Sep 17 00:00:00 2001 From: Nicolas Riesco Date: Fri, 13 May 2016 16:21:35 +0100 Subject: [PATCH 06/19] Legend: set tspan.line's x in the callback * Set tspan.line's x in the callback to convertToSpans, otherwise they won't be set in the first render. * Checked all jasmine and image tests still pass. --- src/components/legend/draw.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/legend/draw.js b/src/components/legend/draw.js index 3cdcbe60c01..842bf9d8763 100644 --- a/src/components/legend/draw.js +++ b/src/components/legend/draw.js @@ -338,8 +338,8 @@ function drawTexts(gd, context, legendItem, traces) { computeLegendDimensions(gd, traces); expandMargin(gd); } + s.selectAll('tspan.line').attr({x: s.attr('x')}); }); - s.selectAll('tspan.line').attr({x: s.attr('x')}); } if(gd._context.editable && !isPie) { From 9dc260925285069b36f39efbd7fae3fbebc95fc4 Mon Sep 17 00:00:00 2001 From: Nicolas Riesco Date: Fri, 13 May 2016 16:31:41 +0100 Subject: [PATCH 07/19] Legend: set tspan.line's x before expandMargin * Ensure the position of the `tspan.line`s is set before computing the legend dimensions and expanding the margins. * The baseline image for `pseudo_html.json` needed updating because it has a multi-line legend. --- src/components/legend/draw.js | 3 ++- test/image/baselines/pseudo_html.png | Bin 17208 -> 17811 bytes 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/legend/draw.js b/src/components/legend/draw.js index 842bf9d8763..49d751f2aa5 100644 --- a/src/components/legend/draw.js +++ b/src/components/legend/draw.js @@ -334,11 +334,12 @@ function drawTexts(gd, context, legendItem, traces) { function textLayout(s) { Plotly.util.convertToTspans(s, function() { + s.selectAll('tspan.line').attr({x: s.attr('x')}); + if(gd.firstRender) { computeLegendDimensions(gd, traces); expandMargin(gd); } - s.selectAll('tspan.line').attr({x: s.attr('x')}); }); } diff --git a/test/image/baselines/pseudo_html.png b/test/image/baselines/pseudo_html.png index d15e9753126fe626dead72e134cc75b91dd47ba8..269d6ef1f8af5051558e5adbbc7e6c48996c47b5 100644 GIT binary patch literal 17811 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 k$;f?q!c9!CG`FO4|pCD-~a#s literal 17208 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 From f68344ba250baf66033667088c26a05340a93ed3 Mon Sep 17 00:00:00 2001 From: Nicolas Riesco Date: Fri, 13 May 2016 16:49:46 +0100 Subject: [PATCH 08/19] Legend: compute size only after drawing texts * This change not only improves drawing performance, but it will also allows for `drawTexts` to be moved to `styles.js`. * Checked all jasmine and image tests still pass. --- src/components/legend/draw.js | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/components/legend/draw.js b/src/components/legend/draw.js index 49d751f2aa5..d05c4a0ac76 100644 --- a/src/components/legend/draw.js +++ b/src/components/legend/draw.js @@ -123,10 +123,15 @@ module.exports = function draw(gd) { } }) .each(function(d) { - drawTexts(gd, this, d[0], traces); + drawTexts(gd, this, d[0]); setupTraceToggle(gd, this, d[0]); }); + if(gd.firstRender) { + computeLegendDimensions(gd, traces); + expandMargin(gd); + } + // Position and size the legend var lyMin = 0, lyMax = fullLayout.height; @@ -312,7 +317,7 @@ module.exports = function draw(gd) { } }; -function drawTexts(gd, context, legendItem, traces) { +function drawTexts(gd, context, legendItem) { var fullLayout = gd._fullLayout, trace = legendItem.trace, isPie = Plots.traceIs(trace, 'pie'), @@ -335,11 +340,7 @@ function drawTexts(gd, context, legendItem, traces) { function textLayout(s) { Plotly.util.convertToTspans(s, function() { s.selectAll('tspan.line').attr({x: s.attr('x')}); - - if(gd.firstRender) { - computeLegendDimensions(gd, traces); - expandMargin(gd); - } + computeTextDimensions(gd, context, legendItem); }); } @@ -461,11 +462,8 @@ function computeLegendDimensions(gd, traces) { opts.height = 0; traces.each(function(d) { - var legendItem = d[0]; - - computeTextDimensions(gd, this, legendItem); - - var textHeight = legendItem.height, + var legendItem = d[0], + textHeight = legendItem.height, textWidth = legendItem.width; d3.select(this).attr('transform', From c0dfc8a5476e50c3dcd14205efc03c882a8e2db5 Mon Sep 17 00:00:00 2001 From: Nicolas Riesco Date: Fri, 13 May 2016 18:41:01 +0100 Subject: [PATCH 09/19] Legend: move placing of groups and traces together * Moved the placing of legend groups to `computeLegendDimensions` so that they are handled along with the placing of legend traces. * This change is a preliminary step to implement horizontal legends. * Checked all jasmine and image tests still pass. --- src/components/legend/draw.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/components/legend/draw.js b/src/components/legend/draw.js index d05c4a0ac76..3d500906edc 100644 --- a/src/components/legend/draw.js +++ b/src/components/legend/draw.js @@ -101,12 +101,6 @@ module.exports = function draw(gd) { groups.exit().remove(); - if(helpers.isGrouped(opts)) { - groups.attr('transform', function(d, i) { - return 'translate(0,' + i * opts.tracegroupgap + ')'; - }); - } - var traces = groups.selectAll('g.traces') .data(Lib.identity); @@ -128,7 +122,7 @@ module.exports = function draw(gd) { }); if(gd.firstRender) { - computeLegendDimensions(gd, traces); + computeLegendDimensions(gd, groups, traces); expandMargin(gd); } @@ -136,7 +130,7 @@ module.exports = function draw(gd) { var lyMin = 0, lyMax = fullLayout.height; - computeLegendDimensions(gd, traces); + computeLegendDimensions(gd, groups, traces); if(opts.height > lyMax) { // If the legend doesn't fit in the plot area, @@ -453,11 +447,17 @@ function computeTextDimensions(gd, container, legendItem) { legendItem.width = width; } -function computeLegendDimensions(gd, traces) { +function computeLegendDimensions(gd, groups, traces) { var fullLayout = gd._fullLayout, opts = fullLayout.legend, borderwidth = opts.borderwidth; + if(helpers.isGrouped(opts)) { + groups.attr('transform', function(d, i) { + return 'translate(0,' + i * opts.tracegroupgap + ')'; + }); + } + opts.width = 0; opts.height = 0; From e5049c98413b17e5f0c8c2c4b5ad60ef5177635d Mon Sep 17 00:00:00 2001 From: Nicolas Riesco Date: Fri, 13 May 2016 21:20:37 +0100 Subject: [PATCH 10/19] Legend: implement layout.legend.orientation --- src/components/legend/draw.js | 136 +++++++++++++++++++++++++++------- 1 file changed, 110 insertions(+), 26 deletions(-) diff --git a/src/components/legend/draw.js b/src/components/legend/draw.js index 3d500906edc..ab61cf87875 100644 --- a/src/components/legend/draw.js +++ b/src/components/legend/draw.js @@ -452,43 +452,127 @@ function computeLegendDimensions(gd, groups, traces) { opts = fullLayout.legend, borderwidth = opts.borderwidth; - if(helpers.isGrouped(opts)) { - groups.attr('transform', function(d, i) { - return 'translate(0,' + i * opts.tracegroupgap + ')'; + if(helpers.isVertical(opts)) { + if(helpers.isGrouped(opts)) { + groups.attr('transform', function(d, i) { + return 'translate(0,' + i * opts.tracegroupgap + ')'; + }); + } + + opts.width = 0; + opts.height = 0; + + traces.each(function(d) { + var legendItem = d[0], + textHeight = legendItem.height, + textWidth = legendItem.width; + + d3.select(this).attr('transform', + 'translate(' + borderwidth + ',' + + (5 + borderwidth + opts.height + textHeight / 2) + + ')' + ); + + opts.height += textHeight; + opts.width = Math.max(opts.width, textWidth); }); + + opts.width += 45 + borderwidth * 2; + opts.height += 10 + borderwidth * 2; + + if(helpers.isGrouped(opts)) { + opts.height += (opts._lgroupsLength-1) * opts.tracegroupgap; + } + + traces.selectAll('.legendtoggle') + .attr('width', (gd._context.editable ? 0 : opts.width) + 40); + + // make sure we're only getting full pixels + opts.width = Math.ceil(opts.width); + opts.height = Math.ceil(opts.height); } + else if(helpers.isGrouped(opts)) { + opts.width = 0; + opts.height = 0; + + var groupXOffsets = [opts.width]; + groups.each(function(d) { + var textWidths = d.map(function(legendItemArray) { + return legendItemArray[0].width; + }); - opts.width = 0; - opts.height = 0; + var groupWidth = 40 + Math.max.apply(null, textWidths); + opts.width += opts.tracegroupgap + groupWidth; - traces.each(function(d) { - var legendItem = d[0], - textHeight = legendItem.height, - textWidth = legendItem.width; + groupXOffsets.push(opts.width); + }); - d3.select(this).attr('transform', - 'translate(' + borderwidth + ',' + - (5 + borderwidth + opts.height + textHeight / 2) + - ')' - ); + groups.attr('transform', function(d, i) { + return 'translate(' + groupXOffsets[i] + ',0)'; + }); - opts.height += textHeight; - opts.width = Math.max(opts.width, textWidth); - }); + groups.each(function() { + var group = d3.select(this), + groupTraces = group.selectAll('g.traces'), + groupHeight = 0; + + groupTraces.each(function(d) { + var legendItem = d[0], + textHeight = legendItem.height; + + d3.select(this).attr('transform', + 'translate(0,' + + (5 + borderwidth + groupHeight + textHeight / 2) + + ')' + ); + + groupHeight += textHeight; + }); - opts.width += 45 + borderwidth * 2; - opts.height += 10 + borderwidth * 2; + opts.height = Math.max(opts.height, groupHeight); + }); + + opts.height += 10 + borderwidth * 2; + opts.width += borderwidth * 2; - if(helpers.isGrouped(opts)) { - opts.height += (opts._lgroupsLength-1) * opts.tracegroupgap; + // make sure we're only getting full pixels + opts.width = Math.ceil(opts.width); + opts.height = Math.ceil(opts.height); + + traces.selectAll('.legendtoggle') + .attr('width', (gd._context.editable ? 0 : opts.width)); } + else { + opts.width = 0; + opts.height = 0; + + traces.each(function(d) { + var legendItem = d[0], + traceWidth = 40 + legendItem.width, + traceGap = opts.tracegroupgap || 5; + + d3.select(this).attr('transform', + 'translate(' + + (borderwidth + opts.width) + + ',' + + (5 + borderwidth + legendItem.height / 2) + + ')' + ); + + opts.width += traceGap + traceWidth; + opts.height = Math.max(opts.height, legendItem.height); + }); + + opts.width += borderwidth * 2; + opts.height += 10 + borderwidth * 2; - traces.selectAll('.legendtoggle') - .attr('width', (gd._context.editable ? 0 : opts.width) + 40); + // make sure we're only getting full pixels + opts.width = Math.ceil(opts.width); + opts.height = Math.ceil(opts.height); - // make sure we're only getting full pixels - opts.width = Math.ceil(opts.width); - opts.height = Math.ceil(opts.height); + traces.selectAll('.legendtoggle') + .attr('width', (gd._context.editable ? 0 : opts.width)); + } } function expandMargin(gd) { From 23e39723b615881ae9fa8a6ac72fb19a30ee6c23 Mon Sep 17 00:00:00 2001 From: Nicolas Riesco Date: Fri, 13 May 2016 21:23:18 +0100 Subject: [PATCH 11/19] Legend: add mocks with horizontal legends * Added `legend_horizontal.json` (a mock with a horizontal legend without groups). * Added `legend_horizontal_groups.json` (a mock with a grouped horizontal legend). --- test/image/baselines/legend_horizontal.png | Bin 0 -> 23341 bytes .../baselines/legend_horizontal_groups.png | Bin 0 -> 27522 bytes test/image/mocks/legend_horizontal.json | 211 ++++++++++++++++++ .../image/mocks/legend_horizontal_groups.json | 119 ++++++++++ 4 files changed, 330 insertions(+) create mode 100644 test/image/baselines/legend_horizontal.png create mode 100644 test/image/baselines/legend_horizontal_groups.png create mode 100644 test/image/mocks/legend_horizontal.json create mode 100644 test/image/mocks/legend_horizontal_groups.json diff --git a/test/image/baselines/legend_horizontal.png b/test/image/baselines/legend_horizontal.png new file mode 100644 index 0000000000000000000000000000000000000000..878dc8b001886e2b2d204ee88bf167cb411c5909 GIT binary patch literal 23341 zcmeFZWmJ{l^F9oRR6uE@5d;JT3_?&!8U&Qib3i~uQaYqW5hVoyr5oV@hwcMdq;%H- zrMtVHeWRcF#q;KQ{%`(kec!N@#l2(p?3rt3uGw!MsLGR^r#p{@g+-#MAft|j1*^fr z!rmgp2frEDI~m8qV!=|Bkc}M-aZanoN=+RW)yi zp3W=dtZJXvut>@=I@J$~YRc9q-CZ5ix@&|+a_1!{Crj#*N@8K-{{B&*$r4g;WobT7 z4I^an#e#nLvPn*uv;6rF_>C^FN+$X4aq zf0j*H6a4pLu&|MMgf-eRG3}TCo|Dv#7U!SQw24UF^7!}@r2n3iW$h;ZKcnSRv#jYG z!9`#HJtq(V@qYyHw>bZ!0spxI|FHr8F@pbpy+C>V#?16|bJEEcr~B@hE4zdQqFr?H zn)`$wLAsPbzV^lQ|JdNcE0PnuS+TD#Fh*25&bBxY7;y?(^}m-mSr036oKXNsi z!`Z_7%MTO)FGMfzetNQ7*ZS#UnptLMy(l$_WAuinnI@JbW2oZrTb#J%0x)vH-z_o1~JoJUAa((W(Lfq zHeHgx<|TXqMhf75zS$<2X+>k-1O3lfQE3j)AE20wo(4@*k&$tLR&Apel&*Smgb9 z-QUh2zJ4&i}pa!1rM1>eHFU*_4;|+qFOLos1`NXev>-PtEE%7|cG-wkAK6J9D`# z%=P9qJ8|KLWg2odm6bmpoA)cn*xJx3?cjZk=)2AK zL?uh?Hv)JG2a0h(-tBjtkYR7PyxV4!e1BoQ@qC=8e!_w}T8Vwg>w5Xxs=(3C%IN(n zb3w}E(`$dQLwE();WOznU&;G0(^)!q(ez4;Gig?tj(`1!`U zHieg?q~$lymuKjB7LQnvdz*Hfv;Rgss(b)XII$QjOypR^i2iihXj@L;A~xrx^B5mH zlFeR2E+P`00}P{`1I*HO1bZL3`2WT|jNlaSEGY29_zD({^PQL~br*U+u`*w*zMI+K z4lh^6jFsq6Tc4y39@y@oYrP)dA2IneV=9<2KvY;{9#q zA{DlKee@V5@%faR#`x)^tKlsNIl_PDV`T*kRY;kCynyS(x00+!A8$#ZVLKoGK47lR zzCC`t%~S2*L$MJ-SW^XFQqw{LK{`;x%Ec_+sfA5?_6#v=%Cmdu$8wI;&0mvb_)$hZ zW6yx7a3Z^C!e#CFNU@pwsD*{TvD8+B<2%Z64bG-x0*k+|6sZz6%n_`x&)D1y;(mgWK`C!i^q(^ayAjeM?c-Tmj*eiKSbn2_?4gFWX(5 zizs?rcQ7#KFy6{c=BA;I?Gg-~UN|&5_x4cvHtgb$VHU^!<%kp=3lS8tYTt&+%Cq^K z3u0Y7?XonP0_i!dOEl0f>eB&EP8T|S8}BQgASFFh^f^Z9F?#F$j?Z-H@hjmxOX-Dy z9F9e1^tB9|N3*{d^?{USE%w1<=695YElvRudmfX+-_yn&6K5V^tU}rJ1Vlri#TaLR zkz0zovsnl$dT6&YucJk-DFhvUDhX{V(zX(;auzG zneA2bit?m+fgn{jn%0ywch!l$iPjgtRWuK%r~!|1ojP}N#~1X%P)2t;yy_bBb4#TW zhoXcq#NL}=M8(*-YQt#~vo}vDA&caz2EIvR86t+s;stb!UDJqJeUC|qZSJ%xg1yn$ z;HmRhOlmm+8cPaW^3)*Vx7);aK(6!nux!uRagorhFuPi7vU zYt_=&wInyOrC8}p&-C?rLdw;Cpm{AX+7Jq)Nwo1Bsohx6mGbKZ!G|>Bo+#-RzXBBt`{k|D zufq4?^M+&7+;-t|lr~b(HrJ$m>la_Mjz~_N;(DmUxsWbPF*n9Wlw1yfJgBU&VfJv2 z-dY*GrfHK^`1{=7a{`m{oMj@?SA1aSsB!j=!N{I&d1u=zXVk{yer4Ch!TLWZ#0#Ae zx1xkP-*wM1K3V}Qf5_0>ugs8c8PRx$Kerg*%KU?5nrcD!;Bdgli&weKhs!xf=Ur0L zxI%l=C$iQ7T>?luS*Cyu52p#AA&{>}uk!@=&>G4LmyEbY?e4a^woEz-(_HuoOdYysOs}B$AwNLkvN}zmbnx8VPP~;h;>GvTO#)CSd4@z@d zdRDES4+g3=Zqa(EXn$&82$6*pK2QxPJeixa!_Lx>Mxy76h{$qD&#%bGHdc5{A4;WW za!1U^tlVG!F%OF)7A=D-Hqr(XB&!MXXwHK=Swv3Z{w6~uusEu9UyjT|I;jH!*g(LF z53cVse9Y34^+zF_*xr1j5#x`8TH$zG<`i_9))nOXz3u~_4d;Pr+tfK=J@2KdcZp_~ zAc9#~LJQ9Kj3V)n`-xY^#*aIq0Vhf>mlmbtAY?)TRG-|>brpkd@5M_%R{NZK&#JXX z^Jai#%Hy_JcB}r}XNkl0FMQ8e=$wn|RgRgau1)ws5@dpIS*#VyR}JCb*zpZ&C0@2= zb{-B0fRohyMi?%@hA87=Lg(@FxPxOsyxQ%yN(1g^K#uTFxoQ z#|?hz@6f$=cIyMH003HG^F7hgtxsrAuH!p(8=R)XsCL%PsSqX)nayh8e|^r?~f9()U6;kSJf zV$LnCcWj?!Z%<(mj=Vnt+1Wh+ve(@Ug9&{w}W`Z1i^(I4W> zE!}+CXp5t4Y3HM=kKUPa`T_!b64&D=UT<+nXUhY&pBYh^#G!3th+|7X?+f}oKy6g% zj8S+!4ZxpGjI8rCa_WlF()<>(dM4L&fGpz<=sI7Jo|mx{mG0X3V@#*C;I7>M;uQPK zCr0G8mF-@Pg*!fvlR~=-_p>iEWDC$j_EZumYA_D&FUn4Y`{GES)47pi%gLpu*?qv- z(47e2;+u1cMt$zEZ&9(9%D%n~;bU?NmNkx<#&Wi+69KiYMeX5S+uZgJ%X+@LtN8bMcP{!_2(85Jg@4nz=NI2O5m}K5d@CwidinBI3lhx9S9sBhu zoxoN8G5f5WA3nf;^~3Wt7`Idg;*KFeWd-np9f^b_~4$hWts zu&c`7>6=Hhi4U$#P5bk!>}3-d5~u%k6mIREzLVhfYFeiL-nU4g25L z774|p#oduX@M*zgw=(ft{crlee$xzyfXU8Y=bX$YEeoMIfY3Rv6aa%SxjO?M5CYfl z^wBW#&n2YGPCN8}-JDI#en)$&vTpR-qvqy|;oJCJ z(W`i)B6%F(=rm|wY`iDlJztI~$&w(n-23xQBKXElFhv%d(tfqwqW$swFG_R^($PJ# zlro`Z4HzSh4YRaO66<6Eag8ML5^5D#GJ&PJaiaig7;NSxgzO{amte5tkC&oyBOX$d{ z8y=7^+ecUE4Eo=UN-;YfMUEcqW->?4lnahP*;s23^$zQ59ZVr5A7Hp=tg<2sZg`EY zt@u~gj^CdNQ1s%K4$r*#{)!Xg6ooU+RL| zSm-(LwD6iaNR{S+Pl76Wz&vb4#rkQon(YLKkc1re$k`WOJ3O{47s?ebQvQc!AWbUB%Jo-(Z0SJ>WD*m?H*79=I zp`8>_86;lF0!;ZzZ-B5@bu8b(bG;eU z1|iL(isp_nIb9$Y_Q@To#t?W)Kc{ZNZ-XQU1ViV#LkGj&<;eYGAqb^{{JXxTN?e^| zYxzauv0^$=B5VS#d-Ta4ym}kOIKxq99IU4AhXv~bCn8t8vL%X-Eu4F0(fs@kfy*Vx z3N@ZjO`{gBbZPW3$%F z-ODTHHf2ybdC|&zS>mGT@h1c_Hh8g1)!W0?Uvj54p`El>*b|RDPbO^?SyPB{(sttZ zw-NTBLcifHhN~!|wDt1E>)sLX4T+dsWw((5igu45*m{4kxy6s#Two;q^ z>aNp%C6)Y4+!++V0nDoDqemGsc-}%gUi*hJr+lR!*)JNgsw@uNciOD=K_s;&_t5>? zcdl6tDKPdwAP>;Gv*Rfq*6)QWRMDVSie8nkgI`53iE1yQ=zFvIteEDXN@dK$z=a~U z20>)OqN(iSmJ%YYnP+OPtLD*hwjq~FSxAL?j;1P+ro``-z>k=oI`Z25#rl}`x3*v5GvCLHe0tTm-GZr~s0 z^VrT`Vpj=(_YCh-xr9?^-r6%D+2vksPIURHYF==>Zg;T_a}||)oO{VO?1Du2!=c$j zqW1nXC#nQQKuf7e*2&}P|Ja5U?U5CPspviV;ZbDYDn6@Z7m^b-ouM_}Hcv7<89O>p zY~q7&t$yCXFQiHsYhlyP`K?0N_k@-QS#nf*;(O{H?zL2dUdFW>Hkfm>AKXm8&c3qo zSoKR%D#kB`^~ljdam^q%NJp0zaV^Ba`xpg0)8te3N-dvQU z5eP44kBrR@H3N!txewxhY4(L3v;OgH4G%tRA+?($)x^1=j9qbu_?-Yd87r#eMgt!$ zWX~n1E{lN$tub8$m%-NOqwGWsWP4{@*m`J>n7^)QVGxL2>1_4N2;#)zuKmwVJK4mX zk-@tn-%oU2@G#X|R{2H72 zPIMzzmU(CmoKu~0OESKMNC=rBe!7+~iChs@GnmCq>knCI+CspMm)egP;kxWqr?a-V z5mjYnS&ymsg2NDog_FLc2d}p?$_9BCo%U5a=ES2H`@(jbzM^a+II?=fzwbKlJd9Vl z?CWa->qF|4=PAn_N>7BmJ2dkX&O}{A()T=-LRflx6VN8Q7B6u>nGkR`juL54dKqIf zPB|jeHBaIZ*#m+Q4zaB&VX}Fu>9E&EiS{vrlF$6|JTEp=O~$-`RJose%luoZM6f{2 zo${fX7+aaDdM74qT-arhQY$2Wc%g>QUU2T|MBj8{R9Ta$R;IFc#%f|(+?qP;+QN>& z)`E%{$mHD)6Hs=Ub50^?HBBYYpHURHZ`>*^GTx;5F79)TQSBDmd_T1;fNS8AWZVVd z>&;@dM$(cG9FWfa1aP!LxA+r2CVO9}X|Kk*E1TGPDsWWCJaj96!zK9XjeKpni9Wl9 z$+j(CBaVBh+F@;JA)TQ|xq5gyo-SQ3`)jL*vPq7ki(fL^TNP4k=WY)mYeYljaZvbw z@{vBkwcPNK<6W~Af0jwyQ7x;TxVJKs*UFt2)tJ*B{-cE7lrqS)G!hrCk)nh1y4FY~ zCM3*R`C#kKZ8Kd#R@gy0h1aihbtZudpXWJXgqMKdZct##sJ|n=>d_@pHK#RJsD%i( zjT&gUs^!<$a;}D5+D^_x%fdri&(0QEpO}EEs8bL9MMTQ|v|;y%YC@Ls#G^m zSNH7$VY7;rhoEccdhILWjP3lRP~zO11~Jxiz}Y}==d)#0AUSBfI>ZvU9)^hsp?_OUG43Q=fs{~MHd>G(G*JRK>}||4xDw;`Px@*QQ1d!G4t&zL@mNr;XlkHt6Rf>RUJ<*l~F+ z_7X1kxtht1s@Bn?pm?U!^bPzWk5tQ_DwYSIZX_V%-p6&<1WyvytYnTNPC4j2#+FI1 z*S!5U%Yi#OKw<&1@aF#ff`!UE089|dK^Awdv)*TQxVow z?Wd-=-rv~=vFZ`(abMQ0xe|O58oHahqza|Jhpgvk-e*;jFEIm@2#`?hr^i?@yVq$H z(>z=!4dqWGIIWPoDkmzI@CGX48d+)7$*CL8mm?L=jE-RE?y83YHDbv@Iz0Of*le&B z0eUa;=9-gWWwtp8i{}D0h`ss@jMv{a-b%)G!n6|Wa9?O(FY27%#_l^15nS22nQ(bK zBMZ-*C|-EU2rlz^0>X~Z0XRAcbnjNdV_CZ(;{Eza>{eIN!#CSXC?IfD>i)jrc&~r=ivpqw{?v(~P7~CXWqB;WWRQ+j(PRZkT_P{y z?$&a`P0rJ5#5*{`Jv%r@NRgW+{`%$ct$O4gdmkzWhIi{oP=bUZ)>LsWx7i7!E(kJ>AN2Pj`Y zHRAe}iCWtaG!HMqEQA4ofM^{u?&oTzc@7!e(2$1SC-&I+`P%nzc=1m(bWo^RcBThV z#U^zL7e47%Uenp?giqn0=(TrwqBigzYQy$sPlR0ux93#pK1Hwho5=IJl?32=(u?UHb?-YqPDmDHs$=4ieoAWOzsQhKn#P~ zDdC`2p0CA+Y;44KD3$uli+{Y0H7K77TUiXS*qOh|7?%_~H?t=W;WH87BHu(%xM?uC zd8!$(1(mPx^o5R(AFx%X_sw(2VIN8+e}Sz8T@_e*I`=y=gA!l#Njl&AIo2}ou8CJa zsSY++Q_ObB^-f2|!?X5yVtBO8YF|li;BLuMdPM2WrfyzEPl*(pgIu@{B*ZdY%zFY% zTH|KMz^Zohfe+I)>sFjGeWg0(jvHsYI!9EYM)Oma@|;EyluAj4PO0l$4cEmQTO6oj zwDa6iQ#4*r&3iCC|II@2Mcn6P_6V62defCk{&Z__Jy=2IRq&xT%+45W&H?;E1pDuE zzoPtMnbp@9%K1}7v9FN>wYjBn*t9>|oA{+NDY!w=%C(E;;Wf`W@-7oQcwxJr(FIRpE%%p11Siw%xS zjkowy1ADvVEXXA5If0v4Jja{`oF zb$@yjgfcUis}-0bI<_g#DFd_72CE!w=_qr-jqp5W!TpeE|`c$Yf-E_DDsa3{lS1pb6& z0;G?&g_NF?!0xfY?)`dYMih!QDMC8=k>;WOUC2ikg8iG8=j_GezLdm$`IaW!j+(;w zF2Uow)%>Y*W7!{x(Hud3XXR;oa!8j_q$CONOJ09yySV$=?ZOW?D5xd6>PGfzTb_wg z2Fni@WVy~wd_U5H-7|*W`ypuhJ(B2pB936<*xAA_=!1n%fJ{A{BF*2I^b-)(l=iCs zI>V>+rCQtD#h^Ar|2(@-I_!)qMMcH3rme}BxJpI}qayvq#kd%Kx!&!R$mPRe+HKS&`2Iek_iEA5M{PgpzM>LG6!+o2FxzkkF5aaQ!{-!GvI0 zB8eUJJNXQvv79x5FW9JoI$i|=6THC<{*0KAL&6WU0RaROfnD^m}_(uY_VXoDQW!lc zH@uh7Cvu%(aNTgr`71s1BFDkK^S={sf$*PWRnEx!@wXpx-2X5U?DygYY`!b)_5C;@ zm8X3eDZ376OWsy)-TA$2W(TDJ#i+-o~YYyET(;MV9D8@s- z8{8hwFIR|KIJXbVT>G$lkp$jwAksd~^OK?Vs?u}Dx_F*pa&QGhG_*x@T!o3z zxv6nKJ%L@kj_vx?ygrsHc1GsrT6>(Zn)vaShJ})UH8Gulf^F42hvh)NQQ zo*sw?0{2`N)GILdyB{mSRSVnXnb<%Fcu^$HHupEsTKLGRKQdUiy35)5mWT6N6tAa) z+5O$Jh%xb7zc(sbf5A@yAM-tkrgfnYIsNlBGhgm6BiAu@9DL$%z>bJA7)liLY;o)m z+kZ*SWdX8lSNUlJMCBn}YWaBq}-0EoB z?2uTc)Ieb#TUfMi&G%%eCWuZ`>kjl()|OfggnF@%lK#NOjeiz;{OLX>*8AA_oiWka z0LdonTinb0qJTennY6hcxoK-xy)0A-s3t^7-D_ZpqH3mt)vl;p&Qh}rE8}(J`#nYG z%Cik+dc}{MV+F0^w}0sqKEf@mz`q}%y~7iDBe5-b7Weh%Uh_NVdvS3YrkffG<)}g^ z@AHs4&}^db#p+<8v|I=sJ5)pfIxpHozxBA}pW4E~5QW;^pD!nX$|-7VN6+=XE=n9Q zSYcsh`EZW#_9Vm0;!1>s?v=rqRQ}Wt19d@Wg6#_SLC+b%ttCWBn&F_jBFMfGK9VCC zRdkurAvL`lN82GD{P9m3_7%;;J>O;ykTC9rY{oR(?@_IPx$O+U2IIOda|Uz-)ds#8 zAZf&E;Qo_;kg+`X2=@lX_X4(dMDd9cWh1Ei zh{I?Rufos)KLqpwXN2%`?-{O}OR?7~Cw_Rq#eRbI{GMP5@jZ8h9IQw2zpO_RXSFuo z)S;^<=*p>#Uypz0wpGjA(<yo7(mQSrQwdvOq$Z{l;UyObvvf)cRk9K{#HQ3m#L@zEPR!vv3^OfqAp?UuD zz&*i45oi=oYQZWVfa!V@amIf5h2CoC2(>_Y?NO1|>}dFPY@c7XVqT7pAH8eYR}gw_ zxJs>TsrebER*2*9`Fww-30@i92Fe~YQA76fGQ-5C9I4yU6CA&Ri?S#i`+L(b7X;<* zKVKO*7qxEv_%8h=3X#gjX+J%Bv(Gd9@o18zVRd{LvBvsDoDw2PtAmSaXR#RdrL4{a zame2Omm>YX8;y+}jr>P44g8}k)(?Tp?}MWk=-<5B#GegeA>JZQ6n;@ptws+DTu-!| zj8s3xKj0B{IXX&2aB8028H;7p!TuJ;!|Bj@tLe_JyUkDIFPj#Ph@M&o`q41ycU^smEu}1Lt;4`Z`@7?)mSH>UC_w3SVwjIE(-@P!+>*bSv zjv<60uGxUFIraUVX#4|_6b{jVqrKX{W|nW`DIiH0I0P2SyuHe(y*w{zp!Ls`hJL2v z+z1d*eiHb%dao@K5TTB*>^pk##MLIK#6TPr0O-pd;rz2C?evP`(T|2}*k?mN9K@zZ z0Zp9{NpZL*c%!{$=jR`Bd-nCz&&tkjFF1N^yQBNt7R@1BbUW^ukUgAmkq>;s-S}_q zK05gP#Y!SToL>axI@hNM{6kmho=mg=rhjA}JOv=&uzs3Js0r&Q^G|BgQ{-y_WQg!xP)VEu!bC>dG&yKnB(a?w3&2)!N4x&e<*B|nBWj`}ZTBScZ*^fv-n`ctdk@@tvVY(D zp92@E;fLo2XGKxFp|p!;fRd)#dhgcny|FMTlZn}VNatLO?VR~vHs5z7be07unE=rWs7H~qPZ_knt% zV1B~$-&nt#i=xPR^K1s3wd$u}i(8XJ$VBYZnyDHL&}CP+Hd)21zfR4bK-Zp52JDOI zf7#b(urD2EqcV_jQ?;^Nd>#$ZGJo|2rgy5ms*#?2mhTSWkP&)!@bKyvceZ&gP`pa` zz*Cd>&6{!V=<9b0!$kkK`t#l)7C0(`r9taN67N9HI%arm+J>$rJ#HlKsoc=v&zjHf zY^7{#)o4eIf(OuYMNW=25As9j>! zb>}<`XwIY@r-5!}Hoe#Q>c>sFZX`%Hh~DrUh#W-WB=}V9y>4|Zpw<11TDMNl=5X!W z4O^T_s9WYOZI!^Bn9h&>5{Oi}yw;GmJm5A1c~k~98@4h&zk#%gkusae8>S6SemDf_ z?wd0=&6-HF0mtR}*Oz}R_B!LoX1x)VZ+LuvhBfk*_K^mY*RkFA9RwGzN?CBly&RqF z_eCzxGztmOh{=ze#UD2v7edqPS3d%x>>Jhi+n38R9>}fLafGPT91E)UASV}52bT-J zM20Z=%Lb0W`xsw(e4en`(nzWNpmT|2qh;7gmA<=MCS7vsVCQ4IGPio!*%1_d)-h|0 z7mk4A!R$o70cKIu8w$>rm**(rOV6J_pAOhZH*JOmvbB)Wo32DOd|TJl2h0aN^C_mO zs9h2#m3N=dOfq0W_!zKg^>mwU9oVr8t4&GJYeise)HfZ@ zx6{W9zp%gh-2pQek9NmMR+*&r@|#e9!o&K8SH5Jy+2>?P9xzv#Wrc zJg;};fkz-V@MhyYLC?Z|w^w|t#kZjtlbK4gy7)tegtoXvO3q?*KW@5k;5 zK7V|Yh&bCSMX)xS<#*DnWRfhEFtUBE!=WQ`JUPxYomY}IFaA|@2eo3yC7|2$p#~QsmJoj zPe*yXe!UhX8Nd10eAIM&k5#MIte{f+pa~L`)s;Y5JsHYBzPL)-RgcUFChU+h5Qed}na zt4P`oe6|W|VvV!5e1eHSec2!Hx~OP7HHwJI*N1~76RAKol+^wOlC`3SveK*d+>SD* zx0M57cB(7SXg6ZQrt`vf?OzG!`};+Bz6Oc=XM0@2-N!R9jh!}q2sGZu0KZx z?~%I+175Y)4C0!QVLkOeKC*4WeCTg?inh4Bg#Wgrzmi-_@ql8d+xfqvw2XJ8tH zeuc1T=jp})9K|iTdd3L~J;h0Q}Hglu<(Y z2q4KiYL$Z!u63m~m*l3!7~kwB;2jJLde4)cj z(MVTww6J+=BE#%?Fqq182m+$4OBD-?>Nqd-F%QW@EENBar_X(nI%oa@+*IiG8wlR){@_Qi zmJ-+2m}tRIq1qaVXINeF04Nj0$TPiAQ}w9J5*uV+Q9B2flwNOMLSwfvKKHpoCtR?v zccbi;X9#X{msB%Pv&0k6>y?R_d{o`p-1^n;Hc zK4QfE1r@FA8ib*&*c7;*Jd|$R$}1$s9#mzlcBVZ06@`H4VV{^6my4`oztciu-7HZv zD7^*b)rAxhlfwdi58xvPH;QxUH#IU}P$pVi_+>IE^}{}nGXMXs{paxD$3^04t^j4- zK!>PE&+N&L5HSm9^1tguR%LtGJnNz#j3%k=ZNH(4BE5bUB=Z8>pmq>Hh&6PM0F%m} zd3BZQ+d)Mk;7*Bxugn49rt*Fx^J6>2MAp_g2>Xo|X&|_;^lX%8tu1nA-@(Tun>+99 zV%m!~kv_^nJyv%{_zx;>0LjDq`s^8Aenq9;|*1XPz#EaOlG zBLY-Bx7pVgs16j<+j>3qE=~ z7bSTa8~jbAtgAF zo2<~LSwPy;i=-wEGse+Tw`-YgbD=sjWOR5wmnGEqi_kM1gXC7}$$P*ikSL}+0r_H? z`@rg1O(cL$8S|+-2Ff;@`=^zX`J$+Y69hEE1$ebG0@o*i()!W_&Vb7%17uT+j~OFy z%ow?)JT*Q(LuI?WgkNgjg(Gq9JJuwA*@O3Q<+M)IT?|jnu#=an~=?Lp~(}FyOYu);Lm>LN7=^Ma`8k&bLL)Y0K*x!0jazD@&5Y(=CVWHUH z^wJoYfoxLm4cAE~i_?MlaRtDZk!>0N650j?)#gzw48+VL1P!@+1qRkKa#_%fs73>rJB(W|`BI7&S zz6Y$jZXrLYnpA=6iPaLlNn0nFN7_J?4$#q{re9E-B7A;YHFX!FcpHyX(xjV~Y^SX% ztgIhBQc*(b>j4bOs?e6ss|buW$GPY>C}n>ROnt6~3Fpbt7d5k^FU##|eL&*{Qhrju z;YrLeT*CqsI zP$@W7oASyr+{cHzF&7v`n~ll;`y9I@aWAv2xi0l`TceSuYChmBn}DXk z?1CqOtx~-p_@p2IBM5l^ki1xF=YdOkrmI)3e+6f?KhMDY*S9w}O}^k}CF9}Yb*IT+ zJY#6*Xd!jqd4iree)N|5Pby3V+r-+>ul*$FMPC9IDa|LbOvMFyvI%Mirjk4LdAG(( zW@C<|6A>F~mWJh3KUN#H?&sA9YgL;~y{J=OUWhUuZd*>*`Z_#AG&#v+HE_Z8&@25@ zXC^DH8x61ilwp_G+GhfyF2E4s+{JjJ;yrEG2_7K+U$Woht*xy{(z^%V7qS1dfvyfWSph!=`8ks63xKvdla6fk-#Jq9=m0$zlvKV z=SnU0b8U|ox#@Fqq%LII7#hW{9Nm`a08b^=TEc3%VYK9g9FQ`O9=JgxB-c|;&3 zGFB?I7OnH^zaZ`9ee{7_5}D0Vd@bGSmJdf_{PuDVUA{-70>pWP31{qi$f`_bIgI*2E*`-Ko<|@Kr)Nl1Mmv zf0aIpm)tE)-SXfK_zbuc=(EDc4ON9hGNP%q!WwmhzS#lHKxu{}g>EM`S}||)({B6# zzGI|*XAVXF4&df%@#_P3_wdZ!c`+^8*^IJ<)t(58tgYH5@FKbwoQ4kD9u5_8Htw&o z;3LpQ$iEG^e3I;-;d`JQ4|9aPWU>6#0OC7Wqj)I~50BO7cquvlVOD^^ew}dS{L!EV zwKpq>f$+Ka7J}GIY=+y*4_$w9lwJvbebpwSo<8Ggj}8E}VUTmTaw~}@uJte-1Z5HR z4eDFFKt?uetzLY;I0V0%er^~ebF<0i_PPfqJae{Obl=(iQMF~R#siMQcnDi{<%d6c z$9eq*HefxVU5hXq8Z_=#${o;rXOZ(YC2f3c?lJ4$0?|z;Og<*P|4)<9TdG0yUtMe9 zBJ!PGL@YLa|5-rypZ;!sCkPLburRS(Y!AvL_w|}po??Hh4pI5dBnM98C%|XqZa4yO zThG@HE#ERX9*A!5VLZ|ujqBYi{d^!35WJP+Z5?gHG6BRyO9pTQOqFmmuEzmjo z1;AhSwE)v}YO4(VaS)zI;KkM1pVa0~AW=g3TIjc1hnooVlT0+&)8%VUgmL#LNKCq( z0FtK+c*#Y1f@B>qV=FtZjq-uELw@4gx{BmC)0cjI#vhL`>ZTt9k(iZ~+Wfsvuzo2N>9RDI-;*;`LmhHdE`i~3 zMVI7jh7Akk^Vn^#T0c~qSArrksXSuP>E`$3OnayqvB#&FV#>lg`1{g`;`(BAR%)73 z6T735!9f1{w8O7JQUbixLhiiqF!tSJyO+N`lAhoCsh--rDs+xgx#w*l zj|~I~CklI!HICt4wI1flO4o^60Wq_WXriSF|GfHt|I<(yXv0(i_?(`d9{L>OdO>$s z)%v{OC$PXYaoC&$u-6)ABAaPS*CKrRrz7|YC>VoQAmxct@9-We+#f(w+VqM!A+YOm zro1~{Ut$4S1e}w3AXKoGIvd;nHlHO0>@qMh0VVbV^w_x9&J>rI`Ipm0>_`v>Tq@DY z(`Q!`-%k&w7glW-KU}(0`x%r@eI;LO0A9^-L`eX?_TeR;&-B#q!+ z|D)I-$w#m#9vxL{9I{g(K(NKWZa*P8KY&7H*T+RhQcO~xy@U{G#9}&n@exAgh1JaH zsUEJUN=(`{=&6P270%J!CIU>D#EGu=;mCOOi<-^$JJTVNIbyA&9p2Kx6}4&Gq0xTo~bV&Uz}$C3%p%m%FMBT2Fk= z^utGv+yG#TKhF^neu4}XeP@bdF)3jhmX6z3UBO|{&AoG`pF3d=9)Z3PDf-4!7hq-x zzn$H?h8u>uQ~)1BLE*i>g2Hn(QVcOA=lsHf>PqY1js;!V(Px81Uwl^e+E)<_qG+=N z6q@kc8JcMj)z-ZT2%$iI6J>INh7hKoT}_qG1*S27vE8?bz+DIY8F1Gv9|!B@&y+(3cjOR zH#hD*@NW|Hp(g@>r~sNIz^#^OnrDH{0Qt=14pBgnUiFz+4xgB)0C58u-;@FS1g8Z3 z_|Mx(|7RYLs#`UblJbK%Le%{5YoJ#k3Xb+@79237c!!Bwer#)-AIu=4-g~s($ShpF z8MtHvSROacTPTMr9kT$w1y53}@||uYPN~43FU|mBk{JjRi#&I2v*G9}$M(6Q;;c%1 z8GAL2EY&FU*624U{6TfFI3b$|0w%Zmec?`{$L;Z4rBC}dT;;8K!-4UUjQ)Nqhd$mJ z*}!xQR1ke#CA+H zmPK)8yUb?9Y`Da7<2wxkI7Z_<35BC=l#g@64P_{)MV7tK7Iv4lZtpvPy4T^3Y8b+6 zTWhG?E@{+#Hi3-ndQTgOn{MkchA~U5TylIh5PWDFCdL5>SdoCX^Kr;TW;a#hy6b$m ztoK1rlAI=s`&hqY16ZYby)X90R*xEmTcqUiOq^W{pkeU}k2z_Om$h^F1AZ-u$E)X0 z$N7Esm7(;1{IdqycIts#JvJ12C-&%Ipl-+VqIKq{da#}8?EwVm8r>yocX#*HNzbFb zb%fhHWw;h|ie5JCn?r>~1ejO=sf6i{=L-&NlUanrT83-5E z^YjHRxO@9_5N(=QPe0;R%K}EG@}%8Y+lrs~?mu7AOug4oeI``%Y*KDk#{zVfY=Wa} z1NJ_ao{+zGFZIdXbU9V?jng(eZ?@Ii!+h{w%=dk*wGQu{;;E&pUko5l+7Wmy$2EUx zp_dG1=Yane)U&1lLC*Qh%50Jk-$C5vV-xW9PCH2W7?41Zy*!v!fScN)x3!^G{)}gn z4ehE>-~GWNWBwXPV|;xa!$5>VA94<Al0+W_d00CuiR+iNtkE5 zc0%|BtNQfhaJoyL+1VRsw@rAQ)a^KBd$a{G?$|}`^pEwHfHeh(KkK!}&Ex$JA3nxA zE>0(hQ9AHvwmDURLdC{vTowoVQau;78eb97v_Q5S6~4D7h8t}!QlDG>)cv7Q%5;Q9n3Lsk8H=N z7kTK%T&o`>(uzPJS@&LNMQT`1O(g0uq{MdtNss`_u z|Miv-s43BZa_GGD+loV`ybkyW@1UZycNNZzyPqTgGB{cn=zc#(0}VD&4ib!Z56k{} zDUb9jNMt9sNSXfQ5{`gHJm78F`R6zP_Ef(YUp=Na2du-tw(AF?FZ>(^0SHL^_EYtCz~PRk zS_2pR=Qk|>mkTL7y#7$Fakuo=oi_rD9Z+cI0x7(Wy~(h{#irjqfTRULCF#Szc)LslUK`zbbr&?r zUGthF-XqxJ^V_?b#<@yhKAkoJHz3H zt(OMEmfcs}mrDoI!4nFdWH0s9k;M?~EO8Apgge0s8a%GVDk z34~mb+02iRudrRg^BWG|sdN+?Lm4Sn41VGh<6(-fy(Xq*9U2Aqn$yRZm|qY22N zr=S^(M=R&b?x)9r!St;KSw?aKPf#{Z|C^M6YEj^p@B)0Ic_uG_8blJ>>Z zh9RdCLoCzPW`2QM=a7_-ZfR(y2!2T|K~u5NPTQqjA!D5ZGYqP^wh+*)>9l4kg6SrZ z4nZ(wB58=QH@4gVu)F>I`F!r)@Av0*@7Lq~dOhDyYv!;wZgSl81kLN$Q0ejI6magP z69OO2G))4{!T#w%F2a2v`BSgQn%!3nhXHEzteTVD8jbX2T0WFyQl5F7-|vKo~=V zGd;g=$LUXqogi<0jV&}bPTj(rFbqdY_OtIQ>;3nR-M>SD-cPP^F?a((8z z);spS4Vvh(OEC54uUPCUR))f6enYHd^37&CI!8cGb>HY}E!J`SvyY5L`EbCFq% zCDwdizxDls=_j<9`H9n7@+noH|Ct12mxKQLsmnny%-aS8(2xpcKz5#iDpO>1E1_|cW z^PSA)hwuzwd*i98_V!+Dxd8KrYB1;{D8`FGT5i$wH8Njp+0)KJVjMwX;+HM6?0iz? z5~#z|1pz-lmX%sFfd2wMOND3A{RHJXn~+f*X_=3JL=~K9*X7`(*E!qB>xsz z-#K*NQTYOvaS;ZS@y;$>sNaFRH}WndXEQ9i==*?KkB5F0_h~{xyZe|1Qj6Q{Z)eqm z^0=x!!W?th*)wrfdGmv~`NHWbr=>Qkuq-9iVuIzwHwV+!i=j4EAi{X@h+P}8I~pD! zz;tGwI1yn@B!EIWn5Od@M2%63E=4pXdF1s6MjIu18+#7?EK?*ux@w^#Te-=wd8LPn zvNU%DZ!1}vn=q%U)TNKnCr26qER%rFKfo{`##5hhHmoepOnEZo8xtjWMO;785{bgq zkLUo5)?i@G;U8G+p(mfey*7htH~9v=8s^7y5i@}V96Wr=)XT8YKYCz zD&$=zu(cn03@Y+CK`*dRQrr*1HXUBQxo%j2_=g)JU^IhkfKW0WB*w0>j?Y-}HuY2uh&&zwd8Z1Y- zkM7&Ik45v&ErWgg4&e9g+rNC65j+_(-5uJuPhg+st?PzJC^hW}@=SN{ZpKIW{_AqR z9M|K84P)Pb_Q`*+<@D*RiAnj0@gXysHQ;&v;jOY%_?*_>ilJ_w~18 zr|-oYnw~N}c;KSion0~)ck*+5lj6MJc#^zyZDkQOfIkV9?isL_7c;A{fE`|9XS4U-@%7k0!##+`}Rp^{(kyYV;`aA2KeD$zxRjierEWGF?$bsi+?@j zg!cUV&&QvteK=x`v=tSP3I6-xXIe4iUvHrIq_dB}14AY8{`Cg%GIWCM-=+v0haKRg zJZNbd{f|}>_z(ZKRbXGx1NP6fdNZgX)87xD4%@T*YcTY7-;(#CAw7#y@_&sGJY*J! z{W;p-FBa%ID1rYJpU`yu?}ye%Q-=Q-+$X`O!{KH4yR5%`^rtz57Vf`CfBYYp0RR5u zl7CjoKO5&CEcpjs|G$ekpH&XVKf%>)VO5x9Ua%e%uul5if#pD*_G9C+u9O;kCh#$! z+Zf~0!m9I3NKdEbAmXa!xY36pT*6p$tY_LjG?x2NXlUq|Uf^a7ezgx)?6>AN)sY=) z;X9Sx@!m*;?2Yl*wu1irjiv4kUKQo5SvUYP?q>@_RKRO)3Px0&SDf9~% zFzQ?wT%ETgmdnbfotY++d`s0{`IzwDs8%SmTZp@PgD;_gI8*JJ+vVq&TtL8h3@An> zUsQ~&lJW5L7~XZ>T{@PntLc6SQCBv7XXkPNzkK=_Q&*`y%&9oAr?KqWq$ZrZ^!Mei>a02Td&S|meJB77Up++vLzR37oTe z=A2xRcU?^jwI?nr*OKlbN@qT0gjFoJuiuqYm)_V6`(C^g%qHCW$O#w!dg#4rmSa-a zmI$-H1m5Z15FSY3%(IjnYa9wX4BrXVYcm%S&&HP{q$xg}3ObF}e-^w3n;CPSqZTCd@WaNvU| zaR?rND_QP?i05V2Xjb9|b=1pExb6Gp<6~O|b|#*^>4DL)b8Z4GefX>1=2xSnClK*P zGjiJVvNPEg2vHQyQRB)74kEvaAT`M1MGe?YGW>rI{8K_iyWEH^BfG(R(K z$qvX=cm&!pzAyjnZf_mee=%EgWMLQ=+hth#0lZDH1`t|XpTOxNw z!7gtfs`1BJ_^)(Jd5qrSl6iE`SmE|YkVW^muwmJTN@>+tNc@L56>73?P6ERL{foe8 znECFlD_5K^dwV3@A+Sm-KdGlB+kURCiIGdeHpQb??5>lP>xG>)I?guM&lXu#8da^r zu3U~NSXW0^vIU&q;KwAy^Q9nj5-vPBP(OP{)KakWW{6hE)*3!~KY^!4OrLi@Ku9Af zYV359ihq?M>npt!IUV1X#WjN&A=Rh?X}tMSpQa;gc+rADq1X~e?>Ly=G<%(QYvM^= zf%j|Vh_cH~ZQ;QebLZGPDrUTz@~bBj-ZV4A(*`d|jV{G?JU02XT`(3(a4s~lr1nb~TMePQtN)16JeetpJ_z6(cBUP3U#;OW9V zj%~43)ILqJyk{1o(}EfP(BvkOy@A%#+Stsc?=O&>Y|+b#+1Pw7Yd-qTkFu(Ji3GEk zzxPclNQh!(Uuh}bU2i!bZN{>@WcF2x0ITUKeVog@`;Y`r(2yjhoFbU3U||S2QOwOK zq<2Ra_jz1^1lv$w)h~MDhMk%1?RYa_Wo#QlW@CqseL92WZoGceKW5X(0qt2`I@j>r|&C}D?R<5 z8B;k|eVS*~M4GasrKG%iSpJ>)azK+{+J?I>{_w4_-M;GT6qh~U4@_A72`&TN_gBK# zO(JAs(@OVxZfrD}_!Za8`@k>rBtPF1{(OxGT2cT*_z-OnPDHoDj0^oUJIf;$(bQuc z&E(7mq>uvXi3K;yhfN)>Tig#sjZS=~2^WUuDMfXrxd9Ip)%sC5Jl61Ilr0p8ML^h^ z73<;WngU1H5>TYMa!k=O1#4d0t&~spfNEXL2bRBS=nL=oh2zJsE!FhmO4f!XA}hF| zB{#Re$<8C^`-u)AVZ|H^=#`rYO^(jiiM`GcM(pPKs5 z36gkPon;kq4k6g@!y(!emsjy5h3=qX7Ig-4!9!%+sj#mMy(B}J6n+%7(>^-z=E!sZ zK&nMx>g)rb)X^^C*Y!-4;x&I<{hTR?j z-Hs3BjiP=zAcLC+8I2%$e)VxxQ{#vhQV1W^q^q0nGTP*&Pa@ms-JHaTVOj5{C5Iac zFcT_SXXzLP3`E1JE`%p=elk z1+>*lnsGVtXItVoS~Bcw+wZnu9h>1sQLcmCBh}I82EmpgpIxgk{z?=Kig6Vx&u5xzlsCDEDnKw-8k7sU2?`7Xvr$0 zsFJtDvfh*JHMLSr^p-?#n{m`HYh>9{S>H}^b>KUMzhI>$GrY?%jDnQFYb8HYjVeit zw<5qcqbG>*3S>tuwWZx=8Ei`Uuq+uJH{m@jo`|D^9^@^G%HpsZH zo+kqRi3Wmb@-o1;U=`WzlkNCgDPS@1)r!q1$`XR-t{gO+iBrN1DatR=$ErG$Wf?SV zWMHur}+FsPE7u=>`v2CpFxnq)XDaW+F~NLPXeEVMx>LC2t0ATu7>r|bJeGMP`%?| zaoAj$(6s`K!9Vv2Yre&_Q~hYMduWn(UXr*V6YqC`annhmuD^0rzW+{oo%eaV0x zxhQ!P_L(Xw)JU!rFr}Ds-?aQ}~CQ63%?<&EJxH?AOoIr09=K>=n= zK9^TI`7{BBxR(KF#3>h{*Mt!7xFAB6`Xb|%{-8EM9Y!sc?@dGAvp2ajDhu_~7fbuA zN-KV_&}@#gjS7Ugbpj8jOYFFsZc@+4*TBt_-0PnTgy>Qao;*CVTb$O<(o9RPx>@t! zQsoOpJJ*u>;yi8h0+G+B30u=QGn!vT_GseLx0?RY3^B8}#{H1Kf2MiU$UNJ8&)DPZ z22;P-{4HgAuNd~?5QRI;n3KB#XB)4x4wesFuH1Z^DzO7MxMz5k%sO+yktJe$PCM#u zJ|FM?{xxz@cyRV3szg)1(Z%p8odh%Qz>f;+fJ~K}VTRita&6aX<>PR-;>%%IHVTtX z3+A5qD+5T5MC0Qrp-Nn7<1Tf5sJ9 zu5O%JWo3tJn@fIwO?CI#?T%!l)K6E?!$z+=RvF|cZTjW#4tPx9YFe28!)VBIC40!7 z41`W_I^zoajnCsdMh0EF6_oqk2KIwi3v&rC6f=XdtC;Lzya4gRXnREA) zNX_N(P*y~+zWR)wiGv0uu<5Thh)iNpsr=p2xAqN!V$6y&l62+-*d5YaVZbM2^ejYX zCOPhyHL~zR`0eXpy@$#1H*()({R(Dlh}Lm(gD|v|eRBz&KIPi?v8di_@`UGs@;ULC z{y{qboOKpkG26DB#-gqq_qfgpm2OulfZRz~Ny+*M<@-%Ri!4QE7BqTk@g(Z1VtFRB zN|{E_Quo!5KYPa(7g9v3`KB(8qIBHIiG!8}CfcFjGqZ_CF$`bAhgl95EZvsGYn|-# z6%b)Dc_xLYh%uv}qFn5q4Lv(XfTf?}SdKPZsg0{2%weh*7b3tIT@*ShMC-<-&G_fX-k*!2?qo;zcT3@OB8f`yQ!JPQfDhW&=1@>NIwWY^(gAt0 z?1|##6&L=-cyu%(=?x2p>oAH^I`;D$_hCEFK<EDL7JUWCLWOPKL>gLE52z|u`b zu%W|alKSjG;@5e8)n7S*Zk-VY==cF4;3i`LP0l-sz4i@VDwB#VbMIRJ>vzlDnJ$eDl1E928nz*F? zg;p<*O_?6|mM8J3yKxXw)*IBq_W?(rFZO&k#8jMClw@**Km&~}Fj-bp6T3%6usr3% zL>UtJceo$$arKOII^+Z0?kT;X20N`LYda$J7AE^NlNheua}k=z2-3h zw{3uvRb!OkiD<|b;ACte3`K`?PRjFu^{qrXkjH;;(bZWCO4VUYA*1b)MBc`wK0_(4 zvX08yuWeLdakAt(aS8k+Cca%myDQ52yK%$4m*^w~x`34DNbtX%E~^|R zTK35pw1o-YNGB(!eiAnv+&LXL;1Qnmme_7$|!XHbwPu(cpUG9QgoaUK^9Lw{Bp%I)_c~mCYe1 z0*(vb03vqLL5Qy{GS2HO&4JNZdswU~Wg-3Q4k9#+xBdFuwQMVg7Zt)i2Mq?TZo_n= zEmN586mAY_Wwxr&s{d3?>&ZQ@Q?X4~9J`Naa+*X9*Bjb%x3dJ1K%-LyGbFTUhE z6j_D~Uxc)RX*K5(0ei*t30Frbsi7mL_@-$+cWbodNa><1zALYFr5&}XIhAiCazAXO zp$O+CBfJ>jZm`%Z{Cc@059o-uBt9t^TI>)CxU>mKZuB5pI>&sP^=iySy?qjpXfo%}Vn`1|@2mwk!5m}5$0d11LA5xt z_1(srTI<}}tW&7Hqs=ErWcUKhFA4hl=+Or?e%GlTXTnLyE53||NEzI6767KmOW=Eh z0^Gg}SGx2xK(oHw;<@`Rh~a?!LE#}QK`d@3<Zm{UU+YJ_m#67R%uI!n_>tU4hwu^V2-9aymvlcWbMua z6eSOk`Wf`FxBcmv2zEljHy#3vNd^T~^dQfuTZB+HXi14YL`t4|*3YaBkR0zlh(gd@7aNZ&t1QlANuUj@ zo<$VJw}B;YZf(%f`z7fARi_{BcGUcY_c;JKWw@M?-?@k|nym6@5x<&L_2ARhk&|_6 z)GCk+RJ2T>Tx)z^4Y*18nBGG{O+d#K>mH+2&}m%PHyR^DvJzav!ZP2vW@@AR!u-qL zg~*XDge71#v-T+H5=ZIX(sTW)Vrp)XABru2ZfDam_D9+2kZG_4PlH4(2%tZ2zmSQX zAUV;});DA~@8#72WtC<^p+tF}26rZ?q!f_})ByHP_*;+2Ds=aTO(;fv_G z$nXd0getnPJ*Yw3Q;B+UjXzvLLLo-VGZM+@-x+(#>M?P}kHR+7w=?!`ST>bxA#W;2 zN{T_GgLPWr1Kx*ep|8^l81cm%aCw}Cp8(DoWEH}qlTm%Z2o>qo!%lr4!K_$|Ht#vv zkdB9+P5a&Y^GMgdnkVVlp-+7Fw0!0F)nCWxlQ&Q{e!~Y0Mhm>H-2n?Ho&jK6bn4XU zmN03?#s&ZWY1!QS)(3?r5CHK3p2OA>3Ka2-6&uk$rs-IM|C;8U`^|!`Cv_S#qun7Y zalR}wjey!~wM6I~Fy}d?tMleb`r7j)ws^N4b0bvo3_URUT>pzVd6UmJ7R}M(n^r;& zZFmq`wDEkO>7+SioJI7CW|G8V!?=D?RaWwxcmfM%xMpD?sTeVBIDgvS(vcKjMeR3v zaOM!ttI?#CGrocQT_zJL9W#v#UmwUVZ$pA2Cor*xO5(M5)V(jxPY1om1qL5=8HoZ3 zZ1Di>uLKLXs)iV(ard^RZM?;QvMWqXQ?vDzAGq{*L>ca;@HNt%kRVzc-o~bsnCH0Bcu)OMg^(*aeNn1!@AD4EHhPVdE`trHW9?Vi zUU>ApDe|Cd`WLfD7u-Den4qma$`(jUSS9i_7qExS5~=b0VX!q5US>?w(l{Hx7_R3- z^qEWz?UVvRzt>lhh{`A1<62Fw-_;h2xF)H>9?$hY&z7r7+k>3%>T7@@We~l%a1h=G z5!9@iRC%sFn`oNjdd3NBWM-DSSN-cpgst7J`4%E%=xS$t+d|=+KaIcey7#mUE*OZFGk(43fG;x{{+Det9*l+)W;+r{^zA*G z@5a#2XTU#;EgyxcO2RPf}h>#c$2w3=9n~#t7Av+JCJ|L=Uy%#hqt|u-Tm@n4=rH%yG92VZY8N$ z!2w0uXb}{hyM#7=@$XgmgkYt1_!JRYml`|5wa3E9q&qVMLaEEc7?rTE5+A~cpXI8= zZ?yDi&NFz}w{56?GETVh6KZ87WHzu_E%lA;k?p11kXNPw$TZ>&QUeYOz=S2)fb!XeYl?yMTD?228+XHks*73m?XE7Vn(KuN<{v2ne_CO&j*v_on@eL_p8I||Kq z=T&hQ@p$ZY?o+O@Z!P1sXIjLIYlZS2g@0bd>LhIJO`p5XVsgBIgikoN+fofKGs9WX*y2PK3gxl4v!>k=FX}%P zHoWpehjceu;%Y~V3Fh5f2)fZ;CQvDL<3Im`DKM147YTFBR!HLGnCE?l{3mX6+%@(g zpjjw;zN@oWva_?Lz>eAY8O(;q%B?GdXwo3raW98!eqsgZ>)oa|;Sb^+pJ=m>W*H%6 z8c4GgQh}<6Lj2{ZKmRf#rOb?JnLY$TFvBkqwwf+yG^Y7brl=zUz#&rh&8H*S`2eVv-2e1`jcOdA3dimi&dRdAJ&A@KoMbJ%iy!XpXe?v$NcBOs$Xq5Blx-Hw z$2ft6u^`iGjE~X`GP(JFQQ#9m;nSPm1I4E8>6Af`+8D@l)~Iv-s_;w&3O@_ITvl>X z65po9G5J{%A2hO~=MH42M;Wdl6F+$7^HdT&a_|2`|8`R|8WcI)-bY7GbbrsQ5(CAN z`)T|MNkp$_S?5g@Jk1-bbzgr3!B^UzRCK@i0 zLWfy=25*-sf&vT|=yQ^}FKU9gFZqQwkTf46MgNFWe*EKZ)ttK?#)He^49N`{h;M>3v@znBWNl8e11vF7Re(!BOuspjo3%rLVzmC{Ww9= z47+c9Zf;7yPIvtZ-SCz}r#f4JI`b8<5;e!~XeIa=+7qbr1z`Bf5oJPW`0!54eV)46 zZEq^sK$q9&j(S|90l_=?ad->Bfr-M-7}|xj3I3WKgT07WN+K&4*LwL$^W3D=U;Sq5R~53D>m`1@oVt zd+$d>t}cF`3mrDI_VqqF*+;k2eA(`~B#&ctDhV=kBmS3KXlfLD4GhXXLQ=4Z)S` zVAN57@2iob_06S1u9XoIhGL zXr;S7{4#a3<4v#pdHI#Pan_-#t+|+$wL$Um9sJ+~ac#FHT6up-@NT#J&ARPBt1;^f zy&R{b|5eZOQ`~aAD=++uFF+(%v*a)uqI2(vA}AtUtN^j}B6#_976~N1_}YiTSfJMW z$`@az6>!Zr`H9Fi>Qzz2Ne>*R0Y`iWYB%(Hi+%3qYoG2nvm9!bN3Aj>&B_C5LH};I zGAUW?KYYWGpe_-XfG+u)^Y+NJLo;Y_4zTv^T*#cR1Q0_e->aS=CM5nmnA> ztSuZuxq7$c*v44_y#uRXi-3(LZQP`w&*OAm!9a{oKl- z_DY24mem_4!-S%=E;ze;U7;_;C(3mjTJ#jGNI6Op?{|g~MVWPr67a;0X^aDtO$p{= zSaXZzqEj3-B5`}Aj}ap8M!G@KB$LY!$VPbw4p zC+SpM+S0(%NCk_tUCKP4t!T(B4&LjD7DWNdG!s-PmjsP|Dpu!tDZuzdK z=(Ad;u28Vx^h0F~+o;KWl;R7Me9%q}kr3`?;&HXkkEq+qzro=9zrX-6>Ra5amYk!g zPMm3}2X2;@ldBQ#XcXNq8W@fSg_Fjmp1fF}X9&8*?@}k~XgS#U*N8I!Na(OP`4j+2 zA=gJ^fTQLmXQop1jocv21eh0ONrEedm0RS8;Pi5&o zn&t2VQ1<|x0G=eHK_N%>ecm`2UT>h>w@(K^H%4@HeIeJkVff;TsnZET4nW6*?2rX5 zR3M<~41HY6H+Dnsdvz;L`_vMild|uOHM17jr?a^AzmYL>fEs>vg69}>K z*=2Gzqln&N;*A<^51b7*v@=Bse%m$kHK-tsyo(3pb6Ds-{!1HR+z1`xM9R;Rw)lU5 zHo)WJs{l{w>R*P^e4ybU2EZrpLk-e_=D6W_GZpiVCY%pI=s@8Qw9@?9A2xJxDoJ$J z%L4}vsEnf4@{X5*aA3rdO-Ira68i7yGpp1|tTYws*i#s-nCbM+ch*SawWH(2 z1fyRKezwyJe&sTggDqqw3;D`NQ&LSJ_2O|00jNCi3tc6(eDs&a!gmGK%3Hnaz!seE zo6^}Iw_MM1LS?&jWkK<^=}-4N9Q%b%h;QWIO&8}&hAiL3p!DFWtR*q7t#j}BkB)t~ zZaLN$vw7>GFW8Ylkk@XQUCfF5G?8o132(5l}$1VrJTDCoMMpoX`xtl7MjUzWj zi0av8nZz<dJt5rB)F(v0%jt%7t z$+W&1t)y)KcJ}JkGlle>!z$9S%PRrIDr3{{WlU0N2=2uREU32t*gow6_D&zoxRL7S ze_adVAGh!3$29W68JYuppXA&d|7=s}`>DT?S_PID=dY-V za9aQh4IhmGDDZq@vblu@lIO_-bcBBBYC&33mj}HJ`h4ndrUGHdlC)G$7vXImhyb&~ ze*{aMCxFd;1eClF@O_ah8b@WO0|CO=Vph%*R|Lvzx+Y6_cM>&cQ>cd?JT9yYgnf zY01HY5kXP109W+C$dm*CMt%J{=SVxShz0=k%>|0!GzywPSJ$H7c;Ljiq0-}d6R4PE zV9+OCL%Kl=Og4AGG8PVM0RJG~=okX&YYf2-M>4ejsX=BYPw3DKVH%#t!7N}H*uEY| z|1oUz4Aj{VQ17G&jnlP2L2&FKso%Somi!4EiPCn1tb~+M!CE0lGre7u0Hy$@uJwk` ziM>n-6IwZVk%#gIIFyHyH->7W8t;7p1;o%{@6qddN_W99AA^4$h4kG5Lv?n8uSFI&2scWvz&ODdKJLb2py&(%8n?KW`I;2jW)T01H$Xj;nmqN6FxU_wGeXW<1685p~Zw|~_ex+q8;?HVD#x%1<8&&W-t;cm)I^VJu z6FUdJtXQt}w%AxV!xvjRg?OWd5lD_5L#2dso}=bacyEQq$~I9q8!Q1@dynpy^12J( zJ9G;i;5t$M!|FLu-01|N?+cw2*VDLv6}T&5AH`Y7&Db`%-qV0qPu6CEIxn{?!_;u! zj`#RLTa7$tCX5;GG{xFmIi`6Gm3;iNuc8N;-1V`Z_y@pV~&FIegXE~vkJ`IKu`UfR110B(d zj@pih@TtLS&zG}(s}lmpb3Sl^=@rC|H#Zfd+IZ>8G^`bVJVdgx9{jQ2W&N>}PfM3T z-?y3^Nqqgf!)vfD>H|=AGS`{m>OZ!vM*A4J2s2i{Trd*qGVppopy7x@Kb*@`!n~AB z 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 D2g2=) literal 0 HcmV?d00001 diff --git a/test/image/mocks/legend_horizontal.json b/test/image/mocks/legend_horizontal.json new file mode 100644 index 00000000000..796ca877275 --- /dev/null +++ b/test/image/mocks/legend_horizontal.json @@ -0,0 +1,211 @@ +{ + "data": [ + { + "x": [ + 0, + 0.3571429, + 0.7142857, + 1.071429, + 1.428571, + 1.785714, + 2.142857, + 2.5, + 2.857143, + 3.214286, + 3.571429, + 3.928571, + 4.285714, + 4.642857, + 5 + ], + "y": [ + 0.869693, + 1.088434, + 0.758308, + 1.849319, + 1.728616, + 0.9908515, + 1.519909, + 1.083975, + 0.3153477, + 0.04181056, + -0.3400965, + -0.1003989, + -0.6768811, + -0.8555722, + -0.4287511 + ], + "name": "trace 0", + "type": "scatter" + }, + { + "x": [ + 0, + 1, + 2, + 3, + 4, + 5 + ], + "y": [ + 1, + 0.5, + 0.7, + -1.2, + 0.3, + 0.4 + ], + "name": "trace 1", + "type": "bar" + } + ], + "layout": { + "title": "Click to enter Plot title", + "titlefont": { + "color": "", + "family": "", + "size": 0 + }, + "font": { + "family": "'Open sans', verdana, arial, sans-serif", + "size": 12, + "color": "#444" + }, + "showlegend": true, + "autosize": true, + "width": 1152, + "height": 481, + "xaxis": { + "title": "Click to enter X axis title", + "titlefont": { + "color": "", + "family": "", + "size": 0 + }, + "range": [ + -0.5, + 5.5 + ], + "domain": [ + 0, + 1 + ], + "type": "linear", + "rangemode": "normal", + "showgrid": false, + "zeroline": false, + "showline": false, + "autotick": true, + "nticks": 0, + "ticks": "", + "showticklabels": true, + "tick0": 0, + "dtick": 1, + "ticklen": 5, + "tickwidth": 1, + "tickcolor": "#444", + "tickangle": "auto", + "tickfont": { + "family": "", + "size": 0, + "color": "" + }, + "exponentformat": "B", + "showexponent": "all", + "gridcolor": "#eee", + "gridwidth": 1, + "zerolinecolor": "#444", + "zerolinewidth": 1, + "linecolor": "#444", + "linewidth": 1, + "anchor": "y", + "position": 0, + "mirror": false, + "overlaying": false, + "autorange": true + }, + "yaxis": { + "title": "Click to enter Y axis title", + "titlefont": { + "color": "", + "family": "", + "size": 0 + }, + "range": [ + -1.3694066111111112, + 2.018725611111111 + ], + "domain": [ + 0, + 1 + ], + "type": "linear", + "rangemode": "normal", + "showgrid": true, + "zeroline": true, + "showline": false, + "autotick": true, + "nticks": 0, + "ticks": "", + "showticklabels": true, + "tick0": 0, + "dtick": 0.5, + "ticklen": 5, + "tickwidth": 1, + "tickcolor": "#444", + "tickangle": "auto", + "tickfont": { + "family": "", + "size": 0, + "color": "" + }, + "exponentformat": "B", + "showexponent": "all", + "gridcolor": "#eee", + "gridwidth": 1, + "zerolinecolor": "#444", + "zerolinewidth": 1, + "linecolor": "#444", + "linewidth": 1, + "anchor": "x", + "position": 0, + "mirror": false, + "overlaying": false, + "autorange": true + }, + "legend": { + "orientation": "h", + "x": 0, + "xanchor": "left", + "y": -0.1, + "yanchor": "top", + "traceorder": "normal", + "font": { + "family": "", + "size": 0, + "color": "" + }, + "bgcolor": "#fff", + "bordercolor": "#444", + "borderwidth": 0 + }, + "margin": { + "l": 80, + "r": 80, + "b": 80, + "t": 100, + "pad": 0, + "autoexpand": true + }, + "paper_bgcolor": "#fff", + "plot_bgcolor": "#fff", + "hovermode": "x", + "dragmode": "zoom", + "barmode": "group", + "bargap": 0.2, + "bargroupgap": 0, + "boxmode": "overlay", + "separators": ".,", + "hidesources": false + } +} diff --git a/test/image/mocks/legend_horizontal_groups.json b/test/image/mocks/legend_horizontal_groups.json new file mode 100644 index 00000000000..ee67ea2cf51 --- /dev/null +++ b/test/image/mocks/legend_horizontal_groups.json @@ -0,0 +1,119 @@ +{ + "data": [ + { + "type": "scatter", + "x": [ + 1, + 2, + 3 + ], + "y": [ + 2, + 1, + 2 + ], + "legendgroup": "group" + }, + { + "type": "box", + "x": [ + 1, + 2, + 3 + ], + "y": [ + 1, + 2, + 1 + ], + "legendgroup": "group", + "showlegend": false + }, + { + "type": "bar", + "x": [ + 1, + 2, + 3 + ], + "y": [ + 2, + 1, + 2 + ], + "legendgroup": "group 2" + }, + { + "type": "scatter", + "x": [ + 3, + 4, + 5 + ], + "y": [ + 2, + 1, + 2 + ], + "legendgroup": "group" + }, + { + "type": "scatter", + "x": [ + 3, + 4, + 5 + ], + "y": [ + 1, + 2, + 1 + ] + }, + { + "type": "bar", + "x": [ + 3, + 4, + 5 + ], + "y": [ + 2, + 1, + 2 + ], + "legendgroup": "group 2", + "showlegend": false + } + ], + "layout": { + "legend": { + "x": 0, + "xanchor": "left", + "y": -0.1, + "yanchor": "top", + "orientation": "h", + "tracegroupgap": 20 + }, + "xaxis": { + "type": "linear", + "range": [ + 0.5, + 5.5 + ], + "autorange": true + }, + "yaxis": { + "type": "linear", + "range": [ + 0, + 2.136498516320475 + ], + "autorange": true + }, + "height": 450, + "width": 1000, + "autosize": true, + "showlegend": true + } +} From 25c2970fd4490327d59db4b7569a182d781374be Mon Sep 17 00:00:00 2001 From: Nicolas Riesco Date: Tue, 17 May 2016 12:02:48 +0100 Subject: [PATCH 12/19] Legend: Use D3 to invoke functions * Used `selection.call()` to invoke drawTexts, setupTraceToggle and computeTextDimentions. --- src/components/legend/draw.js | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/src/components/legend/draw.js b/src/components/legend/draw.js index ab61cf87875..23428860fe9 100644 --- a/src/components/legend/draw.js +++ b/src/components/legend/draw.js @@ -117,8 +117,11 @@ module.exports = function draw(gd) { } }) .each(function(d) { - drawTexts(gd, this, d[0]); - setupTraceToggle(gd, this, d[0]); + var legendItem = d[0]; + + d3.select(this) + .call(drawTexts, gd, legendItem) + .call(setupTraceToggle, gd, legendItem); }); if(gd.firstRender) { @@ -311,14 +314,14 @@ module.exports = function draw(gd) { } }; -function drawTexts(gd, context, legendItem) { +function drawTexts(g, gd, legendItem) { var fullLayout = gd._fullLayout, trace = legendItem.trace, isPie = Plots.traceIs(trace, 'pie'), traceIndex = trace.index, name = isPie ? legendItem.label : trace.name; - var text = d3.select(context).selectAll('text.legendtext') + var text = g.selectAll('text.legendtext') .data([0]); text.enter().append('text').classed('legendtext', true); text.attr({ @@ -334,7 +337,7 @@ function drawTexts(gd, context, legendItem) { function textLayout(s) { Plotly.util.convertToTspans(s, function() { s.selectAll('tspan.line').attr({x: s.attr('x')}); - computeTextDimensions(gd, context, legendItem); + g.call(computeTextDimensions, gd, legendItem); }); } @@ -352,12 +355,12 @@ function drawTexts(gd, context, legendItem) { else text.call(textLayout); } -function setupTraceToggle(gd, container, legendItem) { +function setupTraceToggle(g, gd, legendItem) { var hiddenSlices = gd._fullLayout.hiddenlabels ? gd._fullLayout.hiddenlabels.slice() : []; - var traceToggle = d3.select(container).selectAll('rect') + var traceToggle = g.selectAll('rect') .data([0]); traceToggle.enter().append('rect') @@ -402,11 +405,10 @@ function setupTraceToggle(gd, container, legendItem) { }); } -function computeTextDimensions(gd, container, legendItem) { - var opts = gd._fullLayout.legend, - g = d3.select(container), - bg = g.selectAll('.legendtoggle'), +function computeTextDimensions(g, gd, legendItem) { + var bg = g.selectAll('.legendtoggle'), mathjaxGroup = g.select('g[class*=math-group]'), + opts = gd._fullLayout.legend, lineHeight = opts.font.size * 1.3, height, width; From 7d502fa0527ba722cd9233936dcd7b467626564d Mon Sep 17 00:00:00 2001 From: Nicolas Riesco Date: Tue, 17 May 2016 13:16:08 +0100 Subject: [PATCH 13/19] Legend: Use Lib.setTranslate --- src/components/legend/draw.js | 49 +++++++++++++++-------------------- 1 file changed, 21 insertions(+), 28 deletions(-) diff --git a/src/components/legend/draw.js b/src/components/legend/draw.js index 23428860fe9..7d574ca714f 100644 --- a/src/components/legend/draw.js +++ b/src/components/legend/draw.js @@ -182,7 +182,7 @@ module.exports = function draw(gd) { // Set size and position of all the elements that make up a legend: // legend, background and border, scroll box and scroll bar - legend.attr('transform', 'translate(' + lx + ',' + ly + ')'); + Lib.setTranslate(legend, lx, ly); bg.attr({ width: opts.width - opts.borderwidth, @@ -193,7 +193,7 @@ module.exports = function draw(gd) { var scrollPosition = scrollBox.attr('data-scroll') || 0; - scrollBox.attr('transform', 'translate(0, ' + scrollPosition + ')'); + Lib.setTranslate(scrollBox, 0, scrollPosition); clipPath.select('rect').attr({ width: opts.width - 2 * opts.borderwidth, @@ -268,8 +268,10 @@ module.exports = function draw(gd) { function scrollHandler(scrollBarY, scrollBoxY) { - scrollBox.attr('data-scroll', scrollBoxY); - scrollBox.attr('transform', 'translate(0, ' + scrollBoxY + ')'); + scrollBox + .attr('data-scroll', scrollBoxY) + .call(Lib.setTranslate, 0, scrollBoxY); + scrollBar.call( Drawing.setRect, opts.width, @@ -299,8 +301,7 @@ module.exports = function draw(gd) { var newX = x0 + dx, newY = y0 + dy; - var transform = 'translate(' + newX + ', ' + newY + ')'; - legend.attr('transform', transform); + Lib.setTranslate(legend, newX, newY); xf = dragElement.align(newX, 0, gs.l, gs.l+gs.w, opts.xanchor); yf = dragElement.align(newY, 0, gs.t+gs.h, gs.t, opts.yanchor); @@ -424,7 +425,7 @@ function computeTextDimensions(g, gd, legendItem) { height = mathjaxBB.height; width = mathjaxBB.width; - mathjaxGroup.attr('transform','translate(0,' + (height / 4) + ')'); + Lib.setTranslate(mathjaxGroup, 0, (height / 4)); } else { var text = g.selectAll('.legendtext'), @@ -456,8 +457,8 @@ function computeLegendDimensions(gd, groups, traces) { if(helpers.isVertical(opts)) { if(helpers.isGrouped(opts)) { - groups.attr('transform', function(d, i) { - return 'translate(0,' + i * opts.tracegroupgap + ')'; + groups.each(function(d, i) { + Lib.setTranslate(this, 0, i * opts.tracegroupgap); }); } @@ -469,11 +470,9 @@ function computeLegendDimensions(gd, groups, traces) { textHeight = legendItem.height, textWidth = legendItem.width; - d3.select(this).attr('transform', - 'translate(' + borderwidth + ',' + - (5 + borderwidth + opts.height + textHeight / 2) + - ')' - ); + Lib.setTranslate(this, + borderwidth, + (5 + borderwidth + opts.height + textHeight / 2)); opts.height += textHeight; opts.width = Math.max(opts.width, textWidth); @@ -509,8 +508,8 @@ function computeLegendDimensions(gd, groups, traces) { groupXOffsets.push(opts.width); }); - groups.attr('transform', function(d, i) { - return 'translate(' + groupXOffsets[i] + ',0)'; + groups.each(function(d, i) { + Lib.setTranslate(this, groupXOffsets[i], 0); }); groups.each(function() { @@ -522,11 +521,9 @@ function computeLegendDimensions(gd, groups, traces) { var legendItem = d[0], textHeight = legendItem.height; - d3.select(this).attr('transform', - 'translate(0,' + - (5 + borderwidth + groupHeight + textHeight / 2) + - ')' - ); + Lib.setTranslate(this, + 0, + (5 + borderwidth + groupHeight + textHeight / 2)); groupHeight += textHeight; }); @@ -553,13 +550,9 @@ function computeLegendDimensions(gd, groups, traces) { traceWidth = 40 + legendItem.width, traceGap = opts.tracegroupgap || 5; - d3.select(this).attr('transform', - 'translate(' + - (borderwidth + opts.width) + - ',' + - (5 + borderwidth + legendItem.height / 2) + - ')' - ); + Lib.setTranslate(this, + (borderwidth + opts.width), + (5 + borderwidth + legendItem.height / 2)); opts.width += traceGap + traceWidth; opts.height = Math.max(opts.height, legendItem.height); From 107883a047b4b781f30bd53b67ccb20cd2718c1d Mon Sep 17 00:00:00 2001 From: Nicolas Riesco Date: Tue, 17 May 2016 13:41:06 +0100 Subject: [PATCH 14/19] Legend: replace .each() by a explicit loop --- src/components/legend/draw.js | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/components/legend/draw.js b/src/components/legend/draw.js index 7d574ca714f..25b55ac6895 100644 --- a/src/components/legend/draw.js +++ b/src/components/legend/draw.js @@ -453,10 +453,11 @@ function computeTextDimensions(g, gd, legendItem) { function computeLegendDimensions(gd, groups, traces) { var fullLayout = gd._fullLayout, opts = fullLayout.legend, - borderwidth = opts.borderwidth; + borderwidth = opts.borderwidth, + isGrouped = helpers.isGrouped(opts); if(helpers.isVertical(opts)) { - if(helpers.isGrouped(opts)) { + if(isGrouped) { groups.each(function(d, i) { Lib.setTranslate(this, 0, i * opts.tracegroupgap); }); @@ -481,7 +482,7 @@ function computeLegendDimensions(gd, groups, traces) { opts.width += 45 + borderwidth * 2; opts.height += 10 + borderwidth * 2; - if(helpers.isGrouped(opts)) { + if(isGrouped) { opts.height += (opts._lgroupsLength-1) * opts.tracegroupgap; } @@ -492,21 +493,24 @@ function computeLegendDimensions(gd, groups, traces) { opts.width = Math.ceil(opts.width); opts.height = Math.ceil(opts.height); } - else if(helpers.isGrouped(opts)) { + else if(isGrouped) { opts.width = 0; opts.height = 0; - var groupXOffsets = [opts.width]; - groups.each(function(d) { - var textWidths = d.map(function(legendItemArray) { + var groupXOffsets = [opts.width], + groupData = groups.data(); + + for(var i = 0, n = groupData.length; i < n; i++) { + var textWidths = groupData[i].map(function(legendItemArray) { return legendItemArray[0].width; }); var groupWidth = 40 + Math.max.apply(null, textWidths); + opts.width += opts.tracegroupgap + groupWidth; groupXOffsets.push(opts.width); - }); + } groups.each(function(d, i) { Lib.setTranslate(this, groupXOffsets[i], 0); From 65aa6c055e86ec1573c0f3100e1d4a308e500ebe Mon Sep 17 00:00:00 2001 From: Nicolas Riesco Date: Tue, 17 May 2016 13:45:10 +0100 Subject: [PATCH 15/19] Legend: Remove legendItem from function signatures * Removed legendItem from the function signatures of drawTexts, setupTraceToggle and computeTextDimensions. --- src/components/legend/draw.js | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/components/legend/draw.js b/src/components/legend/draw.js index 25b55ac6895..0b33f4f00c0 100644 --- a/src/components/legend/draw.js +++ b/src/components/legend/draw.js @@ -116,12 +116,10 @@ module.exports = function draw(gd) { return trace.visible === 'legendonly' ? 0.5 : 1; } }) - .each(function(d) { - var legendItem = d[0]; - + .each(function() { d3.select(this) - .call(drawTexts, gd, legendItem) - .call(setupTraceToggle, gd, legendItem); + .call(drawTexts, gd) + .call(setupTraceToggle, gd); }); if(gd.firstRender) { @@ -315,8 +313,9 @@ module.exports = function draw(gd) { } }; -function drawTexts(g, gd, legendItem) { - var fullLayout = gd._fullLayout, +function drawTexts(g, gd) { + var legendItem = g.data()[0][0], + fullLayout = gd._fullLayout, trace = legendItem.trace, isPie = Plots.traceIs(trace, 'pie'), traceIndex = trace.index, @@ -338,7 +337,7 @@ function drawTexts(g, gd, legendItem) { function textLayout(s) { Plotly.util.convertToTspans(s, function() { s.selectAll('tspan.line').attr({x: s.attr('x')}); - g.call(computeTextDimensions, gd, legendItem); + g.call(computeTextDimensions, gd); }); } @@ -356,7 +355,7 @@ function drawTexts(g, gd, legendItem) { else text.call(textLayout); } -function setupTraceToggle(g, gd, legendItem) { +function setupTraceToggle(g, gd) { var hiddenSlices = gd._fullLayout.hiddenlabels ? gd._fullLayout.hiddenlabels.slice() : []; @@ -373,7 +372,8 @@ function setupTraceToggle(g, gd, legendItem) { traceToggle.on('click', function() { if(gd._dragged) return; - var fullData = gd._fullData, + var legendItem = g.data()[0][0], + fullData = gd._fullData, trace = legendItem.trace, legendgroup = trace.legendgroup, traceIndicesInGroup = [], @@ -406,8 +406,9 @@ function setupTraceToggle(g, gd, legendItem) { }); } -function computeTextDimensions(g, gd, legendItem) { - var bg = g.selectAll('.legendtoggle'), +function computeTextDimensions(g, gd) { + var legendItem = g.data()[0][0], + bg = g.selectAll('.legendtoggle'), mathjaxGroup = g.select('g[class*=math-group]'), opts = gd._fullLayout.legend, lineHeight = opts.font.size * 1.3, From 8c6d47a0011e3446ac7edd68531dd75d6dc2ecfd Mon Sep 17 00:00:00 2001 From: Nicolas Riesco Date: Tue, 17 May 2016 15:20:44 +0100 Subject: [PATCH 16/19] Legend: set default position of horizontal legends * Position horizontal legends on the bottom left, unless a range slider is present. * If a range slider is present, position the horizontal legend on the top left. --- src/components/legend/defaults.js | 30 +++++++++++++++++---- test/image/baselines/legend_horizontal.png | Bin 23341 -> 23653 bytes test/image/mocks/legend_horizontal.json | 6 +---- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/components/legend/defaults.js b/src/components/legend/defaults.js index 605e66d234e..aa6e8794ca5 100644 --- a/src/components/legend/defaults.js +++ b/src/components/legend/defaults.js @@ -21,7 +21,11 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) { containerOut = layoutOut.legend = {}; var visibleTraces = 0, - defaultOrder = 'normal'; + defaultOrder = 'normal', + defaultX, + defaultY, + defaultXAnchor, + defaultYAnchor; for(var i = 0; i < fullData.length; i++) { var trace = fullData[i]; @@ -57,14 +61,30 @@ module.exports = function legendDefaults(layoutIn, layoutOut, fullData) { coerce('bordercolor'); coerce('borderwidth'); Lib.coerceFont(coerce, 'font', layoutOut.font); + coerce('orientation'); + if(containerOut.orientation === 'h') { + var xaxis = layoutIn.xaxis; + if(xaxis && xaxis.rangeslider && xaxis.rangeslider.visible) { + defaultX = 0; + defaultXAnchor = 'left'; + defaultY = 1.1; + defaultYAnchor = 'bottom'; + } + else { + defaultX = 0; + defaultXAnchor = 'left'; + defaultY = -0.1; + defaultYAnchor = 'top'; + } + } coerce('traceorder', defaultOrder); if(helpers.isGrouped(layoutOut.legend)) coerce('tracegroupgap'); - coerce('x'); - coerce('xanchor'); - coerce('y'); - coerce('yanchor'); + coerce('x', defaultX); + coerce('xanchor', defaultXAnchor); + coerce('y', defaultY); + coerce('yanchor', defaultYAnchor); Lib.noneOrAll(containerIn, containerOut, ['x', 'y']); }; diff --git a/test/image/baselines/legend_horizontal.png b/test/image/baselines/legend_horizontal.png index 878dc8b001886e2b2d204ee88bf167cb411c5909..180d1b3b61e59d9966998006553df5f4f53136b1 100644 GIT binary patch literal 23653 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

W4*wyV7Ru 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 Xn?v=mYHApu4;QjBKV(+8&;823Z^IYC literal 23341 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 Date: Tue, 17 May 2016 16:06:40 +0100 Subject: [PATCH 17/19] Legend: ensure all the legends sides are visible --- src/components/legend/draw.js | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/src/components/legend/draw.js b/src/components/legend/draw.js index 0b33f4f00c0..310b81c0ebe 100644 --- a/src/components/legend/draw.js +++ b/src/components/legend/draw.js @@ -128,7 +128,9 @@ module.exports = function draw(gd) { } // Position and size the legend - var lyMin = 0, + var lxMin = 0, + lxMax = fullLayout.width, + lyMin = 0, lyMax = fullLayout.height; computeLegendDimensions(gd, groups, traces); @@ -162,6 +164,20 @@ module.exports = function draw(gd) { ly -= opts.height / 2; } + // Make sure the legend left and right sides are visible + var legendWidth = opts.width, + legendWidthMax = gs.w; + + if(legendWidth > legendWidthMax) { + lx = gs.l; + legendWidth = legendWidthMax; + } + else { + if(lx + legendWidth > lxMax) lx = lxMax - legendWidth; + if(lx < lxMin) lx = lxMin; + legendWidth = Math.min(lxMax - lx, opts.width); + } + // Make sure the legend top and bottom are visible // (legends with a scroll bar are not allowed to stretch beyond the extended // margins) @@ -173,7 +189,7 @@ module.exports = function draw(gd) { legendHeight = legendHeightMax; } else { - if(ly > lyMax) ly = lyMax - legendHeight; + if(ly + legendHeight > lyMax) ly = lyMax - legendHeight; if(ly < lyMin) ly = lyMin; legendHeight = Math.min(lyMax - ly, opts.height); } @@ -183,7 +199,7 @@ module.exports = function draw(gd) { Lib.setTranslate(legend, lx, ly); bg.attr({ - width: opts.width - opts.borderwidth, + width: legendWidth - opts.borderwidth, height: legendHeight - opts.borderwidth, x: opts.borderwidth / 2, y: opts.borderwidth / 2 @@ -194,7 +210,7 @@ module.exports = function draw(gd) { Lib.setTranslate(scrollBox, 0, scrollPosition); clipPath.select('rect').attr({ - width: opts.width - 2 * opts.borderwidth, + width: legendWidth - 2 * opts.borderwidth, height: legendHeight - 2 * opts.borderwidth, x: opts.borderwidth - scrollPosition, y: opts.borderwidth @@ -208,14 +224,14 @@ module.exports = function draw(gd) { // increase the background and clip-path width // by the scrollbar width and margin bg.attr({ - width: opts.width - + width: legendWidth - 2 * opts.borderwidth + constants.scrollBarWidth + constants.scrollBarMargin }); clipPath.select('rect').attr({ - width: opts.width - + width: legendWidth - 2 * opts.borderwidth + constants.scrollBarWidth + constants.scrollBarMargin @@ -272,7 +288,7 @@ module.exports = function draw(gd) { scrollBar.call( Drawing.setRect, - opts.width, + legendWidth, scrollBarY, constants.scrollBarWidth, constants.scrollBarHeight From c1632d40e71f7305e6d0cc5acb918838aa975606 Mon Sep 17 00:00:00 2001 From: Nicolas Riesco Date: Tue, 17 May 2016 16:50:48 +0100 Subject: [PATCH 18/19] Legend: update baseline of legend_horizontal.json --- test/image/baselines/legend_horizontal.png | Bin 23653 -> 23548 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/test/image/baselines/legend_horizontal.png b/test/image/baselines/legend_horizontal.png index 180d1b3b61e59d9966998006553df5f4f53136b1..a218a2bc4f4818415df1fcf46db0b717723c927c 100644 GIT binary patch literal 23548 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 literal 23653 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

W4*wyV7Ru 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 Xn?v=mYHApu4;QjBKV(+8&;823Z^IYC From 313976dafa07e226258e434cfa4a42048af7eedb Mon Sep 17 00:00:00 2001 From: Nicolas Riesco Date: Tue, 17 May 2016 17:34:17 +0100 Subject: [PATCH 19/19] Legend: test defaults for horizontal legends --- test/jasmine/tests/legend_test.js | 41 +++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/test/jasmine/tests/legend_test.js b/test/jasmine/tests/legend_test.js index 34ef1e618a2..21a35794ec9 100644 --- a/test/jasmine/tests/legend_test.js +++ b/test/jasmine/tests/legend_test.js @@ -1,4 +1,5 @@ var Plots = require('@src/plots/plots'); +var Lib = require('@src/lib'); var Legend = require('@src/components/legend'); var getLegendData = require('@src/components/legend/get_legend_data'); @@ -65,6 +66,46 @@ describe('Test legend:', function() { expect(layoutOut.legend.traceorder).toEqual('grouped+reversed'); }); + it('should default orientation to vertical', function() { + supplyLayoutDefaults(layoutIn, layoutOut, []); + expect(layoutOut.legend.orientation).toEqual('v'); + }); + + describe('for horizontal legends', function() { + var layoutInForHorizontalLegends; + + beforeEach(function() { + layoutInForHorizontalLegends = Lib.extendDeep({ + legend: { + orientation: 'h' + }, + xaxis: { + rangeslider: { + visible: false + } + } + }, layoutIn); + }); + + it('should default position to bottom left', function() { + supplyLayoutDefaults(layoutInForHorizontalLegends, layoutOut, []); + expect(layoutOut.legend.x).toEqual(0); + expect(layoutOut.legend.xanchor).toEqual('left'); + expect(layoutOut.legend.y).toEqual(-0.1); + expect(layoutOut.legend.yanchor).toEqual('top'); + }); + + it('should default position to top left if a range slider present', function() { + var mockLayoutIn = Lib.extendDeep({}, layoutInForHorizontalLegends); + mockLayoutIn.xaxis.rangeslider.visible = true; + + supplyLayoutDefaults(mockLayoutIn, layoutOut, []); + expect(layoutOut.legend.x).toEqual(0); + expect(layoutOut.legend.xanchor).toEqual('left'); + expect(layoutOut.legend.y).toEqual(1.1); + expect(layoutOut.legend.yanchor).toEqual('bottom'); + }); + }); }); describe('getLegendData', function() {