1+ import React , { useEffect } from 'react' ;
2+ import { ResponsiveRadar } from '@nivo/radar'
3+ import { ChartReportProps , ExtendedChartReportProps } from './VisualizationProps'
4+ import { checkResultKeys , recordToNative } from './Utils'
5+ import { categoricalColorSchemes } from "../../config/ColorConfig" ;
6+ import { evaluateRulesOnDict , evaluateRulesOnNode } from '../../report/ReportRuleEvaluator'
7+ import { convertRecordObjectToString , valueIsArray , valueIsNode , valueIsPath , valueIsRelationship } from "../../report/ReportRecordProcessing" ;
8+
9+ export default function RadarVisualization ( props : ExtendedChartReportProps ) {
10+ const { records, first } = props
11+
12+ if ( ! first ) {
13+ return < p > Loading data...</ p >
14+ }
15+
16+ const selection = ( props . selection ) ? props . selection : { } ;
17+ const settings = ( props . settings ) ? props . settings : { } ;
18+ const legendHeight = 20 ;
19+ const legendWidth = 20 ;
20+ const marginRight = ( settings [ "marginRight" ] ) ? settings [ "marginRight" ] : 24 ;
21+ const marginLeft = ( settings [ "marginLeft" ] ) ? settings [ "marginLeft" ] : 24 ;
22+ const marginTop = ( settings [ "marginTop" ] ) ? settings [ "marginTop" ] : 40 ;
23+ const marginBottom = ( settings [ "marginBottom" ] ) ? settings [ "marginBottom" ] : 40 ;
24+ const dotSize = ( settings [ "dotSize" ] ) ? settings [ "dotSize" ] : 10 ;
25+ const dotBorderWidth = ( settings [ "dotBorderWidth" ] ) ? settings [ "dotBorderWidth" ] : 2 ;
26+ const gridLabelOffset = ( settings [ "gridLabelOffset" ] ) ? settings [ "gridLabelOffset" ] : 16 ;
27+ const gridLevels = ( settings [ "gridLevels" ] ) ? settings [ "gridLevels" ] : 5 ;
28+ const interactive = ( settings [ "interactive" ] !== undefined ) ? settings [ "interactive" ] : true ;
29+ const animate = ( settings [ "animate" ] !== undefined ) ? settings [ "animate" ] : true ;
30+ const legend = ( settings [ "legend" ] !== undefined ) ? settings [ "legend" ] : false ;
31+ const colorScheme = ( settings [ "colors" ] ) ? settings [ "colors" ] : 'set2' ;
32+ const blendMode = ( settings [ "blendMode" ] ) ? settings [ "blendMode" ] : 'normal' ;
33+ const motionConfig = ( settings [ "motionConfig" ] ) ? settings [ "motionConfig" ] : 'gentle' ;
34+ const curve = ( settings [ "curve" ] ) ? settings [ "curve" ] : 'linearClosed' ;
35+ const styleRules = settings && settings [ "styleRules" ] ? settings [ "styleRules" ] : [ ] ;
36+ const keys = first ! . keys . slice ( 1 ) . map ( k => k . substring ( 7 , k . length - 1 ) ) ;
37+
38+
39+ if ( ! selection || props . records == null || props . records . length == 0 || props . records [ 0 ] . keys == null ) {
40+ return < p > No data.</ p > ;
41+ }
42+
43+
44+ // Compute slice color based on rules - overrides default color scheme completely.
45+ const getCircleColor = ( slice ) => {
46+ const data = { }
47+ if ( ! props . selection ) {
48+ return "grey" ;
49+ }
50+ data [ props . selection [ 'value' ] ] = slice . value ;
51+ data [ props . selection [ 'index' ] ] = slice . id ;
52+ const validRuleIndex = evaluateRulesOnDict ( data , styleRules , [ 'slice color' ] ) ;
53+ if ( validRuleIndex !== - 1 ) {
54+ return styleRules [ validRuleIndex ] [ 'customizationValue' ] ;
55+ }
56+ return "grey"
57+ }
58+
59+ const data = records . map ( r => {
60+ const entry = { }
61+ first ! . keys . forEach ( ( k , i ) => {
62+ const key = k == "index" ? selection [ "index" ] : k . substring ( 7 , k . length - 1 ) ;
63+ const fieldIndex = r [ "_fieldLookup" ] [ k ] ;
64+ entry [ key ] = "" + r [ "_fields" ] [ fieldIndex ] ;
65+ } ) ;
66+ return entry ;
67+ } ) ;
68+
69+ return < ResponsiveRadar
70+ data = { data }
71+ isInteractive = { interactive }
72+ animate = { animate }
73+ margin = { { top : ( legend ) ? legendHeight + marginTop : marginTop , right : ( legend ) ? legendWidth + marginRight : marginRight , bottom : marginBottom , left : ( legend ) ? legendHeight + marginLeft : marginLeft } }
74+ gridLevels = { gridLevels }
75+ keys = { keys }
76+ indexBy = { selection [ 'index' ] }
77+ valueFormat = ">-.2f"
78+ borderColor = { { from : 'color' } }
79+ gridLabelOffset = { gridLabelOffset }
80+ dotSize = { dotSize }
81+ dotColor = { { theme : 'background' } }
82+ dotBorderWidth = { dotBorderWidth }
83+ colors = { styleRules . length >= 1 ? getCircleColor : { scheme : colorScheme } }
84+ blendMode = { blendMode }
85+ motionConfig = { motionConfig }
86+ curve = { curve }
87+ legends = { ( legend ) ? [
88+ {
89+ anchor : 'top-left' ,
90+ direction : 'column' ,
91+ translateX : 0 ,
92+ translateY : - 40 ,
93+ itemWidth : 100 ,
94+ itemHeight : 14 ,
95+ itemTextColor : '#999' ,
96+ symbolSize : 14 ,
97+ symbolShape : 'circle' ,
98+ effects : [
99+ {
100+ on : 'hover' ,
101+ style : {
102+ itemTextColor : '#000'
103+ }
104+ }
105+ ]
106+ }
107+ ] : [ ] }
108+ { ...props . config }
109+ />
110+
111+ }
0 commit comments