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

Moving graph controls within the legend component

parent 0ec4f53a
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.
......@@ -29,7 +29,6 @@ import {getPreferredIVMethodID} from './selectors/time-series-data';
import {showDataIndicators} from './data-indicator';
import {drawTimeSeriesLegend} from './legend';
import {initializeTimeSeriesGraph, drawTimeSeriesGraphData} from './time-series-graph';
......@@ -156,21 +155,20 @@ export const attachToNode = function(store,
mapStateToPropsFactory: createStructuredSelector
});
hydrographApp.provide('store', store);
hydrographApp.provide('siteno', siteno);
hydrographApp.provide('initialLoadingComplete', initialLoadingComplete);
hydrographApp.mount('#hydrograph-brush-container');
}
const legendControlsContainer = graphContainer.append('div')
.classed('ts-legend-controls-container', true);
if (!showOnlyGraph) {
const graphControlsApp = createApp(GraphControlsApp, {});
graphControlsApp.use(ReduxConnectVue, {
store,
mapDispatchToPropsFactory: (actionCreators) => (dispatch) => bindActionCreators(actionCreators, dispatch),
mapStateToPropsFactory: createStructuredSelector
});
graphControlsApp.provide('store', store);
graphControlsApp.provide('siteno', siteno);
graphControlsApp.mount('.ts-legend-controls-container');
// const graphControlsApp = createApp(GraphControlsApp, {});
// graphControlsApp.use(ReduxConnectVue, {
// store,
// mapDispatchToPropsFactory: (actionCreators) => (dispatch) => bindActionCreators(actionCreators, dispatch),
// mapStateToPropsFactory: createStructuredSelector
// });
// graphControlsApp.provide('store', store);
// graphControlsApp.provide('siteno', siteno);
// graphControlsApp.mount('.ts-legend-controls-container');
const parameterSelectionApp = createApp(ParameterSelectionApp, {});
parameterSelectionApp.use(ReduxConnectVue, {
......@@ -195,8 +193,6 @@ export const attachToNode = function(store,
showDataIndicators(false, store);
graphContainer.call(drawTimeSeriesGraphData, store, !thisShowOnlyGraph);
legendControlsContainer.call(drawTimeSeriesLegend, store);
if (!thisShowOnlyGraph) {
// eslint-disable-next-line vue/one-component-per-file
const dataTablesApp = createApp(DataTablesApp, {});
......
<template>
<div class="hydrograph-container">
<svg
<div class="ts-legend-controls-container">
<div class="hydrograph-container">
<svg
v-if="legendMarkerRows.length"
class="legend-svg"
:viewBox="svgViewBox"
>
<g
ref="legend"
class="legend"
:transform="legendTransform"
>
</g>
/>
</svg>
</div>
<div class="graph-controls-container">
<GraphControls />
</div>
</div>
</template>
<script>
import {useActions, useState} from 'redux-connect-vue';
import {computed, inject, ref, watchEffect} from 'vue';
import {createStructuredSelector} from 'reselect';
import GraphControls from './graph-controls.vue';
import {drawSimpleLegend} from 'd3render/legend';
import {useState} from 'redux-connect-vue';
import {computed, ref, watchEffect} from 'vue';
import {select} from 'd3-selection';
import {getMainLayout} from './selectors/layout';
import {getLegendMarkerRows} from './selectors/legend-data';
import {getMainLayout} from '../selectors/layout';
import {getLegendMarkerRows} from '../selectors/legend-data';
import {mediaQuery} from 'ui/utils';
import config from 'ui/config';
export default {
name: 'Legend',
components: {
GraphControls
},
setup() {
const legend = ref(null);
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;
let yPosition = VERTICAL_ROW_OFFSET;
const state = useState({
legendMarkerRows: getLegendMarkerRows,
layout: getMainLayout
});
// Set the size of the containing svg node to the size of the legend.
const bBox = computed(() => {
try {
return select(legend.value).node().getBBox();
} catch (error) {
return null;
}
})
const legendTransform = computed(() => {
return `translate(${mediaQuery(config.USWDS_MEDIUM_SCREEN) ? layout.margin.left : 0}, 0)`
return `translate(${mediaQuery(config.USWDS_MEDIUM_SCREEN) ? state.layout.value.margin.left : 0}, 0)`;
});
const svgViewBox = computed(() => {
if (bBox.value) {
return `0 0 ${state.layout.value.width} ${bBox.value.height + 10}`;
}
return ''
});
watchEffect(() => {
state.legendMarkerRows.value.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 > state.layout.value.width && legend.value) {
// 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.value, markerArgs);
xPosition = getNewXPosition(markerGroup, xPosition);
}
};
rowMarkers.forEach((marker) => {
if (legend.value) {
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(select(legend.value), markerArgs);
xPosition = getNewXPosition(markerGroup, xPosition);
}
});
repositionLastMarkerWhenNeeded();
//start new row
yPosition = yPosition = yPosition + VERTICAL_ROW_OFFSET;
});
});
return {
...state,
legendTransform
}
legendTransform,
svgViewBox,
legend
};
}
}
</script>
<style>
</style>
\ No newline at end of file
</script>
\ No newline at end of file
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