Yogesh_altrosyn
Yogesh_altrosyn

Reputation: 13

How to fix alignment of colors in apexchart after applying gradient fill with axistype-datetime with multiple x-axis labels?

In my code, I have applied a colorstop in a line chart using the fill gradient option. I have set the x-axis type as datetime. The Colorstop works correctly when there are a small number of labels. However, when there are 5 or 7 labels, such as one label per week day, the applied colors in the chart do not match the data. Even though everything else is correct, the alignment of colors is mismatched. I resolved this issue by converting the x-axis type to category, but in my case, it should remain as datetime.

In code i have used range value 100,220,450 and green,red,yellow color, 0 t0 100 values color should by green,100 to 220 color should be yellow and 220 to 450 color should be red but due to many x-axis lable graph get crushed and alignment of color showing mismatched in x-axis type datetime

This is my sample code add for your reference codesandbox

sample image added:
[1]: https://i.sstatic.net/xpwnA.png [linechart][1]

Upvotes: 1

Views: 436

Answers (1)

kikon
kikon

Reputation: 8700

The problem with your code is that you interpolate the gradient by the index of the points, but you should interpolate it by the x distance, which is the date of the current point. Your approach only works if the points are equidistant in time, but that's not the case with your data.

A simple solution for your code is to compute the UNIX timestamp for each point x coordinate (date), by calling the Date.parse function. Your dates are almost in ISO 8601 format, except for some whitespaces that can be eliminated:

const tStart = Date.parse(JsonData?.[0]?.x?.replace(/\s/g, "")),
    tEnd = Date.parse(JsonData?.[JsonData?.length - 1]?.x?.replace(/\s/g, "")),
    dt = tEnd - tStart;

const colorStops = JsonData.map((e, index) => {
    let color = "black";
    for (let j = 0; j < rangeValue?.length; j++) {
        if (e.y <= rangeValue[j].Range_End_Value) {
            color = rangeValue[j].Range_color;
            break;
        }
    }
    const t = Date.parse(e.x.replace(/\s/g, ""));
    
    return {
        offset: ((t - tStart) / dt) * 100,
        color,
        opacity: 0.5
    };
});

Here's a codesandbox fork of yours with that change.


An alternative solution for your problem is to use a vertical gradient. The only difficulty is that it starts from the top of the chart space. You also have to set (or compute) the maximum and minimum values of y axis.

If one sets the maximum value at

const maxY = 450;

(assuming minimum at zero) for the two color breaks at 220 from red to yellow and at 100 from yellow to green (we have to think it top-down), the color stops should be:

colorStops: [
    {
        offset: (1 - 220 / maxY) * 100,
        color: "red",
        opacity: 0.5
    },
    {
        offset: (1 - 220 / maxY) * 100,
        color: "yellow",
        opacity: 0.5
    },
    {
        offset: (1 - 100 / maxY) * 100,
        color: "yellow",
        opacity: 0.5
    },
    {
        offset: (1 - 100 / maxY) * 100,
        color: "green",
        opacity: 0.5
    }
]

which I hardcoded for brevity, but can be computed from a changeable data structure, like before.

Here's the codesandbox fork that implements that variant.

Upvotes: 0

Related Questions