javascriptchartsapexcharts

ApexCharts type line - background color


i have a simple js, html file, im using ApexCharts and want to handle the positive and negative parts of chart.

3 things about it:

  1. markers style (handled already)
  2. line color (handled already)
  3. the background gradient below the line (problem)

is there any way to add a background to the line type chart below the line?

desired chart : desired chart

  <div id="chart"></div>
  <script src="exp.js"></script>
const dataPoints = [-10, 3, -5, -18, -10, 12, 8]

const discreteMarkers = dataPoints.map((value, index) => {
  return {
    shape: "circle",
    size: 4,
    seriesIndex: 0,
    dataPointIndex: index,
    fillColor: "#ffffff",
    strokeColor: value >= 0 ? "#157446" : "#C13446",
    strokeWidth: 1,
  };
});

var options = {
  chart: {
    height: 380,
    type: "line",
    foreColor: '#aaa',
    zoom: {
      type: 'x',
      enabled: true,
      autoScaleYaxis: true
    },
  },
  series: [
    {
      name: "Series 1",
      data: dataPoints
    }
  ],
  stroke: {
    width: 5,
    curve: "monotoneCubic"
  },
  plotOptions: {
    line: {
      colors: {
        threshold: 0,
        colorAboveThreshold: '#157446',
        colorBelowThreshold: '#C13446',
      },
    },
  },
  markers: {
    discrete: discreteMarkers
  },
  grid: {
     borderColor: '#6D6D6D',
     strokeDashArray: 3,
  },
  xaxis: {
    categories: [
      "01 Jan",
      "02 Jan",
      "03 Jan",
      "04 Jan",
      "05 Jan",
      "06 Jan",
      "07 Jan"
    ]
  },
  stroke: {
      curve: 'smooth',
      width: 2
  },
};

var chart = new ApexCharts(document.querySelector("#chart"), options);

chart.render();

here is a link to check output. https://codepen.io/amirdoosti/pen/RNbQWPK


Solution

  • i figured it out. the plotOption has a property for area charts named fillTo :

    fillTo = When negative values are present in the area chart, this option fill the area either from 0 (origin) or from the end of the chart as illustrated below.

    area: {
      fillTo: "end",
    },
    

    also i handled the colors using fill property to show positive and negative values.

    andd... for better controlling data i made a function to set 0 label always in center of the chart. ( minY , minX ).


    i didnt check all versions of apexcharts but i was supposed to use my script in a nuxt2 app. so the compatible version with my nuxt app was 3.40. so i can tell this script can work from 3.40 version and higher

    const dataPoints = [-80, 3, -5, 100, -40, 120, 8];
    let lowest_point = Math.min(...dataPoints);
    let highest_point = Math.max(...dataPoints);
    
    let zero_stop_percent = 100 - (Math.abs(lowest_point) / (Math.abs(lowest_point) + highest_point)) * 100;
    const isNegativeHigher = Math.abs(lowest_point) > Math.abs(highest_point);
    
    const minY =
      Math.min(...dataPoints) === 0 && Math.max(...dataPoints) === 0
        ? -500
        : Math.min(...dataPoints) === 0 && Math.max(...dataPoints) > 0
        ? Math.max(...dataPoints) * -1
        : Math.abs(Math.min(...dataPoints)) < Math.max(...dataPoints)
        ? Math.max(...dataPoints) * -1
        : Math.min(...dataPoints);
    
    const maxY =
      Math.max(...dataPoints) === 0 && Math.min(...dataPoints) === 0
        ? 500
        : Math.max(...dataPoints) === 0 && Math.min(...dataPoints) < 0
        ? Math.abs(Math.min(...dataPoints))
        : Math.abs(Math.min(...dataPoints)) > Math.max(...dataPoints)
        ? Math.abs(Math.min(...dataPoints))
        : Math.max(...dataPoints);
    
    const discreteMarkers = dataPoints.map((value, index) => {
      return {
        shape: "circle",
        size: 4,
        seriesIndex: 1,
        dataPointIndex: index,
        fillColor: "#ffffff",
        strokeColor: value >= 0 ? "#157446" : "#C13446",
        strokeWidth: 1,
      };
    });
    var options = {
      // okayyy
      chart: {
        height: 250,
        width: 380,
        toolbar: {
          show: false,
        },
      },
      // okayyy
      series: [
        {
          name: "TEAMA",
          type: "area",
          data: dataPoints, // Your area chart data
          zIndex: 2,
        },
        {
          name: "TEAMB",
          type: "line",
          data: dataPoints, // Your area chart data
          zIndex: 1,
        },
      ],
      markers: {
        discrete: discreteMarkers,
      },
      fill: {
        type: "gradient",
        gradient: {
          shade: "light",
          type: "vertical",
          shadeIntensity: 0.5,
          opacityFrom: 0.2,
          opacityTo: 0.2,
          colorStops: [
            // area
            [
              {
                offset: 0,
                color: "#589F7E", // Green for positive values
                opacity: 0.15,
              },
              {
                offset: isNegativeHigher ? zero_stop_percent : 50,
                color: "#589F7E", // Transition at zero
                opacity: 0.15,
              },
              {
                offset: isNegativeHigher ? zero_stop_percent : 50,
                color: "#D98B95", // Red for negative values
                opacity: 0.15,
              },
              {
                offset: 100,
                color: "#FBF5F5",
                opacity: 0.1,
              },
            ],
            // line
            [
              {
                offset: 0,
                color: "#157446", // Green for positive values
                opacity: 1,
              },
              {
                offset: zero_stop_percent,
                color: "#157446", // Transition at zero
                opacity: 1,
              },
              {
                offset: zero_stop_percent,
                color: "#C13446", // Red for negative values
                opacity: 1,
              },
              {
                offset: 100,
                color: "#C13446",
                opacity: 1,
              },
            ],
          ],
        },
      },
      xaxis: {
        categories: ["12/20", "12/21", "12/22", "12/23", "12/24", "12/25", "12/26"],
        tooltip: {
          enabled: false,
        },
      },
      legend: {
        show: false,
      },
      tooltip: {
        enabled: true, // Disable tooltip entirely if unwanted
        shared: false, // Ensure no shared tooltip for markers
        x: {
          show: false,
        },
        y: {
          formatter(val) {
            return val;
          },
          title: {
            formatter(seriesName) {
              return "";
            },
          },
        },
        style: {
          fontSize: "12px",
          fontFamily: "iransansx",
          width: "fit-content",
        },
      },
      yaxis: {
        forceNiceScale: true,
        min: minY,
        max: maxY,
        tickAmount: 4,
        labels: {
          offsetX: -25,
          style: {
            colors: "#5B5C5F",
          },
          minWidth: 36,
          show: true,
        },
      },
      // okayyy
      stroke: {
        width: 2,
        curve: "smooth",
        colors: ["transparent"],
      },
    
      // okayyy
      plotOptions: {
        area: {
          fillTo: "end",
        },
      },
      grid: {
        borderColor: "#EAEAEB",
        strokeDashArray: 4,
        position: "back",
      },
    };
    
    var chart = new ApexCharts(document.querySelector("#chart"), options);
    chart.render();
    .apexcharts-datalabel,
          .apexcharts-datalabel-label,
          .apexcharts-datalabel-value,
          .apexcharts-datalabels,
          .apexcharts-pie-label {
            display: none !important;
          }
          .apexcharts-tooltip-series-group.apexcharts-active,
          .apexcharts-tooltip-series-group:last-child {
            padding-bottom: 0 !important;
          }
          .apexcharts-tooltip-series-group {
            padding: 0 8px !important;
          }
          .apexcharts-tooltip-series-group.apexcharts-active .apexcharts-tooltip-marker {
            display: none !important;
          }
          .apexcharts-tooltip-text-goals-value,
          .apexcharts-tooltip-text-y-value,
          .apexcharts-tooltip-text-z-value {
            margin-left: unset !important;
          }
    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>bb</title>
      </head>
      <body>
        <div id="chart"></div>
    
        <script src="
        https://cdn.jsdelivr.net/npm/apexcharts@3.40.0/dist/apexcharts.min.js
        "></script>
        <link
          href="
        https://cdn.jsdelivr.net/npm/apexcharts@3.40.0/dist/apexcharts.min.css
        "
          rel="stylesheet"
        />
      </body>
    </html>