1
0

Indicator.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. /*
  2. * Copyright 2021-2024 Avaiga Private Limited
  3. *
  4. * Licensed under the Apache License, Version 2.0 (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. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
  10. * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
  11. * specific language governing permissions and limitations under the License.
  12. */
  13. import React, { useCallback, useMemo } from "react";
  14. import Slider from "@mui/material/Slider";
  15. import Tooltip from "@mui/material/Tooltip";
  16. import { sprintf } from "sprintf-js";
  17. import { TaipyBaseProps, TaipyHoverProps } from "./utils";
  18. import { useClassNames, useDynamicProperty } from "../../utils/hooks";
  19. interface IndicatorProps extends TaipyBaseProps, TaipyHoverProps {
  20. min?: number;
  21. max?: number;
  22. value?: number;
  23. defaultValue: number;
  24. display?: number | string;
  25. defaultDisplay: number | string;
  26. format?: string;
  27. orientation?: string;
  28. width?: string;
  29. height?: string;
  30. }
  31. const getValue = (value: number, min: number, max: number) => {
  32. const dir = max - min >= 0;
  33. value = typeof value === "number" ? value : min;
  34. return (100 * (Math.max(Math.min(value, dir ? max : min), dir ? min : max) - min)) / (max - min);
  35. };
  36. const Indicator = (props: IndicatorProps) => {
  37. const { min = 0, max = 100, display, defaultDisplay, format, value, defaultValue = 0, width, height } = props;
  38. const horizontalOrientation = props.orientation ? props.orientation.charAt(0).toLowerCase() !== "v" : true;
  39. const className = useClassNames(props.libClassName, props.dynamicClassName, props.className);
  40. const hover = useDynamicProperty(props.hoverText, props.defaultHoverText, undefined);
  41. const getLabel = useCallback(() => {
  42. const dsp = display === undefined ? (defaultDisplay === undefined ? "" : defaultDisplay) : display;
  43. return format ? (typeof dsp === "string" ? dsp : sprintf(format, dsp)) : dsp;
  44. }, [display, defaultDisplay, format]);
  45. const marks = [
  46. { value: 0, label: "" + min },
  47. { value: 100, label: "" + max },
  48. ];
  49. const sliderSx = useMemo(
  50. () => ({
  51. "&": {
  52. width: horizontalOrientation ? width : undefined,
  53. height: horizontalOrientation ? undefined : height,
  54. },
  55. "&.Mui-disabled": {
  56. color: "transparent",
  57. },
  58. "& .MuiSlider-markLabel": {
  59. transform: "initial",
  60. },
  61. "& span:nth-of-type(6)": {
  62. transform: horizontalOrientation ? "translateX(-100%)" : "translateY(100%)",
  63. },
  64. "& .MuiSlider-rail": {
  65. background: `linear-gradient(${
  66. horizontalOrientation ? 90 : 0
  67. }deg, rgba(255,0,0,1) 0%, rgba(0,255,0,1) 100%)`,
  68. opacity: "unset",
  69. },
  70. "& .MuiSlider-track": {
  71. border: "none",
  72. backgroundColor: "transparent",
  73. },
  74. "& .MuiSlider-valueLabel": {
  75. top: "unset",
  76. },
  77. "& .MuiSlider-valueLabel.MuiSlider-valueLabelOpen": {
  78. transform: horizontalOrientation ? "" : "translate(calc(50% + 10px))",
  79. },
  80. "& .MuiSlider-valueLabel:before": {
  81. left: horizontalOrientation ? "50%" : "0",
  82. bottom: horizontalOrientation ? "0" : "50%",
  83. },
  84. }),
  85. [horizontalOrientation, width, height]
  86. );
  87. return (
  88. <Tooltip title={hover || ""}>
  89. <Slider
  90. id={props.id}
  91. className={className}
  92. min={0}
  93. max={100}
  94. value={getValue(value === undefined ? defaultValue : value, min, max)}
  95. disabled={true}
  96. valueLabelDisplay="on"
  97. valueLabelFormat={getLabel}
  98. marks={marks}
  99. orientation={horizontalOrientation ? undefined : "vertical"}
  100. sx={sliderSx}
  101. ></Slider>
  102. </Tooltip>
  103. );
  104. };
  105. export default Indicator;