amCharts Custom legend with values (correct method and alignment) - amcharts

I'm currently building a heat map, with a 100+ data points (Country, value).
I've created a custom legend to only display the top 10 countries and their values.
However the alignment is off (wrong side and the distance between the name and values), is there a better way to do this?
chart.legend = new am4maps.Legend();
chart.legend.position = "right";
chart.legend.data = [];
for (let index = 0; index < 10; index++) {
chart.legend.data.push({
name: legend_data[index]['id'],
fill: colorSet.next(),
value: legend_data[index]['value']
});
}
chart.legend.labels.template.text = "{name}: {value}%";
chart.legend.itemContainers.template.paddingTop = 2;
chart.legend.itemContainers.template.paddingBottom = 2;

Very simple answer, I just needed to set the valueLabels text, rather than concatenating both into the legend label text. Aligns correctly now.
chart.legend.labels.template.text = "{name}";
chart.legend.valueLabels.template.text = "{value}";

Related

How to extract pixel value from geometry points in shp format (2500 points) starting from an Image Collection resempled

I'm trying to extract the value of each single band of Sentinel-2 after resampling the bands from 10 meters to 30 meters using the resolution of the Landsat-8 (I didn't know how to do this in another way)
This is the code using band 4 as an example. When I try to export the values ​​in a table the running time is infinite and I was not able to extract even the value for a single point.
N.B. my area is very large, it corresponds to all of southern europe
thank you !
function maskS2clouds(image) {
var qa = image.select('QA60');
var cloudBitMask = 1 << 10;
var cirrusBitMask = 1 << 11;
var mask = qa.bitwiseAnd(cloudBitMask).eq(0).and(qa.bitwiseAnd(cirrusBitMask).eq(0));
return image.updateMask(mask).divide(10000).select("B.*").copyProperties(image, ["system:time_start"]);
}
var start = '2012-01-01';
var end = '2022-12-31';
var cld_max = 30;
var s2 = ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED")
.filterBounds(Eur)
.filterDate(start,end)
.filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE',60))
.map(maskS2clouds);
var land8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR').filterBounds(Eur)
var b4 = land8.select('B4').filterBounds(Eur); // 30-m resolution
var b4s = s2.select('B4').filterBounds(Eur); // 10-m resolution
var proj_10m = b4.first()
.projection();
function resample(image) {
var b4s = image.select('B4');
var b4s_res = b4s.resample('bilinear').reproject(proj_10m);
return b4s_res;
}
var b4s_res =b4s.map(resample).filterBounds(Eur);
//original code
var pts = b4s_res.map(function(img) {
var obs = img.reduceRegion(
{geometry: points , reducer: ee.Reducer.median(), scale: 80});
return img.set('B4', obs.get('B4'));
});
Export.table.toDrive({
collection: pts,
description: 'table_csv',
folder: 'earth_engine_demos',
fileFormat: 'CSV'
});
//test with geometry composed of two single points
var pts2 = b4s_res.map(function(img) {
var obs2 = img.reduceRegion(
{geometry: geometry , reducer: ee.Reducer.median(), scale: 80});
return img.set('B4', obs2.get('B4'));
});
Export.table.toDrive({
collection: pts2,
description:'prova_csv',
folder: 'earth_engine_demos',
fileFormat: 'CSV'
});
Is it possible to find a faster way to extract the value of the points (2500 random points) in the table? Do you also know another way to apply a resampling on all bands simultaneously and extract the corresponding value of each point for each single band?

AmCharts 4 : Show totals of clustered and stacked charts, for individual clusters

Background:
Following the example of stacked and clustered charts as shown here I have created a chart with clustered and stacked columns. I am also attempting to display the total of the individual stacks on the top of the column as shown here
Issue faced:
The main is I am facing is the total value is displayed for all the data in the ValueAxis and not for individual stacks. Please help in displaying individual totals for the clustered columns.
Sample code:
Note the inbuilt APIs used to calculate and display totals
// Fully working example in the CodePen
// Enabling totals calculation
let valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.calculateTotals = true;
// Displaying the total in the LabelBullet
let totalBullet = totalSeries.bullets.push(new am4charts.LabelBullet());
totalBullet.label.text = "{valueY.sum}";
Codepen depicting the issue (note the totals on top of the stacked columns)
Alternate approaches considered:
Adding a field in the data with the totals for the stacks and displaying it instead (Problem: Unable to deselect using the Label - the value would be static and won't change)
Other help from StackOverflow:
Found samples of showing totals on stacked charts, but unable to find help on dealing with grouping
Although this is 7months old, I didn't find an answer either for this anywhere. If you haven't found a solution yet I was able to work around this by creating two Y axes and assigning them the series individually, then adding in the 'none' series for the totals bullet as well.
I adapted your Codepen example here in jsfiddle (codepen freezes for me for some reason)
Essentially though you create the two axes, and hide the labels for the second one.
let valueAxis0 = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis0.min = 0;
valueAxis0.calculateTotals = true;
valueAxis0.title.text = "Expenditure (M)";
var valueAxis1 = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis1.renderer.grid.template.disabled = true;
valueAxis1.calculateTotals = true;
valueAxis1.syncWithAxis = chart.yAxes.getIndex(0);
valueAxis1.min = 0;
valueAxis1.renderer.labels.template.disabled = true;
Then select it when creating the series and assign to the appropriate axis with series.yAxis = valueAxis;
function createSeries(field, name, stacked, yAxes) {
var valueAxis;
if (yAxes == 0) {
valueAxis = valueAxis0;
} else if (yAxes == 1) {
valueAxis = valueAxis1;
}
let series = chart.series.push(new am4charts.ColumnSeries());
...
series.yAxis = valueAxis;
Then the same goes for the TotalSeries

Amcharts4: How to add an image to an axis (valueAxis) label?

With amcharts4, I would like to add an image to a ValueAxis's label. Is this possible? I've found out, how to add an SVG image to a bullet (see demo). But is it possible to do something similar with the label of the ValueAxis?
Here is an example of such an image, I would like to add next to the number:
Currently, the value axis looks like this and it should have an icon next to the label:
EDIT:
Thanks to #zeroin's answer, I found a solution. However, there seems to be a strange bug when using an axis bullet with a template. Not every bullet is hidden even though its label is hidden. Here's the relevant code, a screenshot and a codepen to reproduce.
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.min = 0;
valueAxis.max = 800;
valueAxis.renderer.minGridDistance = 30;
valueAxis.renderer.opposite = true;
valueAxis.renderer.labels.template.dx = 13;
valueAxis.strictMinMax = true;
var image = new am4core.Image();
image.href = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-160/man-user.svg";
image.width = 12;
image.horizontalCenter = "middle";
image.verticalCenter = "middle";
image.dx = 13;
image.dy = -0.5;
image.opacity = 0.3;
valueAxis.dataItems.template.bullet = image;
EDIT2:
This bug seems to be fixed in the current release of amcharts (4.5.14). It works now as expected.
Your question is right on time - in a version released today (4.5.9) we added bullet property to AxisDataItem. So you can add image or any other sprite to all axis labels via template or create axis range at a value you need and add bullet there, like:
var range = valueAxis.axisRanges.create();
range.value = 1500;
//range.label.text = "1500";
var image = new am4core.Image();
image.href = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-160/man-user.svg";
image.width = 15;
image.horizontalCenter = "middle";
image.verticalCenter = "middle";
image.dx = -55;
range.bullet = image;
https://codepen.io/team/amcharts/pen/JgXqvp

How to i dynamically Change the color of Bullet based on condition

I'm developing analytic dashboard using amchart4 to render graph.
But i don't know how to change bullets color based on conditional
var series2 = chart.series.push(new am4charts.LineSeries());
series2.dataFields.valueX = "PROJ_LF";
series2.dataFields.categoryY = "Roundtrip_Market";
series2.strokeWidth = 0;
var bullet1 = series2.bullets.push(new am4charts.Bullet());
bullet1.tooltipText = "Value: [bold]{valueX} %[/]";
var image = bullet1.createChild(am4core.Image);
image.href = "assets/images/proj_lf_red.png";
image.width = 7;
image.height = 41;
image.horizontalCenter = "middle";
image.verticalCenter = "middle";
var series3 = chart.series.push(new am4charts.LineSeries());
series3.dataFields.valueX = "LY_FLOWN";
series3.dataFields.categoryY = "Roundtrip_Market";
series3.strokeWidth = 0;
var bullet2 = series3.bullets.push(new am4charts.Bullet());
bullet2 .tooltipText = "Value: [bold]{valueX} %[/]";
var image1 = bullet2.createChild(am4core.Image);
image1.href = "assets/images/ly_flow.png";
image1.width = 7;
image1.height = 41;
image1.horizontalCenter = "middle";
image1.verticalCenter = "middle";
problem is about bullet1 , bullet2
Now, bullet1 color is RED and bullet2 is Black
but, i need dynamic to change color
if bullet1>bullet2 bullet1 color is RED
if bullet2>bullet1 bullet1 color will be green
is there a way i can achieve this result.
I know this question is 7 month old but i had a similar problem and found a solution.
You can iterate through your data array before assigning it to your chart and add a condition based property that could look like this:
config = {
fill: am4core.color('#ff0000'),
};
now you can add the dataField property to the part of your chart that sould get another color in my case it was:
series.columns.template.configField = 'config';
now the chart will consider if your data item has a config property and change any setting that is listed in your config for this specific entry.

How to format y axis as currency using amcharts 4 with angular 7

I have looked through the documentation for amcharts version 4 (https://www.amcharts.com/javascript-charts/) and I cannot seem to find out how to format the y axis as currency. There is documentation on formatting the y axis in other manners but currency does not seem to be one of them. Anyone out there know how or where to begin?
I have the above chart thus far, just need to know how or where to format the y axis as currency. I currently have the labels when you hover over the lines formatted as currency fine, as that was rather straightforward. Here is my function to create the axis:
function createAxisAndSeries(field, name, opposite) {
const valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
const series = chart.series.push(new am4charts.LineSeries());
series.dataFields.valueY = field;
series.dataFields.dateX = 'date';
series.strokeWidth = 2;
series.yAxis = valueAxis;
series.name = name;
series.tooltipText = '{name}: [bold]${valueY}[/]';
series.tensionX = 0.8;
const interfaceColors = new am4core.InterfaceColorSet();
valueAxis.renderer.line.strokeOpacity = 1;
valueAxis.renderer.line.strokeWidth = 2;
valueAxis.renderer.line.stroke = series.stroke;
valueAxis.renderer.labels.template.fill = series.stroke;
valueAxis.renderer.opposite = opposite;
valueAxis.renderer.grid.template.disabled = true;
}
After some R&D, this solved the issue for me:
valueAxis.numberFormatter = new am4core.NumberFormatter();
valueAxis.numberFormatter.numberFormat = '$#,###.##';
Hopefully, it helps someone else out there searching one day.

Resources