Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reinitialize with new theme #1945

Open
Unbinilium opened this issue Mar 17, 2021 · 9 comments
Open

Reinitialize with new theme #1945

Unbinilium opened this issue Mar 17, 2021 · 9 comments
Labels
Status: Triage Needs to be verified, categorized, etc Type: Other Not an enhancement or a bug

Comments

@Unbinilium
Copy link

Unbinilium commented Mar 17, 2021

How to reinitialize with new theme?

Hi folks, I want mermaidjs rerender diagrams when I switched color-scheme, such as switching form 'dark' to 'light', I tried use mermaid.mermaidAPI.reinitialize() with different theme configurations, but it seems not working.

I see that it keep the theme as same as the first initial, when I changed the theme value, called reinitialize(newConfig), remove last rendered graphs and rerendered the new diagrams, it shows nothing different with the theme rendered before.

Is that I was misunderstood the reinitialize() function usage or there is something wrong with my code?

Thanks.

<pre class="mermaid-container">
  <pre id="mermaid-src-0" hidden>
    graph TD;
      A-->B;
      A-->C;
      B-->D;
      C-->D;
  </pre>
</pre>
var mermaidConfig = {
    startOnLoad: false,
    theme: 'neutral',
    logLevel: 'debug',
    fontFamily: '"Menlo", "Meslo LG", monospace',
    er: {
        minEntityWidth: 100,
        minEntityHeight: 55,
        entityPadding: 15
    },
    sequence: {
        width: 130,
        height: 30
    },
    gantt: {
        barHeight: 25,
        barGap: 4
    }
};

async function mermaidRender(mermaidSrc, mermaidOutId) {
    mermaid.mermaidAPI.render(mermaidOutId, mermaidSrc.textContent, async function (svgCode) {
        mermaidSrc.insertAdjacentHTML('afterend', svgCode);
    });
}

async function mermaidLoaded() {
    if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
        mermaidConfig['theme'] = 'dark';
    }
    mermaid.mermaidAPI.initialize(mermaidConfig);
    var mermaidContainer = document.getElementsByClassName('mermaid-container');
    for (var i = 0; i != mermaidContainer.length; ++i) {
        var mermaidSrc = mermaidContainer[i].firstElementChild;
        var mermaidOutId = mermaidSrc.id.replace('src', 'out');

        mermaidRender(mermaidSrc, mermaidOutId);
    }
}

async function mermaidReloaded() {
    mermaidConfig['theme'] = 'neutral';

    mermaid.mermaidAPI.reinitialize(mermaidConfig);
    var mermaidContainer = document.getElementsByClassName('mermaid-container');
    for (var i = 0; i != mermaidContainer.length; ++i) {
        var mermaidSrc = mermaidContainer[i].firstElementChild;
        var mermaidOutId = mermaidSrc.id.replace('src', 'out');

        mermaidContainer[i].querySelector('[id^=mermaid-out-]').remove();

        mermaidRender(mermaidSrc, mermaidOutId);
    }
}

if (document.getElementsByClassName('mermaid-container').length != 0) {
    var script = document.createElement('script');
    script.src = 'https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js';
    script.setAttribute('onload', 'mermaidLoaded();')
    document.head.appendChild(script);
}

window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', mermaidReloaded);
@Unbinilium Unbinilium added the Type: Other Not an enhancement or a bug label Mar 17, 2021
@github-actions github-actions bot added the Status: Triage Needs to be verified, categorized, etc label Mar 17, 2021
@Unbinilium
Copy link
Author

Unbinilium commented Mar 17, 2021

I noticed that the reinitialize() function was commented like this in v8.9.2:

function reinitialize() {
  // `mermaidAPI.reinitialize: v${pkg.version}`,
  //   JSON.stringify(options),
  //   options.themeVariables.primaryColor;
  // // if (options.theme && theme[options.theme]) {
  // //   options.themeVariables = theme[options.theme].getThemeVariables(options.themeVariables);
  // // }
  // // Set default options
  // const config =
  //   typeof options === 'object' ? configApi.setConfig(options) : configApi.getSiteConfig();
  // updateRendererConfigs(config);
  // setLogLevel(config.logLevel);
  // log.debug('mermaidAPI.reinitialize: ', config);
}

And for initialize(options) function, it seems only the theme changes can not be applied, I am not sure whether the color changes is applied to render new svgs.

...
if (options && options.theme && theme[options.theme]) {
    // Todo merge with user options
    options.themeVariables = theme[options.theme].getThemeVariables(options.themeVariables);
  } else {
    if (options) options.themeVariables = theme.default.getThemeVariables(options.themeVariables);
  }
...

@deoxykev
Copy link

deoxykev commented May 5, 2021

Same issue with me too...

@matthiasg
Copy link

Yes this is definitely required

@tekstrand
Copy link

+1

@appotry
Copy link

appotry commented Sep 21, 2022

I want this too!!!

@esotericman
Copy link

+1

1 similar comment
@kinachan
Copy link

+1

@barockok
Copy link

barockok commented Aug 2, 2023

I managed to have a workaround for the reinitialize. by persisting the original content first, then initialize mermaid afterward. whenever the site theme (light/dark) it will reset the data-processed since mermaid has initialized before, and overide the content with the original content, then initialize new mermaid.

whenever the theme variable change in my site, I emit an event (dark-theme-set/light-theme-set), and register callback to initialize mermaid.

you can check the live site here

(function(window){
'use strict'

  const elementCode = '.language-mermaid'
  const loadMermaid = function(theme) {
    window.mermaid.initialize({theme})
    window.mermaid.init({theme}, document.querySelectorAll(elementCode))
  }
  const saveOriginalData = function(){
    return new Promise((resolve, reject) => {
      try {
        var els = document.querySelectorAll(elementCode),
            count = els.length;
        els.forEach(element => {
          element.setAttribute('data-original-code', element.innerHTML)
          count--
          if(count == 0){
            resolve()
          }
        });
      } catch (error) {
       reject(error) 
      }
    })
  }
  const resetProcessed = function(){
    return new Promise((resolve, reject) => {
      try {
        var els = document.querySelectorAll(elementCode),
            count = els.length;
        els.forEach(element => {
          if(element.getAttribute('data-original-code') != null){
            element.removeAttribute('data-processed')
            element.innerHTML = element.getAttribute('data-original-code')
          }
          count--
          if(count == 0){
            resolve()
          }
        });
      } catch (error) {
       reject(error) 
      }
    })
  } 

  const init = ()=>{
    saveOriginalData()
    .catch( console.error )
    document.body.addEventListener('dark-theme-set', ()=>{
      resetProcessed()
      .then(loadMermaid('dark'))
      .catch(console.error)
    })
    document.body.addEventListener('light-theme-set', ()=>{
      resetProcessed()
      .then(loadMermaid('default'))
      .catch(console.error)
    })
  }
  window.initMermaid = init
})(window);

@giovanniberti
Copy link

I managed to have a workaround for the reinitialize. by persisting the original content first, then initialize mermaid afterward. whenever the site theme (light/dark) it will reset the data-processed since mermaid has initialized before, and overide the content with the original content, then initialize new mermaid.

whenever the theme variable change in my site, I emit an event (dark-theme-set/light-theme-set), and register callback to initialize mermaid.

you can check the live site here

(function(window){
'use strict'

  const elementCode = '.language-mermaid'
  const loadMermaid = function(theme) {
    window.mermaid.initialize({theme})
    window.mermaid.init({theme}, document.querySelectorAll(elementCode))
  }
  const saveOriginalData = function(){
    return new Promise((resolve, reject) => {
      try {
        var els = document.querySelectorAll(elementCode),
            count = els.length;
        els.forEach(element => {
          element.setAttribute('data-original-code', element.innerHTML)
          count--
          if(count == 0){
            resolve()
          }
        });
      } catch (error) {
       reject(error) 
      }
    })
  }
  const resetProcessed = function(){
    return new Promise((resolve, reject) => {
      try {
        var els = document.querySelectorAll(elementCode),
            count = els.length;
        els.forEach(element => {
          if(element.getAttribute('data-original-code') != null){
            element.removeAttribute('data-processed')
            element.innerHTML = element.getAttribute('data-original-code')
          }
          count--
          if(count == 0){
            resolve()
          }
        });
      } catch (error) {
       reject(error) 
      }
    })
  } 

  const init = ()=>{
    saveOriginalData()
    .catch( console.error )
    document.body.addEventListener('dark-theme-set', ()=>{
      resetProcessed()
      .then(loadMermaid('dark'))
      .catch(console.error)
    })
    document.body.addEventListener('light-theme-set', ()=>{
      resetProcessed()
      .then(loadMermaid('default'))
      .catch(console.error)
    })
  }
  window.initMermaid = init
})(window);

Fix to make this work (as of 2024-04-25): replace

const elementCode = '.language-mermaid'

with

const elementCode = '.mermaid'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: Triage Needs to be verified, categorized, etc Type: Other Not an enhancement or a bug
Projects
None yet
Development

No branches or pull requests

9 participants