I am working on amCharts Donut chart.
Following is the script for creating the chart.
JS
var chart = AmCharts.makeChart( "chartdiv", {
"type": "pie",
"pullOutDuration":0.5,
"pullOutRadius": "5",
"theme": "light",
"dataProvider": [ {
"title": "Aaa",
"value": 10,
}, {
"title": "Bbb",
"value": 10,
},{
"title":"Ccc",
"value":10,
},{
"title":"Ddd",
"value":10,
},{
"title":"Eee",
"value":10,
}],
"titleField": "title",
"valueField": "value",
"labelRadius": 50,
"radius": "35%",
"innerRadius": "85%",
"labelText": "[[title]]",
"export": {
"enabled": true
},
"baseColor":"#7a4436",
"pullOutOnlyOne":true,
"startEffect":"easeOutSine",
"pullOutEffect":"easeOutSine",
"showBalloon":false,
"listeners": [{
"event": "clickSlice",
"method": function(e) {
var dp = e.dataItem.dataContext;
alert(dp.title + ':'+dp.value)
e.chart.validateData();
}
}]
});
I am able to give click event listener for each slice of the chart.
But I would like to add a click event for label of each slice. So here in my example click event for the labels Aaa, Bbb, etc..
Edit
or how to give an anchor tag to these Labels??
Here is the working fiddle demo
Normally the listener for clickSlice is only attached to the wedge and the little tick to the label, but not to the label itself.
You can do this manually though, using this code piece:
chart.addListener("init", function() {
var d = chart.chartData;
for (var i = 0; i < d.length; i++) {
d[i].label.node.style.pointerEvents = "auto";
chart.addEventListeners(d[i].labelSet, d[i]);
}
});
As the labels have the pointer-events style assigned to none automatically, you have to change this back, so the mouse-events can be registered. Then you can add a listener manually to the svg element using a method provided by the chart.
You have to do this after the chart was initialized. However if you want to remain the e.chart.validateData() call in your handler, you have to listen on a different event (like drawn).
If the purpose of e.chart.validateData() was to stop a slice to be pulled out, the better way to do this would be using pullOutRadius: 0
Here's a demo.
Updated simple answer for v4:
const yAxisLabel = mySeries.bullets.push(new am4charts.LabelBullet());
yAxisLabel.label.interactionsEnabled = false;
Related
I draw a default OHLC chart. Then add a simple scatter series to it.
I set chart level config to share tooltips.
tooltip: { shared: true }.
But two series won't share tooltips at all.
Another big problem is that I cannot control the mouse hover effect on the new series. If you try the demo below, after clicking the AddSeries button at the bottom, the newly added series will be highlighted on mouse hover. I try to remove the mouse over effect and control it with the lineWidthPlus parameter, but there is no effect on the newly added series. Can anyone shed some light on this?
"hover": {
"enabled": false
},
https://jsfiddle.net/2t7fg9rc/
What do you think about adding the line series instead of scatter? I cannot see the hover issue that you described while using the line series.
var seriesConfig = {
"data": [
[1557322200000, 50.72],
[1566999000000, 51.03],
[1577197800000, 70.73],
[1588858200000, 75.93],
[1601040600000, 108.43],
[1620394200000, 130.85]
],
"type": "line",
"id": "Indicator",
"name": "Indicator",
"yAxis": 0,
"color": "rgb(256,0,0,0.75)",
"marker": {
enabled: true,
"symbol": "circle",
"radius": "2"
},
"showInNavigator": false,
"showInLegend": true,
"states": {
"inactive": {
"opacity": 1
},
"hover": {
"enabled": false
},
"stickyTracking": false
}
};
Demo: https://jsfiddle.net/BlackLabel/hfzwd8Lc/
im trying to figure out how I can add a tooltip when I hover/mouseover the vertical line annotation I've drawn:
annotation: {
annotations: [{
"drawTime": "afterDatasetsDraw",
"type": "line",
"mode": "vertical",
"scaleID": "x-axis-0",
"value": "2020-04-01 12:20:27.709523",
"borderWidth": 2,
"borderColor": "red",
"label": {
"content": "Example Content",
"enabled": true,
"position": "top"
},
onMouseover: function(e) {
console.log("I AM GETTING CALLED!");
},
},
Can anybody explain how this can be done?
Not directly answering your question, but you can modify the chart and annotations in any way you prefer (in ChartJS v3) by accessing the context chart and element (docs)
I used this to change style of annotation on hover (in TypeScript):
enter: (context) => {
const id = context.element.options.id!;
((context.chart.options.plugins!.annotation!.annotations as any)[id] as AnnotationOptions).borderColor = 'blue';
context.chart.canvas.style.cursor = 'pointer';
context.chart.update();
},
leave: (context) => {
const id = context.element.options.id!;
((context.chart.options.plugins!.annotation!.annotations as any)[id] as AnnotationOptions).borderColor = 'rgb(255, 99, 132)';
context.chart.canvas.style.cursor = 'default';
context.chart.update();
},
Recently I changed Floats to FlexBox to have easier work with panels (as advised on other questions I did). While most of the things are working as I expect it, I'm having a problem with Apex Charts after the change.
Full code is here:
https://github.com/EvotecIT/PSWriteHTML/blob/master/Examples/Example12-Charts/Example12.html
Here's how it looks when loaded. You will notice that in 1st and 2nd-row charts go out of bounds even thou the panel they are in is in place and it works for the top row.
And if I do resize (like 1mm) it will start working correctly.
Any idea what could be the problem?
In apex charts CSS it has comments to not use overflow (I tried and it doesn't do anything) but to be honest, I even once forgot to attach that CSS and nothing changed (like everything is done by the JS.
.apexcharts-canvas {
position: relative;
user-select: none;
/* cannot give overflow: hidden as it will crop tooltips which overflow outside chart area */
}
/* scrollbar is not visible by default for the legend, hence forcing the visibility */
Keep in mind that I'm a total noob when it comes to JS/CSS/HTML so excuse my language.
You need to move all your scripts to the end instead of injecting in the HTML to allow the SVG Document parser to get the element's size correctly.
Working Codepen Example
var options = {
"chart": {
"height": 350,
"type": "line",
"toolbar": {
"show": true,
"tools": {
"download": true,
"selection": true,
"zoom": true,
"zoomin": true,
"zoomout": true,
"pan": true,
"reset": true
},
"autoSelected": "zoom"
}
},
"plotOptions": {
"bar": {
"horizontal": true
}
},
"dataLabels": {
"enabled": true,
"offsetX": -6,
"style": {
"fontSize": "12px",
"colors": [
null
]
}
},
"series": [{
"name": "People count",
"data": [
400,
430,
448
]
},
{
"name": "People death",
"data": [
450,
0,
200
]
}
],
"xaxis": {
"type": "category",
"categories": [
"2015",
"2016",
"2017"
]
},
"stroke": {
"show": true,
"curve": "straight",
"width": 2,
"colors": [
"#0000ff",
"#008000"
]
},
"legend": {
"position": "right",
"offsetY": 100,
"height": 230
},
"title": {
}
}
var chart = new ApexCharts(document.querySelector('#ChartID-2rhiatbe'),
options
);
chart.render();
I need to zoom my chart to a specified period on init event.
"listeners": [{
"event": "zoomed",
"method": this.calulateMetrics
},{
"event": "dataUpdated",
"method": this.showPeriod
}, {
"event": "init",
"method": this.showPeriod
},{
"event": "rendered",
"method": this.showPeriod
}],
showPeriod(event) {
// Retrieve the data
let dates = this.$store.getters.getDates
let startDate = dates[0]
let endDate = (dates[dates.length - 1])
endDate.setHours(22)
try {
this.chart.zoom(startDate, endDate)
console.log("Last date", endDate)
} catch(err) {
console.log("Error",(err.message))
}
},
Although I can't catch any errors the period remains the same.
Beside init I tried rendered and dataUpdated but it didn't help me either.
But when I trigger the call to external event <v-btn v-on:click="showPeriod">Button</v-btn> it works fine.
The whole options file is following:
this.chart = window.AmCharts.makeChart("chartdiv", {
"path": AmCharts_path,
"type": "stock",
"theme": "light",
"dataSets": this.$store.state.portfoliosData.performance.map(function (port, idx) {
return {
"title": port.name,
"fieldMappings": [{
"fromField": "value",
"toField": "value"
}],
"dataProvider": port.data,
"compared": (idx === 0 ? false : true),
"categoryField": "date"
}
}),
"panels": [{
"title": "Value",
"percentHeight": 70,
"stockGraphs": [
{
"id": "g1",
"valueField": "value",
"comparable": true,
"compareField": "value",
"balloonFunction": this.ballonRender,
"compareGraphBalloonFunction": this.ballonRender
}]
}],
"chartScrollbarSettings": {
"graph": "g1",
"markPeriodChange": true
},
"categoryAxis": {
"parseDates": true,
},
"categoryAxesSettings": {
"groupToPeriods": ["DD"]
},
"balloon": {
"fixedPosition": true,
"maxWidth": 10000,
"offsetY": 1,
},
"dataDateFormat": "YYYY-MM-DD",
"chartCursorSettings": {
"valueBalloonsEnabled": true,
"categoryBalloonEnabled": true,
"selectWithoutZooming": true,
"showNextAvailable": true,
"categoryBalloonAlpha": 0.8,
"bulletsEnabled": true,
"bulletSize": 10,
"valueZoomable":true,
"usePeriod": "DD",
"categoryBalloonDateFormats": [
{period:'fff',format:'JJ:NN:SS'},
{period:'ss',format:'JJ:NN:SS'},
{period:'mm',format:'JJ:NN'},
{period:'hh',format:'JJ:NN'},
{period:'DD',format:'EEEE, MMM DD'},
{period:'WW',format:'EEEE, MMM DD'},
{period:'MM',format:'MMM'},
{period:'YYYY',format:'YYYY'}
]
},
"periodSelector": {
"position": "bottom"
},
});
},
Reproduction link can be find here
The main issue is that AmCharts' listener callbacks don't understand your component scope. this in the callbacks refers to AmCharts' callback scope, not your component. Every AmCharts listener provides a reference to itself in the event's chart property (see init, for example), so changing all of your this.chart lines to event.chart in your callbacks will fix that part of the problem. If you need a reference to your component itself, add a custom property to the chart object in your renderGraph() method then refer to that through event.chart:
renderGraph() {
// ...
this.chart = window.AmCharts.makeChart("chartdiv", {
// ...
componentRef: this,
// ...
})
}
//example using initPeriod:
initPeriod(event) { //event parameter contains {type: "init", chart: stockChartReference}
console.log("init period")
let dates = event.chart.componentRef.$store.getters.getDates
let startDate = dates[0]
let endDate = (dates[dates.length - 1])
endDate.setHours(22)
try {
event.chart.zoom(startDate, endDate)
console.log("Last date", endDate)
} catch(err) {
console.log("Error",(err.message))
}
},
Your zoomed listener is refering to an undefined method called calulateMetrics. I see a method called calculateMetrics in amstore but I'm not sure if that's what you meant and changing it to that doesn't seem to work for me, so I defer to you on adding the appropriate method. Adding that missing method along with making sure that you refer to the chart object correctly like the other callbacks will fix your problem.
Demo for everything except zoomed due to the missing method: https://codesandbox.io/s/5wpopzwlnp
Here is an example of the AmSerialChart, in which you can use the scroll button to scroll the window over the data. When you reach the end (or beginning) and continue scrolling, the window will remain the same width.
Here is another example, using the AmStockChart. The window is zoomed in using a slightly different method: zoomToIndexes does not exist for stockCharts, thus the "zoom" method is used.
var chartData = generateChartData();
var chart = AmCharts.makeChart("chartdiv", {
"categoryAxesSettings": {
minPeriod: "fff",
},
"chartScrollbarSettings": {
graph: "g1",
usePeriod: "fff",
},
"dataSets": [
{
mouseWheelZoomEnabled: false,
categoryField: "date",
dataProvider: chartData,
fieldMappings: [
{
fromField: "gg1",
toField: "gg1"
}, {
fromField: "gg2",
toField: "gg2"
}
],
}
],
"mouseWheelScrollEnabled": true,
"panels": [
{
stockGraphs: [
{
id: "g1",
valueField: "gg1",
type: "step",
}
],
}, {
stockGraphs: [
{
valueField: "gg2",
type: "step",
}
],
}
],
"type": "stock",
});
When you scroll to the left in the StockChart, the window will reduce in size!
So far, I have not been able to identify a reason why the SerialChart does not reduce the size, while the StockChart does. I did find a post on SO that says to set mouseWheelZoomEnabled to false, however this option is for the SerialChart, not the StockChart.
I guess it is possible to add a listner to the scroll event, and prevent the window from reducing in size when it collides with the left or right side, however... I assume there is a better reason.
My question: How to prevent the window from reducing in size in the AmStockChart?
You have to set minSelectedTime in the panelsSettings to achieve the same behavior in a stock chart. Note that this will also prevent the scrollbar from zooming to a smaller time frame when dragging the sliders directly:
var chart = AmCharts.makeChart("chartdiv", {
panelsSettings: {
mouseWheelZoomEnabled: false,
minSelectedTime: 4.32e+9,
mouseWheelScrollEnabled: true
},
// ...
});
Demo