I am creating a heatmap chart, using Anychart and their Riskmap as a starting point.
I need to have each square of the heatmap to have a label on it that display a calculated Double value. for Example: "1.654"
Currently it is setup as default that the heat is an array and each name in the array corresponds to a heat integer that you set as so:
data.add(new CustomHeatDataEntry("98%", "50F", 0, "#90caf9"));
the "0" being the location of the heat.....so if you have seven names then beginning with "0" ending in "7"....will call up each name.....example: "Low", "Medium", etc...
but what I need is to run calculations and have each rectangle on the heatmap to show a double value for each row and column. Example: row 1, column 2 are row=50F, column=98%RH....so on for each row column combination calculation.
I am calculating Vapor pressure deficit and the chart will show all the values color coded for each square.
My code so far:
Main method:
private void anychart(){
setContentView(R.layout.activity_vpd_chart);
Objects.requireNonNull(getSupportActionBar()).setTitle("Leaf VPD: Interactive Heatmap Chart");
getSupportActionBar().setBackgroundDrawable(new ColorDrawable(ContextCompat.getColor(this,R.color.sea)));
ConstraintLayout clVPDChart = findViewById(R.id.clVPDChart);
clVPDChart.setBackgroundColor(ContextCompat.getColor(this,R.color.window_background));
AnyChartView anyChartView = findViewById(R.id.any_chart_view);
anyChartView.setProgressBar(findViewById(R.id.progress_bar));
HeatMap riskMap = AnyChart.heatMap();
riskMap.padding(5d, 5d, 5d, 5d);
riskMap.xScroller(true); // ADDS SCROLL BARS
riskMap.xZoom().setToPointsCount(88,false,);
riskMap.yScroller(true); // ADDS SCROLL BARS
riskMap.yZoom().setToPointsCount(4);
riskMap.stroke("1 #fff");
riskMap.hovered()
.stroke("6 #fff")
.fill(new SolidFill("#545f69", 1d))
.labels("{ fontColor: '#fff' }");
riskMap.interactivity().selectionMode(SelectionMode.NONE);
// test out Averages from VPDActivity to logcat
Log.i("Average Air in Anychart", String.valueOf(VPDActivity.DataShare.getAverageAir()));
Log.i("Average Leaf in Anychart", String.valueOf(VPDActivity.DataShare.getAverageLeaf()));
Log.i("Average RH in Anychart", String.valueOf(VPDActivity.DataShare.getAverageRH()));
// Averages from VPDActivity
double averageAir = VPDActivity.DataShare.getAverageAir();
double averageLeaf = VPDActivity.DataShare.getAverageLeaf();
double averageRH = VPDActivity.DataShare.getAverageRH();
double leafOffset = averageAir - averageLeaf;
double calcLeafTemp = averageAir - leafOffset;
double calcLeafTempC = convertToCelsius(calcLeafTemp);
double calcAirTempC = convertToCelsius(averageAir);
// Calculate VPD for Celsius
// perform calculations
double VPsat = (610.78 * (Math.pow(10, ((7.5 * (calcLeafTempC)) / (237.3 + (calcLeafTempC))))) / 1000);
double VPpair = ((610.78 * (Math.pow(10, ((7.5 * calcAirTempC) / (237.3 + calcAirTempC)))) / 1000) * (averageRH / 100));
double leafvpd = VPsat - VPpair;
// String LeafVPD = String.valueOf(leafvpd);
riskMap.title().enabled(true);
riskMap.title()
.text("Leaf VPD")
.padding(0d, 0d, 20d, 0d);
// set the display mode of labels
riskMap.labelsDisplayMode("clip");
riskMap.labels().enabled(true);
riskMap.labels()
.minFontSize(14d)
.format("function() {\n" +
" var namesList = [\"Low\", \"Seedling\", \"Vegetative\", \"Early Flower\", \"Mid Flower\", \"Late Flower\", \"High\" ];\n" +
" return namesList[this.heat];\n" +
" }");
riskMap.yAxis(0).stroke(null);
riskMap.yAxis(0).labels().padding(0d, 15d, 0d, 0d);
riskMap.yAxis(0).ticks(true);
riskMap.xAxis(0).stroke(null);
riskMap.xAxis(0).ticks(true);
riskMap.tooltip().title().useHtml(true);
riskMap.tooltip()
.useHtml(true)
.titleFormat("function() {\n" +
" var namesList = [\"Low\", \"Seedling\", \"Vegetative\", \"Early Flower\", \"Mid Flower\", \"Late Flower\", \"High\" ];\n" +
" return '<b>' + namesList[this.heat] + '</b> Leaf VPD';\n" +
" }")
.format("function () {\n" +
" return '<span style=\"color: #CECECE\">Humidity: </span>' + this.x + '<br/>' +\n" +
" '<span style=\"color: #CECECE\">Temperature: </span>' + this.y;\n" +
" }");
// square colors per plant stage
String prop_early_veg = "#00FFFF"; // CYAN
String late_veg_early_flower = "#008000"; // GREEN
String mid_late_flower = "#FFFF00"; // YELLOW
String danger_under_trans = "#FF00FF"; // MAGENTA
String danger_over_tran = "#FF0000"; // RED
String danger_disease = "#FF0000"; // RED
// This is where I am stuck trying to cram a double into an integer.
List<DataEntry> data = new ArrayList<>();
// 98%
data.add(new CustomHeatDataEntry("98%", "50F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "52F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "54F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "56F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "58F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "60F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "62F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "64F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "66F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "68F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "70F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "72F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "74F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "76F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "78F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "80F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "82F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "84F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "86F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "88F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "90F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "92F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "94F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "96F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "98F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "100F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "102F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "104F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "106F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "108F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("98%", "110F", 0, "#90caf9"));
// 96%
data.add(new CustomHeatDataEntry("96%", "50F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "52F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "54F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "56F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "58F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "60F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "62F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "64F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "66F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "68F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "70F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "72F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "74F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "76F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "78F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "80F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "82F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "84F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "86F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "88F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "90F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "92F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "94F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "96F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "98F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "100F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "102F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "104F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "106F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "108F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("96%", "110F", 0, "#90caf9"));
// 94%
data.add(new CustomHeatDataEntry("94%", "50F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("94%", "52F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("94%", "54F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("94%", "56F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("94%", "58F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("94%", "60F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("94%", "62F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("94%", "64F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("94%", "66F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("94%", "68F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("94%", "70F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("94%", "72F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("94%", "74F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("94%", "76F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("94%", "78F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("94%", "80F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("94%", "82F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("94%", "84F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("94%", "86F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("94%", "88F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("94%", "90F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("94%", "92F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("94%", "94F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("94%", "96F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("94%", "98F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("94%", "100F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("94%", "102F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("94%", "104F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("94%", "106F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("94%", "108F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("94%", "110F", 0, "#ffb74d"));
// 92%
data.add(new CustomHeatDataEntry("92%", "50F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("92%", "52F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("92%", "54F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("92%", "56F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("92%", "58F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("92%", "60F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("92%", "62F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("92%", "64F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("92%", "66F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("92%", "68F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("92%", "70F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("92%", "72F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("92%", "74F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("92%", "76F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("92%", "78F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("92%", "80F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("92%", "82F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("92%", "84F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("92%", "86F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("92%", "88F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("92%", "90F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("92%", "92F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("92%", "94F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("92%", "96F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("92%", "98F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("92%", "100F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("92%", "102F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("92%", "104F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("92%", "106F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("92%", "108F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("92%", "110F", 0, "#ffb74d"));
// 90%
data.add(new CustomHeatDataEntry("90%", "50F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("90%", "52F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("90%", "54F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("90%", "56F", 0, "#ef6c00"));
data.add(new CustomHeatDataEntry("90%", "58F", 0, "#ef6c00"));
data.add(new CustomHeatDataEntry("90%", "60F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("90%", "62F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("90%", "64F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("90%", "66F", 0, "#ef6c00"));
data.add(new CustomHeatDataEntry("90%", "68F", 0, "#ef6c00"));
data.add(new CustomHeatDataEntry("90%", "70F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("90%", "72F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("90%", "74F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("90%", "76F", 0, "#ef6c00"));
data.add(new CustomHeatDataEntry("90%", "78F", 0, "#ef6c00"));
data.add(new CustomHeatDataEntry("90%", "80F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("90%", "82F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("90%", "84F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("90%", "86F", 0, "#ef6c00"));
data.add(new CustomHeatDataEntry("90%", "88F", 0, "#ef6c00"));
data.add(new CustomHeatDataEntry("90%", "90F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("90%", "92F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("90%", "94F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("90%", "96F", 0, "#ef6c00"));
data.add(new CustomHeatDataEntry("90%", "98F", 0, "#ef6c00"));
data.add(new CustomHeatDataEntry("90%", "100F", 0, "#90caf9"));
data.add(new CustomHeatDataEntry("90%", "102F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("90%", "104F", 0, "#ffb74d"));
data.add(new CustomHeatDataEntry("90%", "106F", 0, "#ef6c00"));
data.add(new CustomHeatDataEntry("90%", "108F", 0, "#ef6c00"));
data.add(new CustomHeatDataEntry("90%", "110F", 0, "#ef6c00"));
// I removed data.add's from here down to 30% as the body had limits of characters.
riskMap.data(data);
anyChartView.setChart(riskMap);
riskMap.draw(true);
}
Temperature Convert method
private static double convertToCelsius(double F) {
return (F - 32) * 5 / 9;
}
CustomHeatDataEntry method
private static class CustomHeatDataEntry extends HeatDataEntry {
CustomHeatDataEntry(String x, String y, Integer heat, String fill) {
super(x, y, heat);
setValue("fill", fill);
}
}
To utilize different data types, including the Double, you have to specify them in your data mapping.
//include custom value as a parameter
private static class CustomHeatDataEntry extends HeatDataEntry {
CustomHeatDataEntry(String x, String y, Integer heat, String fill, Double myValue) {
super(x, y, heat);
setValue("fill", fill);
//set a custom value from a passed parameter
setValue("myValue", myValue);
}
}
In the provided example, the myValue is a Double data type variable.
Then, you have to embed this value via custom formatting functions. Please keep in mind that AnyChart is built on JavaScript, and custom formatting functions are essentially JS wrapped in concatenated Java strings.
Knowing that you can access your custom value in the following way.
riskMap.labels().enabled(true);
riskMap.labels()
.minFontSize(14d)
//add custom formatting functions with your custom value
.format("function() {\n" +
" return this.getData('myValue');\n" +
" }");
You can find more information about it on the text formatting documentation page.