This is an automated email from the ASF dual-hosted git repository.
sumitagrawal pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ozone.git
The following commit(s) were added to refs/heads/master by this push:
new 6846a8c6db HDDS-8837. [Recon] Heatmap UI improvements (#5090)
6846a8c6db is described below
commit 6846a8c6db932fe36a1ca948654e0948cb9deac9
Author: Abhishek Pal <[email protected]>
AuthorDate: Fri Aug 4 07:42:00 2023 +0530
HDDS-8837. [Recon] Heatmap UI improvements (#5090)
---
.../heatmapConstants.tsx} | 45 +---
.../src/views/heatMap/heatMapConfiguration.tsx | 114 ++++-----
.../ozone-recon-web/src/views/heatMap/heatmap.less | 55 ++++-
.../ozone-recon-web/src/views/heatMap/heatmap.tsx | 266 ++++++++++++---------
4 files changed, 253 insertions(+), 227 deletions(-)
diff --git
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/heatMap/heatmap.less
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/heatMap/constants/heatmapConstants.tsx
similarity index 54%
copy from
hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/heatMap/heatmap.less
copy to
hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/heatMap/constants/heatmapConstants.tsx
index 9bd191bd2f..2bb3d15b35 100644
---
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/heatMap/heatmap.less
+++
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/heatMap/constants/heatmapConstants.tsx
@@ -16,45 +16,6 @@
* limitations under the License.
*/
-.heatmap-container {
-
- .go-back-button {
- display: inline-block;
- margin-left: 20px;
- }
-
- .entity-dropdown-button {
- display: inline-block;
- margin-left: 30px;
- }
-
- .date-dropdown-button {
- display: inline-block;
- margin-left: 45px;
- }
-
- .input-bar {
- display: inline-block;
- margin-left: 25px;
- }
-
- .input {
- padding-left: 5px;
- margin-right: 10px;
- display: inline-block;
- width: 400px;
- }
-
- .heatmapinformation {
- font-size: 14px;
- fill: rgba(0, 0, 0, 0.65) !important;
- line-height: 1.5;
- font-feature-settings: 'tnum', "tnum";
- height: 800;
- }
-
-}
-
-.ant-drawer-open .ant-drawer-mask {
- opacity: 0 !important;
-}
+export const TIME_PERIODS: string[] = ['24H', '7D', '90D']
+export const ENTITY_TYPES: string[] = ['key', 'bucket', 'volume']
+export const ROOT_PATH:string = '/'
diff --git
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/heatMap/heatMapConfiguration.tsx
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/heatMap/heatMapConfiguration.tsx
index 4d5d3990f4..614c311785 100644
---
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/heatMap/heatMapConfiguration.tsx
+++
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/heatMap/heatMapConfiguration.tsx
@@ -16,52 +16,47 @@
* limitations under the License.
*/
-import React, { Component } from 'react';
+import React from 'react';
import { AgChartsReact } from 'ag-charts-react';
-import {byteToSize} from 'utils/common';
+import { byteToSize } from 'utils/common';
-export default class HeatMapConfiguration extends Component {
- constructor(props: {} | Readonly<{}>) {
- super(props);
- const { data } = this.props;
+interface ITreeResponse {
+ label: string;
+ children: IChildren[];
+ size: number;
+ path: string;
+ minAccessCount: number;
+ maxAccessCount: number;
+}
- const colorRange1 = [
- '#ffff99', //yellow start 80%
- '#ffff80', //75%
- '#ffff66', //70%
- '#ffff4d', //yellow 65%
- '#ffd24d', //dark Mustered yellow start 65%
- '#ffbf00', //dark Mustard yellow end 50%
- '#b38600', //Dark Mustard yellow 35%
- '#ffb366', //orange start 70%
- '#ff9933', //orange 60%
- '#ff8c1a', //55%
- '#e67300', //45%
- '#994d00', //orange end 30%
- '#ff6633', //Red start 60%
- '#ff4000', // Red 50%
- '#cc3300', //40%
- '#992600', //30%
- '#802000', //25%
- '#661a00', //20%
- '#4d1300', // 15%
- '#330000', //dark Maroon
- '#330d00', //10 % Last Red
- ];
+interface IChildren {
+ label: string;
+ size: number;
+ accessCount: number;
+ color: number;
+}
+
+interface IHeatmapConfigurationProps {
+ data: ITreeResponse[];
+ onClick: Function;
+ colorScheme: string[];
+}
+export default class HeatMapConfiguration extends
React.Component<IHeatmapConfigurationProps> {
+ constructor(props: IHeatmapConfigurationProps) {
+ super(props);
+ const { data, colorScheme } = this.props;
this.state = {
// Tree Map Options Start
options: {
data,
- series: [
- {
+ series: [{
type: 'treemap',
labelKey: 'label',// the name of the key to fetch the label value
from
sizeKey: 'normalizedSize',// the name of the key to fetch the value
that will determine tile size
- colorkey: 'color',
- fontSize: 35,
- title: { color: 'white', fontSize: 18, fontFamily:'Courier New' },
- subtitle: { color: 'white', fontSize: 15, fontFamily:'Courier New' },
+ colorKey: 'color',
+ title: { color: '#424242', fontSize: 16, fontFamily: 'Roboto',
fontWeight: '600' },
+ subtitle: { color: '#424242', fontSize: 12, fontFamily: 'Roboto',
fontWeight: '400' },
tooltip: {
renderer: (params) => {
return {
@@ -69,27 +64,29 @@ export default class HeatMapConfiguration extends Component
{
};
}
},
- formatter: ({ highlighted}) => {
- const stroke = highlighted ? 'yellow' : 'white';
+ formatter: ({ highlighted }) => {
+ const stroke = highlighted ? '#CED4D9' : '#FFFFFF';
return { stroke };
},
labels: {
- color: 'white',
+ color: '#FFFFFF',
fontWeight: 'bold',
fontSize: 12
},
- tileStroke: 'white',
- tileStrokeWidth: 1,
+ tileStroke: '#FFFFFF',
+ tileStrokeWidth: 1.5,
colorDomain: [0.000, 0.050, 0.100, 0.150, 0.200, 0.250, 0.300,
0.350, 0.400, 0.450, 0.500, 0.550, 0.600, 0.650, 0.700, 0.750, 0.800, 0.850,
0.900, 0.950, 1.000],
- colorRange: [...colorRange1],
- nodePadding: 1.5, //Distance between two nodes
- nodeGap: '10',
+ colorRange: [...colorScheme],
+ groupFill: '#E6E6E6',
+ groupStroke: "#E1E2E6",
+ nodePadding: 3.5,
labelShadow: { enabled: false }, //labels shadow
+ gradient: false,
highlightStyle: {
text: {
- color: 'yellow',
+ color: '#424242',
},
- item:{
+ item: {
fill: undefined,
},
},
@@ -104,21 +101,20 @@ export default class HeatMapConfiguration extends
Component {
}
},
},
- }],
- title: { text: 'Volumes and Buckets'},
- }
- // Tree Map Options End
- }
- };
-
+ }],
+ title: { text: 'Volumes and Buckets' },
+ }
+ // Tree Map Options End
+ };
+ }
tooltipContent = (params: any) => {
let tooltipContent = `<span>
Size:
${byteToSize(params.datum.size, 1)}
`;
- if(params.datum.accessCount!==undefined ){
- tooltipContent += `<br/>
+ if (params.datum.accessCount !== undefined) {
+ tooltipContent += `<br/>
Access count:
${params.datum.accessCount }
`;
@@ -129,21 +125,17 @@ export default class HeatMapConfiguration extends
Component {
${params.datum.maxAccessCount}
`;}
if (params.datum.label !== "") {
- tooltipContent += `<br/>
+ tooltipContent += `<br/>
File Name:
${params.datum.label ? params.datum.label.split("/").slice(-1) : ""}
`;
- }
+ }
tooltipContent += '</span>';
return tooltipContent;
};
render() {
const { options } = this.state;
- return (
- <AgChartsReact options={options} />
- );
+ return <AgChartsReact options={options} />;
}
-
}
-
diff --git
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/heatMap/heatmap.less
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/heatMap/heatmap.less
index 9bd191bd2f..b16d1ed20f 100644
---
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/heatMap/heatmap.less
+++
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/heatMap/heatmap.less
@@ -18,19 +18,34 @@
.heatmap-container {
- .go-back-button {
- display: inline-block;
- margin-left: 20px;
- }
+ .heatmap-header-container {
+ height: 7vh;
+ display: flex;
+ justify-content: space-between;
+ align-items: stretch;
+ margin: 10px 15px 20px 15px;
+
+ .go-back-button {
+ display: inline-block;
+ }
+
+ .path-input-container {
+ display: inline-flex;
+ margin-left: 15px;
+ align-items: flex-start;
+ .path-input-element{
+ margin: 0px;
+ }
+ }
.entity-dropdown-button {
display: inline-block;
- margin-left: 30px;
+ margin-left: 20px;
}
.date-dropdown-button {
display: inline-block;
- margin-left: 45px;
+ margin-left: 30px;
}
.input-bar {
@@ -45,16 +60,40 @@
width: 400px;
}
- .heatmapinformation {
+ .heatmap-legend-container {
+ display: flex !important;
+ align-self: flex-start;
+ margin-top: 10px;
+
+ .heatmap-legend-item{
+ display: flex;
+ align-items: center;
+ margin-left: 20px;
+ }
+ }
+ }
+
+ #heatmap-chart-container{
+ height: 850px;
+ width: 85vw;
+ margin-left: -10px;
+ }
+
+ .heatmap-no-data-text {
font-size: 14px;
fill: rgba(0, 0, 0, 0.65) !important;
line-height: 1.5;
font-feature-settings: 'tnum', "tnum";
height: 800;
}
-
}
.ant-drawer-open .ant-drawer-mask {
opacity: 0 !important;
}
+
+.ant-calendar-picker-container {
+ left: 62vw !important;
+ top: 15vh !important;
+ backdrop-filter: blur(100vh) !important;
+}
diff --git
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/heatMap/heatmap.tsx
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/heatMap/heatmap.tsx
index c3a7e991fc..713ad5131c 100644
---
a/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/heatMap/heatmap.tsx
+++
b/hadoop-ozone/recon/src/main/resources/webapps/recon/ozone-recon-web/src/views/heatMap/heatmap.tsx
@@ -15,15 +15,17 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
import React from 'react';
import axios from 'axios';
-import { Row, Icon, Button, Input, Dropdown, Menu, DatePicker } from 'antd';
-import {DownOutlined} from '@ant-design/icons';
+import { Row, Icon, Button, Input, Dropdown, Menu, DatePicker, Form } from
'antd';
+import { DownOutlined } from '@ant-design/icons';
import moment from 'moment';
-import {showDataFetchError} from 'utils/common';
+import { showDataFetchError } from 'utils/common';
import './heatmap.less';
import HeatMapConfiguration from './heatMapConfiguration';
+import * as CONSTANTS from './constants/heatmapConstants';
+
+type inputPathValidity = "" | "error" | "success" | "warning" | "validating" |
undefined
interface ITreeResponse {
label: string;
@@ -36,7 +38,6 @@ interface ITreeResponse {
interface IChildren {
label: string;
- path: string;
size: number;
accessCount: number;
color: number;
@@ -51,11 +52,39 @@ interface ITreeState {
entityType: string;
date: string;
treeEndpointFailed: boolean;
+ inputPathValid: inputPathValidity;
+ helpMessage: string;
}
let minSize = Infinity;
let maxSize = 0;
+const colourScheme = {
+ amber_alert: [
+ '#FFCF88',
+ '#FFCA87',
+ '#FFC586',
+ '#FFC085',
+ '#FFBB83',
+ '#FFB682',
+ '#FFB181',
+ '#FFA676',
+ '#FF9F6F',
+ '#FF9869',
+ '#FF9262',
+ '#FF8B5B',
+ '#FF8455',
+ '#FF7D4E',
+ '#FF8282',
+ '#FF7776',
+ '#FF6D6A',
+ '#FF625F',
+ '#FF5753',
+ '#FF4D47',
+ '#FF423B'
+ ]
+};
+
export class Heatmap extends React.Component<Record<string, object>,
ITreeState> {
constructor(props = {}) {
super(props);
@@ -63,55 +92,56 @@ export class Heatmap extends React.Component<Record<string,
object>, ITreeState>
isLoading: false,
treeResponse: [],
showPanel: false,
- entityType: 'key',
- inputPath: '/',
- date: '24H',
- treeEndpointFailed: false
+ entityType: CONSTANTS.ENTITY_TYPES[0],
+ inputPath: CONSTANTS.ROOT_PATH,
+ date: CONSTANTS.TIME_PERIODS[0],
+ treeEndpointFailed: false,
+ inputPathValid: undefined,
+ helpMessage: ""
};
}
handleCalendarChange = (e: any) => {
- if (e.key === '24H' || e.key === '7D' || e.key === '90D') {
- this.setState((prevState, newState) => ({
+ if (CONSTANTS.TIME_PERIODS.includes(e.key)) {
+ this.setState((prevState, _newState) => ({
date: e.key,
inputPath: prevState.inputPath,
entityType: prevState.entityType
}), () => {
- this.updateTreeMap(this.state.inputPath, this.state.entityType,
this.state.date)
+ this.updateTreeMap(this.state.inputPath, this.state.entityType,
this.state.date);
});
}
};
handleMenuChange = (e: any) => {
- if (e.key === 'volume' || e.key === 'bucket' || e.key === 'key')
- {
- minSize=Infinity;
+ if (CONSTANTS.ENTITY_TYPES.includes(e.key)) {
+ minSize = Infinity;
maxSize = 0;
- this.setState((prevState, newState) => ({
+ this.setState((prevState, _newState) => ({
entityType: e.key,
date: prevState.date,
- inputPath : prevState.inputPath
+ inputPath: prevState.inputPath
}), () => {
- this.updateTreeMap(this.state.inputPath,
this.state.entityType,this.state.date)
+ this.updateTreeMap(this.state.inputPath, this.state.entityType,
this.state.date);
});
}
};
handleChange = (e: any) => {
const value = e.target.value;
- let validExpression;
+ let inputValid = "";
+ let helpMessage = ""
// Only allow letters, numbers,underscores and forward slashes
const regex = /^[a-zA-Z0-9_/]*$/;
- if (regex.test(value)) {
- validExpression = value;
- }
- else {
- alert("Please Enter Valid Input Path.");
- validExpression = '/';
+ if (!regex.test(value)) {
+ helpMessage = "Please enter valid path"
+ inputValid = "error"
}
- this.setState({
- inputPath: validExpression
- })
+ this.setState({
+ inputPath: value,
+ inputPathValid: inputValid as inputPathValidity,
+ helpMessage: helpMessage
+ });
};
handleSubmit = (_e: any) => {
@@ -119,7 +149,7 @@ export class Heatmap extends React.Component<Record<string,
object>, ITreeState>
this.updateTreeMap(this.state.inputPath, this.state.entityType,
this.state.date);
};
- updateTreeMap = (path: string, entityType:string, date:string) => {
+ updateTreeMap = (path: string, entityType: string, date: string) => {
this.setState({
isLoading: true,
treeEndpointFailed: false
@@ -159,42 +189,42 @@ export class Heatmap extends
React.Component<Record<string, object>, ITreeState>
this.setState({
isLoading: true,
inputPath: path
- },() => {
- this.updateTreeMap(this.state.inputPath,
this.state.entityType,this.state.date)
+ }, () => {
+ this.updateTreeMap(this.state.inputPath, this.state.entityType,
this.state.date);
});
};
componentDidMount(): void {
+
this.setState({
isLoading: true
});
// By default render treemap for default path entity type and date
- this.updateTreeMap('/',this.state.entityType,this.state.date);
+ this.updateTreeMap(CONSTANTS.ROOT_PATH, this.state.entityType,
this.state.date);
}
onChange = (date: any[]) => {
-
this.setState(prevState => ({
date: moment(date).unix(),
entityType: prevState.entityType,
- inputPath : prevState.inputPath
+ inputPath: prevState.inputPath
}), () => {
- this.updateTreeMap(this.state.inputPath,
this.state.entityType,this.state.date)
+ this.updateTreeMap(this.state.inputPath, this.state.entityType,
this.state.date);
});
- }
+ };
disabledDate(current: any) {
return current > moment() || current < moment().subtract(90, 'day');
}
- resetInputpath = (e:any, path:string) => {
- if (!path || path === '/') {
+ resetInputpath = (_e: any, path: string) => {
+ if (!path || path === CONSTANTS.ROOT_PATH) {
return;
}
else {
this.setState({
- inputPath: '/'
- })
+ inputPath: CONSTANTS.ROOT_PATH
+ });
}
};
@@ -240,65 +270,66 @@ export class Heatmap extends
React.Component<Record<string, object>, ITreeState>
normalize = (min: number, max: number, size: number) => {
//Normaized Size using Deviation and mid Point
- var mean = (max + min) / 2;
- var highMean = (max+mean)/2;
- var lowMean1 = (min+mean)/2;
- var lowMean2 = (lowMean1 + min) / 2;
-
- if(size>highMean){
- var newsize= highMean+(size*0.1);
- return(newsize);
+ const mean = (max + min) / 2;
+ const highMean = (max + mean) / 2;
+ const lowMean1 = (min + mean) / 2;
+ const lowMean2 = (lowMean1 + min) / 2;
+
+ if (size > highMean) {
+ const newsize = highMean + (size * 0.1);
+ return (newsize);
}
// lowmean2= 100 value=10, diff=
// min= 10 ,max=100, mean=55, lowmean1=32.5,lowmean2=22, value= 15,
diff=7, diff/2=3.5, newsize= 22-3.5=18.5
- if(size<lowMean2){
- var diff = (lowMean2-size)/2;
- var newSize= lowMean2-diff;
- return(newSize);
+ if (size < lowMean2) {
+ const diff = (lowMean2 - size) / 2;
+ const newSize = lowMean2 - diff;
+ return (newSize);
}
return size;
- }
+ };
render() {
- const { treeResponse, isLoading, inputPath, date, treeEndpointFailed } =
this.state;
+ const { treeResponse, isLoading, inputPath, date, treeEndpointFailed,
inputPathValid, helpMessage } = this.state;
+
const menuCalendar = (
<Menu
defaultSelectedKeys={[date]}
onClick={e => this.handleCalendarChange(e)}>
- <Menu.Item key='24H'>
- 24 Hour
+ <Menu.Item key={CONSTANTS.TIME_PERIODS[0]}>
+ 24 Hour
</Menu.Item>
- <Menu.Item key='7D'>
- 7 Days
+ <Menu.Item key={CONSTANTS.TIME_PERIODS[1]}>
+ 7 Days
</Menu.Item>
- <Menu.Item key='90D'>
- 90 Days
+ <Menu.Item key={CONSTANTS.TIME_PERIODS[2]}>
+ 90 Days
</Menu.Item>
- <Menu.SubMenu title="Custom Select Last 90 Days">
- <Menu.Item>
- <DatePicker
- format="YYYY-MM-DD"
- onChange={this.onChange}
- disabledDate={this.disabledDate}
- />
+ <Menu.SubMenu title="Custom Select Last 90 Days">
+ <Menu.Item>
+ <DatePicker
+ format="YYYY-MM-DD"
+ onChange={this.onChange}
+ disabledDate={this.disabledDate}
+ />
</Menu.Item>
</Menu.SubMenu>
</Menu>
);
-
+
const entityTypeMenu = (
<Menu
defaultSelectedKeys={[this.state.entityType]}
onClick={e => this.handleMenuChange(e)}>
- <Menu.Item key='volume'>
- Volume
- </Menu.Item>
- <Menu.Item key='bucket'>
- Bucket
- </Menu.Item>
- <Menu.Item key='key'>
- Key
- </Menu.Item>
+ <Menu.Item key={CONSTANTS.ENTITY_TYPES[2]}>
+ Volume
+ </Menu.Item>
+ <Menu.Item key={CONSTANTS.ENTITY_TYPES[1]}>
+ Bucket
+ </Menu.Item>
+ <Menu.Item key={CONSTANTS.ENTITY_TYPES[0]}>
+ Key
+ </Menu.Item>
</Menu>
);
@@ -308,50 +339,53 @@ export class Heatmap extends
React.Component<Record<string, object>, ITreeState>
Tree Map for Entities
</div>
<div className='content-div'>
- { isLoading ? <span><Icon type='loading'/> Loading...</span> : (
+ {isLoading ? <span><Icon type='loading' /> Loading...</span> : (
<div>
{treeEndpointFailed ? <div className='heatmapinformation'><br
/>Failed to Load Heatmap.{' '}<br /></div> :
(Object.keys(treeResponse).length > 0 && (treeResponse.label
!== null || treeResponse.path !== null)) ?
<div>
- <Row>
- <div className='go-back-button'>
- <Button type='primary' onClick={e =>
this.resetInputpath(e, inputPath)}><Icon type='undo'/></Button>
- </div>
- <div className='input-bar'>
- <h4>Path</h4>
- <form className='input' autoComplete="off"
id='input-form' onSubmit={this.handleSubmit}>
- <Input placeholder='/' name="inputPath"
value={inputPath} onChange={this.handleChange} />
- </form>
- </div>
- <div className='entity-dropdown-button'>
- <Dropdown overlay={entityTypeMenu}
placement='bottomCenter'>
- <Button>Entity
Type: {this.state.entityType }<DownOutlined/></Button>
- </Dropdown>
- </div>
- <div className='date-dropdown-button'>
- <Dropdown overlay={menuCalendar}
placement='bottomLeft'>
- <Button>Last {date > 100 ? new
Date(date*1000).toLocaleString() : date }<DownOutlined/></Button>
- </Dropdown>
- </div>
- </Row>
- <br/><br/><br/><br/><br/>
- <div style={{display:"flex", alignItems: "right"}}>
- <div style={{ display: "flex", alignItems:
"center",marginLeft:"30px"}}>
- <div style={{ width: "13px", height: "13px",
backgroundColor: "yellow", marginRight: "5px" }}> </div>
- <span>Less Accessed</span>
- </div>
- <div style={{ display: "flex", alignItems:
"center",marginLeft:"50px" }}>
- <div style={{ width: "13px", height: "13px",
backgroundColor: "orange", marginRight: "5px" }}> </div>
- <span>Moderate Accessed</span>
- </div>
- <div style={{ display: "flex", alignItems:
"center",marginLeft:"50px" }}>
- <div style={{ width: "13px", height: "13px",
backgroundColor: "maroon", marginRight: "5px" }}> </div>
- <span>Most Accessed</span>
- </div>
- </div>
- <div style={{ height:850}}>
- <HeatMapConfiguration data={treeResponse}
onClick={this.updateTreemapParent}></HeatMapConfiguration>
+ <div className='heatmap-header-container'>
+ <Row>
+ <div className='go-back-button'>
+ <Button type='primary' onClick={e =>
this.resetInputpath(e, inputPath)}><Icon type='undo' /></Button>
+ </div>
+ <div className='path-input-container'>
+ <h4 style={{ marginTop: "10px" }}>Path</h4>
+ <form className='input' autoComplete="off"
id='input-form' onSubmit={this.handleSubmit}>
+ <Form.Item className='path-input-element'
validateStatus={inputPathValid} help={helpMessage}>
+ <Input placeholder={CONSTANTS.ROOT_PATH}
name="inputPath" value={inputPath} onChange={this.handleChange}/>
+ </Form.Item>
+ </form>
+ </div>
+ <div className='entity-dropdown-button'>
+ <Dropdown overlay={entityTypeMenu}
placement='bottomCenter'>
+ <Button>Entity
Type: {this.state.entityType}<DownOutlined /></Button>
+ </Dropdown>
+ </div>
+ <div className='date-dropdown-button'>
+ <Dropdown overlay={menuCalendar}
placement='bottomLeft'>
+ <Button>Last {date > 100 ? new Date(date *
1000).toLocaleString() : date}<DownOutlined /></Button>
+ </Dropdown>
+ </div>
+ </Row>
+ <div className='heatmap-legend-container'>
+ <div className='heatmap-legend-item'>
+ <div style={{ width: "13px", height: "13px",
backgroundColor: `${colourScheme["amber_alert"][0]}`, marginRight: "5px" }}>
</div>
+ <span>Less Accessed</span>
+ </div>
+ <div className='heatmap-legend-item'>
+ <div style={{ width: "13px", height: "13px",
backgroundColor: `${colourScheme["amber_alert"][8]}`, marginRight: "5px" }}>
</div>
+ <span>Moderate Accessed</span>
+ </div>
+ <div className='heatmap-legend-item'>
+ <div style={{ width: "13px", height: "13px",
backgroundColor: `${colourScheme["amber_alert"][20]}`, marginRight: "5px" }}>
</div>
+ <span>Most Accessed</span>
+ </div>
</div>
+ </div>
+ <div id="heatmap-chart-container">
+ <HeatMapConfiguration data={treeResponse}
colorScheme={colourScheme["amber_alert"]}
onClick={this.updateTreemapParent}></HeatMapConfiguration>
+ </div>
</div>
:
<div className='heatmapinformation'><br />
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]