JavaFX 차트를 사용하여 스택 된 영역 차트의 y 축을 반전시켜 양수 0이 맨 위에 있고 양수가 y 축에서 아래쪽으로 오도록해야합니다. 아래는 내가 달성하고자하는 것의 모형입니다.반전 된 Y 축이있는 차트
최고 (읽기 : 짧은 개발 시간과 높은 코드 재사용) 란 자바 FX에서 이것을 달성하기 위해 방법은? 음수로 데이터를 변환
UPDATE
를 선택할 수 없습니다. 긍정적 인 숫자 인 "손길이 닿지 않는"답변을 찾고 있습니다.
JavaFX 차트를 사용하여 스택 된 영역 차트의 y 축을 반전시켜 양수 0이 맨 위에 있고 양수가 y 축에서 아래쪽으로 오도록해야합니다. 아래는 내가 달성하고자하는 것의 모형입니다.반전 된 Y 축이있는 차트
최고 (읽기 : 짧은 개발 시간과 높은 코드 재사용) 란 자바 FX에서 이것을 달성하기 위해 방법은? 음수로 데이터를 변환
UPDATE
를 선택할 수 없습니다. 긍정적 인 숫자 인 "손길이 닿지 않는"답변을 찾고 있습니다.
음수 값을 가진 일반 축을 사용할 수 있지만 빼기 기호를 제거하는 TickLabelFormatter
을 추가하십시오.
final NumberAxis yAxis = new NumberAxis(-25, 0, 5);
yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis) {
@Override
public String toString(Number value) {
// note we are printing minus value
return String.format("%7.1f", -value.doubleValue());
}
});
series1.getData().add(new XYChart.Data("Jan", -1));
series1.getData().add(new XYChart.Data("Feb", -5));
series1.getData().add(new XYChart.Data("Mar", -20));
하지 쉬운 옵션은 축에 inverse()
동작을 가능하게하는 것입니다. JRE 클래스에 패치를 적용하지 않으면 매우 복잡합니다.
이 접근하는 방법에 대한 몇 가지 힌트 :
1) 확장 ValueAxis 또는 축 (NumberAxis이
2) 축 클래스에 부울 필드와 inverse()
방법을 추가) 불행하게도 최종
public void inverse() {
inversed = !inversed; // boolean property
invalidateRange();
requestAxisLayout();
}
3) ValueAxis를 확장 한 경우 - 수퍼 클래스에서 적용된 오프셋을 보정해야합니다 (축 크기가 변경되는 코드를 가로 채기).
@Override
public Long getValueForDisplay(double displayPosition) {
if (inversed)
return super.getValueForDisplay(offset - displayPosition);
else
return super.getValueForDisplay(displayPosition);
}
@Override
public double getDisplayPosition(Long value) {
if (inversed)
return offset - super.getDisplayPosition(value);
else
return super.getDisplayPosition(value);
}
4) (가장 못했던 부분) 숨기기 레이블 틱이 Axis 클래스에 의해 숨김 - 원래 구현은 틱의 기본 순서에 따라 달라집니다. 리플렉션을 통해 잠금을 해제하는 다른 방법을 찾지 못했습니다. 그래서 이것은 매우 부서지기 쉽습니다.
@Override
protected void layoutChildren() {
final Side side = getSide();
boolean isHorisontal = null == side || side.isHorizontal();
this.offset = isHorisontal ? getWidth() : getHeight();
super.layoutChildren();
if (inversed) {
double prevEnd = isHorisontal ? offset + getTickLabelGap() : 0;
for (TickMark m : getTickMarks()) {
double position = m.getPosition();
try {
final Text textNode = (Text) textNodeField.get(m);
final Bounds bounds = textNode.getLayoutBounds();
if (0 <= position && position <= offset)
if (isHorisontal) {
textNode.setVisible(position < prevEnd);
prevEnd = position - (bounds.getWidth() + getTickLabelGap());
} else {
textNode.setVisible(position > prevEnd);
prevEnd = position + (bounds.getHeight() + getTickLabelGap());
}
} catch (IllegalAccessException ignored) {
}
}
}
}
사용 특성 LOWERBOUND와 축 UPPERBOUND 반전된다. lowerBound는 upperBound보다 커야합니다. fxml을 사용하는 방법은 다음과 같습니다.
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<HBox
prefHeight="600.0"
prefWidth="800.0"
xmlns:fx="http://javafx.com/fxml/1">
<javafx.scene.chart.LineChart
fx:id="chart" >
<xAxis >
<javafx.scene.chart.NumberAxis
label="X Axis"
lowerBound="0.01"
upperBound="100"
tickUnit="10"
autoRanging="false" />
</xAxis>
<yAxis>
<javafx.scene.chart.NumberAxis
label="Y Axis"
lowerBound="100"
upperBound="0.001"
tickUnit="10"
autoRanging="false"
/>
</yAxis>
</javafx.scene.chart.LineChart>
</Hbox>
차트에서 사용하기 전에 모든 데이터를 음수로 변환 할 것을 제안합니까? – mawcsco
예. 가장 좋은 방법은 아니지만 반전 기능으로 차트를 훨씬 빠르게 확장 할 수 있습니다. 데이터를 직접 업데이트하지 않으려면 반전 논리를 사용하여'XYChart.Data' 클래스를 확장하거나 차트에 반전 된 숫자를 추가하는 유틸리티 메소드를 도입하십시오. –