Skip to content

ECharts server-side rendering SVG contains invalid font property #16127

@htr3n

Description

@htr3n

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>

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugenThis issue is in English

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions