How to hide zero value in chart using amchart.js ?
Here's my code to generate the chart :
function getStatsByFlowByOperation(){
$.ajax({
success: function(data) {
//data = formatData(data);
am4core.useTheme(am4themes_material);
chart = am4core.create("chartdiv", am4charts.XYChart);
chart.hiddenState.properties.opacity = 0;
chart.data = data;
chart.colors.step = 2;
chart.padding(30, 30, 10, 30);
chart.legend = new am4charts.Legend();
var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "OPERATION_NAME";
categoryAxis.renderer.minGridDistance = 30;
categoryAxis.renderer.grid.template.location = 0;
categoryAxis.renderer.labels.template.rotation = 315;
categoryAxis.renderer.labels.template.verticalCenter = "middle";
categoryAxis.renderer.labels.template.horizontalCenter = "right";
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.renderer.inside = true;
valueAxis.renderer.labels.template.disabled = true;
valueAxis.min = 0;
var allStatus = [];
allStatus.push("NEW");
allStatus.push("DISABLED");
allStatus.push("SKIPPED");
allStatus.push("READY");
for(var i = 0; i < allStatus.length; i++) {
createSeries(allStatus[i], allStatus[i]);
}
},
error: function (jqXHR, exception) {
if (globalVars.unloaded) {
return;
}
manageAjaxError(jqXHR, textStatus, errorThrown);
}
});
}
This is an example of date in input:
[{
"READY": 0,
" ": 1,
"OPERATION_NAME": "INIT",
"STEP": 1
}]
EDIT -
Solution is to insert "null". It keeps columns displayed even if they display "0" value, e.i.:
if(data[i].READY == 0) {
data[i].READY = null;
}
How to hide zero value in chart using amchart.js ?
Here's my code to generate the chart :
function getStatsByFlowByOperation(){
$.ajax({
success: function(data) {
//data = formatData(data);
am4core.useTheme(am4themes_material);
chart = am4core.create("chartdiv", am4charts.XYChart);
chart.hiddenState.properties.opacity = 0;
chart.data = data;
chart.colors.step = 2;
chart.padding(30, 30, 10, 30);
chart.legend = new am4charts.Legend();
var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "OPERATION_NAME";
categoryAxis.renderer.minGridDistance = 30;
categoryAxis.renderer.grid.template.location = 0;
categoryAxis.renderer.labels.template.rotation = 315;
categoryAxis.renderer.labels.template.verticalCenter = "middle";
categoryAxis.renderer.labels.template.horizontalCenter = "right";
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.renderer.inside = true;
valueAxis.renderer.labels.template.disabled = true;
valueAxis.min = 0;
var allStatus = [];
allStatus.push("NEW");
allStatus.push("DISABLED");
allStatus.push("SKIPPED");
allStatus.push("READY");
for(var i = 0; i < allStatus.length; i++) {
createSeries(allStatus[i], allStatus[i]);
}
},
error: function (jqXHR, exception) {
if (globalVars.unloaded) {
return;
}
manageAjaxError(jqXHR, textStatus, errorThrown);
}
});
}
This is an example of date in input:
[{
"READY": 0,
" ": 1,
"OPERATION_NAME": "INIT",
"STEP": 1
}]
EDIT -
Solution is to insert "null". It keeps columns displayed even if they display "0" value, e.i.:
if(data[i].READY == 0) {
data[i].READY = null;
}
Share
Improve this question
edited Apr 25, 2019 at 13:15
Majestic
asked Apr 19, 2019 at 13:48
MajesticMajestic
9384 gold badges14 silver badges38 bronze badges
1
-
I don't think it's better to alter the data. You haven't shared the code for your chart, but whatever is generating the label bullets, you can do something like
bullet.events.on("inited", function(event) { if (event.target.dataItem.dataContext && event.target.dataItem.dataContext.READY === 0) { event.target.hide(); } } )
. That'd hide the bullet if its data'sREADY
field is precisely0
(also in the code you provided, would be better to use=== 0
instead of== 0
). – notacouch Commented Apr 27, 2019 at 3:55
6 Answers
Reset to default 9To hide zero value bullets you should use adapters (Amcharts 4). No need to adjust your data or do ugly JS-tricks. Amcharts implemented adapters to do all kind of dynamic rendering modifications.
For a column chart this would look like:
var series = chart.series.push(new am4charts.ColumnSeries());
series.dataFields.valueY = field;
series.dataFields.categoryX = "category";
series.name = name;
series.columns.template.tooltipText = "{name}: {valueY}";
var bullet = series.bullets.push(new am4charts.LabelBullet);
bullet.label.text = "{name}: {valueY}";
bullet.label.fill = am4core.color("#ffffff");
bullet.locationY = 0.5;
bullet.label.adapter.add("textOutput", function(text, target) {
// Hide labels with 0 value
if(target.dataItem && target.dataItem.valueY == 0) {
return "";
}
return text;
});
Check: https://www.amcharts./docs/v4/concepts/adapters/
To hide zero values bullets for a column chart this would look like:
series.bullets.push((root, series, dataItem) => {
if (dataItem.get("valueY")) {
return am5.Bullet.new(root, {
locationY: 0.5,
sprite: am5.Label.new(root, {
text: "{valueY}",
fill: root.interfaceColors.get("alternativeText"),
centerY: am5.percent(50),
centerX: am5.percent(50),
populateText: true,
}),
});
}
});
Or there's the short ugly way :
var numbers = document.getElementsByTagName('tspan');
for(var i = 0; i < numbers.length; i++){
if(numbers[i].innerHTML == '0'){
numbers[i].parentElement.removeChild(numbers[i]);
}
}
Adjusted to change zero to null instead of removing after getting clarification about the question.
edit test 2019-05-07
var objData = [
{ READY: 0, " ": 1, OPERATION_NAME: "INIT", STEP: 1 },
{ READY: 0, " ": 1, OPERATION_NAME: "EXPORT_SPEC", STEP: 2 },
{ READY: 0, " ": 1, OPERATION_NAME: "TRANSFORM_APS", STEP: 3 },
{ READY: 1, OPERATION_NAME: "PUBLISH_APS", STEP: 4 }
];
// change zero values to null
_.transform(objData, function(myObj, val, idx) {
if(val.READY==0){
val.READY = null;
}
console.log("val: "+JSON.stringify(val));
});
console.log("After Processing");
console.log(JSON.stringify(objData));
//am4core.useTheme(am4themes_material);
chart = am4core.create("chartdiv", am4charts.XYChart);
chart.hiddenState.properties.opacity = 0;
chart.data = objData;
chart.colors.step = 2;
chart.padding(30, 30, 10, 30);
chart.legend = new am4charts.Legend();
var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "OPERATION_NAME";
categoryAxis.renderer.minGridDistance = 30;
categoryAxis.renderer.grid.template.location = 0;
categoryAxis.renderer.labels.template.rotation = 315;
categoryAxis.renderer.labels.template.verticalCenter = "middle";
categoryAxis.renderer.labels.template.horizontalCenter = "right";
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.renderer.inside = true;
valueAxis.renderer.labels.template.disabled = true;
valueAxis.min = 0;
chart.colors.list = [
am4core.color("#8BC9FF"), // NEW
am4core.color("#FF4D4D"), // ERROR
am4core.color("#F2F2F2"), // DISABLED
am4core.color("#B5E8B5"), // FINISHED
am4core.color("#715AFF"), // SKIPPED
am4core.color("#FFEBCC"), // TIMEOUT
am4core.color("#BEECFF"), // READY
am4core.color("#EDD9BA"), // RESUBMITTED
am4core.color("#cceeff"), // DISPATCHED
am4core.color("#FFF4BE"), // CANCELLED
am4core.color("#FFFFB3"), // RUNNING
am4core.color("#CCFFCC"), // DONE
am4core.color("#FF4D4D") // ERROR_RESUMED
];
var allStatus = [];
allStatus.push("NEW");
allStatus.push("DISABLED");
allStatus.push("SKIPPED");
allStatus.push("READY");
allStatus.push("DISPATCHED");
allStatus.push("RUNNING");
allStatus.push("ERROR_RESUMED");
allStatus.push("ERROR");
allStatus.push("FINISHED");
allStatus.push("TIMEOUT");
allStatus.push("RESUBMITTED");
allStatus.push("CANCELLED");
allStatus.push("DONE");
for (var i = 0; i < allStatus.length; i++) {
createSeries(allStatus[i], allStatus[i]);
}
function isZero(x) { return x == 0; }
// Create series
function createSeries(field, name) {
// Set up series
var series = chart.series.push(new am4charts.ColumnSeries());
series.name = name;
series.dataFields.valueY = field;
series.dataFields.categoryX = "OPERATION_NAME";
series.sequencedInterpolation = true;
// Make it stacked
series.stacked = true;
// Configure columns
series.columns.template.width = am4core.percent(60);
series.columns.template.tooltipText =
"[bold]{name}[/]\n[font-size:14px]{categoryX}: {valueY}";
// Add label
var labelBullet = series.bullets.push(new am4charts.LabelBullet());
labelBullet.label.text = "{valueY}";
labelBullet.locationY = 0.5;
return series;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
height:97vh;
}
#chartdiv {
width: 100%;
height: 100%;
}
<script src="//www.amcharts./lib/4/core.js"></script>
<script src="//www.amcharts./lib/4/charts.js"></script>
<script src="//www.amcharts./lib/4/themes/animated.js">
</script>
<script src="https://cdnjs.cloudflare./ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
<div id="chartdiv"></div>
In this case, you need to hide the label text and also the tooltip text if those are enabled where the values are zero in your series.
For this, you can use "Adapters" in amchart - https://www.amcharts./docs/v4/concepts/adapters/
Note that this answer is based on amchart V4
Hide label text using adapter - "textOutput"
var series = chart.series.push(new am4charts.ColumnSeries());
//setting text for tooltip
series.columns.template.tooltipText = "{term}: {valueX.value.formatNumber('#,###'|''|' ')} ({valueX.percent.formatNumber('#.00'|''|'')}%)";
//other configurations in series............
//create a label bullet for this series
var labelBullet = series.bullets.push(new am4charts.LabelBullet());
//setting text for label
labelBullet.label.text = "{valueX.value.formatNumber('#,###'|''|' ')} ({valueX.percent.formatNumber('#.00'|''|'')}%)";
//hide label when valueX = 0
labelBullet.label.adapter.add("textOutput", function (text, target) {
if (target.dataItem && target.dataItem.valueX == 0) //valueX or valueY based on your data
return "";
return text;
});
Hide tooltip using adapter - "text"
series.tooltip.label.adapter.add("text", function (text, target) {
if (target.dataItem && target.dataItem.valueX == 0)
return "";
return text;
});
Before
After
There may be a parameter or option in amCharts but I'm not experienced with using that library so the first option that came to mind was to remove the element from the data.
The easiest way I know of to do that is with lodash.
You didn't supply data, so I'm using different data that I have available to illustrate.
/**
* ---------------------------------------
* This demo was created using amCharts 4.
*
* For more information visit:
* https://www.amcharts./
*
* Documentation is available at:
* https://www.amcharts./docs/v4/
* ---------------------------------------
*/
am4core.useTheme(am4themes_animated);
var chart = am4core.create("chartdiv", am4charts.XYChart);
chart.hiddenState.properties.opacity = 0; // this creates initial fade-in
chart.colors.saturation = 0.4;
var objData = [{
"country": "USA",
"visits": 3025
}, {
"country": "China",
"visits": 1882
}, {
"country": "Japan",
"visits": 0
}, {
"country": "Germany",
"visits": 1322
}, {
"country": "UK",
"visits": 1122
}, {
"country": "France",
"visits": 1114
}, {
"country": "India",
"visits": 984
}, {
"country": "Spain",
"visits": 711
}, {
"country": "Netherlands",
"visits": 665
}, {
"country": "Russia",
"visits": 580
}, {
"country": "South Korea",
"visits": 443
}, {
"country": "Canada",
"visits": 441
}];
objData.visits = _.reject(objData.visits, (o) => {
return o.visits > 0;
});
_.remove(objData, function(currentObject) {
return currentObject.visits == 0;
});
console.log(JSON.stringify(objData));
chart.data = objData;
var categoryAxis = chart.yAxes.push(new am4charts.CategoryAxis());
categoryAxis.renderer.grid.template.location = 0;
categoryAxis.dataFields.category = "country";
categoryAxis.renderer.minGridDistance = 20;
categoryAxis.renderer.minWidth = 120;
var valueAxis = chart.xAxes.push(new am4charts.ValueAxis());
valueAxis.renderer.maxLabelPosition = 0.98;
var series = chart.series.push(new am4charts.ColumnSeries());
series.dataFields.categoryY = "country";
series.dataFields.valueX = "visits";
series.tooltipText = "{valueX.value}";
series.sequencedInterpolation = true;
series.defaultState.transitionDuration = 1000;
series.sequencedInterpolationDelay = 100;
series.columns.template.strokeOpacity = 0;
chart.cursor = new am4charts.XYCursor();
chart.cursor.behavior = "zoomY";
// as by default columns of the same series are of the same color, we add adapter which takes colors from chart.colors color set
series.columns.template.adapter.add("fill", (fill, target) => {
return chart.colors.getIndex(target.dataItem.index);
});
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica,
Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
height:97vh;
}
#chartdiv {
width: 100%;
height: 100%;
}
<script src="//www.amcharts./lib/4/core.js"></script>
<script src="//www.amcharts./lib/4/charts.js"></script>
<script src="//www.amcharts./lib/4/themes/animated.js">
</script>
<script src="https://cdnjs.cloudflare./ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
<p>Notice that Japan has 0 visits so it is removed</p>
<div id="chartdiv"></div>