echarts: ECharts server-side rendering SVG contains invalid font property

Version

5.2.2 (and 5.2.1)

Reproduction link

https://codesandbox.io/s/echarts-ssr-uxfju

Steps to reproduce

  1. Create a server-side rendering of ECharts (5.2.2) with JsDOM and Node Canvas
  2. Configure to render a simple chart to SVG
const echarts = require("echarts");
const { JSDOM } = require("jsdom");
const { createCanvas } = require("canvas");
const fs = require("fs");

const config = {
  option: {
    animation: false,
    fontSize: 10,
    fontFamily: "Arial",
    xAxis: {
      data: ["1493190351122"],
      axisLabel: {
        fontSize: 10,
        fontFamily: "Arial"
      }
    },
    yAxis: {
      name: "Y Axis",
      type: "value",
      nameTextStyle: {
        fontWeight: "bold",
        fontSize: 10,
        fontFamily: "Arial"
      }
    },
    series: [
      {
        type: "line",
        name: "Series 1",
        data: [39]
      }
    ]
  }
};

function render() {
  const ctx = createCanvas(1920, 1080);

  if (ctx) {
    ctx.font = "Arial";
  }

  echarts.setCanvasCreator(() => {
    return ctx;
  });

  const virtualDom = new JSDOM();
  global.window = virtualDom.window;
  global.document = virtualDom.window.document;
  const root = global.document.createElement("div");
  if (root) {
    root.style.cssText = "width: 1920px; height: 1080px;";
    Object.defineProperty(root, "clientWidth", { value: 1920 });
    Object.defineProperty(root, "clientHeight", { value: 1080 });
    let chart = echarts.init(root, null, {
      width: 1920,
      height: 1080,
      renderer: "svg"
    });
    if (chart) {
      chart.setOption(config.option);
      let result = root.querySelector("svg")?.outerHTML ?? null;
      chart.dispose();
      return result;
    }
  }
  return null;
}

const buffer = render();
console.log(buffer);

fs.writeFile(`output.svg`, buffer, function (err) {
  if (err) return console.log(err);
});

What is expected?

  1. The SVG <text> elements should have the correct font family as specified.
  2. The <text> elements inside the resulting SVG should have valid font specification inside style="".
<text xml:space="preserve" style="font: normal sans-serif 12px;">

What is actually happening?

  1. The SVG <text> elements do not have the correct font family as specified.
  2. The SVG’s <text> elements contain invalid font specification so that the SVG text will be rendered incorrectly.
<text xml:space="preserve" style="font: sans-serif 12px normal normal normal 12px;">

Per CSS font property (see https://developer.mozilla.org/en-US/docs/Web/CSS/font), it should be

[ [ <'font-style'> || <font-variant-css21> || <'font-weight'> || <'font-stretch'> ]? <'font-size'> [ / <'line-height'> ]? <'font-family'> ] | caption | icon | menu | message-box | small-caption | status-bar

I found this bug when I tried to configure the Y axis nameTextStyle to bold and small size and realised that the font styles and weight I set there do not affect the outcome at all.

This issue is only seen with server-side rendering. I use an identical configuration for a React front-end, it works fine, produces valid CSS.

<text xml:space="preserve"
  fill="#101010"
  fill-opacity="1"
  stroke="none"
  transform="matrix(0,-1,1,0,27,122)"
  dominant-baseline="central"
  text-anchor="middle"
  x="0"
  y="-8.5"
  style="font: bold normal normal 12px Arial;">Axis Title
</text>

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 22 (8 by maintainers)

Most upvoted comments

Made a simple example, it’s easy enough to get started. https://codepen.io/plainheart/pen/RwLbqye