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

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

Related

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.

Blending artifacts when rendering polygon hair with Three.js

Trying to render polygon hair with transparency I get this artifact:
What I've checked so far:
renderer.sortObjects is true.
The hair's material.side is THREE.DoubleSide.
Set material.alphaTest=0.5 - reduced the problem but some artifacts are still visible.
How do I debug this?
What solved the problem was rendering the hair twice, first the back side and then the front side:
var hairMesh1 = obj;
var hairMaterial1 = hairMesh1.material;
hairMaterial1.opacity = 1.0;
hairMaterial1.transparent = true;
hairMaterial1.side = THREE.BackSide;
hairMaterial1.depthWrite = false;
var hairMesh2 = hairMesh1.clone();
var hairMaterial2 = hairMesh2.material = hairMesh2.material.clone();
hairMaterial2.side = THREE.FrontSide;
var hairObj2 = new THREE.Object3D();
hairObj2.add(hairMesh2)
hairObj2.renderOrder = 1;
model.add(hairObj1);
model.add(hairObj2);
This is explained in this answer.
Another thing I tried was like here - I set
material.alphaTest = 0.5; // between 0 and 1
which reduced problem (still noticeable artifacts seen). An explanation can be found here.

Put two y-axes on an imagesc image in MATLAB

I have what I think is a simple problem: I have a matrix that I image using imagesc. I simply want to show a second y-axis on the right hand side of the image. How do I do that? Example:
clear all;
aMatrix = rand(20,30);
yAxis1 = 32.*(1:size(aMatrix,1));
yAxis2 = 165.*(1:size(aMatrix,1));
xAxis = 1:size(aMatrix,2);
imagesc(yAxis1, xAxis1, aMatrix);
The following will show the image with yAxis1, on the left hand side. That is great, but how do I show yAxis2 on the right hand side of the image at the same time? Thanks.
aMatrix = rand(20,30);
yAxis1 = 32.*(1:size(aMatrix,1));
yAxis2 = 165.*(1:size(aMatrix,1));
xAxis = 1:size(aMatrix,2);
h1=imagesc(xAxis, yAxis1, aMatrix);set(gca,'YDir','normal');
ax1=gca;
set(ax1,'YColor','r','YAxisLocation','right');
set(ax1,'XTickLabel',' ');
ax2=axes('Position',get(ax1,'Position'),'YAxisLocation','left');
h2=imagesc(xAxis, yAxis2,aMatrix,'Parent',ax2);
set(gca,'YDir','normal');
A quite similar solution using yyaxis :
aMatrix = rand(20,30);
yAxis1 = 32.*(1:size(aMatrix,1));
yAxis2 = 165.*(1:size(aMatrix,1));
xAxis = 1:size(aMatrix,2);
yyaxis left
imagesc(xAxis, yAxis1, aMatrix);
ax = gca;
ax.YColor = ax.XColor;
ylabel('Left Side')
yyaxis right
imagesc(xAxis, yAxis2,aMatrix);
ax.YColor = ax.XColor;
ylabel('Right Side')

Clipping an ImageSnapshot in Flex

I'm using the ImageSnapshot.captureImage() method to screen capture a map image which is 2305 pixels high and 1134 pixels wide. I'm then trying to clip that image to one which is 1100 pixels high and 775 pixels wide.
public function grabScreenMapImage2():void {
// use ppi of 100 for testing
var ppi = 100;
var mapHeightInPixels = 1100
var mapWidthInPixels = 775
var snapImage:ImageSnapshot = ImageSnapshot.captureImage(myMap, ppi, new JPEGEncoder());
var bitmapData:BitmapData = new BitmapData(mapWidthInPixels, mapHeightInPixels);
var pixels:ByteArray = new ByteArray();
pixels = snapImage.data;
pixels.position = 0;
var clipRect:Rectangle = new Rectangle(0,0,mapWidthInPixels, mapHeightInPixels);
bitmapData.setPixels(clipRect, pixels);
}
However, I'm getting an error #2030 - end of file was encountered on my call to setPixels(), and cannot for the life of me work out why.
Any help greatly appreciated!
Thanks,
DrBacchus
This works for me. I zoom in on the original bitmap, then crop it into a new image the same size as the old one.
var myScaleFactor:Number = 1/3;
var zoomArea:Rectangle = bitmapData.rect;
zoomArea.inflate(zoomArea.width * imageScale, zoomArea.height * myScaleFactor);
var croppedImage = new BitmapData(zoomArea.width ,zoomArea.height,false,0xCCCCCC);
croppedImage.copyPixels(imageData,zoomArea,new Point(0,0));
var newImage = new BitmapAsset(croppedImage);

Resources