drawValue_() {
    if (!this.isInDocument()) {
      return;
    }

    const r = this.needleRadius_;
    const graphics = this.graphics_;
    const theme = this.theme_;
    const cx = this.width_ / 2;
    const cy = this.height_ / 2;
    const angle = this.valuePositionToAngle_(
        /** @type {number} */ (this.needleValuePosition_));

    // Compute the needle path
    const frontRadius = Math.round(r * FACTOR_NEEDLE_FRONT);
    const backRadius = Math.round(r * FACTOR_NEEDLE_BACK);
    const frontDx = googMath.angleDx(angle, frontRadius);
    const frontDy = googMath.angleDy(angle, frontRadius);
    const backDx = googMath.angleDx(angle, backRadius);
    const backDy = googMath.angleDy(angle, backRadius);
    const angleRight = googMath.standardAngle(angle + 90);
    const distanceControlPointBase = r * FACTOR_NEEDLE_WIDTH;
    const controlPointMidDx =
        googMath.angleDx(angleRight, distanceControlPointBase);
    const controlPointMidDy =
        googMath.angleDy(angleRight, distanceControlPointBase);

    const path = new Path();
    path.moveTo(cx + frontDx, cy + frontDy);
    path.curveTo(
        cx + controlPointMidDx, cy + controlPointMidDy,
        cx - backDx + (controlPointMidDx / 2),
        cy - backDy + (controlPointMidDy / 2), cx - backDx, cy - backDy);
    path.curveTo(
        cx - backDx - (controlPointMidDx / 2),
        cy - backDy - (controlPointMidDy / 2), cx - controlPointMidDx,
        cy - controlPointMidDy, cx + frontDx, cy + frontDy);

    // Draw the needle hinge
    const rh = Math.round(r * FACTOR_NEEDLE_HINGE);

    // Clean previous needle
    let needleGroup = this.needleGroup_;
    if (needleGroup) {
      needleGroup.clear();
    } else {
      needleGroup = this.needleGroup_ = graphics.createGroup();
    }

    // Draw current formatted value if provided.
    if (this.formattedValue_) {
      let font = this.valueFont_;
      if (!font) {
        const fontSize = Math.round(r * FACTOR_VALUE_FONT_SIZE);
        font = new Font(fontSize, TITLE_FONT_NAME);
        font.bold = true;
        this.valueFont_ = font;
      }
      let fill = new SolidFill(theme.getValueColor());
      const y = cy + Math.round(r * FACTOR_VALUE_OFFSET);
      graphics.drawTextOnLine(
          this.formattedValue_, 0, y, this.width_, y, 'center', font, null,
          fill, needleGroup);
    }

    // Draw the needle
    let stroke = theme.getNeedleStroke();
    let fill = theme.getNeedleFill(cx, cy, rh);
    graphics.drawPath(path, stroke, fill, needleGroup);
    stroke = theme.getHingeStroke();
    fill = theme.getHingeFill(cx, cy, rh);
    graphics.drawCircle(cx, cy, rh, stroke, fill, needleGroup);
  }
Draw the elements that depend on the current value (the needle and
the formatted value). This function is called whenever a value is changed
or when the entire gauge is redrawn.
@private