From 1cbc150248e45a46ae5f88e17d98501c425463ba Mon Sep 17 00:00:00 2001 From: nxanil Date: Thu, 7 Jan 2021 15:08:11 +0530 Subject: [PATCH 1/7] [Feature]: Heatmap & AreaGraph Legends --- Graphs/AbstractGraph.js | 47 ++++++++++++------- Graphs/AreaGraph/index.js | 4 +- .../Components/utils/Legend/StandardLegend.js | 25 ++++++++-- Graphs/Components/utils/Legend/index.js | 5 +- Graphs/HeatmapGraph/index.js | 12 +++-- 5 files changed, 64 insertions(+), 29 deletions(-) diff --git a/Graphs/AbstractGraph.js b/Graphs/AbstractGraph.js index 9cb77e3c..dc4d2ff2 100644 --- a/Graphs/AbstractGraph.js +++ b/Graphs/AbstractGraph.js @@ -339,11 +339,11 @@ export default class AbstractGraph extends React.Component { return this.yLabelWidth; } - setDimensions(props, data = null, column = null, label = null, legendData = null) { + setDimensions(props, data = null, column = null, label = null, legendData = null, heatmapColor = {}) { const { graphWidth, graphHeight - } = this.getGraphDimension(label, legendData); + } = this.getGraphDimension(label, legendData, heatmapColor); this.setYlabelWidth(data ? data : props.data, column); this.setLeftMargin(); @@ -483,7 +483,7 @@ export default class AbstractGraph extends React.Component { return null; } - getGraphDimension = (label, filterData = null) => { + getGraphDimension = (label, filterData = null, heatmapColor) => { const { height, width, @@ -521,13 +521,13 @@ export default class AbstractGraph extends React.Component { } else { const lineHeight = this.getLegendLineHeight(legend); const legendData = filterData || data.filter((e, i) => data.findIndex(a => label(a) === label(e)) === i); - const legendCount = legendData.length; - const value = this.getLegendArea(filterData || data, label, { lineHeight, legendCount }); + const legendCount = heatmapColor ? Object.keys(heatmapColor).length : legendData.length; + const value = this.getLegendArea(filterData || data, label, { lineHeight, legendCount, legendWidth: width }); dimensions = { ...dimensions, graphHeight: height - value - margin.top, legendHeight: value + margin.top, - legendWidth: width, + legendWidth: this.getAvailableWidth(), labelWidth: labelTextWidth, } } @@ -547,19 +547,26 @@ export default class AbstractGraph extends React.Component { return legend.circleSize * circleToPixel; } - renderLegend(data, legend, getColor, label, isVertical) { + renderLegend(data, legend, getColor, label, isVertical, heatmapColor) { if (!legend.show) return; // Getting unique labels data = data.filter((e, i) => data.findIndex(a => label(a) === label(e)) === i); + const dataKey = data.map(element => element.key); + for (const key in heatmapColor) { + if (!dataKey.includes(key)) { + data.push({ key, values: [] }); + } + } + const { legendHeight, legendWidth, - } = this.getGraphDimension(label, data); + } = this.getGraphDimension(label, data, heatmapColor); const legendContainerStyle = { - marginLeft: '5px', + marginLeft: this.props.width - legendWidth, marginTop: '5px', width: legendWidth, height: legendHeight, @@ -572,31 +579,33 @@ export default class AbstractGraph extends React.Component { // Place the legends in the bottom left corner legendStyle = { ...legendStyle, alignSelf: 'flex-end', height: legendHeight } } else { - // Place legends horizontally, Maximum 3 legend 1 row + // Place legends horizontally, 20 is margin between legends + const highestLabel = this.getLongestLabel(data, label); + legendStyle = { ...legendStyle, - display: 'grid', - gridTemplateColumns: `repeat(auto-fit, minmax(${legendWidth / 3 - 5}px, 1fr))`, + display: 'grid', + gridTemplateColumns: `repeat(auto-fit, minmax(${highestLabel + 20}px, 1fr))`, } } return (
- {this.getLegendContent(data, legend, getColor, label)} + {this.getLegendContent(data, legend, getColor, label, heatmapColor)}
); } - getLegendContent(data, legend, getColor, label) { + getLegendContent(data, legend, getColor, label, heatmapColor) { const { fontColor } = this.getConfiguredProperties(); const { labelWidth - } = this.getGraphDimension(label, data); + } = this.getGraphDimension(label, data, heatmapColor); const lineHeight = this.getLegendLineHeight(legend); @@ -682,9 +691,11 @@ export default class AbstractGraph extends React.Component { const highestLabel = this.getLongestLabel(data, label); if (legend) { - const { legendCount, lineHeight } = legend; - //Maximum 3 legend 1 row - const legendRow = Math.ceil(legendCount / 3); + const { legendCount, lineHeight, legendWidth } = legend; + //Caluting legendContainer height, 20 is margin between margin label. + let legendRow = Math.ceil(legendWidth / (highestLabel + 20)); + legendRow = Math.ceil(legendRow / legendCount) + return legendRow * lineHeight; } diff --git a/Graphs/AreaGraph/index.js b/Graphs/AreaGraph/index.js index 300b74bb..494f9713 100644 --- a/Graphs/AreaGraph/index.js +++ b/Graphs/AreaGraph/index.js @@ -121,7 +121,9 @@ const AreaGraph = (props) => { renderLegend({ legend, height, - customLegendLabel + customLegendLabel, + margin, + containerWidth: width }) } { diff --git a/Graphs/Components/utils/Legend/StandardLegend.js b/Graphs/Components/utils/Legend/StandardLegend.js index 4cd203a1..460954ff 100644 --- a/Graphs/Components/utils/Legend/StandardLegend.js +++ b/Graphs/Components/utils/Legend/StandardLegend.js @@ -1,5 +1,7 @@ import React from 'react'; import { styled } from '@material-ui/core/styles'; +import * as d3 from "d3"; +import max from 'lodash/max'; const Container = styled('div')({ display: 'flex', @@ -12,11 +14,20 @@ const Container = styled('div')({ const Item = styled('div')({ color: ({ color } = {}) => color, - flexBasis: '50%', + flexBasis: ({ legendWidth }) => legendWidth, padding: '0.15rem 0', }); -export default ({ payload: legends, labelColumn, legend, customLegendLabel }) => { +const labelSize = (label, LabelFont = '0.6rem') => { + const container = d3.select('body').append('svg'); + container.append('text').text(label).style("font-size", LabelFont); + const dimension = container.node().getBBox(); + container.remove(); + + return dimension.width + 30; +} + +export default ({ payload: legends, labelColumn, legend, customLegendLabel, containerWidth }) => { if (legends && legends[0].value === undefined) { return false; } @@ -35,11 +46,19 @@ export default ({ payload: legends, labelColumn, legend, customLegendLabel }) => }); } + const legendWidth = containerWidth ? `${highestLabel/containerWidth * 100}%` : '50%'; + + const highestLabel = max(legends.map( ({payload, value}) => { + const label = labelColumn ? payload[labelColumn] : value; + + return labelSize(label); + })); + return ( { legends.map(({ color, payload, value, props: { fill, name: { xVal } = {} } = {} }, index) => ( - + diff --git a/Graphs/Components/utils/Legend/index.js b/Graphs/Components/utils/Legend/index.js index 4bac5faa..c3fb6072 100644 --- a/Graphs/Components/utils/Legend/index.js +++ b/Graphs/Components/utils/Legend/index.js @@ -7,13 +7,14 @@ import { LEGEND_SEPARATE } from '../../../../constants'; import * as customLegends from './export'; import StandardLegend from './StandardLegend'; -export default ({ legend, height, type, ...rest }) => { +export default ({ legend, height, type, margin, ...rest }) => { let Component = type ? customLegends[type] || StandardLegend : StandardLegend; const legendHeight = legend.separate ? (legend.separate * height) / 100 : (LEGEND_SEPARATE * height) / 100; + const marginLeft = margin ? margin.left : 0; if (legend && legend.show) { return ( ( )} diff --git a/Graphs/HeatmapGraph/index.js b/Graphs/HeatmapGraph/index.js index c357e5ed..81eefe36 100644 --- a/Graphs/HeatmapGraph/index.js +++ b/Graphs/HeatmapGraph/index.js @@ -61,14 +61,15 @@ class HeatmapGraph extends XYGraph { } = props const { - yColumn + yColumn, + heatmapColor, } = this.getConfiguredProperties() if (!data || !data.length) return this.parseData(props) - this.setDimensions(props, this.getFilterData(), yColumn, (d) => d["key"], this.getCellColumnData()) + this.setDimensions(props, this.getFilterData(), yColumn, (d) => d["key"], this.getCellColumnData(), heatmapColor) this.configureAxis({ data: this.getFilterData() }) @@ -574,13 +575,14 @@ class HeatmapGraph extends XYGraph { const { margin, - legend + legend, + heatmapColor } = this.getConfiguredProperties(); const { graphHeight, graphWidth, - } = this.getGraphDimension(this.getLegendFn()); + } = this.getGraphDimension(this.getLegendFn(), null, heatmapColor); const graphStyle = { width: graphWidth, @@ -595,7 +597,7 @@ class HeatmapGraph extends XYGraph {
{this.tooltip}
- {this.renderLegend(this.getCellColumnData(), legend, this.getColor(), (d) => d["key"], this.checkIsVerticalLegend())} + {this.renderLegend(this.getCellColumnData(), legend, this.getColor(), (d) => d["key"], this.checkIsVerticalLegend(), heatmapColor)}
this.node = node}> From b785d5c60c273937bae0c8637310d26b97ed7cda Mon Sep 17 00:00:00 2001 From: nxanil Date: Thu, 7 Jan 2021 15:46:10 +0530 Subject: [PATCH 2/7] [Fix]: issue --- Graphs/Components/utils/Legend/StandardLegend.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Graphs/Components/utils/Legend/StandardLegend.js b/Graphs/Components/utils/Legend/StandardLegend.js index 460954ff..4ae3fd79 100644 --- a/Graphs/Components/utils/Legend/StandardLegend.js +++ b/Graphs/Components/utils/Legend/StandardLegend.js @@ -46,14 +46,14 @@ export default ({ payload: legends, labelColumn, legend, customLegendLabel, cont }); } - const legendWidth = containerWidth ? `${highestLabel/containerWidth * 100}%` : '50%'; - const highestLabel = max(legends.map( ({payload, value}) => { const label = labelColumn ? payload[labelColumn] : value; return labelSize(label); })); + const legendWidth = containerWidth ? `${highestLabel/containerWidth * 100}%` : '50%'; + return ( { From 216e86ac23ec978b8c67001510f36b87b7a5561d Mon Sep 17 00:00:00 2001 From: nxanil Date: Thu, 7 Jan 2021 16:59:24 +0530 Subject: [PATCH 3/7] [Fix]: Heatmap legends --- Graphs/AbstractGraph.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Graphs/AbstractGraph.js b/Graphs/AbstractGraph.js index dc4d2ff2..62d42fd0 100644 --- a/Graphs/AbstractGraph.js +++ b/Graphs/AbstractGraph.js @@ -585,7 +585,7 @@ export default class AbstractGraph extends React.Component { legendStyle = { ...legendStyle, display: 'grid', - gridTemplateColumns: `repeat(auto-fit, minmax(${highestLabel + 20}px, 1fr))`, + gridTemplateColumns: `repeat(auto-fit, ${highestLabel+20}px)`, } } @@ -693,7 +693,7 @@ export default class AbstractGraph extends React.Component { if (legend) { const { legendCount, lineHeight, legendWidth } = legend; //Caluting legendContainer height, 20 is margin between margin label. - let legendRow = Math.ceil(legendWidth / (highestLabel + 20)); + let legendRow = Math.ceil((highestLabel + 20) / legendWidth); legendRow = Math.ceil(legendRow / legendCount) return legendRow * lineHeight; From c8e05bc5481fa48eadb592822c43a369089c361e Mon Sep 17 00:00:00 2001 From: nxanil Date: Thu, 7 Jan 2021 17:16:18 +0530 Subject: [PATCH 4/7] [Fix]: Heatmap legends --- Graphs/AbstractGraph.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Graphs/AbstractGraph.js b/Graphs/AbstractGraph.js index 62d42fd0..f9cffc02 100644 --- a/Graphs/AbstractGraph.js +++ b/Graphs/AbstractGraph.js @@ -693,8 +693,8 @@ export default class AbstractGraph extends React.Component { if (legend) { const { legendCount, lineHeight, legendWidth } = legend; //Caluting legendContainer height, 20 is margin between margin label. - let legendRow = Math.ceil((highestLabel + 20) / legendWidth); - legendRow = Math.ceil(legendRow / legendCount) + let legendRow = Math.ceil( legendCount * (highestLabel + 20) ); + legendRow = Math.ceil(legendRow / legendWidth) return legendRow * lineHeight; } From 0916a413eef5ed95b77e5d78f15881844413ca50 Mon Sep 17 00:00:00 2001 From: nxanil Date: Fri, 8 Jan 2021 12:00:50 +0530 Subject: [PATCH 5/7] [Update]: changes heatmap color --- Graphs/HeatmapGraph/index.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Graphs/HeatmapGraph/index.js b/Graphs/HeatmapGraph/index.js index 81eefe36..15975104 100644 --- a/Graphs/HeatmapGraph/index.js +++ b/Graphs/HeatmapGraph/index.js @@ -365,7 +365,8 @@ class HeatmapGraph extends XYGraph { colorColumn, colors, legendColumn, - emptyBoxColor + emptyBoxColor, + heatmapColor, } = this.getConfiguredProperties() const colorScale = this.getMappedScaleColor(this.getFilterData(), legendColumn) @@ -383,6 +384,9 @@ class HeatmapGraph extends XYGraph { if (value === 'Empty') { return emptyBoxColor } + if (heatmapColor.hasOwnProperty(value)) { + return heatmapColor[value] + } return colorScale ? colorScale(value) : stroke.color || colors[0] } From 3154e95c968a15d4eb18d2e40a1dc3a15fbc32d6 Mon Sep 17 00:00:00 2001 From: nxanil Date: Mon, 11 Jan 2021 18:57:09 +0530 Subject: [PATCH 6/7] [Done]: Feedback changes regarding heatmap --- Graphs/AbstractGraph.js | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Graphs/AbstractGraph.js b/Graphs/AbstractGraph.js index f9cffc02..3cf64630 100644 --- a/Graphs/AbstractGraph.js +++ b/Graphs/AbstractGraph.js @@ -553,17 +553,20 @@ export default class AbstractGraph extends React.Component { // Getting unique labels data = data.filter((e, i) => data.findIndex(a => label(a) === label(e)) === i); - const dataKey = data.map(element => element.key); + const legendData = []; for (const key in heatmapColor) { - if (!dataKey.includes(key)) { - data.push({ key, values: [] }); + const filterData = data.filter(element => element.key === key); + if (!!filterData.length && filterData[0].key === key) { + legendData.push(filterData[0]); + } else { + legendData.push({ key, values: [] }); } } const { legendHeight, legendWidth, - } = this.getGraphDimension(label, data, heatmapColor); + } = this.getGraphDimension(label, legendData, heatmapColor); const legendContainerStyle = { marginLeft: this.props.width - legendWidth, @@ -580,8 +583,7 @@ export default class AbstractGraph extends React.Component { legendStyle = { ...legendStyle, alignSelf: 'flex-end', height: legendHeight } } else { // Place legends horizontally, 20 is margin between legends - const highestLabel = this.getLongestLabel(data, label); - + const highestLabel = this.getLongestLabel(legendData, label); legendStyle = { ...legendStyle, display: 'grid', @@ -592,7 +594,7 @@ export default class AbstractGraph extends React.Component { return (
- {this.getLegendContent(data, legend, getColor, label, heatmapColor)} + {this.getLegendContent(legendData, legend, getColor, label, heatmapColor)}
); From b96d47bfa6bc038e4b61ab044e409cee4ae1a0a1 Mon Sep 17 00:00:00 2001 From: nxanil Date: Tue, 12 Jan 2021 09:48:16 +0530 Subject: [PATCH 7/7] [Fix]: add heatmapColor {} --- Graphs/AbstractGraph.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Graphs/AbstractGraph.js b/Graphs/AbstractGraph.js index 3cf64630..991fff5d 100644 --- a/Graphs/AbstractGraph.js +++ b/Graphs/AbstractGraph.js @@ -483,7 +483,7 @@ export default class AbstractGraph extends React.Component { return null; } - getGraphDimension = (label, filterData = null, heatmapColor) => { + getGraphDimension = (label, filterData = null, heatmapColor = {}) => { const { height, width, @@ -547,7 +547,7 @@ export default class AbstractGraph extends React.Component { return legend.circleSize * circleToPixel; } - renderLegend(data, legend, getColor, label, isVertical, heatmapColor) { + renderLegend(data, legend, getColor, label, isVertical, heatmapColor = {}) { if (!legend.show) return;