Creating responsive arrow heads using D3: A step-by-step guide

Currently, I am working on creating a thermometer-style bar chart using D3.js version 3. While I have successfully created a basic responsive rectangle with two filled colors, I am facing difficulties in figuring out how to add arrow heads to the design. Below is the code snippet and screenshot for reference. Your assistance in this matter would be greatly appreciated!

https://i.sstatic.net/saaRc.png

    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
    
    <style>
    #temp_pue_wrapper {
        position: relative;
        height: 0;
        width: 100%;
        padding: 0;
        /* padding-bottom will be overwritten by JavaScript later */
        padding-bottom: 100%;
    }
    #temp_pue_wrapper > svg {
        position: absolute;
        height: 100%;
        width: 100%;
        left: 0;
        top: 0;
    }
    </style>
    <div id="temp_pue_wrapper"></div>
    
    <script>
    var width = 500,
        height = 30,
        tmp_wrapper = d3.select("#temp_pue_wrapper")
            .attr(
                "style",
                "padding-bottom: " + Math.ceil(height * 85 / width) + "%"
            )
            .append("svg")
            .attr("viewBox", "0 0 " + width + " " + height);
    
    var gradient = tmp_wrapper.append("defs")
      .append("linearGradient")
    .attr("id", "gradient")
    .attr("x1", "0%")
    .attr("y1", "0%")
    .attr("x2", "100%")
    .attr("y2", "0%")
    .attr("spreadMethod", "pad");
    
    gradient.append("stop")
        .attr("offset", "0%")
        .attr("stop-color", "#228582")
        .attr("stop-opacity", 1);
    
    gradient.append("stop")
        .attr("offset", "50%")
        .attr("stop-color", "#228582")
        .attr("stop-opacity", 1);
    
    gradient.append("stop")
        .attr("offset", "50%")
        .attr("stop-color", "#C23439")
        .attr("stop-opacity", 1);
    
    gradient.append("stop")
        .attr("offset", "100%")
        .attr("stop-color", "#C23439")
        .attr("stop-opacity", 1);
    
    tmp_wrapper.append('rect')
    .attr("width", "100%")
    .attr("height", "100%")
    .attr("fill", "url(#gradient)");
    
    </script>

Answer №1

Using a combination of triangle shapes and line graphs, I have successfully solved the problem.

 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.min.js"></script>
    
    <style>
    #temp_pue_wrapper {
        position: relative;
        height: 0;
        width: 100%;
        padding: 0;
        /* padding-bottom will be overwritten by JavaScript later */
        padding-bottom: 100%;

    }
    #temp_pue_wrapper > svg {
        position: absolute;
        height: 100%;
        width: 100%;
        left: 0;
        top: 0;
    }

  

path {
fill: none;

}
    </style>
    <div id="temp_pue_wrapper"></div>


    <script>
    var width = 500,
        height = 30,
        tmp_wrapper = d3.select("#temp_pue_wrapper")
            .attr(
                "style",
                "padding-bottom: " + Math.ceil(height * 80 / width) + "%"
            )
            .append("svg")
            .attr("viewBox", "0 0 " + width + " " + height);

    
    var gradient = tmp_wrapper.append("defs")
      .append("linearGradient")
    .attr("id", "gradient")
    .attr("x1", "0%")
    .attr("y1", "0%")
    .attr("x2", "100%")
    .attr("y2", "0%")
    .attr("spreadMethod", "pad");
    
    gradient.append("stop")
        .attr("offset", "0%")
        .attr("stop-color", "#228582")
        .attr("stop-opacity", 1);
    
    gradient.append("stop")
        .attr("offset", "50%")
        .attr("stop-color", "#228582")
        .attr("stop-opacity", 1);
    
    gradient.append("stop")
        .attr("offset", "50%")
        .attr("stop-color", "#C23439")
        .attr("stop-opacity", 1);
    
    gradient.append("stop")
        .attr("offset", "100%")
        .attr("stop-color", "#C23439")
        .attr("stop-opacity", 1);

tmp_wrapper.append('rect')
    .attr("width", "88.8%")
    .attr("height", "100%")
    .attr("x", "29px")
    .attr("y", "0px")
    .attr("fill", "url(#gradient)")
.attr("class","foo");

tmp_wrapper.append("svg:path")  
 .attr("d", d3.svg.symbol().type("triangle-up").size(400))
 .style("fill", "#228582")
 .attr ("transform", "translate(17,15) rotate (-90)");
 
tmp_wrapper.append("svg:path")  
 .attr("d", d3.svg.symbol().type("triangle-up").size(400))
 .style("fill", "#C23439")
 .attr ("transform", "translate(485,15) rotate (90)"); 



var lineFunction = d3.svg.line()
  .x(function(d) { return d.x; })
  .y(function(d) { return d.y; })
  .interpolate('linear');

var lineData = [ 
  { "x": -5,   "y": 0},  
  { "x": 20,  "y": 0},
  { "x": -5,  "y": 15}, 
  { "x": 20,  "y": 30},
  { "x": -5,  "y": 30},  
  { "x": -30, "y": 15},
  { "x": -5, "y": 0}

];
  

var lineGraph = tmp_wrapper.append("path")
  .attr("d", lineFunction(lineData))
  .style("fill", "#228582");

 var lineGraph1 = tmp_wrapper.append("path")
  .attr("d", lineFunction(lineData))
  .style("fill", "#C23439")
  .attr ("transform", "translate(502,30) rotate(180)");
   
    </script>

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

Using Three.JS to navigate a 3D cube by utilizing accelerometer data on both the x and y axes

After referencing my previous question I'm currently working on a 3D model that responds to input from accelerometer and gyroscope sensors. The 3D model is created using three.js, and the input data for rotation and translation is in JSON format. How ...

What is the best method for converting an Object with 4 properties to an Object with only 3 properties?

I have a pair of objects: The first one is a role object with the following properties: Role { roleId: string; name: string; description: string; isModerator: string; } role = { roleId:"8e8be141-130d-4e5c-82d2-0a642d4b73e1", ...

Error: VueQuill Vue3 encountered an issue while trying to read properties of undefined with the message "emit"

Incorporating VueQuill into my vue3 application is resulting in the following console error when attempting to display an HTML string - https://i.stack.imgur.com/KGQqD.png This is my code snippet: <template> <div class=""> & ...

Double the Power of jQuery Live Search with Two Implementations on a Single Website

I recently implemented a JQuery Live Search feature that is working perfectly. Here is the JQuery script: <script type="text/javascript"> $(document).ready(function(){ $('.search-box input[type="text"]').on("keyup input", function(){ ...

Turn off link preview feature on Android messages

As a developer, I am looking for a way to disable or hide link previews on Android devices when someone receives a text message with a link to our website. I still want the URL address to be visible, but I prefer to keep the link previews on IOS devices. I ...

Looking for assistance in retrieving a document by its reference id from Firestore using ReactJS?

As a newcomer to using firestore and reactjs, I am currently working on creating a basic react code that retrieves documents from 2 different collections. The two collections I am focusing on are: user-habits {email, habitid} habits {habitid, conte ...

Unable to cancel the RTK query request

It's quite a dilemma. I need to handle the request differently when there is no user present. I've attempted different approaches like this and that const { data: carts = [] as ICart[], isFetching } = api.useGetCartProductsQuery(user.id, { skip: ...

Error message: Unknown scope- unable to process 'files-path' Android File provider issue

My current project involves implementing file system access in react native Android. However, when attempting to add 'files-path' in XML, an error stating "Error: Unsupported type 'files-path'" is encountered. I am utilizing the react n ...

Encountering difficulties in compiling Dynamic HTML with the $compile function

I'm attempting to incorporate dynamic HTML into my code with the following lines: var el = $compile('<a ng-controller=\"tableController\" ng-click=\"open\">...ReadMore</a>')($scope); But I'm encounterin ...

Adding a marker to Google Maps in React that displays the user's current location

I successfully integrated Google Maps into my website and now I want to add a marker for the user's location. The first file is Map.js, and the second one is MapContainer.js. In MapContainer.js, I have all the necessary data for map rendering, includi ...

What is the correct way to update an array of objects using setState in React?

I am facing an issue where I have an array of objects that generates Close buttons based on the number of items in it. When I click a Close button, my expectation is that the array should be updated (removed) and the corresponding button element should dis ...

if the checkbox is selected, navigate to the displayed section

In my scenario, I have a total of 5 checkboxes and corresponding to each checkbox, there are 5 div elements. The functionality that I need is that when a checkbox is checked, the associated div should be displayed; otherwise, it should be hidden. The check ...

Having issues with the right margin in HTML5 canvas and struggling to remove the scroll bar

I am struggling with adjusting the margins of my canvas to ensure equal spacing on both sides without any horizontal scroll bars. Desired Outcome: Equal margin on both sides of canvas without any horizontal scroll bars. Issue: The margin-right property i ...

Unable to activate click function in Jquery

Here is a basic HTML page snippet: <html> <head> <script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"> </script> <script> $(document).ready(function () { $('#test').click(); }); < ...

The TypeScript fs/promises API is experiencing compilation issues when used in JavaScript

While working with TypeScript and the fs/promises API, I encountered an error when compiling and running the TypeScript code. The error message displayed: internal/modules/cjs/loader.js:968 throw err; ^ Error: Cannot find module 'fs/promises' ...

Superimpose a canvas onto a div element

I'm struggling to overlay a canvas on top of a div with the same dimensions, padding, and margins. Despite using position: absolute and z-index as suggested in similar questions, the canvas keeps appearing underneath the div. Here's my current co ...

Status and route redirection in Vue instance management

I am looking to establish a global status property for my application using vue.js and vue-router. This property should be shared between components and used to control access to certain routes based on its value. For instance, I want to redirect all rout ...

What are the steps to styling a component with CSS Emotion?

I am facing an issue with using a theme with TypeScript in this component const buttonDisabled = css` color: ${({ theme }) => theme.color}; `; Is there a way to correctly type this component? Error: No overload matches this call. Overload 1 of 2, & ...

My goal is to display the products on the dashboard that have a quantity lower than 10. This information is linked to Firestore. What steps can I take to enhance this functionality?

{details.map((val, colorMap, prodName) => { I find myself a bit perplexed by the conditional statement in this section if( colorMap < 10 ){ return ( <ul> <li key= ...

How can I pass an Objective-C object to JavaScript?

Currently, I am working on a UIWebView project that involves HTML and JavaScript. One of my friends is working on something similar but for Android. The challenge I'm facing is that in Android, there is a simple way to send an Android object to JavaS ...