изображение как фон круга (d3.js svg)

#d3.js #d3-force-directed

#d3.js #d3-принудительно направленный

Вопрос:

ОБНОВЛЕНО Я создал график, ориентированный на силу, используя D3.js . Каждый узел соответствует компании, и каждая ссылка соответствует тому, как они связаны друг с другом в соответствии с цветом ссылки. Чего я хотел бы добиться, так это использовать URL-адреса изображений в данных «узлов» и показывать разные изображения для каждого пузырька. В настоящее время я смог установить фиксированное статическое / идентичное изображение для всех моих пузырьков. Я попытался подключить шаблон к моим данным «узлов», но безуспешно, что привело к бесконечному циклу.

введите описание изображения здесь

Простой HTML-холст для моего svg и две кнопки для увеличения и уменьшения масштаба щелчком мыши.

     <div class="main-map-container" style="overflow: hidden">
        <div class="canvas">
            <div>
                <button id="zoom_in"> </button>
                <button id="zoom_out">-</button>
            </div>
        </div>
    </div> 
 

Мои наборы данных (ссылки и узлы), обратите внимание на атрибут изображения на узлах. это относится к изображению, которое я хочу установить в качестве фона узла

 
    const links = [
        {src:"Amazon",target:"Aurora",link:"Investment",market:"Semi_Truck",tags:"AD_L3-4|AD_Driverless",technology:"",aces:"Automated",amount:"",region:"EU| US",date:"2019-02-01",description:"Amazon Investing in Aurora in an $530 million Financing Round",source:"https://drive.google.com/open?id=1aLuuUqXKSQcGzivH21CSuO7204pdyP7K",years:"2019"},
        {src:"Amazon",target:"Aurora",link:"Investment",market:"Robotaxi | Semi_Truck",tags:"AD_Driverless",technology:"",aces:"Automated",amount:"$530",region:"EU| US",date:"2019-02-01",description:"Aurora announced that they have secured over $530 million in Series B financing led by Sequoia. This funding and partnership will accelerate their mission of delivering the benefits of self-driving technology safely, quickly, and broadly.rnrnIn addition to Sequoia, Amazon, and funds and accounts advised by T. Rowe Price Associates, Inc. are making significant investments in Aurora. Amazon’s unique expertise, capabilities, and perspectives will be valuable for us as we drive towards our mission.",source:"https://drive.google.com/open?id=1aLuuUqXKSQcGzivH21CSuO7204pdyP7K",years:"2019"},
        {src:"Amazon",target:"Zoox",link:"Acquisition",market:"Robotaxi",tags:"AD_Driverless",technology:"",aces:"Automated",amount:"$1,200",region:"US",date:"2020-06-01",description:"Amazon acquires Zoox to help bring their vision of autonomous ride-hailing to reality. [The Financial Times reports that Amazon spends $1.2bn on the acquisition.]",source:"https://drive.google.com/open?id=18-zXDSHy9_o0OrIwYFfb5FdyMxMzgtHH",years:"2020"},
        {src:"Amazon",target:"Rivian",link:"Investment",market:"Light_CV",tags:"Other",technology:"",aces:"Automated",amount:"",region:"US",date:"2020-10-01",description:"Amazon unveils its new electric delivery vans built by RiviannThe delivery giant aims to have 10,000 vehicles on the road by 2022, 100,000 vehicles expected by 2030.",source:"https://www.theverge.com/2020/10/8/21507495/amazon-electric-delivery-van-rivian-date-specs",years:"2020"},
        {src:"Amazon",target:"Torc",link:"Partnership",market:"Semi_Truck",tags:"AD_L3-4| Edge/Cloud_computing",technology:"",aces:"Automated| Connected",amount:"",region:"US",date:"2021-02-17",description:"Torc selects AWS as preferred cloud provider for self-driving truck fleet",source:"https://drive.google.com/open?id=1QDHZIyUHpAY4oKEqmeM9cngPIWZWV2doE0r1emQZuNY",years:"2021"},
        {src:"Amazon",target:"Intel",link:"Partnership",market:"PoV",tags:"Edge/Cloud_computing",technology:"",aces:"Connected",amount:"",region:"EU| US| China| Korea| Japan| Others",date:"2021-03-01",description:"Intel Achieves AWS High Performance Computing Competency Status",source:"https://drive.google.com/open?id=1MvhLikyzwbu-Mz_OuXUvytAuqXNEnUjHdSxMGXcKLok",years:"2021"},
        {src:"Aurora",target:"Blackmore",link:"Acquisition",market:"Semi_Truck | Robotaxi",tags:"AD_Driverless",technology:"LiDAR",aces:"Automated",amount:"",region:"US",date:"2019-01-09",description:"Yesterday announce that they plan to acquire the industry-leading lidar company Blackmore, located in Bozeman, Montana.rnrnThe Bozeman, Montana–based outfit, which started up a decade ago to do work for the defense industry, uses a “frequency modulated continuous wave” system, also known as a Doppler lidar. When the infrared light hits an object and bounces back, the system determines both how far away it is and its velocity. Knowing where something is headed and how fast is prized data. Blackmore has at least one Doppler lidar competitor in Aeva, founded in early 2017 by a pair of former Apple engineers. [...]",source:"https://drive.google.com/open?id=1UkF-sxgA1AgpgWoRCd2qgWjovLQULoAP",years:"2019"},
        {src:"Aurora",target:"Uber ATG",link:"Acquisition",market:"Robotaxi | Semi_Truck",tags:"AD_Driverless",technology:"",aces:"Automated",amount:"$4,000",region:"US",date:"2020-12-01",description:"Aurora is acquiring Uber's self-driving unit, ATG, accelerating the first Aurora Driver applications for heavy-duty trucks while allowing us to continue and accelerate our work on light-vehicle products. "Simply put, Aurora will be the company best positioned to deliver the self-driving products necessary to make transportation and logistics safer, more accessible, and less expensive," said Chris Urmson, co-founder and CEO of Aurora.",source:"https://drive.google.com/open?id=1rc-_3VLlITe2bdxBgws3Bvb2rPvCluMfsMkFXiwbg98",years:"2020"},
        {src:"Aurora",target:"Paccar",link:"Partnership",market:"Semi_Truck",tags:"AD_L3-4",technology:"",aces:"Automated",amount:"",region:"US",date:"2021-01-19",description:"Aurora teams up with PACCAR to build and deploy self-driving trucks",source:"https://drive.google.com/open?id=1TfA9U81CbyNwQc4Xfg2iJ9wqmka7RLqVEIsES2-62Ww",years:"2021"},
        {src:"Aurora",target:"Denso",link:"Partnership",market:"Robotaxi",tags:"AD_Driverless",technology:"",aces:"Automated",amount:"",region:"EU| US| China| Korea| Japan| Others",date:"2021-02-09",description:"Aurora enters into long-term, global, and strategic collaboration with Toyota and Denso",source:"https://drive.google.com/open?id=1QnlNnMMxbcPdnbi4AcBo36_UWM9TuMrNqItZHfPDUos",years:"2021"},
        {src:"Aurora",target:"Toyota",link:"Partnership",market:"Robotaxi",tags:"AD_Driverless",technology:"",aces:"Automated",amount:"",region:"EU| US| China| Korea| Japan| Others",date:"2021-02-09",description:"Aurora enters into long-term, global, and strategic collaboration with Toyota and Denso",source:"https://drive.google.com/open?id=1QnlNnMMxbcPdnbi4AcBo36_UWM9TuMrNqItZHfPDUos",years:"2021"},
        {src:"Aurora",target:"OURS-Tech",link:"Acquisition",market:"Semi_Truck| Robotaxi",tags:"",technology:"LiDAR",aces:"Automated",amount:"",region:"US",date:"2021-02-26",description:"Aurora acquires OURS lidar (FMCW), unlocking the commercialization of its Aurora Driver",source:"https://drive.google.com/open?id=1TWEII1c0jQk26DcCC2WXw3plT0XTnfDzmD-e551VWSQ",years:"2021"},
        {src:"Zoox",target:"ZadarLabs",link:"Investment",market:"PoV| Robotaxi",tags:"AD_L3-4| AD_Driverless",technology:"Radar",aces:"Automated",amount:"",region:"US",date:"2021-01-26",description:"Zadar Labs, Developing Next Generation Imaging Radar, Closes $5.6M in Seed Funding",source:"https://drive.google.com/open?id=1fz3MhS4P_Cmq2VmT9crQztUBd9W5Pj-IWEL9ABq3ySg",years:"2021"},
        {src:"Intel",target:"Mobileye",link:"Acquisition",market:"PoV",tags:"AD_L3-4",technology:"",aces:"Automated",amount:"$15,000",region:"Worldwide",date:"2017-01-14",description:"Instead of Mobileye being integrated into Intel, Intel’s AD Group (ADG) will be integrated into Mobileye.",source:"https://www.engadget.com/2017-08-08-intel-acquisition-Mobileye-complete.html",years:"<2017"},
        {src:"Intel",target:"Infineon",link:"Acquisition",market:"",tags:"",technology:"",aces:"Automated|Experience",amount:"1400",region:"US|EU",date:"2010-01-01",description:"Intel to Acquire Infineon’s Wireless Solutions Business",source:"https://www.infineon.com/cms/en/about-infineon/press/press-releases/2010/INFXX201008-069.html",years:"<2017"},
    ]

    const nodes = [
        {id:"Amazon",type:"Tech",tags:"",technology:"",market:"Droid_Goods|Robotaxi",valuation:"",description:"Amazon is an international e-commerce website for consumers, sellers, and content creators.",country:"US",region:"North America",image:"https://images-eu.ssl-images-amazon.com/images/G/02/gc/designs/livepreview/a_generic_10_uk_noto_email_v2016_uk-main._CB485921599_.png"},
        {id:"Aurora",type:"Tier1",tags:"AD_Driverless",technology:"",market:"Robotaxi|Semi_Truck",valuation:"1100",description:"Aurora is delivering the benefits of self-driving technology safely, quickly, and broadly.",country:"US",region:"North America",image:"https://res-3.cloudinary.com/crunchbase-production/image/upload/c_lpad,h_170,w_170,f_auto,b_white,q_auto:eco/oeagjbu7wau6o16zdhb1"},
        {id:"Zoox",type:"Tier1",tags:"AD_Driverless",technology:"",market:"Robotaxi",valuation:"",description:"Zoox is an AI robotics company that provides mobility as-a-service and self-driving car services.",country:"US",region:"North America",image:"https://res-4.cloudinary.com/crunchbase-production/image/upload/c_lpad,h_170,w_170,f_auto,b_white,q_auto:eco/kpc7mmk886nbbipbeqau"},
        {id:"Rivian",type:"OEM",tags:"",technology:"",market:"PoV",valuation:"8200",description:"Rivian is an electric vehicle manufacturer that develops products and services to advance the shift to sustainable mobility.",country:"US",region:"North America",image:"https://res-4.cloudinary.com/crunchbase-production/image/upload/c_lpad,h_170,w_170,f_auto,b_white,q_auto:eco/sdz7aspakybuxp7oojvh"},
        {id:"Torc",type:"Tier1",tags:"AD_Driverless|AD_L3-4",technology:"",market:"Semi_Truck|Mining",valuation:"",description:"Torc provides L4 end-to-end self-driving software for mobility, trucking, mining, and defense markets through strategic partnerships",country:"US",region:"North America",image:"https://res-2.cloudinary.com/crunchbase-production/image/upload/c_lpad,h_170,w_170,f_auto,b_white,q_auto:eco/smfgyxvfot1dwq4vqvo7"},
        {id:"Intel",type:"Tech",tags:"",technology:"",market:"PoV | Robotaxi",valuation:"",description:"Intel designs, manufactures, and sells integrated digital technology platforms worldwide.",country:"US",region:"North America",image:"https://res-3.cloudinary.com/crunchbase-production/image/upload/c_lpad,h_170,w_170,f_auto,b_white,q_auto:eco/v1505768454/wrhwa2ogipbd1o6tgggi.png"},
        {id:"Blackmore",type:"Tier2",tags:"",technology:"LiDAR",market:"PoV|Other",valuation:"21.5",description:"Blackmore Sensors and Analytics develops frequency-modulated continuous wave lidar imaging and its supporting analytic tools software.",country:"US",region:"North America",image:"https://res-2.cloudinary.com/crunchbase-production/image/upload/c_lpad,h_170,w_170,f_auto,b_white,q_auto:eco/v1497015437/tqor2yimyfapcsn5uyaj.png"},
        {id:"Uber ATG",type:"Tier1",tags:"AD_Driverless",technology:"",market:"Robotaxi",valuation:"1000",description:"Uber Advanced Technologies Group focuses on autonomous vehicles and the self-driving car business.",country:"US",region:"North America",image:"https://res-5.cloudinary.com/crunchbase-production/image/upload/c_lpad,h_170,w_170,f_auto,b_white,q_auto:eco/dlzugstswtlgq9wejmfi"},
        {id:"Paccar",type:"OEM",tags:"",technology:"",market:"Semi_Truck",valuation:"",description:"Global technology leader in the design, manufacture and customer support of high-quality premium trucks.",country:"US",region:"North America",image:"https://res-2.cloudinary.com/crunchbase-production/image/upload/c_lpad,h_170,w_170,f_auto,b_white,q_auto:eco/v1404996232/nmvcucjqpgpnhrolbnnk.png"},
        {id:"Denso",type:"Tier1",tags:"",technology:"",market:"PoV",valuation:"",description:"Supplier of advanced automotive technology",country:"Japan",region:"Japan",image:"https://res-5.cloudinary.com/crunchbase-production/image/upload/c_lpad,h_170,w_170,f_auto,b_white,q_auto:eco/v1398234958/fnjwkbbov8sivhs79wta.png"},
        {id:"Toyota",type:"OEM",tags:"",technology:"",market:"PoV",valuation:"",description:"Toyota is a Japanese automotive company that manufactures and markets vehicles to over 170 countries and regions.",country:"Japan",region:"Japan",image:"https://res-3.cloudinary.com/crunchbase-production/image/upload/c_lpad,h_170,w_170,f_auto,b_white,q_auto:eco/v1425366959/cleoo1wmofcfxxspobul.jpg"},
        {id:"OURS-Tech",type:"Tier2",tags:"",technology:"LiDAR",market:"Semi_Truck| Robotaxi",valuation:"",description:"Enabling mass-production 5D LiDAR for the autonomous future",country:"US",region:"North America",image:"https://static.wixstatic.com/media/c668c3_f1f58317e99d41deac4152d212fcdbc2~mv2.gif"},
        {id:"ZadarLabs",type:"Tier2",tags:"",technology:"Radar",market:"PoV| Robotaxi",valuation:"",description:"Zadar Labs brings radar intelligence to autonomous systems",country:"US",region:"North America",image:"https://res-1.cloudinary.com/crunchbase-production/image/upload/c_lpad,h_170,w_170,f_auto,b_white,q_auto:eco/g3kgj9vsfjzlpbichdml"},
        {id:"Mobileye",type:"Tech",tags:"AS_NCAP|ADAS_uptoL2 |AD_Driverless",technology:"ECU_ADAS",market:"PoV|Robotaxi|Semi_Truck",valuation:"515",description:"Mobileye is a technology company developing vision-based advanced driver assistance systems that help prevent and mitigate collisions.",country:"Israel",region:"Others",image:"https://res-3.cloudinary.com/crunchbase-production/image/upload/c_lpad,h_170,w_170,f_auto,b_white,q_auto:eco/bcuhhoflftvvdbpeaarx"},
        {id:"Infineon",type:"Tier2",tags:"Interior_cocoon",technology:"",market:"PoV",valuation:"",description:"Infineon Technologies offers semiconductor solutions, microcontrollers, LED drivers, sensors and Automotive amp; Power Management ICs.",country:"Germany",region:"EU",image:"https://res-2.cloudinary.com/crunchbase-production/image/upload/c_lpad,h_170,w_170,f_auto,b_white,q_auto:eco/v1397183702/79bc5b009247cfd1a274f2a328ff17bf.png"},
    
    ]
 

Что касается моего кода javascript на D3, вот раздел с наиболее релевантными :

     const svg = d3.create("svg")
        .attr("preserveAspectRatio", "xMinYMin meet")
        .attr("viewBox", [-width/2,-height/2, width,height])
        .classed("svg-content-responsive", true)

    const defs = svg.append('svg:defs');
    

    defs.append("svg:pattern")
    .attr("id", "grump_avatar")
    .attr("width", 1)
    .attr("height", 1)
    //.attr("patternUnits", "userSpaceOnUse")
    .append("svg:image")
    .attr("xlink:href", 'http://placekitten.com/g/48/48')
    .attr("width",40)
    .attr("height",40)
    .attr("x",0)
    .attr("y",0)

   
    const link = svg.append("g")
        .attr("stroke-opacity", 0.6)
        .attr("stroke-width",  7)
        .attr("stroke-linecap", "round")
        .selectAll("line")
        .data(links)
        .join("line")
        
    if (l) link.attr("stroke", ({index: i}) => setLinkColor(l[i])); // set conditional link color

    
    const node = svg.append("g")
        .attr("stroke", "teal")
        .attr("stroke-opacity", 1)
        .attr("stroke-width", 2)
        .selectAll("circle")
        .data(nodes)
        .join("circle")
        .style("fill", "#fff")
        .style("fill", "url(#grump_avatar)")
        .attr("r", 20)
        .call(drag(simulation))
        

 

Ответ №1:

Я использовал ваш код для сборки небольшого примера, который вы можете увидеть ниже.

  1. Внутри svg > defs создайте по одному pattern для каждого узла и используйте его pattern (с идентификатором компании) для получения логотипа этой компании;
  2. Обратитесь pattern к узлу for, используя информацию, которая у вас уже есть.

Некоторые указатели на ваш код:

  1. Вы уже используете логику ES6, поэтому вы также можете использовать Array.prototype.map и другие функции. Они, как правило, гораздо более удобочитаемы (и изначально реализованы!), Чем d3.map ;
  2. Нет необходимости хранить так много массивов значений, как правило, наличие меньшего количества достоверных источников для ваших данных упростит поддержку и обновление кода в будущем;
  3. Используйте четкие имена переменных! LS и LT логичны, когда вы знаете контекст, но когда вы вернетесь к этому коду через 6 месяцев, вы можете не сразу понять, о чем вы говорили, когда писали его.
 const nodes = [{
    id: "Amazon",
    image: "https://images-eu.ssl-images-amazon.com/images/G/02/gc/designs/livepreview/a_generic_10_uk_noto_email_v2016_uk-main._CB485921599_.png"
  },
  {
    id: "Aurora",
    image: "https://res-3.cloudinary.com/crunchbase-production/image/upload/c_lpad,h_170,w_170,f_auto,b_white,q_auto:eco/oeagjbu7wau6o16zdhb1"
  },
  {
    id: "Zoox",
    image: "https://res-4.cloudinary.com/crunchbase-production/image/upload/c_lpad,h_170,w_170,f_auto,b_white,q_auto:eco/kpc7mmk886nbbipbeqau"
  }
];

const links = [{
    src: 'Amazon',
    target: 'Aurora'
  },
  {
    src: 'Amazon',
    target: 'Zoox'
  },
  {
    src: 'Aurora',
    target: 'Zoox'
  }
];

const width = 500,
  height = 500;

function ForceGraph({
  nodes, // an iterable of node objects (typically [{id}, …])
  links // an iterable of link objects (typically [{src, target}, …])
}, {
  nodeId = d => d.id, // given d in nodes, returns a unique identifier (string)
  nodeTitle, // given d in nodes, a title string
  nodeStroke = "teal", // node stroke color
  nodeStrokeWidth = 2, // node stroke width, in pixels
  nodeStrokeOpacity = 1, // node stroke opacity
  nodeRadius = 20, // node radius, in pixels
  nodeStrength = -750,
  linkDistance = 100,
  linkStrokeOpacity = 0.6, // link stroke opacity
  linkStrokeWidth = 7, // given d in links, returns a stroke width in pixels
  linkStrokeLinecap = "round", // link stroke linecap
  linkStrength,
  container
} = {}) {

  // Compute values.
  const N = d3.map(nodes, nodeId);

  // HERE: Don't replace the input nodes using this complex method,
  // just Object.assign({}, n) to essentially perform a deep copy of a node.

  // Replace the input nodes and links with mutable objects for the simulation.
  nodes = nodes.map(n => Object.assign({}, n));
  links = links.map(l => ({
    source: l.src,
    target: l.target
  }));

  const svg = d3.select('body')
    .append("svg")
    .attr("preserveAspectRatio", "xMinYMin meet")
    .attr("viewBox", [-width / 2, -height / 2, width, height])
    .classed("svg-content-responsive", true)

  const defs = svg.append('svg:defs');

  // HERE: See we add one image per node
  defs.selectAll("pattern")
    .data(nodes)
    .join(
      enter => {
        // For every new <pattern>, set the constants and append an <image> tag
        const patterns = enter
          .append("pattern")
          .attr("width", 48)
          .attr("height", 48);
        patterns
          .append("image")
          .attr("width", 48)
          .attr("height", 48)
          .attr("x", 0)
          .attr("y", 0);
        return patterns;
      }
    )
    // For every <pattern>, set it to point to the correct
    // URL and have the correct (company) ID
    .attr("id", d => d.id)
    .select("image")
    .datum(d => {
      debugger;
      return d;
    })
    .attr("xlink:href", d => {
      debugger;
      return d.image;
    })

  const link = svg.append("g")
    .attr("stroke-opacity", linkStrokeOpacity)
    .attr("stroke-width", linkStrokeWidth)
    .attr("stroke-linecap", linkStrokeLinecap)
    .selectAll("line")
    .data(links)
    .join("line");

  // Construct the forces.
  const forceNode = d3.forceManyBody();
  const forceLink = d3.forceLink(links).id(({
    index: i
  }) => N[i]);
  if (nodeStrength !== undefined) forceNode.strength(nodeStrength);
  if (linkStrength !== undefined) forceLink.strength(linkStrength);
  forceLink.distance(linkDistance)
  const simulation = d3.forceSimulation(nodes)
    .force(link, forceLink)
    .force("charge", forceNode)
    .force("x", d3.forceX())
    .force("y", d3.forceY())
    .on("tick", ticked);

  const node = svg.append("g")
    .attr("stroke", nodeStroke)
    .attr("stroke-opacity", nodeStrokeOpacity)
    .attr("stroke-width", nodeStrokeWidth)
    .selectAll("circle")
    .data(nodes)
    .join("circle")
    .style("fill", "#fff")
    .style("fill", d => `url(#${d.id})`)
    .attr("r", nodeRadius);

  function ticked() {
    link
      .attr("x1", d => d.source.x)
      .attr("y1", d => d.source.y)
      .attr("x2", d => d.target.x)
      .attr("y2", d => d.target.y);
    node
      .attr("cx", d => d.x)
      .attr("cy", d => d.y);
  }
} // ForceGraph

ForceGraph({
  nodes,
  links
}); 
 line {
  stroke: red;
} 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.2.0/d3.js"></script>