JavaFX面积图100%直线
好的,你们都往外看。我需要一些帮助在面积图上的100刻度点添加一条暗线 正如你从100号的图片上看到的,我需要一条线穿过这张纸,告诉每个人他们是否在100%的生产。这100人的位置可以在任何给定的一周内改变。有时最高值不是170,但可能是150左右。我当前的代码如下所示,但它只是在测试这一点(它也不能正常工作) 正在做。 我以前解决这个问题的方式不同。我使用未经修改的图表,而是将组件添加到“.chart content”窗格中。然后使用坐标变换将其与“.plot area”组件对齐。这是这种方法的一个完全有效的例子JavaFX面积图100%直线,java,javafx,Java,Javafx,好的,你们都往外看。我需要一些帮助在面积图上的100刻度点添加一条暗线 正如你从100号的图片上看到的,我需要一条线穿过这张纸,告诉每个人他们是否在100%的生产。这100人的位置可以在任何给定的一周内改变。有时最高值不是170,但可能是150左右。我当前的代码如下所示,但它只是在测试这一点(它也不能正常工作) 正在做。 我以前解决这个问题的方式不同。我使用未经修改的图表,而是将组件添加到“.chart content”窗格中。然后使用坐标变换将其与“.plot area”组件对齐。这是这种方
public class Horse extends Application {
public static void main(String args[]) {
launch(args);
}
private Line line;
private NumberAxis yAxis;
private Region plotArea;
private Pane chartContent;
@Override
public void start(Stage primaryStage) throws Exception {
final CategoryAxis xAxis = new CategoryAxis();
yAxis = new NumberAxis();
final AreaChart<String, Number> chart = new AreaChart<String, Number>(xAxis, yAxis);
Series<String, Number> series = new Series<>();
series.getData().add(new Data<>("foo", 50));
series.getData().add(new Data<>("bar", 25));
series.getData().add(new Data<>("baz", 125));
chart.getData().add(series);
plotArea = (Region) chart.lookup(".chart-plot-background");
chartContent = (Pane) chart.lookup(".chart-content");
line = new Line();
chartContent.getChildren().add(line);
primaryStage.setScene(new Scene(chart));
primaryStage.show();
chart.boundsInParentProperty().addListener((obs, oldValue, newValue) -> {
update();
});
plotArea.boundsInLocalProperty().addListener((obs, oldValue, newValue) -> {
update();
});
update();
}
private void update() {
double location = yAxis.getDisplayPosition(100);
Point2D a = plotArea.localToScene(new Point2D(0, location));
Point2D b = plotArea.localToScene(new Point2D(plotArea.getWidth(), location));
Point2D aTrans = chartContent.sceneToLocal(a);
Point2D bTrans = chartContent.sceneToLocal(b);
line.setStartX(aTrans.getX());
line.setStartY(aTrans.getY());
line.setEndX(bTrans.getX());
line.setEndY(bTrans.getY());
}
}
公共类扩展应用程序{
公共静态void main(字符串参数[]){
发射(args);
}
专线;
私人号码xis yAxis;
私人区域;
私人内容;
@凌驾
public void start(Stage primaryStage)引发异常{
最终CategoryAxis xAxis=新CategoryAxis();
yAxis=新的数字Axis();
最终面积图=新面积图(xAxis,yAxis);
系列=新系列();
series.getData().add(新数据(“foo”,50));
series.getData().add(新数据(“bar”,25));
series.getData().add(新数据(“baz”,125));
chart.getData().add(系列);
plotArea=(区域)chart.lookup(“.chart-plot-background”);
chartContent=(窗格)chart.lookup(“.chart content”);
行=新行();
chartContent.getChildren().add(行);
初始阶段。设置场景(新场景(图表));
primaryStage.show();
chart.boundsInParentProperty().addListener((obs、oldValue、newValue)->{
更新();
});
plotArea.boundsInLocalProperty().addListener((obs、oldValue、newValue)->{
更新();
});
更新();
}
私有void更新(){
双位置=yAxis.getDisplayPosition(100);
Point2D a=plotArea.localToScene(新的Point2D(0,位置));
Point2D b=plotArea.localToScene(新的Point2D(plotArea.getWidth(),location));
Point2D aTrans=chartContent.sceneToLocal(a);
Point2D bTrans=chartContent.sceneToLocal(b);
line.setStartX(aTrans.getX());
line.setStartY(aTrans.getY());
line.setEndX(bTrans.getX());
line.setEndY(bTrans.getY());
}
}
您正在使用getValueForDisplay()
将像素值转换为轴值。要使用getDisplayPosition()
将轴值转换为像素值
替换
Double y = Double.valueOf(getYAxis().getValueForDisplay(100.0).toString());
与
SSCCE:
import java.util.Random;
import java.util.stream.Collectors;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
public class LineChartWithHorizontal extends Application {
@Override
public void start(Stage primaryStage) {
LineChart<String, Number> chart = new LineChart<String, Number>(new CategoryAxis(), new NumberAxis()) {
// Line line = new Line();
//
// @Override
// protected void layoutPlotChildren() {
// super.layoutPlotChildren();
// getPlotChildren().remove(line);
// line.setStartX(0);
// line.setEndX(600);
// double y = getYAxis().getDisplayPosition(100.0);
// line.setStartY(y);
// line.setEndY(y);
// getPlotChildren().add(line);
// }
@Override
protected void layoutPlotChildren() {
super.layoutPlotChildren();
ObservableList<Node> removeable = FXCollections.observableArrayList();
removeable.addAll(getPlotChildren().stream().filter(node -> node instanceof Line).collect(Collectors.toList()));
getPlotChildren().removeAll(removeable);
double y = getYAxis().getDisplayPosition(100.0);
System.out.println(y);
Line line = new Line();
line.setStartX(0.0);
line.setStartY(y);
line.setEndX(600.0);
line.setEndY(y);
getPlotChildren().add(line);
}
};
Random rng = new Random();
for (int i = 1 ; i <= 4; i++) {
Series<String, Number> s = new Series<>();
s.setName("Data "+i);
chart.getData().add(s);
}
for (int i = 1 ; i <= 6; i++) {
for (int s = 0 ; s < 4 ; s++) {
chart.getData().get(s).getData().add(new Data<>("Item "+i, rng.nextDouble()*200));
}
}
primaryStage.setScene(new Scene(chart, 600, 600));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
import java.util.Random;
导入java.util.stream.collector;
导入javafx.application.application;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.scene.Node;
导入javafx.scene.scene;
导入javafx.scene.chart.CategoryAxis;
导入javafx.scene.chart.LineChart;
导入javafx.scene.chart.NumberAxis;
导入javafx.scene.chart.XYChart.Data;
导入javafx.scene.chart.XYChart.Series;
导入javafx.scene.shape.Line;
导入javafx.stage.stage;
带有水平扩展应用程序的公共类LineChart{
@凌驾
公共无效开始(阶段primaryStage){
线形图=新线形图(新类别Axis(),新编号Axis()){
//行=新行();
//
//@覆盖
//受保护的无效layoutPlotChildren(){
//super.layoutPlotChildren();
//getPlotChildren()。删除(行);
//行。设置开始x(0);
//行。setEndX(600);
//双y=getYAxis().getDisplayPosition(100.0);
//行。设置开始(y);
//行。setEndY(y);
//getPlotChildren().add(行);
// }
@凌驾
受保护的无效layoutPlotChildren(){
super.layoutPlotChildren();
ObservableList removeable=FXCollections.observableArrayList();
addAll(getPlotChildren().stream().filter(node->node instanceof Line).collect(Collectors.toList());
getPlotChildren().removeAll(可移除);
双y=getYAxis().getDisplayPosition(100.0);
系统输出打印项次(y);
行=新行();
行。设置起点x(0.0);
行。设置开始(y);
行setEndX(600.0);
行。setEndY(y);
getPlotChildren().add(行);
}
};
随机rng=新随机();
对于(int i=1;i),它看起来应该可以工作,不过您通常会执行double y=getYAxis().getValueForDisplay(100.0)
,而不是转换为字符串以便将其转换回double。您是否可以将示例扩展为?getYAxis().getValueForDisplay(100.0)返回类型为Y的FX对象。Y是任意轴(在我的例子中是NumberAxis)。没有将其转换为double(我无论如何都看到了)的转换,因此我将其转换为字符串(无论何时打印Y,它都会打印看起来像double的数字)然后是双精度。关于这个例子,呃,我们将看看我今天下班后能做些什么。哦,我明白了。你想要getDisplayPosition
。你正在将像素坐标ls转换为轴值,而不是将轴值转换为像素坐标。谢谢亚当,我感谢你的回答。我实际上忽略了“getDisplayPosition”这正是我工作所需要的。是的,我通过阅读每个人的帖子注意到了。谢谢你的帮助问题解决了(最后)。我的问题与你的代码略有不同,只是因为我为AreaChart创建了一个单独的类,并且需要通用参数(而不是字符串和数字)因为我在多个图表中使用它,但我只是
Double y = Double.valueOf(getYAxis().getValueForDisplay(100.0).toString());
double y = getYAxis().getDisplayPosition(100.0);
import java.util.Random;
import java.util.stream.Collectors;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart.Data;
import javafx.scene.chart.XYChart.Series;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
public class LineChartWithHorizontal extends Application {
@Override
public void start(Stage primaryStage) {
LineChart<String, Number> chart = new LineChart<String, Number>(new CategoryAxis(), new NumberAxis()) {
// Line line = new Line();
//
// @Override
// protected void layoutPlotChildren() {
// super.layoutPlotChildren();
// getPlotChildren().remove(line);
// line.setStartX(0);
// line.setEndX(600);
// double y = getYAxis().getDisplayPosition(100.0);
// line.setStartY(y);
// line.setEndY(y);
// getPlotChildren().add(line);
// }
@Override
protected void layoutPlotChildren() {
super.layoutPlotChildren();
ObservableList<Node> removeable = FXCollections.observableArrayList();
removeable.addAll(getPlotChildren().stream().filter(node -> node instanceof Line).collect(Collectors.toList()));
getPlotChildren().removeAll(removeable);
double y = getYAxis().getDisplayPosition(100.0);
System.out.println(y);
Line line = new Line();
line.setStartX(0.0);
line.setStartY(y);
line.setEndX(600.0);
line.setEndY(y);
getPlotChildren().add(line);
}
};
Random rng = new Random();
for (int i = 1 ; i <= 4; i++) {
Series<String, Number> s = new Series<>();
s.setName("Data "+i);
chart.getData().add(s);
}
for (int i = 1 ; i <= 6; i++) {
for (int s = 0 ; s < 4 ; s++) {
chart.getData().get(s).getData().add(new Data<>("Item "+i, rng.nextDouble()*200));
}
}
primaryStage.setScene(new Scene(chart, 600, 600));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}