javascriptecharts

How to show tooltip when click markLine in echarts


My requirement is:

User could leave comment for the chart and in the chart, it will show a green vertical line if any comments. When user clicks the vertical line, it should open a text box or tooltip showing the exact comments content.

I created an example:

var dom = document.getElementById("chart-container");
var myChart = echarts.init(dom, null, {
  renderer: "canvas",
  useDirtyRect: false,
});
var app = {};

var option;

var svgIconStr = `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="22" viewBox="0 0 20 22" fill="none">
<path d="M10 20L9.79075 20.4541L10 20.5505L10.2092 20.4541L10 20ZM10 20C10.2092 20.4541 10.2094 20.454 10.2096 20.4539L10.2102 20.4537L10.2119 20.4529L10.2177 20.4502L10.2383 20.4405C10.2559 20.4321 10.2814 20.42 10.3142 20.404C10.3798 20.3721 10.4746 20.325 10.5945 20.2632C10.8343 20.1394 11.1746 19.9562 11.5822 19.7158C12.3961 19.2357 13.4835 18.5243 14.5734 17.6001C16.7356 15.7664 19 13.0143 19 9.5C19 4.52944 14.9706 0.5 10 0.5C5.02944 0.5 1 4.52944 1 9.5C1 13.0143 3.26439 15.7664 5.42661 17.6001C6.5165 18.5243 7.60392 19.2357 8.41784 19.7158C8.82535 19.9562 9.16572 20.1394 9.40545 20.2632C9.52535 20.325 9.62018 20.3721 9.68577 20.404C9.71856 20.42 9.74405 20.4321 9.76172 20.4405L9.7823 20.4502L9.78806 20.4529L9.7898 20.4537L9.79037 20.4539C9.79058 20.454 9.79075 20.4541 10 20Z" fill="#05823F" stroke="white"/>
<path d="M6.5 7.58887C6.5 6.76044 7.17157 6.08887 8 6.08887H12C12.8284 6.08887 13.5 6.76044 13.5 7.58887V13.6671C13.5 14.1219 12.9421 14.3406 12.6331 14.0068L10 11.1629L7.36689 14.0068C7.05791 14.3406 6.5 14.1219 6.5 13.6671V7.58887Z" fill="white"/>
</svg>`;

option = {
  xAxis: {
    type: "time",
  },
  yAxis: {
    type: "value",
  },
  tooltip: {
    show: true,
    trigger: "axis",
  },
  series: [{
      name: "metric",
      type: "line",
      data: [
        [1041811200000, 30429.64],

        [1043625600000, 99323.95999999999],

        [1055116800000, 32376.289999999997],
        [1055721600000, 27628.299999999996],

        [1062374400000, 42592.52],
      ],

      showSymbol: false,
    },
    {
      id: "Annotation",
      name: "annotation",
      type: "line",
      tooltip: {
        trigger: "item",
      },
      data: [
        [1050883200000, null]
      ],
      markLine: {
        symbol: "none",
        label: {
          show: true,
          backgroundColor: "green",
          color: "white",
          formatter: "C",
          width: 20,
          height: 20,
          triggerEvent: true,
        },
        data: [{
          name: "MarkLine",
          xAxis: 1050883200000,
        }, ],
      },
    },
  ],
};

function encodeSvgToDataURI(svg) {
  return (
    "data:image/svg+xml;charset=utf8," +
    encodeURIComponent(
      svg.replace(
        "<svg",
        svg.indexOf("xmlns") > -1 ?
        "<svg" :
        '<svg xmlns="http://www.w3.org/2000/svg"'
      )
    )
  );
}

if (option && typeof option === "object") {
  myChart.setOption(option);
}

myChart.on("click", (params) => {
  console.log("clicked params", params);
});

window.addEventListener("resize", myChart.resize);
* {
  margin: 0;
  padding: 0;
}

#chart-container {
  position: relative;
  height: 100vh;
  overflow: hidden;
}
<div id="chart-container"></div>
<script src="https://fastly.jsdelivr.net/npm/echarts@5.5.1/dist/echarts.min.js"></script>

The question is

  1. When i click markLine, it will trigger an click event, but i only need the click event triggered when user clicks the label.
  2. I have no idea to show the tooltip in this case.

Could anyone please help me on this, thank you so much!

enter image description here


Solution

  • Here is a small example to give you an idea how it could be done. The event.target.name property seems to equal 'line' if you click on the markLine instead of the icon, which allows to differentiate between them. Further you can add/remove a new markpoint without icon as a comment, in a location of your choice.

    Example:

    var svgIconStr = `<svg xmlns="http://www.w3.org/2000/svg" width="20" height="22" viewBox="0 0 20 22" fill="none">
    <path d="M10 20L9.79075 20.4541L10 20.5505L10.2092 20.4541L10 20ZM10 20C10.2092 20.4541 10.2094 20.454 10.2096 20.4539L10.2102 20.4537L10.2119 20.4529L10.2177 20.4502L10.2383 20.4405C10.2559 20.4321 10.2814 20.42 10.3142 20.404C10.3798 20.3721 10.4746 20.325 10.5945 20.2632C10.8343 20.1394 11.1746 19.9562 11.5822 19.7158C12.3961 19.2357 13.4835 18.5243 14.5734 17.6001C16.7356 15.7664 19 13.0143 19 9.5C19 4.52944 14.9706 0.5 10 0.5C5.02944 0.5 1 4.52944 1 9.5C1 13.0143 3.26439 15.7664 5.42661 17.6001C6.5165 18.5243 7.60392 19.2357 8.41784 19.7158C8.82535 19.9562 9.16572 20.1394 9.40545 20.2632C9.52535 20.325 9.62018 20.3721 9.68577 20.404C9.71856 20.42 9.74405 20.4321 9.76172 20.4405L9.7823 20.4502L9.78806 20.4529L9.7898 20.4537L9.79037 20.4539C9.79058 20.454 9.79075 20.4541 10 20Z" fill="#05823F" stroke="white"/>
    <path d="M6.5 7.58887C6.5 6.76044 7.17157 6.08887 8 6.08887H12C12.8284 6.08887 13.5 6.76044 13.5 7.58887V13.6671C13.5 14.1219 12.9421 14.3406 12.6331 14.0068L10 11.1629L7.36689 14.0068C7.05791 14.3406 6.5 14.1219 6.5 13.6671V7.58887Z" fill="white"/>
    </svg>`;
    
    option = {
      xAxis: {
        type: "time",
      },
      yAxis: {
        type: "value",
      },
      tooltip: {
        show: true,
        trigger: "axis",
      },
      series: [{
          id: "metric",
          name: "metric",
          type: "line",
          data: [
            [1041811200000, 30429.64],
    
            [1043625600000, 99323.95999999999],
    
            [1055116800000, 32376.289999999997],
            [1055721600000, 27628.299999999996],
    
            [1062374400000, 42592.52],
          ],
    
          showSymbol: false,
        },
        {
          id: "annotation",
          name: "annotation",
          type: "line",
          tooltip: {
            trigger: "item",
          },
          data: [
            [1050883200000, null]
          ],
          markLine: {
            symbol: "none",
            label: {
              show: true,
              backgroundColor: "green",
              color: "white",
              formatter: "C",
              width: 20,
              height: 20,
            },
            data: [{
              name: "MarkLine",
              xAxis: 1050883200000,
            }, ],
          },
        },
      ],
    };
    
    function encodeSvgToDataURI(svg) {
      return (
        "data:image/svg+xml;charset=utf8," +
        encodeURIComponent(
          svg.replace(
            "<svg",
            svg.indexOf("xmlns") > -1 ?
            "<svg" :
            '<svg xmlns="http://www.w3.org/2000/svg"'
          )
        )
      );
    }
    
    if (option && typeof option === "object") {
      myChart.setOption(option);
    }
    
    let commentOpen = false;
    myChart.on("click", (params) => {
      const event = params.event;
      if(params.name === 'MarkLine' && event.target.name !== 'line') {
        console.log("icon clicked");
        if (commentOpen) {
          commentOpen = false;
          myChart.setOption({series: [{id: 'metric'}, {id: 'annotation'}]}, {replaceMerge: ['series']});
        } else {
          commentOpen = true;
          myChart.setOption({
            series: [{
              id: 'comment',
              type: 'custom',
              data: [],
              markPoint: {
                itemStyle: {color: 'transparent'},
                data: [{name: 'comment', x: event.offsetX, y: event.offsetY}],
                label: {show: true, formatter: "This is a comment"}
              },
            }]
          });
        }
      }
    });