What is the best method for incorporating a half circle in D3 utilizing designated function parameters?

My query revolves around enhancing this particular chart by filling only half of the circle with a specific group color.

This post on Stack Overflow provides insights into creating half circles using D3.js.

Below is an excerpt from the original code:

var node = svg.append("g")
    .attr("class", "nodes")
    .selectAll("circle")
    .data(graph.nodes)
    .enter().append("circle")
      .attr("r", 5)
      .attr("fill", function(d) { return color(d.group); })
      .call(d3.drag()
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended));

Now, let's introduce a half circle:

var grad = svg.append("defs").append("linearGradient").attr("id", "grad")
              .attr("x1", "0%").attr("x2", "0%").attr("y1", "100%").attr("y2", "0%");
grad.append("stop").attr("offset", "50%").style("stop-color", "lightblue");
grad.append("stop").attr("offset", "50%").style("stop-color", "white");
var node = svg.append("g")
      .attr("class", "nodes")
    .selectAll("circle")
    .data(graph.nodes)
    .enter().append("circle")
      .attr("r", 5)
      .attr("fill", function(d) { return color(d.group); })
      .call(d3.drag()
          .on("start", dragstarted)
          .on("drag", dragged)
          .on("end", dragended));

Is it possible to link this gradient (grad) to the d.group dynamically?

  • I attempted creating a get_grad() function to fetch the gradient and a set_grad() function to assign the fill attribute, but encountered issues implementing them. Can anyone provide guidance on how to accomplish this?

Answer №1

If you wish to incorporate various elements with distinct gradients, the key is to utilize the same data binding technique to generate the gradients themselves:

var defs = svg.append("defs")
    .selectAll("foo")
    .data(data)
    .enter()
    .append("linearGradient")
    //etc...

Remember that IDs must be unique. In this demonstration, I'm achieving this by using:

.attr("id", function(d) {
    return "grad" + d
})

...to establish unique IDs.

The section that may pique your interest in the demo is:

defs.append("stop")
    .attr("offset", "50%")
    .style("stop-color", function(d) {
        return colours(d)
    })

This illustrates applying stop colors based on the provided data.

Take a look at the demo (which isn't a force directed chart but simply displays elements with varying gradients):

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

var colours = d3.scaleOrdinal(d3.schemeCategory10);

var defs = svg.append("defs")
  .selectAll("foo")
  .data(d3.range(5))
  .enter()
  .append("linearGradient")
  .attr("id", function(d) {
    return "grad" + d
  })
  .attr("x1", "0%")
  .attr("x2", "0%")
  .attr("y1", "100%")
  .attr("y2", "0%");

defs.append("stop")
  .attr("offset", "50%")
  .style("stop-color", function(d) {
    return colours(d)
  })

defs.append("stop")
  .attr("offset", "50%")
  .style("stop-color", "white");

var circles = svg.selectAll("foo")
  .data(d3.range(5))
  .enter()
  .append("circle")
  .attr("cy", 50)
  .attr("cx", function(d) {
    return 25 + d * 62
  })
  .attr("r", 25)
  .attr("stroke", "dimgray")
  .attr("fill", function(d) {
    return "url(#grad" + d + ")"
  })
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>

Furthermore, you can experiment with the offsets:

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

var colours = d3.scaleOrdinal(d3.schemeCategory10);

var defs = svg.append("defs")
  .selectAll("foo")
  .data(d3.range(5))
  .enter()
  .append("linearGradient")
  .attr("id", function(d) {
    return "grad" + d
  })
  .attr("x1", "0%")
  .attr("x2", "0%")
  .attr("y1", "100%")
  .attr("y2", "0%");

defs.append("stop")
  .attr("offset", function(d) {
    return 20 + d * 15 + "%"
  })
  .style("stop-color", function(d) {
    return colours(d)
  })

defs.append("stop")
  .attr("offset", function(d) {
    return 20 + d * 15 + "%"
  })
  .style("stop-color", "white");

var circles = svg.selectAll("foo")
  .data(d3.range(5))
  .enter()
  .append("circle")
  .attr("cy", 50)
  .attr("cx", function(d) {
    return 25 + d * 62
  })
  .attr("r", 25)
  .attr("stroke", "dimgray")
  .attr("fill", function(d) {
    return "url(#grad" + d + ")"
  })
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountering an unusual reactivity problem involving Firebase (Firestore) when using Vue.js and Vuefire

I'm facing a strange issue and I'm completely stuck. Here is the component in question: <template> <v-card elevation="0"> <h2>Accounts</h2> <v-simple-table fixed-header height="300px"> <template v ...

JQUERY function fails to execute following the invocation of an array

There is an array named NAME being created. Weirdly, the code seems to be functioning fine for alert('test1') but encounters an issue when reaching alert('test2') $(document).on('submit','form',function() { ...

Error encountered while invoking web server method in C# through ajax resulting in a 500 Internal Server Error

Occasionally encountering a 500 internal server error when calling a server method from an AJAX request has left me perplexed. The inconsistency of the issue, sometimes working fine and sometimes not, is baffling. To add to the confusion, no changes were m ...

What is the most effective way to stop zooming when focusing on form fields on iOS or similar devices when using font sizes of 16px or lower?

It appears that many proposed solutions involve changing the text to 16px or using JavaScript to determine if the phone is an iPhone. However, altering the style may not be the most practical solution and checking for specific devices like iPhones could ...

Step-by-step guide on concealing elements and subsequently displaying them upon clicking the containing DIV

It's a bit tricky to explain without visuals, so I suggest checking out the JSFiddle link provided. Essentially, when a specific div is clicked, it should expand to reveal some inputs and buttons. However, the issue I'm facing is that upon loadin ...

Choosing various data using Ajax

I am currently in the process of extracting various pieces of data from my insert.php page, including the post id, username, and user id. I intend to include other selected data as well. However, when trying to echo out multiple queries, all the informatio ...

Using Angular.JS to iterate over a nested JSON array using ng-repeat

I am currently working on a People service that utilizes $resource. I make a call to this service from a PeopleCtrl using People.query() in order to retrieve a list of users from a json api. The returned data looks like this: [ { "usr_id" : "1" ...

Secure your website with the latest JWT cookie security measures

After storing a JWT with an expiry date set 30 days ahead, the question arises - is it secure to store this JWT in a cookie? The aim is for the token to persist beyond a single session, much like the "Keep me logged in" feature found on some websites. Se ...

What is the best way to update the state of object.item[n] that is nested within an array, which in turn is nested within

A unique data structure is set up in the following way: const library = [ { procedureName:'Build Foundations', id:1, tasks:[ { taskName:'dig at least 1m deep', isCompleted:false, procedureId:1 }, ...

Express is having trouble providing data to React

Currently, I am delving into mastering the realms of React and Express. My ongoing project involves crafting a learning application that fetches data from MySQL and renders it visually for analysis. To kickstart this endeavor, I set up a basic express ser ...

Utilize Redux-forms to trigger an alternative submission method when ComponentWillRecieveProps is called

redux-forms version: 6.6.3 react version: 15.5.0 Seeking help with calling different submit functions from the componentWillReceiveProps method in a React component. componentWillReceiveProps(nextProps) { if (nextProps.updateTierConfigState == "Valida ...

Comparing the use of visibility: hidden with -webkit-transform: translate3d() within a PhoneGap application

Currently, I am creating a hybrid application using PhoneGap. As part of the design, I have several divs (each representing a page) that I toggle between by changing their visibility in CSS using "visibility: hidden" and "visible". However, I recently ca ...

When the C# method is executed, jQuery is reset

One feature I have on my website is a "newsletter" widget that expands when the user clicks a button. Inside the expanded section, there is an input box for email address and a submit button. The code behind this functionality verifies the email format and ...

The mouse pointer position in THREE.js does not align with the arrow tip during events

I am currently grappling with figuring out how to accurately determine the position of click events on the screen while using THREE.js alongside an Orthographic camera. Unfortunately, the position that I have managed to calculate (similarly to what is des ...

Ways to modify the end result using callback information

In my scenario, I am working with an object that has keys id and name as shown below. The goal is to retrieve the customer name based on the id and then update the object accordingly. Const arr=[{id:1,name:''},{id:2,name:''}]; ...

Linking a Checkbox to a Field's Value in AngularJS

I need assistance with checking/unchecking the checkbox depending on the value of the field services.Register.IsTest. If services.Register.IsTest=True, then the checkbox should be checked. Otherwise, it should remain unchecked. Here is the checkbox code: ...

AngularJS multiple select dropdown with dynamic quantity selection

I am currently utilizing AngularJS instead of Angular and I am looking to implement a corresponding textbox next to the dynamic select box. Below is my code for dynamically adding select boxes: HTML <div ng-controller='MyController'> ...

In Typescript, try/catch blocks do not capture return values

I am currently working on a function that performs database operations, with the implementation contained within a try/catch block. Here is an example: async function update({id, ...changes}): Promise<IUserResult> { try { //insert code here retu ...

Having trouble retrieving process variable in Vue3JS Vite project

In my Vue3 application, developed with Vite, I am integrating with a Solidity smart contract on Ropsten using web3js. Additionally, I am utilizing web3.storage to store images on IPFS, with the API key stored in a `.env` file at the project root: VUE_APP_A ...

Is it possible to enhance an external class with a non-static method using prototypes?

Is it possible to use prototypes to add a function for a class instance? allowing me to access this or __proto__ keyword inside my method, like so: class PersonClass { name: string; constructor(name: string) { this.name = name; } sayHello() ...