Java – draws a smooth color scale and assigns a specific value to it
I am considering a new implementation, a simple 2D graphics matrix, in which the color of the items depends on the values assigned to these items So far, I have used the following architecture for this purpose:
1) Provide an interval based color code reference (for example, the construction of 20 blocks) for which I can specify a specific value range, for example, 100-1000
2) The color of each value of the link matrix item and the above scale, so the item with a value of 100 will be blue, for example, and the item with a value of 1000 will be red
The problem with this solution is that I have to build my color code from "blocks", so it looks like this:
This solution is not that bad, but I want to go further and achieve more accurate values with the help of color codes - color matching, as shown below:
Next, the above rigs will not be much different I "place" this scale between the values in a given range (e.g. 100-1000), and depending on the individual values of the matrix item, I will select the appropriate color from the scale and assign it to the given item
But how do I draw such a scale and put it within a specific value range, trying to avoid the itemvalue to specificcolorblock matching problem in my old solution?
Solution
In Statistics (visualization), this is called a heat map
To calculate the color of a given value, min < = value < max, I'll insert it into the range color BLUE. getHue() - Color. RED. getHue(). Namely
double hue = Color.BLUE.getHue() + (Color.RED.getHue() - Color.BLUE.getHue()) * (value - MIN) / (MAX - MIN) ;
Then use hue to create a color with full saturation and brightness:
Color color = Color.hsb(hue,1.0,1.0);
To create a color scale image, create a writableimage, grab the pixel writer, iterate over all pixels, set the color of each pixel using the above formula, and interpolate the value along the X axis from 0 to the width of the image (if you want a vertical color scale, also interpolate along the Y axis.)
This is an example of drawing a color code You can use the getcolorforvalue (...) method to calculate the color of a given value to display the matrix
import javafx.application.Application; import javafx.geometry.Orientation; import javafx.scene.Scene; import javafx.scene.image.Image; import javafx.scene.image.ImageView; import javafx.scene.image.PixelWriter; import javafx.scene.image.WritableImage; import javafx.scene.layout.StackPane; import javafx.scene.paint.Color; import javafx.stage.Stage; public class HeatMap extends Application { private final static double MIN = 100 ; private final static double MAX = 1000 ; private final static double BLUE_HUE = Color.BLUE.getHue() ; private final static double RED_HUE = Color.RED.getHue() ; @Override public void start(Stage primaryStage) { Image colorScale = createColorScaleImage(600,120,Orientation.HORIZONTAL); ImageView imageView = new ImageView(colorScale); StackPane root = new StackPane(imageView); Scene scene = new Scene(root,800,400); primaryStage.setScene(scene); primaryStage.show(); } private Color getColorForValue(double value) { if (value < MIN || value > MAX) { return Color.BLACK ; } double hue = BLUE_HUE + (RED_HUE - BLUE_HUE) * (value - MIN) / (MAX - MIN) ; return Color.hsb(hue,1.0); } private Image createColorScaleImage(int width,int height,Orientation orientation) { WritableImage image = new WritableImage(width,height); PixelWriter pixelWriter = image.getPixelWriter(); if (orientation == Orientation.HORIZONTAL) { for (int x=0; x<width; x++) { double value = MIN + (MAX - MIN) * x / width; Color color = getColorForValue(value); for (int y=0; y<height; y++) { pixelWriter.setColor(x,y,color); } } } else { for (int y=0; y<height; y++) { double value = MAX - (MAX - MIN) * y / height ; Color color = getColorForValue(value); for (int x=0; x<width; x++) { pixelWriter.setColor(x,color); } } } return image ; } public static void main(String[] args) { launch(args); } }