I had implemented the follow stacked column chart below:
As you can see, some bar does not appear the label name.
I tried increase the width from this chart and now I can see the label from bars (look the new print below)
Bus now I cannot see all items. i think that I need add a scroll bar.
Could you please help me? Basically I would like to add a X-axis scroll at this chart.
Note:
I'm using the amchart version 4.
I'm using this example: https://www.amcharts.com/demos/stacked-column-chart/
follow my code below.
method used to build the chart
private buildChart(dataChart) {
/* Chart code */
// Themes begin
am4core.useTheme(am4themes_animated);
// Create chart instance
const chart = am4core.create('chartdiv', am4charts.XYChart);
for (const data of dataChart) {
chart.data.push(data);
}
console.log(chart);
// Create axes
const categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = 'model';
categoryAxis.renderer.grid.template.location = 0;
const valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.renderer.inside = true;
valueAxis.renderer.labels.template.disabled = true;
valueAxis.min = 0;
// Create series
function createSeries(field, name) {
// Set up series
const series = chart.series.push(new am4charts.ColumnSeries());
series.name = name;
series.dataFields.valueY = field;
series.dataFields.categoryX = 'model';
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
const labelBullet = series.bullets.push(new am4charts.LabelBullet());
labelBullet.label.text = '{valueY}';
labelBullet.locationY = 0.5;
return series;
}
createSeries('DISCONNECTED', 'DISCONNECTED');
createSeries('AVAILABLE', 'AVAILABLE');
// Legend
chart.legend = new am4charts.Legend();
}
html code
<div class="row">
<div class="col-md-12 teste">
<app-card [title]="'Available Devices'" >
<div id="chartdiv" [style.height]="'400px'" [style.width]="'4000px'"></div>
</app-card>
</div>
I found one solution for it. follow below:
// I use the scrollbarX to create a horizontal scrollbar
chart.scrollbarX = new am4core.Scrollbar();
// here I set the scroolbar bottom the chart
chart.scrollbarX.parent = chart.bottomAxesContainer;
//here I chose not to show the startGrip (or button that expand the series from chart)
chart.scrollbarX.startGrip.hide();
chart.scrollbarX.endGrip.hide();
// here I set the start and end scroolbarX series that I would like show in chart initially
chart.scrollbarX.start = 0;
chart.scrollbarX.end = 0.25;
// here I chose not to show the zoomOutButton that appear above from chart
chart.zoomOutButton = new am4core.ZoomOutButton();
chart.zoomOutButton.hide();
So my full method that build chart is:
private buildChart(dataChart) {
/* Chart code */
// Themes begin
am4core.useTheme(am4themes_animated);
// Create chart instance
const chart = am4core.create('chartdiv', am4charts.XYChart);
for (const data of dataChart) {
chart.data.push(data);
}
// Create axes
const categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = 'model';
categoryAxis.renderer.grid.template.location = 0;
const valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.renderer.inside = true;
valueAxis.renderer.labels.template.disabled = true;
valueAxis.min = 0;
// Create series
function createSeries(field, name) {
// Set up series
const series = chart.series.push(new am4charts.ColumnSeries());
series.name = name;
series.dataFields.valueY = field;
series.dataFields.categoryX = 'model';
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:15px]{categoryX}: {valueY}';
// Add label
const labelBullet = series.bullets.push(new am4charts.LabelBullet());
labelBullet.label.text = '{valueY}';
labelBullet.locationY = 0.5;
return series;
}
createSeries('DISCONNECTED', 'DISCONNECTED');
createSeries('AVAILABLE', 'AVAILABLE');
// Legend
chart.legend = new am4charts.Legend();
chart.scrollbarX = new am4core.Scrollbar();
chart.scrollbarX.parent = chart.bottomAxesContainer;
chart.scrollbarX.startGrip.hide();
chart.scrollbarX.endGrip.hide();
chart.scrollbarX.start = 0;
chart.scrollbarX.end = 0.25;
chart.zoomOutButton = new am4core.ZoomOutButton();
chart.zoomOutButton.hide();
}
Follow the print below showing how it got
Related
I'm looking to do a chart like this one using amcharts 4.
The question linked only supports AmCharts 3, and AmCharts 4 has no .addGraph() functionality. Is it possible to do this using XYCharts()?
const chart = new am4core.create(chartDiv.current, am4charts.XYChart);
chart.dataProvider = chartData;
chart.categoryField = 'category';
chart.rotate = true;
chart.columnWidth = 1;
// AXES
// Category
const categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
categoryAxis.gridAlpha = 0;
categoryAxis.axisAlpha = 0;
categoryAxis.gridPosition = 'start';
// value
const valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
valueAxis.stackType = '100%';
valueAxis.gridAlpha = 0;
valueAxis.autoGridCount = false;
valueAxis.gridCount = 20;
valueAxis.axisAlpha = 1;
// GRAPHS
// firstgraph
const graph = new am4charts.XYChart();
graph.labelText = 'Bad';
graph.valueField = 'bad';
graph.type = 'column';
graph.lineAlpha = 0;
graph.fillAlphas = 1;
graph.fillColors = ['#d05c4f', '#ffb2a8'];
chart.createChild(graph);
I tried chart.createChild(), but that appears to be for containers like rectangles. How would I achieve the same functionality using AmCharts 4?
A gauge chart is essentially a stacked column(bar) chart of only 1 type of series data. I've modified stacked column chart to look like the gauge chart linked in the question.
working demo: https://codepen.io/rabelais88/pen/RwMGxxJ
<script src="https://cdn.amcharts.com/lib/4/core.js"></script>
<script src="https://cdn.amcharts.com/lib/4/charts.js"></script>
<script src="https://cdn.amcharts.com/lib/4/themes/animated.js"></script>
<div id="chartdiv"></div>
<style>
#chartdiv {
width: 100%;
height: 400px;
}
</style>
// Themes begin
am4core.useTheme(am4themes_animated);
// Themes end
// Create chart instance
var chart = am4core.create("chartdiv", am4charts.XYChart);
// Add data
chart.data = [
{
type: "gauge",
bad: 2,
good: 7,
worst: 1
}
];
// Create axes
var categoryAxis = chart.yAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "type";
categoryAxis.renderer.grid.template.location = 0;
categoryAxis.renderer.minGridDistance = 20;
// forcefully expand axis to make it look like gauge
categoryAxis.renderer.cellStartLocation = -0.12;
categoryAxis.renderer.cellEndLocation = 1.12;
categoryAxis.visible = false;
var valueAxis = chart.xAxes.push(new am4charts.ValueAxis());
// remove inner margins by syncing its start and end with min and max
valueAxis.min = 0;
valueAxis.max = 10;
// Create series
function createSeries(field, name, stacked) {
var series = chart.series.push(new am4charts.ColumnSeries());
series.dataFields.valueX = field;
series.dataFields.categoryY = "type";
series.name = name;
series.columns.template.tooltipText = "{name}: [bold]{valueX[/]}";
series.stacked = stacked;
// add inner text
const bullet = series.bullets.push(new am4charts.LabelBullet());
bullet.label.text = "{name}";
bullet.locationX = 0.5;
}
createSeries("good", "Good", false); // base of stacked column
createSeries("bad", "Bad", true);
createSeries("worst", "Worst", true);
// Add legend
chart.legend = new am4charts.Legend();
Edit
I've added hand as requested.
added another a column and designated it as a non-cluster to make it ignore the grid layout.
set the column's interaction and style as hidden and attached a bullet shape that looks like a 'clock hand'.
it includes a lot of manual position manipulation; due to the limit of a pre-made charts.
On a side note, normally if a chart has anything unusual element, it's better to implement it with D3.js by scratch; fiddling with a pre-made chart will bring too much side effects later.
// adding a pointing hand(clock hand) as annotation
// draw pointing hand
var series = chart.series.push(new am4charts.ColumnSeries());
series.dataFields.valueX = "current";
series.dataFields.categoryY = "type";
series.fillOpacity = 0;
// hide shape
series.stroke = am4core.color("rgba(0,0,0,0)");
// make it ignore other columns
series.clustered = false;
// disable tooltips
series.interactionsEnabled = false;
const bullet = series.bullets.push(new am4core.Triangle());
bullet.width = 30;
bullet.height = 30;
bullet.fill = am4core.color("black");
bullet.horizontalCenter = "middle";
bullet.verticalCenter = "top";
bullet.rotation = 180;
// manually change its position
bullet.dy = -65;
const label = series.bullets.push(new am4charts.LabelBullet());
label.label.text = "current: {valueX}";
label.label.dy = -30;
updated working demo with pointing hand(clock hand): https://codepen.io/rabelais88/pen/mdxOyYQ
I have problem to make my tooltip in amchart have to look nice, I just want to make that tooltip not struck down by other tooltip, this is my screen shoot amchart tooltip
how can I solve my problem? this is my code with amchart
< style > #chartdiv {
height: 280 px;
position: relative;
} < /style>
<!-- Chart code -->
< script >
am4core.ready(function() {
// Themes begin
am4core.useTheme(am4themes_kelly);
am4core.useTheme(am4themes_animated);
// Themes end
// Create chart instance
var chart = am4core.create("chartdiv", am4charts.XYChart);
// Enable chart cursor
chart.cursor = new am4charts.XYCursor();
chart.cursor.lineX.disabled = true;
chart.cursor.lineY.disabled = true;
// Enable scrollbar
chart.scrollbarX = new am4core.Scrollbar();
// Add data
chart.data = <?php
echo $realisasi;
?>;
// Create axes
var dateAxis = chart.xAxes.push(new am4charts.DateAxis());
dateAxis.dataFields.category = "Date";
dateAxis.renderer.grid.template.location = 0.5;
dateAxis.dateFormatter.inputDateFormat = "yyyy-MM-dd";
dateAxis.renderer.minGridDistance = 40;
dateAxis.tooltipDateFormat = "MMM dd, yyyy";
dateAxis.dateFormats.setKey("day", "dd");
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
// Create series
var series = chart.series.push(new am4charts.LineSeries());
series.tooltipText = "{date}\n[bold font-size: 17px]realisasi: {valueY}[/]";
series.tooltip.valign = "middle";
series.dataFields.valueY = "realisasi";
series.dataFields.dateX = "date";
series.strokeDasharray = 3;
series.strokeWidth = 2
series.strokeOpacity = 0.3;
series.strokeDasharray = "3,3"
var bullet = series.bullets.push(new am4charts.CircleBullet());
bullet.strokeWidth = 2;
bullet.stroke = am4core.color("#fff");
bullet.setStateOnChildren = true;
bullet.propertyFields.fillOpacity = "opacity";
bullet.propertyFields.strokeOpacity = "opacity";
var hoverState = bullet.states.create("hover");
hoverState.properties.scale = 1.7;
function createTrendLine(data) {
var trend = chart.series.push(new am4charts.LineSeries());
trend.dataFields.valueY = "pakta";
trend.dataFields.dateX = "date";
trend.strokeWidth = 2
trend.stroke = trend.fill = am4core.color("#c00");
trend.data = data;
var bullet = trend.bullets.push(new am4charts.CircleBullet());
bullet.tooltipText = "{date}\n[bold font-size: 17px]pakta: {pakta}[/]";
bullet.strokeWidth = 2;
bullet.stroke = am4core.color("#fff")
bullet.circle.fill = trend.stroke;
var hoverState = bullet.states.create("hover");
hoverState.properties.scale = 1.7;
return trend;
};
// createTrendLine();
createTrendLine(<?php
echo $pagu;
?>);
}); // end am4core.ready()
< /script>
<!-- HTML -->
< div id = "chartdiv" > < /div>
Help me to solve my problem, or whether other solution to make my two tooltip is not struck down.
You didn't specify any sample data on your code, but try replacing valign:
series.tooltip.valign = "middle";
with pointerOrientation:
series.tooltip.pointerOrientation = "down";
I've applied code like this:
var series = chart.series.push(new am4charts.LineSeries());
series.tooltip.getFillFromObject = false;
series.tooltip.background.fill = am4core.color("#fff");
series.tooltip.border.fill = am4core.color("#000");
series.tooltip.label.fill = am4core.color("#000");
series.tooltipText = "{date.formatDate('d MMM, yyyy')}: [bold]{value}";
series.dataFields.dateX = "date";
series.dataFields.valueY = "value";
But somehow tooltip is not loaded with border color.
In amcharts the field for the border color is stroke. You can set it eiter on the tooltip itself, on the tooltip.background or on the tooltip.label. For example like this:
series.tooltip.background.stroke = am4core.color("#000");
You also can change the border width using strokeWidth:
series.tooltip.background.strokeWidth = 2;
Here is a working code pen.
I am using amcharts to prepare graph for 5 application status. On clicking each title, respective application column appears and on clicking again title disables and column for that application disappears. How can I keep this title disable from the beginning on load.
function createXYZchart() {
var chart = new AmCharts.AmSerialChart();
chart.dataProvider = dataXYZ; //data source
chart.categoryField = "month"; //data provider X-Axis
var categoryAxis = chart.categoryAxis;
categoryAxis.labelRotation = 90;
chart.angle = 60;
chart.depth3D = 5;
chart.columnWidth = 0.85;
var valueAxis = new AmCharts.ValueAxis();
valueAxis.dashLength = 10;
valueAxis.autoGridCount = false;
valueAxis.minimum = 90;
valueAxis.maximum = 100;
valueAxis.gridCount=5;
valueAxis.labelFunction = formatLabel;
chart.addValueAxis(valueAxis);
}
To hide the graph on initial chart load, set it's hidden attribute to true.
I.e.:
var graph = new AmChars.AmGraph();
graph.hidden = true;
graph.title = "Hidden graph";
graph.valueField = "value";
chart.addGraph(graph);
I need to update the data in a number of JSON arrays by using a select menu.
The idea is this:
Select a year which updates a global variable (JSON Array) with data associated with that year.
My problem is I am not sure about variable scope and how to get control of this. I am also finding that amcharts builds the charts onload so updating a variable wouldn'd do anything
Is it possible to update a global variable with a new data set and then reload the charts with the new data? What would this look like?
Not sure this update helps or if this is any more clear.
Here is a link to a fiddle of one of the charts I built:
http://jsfiddle.net/kenaesthetic/33JH9/
The shorthand structure goes like this:
<head>
<script> amchart script </script>
<head>
<body>
<select>
<option>2010</option
<option>2011</option
<option>2012</option
<option>2013</option
<option>2014</option
</select>
<div id="chart-container-1"></div> // These charts are stacked (refer to the fiddle)
<div id="chart-container-2"></div>
<div id="chart-container-3"></div>
<div id="chart-container-4"></div>
<div id="chart-container-5"></div>
</body>
I think you want to do something more like this:
var chart;
var chartData = [
{
"subject": "Personal Services",
"2010": 493142064,
"2011": 540156996,
"2012": 593541335,
"2013": 640585618,
"2014": 689417065
}
];
AmCharts.ready(function () {
// SERIALL CHART
chart = new AmCharts.AmSerialChart();
chart.dataProvider = chartData;
chart.categoryField = "subject";
chart.plotAreaBorderAlpha = 0.2;
chart.rotate = true;
// AXES
// Category
var categoryAxis = chart.categoryAxis;
categoryAxis.gridAlpha = 0.1;
categoryAxis.axisAlpha = 0;
categoryAxis.gridPosition = "start";
// value
var valueAxis = new AmCharts.ValueAxis();
valueAxis.stackType = "regular";
valueAxis.gridAlpha = 0.1;
valueAxis.axisAlpha = 0;
chart.addValueAxis(valueAxis);
// GRAPHS
// firstgraph
var graph = new AmCharts.AmGraph();
graph.title = "2010";
graph.labelText = "[[value]]";
graph.valueField = "2010";
graph.type = "column";
graph.lineAlpha = 0;
graph.fillAlphas = 1;
graph.lineColor = "#C72C95";
graph.balloonText = "<b><span style='color:#C72C95'>[[title]]</b></span><br><span style='font-size:14px'>[[category]]: <b>[[value]]</b></span>";
chart.addGraph(graph);
// second graph
graph = new AmCharts.AmGraph();
graph.title = "2011";
graph.labelText = "[[value]]";
graph.valueField = "2011";
graph.type = "column";
graph.lineAlpha = 0;
graph.fillAlphas = 1;
graph.lineColor = "#D8E0BD";
graph.balloonText = "<b><span style='color:#afbb86'>[[title]]</b></span><br><span style='font-size:14px'>[[category]]: <b>[[value]]</b></span>";
chart.addGraph(graph);
// third graph
graph = new AmCharts.AmGraph();
graph.title = "2012";
graph.labelText = "[[value]]";
graph.valueField = "2012";
graph.type = "column";
graph.lineAlpha = 0;
graph.fillAlphas = 1;
graph.lineColor = "#B3DBD4";
graph.balloonText = "<b><span style='color:#74bdb0'>[[title]]</b></span><br><span style='font-size:14px'>[[category]]: <b>[[value]]</b></span>";
chart.addGraph(graph);
// fourth graph
graph = new AmCharts.AmGraph();
graph.title = "2013";
graph.labelText = "[[value]]";
graph.valueField = "2013";
graph.type = "column";
graph.lineAlpha = 0;
graph.fillAlphas = 1;
graph.lineColor = "#69A55C";
graph.balloonText = "<b><span style='color:#69A55C'>[[title]]</b></span><br><span style='font-size:14px'>[[category]]: <b>[[value]]</b></span>";
chart.addGraph(graph);
// fifth graph
graph = new AmCharts.AmGraph();
graph.title = "2014";
graph.labelText = "[[value]]";
graph.valueField = "2014";
graph.type = "column";
graph.lineAlpha = 0;
graph.fillAlphas = 1;
graph.lineColor = "#B5B8D3";
graph.balloonText = "<b><span style='color:#7a81be'>[[title]]</b></span><br><span style='font-size:14px'>[[category]]: <b>[[value]]</b></span>";
chart.addGraph(graph);
// LEGEND
var legend = new AmCharts.AmLegend();
legend.position = "right";
legend.borderAlpha = 0.3;
legend.horizontalGap = 10;
legend.switchType = "v";
chart.addLegend(legend);
// WRITE
chart.write("chartdiv");
});
// Make chart 2D/3D
function setDepth() {
if (document.getElementById("rb1").checked) {
chart.depth3D = 0;
chart.angle = 0;
} else {
chart.depth3D = 20;
chart.angle = 30;
}
chart.validateNow();
}
This example is based on the AmChart's example code for stacked chart. It does separate out the data for the chart into a global Javascript variable, namely chartData.
You need to break down the problem into two parts: the manipulation of the data and then loading the data into the chart after it has been changed.
Here is very simple example of manipulating the data using jQuery and a button. http://jsfiddle.net/stevewilhelm/XzmQ6/2/
Once the data is modified, you will need to update the chart. See http://blog.amcharts.com/2013/08/tutorial-live-editing-chart-data.html as an example.
And look at chart.dataProvider chart.validateData() for details.