好久没更了,近期开发遇到的需求,抽空梳理一下~

需求:实现一个复杂的拓扑图,图中元素的个数,以及各个参数内容是动态展示的。

于是让ui提供了对应的svg图片。

解决思路:使用iframe嵌入svg图片,运用D3.js修改其文本及样式。

html:

<iframe class="systemFrame" ref="systemFrame" :src="exportImg(topoSrc)" width="100%" height="100%" frameborder="0" ></iframe>

js:要从svg图里找到对应的元素id

onMounted(() => {
  let frameObj = systemFrame.value;
  if (frameObj.attachEvent) {
    frameObj.attachEvent("onload", function () {});
  } else {
    frameObj.onload = function () {
      onIframeLoaded()
      loading.value = false
    };
  }
  getTopo()
})
const onIframeLoaded = () => {
  const iframeWindow = systemFrame.value.contentWindow.document;
  const svg = iframeWindow.getElementsByTagName('svg')
  if(!svg.length) return
  svg[0].style.background = '#242424'

  // iframe加载完成后要进行的操作
  var iframeSvg = systemFrame.value.contentDocument; //!!!!这里获取svgDom,一定要先获取父元素,才会展示子元素!!否则找不到
  var svgObj = iframeSvg.getElementById("drawing"); //获取父元素下面id是drawing的子元素,接下来就可以对svgDom进行操作,绑定元素点击事件,改变元素的属性等等
 
  let d3svg = d3.select(svgObj);
 // 实现拓扑图缩放功能
  svgPanZoom(svgObj, {
    zoomEnabled: true,
    panEnabled: false,
    maxZoom: 2,
    minZoom: 0.5,
    preventMouseEventsDefault: false,
  })
   
  svgEdit(d3svg)
};

const svgEdit = (d3svg) => {
 // 改变样式 流动的虚线
 d3svg.select("#Right")
    .style("animation", "path-animation " + 18 + "s")
    .style("animation-timing-function", "linear")
    .style("animation-iteration-count", "infinite");
  // 循环各个元素  topoSrc是需要展示的元素个数
  for(let i=1; i<topoSrc.value*1 + 1; i++) {
    // 找到元素并移动位置
    d3svg.selectAll('#power-'+ i).attr('transform', 'translate(-15)')
    // 找到元素替换文本
    d3svg.selectAll('#power-'+ i + ' .cls-20:nth-child(1)').text(topoData.value.packs[i-1].power + 'kW')    
    // 找到元素替换颜色
    d3svg.select('#sys'+ i + ' .cls-24').style("fill", '#fff')
    d3svg.select('#cu'+ i).style("fill", '#fff')
    }
  }
 

 

posted on 2024-07-24 09:50  丶小馨  阅读(10)  评论(0编辑  收藏  举报