apache / echarts

Apache ECharts is a powerful, interactive charting and data visualization library for browser
https://echarts.apache.org
Apache License 2.0
60.29k stars 19.61k forks source link

[Feature] candlestick y-axis scalable #16491

Open SanLeen opened 2 years ago

SanLeen commented 2 years ago

What problem does this feature solve?

Sincerely hope to add it to make Candlestick-Chart easier to use and easy to customize.

like this

_scg15

What does the proposed API look like?

setOption({
  ...,
  series: [
    {
      type: 'candlestick',
      yAxisScalable: boolean,  // 👈
    }
  ],
});
pissang commented 2 years ago

Perhaps adding a dataZoom on the yAxis can meet part of the feature.

{
  type: 'slider',
  yAxisIndex: 0
}
SanLeen commented 2 years ago

@pissang I have tried using dataZoom to achieve.

Problems

  1. filterMode gets weird

filterMode: 'filter'

_scg10

filterMode: 'weakFilter'

_scg11

  1. Due to the upper and lower restrictions, it cannot be freely dragged up and down

_scg12

Desired Result

_scg13

Demo Code

function splitData(rawData: number[][]) {
  let categoryData = [];
  let values = [];
  let volumes = [];
  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]);
  }

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

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

  myChart.setOption(
    (option = {
      animation: false,
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'cross'
        }
      },
      axisPointer: {
        link: [
          {
            xAxisIndex: 'all'
          }
        ],
        label: {
          backgroundColor: '#777'
        }
      },
      grid: [
        {
          left: '10%',
          right: '8%',
          height: '50%'
        },
        {
          left: '10%',
          right: '8%',
          top: '63%',
          height: '16%'
        }
      ],
      xAxis: [
        {
          type: 'category',
          data: data.categoryData,
          boundaryGap: false,
          axisLine: { onZero: false },
          splitLine: { show: false },
          min: 'dataMin',
          max: 'dataMax',
          axisPointer: {
            z: 100
          }
        },
        {
          type: 'category',
          gridIndex: 1,
          data: data.categoryData,
          boundaryGap: false,
          axisLine: { onZero: false },
          axisTick: { show: false },
          splitLine: { show: false },
          axisLabel: { show: false },
          min: 'dataMin',
          max: 'dataMax'
        }
      ],
      yAxis: [
        {
          scale: true,
          splitArea: {
            show: true
          }
        },
        {
          scale: true,
          gridIndex: 1,
          splitNumber: 2,
          axisLabel: { show: false },
          axisLine: { show: false },
          axisTick: { show: false },
          splitLine: { show: false }
        }
      ],
      dataZoom: [
        {
          type: 'inside',
          xAxisIndex: [0, 1],
          start: 98,
          end: 100
        },
        {
          show: true,
          xAxisIndex: [0, 1],
          type: 'slider',
          top: '85%',
          start: 98,
          end: 100
        },
        {
          type: 'inside',
          yAxisIndex: 0,
        },
        {
          type: 'slider',
          yAxisIndex: 0,
          right: '2%',
          // filterMode: 'weakFilter', // 👈 switch filterMode
        }
      ],
      series: [
        {
          name: 'Dow-Jones index',
          type: 'candlestick',
          data: data.values
        },
        {
          name: 'Volume',
          type: 'bar',
          xAxisIndex: 1,
          yAxisIndex: 1,
          data: data.volumes
        }
      ]
    }),
    true
  );
});
pissang commented 2 years ago

filterMode gets weird

filterMode: 'weakFilter' can be used with clip: true to get the best result.

Due to the upper and lower restrictions, it cannot be freely dragged up and down

It will be a bit tricky but you can fix yAxis.min and yAxis.max, then set a initial dataZoom.start and dataZoom.end to focus on the main zone.

SanLeen commented 2 years ago

filterMode: 'weakFilter' can be used with clip: true to get the best result.

clip: true not work

...
series: [
        {
          name: 'Dow-Jones index',
          type: 'candlestick',
          data: data.values,
          clip: true ,
        },
        ...
      ]
...

preview

github-actions[bot] commented 7 months ago

This issue has been automatically marked as stale because it did not have recent activity. It will be closed in 7 days if no further activity occurs. If you wish not to mark it as stale, please leave a comment in this issue.

SanLeen commented 7 months ago

🤔