Skip to content

Commit

Permalink
Merge pull request #72 from NucodeLabs/LogColor
Browse files Browse the repository at this point in the history
Log color
  • Loading branch information
lilvadim committed Jul 19, 2022
2 parents 3925299 + 6d189e6 commit 6de2183
Show file tree
Hide file tree
Showing 9 changed files with 184 additions and 57 deletions.
3 changes: 2 additions & 1 deletion src/main/java/ru/nucodelabs/data/ves/ExperimentalData.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ru.nucodelabs.data.ves

import jakarta.validation.constraints.DecimalMin
import jakarta.validation.constraints.Max
import jakarta.validation.constraints.Min
import jakarta.validation.constraints.Positive
Expand All @@ -19,7 +20,7 @@ data class ExperimentalData(
@field:Positive val mn2: Double,
@field:Min(0) val amperage: Double,
@field:Min(0) val voltage: Double,
@field:Min(1) val resistanceApparent: Double = rhoA(ab2, mn2, amperage, voltage),
@field:DecimalMin("0.1") val resistanceApparent: Double = rhoA(ab2, mn2, amperage, voltage),
@field:Min(0) @Max(100) val errorResistanceApparent: Double = 5.0,
val isHidden: Boolean = false
)
2 changes: 1 addition & 1 deletion src/main/java/ru/nucodelabs/gem/app/pref/UIPreferences.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ package ru.nucodelabs.gem.app.pref
val VES_CURVES_LEGEND_VISIBLE = Preference("VES_CURVES_LEGEND", false)

@JvmField
val COLOR_MIN_VALUE = Preference("COLOR_MIN_VALUE", 1.0)
val COLOR_MIN_VALUE = Preference("COLOR_MIN_VALUE", 0.1)

@JvmField
val COLOR_MAX_VALUE = Preference("COLOR_MAX_VALUE", 100_000.0)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class PropertyDelegate<T>(val fxProperty: Property<T>) : ReadWriteProperty<Any,
/**
* Binds this property to an observable, automatically unbinding it before if already bound.
*/
infix fun <T> Property<T>.rebindTo(observable: ObservableValue<T>) {
infix fun <T> Property<T>.bindTo(observable: ObservableValue<T>) {
unbind()
bind(observable)
}
Expand Down
96 changes: 67 additions & 29 deletions src/main/java/ru/nucodelabs/gem/view/charts/ColorAxisController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@ import javafx.event.EventHandler
import javafx.fxml.FXML
import javafx.scene.chart.XYChart.Data
import javafx.scene.chart.XYChart.Series
import javafx.scene.control.CheckBox
import javafx.scene.control.ContextMenu
import javafx.scene.control.Spinner
import javafx.scene.control.SpinnerValueFactory
import javafx.scene.control.TextFormatter
import javafx.scene.input.ContextMenuEvent
import javafx.scene.layout.VBox
import javafx.stage.Stage
import javafx.stage.StageStyle
import javafx.util.StringConverter
import ru.nucodelabs.gem.app.pref.*
import ru.nucodelabs.gem.extensions.fx.*
import ru.nucodelabs.gem.extensions.fx.decimalFilter
import ru.nucodelabs.gem.extensions.fx.isValidBy
import ru.nucodelabs.gem.extensions.fx.observableListOf
Expand All @@ -22,13 +25,14 @@ import ru.nucodelabs.gem.view.color.ColorMapper
import ru.nucodelabs.gem.view.control.chart.NucodeNumberAxis
import ru.nucodelabs.gem.view.control.chart.PolygonChart
import ru.nucodelabs.gem.view.control.chart.limitTickLabelsWidth
import ru.nucodelabs.gem.view.control.chart.rangeBinding
import ru.nucodelabs.gem.view.control.chart.log.LogarithmicAxis
import java.net.URL
import java.text.DecimalFormat
import java.util.*
import java.util.prefs.Preferences
import javax.inject.Inject


class ColorAxisController @Inject constructor(
private val colorMapper: ColorMapper,
private val fxPreferences: FXPreferences,
Expand All @@ -37,9 +41,12 @@ class ColorAxisController @Inject constructor(
private val decimalFormat: DecimalFormat
) : AbstractController() {

private val minAndMaxRange = 0.0..100_000.0
private val minAndMaxRange = 0.1..100_000.0
private val segmentsRange = 2..100

@FXML
private lateinit var root: VBox

@FXML
private lateinit var configWindow: Stage

Expand All @@ -52,31 +59,54 @@ class ColorAxisController @Inject constructor(
@FXML
private lateinit var numberOfSegmentsSpinner: Spinner<Int>

@FXML
private lateinit var isLogChkBox: CheckBox

@FXML
private lateinit var ctxMenu: ContextMenu

@FXML
private lateinit var yAxis: NucodeNumberAxis
private lateinit var linearYAxis: NucodeNumberAxis

@FXML
private lateinit var chart: PolygonChart
private lateinit var logYAxis: LogarithmicAxis

@FXML
private lateinit var linearChart: PolygonChart

@FXML
private lateinit var logChart: PolygonChart

override val stage: Stage?
get() = chart.scene.window as Stage?
get() = root.scene.window as Stage?

override fun initialize(location: URL?, resources: ResourceBundle?) {
colorMapper.minValueProperty().addListener { _, _, _ -> update() }
colorMapper.maxValueProperty().addListener { _, _, _ -> update() }
colorMapper.numberOfSegmentsProperty().addListener { _, _, _ -> update() }
colorMapper.logScaleProperty().addListener { _, _, _ -> update() }

linearChart.data = observableListOf()

setupControls()
setupAxis()
setupCharts()
setupAxes()
update()
}

private fun setupAxis() {
yAxis.tickLabelFormatter = stringConverter
yAxis.tickUnitProperty().bind(yAxis.rangeBinding().divide(colorMapper.numberOfSegmentsProperty()))
yAxis.limitTickLabelsWidth(35.0)
private fun setupAxes() {
linearYAxis.lowerBoundProperty() bindTo colorMapper.minValueProperty()
linearYAxis.upperBoundProperty() bindTo colorMapper.maxValueProperty()

logYAxis.lowerBoundProperty() bindTo linearYAxis.lowerBoundProperty()
logYAxis.upperBoundProperty() bindTo linearYAxis.upperBoundProperty()

linearYAxis.tickLabelFormatter = stringConverter
logYAxis.tickLabelFormatter = stringConverter
linearYAxis.limitTickLabelsWidth(35.0)
logYAxis.limitTickLabelsWidth(35.0)

linearYAxis.tickUnitProperty() bindTo (colorMapper.maxValueProperty() - colorMapper.minValueProperty()) / colorMapper.numberOfSegmentsProperty()
}

private fun lazyConfigWindowInitOwner() {
Expand All @@ -97,7 +127,7 @@ class ColorAxisController @Inject constructor(
val step = 10.0
val doubleValueFactory = { pref: Preference<Double> ->
SpinnerValueFactory.DoubleSpinnerValueFactory(
0.0,
0.1,
100_000.0,
preferences.getDouble(pref.key, pref.def),
step
Expand Down Expand Up @@ -135,33 +165,41 @@ class ColorAxisController @Inject constructor(
editor.onAction = EventHandler { if (valid.get()) numberOfSegmentsSpinner.commitValue() }
}

initConfig()
}

private fun setupCharts() {
colorMapper.minValueProperty().bind(minValueSpinner.valueProperty())
colorMapper.maxValueProperty().bind(maxValueSpinner.valueProperty())
colorMapper.numberOfSegmentsProperty().bind(numberOfSegmentsSpinner.valueProperty())
isLogChkBox.isSelected = colorMapper.isLogScale
colorMapper.logScaleProperty().bind(isLogChkBox.selectedProperty())

yAxis.lowerBoundProperty().bind(colorMapper.minValueProperty())
yAxis.upperBoundProperty().bind(colorMapper.maxValueProperty())
linearChart.visibleProperty() bindTo !isLogChkBox.selectedProperty()
linearChart.managedProperty() bindTo linearChart.visibleProperty()

initConfig()
logChart.visibleProperty() bindTo !linearChart.visibleProperty()
logChart.managedProperty() bindTo !linearChart.managedProperty()
}

@Suppress("UNCHECKED_CAST")
private fun update() {
val range = colorMapper.maxValue - colorMapper.minValue
chart.data = colorMapper.segments.map {
Series(
observableListOf(
Data(0.0, colorMapper.minValue + it.from * range),
Data(100.0, colorMapper.minValue + it.from * range),
Data(100.0, colorMapper.minValue + it.to * range),
Data(0.0, colorMapper.minValue + it.to * range)
)
) as Series<Number, Number>
// safe upcast Double : Number
}.toObservableList()

chart.data.forEachIndexed { index, series ->
chart.seriesPolygons[series]?.apply { fill = colorMapper.segments[index].color }
with(if (isLogChkBox.isSelected) logChart else linearChart) {
data.setAll(colorMapper.segments.map {
Series(
observableListOf(
Data(0.0, it.from),
Data(100.0, it.from),
Data(100.0, it.to),
Data(0.0, it.to)
)
) as Series<Number, Number>
// safe upcast Double : Number
}.toObservableList())

data.forEachIndexed { index, series ->
seriesPolygons[series]?.apply { fill = colorMapper.segments[index].color }
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class ModelSectionController @Inject constructor(
colorMapper.maxValueProperty().addListener { _, _, _ -> update() }
colorMapper.minValueProperty().addListener { _, _, _ -> update() }
colorMapper.numberOfSegmentsProperty().addListener { _, _, _ -> update() }
colorMapper.logScaleProperty().addListener { _, _, _ -> update() }
}

private fun update() {
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/ru/nucodelabs/gem/view/color/ColorMapper.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package ru.nucodelabs.gem.view.color

import javafx.beans.property.BooleanProperty
import javafx.beans.property.DoubleProperty
import javafx.beans.property.IntegerProperty
import javafx.scene.paint.Color
Expand All @@ -14,5 +15,8 @@ interface ColorMapper {
fun numberOfSegmentsProperty(): IntegerProperty
val segments: List<Segment>

fun logScaleProperty(): BooleanProperty
var isLogScale: Boolean

data class Segment(val from: Double, val to: Double, val color: Color)
}
Loading

0 comments on commit 6de2183

Please sign in to comment.