github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/ui/ccl/src/views/clusterviz/containers/map/circleLayout.tsx (about) 1 // Copyright 2017 The Cockroach Authors. 2 // 3 // Licensed as a CockroachDB Enterprise file under the Cockroach Community 4 // License (the "License"); you may not use this file except in compliance with 5 // the License. You may obtain a copy of the License at 6 // 7 // https://github.com/cockroachdb/cockroach/blob/master/licenses/CCL.txt 8 9 import React from "react"; 10 11 import { LocalityTree } from "src/redux/localities"; 12 import { getChildLocalities } from "src/util/localities"; 13 14 import { LocalityView } from "./localityView"; 15 import { NodeView } from "./nodeView"; 16 import { LivenessStatus } from "src/redux/nodes"; 17 import { cockroach } from "src/js/protos"; 18 19 type Liveness = cockroach.kv.kvserver.storagepb.ILiveness; 20 21 const MIN_RADIUS = 150; 22 const PADDING = 150; 23 24 interface CircleLayoutProps { 25 localityTree: LocalityTree; 26 livenessStatuses: { [id: string]: LivenessStatus }; 27 livenesses: { [id: string]: Liveness }; 28 viewportSize: [number, number]; 29 } 30 31 export class CircleLayout extends React.Component<CircleLayoutProps> { 32 coordsFor(index: number, total: number, radius: number) { 33 if (total === 1) { 34 return [0, 0]; 35 } 36 37 if (total === 2) { 38 const leftOrRight = index === 0 ? -radius : radius; 39 return [leftOrRight, 0]; 40 } 41 42 const angle = 2 * Math.PI * index / total - Math.PI / 2; 43 return [radius * Math.cos(angle), radius * Math.sin(angle)]; 44 } 45 46 render() { 47 const { localityTree, viewportSize } = this.props; 48 const childLocalities = getChildLocalities(localityTree); 49 50 const total = localityTree.nodes.length + childLocalities.length; 51 52 const calculatedRadius = Math.min(...viewportSize) / 2 - PADDING; 53 const radius = Math.max(MIN_RADIUS, calculatedRadius); 54 55 return ( 56 <g transform={`translate(${viewportSize[0] / 2},${viewportSize[1] / 2})`}> 57 { 58 childLocalities.map((locality, i) => ( 59 <g transform={`translate(${this.coordsFor(i, total, radius)})`}> 60 <LocalityView 61 localityTree={locality} 62 livenessStatuses={this.props.livenessStatuses} 63 /> 64 </g> 65 )) 66 } 67 { 68 localityTree.nodes.map((node, i) => { 69 return ( 70 <g transform={`translate(${this.coordsFor(i + childLocalities.length, total, radius)})`}> 71 <NodeView 72 node={node} 73 livenessStatus={this.props.livenessStatuses[node.desc.node_id]} 74 liveness={this.props.livenesses[node.desc.node_id]} 75 /> 76 </g> 77 ); 78 }) 79 } 80 </g> 81 ); 82 } 83 }