将自定义行添加到JavaFX LineChart
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将自定义行添加到JavaFX LineChart相关的知识,希望对你有一定的参考价值。
我正在使用Java FX折线图来绘制蛋白质结构但是我在这个图表上试图表示“健身债券”时遇到了麻烦(这是两个疏水酸相距1个单位的距离,但没有依次连接,如下面的链接所示)。
This is what my chart looks like now.
This is what I am trying to get my chart to look like.
我的健身债券是在List<Pair<Point, Point>>
举行的。
例如,我需要做类似的事情:
for (Pair<Point, Point> pair : pointPairs) {
//draw red line from pair.getKey() to pair.getValue()
}
健身粘合可以是水平或垂直线。
如何在每个点对之间的图表上直接获取此点对列表并绘制自定义线?
答案
这可以通过每个线段使用单独的Series
来实现。备查;如果你提供一个最小的,可运行的问题示例,那将是最有帮助的。
以下是基于您的要求的示例:
fitness B你当时.Java:
包装申请;
import static java.util.stream.Collectors.toList;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Point2D;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class FitnessBonds extends Application
{
public static void main( final String[] args )
{
Application.launch( args );
}
@Override
public void start( final Stage primaryStage )
{
final XYChart.Series<Number, Number> series1 = new XYChart.Series<>();
series1.setData( FXCollections.observableArrayList(
createData( 0, 0 ),
createData( 1, 0 ),
createData( 1, -1 ),
createData( 0, -1 ),
createData( 0, -2 ),
createData( 1, -2 ),
createData( 2, -2 ),
createData( 2, -1 ),
createData( 3, -1 ),
createData( 3, 0 ),
createData( 4, 0 ),
createData( 4, -1 ),
createData( 4, -2 ),
createData( 3, -2 ),
createData( 3, -3 ),
createData( 3, -4 ),
createData( 2, -4 ),
createData( 1, -4 ),
createData( 1, -3 ),
createData( 2, -3 ) ) );
final List<XYChart.Series<Number, Number>> bonds = bruteForceSearchUnconnectedNodesOneDistance( series1.getData().stream()
.map( data -> new Point2D( data.getXValue().doubleValue(), data
.getYValue().doubleValue() ) )
.collect( toList() ) );
final ObservableList<XYChart.Series<Number, Number>> series = FXCollections
.observableArrayList( series1 );
series.addAll( bonds );
final NumberAxis xAxis = new NumberAxis();
xAxis.setLowerBound( -2 );
xAxis.setUpperBound( 5 );
xAxis.setAutoRanging( false );
final NumberAxis yAxis = new NumberAxis();
yAxis.setLowerBound( -5 );
yAxis.setUpperBound( 5 );
yAxis.setAutoRanging( false );
final LineChart lineChart = new LineChart<>( xAxis, yAxis,
series );
lineChart.setCreateSymbols( true );
lineChart.setAnimated( true );
lineChart.setAxisSortingPolicy( LineChart.SortingPolicy.NONE );
lineChart.setPadding( new Insets( 32 ) );
final Scene scene = new Scene( new StackPane( lineChart ) );
scene.getStylesheets().add( FitnessBonds.class.getResource( "fit.css" ).toExternalForm() );
primaryStage.setScene( scene );
primaryStage.show();
}
private List<XYChart.Series<Number, Number>> bruteForceSearchUnconnectedNodesOneDistance( final List<Point2D> data )
{
if ( data.size() < 2 )
{
return Collections.emptyList();
}
final List<XYChart.Series<Number, Number>> list = new ArrayList<>();
for ( int i = 1; i < data.size(); ++i )
{
try
{
final Point2D previousNode = data.get( i - 1 );
final Point2D nextNode = data.get( i + 1 );
final Point2D node = data.get( i );
final List<Point2D> allAround = getAllAroundDistanceOne( node );
allAround.stream()
.filter( data::contains )
.filter( point -> !nextNode.equals( point ) )
.filter( point -> !previousNode.equals( point ) )
//FIXME this does not eliminate duplicates
.forEach( point -> list.add( new XYChart.Series<>( FXCollections.observableArrayList(
createBondData( node.getX(), node.getY() ),
createBondData( point.getX(), point.getY() ) ) ) ) );
}
catch ( final IndexOutOfBoundsException exception )
{
continue;
}
}
return list;
}
private List<Point2D> getAllAroundDistanceOne( final Point2D node )
{
return Stream.of(
new Point2D( 0, 1 ),
new Point2D( 1, 0 ),
new Point2D( 0, -1 ),
new Point2D( -1, 0 ) )
.map( node::add )
.collect( toList() );
}
private XYChart.Data<Number, Number> createData( final double x, final double y )
{
final XYChart.Data<Number, Number> data = new XYChart.Data<>( x, y );
data.setNode( new Circle( 4, Color.BLUE ) );
return data;
}
private XYChart.Data<Number, Number> createBondData( final double x, final double y )
{
final XYChart.Data<Number, Number> data = new XYChart.Data<>( x, y );
data.setNode( new Circle( 6, Color.GREEN ) );
return data;
}
}
fit.css:
.default-color0.chart-series-line { -fx-stroke: black; }
请注意,根据您的描述
这是当两个疏水酸彼此相距1个单位但没有顺序连接时,如下面的链接所示)
你的例子中应该有更多的链接。我只能假设构成“健身纽带”的限制更加严格。但在我的例子中,您将看到更多链接。
以上是关于将自定义行添加到JavaFX LineChart的主要内容,如果未能解决你的问题,请参考以下文章
Xamarin.Forms 条目 - 自定义行为和 MVVM