apache / echarts

Apache ECharts is a powerful, interactive charting and data visualization library for browser
https://echarts.apache.org
Apache License 2.0
60.5k stars 19.62k forks source link

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

Open plainheart opened 3 years ago

plainheart commented 3 years ago

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

pissang commented 3 years ago

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.

github-actions[bot] commented 1 year ago

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.