github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/ui/src/views/cluster/containers/nodesOverview/barChart.tsx (about)

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  import d3 from "d3";
    12  import React from "react";
    13  
    14  import { Bytes, Percentage } from "src/util/format";
    15  
    16  interface BytesBarChartProps {
    17    used: number;
    18    usable: number;
    19  }
    20  
    21  const width = 175;
    22  const height = 28;
    23  
    24  const chartHeight = 14;
    25  
    26  export class BytesBarChart extends React.Component<BytesBarChartProps> {
    27    chart: React.RefObject<HTMLDivElement> = React.createRef();
    28  
    29    componentDidMount() {
    30      this.renderChart(this.props);
    31    }
    32  
    33    shouldComponentUpdate(props: BytesBarChartProps) {
    34      this.renderChart(props);
    35      return false;
    36    }
    37  
    38    renderChart(props: BytesBarChartProps) {
    39      const svg = d3.select(this.chart.current)
    40        .selectAll("svg")
    41        .data([{ width, height }]);
    42  
    43      const svgEnter = svg
    44        .enter()
    45        .append("svg")
    46        .attr("width", d => d.width)
    47        .attr("height", d => d.height);
    48  
    49      svgEnter.append("text")
    50        .attr("y", chartHeight - 4)
    51        .attr("class", "bar-chart__label percent");
    52  
    53      const label = svg.select(".bar-chart__label.percent")
    54        .text("100%");
    55  
    56      const textNode = label.node();
    57      const reserveWidth = !textNode ? 100 : (textNode as SVGSVGElement).getBBox().width;
    58  
    59      svg.selectAll(".bar-chart__label.percent")
    60        .text(Percentage(props.used, props.usable));
    61  
    62      const labelWidth = !textNode ? 100 : (textNode as SVGSVGElement).getBBox().width;
    63  
    64      label.attr("x", reserveWidth - labelWidth);
    65  
    66      const spacing = 3;
    67  
    68      const chartEnter = svgEnter.append("g")
    69        .attr("class", "bar-chart__bars")
    70        .attr("transform", `translate(${reserveWidth + spacing},0)`);
    71  
    72      const chart = svg.selectAll(".bar-chart__bars");
    73  
    74      const chartWidth = width - reserveWidth - spacing;
    75  
    76      chartEnter.append("rect")
    77        .attr("width", chartWidth * 0.9)
    78        .attr("height", chartHeight)
    79        .attr("fill", "#e2e5ee");
    80  
    81      chartEnter.append("rect")
    82        .attr("x", chartWidth * 0.9)
    83        .attr("width", chartWidth * 0.1)
    84        .attr("height", chartHeight)
    85        .attr("fill", "#cfd2dc");
    86  
    87      chartEnter.append("rect")
    88        .attr("class", "bar-chart__bar used")
    89        .attr("height", 5) // This attr's for FF, the CSS rule is for Chrome.
    90        .attr("y", (chartHeight - 5) / 2);
    91  
    92      chart.selectAll(".bar-chart__bar.used")
    93        .attr("width", chartWidth * props.used / props.usable);
    94  
    95      chartEnter.append("text")
    96        .attr("y", height)
    97        .attr("class", "bar-chart__label used");
    98  
    99      chart.selectAll(".bar-chart__label.used")
   100        .text(Bytes(props.used));
   101  
   102      chartEnter.append("text")
   103        .attr("y", height)
   104        .attr("class", "bar-chart__label total");
   105  
   106      const total = chart.selectAll(".bar-chart__label.total")
   107        .text(Bytes(props.usable));
   108  
   109      const totalNode = total.node();
   110      const totalWidth = !totalNode ? 100 : (totalNode as SVGSVGElement).getBBox().width;
   111  
   112      total.attr("x", chartWidth - totalWidth - 0);
   113    }
   114  
   115    render() {
   116      return <div ref={this.chart} />;
   117    }
   118  }