echarts icon indicating copy to clipboard operation
echarts copied to clipboard

[SVG] Allow adding DOM to the chart in SVG renderer through `foreignObject`

Open plainheart opened this issue 4 years ago • 3 comments

What problem does this feature solve?

For SVG renderer, it would be flexible and creative if allow adding DOM to the chart through foreignObject.

What does the proposed API look like?

Currently no good idea about how to design the API in ECharts. Here is the proposed usage in zrender.

DOM string

// DOM string
const dom = new zrender.ForeignObject({
    style: {
        x: 600,
        y: 250,
        width: 200,
        height: 400
    },
    rotation: -60 * Math.PI / 180,
    originX: 600 + 200 / 2,
    originY: 250 + 400 / 2,
    // scaleX: 2,
    // scaleY: 2,
    html: `
        <h1 class="hover-change-color" style="color:#F72C5B">Apache ECharts</h1>
        <h4>一个基于 JavaScript 的开源可视化图表库</h3>
        <img height="150" src="https://cdn.jsdelivr.net/gh/apache/echarts-website@asf-site/zh/images/index-home-pie.png?_v_=20200710_1" />
    `
});
zr.add(dom);

DOM Array

// DOM array
const h1 = document.createElement('h1');
h1.className = 'hover-change-color';
h1.innerText = 'Created Element';
const p = document.createElement('p');
p.innerText = new Date().toLocaleString();
setInterval(() => p.innerText = new Date().toLocaleString(), 1e3);

const dom2 = new zrender.ForeignObject({
    style: {
        x: 600,
        y: 150,
        width: 200,
        height: 200
    },
    originX: 600 + 200 / 2,
    originY: 150 + 200 / 2,
    scaleX: 0.8,
    scaleY: 0.8,
    html: [h1, p]
});
zr.add(dom2);

Video

// video
const video = document.createElement('video');
video.src = 'https://cdn.jsdelivr.net/gh/apache/echarts-website@asf-site/v4/zh/video/index.mp4';
video.poster = 'https://cdn.jsdelivr.net/gh/apache/echarts-website@asf-site/v4/zh/video/index-4.jpg';
video.muted = true;
video.autoplay = true;
video.controls = true;
video.loop = true;
video.style.objectFit = 'contain';
video.style.maxWidth = '100%';

const videoDom = new zrender.ForeignObject({
    style: {
        x: 50,
        y: 250,
        width: 400,
        height: 400
    },
    html: video
});
zr.add(videoDom);

Screenshot

min

plainheart avatar Jun 01 '21 09:06 plainheart

It's a very promising feature! But I think we should try not to break the consistency between SVG and Canvas renderer as much as possible. So this should be a feature that canvas also can have.

For API design, since ForeignObject is a concept that only SVG has. It's better to use a more general API like zrender.HTMLElement.

pissang avatar Jun 01 '21 10:06 pissang

This issue has been automatically marked as stale because it did not have recent activity. It will be closed in 7 days if no further activity occurs. If you wish not to mark it as stale, please leave a comment in this issue.

github-actions[bot] avatar Jun 01 '23 21:06 github-actions[bot]

This issue has been automatically marked as stale because it did not have recent activity. It will be closed in 7 days if no further activity occurs. If you wish not to mark it as stale, please leave a comment in this issue.

github-actions[bot] avatar Jun 01 '25 21:06 github-actions[bot]