Skip to content
Snippets Groups Projects
Commit 846e42e7 authored by Williams, Darius Shamar's avatar Williams, Darius Shamar
Browse files

Merge branch 'wdfn-768' of code.usgs.gov:dswilliams/waterdataui into wdfn-768

parents 827a59c7 d2a6626b
No related branches found
No related tags found
1 merge request!421Wdfn 768 - Convert the legend component to vue
This commit is part of merge request !421. Comments created here will be created in the context of that merge request.
import config from 'ui/config';
import {mediaQuery} from 'ui/utils';
const RECTANGLE_MARKER_WIDTH = 20;
const RECTANGLE_MARKER_HEIGHT = 10;
const LINE_MARKER_WIDTH = 20;
const MARKER_GROUP_X_OFFSET = 15;
const VERTICAL_ROW_OFFSET = 18;
/**
* Create a simple legend
*
* @param {Object} div - d3 selector where legend should be created
* @param {Object} legendMarkerRows - Array of rows. Each row should be an array of legend markers.
* @param {Object} layout - width and height of svg.
*/
export const drawSimpleLegend = function(div, {legendMarkerRows, layout}) {
div.selectAll('.legend-svg').remove();
const svg = div.append('svg')
.attr('class', 'legend-svg');
if (!legendMarkerRows.length || !layout) {
return;
}
const legend = svg
.append('g')
.attr('class', 'legend')
.attr('transform', `translate(${mediaQuery(config.USWDS_MEDIUM_SCREEN) ? layout.margin.left : 0}, 0)`);
let yPosition = VERTICAL_ROW_OFFSET;
legendMarkerRows.forEach((rowMarkers) => {
let xPosition = 0;
let markerArgs;
let markerGroup;
let lastMarker;
const getNewXPosition = function(markerGroup, lastXPosition) {
// Long story short, firefox is unable to get the bounding box if
// the svg element isn't actually taking up space and visible. Folks on the
// internet seem to have gotten around this by setting `visibility:hidden`
// to hide things, but that would still mean the elements will take up space.
// which we don't want. So, here's some error handling for getBBox failures.
// This handling ends up not creating the legend, but that's okay because the
// graph is being shown anyway. A more detailed discussion of this can be found at:
// https://bugzilla.mozilla.org/show_bug.cgi?id=612118 and
// https://stackoverflow.com/questions/28282295/getbbox-of-svg-when-hidden.
try {
const markerGroupBBox = markerGroup.node().getBBox();
return markerGroupBBox.x + markerGroupBBox.width + MARKER_GROUP_X_OFFSET;
} catch (error) {
// See above explanation
return lastXPosition;
}
};
const repositionLastMarkerWhenNeeded = function() {
if (xPosition - MARKER_GROUP_X_OFFSET > layout.width) {
// Need to remove the last marker and draw it on the next row.
markerGroup.remove();
xPosition = 0;
yPosition = yPosition + VERTICAL_ROW_OFFSET;
markerArgs.x = xPosition;
markerArgs.y = yPosition;
markerGroup = lastMarker.type(legend, markerArgs);
xPosition = getNewXPosition(markerGroup, xPosition);
}
};
rowMarkers.forEach((marker) => {
repositionLastMarkerWhenNeeded();
markerArgs = {
x: xPosition,
y: yPosition,
text: marker.text,
domId: marker.domId,
domClass: marker.domClass,
width: RECTANGLE_MARKER_WIDTH,
height: RECTANGLE_MARKER_HEIGHT,
length: LINE_MARKER_WIDTH,
r: marker.radius,
fill: marker.fill
};
lastMarker = marker;
markerGroup = marker.type(legend, markerArgs);
xPosition = getNewXPosition(markerGroup, xPosition);
});
repositionLastMarkerWhenNeeded();
//start new reow
yPosition = yPosition = yPosition + VERTICAL_ROW_OFFSET;
});
// Set the size of the containing svg node to the size of the legend.
let bBox;
try {
bBox = legend.node().getBBox();
} catch (error) {
return;
}
svg.attr('viewBox', `0 0 ${layout.width} ${bBox.height + 10}`);
};
\ No newline at end of file
import {select} from 'd3-selection';
import * as utils from 'ui/utils';
import {drawSimpleLegend} from './legend';
import {circleMarker, lineMarker, rectangleMarker, textOnlyMarker} from './markers';
describe('Legend module', () => {
utils.mediaQuery = jest.fn().mockReturnValue(true);
describe('drawSimpleLegend', () => {
let container;
const legendMarkerRows = [
[{
type: lineMarker,
length: 20,
domId: 'some-id',
domClass: 'some-class',
text: 'Some Text'
}, {
type: rectangleMarker,
domId: 'some-rectangle-id',
domClass: 'some-rectangle-class',
text: 'Rectangle Marker'
}],
[{
type: textOnlyMarker,
domId: 'text-id',
domClass: 'text-class',
text: 'Label'
}, {
type: lineMarker,
domId: null,
domClass: 'some-other-class',
text: 'Median Label'
}, {
type: circleMarker,
domId: null,
domClass: 'circle-marker-class',
text: 'Circle Marker label',
radius: 5
}]
];
const layout = {
width: 100,
height: 100,
margin: {
top: 0,
right: 0,
bottom: 0,
left: 0
}
};
beforeEach(() => {
container = select('body').append('div');
});
afterEach(() => {
container.remove();
});
it('If no markers are provided legend-svg will contain no groups', () => {
drawSimpleLegend(container, {
legendMarkerRows: [],
layout: layout
});
expect(container.select('svg g').size()).toBe(0);
});
it('Adds a legend when width is provided', () => {
drawSimpleLegend(container, {legendMarkerRows, layout});
expect(container.select('svg').size()).toBe(1);
expect(container.selectAll('line').size()).toBe(2);
expect(container.selectAll('rect').size()).toBe(1);
expect(container.selectAll('text').size()).toBe(5);
expect(container.selectAll('circle').size()).toBe(1);
});
});
});
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment