class HistogramBuilder extends TraceBuilder {

    private final String type = "histogram";
    private int nBinsX;
    private int nBinsY;
    private boolean autoBinX;
    private boolean autoBinY;
    private boolean horizontal = false;
    private Object[] x;
    private Object[] y;
    private Marker marker;
    private HistNorm histNorm = HistNorm.NONE;
    private HistFunc histFunc = HistFunc.COUNT;

    private HistogramBuilder(double[] values) {
      this.x = doublesToObjects(values);
    }

    private HistogramBuilder(Object[] xValues, double[] yValues) {
      this.x = xValues;
      this.y = doublesToObjects(yValues);
    }

    /**
     * Specifies the maximum number of desired bins. This value will be used in an algorithm that
     * will decide the optimal bin size such that the histogram best visualizes the distribution of
     * the data.
     */
    public HistogramBuilder nBinsX(int bins) {
      this.nBinsX = bins;
      return this;
    }

    public HistogramBuilder nBinsY(int bins) {
      this.nBinsY = bins;
      return this;
    }

    /**
     * Determines whether or not the x axis bin attributes are picked by an algorithm. Note that
     * this should be set to False if you want to manually set the number of bins using the
     * attributes in xbins.
     *
     * <p>Note also that this should be true (default) to use nbinsx to suggest a bin count
     */
    public HistogramBuilder autoBinX(boolean autoBinX) {
      this.autoBinX = autoBinX;
      return this;
    }

    public HistogramBuilder autoBinY(boolean autoBinY) {
      this.autoBinY = autoBinY;
      return this;
    }

    public HistogramBuilder marker(Marker marker) {
      this.marker = marker;
      return this;
    }

    @Override
    public HistogramBuilder opacity(double opacity) {
      super.opacity(opacity);
      return this;
    }

    public HistogramBuilder horizontal(boolean horizontal) {
      this.horizontal = horizontal;
      return this;
    }

    @Override
    public HistogramBuilder showLegend(boolean b) {
      super.showLegend(b);
      return this;
    }

    /**
     * Specifies the type of normalization used for this histogram trace. If "", the span of each
     * bar corresponds to the number of occurrences (i.e. the number of data points lying inside the
     * bins). If "percent" / "probability", the span of each bar corresponds to the percentage /
     * fraction of occurrences with respect to the total number of sample points (here, the sum of
     * all bin HEIGHTS equals 100% / 1). If "density", the span of each bar corresponds to the
     * number of occurrences in a bin divided by the size of the bin interval (here, the sum of all
     * bin AREAS equals the total number of sample points). If "probability density", the area of
     * each bar corresponds to the probability that an event will fall into the corresponding bin
     * (here, the sum of all bin AREAS equals 1).
     *
     * @param histNorm The normalization type for the histogram
     * @return This HistogramBuilder
     */
    public HistogramBuilder histNorm(HistNorm histNorm) {
      this.histNorm = histNorm;
      return this;
    }

    /**
     * Specifies the binning function used for this histogram trace. If "count", the histogram
     * values are computed by counting the number of values lying inside each bin. If "sum", "avg",
     * "min", "max", the histogram values are computed using the sum, the average, the minimum or
     * the maximum of the values lying inside each bin respectively.
     *
     * @param histFunc The function type
     * @return This HistogramBuilder
     */
    public HistogramBuilder histFunc(HistFunc histFunc) {
      this.histFunc = histFunc;
      return this;
    }

    @Override
    public HistogramBuilder name(String name) {
      super.name(name);
      return this;
    }

    @Override
    public HistogramBuilder xAxis(String xAxis) {
      super.xAxis(xAxis);
      return this;
    }

    @Override
    public HistogramBuilder yAxis(String yAxis) {
      super.yAxis(yAxis);
      return this;
    }

    public HistogramBuilder y(double[] y) {
      this.y = doublesToObjects(y);
      return this;
    }

    public HistogramBuilder y(NumericColumn<? extends Number> values) {
      this.y = values.asObjectArray();
      return this;
    }

    public HistogramTrace build() {
      return new HistogramTrace(this);
    }

    @Override
    protected String getType() {
      return type;
    }
  }

  private static Object[] doublesToObjects(double[] doubles) {<FILL_FUNCTION_BODY>

    Object[] objects = new Object[doubles.length];
    for (int i = 0; i < doubles.length; i++) {
      objects[i] = doubles[i];
    }
    return objects;
  
<methods>public void <init>(tech.tablesaw.plotly.traces.TraceBuilder) ,public tech.tablesaw.plotly.components.HoverLabel hoverLabel() ,public java.lang.String name() ,public boolean showLegend() ,public java.lang.String toString() <variables>protected static final double DEFAULT_OPACITY,protected static final tech.tablesaw.plotly.traces.AbstractTrace.Visibility DEFAULT_VISIBILITY,protected final PebbleEngine engine,private final non-sealed tech.tablesaw.plotly.components.HoverLabel hoverLabel,private final non-sealed java.lang.String[] ids,private final non-sealed java.lang.String legendGroup,private final non-sealed java.lang.String name,private final non-sealed double opacity,private final non-sealed java.lang.Boolean showLegend,protected final non-sealed java.lang.String type,private final non-sealed tech.tablesaw.plotly.traces.AbstractTrace.Visibility visible,private final non-sealed java.lang.String xAxis,private final non-sealed java.lang.String yAxis