java – 绘制平滑的色阶并为其指定特定值
我正在考虑一种新的实现方式,一种简单的2D图形矩阵,其项目的颜色取决于分配给这些项目的各个值.到目前为止,我为此目的使用了以下架构:
1)提供基于区间的色标参考(例如,20个块的构建),我可以为其指定特定的值范围,例如,100-1000. 2)链接矩阵项目各个值与上述比例的颜色,因此值为100的项目将为例如蓝色,值为1000的项目将为红色. 这种解决方案的问题在于我必须从“块”构建我的色标,所以它看起来像这样: 这个解决方案并不是那么糟糕,但我想更进一步,并在色标的帮助下实现更准确的值 – 颜色匹配,如下所示: 接下来,上述钻机将没有太多不同之处.我将这个比例“放”在给定范围的值(例如100-1000)之间,并且取决于矩阵项的单个值,我将从比例中选择适当的颜色并将其分配给给定项. 但是我如何绘制这样的比例并将其放在一个特定值的范围内,试图避免我的旧解决方案中的ItemValue-To-SpecificColorBlock匹配问题? 解决方法
在统计(可视化)中,这称为热图.
要计算给定值的颜色,MIN< = value< MAX,我会将它插入范围Color.BLUE.getHue() - Color.RED.getHue(). 即 double hue = Color.BLUE.getHue() + (Color.RED.getHue() - Color.BLUE.getHue()) * (value - MIN) / (MAX - MIN) ; 然后使用色调创建具有完全饱和度和亮度的颜色: Color color = Color.hsb(hue,1.0,1.0); 要创建颜色比例图像,请创建WritableImage,抓取像素编写器,迭代所有像素,并使用上面的公式设置每个像素的颜色,沿x轴插值的值从0到图像的宽度. (如果你想要一个垂直色标,同样沿y轴插值.) 这是绘制色标的示例.您可以使用getColorForValue(…)方法计算给定值的颜色,以显示矩阵. 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); } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |