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!

    <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

Updating a table dynamically after a form submission using jQuery, Ajax, and PHP without needing to refresh the page

My current setup involves an ajax form along with a table. Here is the ajax code I am using: $(function () { $(".submitann").click(function () { var title = $("#title").val(); var announcement = $("#announcement").val(); var d ...

Google Maps API is successfully loading from an HTML file, however, it is not functioning properly when accessed

I am facing an issue while trying to connect to the Google Maps API through an AngularJS application on my localhost. Despite finding the javascript file in the HTML and displaying 'test1' in the console, the `initMap` function is not being calle ...

What is causing the consistent occurrences of receiving false in Angular?

findUser(id:number):boolean{ var bool :boolean =false this.companyService.query().subscribe((result)=>{ for (let i = 0; i < result.json.length; i++) { try { if( id == result.json[i].user.id) ...

problems encountered when trying to deploy a backend api on the Render platform

Encountered this error: May 14, 04:27:30 PM - Error [email protected]: The "node" engine is not compatible with this module. Expected version ">=14.20.1". Received version "14.17.0". May 14, 04:27:30 PM - Incompatible module detected. Verified my nod ...

Trigger the click event on a specific class selector to extract the corresponding ID

I have an HTML Table with each row: <table> <tr><td><a href='#' id='1' class='delete'>delete</a></td></tr> <tr><td><a href='#' id='2' class='de ...

Show the contents of a JSON file using Vue

I have a JSON file containing some data that needs to be fetched and displayed in a component. In the actions of my Vuex store, I've implemented: async getTodos (context) { const todos = [] const response = await fetch('../../data/todos.jso ...

Revamp MUI class names with React Material UI's innovative randomization and elimination

Can names be randomized or Mui-classNames removed? https://i.stack.imgur.com/J6A9V.png Similar to the image displayed? (All CSS class names would be jssXXX) Appreciate your assistance. ...

Formatting dates for the bootstrap datepicker

Hi there! I am currently using a bootstrap datepicker and I am attempting to retrieve the value from the datepicker text box in the format of date-month-year for my controller. However, at the moment, I am only able to obtain values in the format Tue Oct 0 ...

Issue encountered while configuring server using express.js

Here is the server.js file I am working on, but I encounter a specific error when trying to set up the server with Express.js var express = require('express'); var app = express(); var PORT = process.env.PORT || 3000; app.all('/*', ...

Angular2: the setTimeout function is executed just a single time

Currently, I am working on implementing a feature in Angular2 that relies on the use of setTimeout. This is a snippet of my code: public ngAfterViewInit(): void { this.authenticate_loop(); } private authenticate_loop() { setTimeout (() =& ...

The Quirks of jQuery's .load() Method

On my website, I am incorporating a basic jQuery script to load content from one part of a webpage into the 'display container' on the same page. The content being loaded consists of multiple divs enclosed within an outer <div> that is hid ...

Maximizing the power of Webpack alongside Google Maps API

I have been using Webpack along with the html-webpack-plugin to compile all my static files. However, I am facing an issue when integrating it with the Google Maps API. Here is the code snippet: var map; function initMap() { map = new google.maps.Map(d ...

Converting Vue HTML to PDF without relying on html2canvas functionality

My current challenge involves creating a PDF file from either HTML or Vue component. I have experimented with various libraries such as jsPDF, html2pdf, and vue-html2pdf, but it seems like they all rely on html2canvas, causing the UI to freeze for a few ...

How to Disable a Button with JavaScript in a Vue.js Application Without Using jQuery

I'm currently in the process of transitioning old jQuery code to JavaScript for a Vue.js application. function DisableSubmit() { submitButton.prop('disabled', true); submitButton.attr('data-enabled-value', submitButton.val ...

Not triggering onDragStart in Material UI Autocomplete component in React

I'm facing an issue with an onDragStart handler in a React Autocomplete component. Despite adding the handler, it fails to trigger when dragging using the mouse. You can explore a live demo of this problem here: https://codesandbox.io/s/material-demo- ...

Injecting script into a webpage and initiating an ajax request prior to receiving a response

Trying to accomplish something a bit complex that I believe is feasible, or perhaps someone could offer a suggestion on how to achieve it. At website A, there is a database containing booking data. At website B, the goal is to display information about w ...

What is the proper method for utilizing the .done or .complete functions in conjunction with .toggle in jQuery?

I am struggling to understand the proper usage of .complete or .done after .toggle in jQuery. My goal is to have the button's text change after the toggle animation finishes, but I'm not sure if I'm chaining them correctly. The jQuery docume ...

The callback in Jquery getJSON does not execute even when a valid JSON response is received

My server is sending valid JSON objects (as verified by jsonlint.com) that have this structure: "{\"encryption\": {\"key\": \"gKV0oPJwC5CBQxmn\"}}" This is how my HTML file looks: <html> <head> <title&g ...

SystemJS could not locate the root directory for RxJS

There seems to be an issue with SystemJS loading rxjs modules on Windows, as it throws a 404 Not Found error on the rxjs directory. This problem does not occur on OSX, and all modules are up to date. GET http://localhost:8080/node_modules/rxjs/ 404 (Not F ...

Should I include one of the dependencies' dependencies in my project, or should I directly install it into the root level of the project?

TL;DR Summary (Using Lodash as an example, my application needs to import JavaScript from an NPM package that relies on Lodash. To prevent bundling duplicate versions of the same function, I'm considering not installing Lodash in my application' ...