Dr_Click
Dr_Click

Reputation: 469

How to set the origin baseline of a barchart?

I'd using JavaFX to draw barcharts which represents a sound power. The range of my values are from -60 to +3 dbBF (decibel full scale).

When JavaFX draw the "bars", the baseline is always set to 0 so, my bars are drawn from 0 to +X (above the zero line) or from 0 to -X (below the zero line).

My aim is to get a bar from -60 to -X. Is there a way to set the baseline origin to -60 ? I looked for tips on google and tried few things but nothing worked.

Thank you for your answers.

Upvotes: 0

Views: 73

Answers (1)

Slaw
Slaw

Reputation: 45746

I'm not aware of a way to change the baseline of a JavaFX chart. However, you can make it look like it's starting from -60. The ValueAxis (and by extension, NumberAxis) class has a property for formatting the tick labels: tickLabelFormatter. You can supply your own StringFormatter that makes the labels "off by 60". Here's an example:

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
import javafx.stage.Stage;
import javafx.util.StringConverter;

public class App extends Application {

  @Override
  public void start(Stage primaryStage) throws Exception {
    var scene = new Scene(createChart() 600, 400);
    primaryStage.setScene(scene);
    primaryStage.setTitle("SO-53959031");
    primaryStage.show();
  }

  @SuppressWarnings("unchecked")
  private Series<String, Number> createData() {
    return new Series<>(FXCollections.observableArrayList(
        new Data<>("Test #0", 40),
        new Data<>("Test #1", 20),
        new Data<>("Test #2", 63),
        new Data<>("Test #3", 50),
        new Data<>("Test #4", 30)
    ));
  }

  private BarChart<String, Number> createChart() {
    var yAxis = new NumberAxis("dbBF", 0, 63, 1);
    yAxis.setTickLabelFormatter(new StringConverter<>() {
      @Override
      public String toString(Number object) {
        return Double.toString(object.doubleValue() - 60);
      }

      @Override
      public Number fromString(String string) {
        return Double.valueOf(string) + 60;
      }
    });

    var chart = new BarChart<>(new CategoryAxis(), yAxis);
    chart.getData().add(createData());
    chart.setLegendVisible(false);
    return chart;
  }

}

There's a caveat: You have to translate your data to be zero-based. This only has to be done for the chart's data. In other words, your model can keep the data between -60 and 3 but it has to be translated to be in the range 0 to 63 for the chart.


Screenshot of example:

screenshot of chart

Upvotes: 1

Related Questions