Amcharts - radar chart for one and two data items (amcharts4) - javascript

I am trying to display hexagon or octagon shape like radar series axis in case when I have only one or two items in data. Right Now it renders like that.
Following is my code snippet. I have looked at adapters for radar chart. So far, nothing useful found.
https://www.amcharts.com/docs/v4/reference/radarchart/#Adapters
Upon debugging, I found that series.pixelHeight is 0. Can you guys give some pointers. or show me the way?
const chart = am4core.create('al-radial-chart', am4charts.RadarChart)
chart.logo.disabled = true
chart.data = data
chart.radius = am4core.percent(70)
//* Create axes */
const categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis())
const valueAxis = chart.yAxes.push(new am4charts.ValueAxis())
// Fields
categoryAxis.dataFields.category = 'title'
valueAxis.title.fontWeight = 'bold'
valueAxis.renderer.gridType = 'polygons'
// Labels
valueAxis.renderer.labels.template.disabled = true
categoryAxis.renderer.labels.template.fontSize = 12
categoryAxis.renderer.labels.template.fill = am4core.color(colors.text)
// Axes
categoryAxis.renderer.grid.template.strokeWidth = 2
categoryAxis.renderer.grid.template.strokeOpacity = 0.99
categoryAxis.renderer.grid.template.fillOpacity = 0.05
categoryAxis.renderer.labels.template.html = `
<div style="width: ${
window.innerWidth < 1000 ? 80 : window.innerWidth < 1500 ? 120 : 150
}px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; text-align: center;">{category}</div>
<div style="text-align: center; font-weight: bold">{score.formatNumber("#,###.0")}</div>`
categoryAxis.renderer.labels.template.tooltipText = `[bold]{title}[/]\n score is [bold]{score.formatNumber("#,###.0")}[/]`
categoryAxis.tooltip.getFillFromObject = false
categoryAxis.tooltip.background.fill = am4core.color(colors.turq)
categoryAxis.tooltip.background.stroke = am4core.color(colors.turq)
categoryAxis.renderer.grid.template.fill = am4core.color(colors.gridFill)
categoryAxis.renderer.grid.template.stroke = am4core.color(colors.lines)
valueAxis.renderer.grid.template.strokeWidth = 2
valueAxis.renderer.grid.template.strokeOpacity = 0.99
valueAxis.renderer.grid.template.fillOpacity = 0.05
valueAxis.renderer.grid.template.fill = am4core.color(colors.gridFill)
valueAxis.renderer.grid.template.stroke = am4core.color(colors.lines)
valueAxis.zIndex = 1
categoryAxis.zIndex = 2
/* Create and configure series */
const series = chart.series.push(new am4charts.RadarSeries())
// series.zIndex = 1
series.dataFields.valueY = 'score'
series.dataFields.categoryX = 'title'
series.strokeWidth = 2
series.stroke = am4core.color(colors.turq)
series.fillOpacity = 0.4
series.sequencedInterpolation = true
series.sequencedInterpolationDelay = 100

I have created dummy data with valueAxis values set to zero and with different titles. Have used the categoryAxis htmlOutput adapter to hide those labels. Because my values were zero chart rendered correctly. Will post a code solution to this problem shortly.

Related

How do I get rid of the excess white space around pie chart? Using amcharts 4 libs

I have been trying to spread the pie chart I have to cover most of the 'card' I on the page, but no matter how much margin I cut, it either start disappearing behind another border within the card. I noticed that amcharts lib creates a bunch of layers that the developer doesn't have much control over. Anyway, this is what I'm talking about:
Here is the generated HTML code snippet:
Here is my javascript:
am4core.ready(function () {
//Themes
var chartType = am4charts.PieChart3D;
var seriesType = new am4charts.PieSeries3D();
//Create Chart and Series
var chart = createChart(thisWidget.id, chartType);
var pieSeries = chart.series.push(seriesType); // 3D Pie Chart
//Set properties
chart.hiddenState.properties.opacity = 0; // 3D Pie Chart: this creates initial fade-in
pieSeries.slices.template.cornerRadius = 6; //Pie Chart with varying Radius + 3D
pieSeries.colors.step = 3; //Pie Chart with varying Radius + 3D
pieSeries.angle = 45;
//color
if (colorTheme) {
pieSeries.colors.list = getAmchartCustomTheme(colorTheme);
}
//data types
pieSeries.dataFields.value = "count";
pieSeries.dataFields.category = "tag";
chart.paddingTop = 0;
chart.marginTop = 0;
// Put a thick white border around each Slice
pieSeries.slices.template.stroke = am4core.color("#fff");
pieSeries.slices.template
// change the cursor on hover to make it apparent the object can be interacted with
.cursorOverStyle = [
{
"property": "cursor",
"value": "pointer"
}
];
//Make the slice move on hover
var slice = pieSeries.slices.template;
slice.states.getKey("active").properties.shiftRadius = 0;
slice.states.getKey("hover").properties.scale = 1;
slice.states.getKey("hover").properties.shiftRadius = 0.2;
//increase size of Chart
chart.svgContainer.htmlElement.style.height = targetHeight;
chart.svgContainer.autoresize = true;
//disable Ticks and labels to save space
pieSeries.labels.template.disabled = true;
//registering events
pieSeries.slices.template.events.on("hit", function (ev) {
var category = ev.target.slice._dataItem.properties.category;
addInput(category);
});
pieSeries.alignLabels = false;
// Create a base filter effect (as if it's not there) for the hover to return to
var shadow = pieSeries.slices.template.filters.push(new am4core.DropShadowFilter);
shadow.opacity = 0;
// Create hover state
var hoverState = pieSeries.slices.template.states.getKey("hover"); // normally we have to create the hover state, in this case it already exists
// Slightly shift the shadow and make it more prominent on hover
var hoverShadow = hoverState.filters.push(new am4core.DropShadowFilter);
hoverShadow.opacity = 0.7;
hoverShadow.blur = 5;
//Add Data
chart.data = displayItems;
})
strokeOpacity = 0 or strokeWidth = 0 should do the trick.

How to remove gap between chart and X-axis value in AmChart?

I have a Multi Value Am-chart graph generated by external data (i.e., after Date selection chart will load based on data provided.) But after loading, data my chart shows like below image
As highlighted in yellow color in image. How to remove the space between "Date and chart" . Also Is there any way to display a line for the x-axis in this chart.
Below is my code.
createAxisAndSeries( field, name ) {
// Add cursor
this._chart.cursor = new am4charts.XYCursor();
this._chart.colors.step = 6;
// Create axes
let dateAxis = this._chart.xAxes.push( new am4charts.DateAxis() );
dateAxis.dataFields.category = "date";
dateAxis.renderer.grid.template.location = 0;
dateAxis.renderer.minGridDistance = 40;
dateAxis.dateFormatter.inputDateFormat = "YYYY-MM-DD, HH:mm:ss";
dateAxis.periodChangeDateFormats.setKey("day", "MMM dt");
let valueAxis = this._chart.yAxes.push( new am4charts.ValueAxis() );
let series = this._chart.series.push( new am4charts.LineSeries() );
series.dataFields.valueY = field;
series.dataFields.dateX = "date";
series.tensionX = 0.8;
series.strokeWidth = 2;
series.strokeOpacity = 5;
series.yAxis = valueAxis;
series.name = name;
series.tooltipText = "{name}: [bold]{valueY}[/]";
let interfaceColors = new am4core.InterfaceColorSet();
let bullet = series.bullets.push( new am4charts.CircleBullet() );
bullet.circle.stroke = interfaceColors.getFor( "background" );
bullet.circle.strokeWidth = 2;
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.grid.template.disabled = true;
}
I know Am-chart have many properties to beautify things but I'm unable to find the exact property according to my requirement.
Any help from experts here.
Thanks in advance.
Finally I got the answer as I mention there is some AmChart property which I was unable to find that. It is nothing but "Positioning Axis Elements"
Just add these lines in dataAxis
dateAxis.renderer.minLabelPosition = 0.05;
dateAxis.renderer.maxLabelPosition = 0.95;
It works. :)

Add HTML Element On Top Of Amchart Instance

I can't find this in the documentation, but is it possible to add a custom div element on top of an Amchart Instance?
Such that:
<div class="container-fluid px-0 mx-0">
<div id="chartdiv"></div>
<ul>
<li>Thailand</li>
<li>Myanmar</li>
<li>Etc...</li>
</ul>
</div>
With the UL displaying at the bottom of the instance?
JS:
<script src="https://www.amcharts.com/lib/4/core.js"></script>
<script src="https://www.amcharts.com/lib/4/maps.js"></script>
<script src="https://www.amcharts.com/lib/4/geodata/worldUltra.js"></script>
<script src="https://www.amcharts.com/lib/4/themes/animated.js"></script>
<script>
am4core.useTheme(am4themes_animated);
var container = am4core.create("chartdiv", am4core.Container);
container.width = am4core.percent(100);
container.height = am4core.percent(100);
container.layout = "vertical";
// Create map instance
var chart = container.createChild(am4maps.MapChart);
// Set map definition
chart.geodata = am4geodata_worldUltra;
// Set projection
chart.projection = new am4maps.projections.Miller();
// Create map polygon series
var polygonSeries = chart.series.push(new am4maps.MapPolygonSeries());
// Exclude Antartica
polygonSeries.exclude = ["AQ"];
// Make map load polygon (like country names) data from GeoJSON
polygonSeries.useGeodata = true;
// Configure series
var polygonTemplate = polygonSeries.mapPolygons.template;
polygonTemplate.tooltipText = "{name}";
polygonTemplate.fill = am4core.color("#dcdcdc");
// Create hover state and set alternative fill color
var hs = polygonTemplate.states.create("hover");
hs.properties.fill = am4core.color("#a98239");
chart.events.on("ready", function(ev) {
chart.zoomToMapObject(polygonSeries.getPolygonById("TH"));
});
chart.zoomControl = new am4maps.ZoomControl();
chart.chartContainer.wheelable = false;
</script>
If I missed something in the docs, I apologize - hoping someone can point me in the right direction!
AmCharts is SVG based so everything in the chartdiv is controlled by the library and mostly contains SVG with a little bit of HTML, without any native options to include custom div objects. One potential workaround is to use a Label object and set its html property to include your HTML code. Note that this uses <foreignObject> to accomplish this, so you may need to be mindful of browser support (IE11, if that still matters).
Here's an example that creates a list on top of the chart
var label = chart.chartContainer.createChild(am4core.Label);
//label.isMeasured = false; //uncomment to make the label not adjust the rest of the chart elements to accommodate its placement
label.fontSize = 16;
label.x = am4core.percent(5);
label.horizontalCenter = "middle";
label.verticalCenter = "bottom";
label.html = "<ul><li>List item 1</li><li>List item 2</li></ul>";
label.toBack(); //move list to top of the chart area. See: https://www.amcharts.com/docs/v4/concepts/svg-engine/containers/#Ordering_elements
Demo:
// Create chart instance
var chart = am4core.create("chartdiv", am4charts.XYChart);
// Add data
chart.data = [{
"category": "Research",
"value": 450
}, {
"category": "Marketing",
"value": 1200
}, {
"category": "Distribution",
"value": 1850
}];
// Create axes
var categoryAxis = chart.xAxes.push(new am4charts.CategoryAxis());
categoryAxis.dataFields.category = "category";
categoryAxis.renderer.grid.template.location = 0;
//categoryAxis.renderer.minGridDistance = 30;
var valueAxis = chart.yAxes.push(new am4charts.ValueAxis());
// Create series
var series = chart.series.push(new am4charts.ColumnSeries());
series.dataFields.valueY = "value";
series.dataFields.categoryX = "category";
var label = chart.chartContainer.createChild(am4core.Label);
//label.isMeasured = false; //uncomment to make the label not adjust the rest of the chart elements to accommodate its placement
label.fontSize = 16;
label.x = am4core.percent(5);
label.horizontalCenter = "middle";
label.verticalCenter = "bottom";
label.html = "<ul><li>List item 1</li><li>List item 2</li></ul>";
label.toBack(); //move list to top of the chart area. See: https://www.amcharts.com/docs/v4/concepts/svg-engine/containers/#Ordering_elements
html, body { width: 100%; height: 100%; margin: 0;}
#chartdiv { width: 100%; height: 100%;}
<script src="//www.amcharts.com/lib/4/core.js"></script>
<script src="//www.amcharts.com/lib/4/charts.js"></script>
<div id="chartdiv"></div>

How to create a JavaScript stacked, semi-circle gauge chart with customized line widths?

I would like to be able to plot two or three values on one stacked gauge chart, similar to the following, with a light green, on top of another blue and a main thick value:
I have seen examples of these lines being separated, which would also do.
The first two need not be superimposed, but would be nice.
In looking at https://github.com/pguso/jquery-plugin-circliful, I can create multiple values on a chart but only in full-circle, not half-circle.
In the following JSFiddle, https://jsfiddle.net/0c8qaqaj/41/
<section class="container">
<h3>Circliful</h3>
<div class="row">
<div class="col-lg-4">
<div id="test-circle"></div>
</div> </div>
</section>
<script>
$( document ).ready(function() { // 6,32 5,38 2,34
$("#test-circle").circliful({
animation: 1,
animationStep: 5,
foregroundBorderWidth: 7,
backgroundBorderWidth: 7,
percent: 99,
textSize: 28,
textStyle: 'font-size: 12px;',
textColor: '#666',
multiPercentage: 1,
//halfCircle: 1,
halfCircle: false,
percentages: [
{'percent': 10, 'color': '#3180B8', 'title': 'Gryffindor' },
{'percent': 30, 'color': '#4ADBEA', 'title': 'Ravenclaw' },
{'percent': 50, 'color': '#49EBA8', 'title': 'Hufflepuff' },
{'percent': 70, 'color': '#FFCA35', 'title': 'Slytherin' }
],
multiPercentageLegend: 1,
replacePercentageByText: '',
backgroundColor: '#eee',
icon: 'f0d0',
iconPosition: 'middle',
iconColor: '#273B4E'
});
});
</script>
Setting 'halfCircle: true', only draws one value. Obviously not what I'm looking for.
The library does have a sample with two values, although I'm not sure how to replicate this example and whether or not it would work in halfcircle or if I can create an array to stack these values.
In another test, using AMCharts, I was able to create a semi-circle, stacked gauge chart.
A few issues:
I am unable to change the chart line widths manually. They seem to be proportional to the larger of the chart's height or width setting.
Setting width: 350:
I cannot change the white-space/padding above/below the charts. This one is fixable using css position: relative; left: -150; or whatever works. I don't really want to have to do this for anything around sides (top, bottom, etc.)
The charts do not display in a '' tag. To get in-line charts, I am using table cells.
Here is the JSFiddle for it.
I managed to locate a closer example of what I'm looking for in Chart.JS
The issue remains that I still am unable achieve exactly what I'm looking for as once again, the line sizing seems to be directly proportional to the container. You can see this by resizing the window.
The question/problem: I am m looking for a library that gives me the ability to customize the line widths in semi-circular gauge/doughnut charts and not be auto-constrained to the chart's dimensions.
Any recommendations on another library that would give me what I'm looking for please?
There is more than one way to do it with amCharts 4, here is one:
am4core.useTheme(am4themes_animated);
var chart = am4core.create("chartdiv", am4charts.GaugeChart);
chart.innerRadius = am4core.percent(80);
var colorSet = new am4core.ColorSet();
var axis = chart.xAxes.push(new am4charts.ValueAxis());
axis.min = 0;
axis.max = 100;
axis.renderer.innerRadius = 10
axis.strictMinMax = true;
axis.renderer.labels.template.disabled = true;
axis.renderer.ticks.template.disabled = true;
axis.renderer.grid.template.disabled = true;
var range0 = axis.axisRanges.create();
range0.value = 0;
range0.endValue = 60;
range0.axisFill.fillOpacity = 1;
range0.axisFill.fill = colorSet.getIndex(0);
range0.grid.disabled = true;
var range1 = axis.axisRanges.create();
range1.value = 60;
range1.endValue = 100;
range1.axisFill.fillOpacity = 1;
range1.axisFill.fill = am4core.color("#DADADA");
range1.grid.disabled = true;
var axis2 = chart.xAxes.push(new am4charts.ValueAxis());
axis2.min = 0;
axis2.max = 100;
axis2.strictMinMax = true;
axis2.renderer.labels.template.disabled = true;
axis2.renderer.ticks.template.disabled = true;
axis2.renderer.grid.template.disabled = true;
var range2 = axis2.axisRanges.create();
range2.value = 0;
range2.endValue = 90;
range2.axisFill.fillOpacity = 1;
range2.axisFill.fill = colorSet.getIndex(3);
range2.axisFill.radius = am4core.percent(105);
range2.axisFill.innerRadius = am4core.percent(100); // set it to >100 if you'd like to have some gap between fills
range2.grid.disabled = true;
var range3 = axis2.axisRanges.create();
range3.value = 90;
range3.endValue = 100;
range3.axisFill.fillOpacity = 0.5;
range3.axisFill.fill = am4core.color("#DADADA");
range3.axisFill.radius = am4core.percent(105);
range3.axisFill.innerRadius = am4core.percent(100); // set it to >100 if you'd like to have some gap between fills
range3.grid.disabled = true;
var label = chart.radarContainer.createChild(am4core.Label);
label.isMeasured = false;
label.fontSize = 45;
label.x = am4core.percent(50);
label.y = am4core.percent(100);
label.horizontalCenter = "middle";
label.verticalCenter = "bottom";
label.text = "50%";
And this is a result: https://codepen.io/team/amcharts/pen/qgxyZK

AmChart not showing second y-axis

I have been assigned a task of displaying 2 charts in a graph, therefore I need two y-axis to represent the charts.
One axis will be on the left, the other on the right.
My problem is that only one y axis is showing.
As I am using amCharts, I have noticed one issue where the visible y Axis has an array called allLabels and it has elements in it, but the second y Axis does not, however I don't know
what fills up that array property.
Code:
function addconsumerUsageGraph(consumerUsageGraph) {
//You can ignore this
if (consumerUsageGraph.graphs.length == 2)
{
var gr1 = consumerUsageGraph.graphs[0];
var gr2 = consumerUsageGraph.graphs[1];
consumerUsageGraph.removeGraph(gr1);
consumerUsageGraph.removeGraph(gr2);
}
if (consumerUsageGraph.graphs.length == 1) {
var gr1 = consumerUsageGraph.graphs[0];
consumerUsageGraph.removeGraph(gr1);
}
//I add the two yAxis here:
var yAxis1 = new AmCharts.ValueAxis();
yAxis1.position = "left";
var yAxis2 = new AmCharts.ValueAxis();
yAxis2.position = "right"; // set this to "right" if you want it on the right
//Adding the value axis to the whole graph
consumerUsageGraph.addValueAxis(yAxis1);
consumerUsageGraph.addValueAxis(yAxis2);
var graph = new AmCharts.AmGraph();
graph.valueField = "value";
graph.type = "column";
graph.title = "Usage";
graph.lineAlpha = 1;
graph.fillAlphas = 0.75;
consumerUsageGraph.addGraph(graph);
var graph2 = new AmCharts.AmGraph();
graph2.valueField = "cost";
graph2.type = "line";
graph2.lineAlpha = 1;
graph2.title = "Cost";
graph2.lineColor = graphColour;
graph2.bullet = "round";
graph2.bulletAlpha = 0.5;
graph2.bulletBorderAlpha = 0.8;
//Assigning the second yAxis to the second graph
graph2.valueAxes = yAxis2;
consumerUsageGraph.addGraph(graph2);
//consumerUsageGraph.write("chartdiv");
var legend = new AmCharts.AmLegend();
legend.marginBottom = -10;
legend.useGraphSettings = true;
consumerUsageGraph.addLegend(legend);
}
How the chart looks now:
graph doesn't have property valueAxes, use valueAxis instead:
graph2.valueAxis = yAxis2;

Categories