У меня есть барчат с 5 полосами, теперь я пытаюсь переместить каждую полосу слева направо на основе высокого значения (больше похоже на гонку на гистограмме от flouri sh @ https://app.flourish.studio ) не то же самое, но идея та же.
Чтобы сравнить маленькие числа с большими числами и большие числа с маленькими числами, я использую случайные целые числа.
Например, если barE больше затем все столбцы и меньше, чем barA, он должен переместиться на номер 2 и заменить столбец B. Я использую «оператор if», чтобы попытаться выполнить sh это. Проблема в том, что происходит только один переход - первый. Когда случайные числа меняются каждые 3 секунды, правильный переход не происходит. Кто-нибудь знает, как я могу исправить эту проблему?
import java.util.Calendar;
import java.util.TimeZone;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.value.ChangeListener;
import javafx.geometry.Bounds;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.chart.BarChart;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class App extends Application {
private ScheduledExecutorService scheduledExecutorService;
final static String austria = "Austria", brazil = "Brazil", france = "France", england = "England", belgium = "Belgium";
private IntegerProperty secondA, secondB , secondC, secondD, secondE;
private Text secondAText, secondBText , secondCText, secondDText, secondEText;
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("Realtime Bar Chart Demo");
//defining the axes
final CategoryAxis xAxis = new CategoryAxis();
final NumberAxis yAxis = new NumberAxis();
xAxis.setAnimated(false);
yAxis.setAnimated(false);
//creating the bar chart with two axis
final BarChart<String,Number> bc = new BarChart<>(xAxis,yAxis);
bc.setAnimated(false);
bc.setTitle("Country Summary");
xAxis.setLabel("Country");
yAxis.setLabel("Value");
//defining a series to display data
XYChart.Series<String, Number> seriesA = new XYChart.Series<>();
Data<String, Number> dataA = new XYChart.Data<>(austria,0);
seriesA.getData().add(dataA);
seriesA.setName("Austra");
secondA = new SimpleIntegerProperty(0);
secondAText = new Text("");
secondA.addListener((ChangeListener<Number>) (observable, oldValue, newValue) -> {
dataA.setYValue(newValue);
secondAText.setText(String.valueOf(newValue));
});
XYChart.Series<String, Number> seriesB = new XYChart.Series<>();
Data<String, Number> dataB = new XYChart.Data<>(brazil,0);
seriesB.getData().add(dataB);
seriesB.setName("Brazil");
secondB = new SimpleIntegerProperty(0);
secondB.bind(secondA.add(0));
secondBText = new Text("");
secondB.addListener((ChangeListener<Number>) (observable, oldValue, newValue) -> {
dataB.setYValue(newValue);
secondBText.setText(String.valueOf(newValue));
});
XYChart.Series<String, Number> seriesC = new XYChart.Series<>();
Data<String, Number> dataC = new XYChart.Data<>(france,0);
seriesC.getData().add(dataC);
seriesC.setName("France");
secondC = new SimpleIntegerProperty(0);
secondC.bind(secondA.add(0));
secondCText = new Text("");
secondC.addListener((ChangeListener<Number>) (observable, oldValue, newValue) -> {
dataC.setYValue(newValue);
secondCText.setText(String.valueOf(newValue));
});
XYChart.Series<String, Number> seriesD = new XYChart.Series<>();
Data<String, Number> dataD = new XYChart.Data<>(england,0);
seriesD.getData().add(dataD);
seriesD.setName("England");
secondD = new SimpleIntegerProperty(0);
secondD.bind(secondA.add(0));
secondDText = new Text("");
secondD.addListener((ChangeListener<Number>) (observable, oldValue, newValue) -> {
dataD.setYValue(newValue);
secondDText.setText(String.valueOf(newValue));
});
XYChart.Series<String, Number> seriesE = new XYChart.Series<>();
Data<String, Number> dataE = new XYChart.Data<>(belgium,0);
seriesE.getData().add(dataE);
seriesE.setName("Belgium");
secondE = new SimpleIntegerProperty(0);
secondE.bind(secondA.add(0));
secondEText = new Text("");
secondE.addListener((ChangeListener<Number>) (observable, oldValue, newValue) -> {
dataE.setYValue(newValue);
secondEText.setText(String.valueOf(newValue));
});
// add series to chart
bc.getData().add(seriesA);
bc.getData().add(seriesB);
bc.getData().add(seriesC);
bc.getData().add(seriesD);
bc.getData().add(seriesE);
displayLabelForData(dataA, secondAText);
displayLabelForData(dataB, secondBText);
displayLabelForData(dataC, secondCText);
displayLabelForData(dataD, secondDText);
displayLabelForData(dataE, secondEText);
// setup scene
Scene scene = new Scene(bc, 800, 600);
primaryStage.setScene(scene);
// show the stage
primaryStage.show();
// setup a scheduled executor to periodically put data into the chart
scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
// input data onto graph per second scheduledExecutorService.scheduleAtFixedRate(() -> {
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
double posA = dataA.getNode().localToScene(dataA.getNode().getBoundsInLocal()).getMinX();
double posB = dataB.getNode().localToScene(dataB.getNode().getBoundsInLocal()).getMinX();
double posC = dataC.getNode().localToScene(dataC.getNode().getBoundsInLocal()).getMinX();
double posD = dataD.getNode().localToScene(dataD.getNode().getBoundsInLocal()).getMinX();
double posE = dataE.getNode().localToScene(dataE.getNode().getBoundsInLocal()).getMinX();
TranslateTransition ttA = new TranslateTransition(Duration.millis(2000), dataA.getNode());
TranslateTransition ttB = new TranslateTransition(Duration.millis(2000), dataB.getNode());
TranslateTransition ttC = new TranslateTransition(Duration.millis(2000), dataC.getNode());
TranslateTransition ttD = new TranslateTransition(Duration.millis(2000), dataD.getNode());
TranslateTransition ttE = new TranslateTransition(Duration.millis(2000), dataE.getNode());
//Genarate random numbers
Integer randomB = ThreadLocalRandom.current().nextInt(60);
Integer randomC = ThreadLocalRandom.current().nextInt(60);
Integer randomD = ThreadLocalRandom.current().nextInt(60);
Integer randomE = ThreadLocalRandom.current().nextInt(60);
int intSecondB = secondB.bind(secondA.add(randomB));
int intSecondC = secondC.bind(secondA.add(randomC));
int intSecondD = secondD.bind(secondA.add(randomD));
int intSecondE = secondE.bind(secondA.add(randomE));
Я не уверен, что проблема связана с приведенными ниже операторами if или самим кодом. Чтобы код не был более длинным, я включил только операторы if, которые сравнивают только seriesB (barB) с другими барами.
//using if statement to swich each bar based on value
if (intSecondB >= intSecondA && intSecondB >= intSecondB && intSecondB >= intSecondC && intSecondB >= intSecondD && intSecondB >= intSecondE) {
double diffBA = posB - posA;
ttA.setByX(diffBA);
ttB.setByX(-diffBA);
ttA.setCycleCount(1);
ttA.setAutoReverse(true);
ttA.play();
ttB.setCycleCount(1);
ttB.setAutoReverse(true);
ttB.play();
}
if (intSecondB < intSecondA && intSecondB >= intSecondC && intSecondB >= intSecondD && intSecondB >= intSecondE) {
System.out.println("keep seriesB(barB) at its position");
}
if (intSecondB < intSecondA && intSecondB < intSecondC && intSecondB >= intSecondD && intSecondB >= intSecondE) {
double diffCB = posC - posB;
ttB.setByX(diffCB);
ttC.setByX(-diffCB);
ttB.setCycleCount(1);
ttB.setAutoReverse(true);
ttB.play();
ttC.setCycleCount(1);
ttC.setAutoReverse(true);
ttC.play();
}
if (intSecondB < intSecondA && intSecondB < intSecondC && intSecondB < intSecondD && intSecondB >= intSecondE) {
double diffDB = posD - posB;
ttB.setByX(diffDB);
ttD.setByX(-diffDB);
ttB.setCycleCount(1);
ttB.setAutoReverse(true);
ttB.play();
ttD.setCycleCount(1);
ttD.setAutoReverse(true);
ttD.play();
}
if (intSecondB < intSecondA && intSecondB < intSecondC && intSecondB < intSecondD && intSecondB < intSecondE) {
double diffEB = posE - posB;
ttB.setByX(diffEB);
ttE.setByX(-diffEB);
ttB.setCycleCount(1);
ttB.setAutoReverse(true);
ttB.play();
ttE.setCycleCount(1);
ttE.setAutoReverse(true);
ttE.play();
}
if (intSecondB < intSecondA && intSecondB < intSecondC && intSecondB < intSecondD && intSecondB < intSecondE) {
double diffFB = posF - posB;
ttB.setByX(diffFB);
ttF.setByX(-diffFB);
ttB.setCycleCount(1);
ttB.setAutoReverse(true);
ttB.play();
ttF.setCycleCount(1);
ttF.setAutoReverse(true);
ttF.play();
}
if (intSecondB < intSecondA && intSecondB < intSecondC && intSecondB < intSecondD && intSecondB < intSecondE) {
double diffGB = posG - posB;
ttB.setByX(diffGB);
ttG.setByX(-diffGB);
ttB.setCycleCount(1);
ttB.setAutoReverse(true);
ttB.play();
ttG.setCycleCount(1);
ttG.setAutoReverse(true);
ttG.play();
}
if (intSecondB < intSecondA && intSecondB < intSecondC && intSecondB < intSecondD && intSecondB < intSecondE) {
double diffHB = posH - posB;
ttB.setByX(diffHB);
ttH.setByX(-diffHB);
ttB.setCycleCount(1);
ttB.setAutoReverse(true);
ttB.play();
ttH.setCycleCount(1);
ttH.setAutoReverse(true);
ttH.play();
}
if (intSecondB < intSecondA && intSecondB < intSecondC && intSecondB < intSecondD && intSecondB < intSecondE) {
double diffIB = posI - posB;
ttB.setByX(diffIB);
ttI.setByX(-diffIB);
ttB.setCycleCount(1);
ttB.setAutoReverse(true);
ttB.play();
ttI.setCycleCount(1);
ttI.setAutoReverse(true);
ttI.play();
}
if (intSecondB < intSecondA && intSecondB < intSecondC && intSecondB < intSecondD && intSecondB < intSecondE) {
double diffJB = posJ - posB;
ttB.setByX(diffJB);
ttJ.setByX(-diffJB);
ttB.setCycleCount(1);
ttB.setAutoReverse(true);
ttB.play();
ttJ.setCycleCount(1);
ttJ.setAutoReverse(true);
ttJ.play();
}
// Update the chart
Platform.runLater(() -> {
secondA.set( cal.get(Calendar.SECOND));
});
}, 0, 3, TimeUnit.SECONDS);
}
@Override
public void stop() throws Exception {
super.stop();
scheduledExecutorService.shutdownNow();
}
private void displayLabelForData(XYChart.Data<String, Number> data, Text text) {
final Node node = data.getNode();
((Group) node.getParent()).getChildren().add(text);
node.boundsInParentProperty().addListener((ChangeListener<Bounds>) (ov, oldBounds, bounds) -> {
text.setLayoutX(
Math.round( bounds.getMinX() + bounds.getWidth() / 2 - text.prefWidth(-1) / 2));
text.setLayoutY(Math.round( bounds.getMinY() - text.prefHeight(-1) * 0.5));
});
}
public static void main(String[] args) {
launch(args);
}
}
Любая помощь будет принята с благодарностью!