第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何用D3.js創(chuàng)建一個圓組一個組織圓圖像并用曲線連接?

如何用D3.js創(chuàng)建一個圓組一個組織圓圖像并用曲線連接?

躍然一笑 2022-10-08 14:55:44
我正在嘗試使用 d3.js 創(chuàng)建一個徑向(圓形)分組圓,例如:我寫了一些如下代碼。但我不知道如何將每個圓圈與曲線連接起來,當(dāng)鼠標(biāo)懸停圓圈時,上面的圓圈會顯示一個工具提示,怎么做?幫助將不勝感激。謝謝。我更新了我的代碼,現(xiàn)在我可以在一個大圓圈中繪制圓圈或圖像元素。    const mockedData = {    "nodes": [      {        "name": "Node1one",        "label": "Node1",        "id": 1,        "x": 120,        "y": 120,      },      {        "name": "Node2",        "label": "Node2",        "id": 2,        "x": 350,        "y": 180,      },    ]  }  const imgList = {    "images": [      {        "image": 'https://via.placeholder.com/30x30',        "x": -50,      },      {        "image": 'https://via.placeholder.com/30',        "x": 20      }    ]  }const svg = d3.select("svg");const width = +svg.attr("width");const height = +svg.attr("height");let { links, nodes } = mockedData;let { images } = imgList;const ticked = ( node) => {  node.attr("transform",   function (d) {return "translate(" + d.x + ", " + d.y + ")";});}const tickedImg = (nodeImg) => {  nodeImg.attr("x", function (d) {return  d.x })}const node = svg.selectAll(".node")        .data(nodes)        .enter()        .append("g")        .attr("class", "node")    node.append('circle').attr("r", 86); //radius    svg.selectAll('circle')    .on('click', function () { // arrow function will produce this = undefined       d3.selectAll('circle')       .style("fill", "lightgray");       d3.select(this)        .style("fill", "aliceblue");     })     .on('mouseover', function () {        d3.selectAll('circle')        .style("stroke", "black");                d3.select(this)        .style("stroke", "green");    })    ticked( node )const nodeText = node.append("text").attr("y", -70);      nodeText.selectAll("tspan.text")      .data((d) =>  d.name.split(" "))      .enter()      .append("tspan")      .attr("class", "text")      .text(d => d)      .attr("x", -30)      .attr("y", -60)      node.append("title")          .text(function (d) {return d.id;});
查看完整描述

1 回答

?
慕妹3242003

TA貢獻1824條經(jīng)驗 獲得超6個贊

好的,如果我們只想在圖像之間繪制彎曲的弧線,我當(dāng)然可以提供幫助:)


我在這里(非常詳細地)回答了一個類似的問題:https ://stackoverflow.com/a/59784798/9792594 - 這應(yīng)該有助于解釋數(shù)學(xué)等。


我將只使用該答案中的最終功能,如果您需要有關(guān)其工作原理的背景知識,請查看該答案。


注意:您可以通過更改“繪制順序”來更改 svg 元素的“z 順序”,即在 DOM 中呈現(xiàn)它們的順序。所以在d3中,使用.append(),這只是意味著首先在底層調(diào)用你想要的代碼,然后在下一層調(diào)用你想要的代碼,依此類推。


const mockedData = {

    "nodes": [

      {

        "name": "Node1",

        "label": "Node1",

        "id": 1,

        "x": 120,

        "y": 120,

      },

      {

        "name": "Node2",

        "label": "Node2",

        "id": 2,

        "x": 350,

        "y": 180,

      },

    ]

  }


  const imgList = {

    "images": [

      {

        "image": 'https://via.placeholder.com/30x30',

        "width": 30,

        "height": 30,

        "x": -50,

        "y": -20

      },

      {

        "image": 'https://via.placeholder.com/30',

        "width": 30,

        "height": 30,

        "x": 20,

        "y": -20

      },

      {

        "image": 'https://via.placeholder.com/30',

        "width": 30,

        "height": 30,

        "x": -15,

        "y": 20

      }

    ]

  }



const svg = d3.select("svg");

const width = +svg.attr("width");

const height = +svg.attr("height");


let { links, nodes } = mockedData;


let { images } = imgList;


const ticked = ( node) => {

  node.attr("transform", 

  function (d) {return "translate(" + d.x + ", " + d.y + ")";});

}


const tickedImg = (nodeImg) => {

  nodeImg.attr("x", function (d) {return  d.x })

}


const node = svg.selectAll(".node")

        .data(nodes);

        

    node

        .enter()

        .append("path")

        .attr("d", (d,i) => {

          //console.log(d,i,images)

          if (nodes.length > 1){

            const j = i == (nodes.length - 1) ? 0 : i + 1;

            const invertArc = (i+1) < (nodes.length/2);

            const gtr2 = nodes.length > 2 ? invertArc : !invertArc;

            //console.log(i,invertArc)

            return pointsToPath(d, nodes[j], gtr2);

          }

          return "";

        })

        .attr("stroke", "black")

        .attr("stroke-dasharray", "4")

        .attr("fill", "transparent");

        

const nodeGroup = node        

        .enter()

        .append("g")

        .attr("class", "node");

        

const circle = nodeGroup.append('circle').attr("r", 86); //radius

circle

    .style("fill", "darkgray")

    .on('click', function () { // arrow function will produce this = undefined

       d3.selectAll('circle')

       .style("fill", "darkgray");

       d3.select(this)

        .style("fill", "aliceblue");

     })

     .on('mouseover', function () {

        d3.selectAll('circle')

        .style("stroke", "black");


        d3.select(this)

        .style("stroke", "green");

    })

    ticked( nodeGroup );


const nodeText = nodeGroup.append("text")

      .attr("y", -70);


nodeText.selectAll("tspan.text")

      .data((d) =>  d.name.split(" "))

      .enter()

      .append("tspan")

      .attr("class", "text")

      .text(d => d)

      .attr("fill", "black")

      .attr("x", -30)

      .attr("y", -60)


nodeGroup.append("title")

      .text(function (d) {return d.id;});


const nodeImg = nodeGroup.selectAll("image")

      .data(images);

nodeImg      

      .enter()

      .append("image")

      .attr("xlink:href", d => d.image)

      .attr("width", d => d.width)

      .attr("height", d => d.height)

      .attr("x", d => d.x)

      .attr("y", d => d.y)

      //tickedImg (nodeImg)

      

      

nodeImg      

      .enter()

      .append("path")

      .attr("d", (d,i) => {

        //console.log(d,i,images)

        if (images.length > 1){

          const j = i == (images.length - 1) ? 0 : i + 1;

          const invertArc = (i+1) < (images.length/2);

          //console.log(i,invertArc)

          return pointsToPath(d, images[j], invertArc);

        }

        return "";

      })

      .attr("stroke", "black")

      .attr("stroke-dasharray", "4")

      .attr("fill", "transparent")

      .attr("transform", d => "translate(" + d.width/2 + ", " + d.height/2 + ")");

      //tickedImg (nodeImg)      

   

      

function pointsToPath(from, to, invertArc) {

  const centerPoint = [ (from.x + to.x) / 2, (from.y + to.y) / 2];

  const slope = (to.y - from.y) / (to.x - from.x);

  const invSlope = -1 / slope;

  const distance = Math.sqrt( Math.pow((to.x - from.x), 2) + Math.pow((to.y - from.y), 2) );

  const offset = (invertArc ? -1 : 1) * 2 * Math.sqrt(distance);


  const angle = Math.atan(slope);

  const offsetY = Math.cos(angle)*offset;

  const offsetX = Math.sin(angle)*offset;

  const offsetCenter = [centerPoint[0] - offsetX, centerPoint[1] + offsetY];

  const arcPointX = offsetCenter[0]

  const arcPointY = offsetCenter[1]   

  return 'M' + from.x + ' ' + from.y + 'Q' + arcPointX + ' ' + arcPointY +

          ' ' + to.x + ' ' + to.y;

 }

<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>

<svg width="100%" viewbox="0 0 1000 500">

  <path d="M20 20 50 50" fill="transparent" stroke-width="5" stroke="black"></path>

</svg>


<script>

//the following d3 code would insert the same path as that manually inserted in the HTML above:

d3.select("svg")

  .append("path")

  //we can set it directly as below, or via a function:

  .attr("d", "M20 20 50 50")

  .attr("fill", "transparent")

  .attr("stroke-width", "5")

  .attr("stroke", "black");

</script>

輸出(20 年 6 月 18 日更新):


http://img1.sycdn.imooc.com//63411f26000188be06010205.jpg

查看完整回答
反對 回復(fù) 2022-10-08
  • 1 回答
  • 0 關(guān)注
  • 78 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號