let chart = am4core.create("chartdiv", am4charts.XYChart);
chart.background.image = am4core.image("/static/img/bar-chart.png")
In Amchart i am trying to add background image over my chart.
But it is not working while i am doing this.
Please take a look if there is any way
I modified the watermark tutorial
// Add watermark
var watermark = new am4core.Image();
watermark.href = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-160/cat.svg";
chart.plotContainer.children.push(watermark);
watermark.align = "right";
watermark.valign = "bottom";
watermark.opacity = 0.3;
watermark.marginRight = 10;
watermark.marginBottom = 5;
like this:
// Add watermark
var watermark = new am4core.Image();
watermark.href = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/t-160/cat.svg";
chart.plotContainer.children.push(watermark);
watermark.align = "center";
watermark.valign = "bottom";
watermark.opacity = 0.3;
watermark.height = 200;
watermark.width = 200;
Based on what do you need you might have to modify opacity, height and width.
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 would like to make a doughnut chart using Chart.Js library, with text in the center of the doughnut and the percentage on each segment.
The segments on the chart are generated dynamically.
So I look through Stackoverflow to look for solution, and combined 2 that I found:
How to create a donut chart like this in chart.js
How to add text inside the doughnut chart using Chart.js?
and combine into the following javascript:
Chart.defaults.derivedDoughnut = Chart.defaults.doughnut;
var helpers = Chart.helpers;
var customDN = Chart.controllers.doughnut.extend({
draw: function(ease) {
Chart.controllers.doughnut.prototype.draw.call(this, ease);
if (this.chart.config.options.elements.center) {
//Get ctx from string
var ctx = this.chart.chart.ctx;
//Get options from the center object in options
var centerConfig = this.chart.config.options.elements.center;
var fontStyle = centerConfig.fontStyle || 'Arial';
var txt = centerConfig.text;
var color = centerConfig.color || '#000';
var sidePadding = centerConfig.sidePadding || 20;
var sidePaddingCalculated = (sidePadding/100) * (this.chart.innerRadius * 2)
//Start with a base font of 30px
ctx.font = "30px " + fontStyle;
//Get the width of the string and also the width of the element minus 10 to give it 5px side padding
var stringWidth = ctx.measureText(txt).width;
var elementWidth = (this.chart.innerRadius * 2) - sidePaddingCalculated;
// Find out how much the font can grow in width.
var widthRatio = elementWidth / stringWidth;
var newFontSize = Math.floor(20 * widthRatio);
var elementHeight = (this.chart.innerRadius * 2);
// Pick a new font size so it will not be larger than the height of label.
var fontSizeToUse = Math.min(newFontSize, elementHeight);
//Set font settings to draw it correctly.
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
var centerX = ((this.chart.chartArea.left + this.chart.chartArea.right) / 2);
var centerY = ((this.chart.chartArea.top + this.chart.chartArea.bottom) / 2);
ctx.font = fontSizeToUse+"px " + fontStyle;
ctx.fillStyle = color;
//Draw text in center
ctx.fillText(txt, centerX, centerY);
//labels
var chart = this.chart;
var chartArea = chart.chartArea;
var opts = chart.options;
var meta = this.getMeta();
var arcs = meta.data;
for (i in arcs){
var arcctx = arcs[i]._chart.ctx;
var view = arcs[i]._view;
var sa = view.startAngle;
var ea = view.endAngle;
var opts = arcs[i]._chart.config.options;
var labelPos = arcs[i].tooltipPosition();
var segmentLabel = view.circumference / opts.circumference*100;
arcctx.fillStyle = view.borderColor;
arcctx.font = "1px" + fontStyle;
arcctx.fillText(segmentLabel.toFixed(0) + "%", labelPos.x, labelPos.y);
}
}
}
});
but my outcome is outcome image
I tried fixing the font of the arc, but it still does not work. It seems to utilize the font set for the text in the center of the doughnut.
Can someone tell me what did I do wrong here, how do I set the font size of the arc and text in the center of the doughnut differently? Thanks!
Is there a good way to remove duplicate data labels in Chartjs? Or a good way to space labels out better above data points so they are not on top of each other?
Chart.plugins.register({
afterDatasetsDraw: function(chart, easing) {
// To only draw at the end of animation, check for easing === 1
var ctx = chart.ctx;
chart.data.datasets.forEach(function (dataset, i) {
var meta = chart.getDatasetMeta(i);
if (!meta.hidden) {
meta.data.forEach(function(element, index) {
// Draw the text in black, with the specified font
ctx.fillStyle = 'rgb(255, 255, 255)';
var fontSize = 12;
var fontStyle = 'normal';
var fontFamily = 'Arial';
ctx.font = Chart.helpers.fontString(fontSize, fontStyle, fontFamily);
// Just naively convert to string for now
var dataString = dataset.data[index].toString();
// Make sure alignment settings are correct
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
var bodySpacing = 3;
var padding = 10;
var position = element.tooltipPosition();
ctx.fillText(dataString, position.x, position.y - (fontSize / 2) - padding);
});
}
});
}
});
To clarify, the data is my data. The code is taken from the chartjs sample data labeling page and basically pasted in.
Visit this chart Style in chart.js library. It show list of all data on specific point. Here is link
I was making a web game just for a little practice, but my drawing will not show in the canvas element of the browser. I do not know why it will not show. By the way, I used variables as the value of the horizontal position so that I could easily change them later.
JavaScript
var canvas = getElementById('myCanvas');
var blt = canvas.getContext('2d');
var bS = 20;
var x = 220;
var y = 340;
var x1 = 227;
var x2 = 229;
var x3 = 240;
var x4 = 251;
var x5 = 253;
var x6 = 260;
function drawShip() {
blt.beginPath();
blt.moveTo(x,360);
blt.lineTo(x,340);
blt.lineTo(x1,337);
blt.lineTo(x2,337);
blt.lineTo(x2,340);
blt.lineTo(x3,330);
blt.lineTo(x4,340);
blt.lineTo(x4,337);
blt.lineTo(x5,337);
blt.lineTo(x6,340);
blt.lineTo(x6,360);
blt.lineTo(x,360);
blt.closePath();
};
drawShip();
You need to use the stroke() method to draw the path as a line.
Here you can find every canvas methods and some documentation and examples:
http://www.w3schools.com/tags/ref_canvas.asp
You forgot to stroke the path. Add this after blt.closePath()
blt.stroke();
In your code change the line
var canvas = getElementById('myCanvas');
by
var canvas = document.getElementById('myCanvas');
and add blt.stroke(); after blt.closePath();
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);