OKLCH Color Support
What problem does this feature solve?
Now that tailwind css is using oklch colors, it would be great to be able to pass them as the colors for ECHARTS. This would make it easier to have consistent colors in the charts and your web application.
Currently if you do this the series goes blank when you hover over it.
What does the proposed API look like?
Ideally you would be able to pass a list of oklch colors to the https://echarts.apache.org/en/option.html#color property.
Ideally you would be able to pass a list of oklch colors to the color property.
All that's needed is the conversion function: color: [ok2rgb(0.45, 0.26, 264), ok2rgb(0.864, 0.162, 92), ...]
Demo.
š please close issue if problem solved.
In Jenkins we also have the same problem! We recently switched to OKLCH and now our charts also show the reported problem. When someone hovers over the charts, then the charts are getting blank. The interesting thing is, that the OKLCH colors in the options parameter are correctly shown. Only the hover is broken. Even when we replace the OKLCH colors with RGB colors using the transformation shown in your suggested fix, then the background is broken. Does ECharts use other colors from the document to create the hover effect?
Example:
https://github.com/user-attachments/assets/bd11bc1e-1fd7-4aab-a74f-63f4252d84a1
@uhafner, impossible to evaluate without seeing your ECharts option.
Here's an example: https://github.com/jenkinsci/echarts-api-plugin/blob/main/src/main/webapp/js/echarts-api.js#L387
You can use the following options to see the problem, I generated a demo as well:
option = {
"tooltip": {
"trigger": "axis",
"axisPointer": {
"type": "shadow"
}
},
"legend": {
"data": [
"Covered",
"Missed"
],
"x": "center",
"y": "top",
"textStyle": {
"color": "oklch(from oklch(55% 0.2308 256.91deg) 2% 0.075 h)"
}
},
"grid": {
"left": "20",
"right": "10",
"bottom": "5",
"top": "40",
"containLabel": true
},
"xAxis": {
"type": "value",
"axisLabel": {
"color": "oklch(from oklch(55% 0.2308 256.91deg) 2% 0.075 h)"
}
},
"yAxis": [
{
"type": "category",
"data": [
"Package",
"File",
"Class",
"Method",
"Line",
"Branch",
"Instruction"
],
"axisLine": {
"show": false
},
"axisTick": {
"show": false
},
"axisLabel": {
"color": "oklch(from oklch(55% 0.2308 256.91deg) 2% 0.075 h)"
}
},
{
"type": "category",
"data": [
100,
100,
100,
95.95645412130638,
96.34247714048213,
92.16269841269842,
96.35989010989012
],
"position": "right",
"axisLabel": {
"color": "oklch(from oklch(55% 0.2308 256.91deg) 2% 0.075 h)"
},
"axisLine": {
"show": false
},
"axisTick": {
"show": false
}
}
],
"series": [
{
"name": "Covered",
"type": "bar",
"stack": "sum",
"itemStyle": {
"normal": {
"color": "oklch(70% 0.2155 150deg)"
}
},
"label": {
"show": true,
"position": "insideLeft",
"color": "#fff",
"fontWeight": "bold"
},
"data": [
100,
100,
100,
95.95645412130638,
96.34247714048213,
92.16269841269842,
96.35989010989012
]
},
{
"name": "Missed",
"type": "bar",
"stack": "sum",
"itemStyle": {
"normal": {
"color": "oklch(60% 0.2671 30deg)"
}
},
"label": {
"show": true,
"position": "insideRight",
"color": "#fff",
"fontWeight": "bold"
},
"data": [
0,
0,
0,
4.043545878693624,
3.657522859517872,
7.837301587301587,
3.64010989010989
]
}
]
};
When I replace the itemStyle colors with rgb values, then the rendering is ok. But since the colors are shown correctly with oklch in the chart, I would assume that just the hover effect needs to be fixed in ECharts?
Here is another example (see demo)
option = {
"series": [
{
"name": "Line Coverage",
"type": "line",
"symbol": "circle",
"data": [
96.86,
97.14,
97.75,
97.75,
97.76,
97.71,
97.46,
97.66,
97.66,
97.66,
97.66,
97.68,
97.64,
97.93,
97.81,
97.65,
97.6,
97.6,
97.6,
97.7,
97.7,
96.35,
96.09,
96.31,
96.47,
96.47,
96.47,
96.34
],
"itemStyle": {
"color": "oklch(70% 0.2155 150deg)",
"borderColor": "#ffffff",
"borderWidth": 0
},
"areaStyle": {
"normal": true
},
"stack": ""
},
{
"name": "Branch Coverage",
"type": "line",
"symbol": "circle",
"data": [
94.75,
94.76,
95.07,
95.07,
95.1,
95.08,
94.79,
94.73,
94.73,
94.73,
94.73,
94.77,
94.88,
94.55,
94.43,
94.3,
94.32,
94.32,
94.36,
94.41,
94.41,
92.92,
92.42,
92.05,
92.33,
92.33,
92.33,
92.16
],
"itemStyle": {
"color": "oklch(50% 0.2155 150deg)",
"borderColor": "#ffffff",
"borderWidth": 0
},
"areaStyle": {
"normal": true
},
"stack": ""
}
]
};
@uhafner, ECharts API says that color could be defined by a string in three formats: 'rgb(255,0,0)', '#ff0000' or 'red'. So when you use color: "oklch(50% 0.2155 150deg)" ECharts considers it an invalid string and ignores it. I do not know if or when oklch color format will be supported in ECharts.
I made an effort in my Demo above to search, adapt, test and share a conversion function ok2rgb. It uses the absolute value syntax of oklch to convert LCH values to color format 'rgb()' The relative value syntax you are using oklch(from oklch(...)...) is not supported. But you are welcome to enhance ok2rgb and make it work with relative syntax as well. And if you are successful, please share.
I do not know if or when oklch color format will be supported in ECharts.
But isn't this exactly what this issue is about: a feature request for ECharts to fully support oklch?
I made an effort in my Demo above to search
Yes, thanks for the snippet, this is a valid workaround until oklch is supported by ECharts. Based on your snippet I created a workaround in jenkinsci/echarts-api-plugin#383.
you use color: "oklch(50% 0.2155 150deg)" ECharts considers it an invalid string and ignores it
Do you understand why the colors are then shown in red and green when they are ignored? I would assume that somehow these values are partly used, or is this just a coincidence?
I would assume that somehow these values are partly used, or is this just a coincidence?
That's indeed an mad coincidence! I noticed that "oklch()" string colors are not exactly ignored, but did not expect them to be so close to the real thing - Demo. Maybe developers can explain, I can't even find the file where colors are interpreted...
That's indeed an mad coincidence! I noticed that "oklch()" string colors are not exactly ignored, but did not expect them to be so close to the real thing - Demo. Maybe developers can explain, I can't even find the file where colors are interpreted...
Echarts can indeed show oklch color, but the problem is on the highlight/emphasis when the user hovers on the chart. The current workaround is to disable the emphasis completely. https://github.com/apache/echarts/issues/19976
I think the problem is on zrender, the library used by echarts to render the charts.
Here is the code to apply emphasis styles https://github.com/ecomfe/zrender/blob/master/src/svg/cssEmphasis.ts.
...
const emphasisStyle = el.states.emphasis && el.states.emphasis.style
? el.states.emphasis.style
: {};
let fill = emphasisStyle.fill;
if (!fill) {
// No empahsis fill, lift color
const normalFill = el.style && el.style.fill;
const selectFill = el.states.select
&& el.states.select.style
&& el.states.select.style.fill;
const fromFill = el.currentStates.indexOf('select') >= 0
? (selectFill || normalFill)
: normalFill;
if (fromFill) {
fill = liftColor(fromFill);
}
}
...
And here is where the new color calculated.
@frenicohansen, thank you for pointing out zRender repo for color parsing. https://github.com/ecomfe/zrender/blob/aa7187279fb306e12f3984f6f7f7fd4134635aea/src/tool/color.ts#L162 I see rgb and hsl formats checked, but no trace of oklch in the entire repo. Mystery remains unsolved, at least to me...
UPDATE: looks like color string falls back to a CSS definition somehow. So all CSS color spaces are supported, not only oklch:
'color(rec2020 0.2 0.2 0.8)',
'color(xyz 1 1 1 )', //transparent
'color(display-p3 1 0.5 0)',
'lch(from hsl(0 100% 50%) 29.6871% 66.83 327.109)',
'lab(50% -120 125)',
'hwb(50deg 30% 40%)',
'oklab(from hsl(180 100% 50%) calc(l - 0.1) a b)',
@uhafner, the emphasis problem is fixed by adding emphasis:{ itemStyle:{ color: 'inherit' } } in your demo.
Now I'm convinced that oklch color format is fully supported in ECharts - both absolute and relative value syntax. Demo
Thanks for this tip! With this trick I get this almost working without a color conversion! It looks fine for all simple charts (bar, pie, etc.), just for line series this seem not to work. Somehow this one is more tricky or I am doing something totally wrong. It seems that my JS expertise is too limited (I'm actually a Java developer using AI for JS tasks š)
just for line series this seem not to work
oh, just add also areaStyle: {color: 'inherit'} in emphasis, should work - Demo.
@frenicohansen, thank you for pointing out zRender repo for color parsing. https://github.com/ecomfe/zrender/blob/aa7187279fb306e12f3984f6f7f7fd4134635aea/src/tool/color.ts#L162 I see rgb and hsl formats checked, but no trace of oklch in the entire repo. Mystery remains unsolved, at least to me...
UPDATE: looks like color string falls back to a CSS definition somehow. So all CSS color spaces are supported, not only oklch:
'color(rec2020 0.2 0.2 0.8)', 'color(xyz 1 1 1 )', //transparent 'color(display-p3 1 0.5 0)', 'lch(from hsl(0 100% 50%) 29.6871% 66.83 327.109)', 'lab(50% -120 125)', 'hwb(50deg 30% 40%)', 'oklab(from hsl(180 100% 50%) calc(l - 0.1) a b)',
That's not a mystery. According to browser's spec, both the canvas API and SVG support CSS color values for fills.
Good job @helgasoft šÆ on finding the workaround with color: inherit
Good job @helgasoft šÆ on finding the workaround with
color: inherit
Yes, indeed. I would never have figured that out myself. ā¤
For those wondering how color: inherit fixes this issue:
According to the ECharts documentation:
Since v5.2.0, it can be set to 'inherit' in the emphasis state to disable color highlight.
By using color: inherit, we effectively prevent ECharts from applying its default color highlight.
To mimic the default highlight effect, we can instead adjust the opacity. The default behavior replaces the color with a lighter RGB color instead of modifying opacity, which unfortunately does not support the OKLCH color space.
I have a line chart, for which I have tried adding itemstyle, areastyle and opacity for emphasis. Still it does not work. Demo
Can someone please help?
I have a line chart, for which I have tried adding itemstyle, areastyle and opacity for emphasis. Still it does not work.
I ran into the same issue when not using areaStyle (Iām also using gradient colors for the line), and the only solution I found was to disable emphasis entirely
emphasis: {
disabled: true,
}
I have a line chart, for which I have tried adding itemstyle, areastyle and opacity for emphasis. Still it does not work.
I ran into the same issue when not using areaStyle (Iām also using gradient colors for the line), and the only solution I found was to disable emphasis entirely
emphasis: { disabled: true, }
So i was able to get it working with
emphasis: { lineStyle: { color: s.color } }
This is my entire code, I hope it helps you
const getLineChartOptions = (data: TLineChartData) => ({
tooltip: xyTooltip,
grid: xyGrid,
xAxis: categoryAxis(data.labels),
yAxis: valueAxis,
series: data.series.map(s => ({
...s,
type: 'line',
smooth: true,
emphasis: { lineStyle: { color: s.color } },
})),
});