How to apply theme to echart, react?

Hello.
I’m trying to make a simple linechart using EChart which works fine, however, how can I implement the “registerTheme” function from ‘@siemens/ix-echarts’?
I tried to look in the docs, but struggle to find a solution

//imports


//How to use?
registerTheme(echarts);

const options = { ... }

const LineChartPage = () => {
  return (

    <IxContent>
      <IxContentHeader
        slot="header"
        header-title="Line chart examples"
      ></IxContentHeader>

      <ReactECharts
        option={options}
        
        style={{ width: "600px", height: "300px" }}
      ></ReactECharts>

    </IxContent>
  )
}

export default LineChartPage

Hello @torgeir.tislevoll, thank you for reaching out. Can you please provide more details about what you are trying to do and what exactly is not working for you?

Hi.
I am simply trying to apply the Siemens Theme to my EChart component.
The documentation doesn’t show how to apply this to React?
I see that there is a function: import { registerTheme } from '@siemens/ix-echarts';

But how can this be for instance be applied to my functional component here

const BarChartWidget: React.FC<{ timeSeriesData: TimeSeriesData[] }> = ({ timeSeriesData }) => {
  
  const variables = Object.keys(timeSeriesData[0]).filter(key => key !== '_time');
  debugger;
  const dataSeries = variables.map(propertyName => ({
    data: timeSeriesData.map(item => item[propertyName]),
    type: 'bar',
  }));


  var barChartData: barChartDataModel = {
    grid: BAR_DEFAULT_GRID,
    xAxis: {
      type: BAR_X_AXIS_DEFAULT_TYPE,
      data: variables
    },
    yAxis: {
      type: BAR_Y_AXIS_DEFAULT_TYPE,
    },
    series: dataSeries,
    tooltip: {
      trigger: BAR_TOOLTIP_DEFAULT_TRIGGER
    }
  }


  return (
    <ReactECharts
      option={barChartData}
      style={{ width: "600px", height: "300px" }}
      // I have tried this, but doesnt make a difference
      theme={registerTheme}
      
    ></ReactECharts>
  )
}

Let me know what details you need!

Hi, any info on this? @LukasMaurer

Hello @torgeir.tislevoll, I am not familiar with react-for-echarts but can you not simply do registerTheme(echarts)?

Hi! Facing the same problem. The registerTheme function is not working with a react+Typescript setup.
Maybe this PR is also related to this. fix(echarts): themes by jul-lam · Pull Request #1190 · siemens/ix · GitHub

@varin.thakur with the given PR we will add better examples how to register the echarts themes for react.

Here is a working example until the pr is merged: Vitejs - Vite (forked) - StackBlitz

Example code
import { useLayoutEffect, useRef } from 'react';
import * as echarts from 'echarts';
import './App.css';
import { registerTheme } from '@siemens/ix-echarts';

function App() {
  const container = useRef(null);

  useLayoutEffect(() => {
    registerTheme(echarts);

    var myChart = echarts.init(container.current!, 'brand-dark'); // brand-dark, brand-light, classic-dark or classic-light

    myChart.setOption({
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'shadow',
        },
      },
      legend: {},
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true,
      },
      xAxis: [
        {
          type: 'category',
          data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
        },
      ],
      yAxis: [
        {
          type: 'value',
        },
      ],
      series: [
        {
          name: 'Direct',
          type: 'bar',
          emphasis: {
            focus: 'series',
          },
          data: [320, 332, 301, 334, 390, 330, 320],
        },
        {
          name: 'Email',
          type: 'bar',
          stack: 'Ad',
          emphasis: {
            focus: 'series',
          },
          data: [120, 132, 101, 134, 90, 230, 210],
        },
        {
          name: 'Union Ads',
          type: 'bar',
          stack: 'Ad',
          emphasis: {
            focus: 'series',
          },
          data: [220, 182, 191, 234, 290, 330, 310],
        },
        {
          name: 'Video Ads',
          type: 'bar',
          stack: 'Ad',
          emphasis: {
            focus: 'series',
          },
          data: [150, 232, 201, 154, 190, 330, 410],
        },
        {
          name: 'Search Engine',
          type: 'bar',
          data: [862, 1018, 964, 1026, 1679, 1600, 1570],
          emphasis: {
            focus: 'series',
          },
          markLine: {
            lineStyle: {
              type: 'dashed',
            },
            data: [[{ type: 'min' }, { type: 'max' }]],
          },
        },
        {
          name: 'Baidu',
          type: 'bar',
          barWidth: 5,
          stack: 'Search Engine',
          emphasis: {
            focus: 'series',
          },
          data: [620, 732, 701, 734, 1090, 1130, 1120],
        },
        {
          name: 'Google',
          type: 'bar',
          stack: 'Search Engine',
          emphasis: {
            focus: 'series',
          },
          data: [120, 132, 101, 134, 290, 230, 220],
        },
        {
          name: 'Bing',
          type: 'bar',
          stack: 'Search Engine',
          emphasis: {
            focus: 'series',
          },
          data: [60, 72, 71, 74, 190, 130, 110],
        },
        {
          name: 'Others',
          type: 'bar',
          stack: 'Search Engine',
          emphasis: {
            focus: 'series',
          },
          data: [62, 82, 91, 84, 109, 110, 120],
        },
      ],
    });
  }, []);

  return (
    <>
      <div ref={container} style={{ width: '30rem', height: '30rem' }}></div>
    </>
  );
}

export default App;

Thanks, was able to use it finally. Followed the example given in the PR which also uses the ‘echarts-for-react’ library
fix(echarts): themes by jul-lam · Pull Request #1190 · siemens/ix · GitHub

However, I have 2 problems-

On the left side, I am using the ‘classic-light’ theme, the labels for the legend become invisible due to their font color as white

On the right side, I am using the ‘classic-dark’ theme. the axis labels should be of a whiter tone which increases their visibility.

Update : The color of legend only malfunctions when the theme is switched using the toggle button provided in the menu. If the theme is already set, the legend doesn’t have visibility issues.

1 Like

The Siemens iX Theming and the ECharts Theming are not connected right now. You have to switch the theme programmaticly via the theme switcher

I will discuss an automatic switch with the team maybe we can provide a solution for that case.

2 Likes

@varin.thakur

As a workaround you can switch the theme this way: Vitejs - Vite (forked) - StackBlitz

Regarding the part with the substring(remove theme prefix). We have already a issue regarding this wrong naming.

Example code
import { useEffect, useLayoutEffect, useRef } from 'react';
import * as echarts from 'echarts';
import type { ECharts } from 'echarts';
import './App.css';
import { registerTheme } from '@siemens/ix-echarts';
import { IxApplication, IxApplicationHeader, IxMenu } from '@siemens/ix-react';
import { themeSwitcher } from '@siemens/ix';
function App() {
  const container = useRef(null);

  const themeRef = useRef<string | null>('classic-dark');
  const echartsRef = useRef<ECharts | null>(null);

  function initChart() {
    const myChart = echarts.init(container.current!, themeRef.current); // brand-dark, brand-light, classic-dark or classic-light

    myChart.setOption({
      .... some chart config...
    });
    echartsRef.current = myChart;
  }

  useLayoutEffect(() => {
    registerTheme(echarts);

    initChart();
  }, []);

  useEffect(() => {
    const prefix = 'theme-';
    themeSwitcher.themeChanged.on((theme) => {
      themeRef.current = theme.substring(theme.indexOf(prefix) + prefix.length);

      const echart = echartsRef.current;
      if (echart) {
        echart.dispose();
        initChart();
      }
    });
  }, []);

  return (
    <IxApplication forceBreakpoint={'md'}>
      <IxApplicationHeader></IxApplicationHeader>
      <IxMenu enableToggleTheme></IxMenu>
      <div ref={container} style={{ width: '40rem', height: '40rem' }}></div>
    </IxApplication>
  );
}

export default App;

1 Like

Thanks for this as well. Since I was using the ‘echarts-for-react’ library, I created a state variable to make my component re-render as the theme switcher is toggled.
Attaching a sample template for everyone.

import * as echarts from "echarts";
import { registerTheme } from "@siemens/ix-echarts";
import { useEffect, useLayoutEffect, useState } from "react";
import { themeSwitcher } from "@siemens/ix";
import ReactECharts from "echarts-for-react";

const Component = () => {
const [theme, setTheme] = useState(
    document.body.className.replace("theme-", "")
  );

  useLayoutEffect(() => {
    registerTheme(echarts);
  },[]);

  useEffect(() => {
    const prefix = "theme-";
    themeSwitcher.themeChanged.on((currentTheme) => {
      setTheme(
        currentTheme.substring(currentTheme.indexOf(prefix) + prefix.length)
      );
    });
  },[]);

const options = {
// .. set your chart options here
}

return (
    <ReactECharts
      style={{ width: "100%", height: "100%" }}
      option={options}
      theme={theme}
    />
  );
}
1 Like