工具提示位置跟随鼠标并仅显示一次类别数据 - Apache ECharts

问题描述 投票:0回答:1

如何使工具提示跟随鼠标(出现在其旁边)并且工具提示仅显示类别数据(日期时间)一次,目前显示 3 次。还有一个小问题,我有 2 个卷系列,其中一个是倒置的,并且 0 值标签出现两次重叠,有什么方法可以解决这个问题吗?谢谢。

编辑器

function splitData(rawData: number[][]) {
  let categoryData = [];
  let values = [];
  let volumes = [];
  let volumesinv = [];
  for (let i = 0; i < rawData.length; i++) {
    categoryData.push(rawData[i].splice(0, 1)[0]);
    values.push(rawData[i]);
    volumes.push([i, rawData[i][4], rawData[i][0] > rawData[i][1] ? 1 : -1]);
    volumesinv.push([i, rawData[i][4], rawData[i][0] > rawData[i][1] ? 1 : -1]);
  }

  return {
    categoryData: categoryData,
    values: values,
    volumes: volumes,
    volumesinv: volumesinv
  };
}

function calculateMA(dayCount: number, data: { values: number[][] }) {
  var result = [];
  for (var i = 0, len = data.values.length; i < len; i++) {
    if (i < dayCount) {
      result.push('-');
      continue;
    }
    var sum = 0;
    for (var j = 0; j < dayCount; j++) {
      sum += data.values[i - j][1];
    }
    result.push(+(sum / dayCount).toFixed(3));
  }
  return result;
}

$.get(ROOT_PATH + '/data/asset/data/stock-DJI.json', function (rawData) {
  var data = splitData(rawData);

  myChart.setOption(
    (option = {
      animation: true,
      legend: {
        top: 10,
        left: 'center',
        data: ['MA5', 'MA10', 'MA20', 'MA30', 'Volume', 'Volumeinv']
      },
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'shadow'
        },
        borderWidth: 1,
        borderColor: '#ccc',
        padding: 10,
        textStyle: {
          color: '#000'
        },
        position: function (pos, params, el, elRect, size) {
          const obj: Record<string, number> = {
            top: 10
          };
          obj[['left', 'right'][+(pos[0] < size.viewSize[0] / 2)]] = 30;
          return obj;
        }
        // extraCssText: 'width: 170px'
      },
      axisPointer: {
        link: [
          {
            xAxisIndex: 'all'
          }
        ],
        label: {
          backgroundColor: '#777'
        }
      },
      grid: [
        {
          left: '10%',
          right: '8%',
          height: '50%'
        },
        {
          left: '10%',
          right: '8%',
          top: '63%',
          height: '16%'
        },
        {
          left: '10%',
          right: '8%',
          top: '79%',
          height: '16%'
        }
      ],
      xAxis: [
        {
          type: 'category',
          data: data.categoryData,
          boundaryGap: false,
          axisLine: { onZero: false },
          splitLine: { show: true },
          min: 'dataMin',
          max: 'dataMax',
          axisPointer: {
            z: 100
          }
        },
        {
          type: 'category',
          gridIndex: 1,
          data: data.categoryData,
          boundaryGap: true,
          axisLine: { onZero: false },
          axisTick: { show: false },
          splitLine: { show: false },
          axisLabel: { show: false },
          min: 'dataMin',
          max: 'dataMax'
        },
        {
          type: 'category',
          gridIndex: 2,
          data: data.categoryData,
          boundaryGap: true,
          axisLine: { show: false },
          axisTick: { show: false },
          splitLine: { show: false },
          axisLabel: { show: false },
          min: 'dataMin',
          max: 'dataMax'
        }
      ],
      yAxis: [
        {
          scale: true
        },
        {
          scale: true,
          gridIndex: 1,
          splitNumber: 2,
          axisLine: { show: false },
          axisTick: { show: false },
          splitLine: { show: false }
        },
        {
          scale: true,
          gridIndex: 2,
          splitNumber: 2,
          axisLine: { show: false },
          axisTick: { show: false },
          splitLine: { show: false },
          inverse: true
        }
      ],
      dataZoom: [
        {
          type: 'inside',
          xAxisIndex: [0, 1, 2],
          start: 99,
          end: 100
        }
      ],
      series: [
        {
          name: 'MA5',
          type: 'line',
          data: calculateMA(5, data),
          smooth: true,
          lineStyle: {
            opacity: 0.5
          }
        },
        {
          name: 'MA10',
          type: 'line',
          data: calculateMA(10, data),
          smooth: true,
          lineStyle: {
            opacity: 0.5
          }
        },
        {
          name: 'MA20',
          type: 'line',
          data: calculateMA(20, data),
          smooth: true,
          lineStyle: {
            opacity: 0.5
          }
        },
        {
          name: 'MA30',
          type: 'line',
          data: calculateMA(30, data),
          smooth: true,
          lineStyle: {
            opacity: 0.5
          }
        },
        {
          name: 'Volume',
          type: 'bar',
          xAxisIndex: 1,
          yAxisIndex: 1,
          data: data.volumes
        },
        {
          name: 'Volumeinv',
          type: 'bar',
          xAxisIndex: 2,
          yAxisIndex: 2,
          data: data.volumesinv
        }
      ]
    }),
    true
  );

  myChart.dispatchAction({
    type: 'brush',
    areas: [
      {
        brushType: 'lineX',
        coordRange: ['2016-06-12', '2016-06-20'],
        xAxisIndex: 1
      }
    ]
  });
});
javascript typescript charts echarts
1个回答
0
投票

1.位置

正如您在评论中所述,您可以删除

position
属性,它将默认为您想要的内容 - 光标位置,稍作调整。

但是,如果您想对位置进行一些控制,则可以使用此:

position: function(pos, params, el, elRect, size) {
    if (pos[1] >= size.viewSize[1] - 205) {
        pos[1] = pos[1] - 205;
    }

    if (pos[0] >= size.viewSize[0] - 190) {
        pos[0] = pos[0] - 190;
    }
    return pos;
}

值 205 和 190 表示工具提示的宽度和高度,如果您接近底部或接近底部,则通过这些值调整

pos
会使其移动到光标左侧并向上移动。屏幕的右侧。


2.删除三重日期提及

这需要您引入

formatter
属性以及适当的回调。例如,以下内容保留了工具提示的原始外观,同时仅显示一次日期:

formatter: function(params) {
    let slimParams = {};
    params.forEach(function(item) {
        slimParams["date"] = item.name;

        // Are they moving averages?
        if (typeof item.value !== "object") {
            if (!slimParams.hasOwnProperty("ma")) {
                slimParams["ma"] = [];
            }

            slimParams["ma"].push({
                "name": item.seriesName,
                "value": item.value,
                "color": item.color,
                "marker": item.marker
            });
            // Case of Volume and Volumeinv
        } else {
            if (!slimParams.hasOwnProperty("volume")) {
                slimParams["volume"] = [];
            }
            slimParams["volume"].push({
                "name": item.seriesName,
                "value": item.value[1],
                "color": item.color,
                "marker": item.marker
            });
        }
    });

    let toolTipContent = `
        <div style="margin: 0px 0 0;line-height:1;">
          <div style="margin: 0px 0 0;line-height:1;">
          <div style="font-size:14px;color:#000;font-weight:400;line-height:1;">${slimParams["date"]}</div>
    `;

    slimParams["volume"].forEach(function(item) {
        let lineContainer = `
            <div style="margin: 0px 0 0;line-height:1;">
              ${item["marker"]}
              <span style="font-size:14px;color:#000;font-weight:400;margin-left:2px">${item["name"]}</span>
              <span style="float:right;margin-left:20px;font-size:14px;color:#000;font-weight:900">${item["value"]}</span>
              <div style="clear:both"></div>
            </div>
            <div style="clear:both"></div>
        `;

        let volumeContainer = `
            <div style="margin: 10px 0 0;line-height:1;">
              <div style="margin: 0px 0 0;line-height:1;">
              ${lineContainer}
              </div>
              <div style="clear:both"></div>
            </div>
            <div style="clear:both"></div>
        `;

        toolTipContent += volumeContainer;
    });

    toolTipContent += `
        <div style="margin: 20px 0 0;line-height:1;">
    `;

    slimParams["ma"].forEach(function(item) {
        let lineContainer = `
            <div style="margin: 0px 0 0;line-height:1;">
              ${item["marker"]}
              <span style="font-size:14px;color:#000;font-weight:400;margin-left:2px">${item["name"]}</span>
              <span style="float:right;margin-left:20px;font-size:14px;color:#000;font-weight:900">${item["value"]}</span>
              <div style="clear:both"></div>
            </div>
            <div style="clear:both"></div>
        `;

        let maContainer = `
            <div style="margin: 10px 0 0;line-height:1;">
            ${lineContainer}
            </div>
        `;

        toolTipContent += maContainer;
    });

    toolTipContent += `
              <div style="clear:both"></div>
            </div>
            <div style="clear:both"></div>
          </div>
    `;

    return toolTipContent;
}

您也可以使用

params
,但我发现稍微修剪一下并重新包装它更容易,这样我以后就可以使用它。将它们记录到
formatter
内的控制台,看看我的意思,并将它们与
slimParams
进行比较。


3.分离 x 轴

为此,您需要更改

grid
选项的配置方式。目前,您有:

grid: [
{
  left: '10%',
  right: '8%',
  height: '50%'
},
{
  left: '10%',
  right: '8%',
  top: '63%',
  height: '16%'
},
{
  left: '10%',
  right: '8%',
  top: '79%',
  height: '16%'
}
],

grid
选项中的第二个和第三个 JSON 负责第二个和第三个图表。它们的 x 轴重叠的原因是:

2nd
top = 63%
height = 16%
x axis position = top + height = 79%

3rd
top = 79%
height = irrelevant
x axis position = top = 79% <---- since it's an inverted graph

因此,您所需要做的就是更改其中一个(或两者)的顶部和/或更改其中一个(或两者)的高度。例如:

grid: [{
        left: '10%',
        right: '8%',
        height: '50%'
    },
    {
        left: '10%',
        right: '8%',
        top: '65%',
        height: '16%'
    },
    {
        left: '10%',
        right: '8%',
        top: '84%',
        height: '16%'
    }
],

您可以在这里看到最终结果。

© www.soinside.com 2019 - 2024. All rights reserved.