I'd like to add an annotations feature to my echarts diagram. It'll be marked as a green dotted line with a green square marker if there's any annotation. When the user clicks the green square marker, a popup will open to show the actual annotation.
When I run the command below, it's triggered whenever I click anywhere on the annotation marker line. How can I tell if the user clicks specifically on the green square marker?
myChart.on('click', "series.line", function(params) {
console.log('normal click series.markLine', params)
})
Here is the demo: https://codepen.io/lora999/pen/azbGPKY
If you explore params
in your myChart.on('click', "series.line", function(params){...
you can find ways to identify that the rectangle was clicked. The most straightforward one
seems to be params.event.target.type === 'rect'
(tested with renderer svg also):
myChart.on('click', "series.line", function(params) {
if(params.event.target.type === 'rect'){
console.log('Rectangle clicked');
// use params.data.name or params.data._id to further
// identify the target, if multiple annotations are added
}
});
Runnable snippet:
const myChart = echarts.init(document.getElementById("chart-container"), null, {
renderer: "canvas",
useDirtyRect: false,
});
const option = {
"useUTC": false,
"grid": {
"containLabel": true,
"left": 35,
"right": 40,
"top": 40,
"bottom": 40
},
"xAxis": {
"type": "time",
},
"yAxis": {
"type": "value",
},
"tooltip": {
appendTo: 'body',
"borderColor": "transparent",
"show": true,
"trigger": "axis",
enterable: true,
},
"legend": {
"orient": "horizontal",
"show": true,
"type": "scroll",
"bottom": 0,
},
"series": [
{
"name": "series1",
"data": [
[
1041811200000,
30429.64
],
[
1043625600000,
99323.95999999999
],
[
1050883200000,
4219.2
],
],
"connectNulls": true,
"type": "line",
"smooth": false,
"showSymbol": false,
},
{
id: 'Annotation',
name: 'annotation',
type: "line",
markLine: {
symbol: 'none',
label: {
show: true,
formatter: '{icon|}',
rich: {
icon: {
height: 20,
width: 20,
backgroundColor: 'green',
_id:'__test__'
},
_id:'__test__'
}
},
data: [
{
name: 'annotationLine',
xAxis: 1043625600000,
lineStyle: {
width: 2,
color:'green'
},
_id: 'annotationLine'
},
]
}
},
],
};
myChart.on('click', "series.line", function(params) {
if(params.event.target.type === 'rect'){
console.log('Rectangle clicked');
// use params.data.name or params.data._id to further
// identify the target, if multiple annotations are added
}
});
myChart.setOption(option);
window.addEventListener('resize', myChart.resize);
<div id="chart-container" style="height:400px; min-width: 800px"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.6.0/echarts.min.js"></script>
However, the safest solution is to separate the rectangle from the line,
make them two different annotations, the rectangle implemented as
a markPoint
:
const myChart = echarts.init(document.getElementById("chart-container"), null, {
renderer: "canvas",
useDirtyRect: false,
});
const option = {
"useUTC": false,
"grid": {
"containLabel": true,
"left": 35,
"right": 40,
"top": 40,
"bottom": 40
},
"xAxis": {
"type": "time",
},
"yAxis": {
"type": "value",
},
"tooltip": {
appendTo: 'body',
"borderColor": "transparent",
"show": true,
"trigger": "axis",
enterable: true,
},
"legend": {
"orient": "horizontal",
"show": true,
"type": "scroll",
"bottom": 0,
},
"series": [
{
"name": "series1",
"data": [
[
1041811200000,
30429.64
],
[
1043625600000,
99323.95999999999
],
[
1050883200000,
4219.2
],
],
"connectNulls": true,
"type": "line",
"smooth": false,
"showSymbol": false,
},
{
id: 'Annotation',
name: 'annotation',
type: "line",
markLine: {
symbol: 'none',
silent: true, // doesn't respond to click
label: {
show: false
},
data: [
{
name: 'annotationLine',
xAxis: 1043625600000,
lineStyle: {
width: 2,
color:'green'
},
_id: 'annotationLine'
},
]
},
markPoint: {
symbol: 'rect',
symbolSize: 20,
symbolOffset: [0, -10],
itemStyle: {
color: 'green'
},
label: {
show: false,
},
data: [
{
name: 'annotationPoint',
coord: [1043625600000, 100000],
_id: 'annotationPoint'
},
]
}
},
],
};
myChart.on('click', "series.line", function(params) {
// in this scenario, only the markPoint is responding to clicks; but if other items are
// added, params.componentType and/or params.data.name (or _id) may be used to identify the target
if(params.componentType === 'markPoint'){
console.log('Rectangle clicked', params.data.name);
}
})
myChart.setOption(option);
window.addEventListener('resize', myChart.resize);
<div id="chart-container" style="height:400px; min-width: 800px"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.6.0/echarts.min.js"></script>
or using the icon label, as in the original code (svg renderer used):
const myChart = echarts.init(document.getElementById("chart-container"), null, {
renderer: "svg",
useDirtyRect: false,
});
const option = {
"useUTC": false,
"grid": {
"containLabel": true,
"left": 35,
"right": 40,
"top": 40,
"bottom": 40
},
"xAxis": {
"type": "time",
},
"yAxis": {
"type": "value",
},
"tooltip": {
appendTo: 'body',
"borderColor": "transparent",
"show": true,
"trigger": "axis",
enterable: true,
},
"legend": {
"orient": "horizontal",
"show": true,
"type": "scroll",
"bottom": 0,
},
"series": [
{
"name": "series1",
"data": [
[
1041811200000,
30429.64
],
[
1043625600000,
99323.95999999999
],
[
1050883200000,
4219.2
],
],
"connectNulls": true,
"type": "line",
"smooth": false,
"showSymbol": false,
},
{
id: 'Annotation',
name: 'annotation',
type: "line",
markLine: {
symbol: 'none',
silent: true, // doesn't respond to click
label: {
show: false
},
data: [
{
name: 'annotationLine',
xAxis: 1043625600000,
lineStyle: {
width: 2,
color:'green'
},
_id: 'annotationLine'
},
]
},
markPoint: {
symbol: 'rect',
symbolSize: 20,
symbolOffset: [0, -10],
itemStyle: {
color: 'green'
},
label: {
show: false,
},
data: [
{
name: 'annotationPoint',
coord: [1043625600000, 100000],
_id: 'annotationPoint'
},
]
}
},
],
};
myChart.on('click', "series.line", function(params) {
// in this scenario, only the markPoint is responding to clicks; but if other items are
// added, params.componentType and/or params.data.name (or _id) may be used to identify the target
if(params.componentType === 'markPoint'){
console.log('Rectangle clicked', params.data.name);
}
});
myChart.setOption(option);
window.addEventListener('resize', myChart.resize);
<div id="chart-container" style="height:400px; min-width: 800px"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/echarts/5.6.0/echarts.min.js"></script>