Changing color in D3.js stacked areas when exceeding a certain threshold

While working on a project, I inherited an application that included a D3.js graph which needed to be completed. Despite not being familiar with the D3.js library initially, I managed to make some improvements. However, there is one issue I haven't been able to resolve - changing the color of the graph area from yellow to red when a certain value (-30 in this case) is exceeded (refer to the images below).

The image on the left shows the current state while the one on the right depicts the desired outcome:

I learned about stacking multiple areas using the d3.layout.stack() function. However, most examples I found involved hard-coded JSON or overlaying multiple graphs.
Below is a portion of the existing code (excluding irrelevant parts):

var area = d3.svg.area()
    .interpolate("basis") 
    .x(function (d) {return x(d.date); })
    .y0(function (d) {return y(0); })
    .y1(function (d) {return y(d.energy); });
var svg = d3.select("#datacontainer2").append("svg")
    .attr("width", width + margin.left + margin.right)
    .attr("height", height + margin.top + margin.bottom);
svg.append("defs").append("clipPath")
    .attr("id", "clip")
    .append("rect")
    .attr("width", width)
    .attr("height", height);
var context = svg.append("g").attr("transform","translate("+margin2.left+","+margin2.top + ")");

d3.csv("file:///data.txt", function (error, data) {
    data.forEach(function (d) {
        d.date = parseDate(d.date);
        d.energy = d.energy; 
    });

    x.domain(d3.extent(data.map(function (d) { return d.date; })));
    y.domain([25, -50] /*d3.extent(data.map(function(d) { return d.energy; }))*/ );
    x2.domain(x.domain());
    y2.domain(y.domain());

    focus.append("path")
        .datum(data)
        .attr("clip-path", "url(#clip)")
        .attr("d", area);

    // red line
    focus.append("svg:line")
        .attr("x1", 0)
        .attr("x2", height * data.length)
        .attr("y1", (function (d) { return y(-30); } ))
        .attr("y2", (function (d) { return y(-30); }))
        .attr("stroke", "#ff0000")
        .attr("stroke-width", "3");
});

Additionally, values below zero should be colored green, a feature that can be easily implemented once the above issue is resolved.

Answer №1

If you're searching for a solution, this might be what you need: http://jsfiddle.net/h45CD/.

To achieve a gradient in a specific area and color it accordingly:
// Define the threshold
    svg.append("linearGradient")                    
        .attr("id", "area-gradient")                // change from line to area
        .attr("gradientUnits", "userSpaceOnUse")    
        .attr("x1", 0).attr("y1", y(0))             
        .attr("x2", 0).attr("y2", y(1000))          
    .selectAll("stop")                              
        .data([                                     
            {offset: "0%", color: "red"},           
            {offset: "30%", color: "red"},      
            {offset: "45%", color: "black"},        
            {offset: "55%", color: "black"},    
            {offset: "60%", color: "lawngreen"},    
            {offset: "100%", color: "lawngreen"}    
        ])                                          
    .enter().append("stop")                         
        .attr("offset", function(d) { return d.offset; })       
        .attr("stop-color", function(d) { return d.color; });   

For further insights, check out d3noob.

Answer №2

Although this question is dated, I wanted to share my experience for those who may come across it in the future. Personally, I'm not a fan of gradient effects, so I sought out an alternative solution. One approach that I found particularly appealing and visually clean is showcased in this example provided by Mike himself.

http://bl.ocks.org/mbostock/4062844

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

Leverage ng-value attribute when working with radio buttons in AngularJS

I have recently started working with AngularJS and I am trying to create a selection using radio buttons that will save as a boolean value. However, when I use ng-value, the value saved in the database is null. Here is the HTML code: <label><in ...

"Using html_attr with the attribute "href" does not return any value in the rvest package

My objective is to extract the URLs linked with specific CSS elements on a website using rvest. Despite trying various methods, such as using the html_attr function with the 'href' argument, my current script only returns NA values instead of the ...

Dealing with vertical overflow in a flex-grow container within Bootstrap 4

As a newcomer to HTML web layout (I must admit, I might be making rookie mistakes), I'm struggling with an issue that's been driving me crazy. Despite searching extensively, I haven't found a solution that fits my particular case. I'm ...

Utilizing Selenium to Extract Data from ESPN Website

I am currently working on a project that involves scraping data from ESPN, performing calculations on the scraped data, and then iterating through a dataframe to process player information. While I have successfully completed this task for one player, I am ...

Incorporating a Vue application into a server-side framework application, encountering issues with Vue Public Path

Summary - Incorporating a Vue app into a Phoenix app. Constructing the Vue app with vue cli and ensuring the files are placed correctly within the Phoenix project directories. After building, there is an issue where the asset file paths do not align with t ...

Increase the right border size by half when the image is being hovered over

Seeking assistance with creating a hover image with a right border of color #000 that covers only 80% of the image's full length. I have attempted adjusting other "half border" codes for this purpose without success. Any suggestions on how to achieve ...

You are unable to insert a variable within the channels.get() method in discord.js

Attempting to troubleshoot this issue has been quite frustrating. Despite my efforts, it seems that something is not working as expected. I can't help but wonder if I am simply overlooking a simple mistake due to fatigue. Here's the scenario: It ...

My intention is to ensure that the page is printed with the Background graphics checkbox pre-checked

When using the print button, I typically include the following code: onclick="window.print();" I also came across this code snippet to set a checkbox as checked by default: <style type="text/css" media="print"> * { -webkit-print-color- ...

What methods are available for managing model fields within a for loop in Django?

As a newcomer to Django, I am embarking on the journey of creating a Quiz web application that presents one question at a time. Upon selecting an answer using radio buttons, the application should promptly display whether the response is correct or incorre ...

The default export (imported as 'Vue') could not be located within the 'vue' module in Vue 3 and Laravel

I'm currently in the process of building a project that combines Laravel 8 and Vue JS 3. I've set everything up, but whenever I try running `npm run watch`, I encounter an error message similar to the one below. Despite looking through various fo ...

Maintain the information at the top of the page

I'm working on a PHP page that showcases a company telephone list. At the top of the page, there are option buttons for adding and removing entries, with the data displayed below. However, when a user scrolls down the page, the buttons move out of vi ...

Step-by-step guide to implementing a datepicker textfield with Vuetify 3

I'm currently exploring Vuetify 3 and aiming to implement a textfield that serves as a datepicker. For reference, you can find a similar example in the Vuetify 2 documentation here. Unfortunately, the Vuetify 3 docs do not yet include an example like ...

The validation messages for jQuery Chosen select do not disappear until the form is submitted

Why are the jQuery chosen select validation messages not disappearing until the form is submitted? I have applied required validation and when I submit the form without choosing a value, an error message is displayed. However, after choosing a value, the ...

Top method for developing a cohesive single-page application

Many websites are incorporating JSON data in string format within their page responses, along with HTML: For example, take a look at https://i.sstatic.net/bDU7X.png The benefit of rendering JSON in string format within the page response is that it allow ...

Experiencing difficulty saving information from an HTML file due to an unexpected error in the browser

My website project includes a registration form to gather user data. I wrote the JavaScript code that should store this data when the user clicks on the sign-up button. Here is a snippet of my HTML: <input type="text" class="loginInfo& ...

Displaying one out of two elements when the button is clicked

Trying to implement two buttons on the parent component, each displaying a different component - one for itemlist and the other for itemlist2. Struggling to get it right, even after following an example at https://codepen.io/PiotrBerebecki/pen/yaVaLK. No ...

Update the color of the text depending on the background color

When hovering over my CTA, a sliding effect occurs. However, I am facing an issue with the text being difficult to read depending on the background color. To better understand what I'm trying to achieve, you can view the demo here: Demo on CodePen T ...

Let's leverage the power of Node.js and Express with the Jade templating

My goal is to iterate over an array within a jade layout file named lessons.jade: each lesson in myLessons ul.nav.pull-center: li.dropdown.nav.text-center .btn.btn-default.dropdown-toggle.btn-lg.btn-block(data-toggle="dropdown ...

Retrieve JSON data by making a POST request to a website's API

Can you help me retrieve Json data from a website API using JavaScript? I'm trying to fetch quotes from the following website: for my quotes generator page. While I have some understanding of making GET requests, it seems that this API requires POST ...

Issue encountered during Firebase deployment: Module '@babel/runtime/helpers/builtin/interopRequireDefault' not found

Struggling to deploy firebase functions and encountering multiple issues. During the deployment process, facing a babel error: Error: Cannot find module '@babel/runtime/helpers/builtin/interopRequireDefault' at Function.Module._resolveFilen ...