skip to Main Content

I’m trying to making a widget for time and have a view of my favorite stock on the stock market. So after some searching I’m using ECharts that seem the best since now.

However the charts in the examples on ECharts’s site should be completed because according to the definition they should have full and empty candles as well as colored ones.

  • Solid candles show that the current close price is less than the current open price.
  • Hollow candles show that the current close price is greater than the current open price.
  • Red candles show that the current close price is less than the previous close price.
  • Green candles show that the current close price is greater than the previous close price.

Source: Wikipedia – Candlestick chart (see the link if you want to know more)

Solid and hollow candles

So how to make a chart like this with candles solid and hollow.

How I would like it to be (but with colors):
Solid and hollow black and white
(Source: Wikipedia – Candlestick chart)

Colored like this https://ibb.co/1fhsPrf

(Source: tradingview.com – Title: Tesla)

Uniform volumn color

Also I want to know how to have the volumns all of a color (example: azure) (together on the same grid, candles and volumns, not 2 grids).

How I would like volumns:
Volumns all of one color


P.S.
I would also like to point out (if any of the creators of ECharts reads) that the volumns are sometimes a color that does not correspond to the rise or fall (e.g. it may happen that it is red if the stock goes up).

2

Answers


  1. Solution

    Candlestick solid and hollow display

    You can handle this by configuring the series-candlestick.itemStyle for the candlestick series.

    itemStyle: {
      color: 'transparent',     // Hollow candle (upward movement)
      color0: '#ec0000',        // Solid candle (downward movement)
      borderColor: '#00da3c',   // Border for hollow candles (upward movement)
      borderColor0: '#ec0000',  // Border for solid candles (downward movement)
    },
    

    Uniform volume color

    You can control this in the series-bar.itemStyle.

    {
      name: 'Volume',
      type: 'bar',
      xAxisIndex: 1,
      yAxisIndex: 1,
      itemStyle: {
        color: 'azure',  // Uniform volume color
      },
    }
    

    Example

    var chartDom = document.getElementById('main')
    var myChart = echarts.init(chartDom)
    var option
    
    const upColor = '#00da3c'
    const downColor = '#ec0000'
    
    var rawData = [["2004-01-02",10452.74,10409.85,10367.41,10554.96,168890000],["2004-01-05",10411.85,10544.07,10411.85,10575.92,221290000],["2004-01-06",10543.85,10538.66,10454.37,10584.07,191460000],["2004-01-07",10535.46,10529.03,10432,10587.55,225490000],["2004-01-08",10530.07,10592.44,10480.59,10651.99,237770000],["2004-01-09",10589.25,10458.89,10420.52,10603.48,223250000],["2004-01-12",10461.55,10485.18,10389.85,10543.03,197960000],["2004-01-13",10485.18,10427.18,10341.19,10539.25,197310000],["2004-01-14",10428.67,10538.37,10426.89,10573.85,186280000],["2004-01-15",10534.52,10553.85,10454.52,10639.03,260090000],["2004-01-16",10556.37,10600.51,10503.7,10666.88,254170000],["2004-01-20",10601.4,10528.66,10447.92,10676.96,224300000],["2004-01-21",10522.77,10623.62,10453.11,10665.7,214920000],["2004-01-22",10624.22,10623.18,10545.03,10717.4,219720000],["2004-01-23",10625.25,10568.29,10490.14,10691.77,234260000],["2004-01-26",10568,10702.51,10510.44,10725.18,186170000],["2004-01-27",10701.1,10609.92,10579.33,10748.81,206560000],["2004-01-28",10610.07,10468.37,10412.44,10703.25,247660000],["2004-01-29",10467.41,10510.29,10369.92,10611.56,273970000],["2004-01-30",10510.22,10488.07,10385.56,10551.03,208990000],["2004-02-02",10487.78,10499.18,10395.55,10614.44,224800000],["2004-02-03",10499.48,10505.18,10414.15,10571.48,183810000],["2004-02-04",10503.11,10470.74,10394.81,10567.85,227760000],["2004-02-05",10469.33,10495.55,10399.92,10566.37,187810000]]
    
    myChart.setOption(
      (option = {
        dataset: {
          source: rawData,
        },
        animation: false,
        legend: {
          bottom: 10,
          left: 'center',
          data: ['Dow-Jones index'],
        },
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'cross',
          },
        },
        axisPointer: {
          link: [
            {
              xAxisIndex: 'all',
            },
          ],
        },
        toolbox: {
          feature: {
            dataZoom: {
              yAxisIndex: false,
            },
          },
        },
        grid: [
          {
            left: '10%',
            right: '8%',
            height: '50%',
          },
          {
            left: '10%',
            right: '8%',
            top: '63%',
            height: '16%',
          },
        ],
        xAxis: [
          {
            type: 'category',
            boundaryGap: false,
            axisLine: { onZero: false },
            splitLine: { show: false },
            min: 'dataMin',
            max: 'dataMax',
          },
          {
            type: 'category',
            gridIndex: 1,
            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: 0,
            end: 100,
          },
          {
            show: true,
            xAxisIndex: [0, 1],
            type: 'slider',
            top: '85%',
            start: 0,
            end: 100,
          },
        ],
        series: [
          {
            name: 'Dow-Jones index',
            type: 'candlestick',
            // Changed
            itemStyle: {
              color: 'transparent',    // Hollow candles (upward movement)
              color0: downColor,       // Solid candles (downward movement)
              borderColor: upColor,    // Border for hollow candles (upward movement)
              borderColor0: downColor, // Border for solid candles (downward movement)
            },
          },
          {
            name: 'Volume',
            type: 'bar',
            xAxisIndex: 1,
            yAxisIndex: 1,
            // Added
            itemStyle: {
              color: 'azure',          // Uniform volume color
            },
          },
        ],
      })
    )
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/echarts.min.js"></script>
    
    <div id="main" style="width: 600px; height: 400px;"></div>

    More information

    Login or Signup to reply.
  2. To customize individual elements in a candlestick chart, I did some research. Initially, I intended to use the traditional approach where itemStyle.[parameter] is assigned a function instead of a fixed string value, but I encountered the same issue as described in apache/echarts #12840 issue.

    Following that, instead of using dataset.source for data transfer, I split the data set into two parts: values (candlestickData and volumeData for two series) and labels (dateData for X Axis). I extracted the dates as dateData and collected the remaining values as candlestickData and volumeData.

    By doing this, candlestickData and volumeData is passed to the series.data parameter, which allows for injecting custom itemStyle. When injecting a custom itemStyle, the item is an object rather than an array, where the data is added through the value parameter. See the example for details.

    var chartDom = document.getElementById('main')
    var myChart = echarts.init(chartDom)
    
    const upColor = '#00da3c'
    const downColor = '#ec0000'
    
    // You can assemble rawData based on any logic you choose, and apply the appropriate custom colors to the relevant places
    // Thats a static example, where 2nd item will custom
    var rawData = [
      ["2004-02-02", 10487.78, 10499.18, 10395.55, 10614.44, 224800000],
      // Changed, example custom item
      {
        value: ["2004-02-03", 10499.48, 10505.18, 10414.15, 10571.48, 183810000],
        itemStyle: {
          color: 'purple',
          color0: 'blue',
          borderColor: 'purple',
          borderColor0: 'blue',
        },
      },
      ["2004-02-04", 10503.11, 10470.74, 10394.81, 10567.85, 227760000],
      ["2004-02-05", 10469.33, 10495.55, 10399.92, 10566.37, 187810000],
    ]
    
    // Added
    let dateData = []        // for X axis
    let candlestickData = [] // for candlestick chart
    let volumeData = []      // for volume bars
    
    // Added
    // Process rawData to separate candlestick data and custom styles
    rawData.forEach(item => {
      // Standard item (only values)
      if (Array.isArray(item)) {
        dateData.push(item[0])                  // Date data
        candlestickData.push(item.slice(1, 5))  // [open, close, low, high]
        volumeData.push(item[5])                // Volume data
      }
      // Custom item with styling
      else if (item && item.value && Array.isArray(item.value)) {
        dateData.push(item.value[0])            // Date data
        candlestickData.push({
          value: item.value.slice(1, 5),        // [open, close, low, high]
          itemStyle: item.itemStyle             // Custom itemStyle
        })
        volumeData.push(item.value[5])          // Volume data
      }
    })
    
    myChart.setOption({
      animation: false,
      legend: {
        bottom: 10,
        left: 'center',
        data: ['Dow-Jones index'],
      },
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'cross',
        },
      },
      axisPointer: {
        link: [{ xAxisIndex: 'all' }],
      },
      toolbox: {
        feature: {
          dataZoom: { yAxisIndex: false },
        },
      },
      grid: [
        { left: '10%', right: '8%', height: '50%' },
        { left: '10%', right: '8%', top: '63%', height: '16%' },
      ],
      xAxis: [
        {
          type: 'category',
          // Added
          data: dateData,             // Use the date data here
          boundaryGap: false,
          axisLine: { onZero: false },
          splitLine: { show: false },
          min: 'dataMin',
          max: 'dataMax',
        },
        {
          type: 'category',
          gridIndex: 1,
          // Added
          data: dateData,             // Use the date data here
          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: 0,
          end: 100,
        },
        {
          show: true,
          xAxisIndex: [0, 1],
          type: 'slider',
          top: '85%',
          start: 0,
          end: 100,
        },
      ],
      series: [
        {
          name: 'Dow-Jones index',
          type: 'candlestick',
          // Added
          data: candlestickData,     // Processed data with custom styles
          // Changed
          itemStyle: {
            color: 'transparent',    // Default color for upward movement
            color0: downColor,       // Default color for downward movement
            borderColor: upColor,    // Default border color for upward movement
            borderColor0: downColor, // Default border color for downward movement
          },
        },
        {
          name: 'Volume',
          type: 'bar',
          // Added
          data: volumeData,          // Volume data
          xAxisIndex: 1,
          yAxisIndex: 1,
          // Added
          itemStyle: {
            color: 'azure',          // Uniform volume color
          },
        },
      ],
    })
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/echarts.min.js"></script>
    
    <div id="main" style="width: 600px; height: 400px;"></div>

    In my code, the sole purpose was to illustrate how you can assign custom colors to a specific element. Which element and the logic you want to apply is up to you; it’s an additional detail that’s not essential to the solution.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search