Plotting data with both line and nested plot in d3

My plot graph has the correct color scheme, but I need to connect each plot with lines. There are two groups of plots that need to be nested into separate line groups. I'm unsure how to proceed with this task.

<!DOCTYPE html>
<html>
 <head>
<meta charset="utf-8">
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3-legend/1.1.0/d3-legend.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3-tip/0.6.3/d3-tip.min.js"></script>
   <style>
    h1 { border-bottom: solid 3px #EBEBED; color: #545c61; font-size: 20px; padding-left: 35px; font-family: sans-serif; padding-bottom: 17px; font-weight: 500; margin-bottom: 37px; padding-top: 8px;}

    circle{ fill:white; stroke-width: 3px;}

    path { stroke: red; stroke-width: 2; fill: none; }

    .axis text {
    font-family: 'Open Sans', sans-serif;
    font-size: 14pt;
  }

  .axis path, .axis line {
    fill: none;
    stroke: none;
    shape-rendering: crispEdges;
  }
    .y.axis { stroke: #babfc5; }
    .y.axis text{ font-weight:100; transform: translate(-24px,0px); }
    .y.axis line { stroke: #EBEBED; stroke-width: 2; }
    .x.axis { stroke: #8e8e8e; }
    .x.axis text{ font-weight: 500; transform:translate(0px,14px)}


  </style>
 </head>
  <body>
  <h1>Example</h1>
<script>
    var outerWidth = 1080;
    var outerHeight = 330;
    var margin = { left: 190, top: 30, right: 30, bottom: 40 };
    var padding = 1.0;
    var circleRadius = 8;
    var xColumn = "month";
    var yColumn = "amount";
    var colorColumn = "monthv";
    var yAxisTitlesOffset = { top: 10 }


    var innerWidth = outerWidth - margin.left - margin.right;
    var innerHeight = outerHeight - margin.top - margin.bottom;



  var svg = d3.select("body").append("svg")
    .attr("width", outerWidth)
    .attr("height", outerHeight);
  var g = svg.append("g")
    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
  var xAxisG = g.append("g")
    .attr("class", "x axis")
    .attr("transform", "translate(0," + innerHeight + ")");
  var yAxisG = g.append("g")
    .attr("class", "y axis");




    var xScale = d3.scale.ordinal()
        .rangeBands([0, innerWidth],padding);
    var yScale = d3.scale.linear()
        .range([innerHeight,0]);
    var colorScale = d3.scale.ordinal()
        .domain(["top", "bot"])
        .range(["#43B365", "#DA5A60" ])




    var xAxis = d3.svg.axis().scale(xScale).orient("bottom")
    .outerTickSize(0);          // Turn off the marks at the end of the axis.
    var yAxis = d3.svg.axis().scale(yScale).orient("left")
    .ticks(4)            
    .tickSize(-innerWidth)
    .outerTickSize(0)
    .tickFormat( function(d) { return "$" + d} );

    var format = d3.format(",");
    var formattedX = format(yAxis);



    function render(data){

        xScale.domain(       data.map( function (d){ return d[xColumn]; }));
        yScale.domain([0, 2000]);
        //if this code is inserted in the max value instead of 2000 - it will show the max data value d3.max(data, function (d){ return d[yColumn]; })
        xAxisG.call(xAxis);
        yAxisG.call(yAxis);

        svg.append("path")
        .attr("class", "line")
        .attr("d", valueline(data));

        //bind data
        var circles = g.selectAll("circle").data(data);
        //Enter
        circles.enter().append("circle")
            .attr("r", circleRadius);
        //update
        circles
            .attr("cx", function (d){ return xScale(d[xColumn]); })
            .attr("cy", function (d){ return yScale(d[yColumn]); })
            .style("stroke", function (d){ return  colorScale(d[colorColumn]); })
        //exit 
        circles.exit().remove();
    }




  function type(d){
    d.amount = +d.amount;
    return d;
  }

  var data = [
    {
      "month": "Jan",
      "monthv": "top",
      "amount": 400
    },
    {
      "month": "Jan",
      "monthv": "bot",
      "amount": 100
    },
    {
      "month": "Feb",
      "monthv": "top",
      "amount": 800
    },
    {
      "month": "Feb",
      "monthv": "bot",
      "amount": 250
    },
    {
      "month": "Mar",
      "monthv": "top",
      "amount": 750
    },
    {
      "month": "Mar",
      "monthv": "bot",
      "amount": 200
    },
    {
      "month": "Apr",
      "monthv": "top",
      "amount": 850
    },
      {
      "month": "Apr",
      "monthv": "bot",
      "amount": 250
    },
    {
      "month": "May",
      "monthv": "top",
      "amount": 800
    },
      {
      "month": "May",
      "monthv": "bot",
      "amount": 250
    },
    {
      "month": "Jun",
      "monthv": "top",
      "amount": 850
    },
      {
      "month": "Jun",
      "monthv": "bot",
      "amount": 250
    },
    {
      "month": "Jul",
      "monthv": "top",
      "amount": 1000
    },
      {
      "month": "Jul",
      "monthv": "bot",
      "amount": 300
    },
    {
      "month": "Aug",
      "monthv": "top",
      "amount": 1050
    },
    {
      "month": "Aug",
      "monthv": "bot",
      "amount": 300
    },
    {
      "month": "Sep",
      "monthv": "top",
      "amount": 1000
    },
    {
      "month": "Sep",
      "monthv": "bot",
      "amount": 300
    },
    {
      "month": "Oct",
      "monthv": "top",
      "amount": 1200
    },
    {
      "month": "Oct",
      "monthv": "bot",
      "amount": 300
    },
    {
      "month": "Nov",
      "monthv": "top",
      "amount": 1100
    },
    {
      "month": "Nov",
      "monthv": "bot",
      "amount": 250
    },
    {
      "month": "Dec",
      "monthv": "top",
      "amount": 1250
    },
    {
      "month": "Dec",
      "monthv": "bot",
      "amount": 250
    }
  ];

  render(data);
</script>
</body>
</html>

I want my visualization to resemble this example. However, when I try to define the line in my code and add it to the path element, I encounter errors. Any guidance on how to tackle this issue would be greatly appreciated.

Answer №1

It seems like you overlooked defining valueline as the path generator using d3.svg.line:

var valueline = d3.svg.line()
    .x(function(d) { return xScale(d[xColumn]); })
    .y(function(d) { return yScale(d[yColumn]); });

Based on how your data is structured, you will need to utilize the path generator twice by filtering the data for both the top line and bottom line. Alternatively, you could structure the data so that each month has values for both lines:

g.append("path")
.attr("class", "line")
.attr("d", valueTopline(data.filter( e => e[colorColumn] === "top")))
.style("stroke", colorScale("top"));

g.append("path")
.attr("class", "line")
.attr("d", valueTopline(data.filter( e => e[colorColumn] === "bot")))
.style("stroke", colorScale("bot"));

Remember to append the paths to the group <g> instead of directly to the SVG in order for the scales to align correctly.

For reference, here is the updated jsbin code:

Answer №2

To begin, it is important to separate the data for the two distinct lines. There are various methods to accomplish this task. In this scenario, I am utilizing a filter:

var dataTop = data.filter(function(d){ return d.monthv == "top"});
var dataBot = data.filter(function(d){ return d.monthv == "bot"});

Subsequently, you will utilize this segregated data for each individual line:

g.append("path").attr("d", valueline(dataTop));
g.append("path").attr("d", valueline(dataBot));

I have opted for this approach considering the fact that there are only 2 lines involved. If there were multiple lines to consider, an alternative method might be more efficient (unless duplicating code is not a concern).

You can access the corresponding demonstration here: https://jsfiddle.net/jh3foyn6/

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 manipulate the camera's movement on the geometry generated in Autodesk Viewer from Point A to Point B

I am currently working on transitioning my camera view state from Point A to Point B within the Autodesk viewer. To achieve this, I am creating a path using LineDashedMaterial and have successfully displayed the line connecting Point A and B. Below is the ...

Develop a list of findings from the search

Is there a way to extract the name from the image shown below? return testData.then((data) => { console.log(data) var results = []; var toSearch = params.suggestTerm; data = data["data"]["0"]; console.log(" ...

What is the best way to change binary digits into a string of characters?

Could you take a moment to examine the following machine code? ‎0111001101110100011100100110010101110011011100110110010101100100 There is definitely a meaning behind this code that needs to be converted to a string. Despite attempting to use Integer.pa ...

Searching for a pattern and replacing it with a specific value using JavaScript

I need to find all occurrences of an unknown string within a larger string that is enclosed in brackets. For example, the string may look like: '[bla] asf bla qwr bla' where bla is the unknown string I need to locate. Is it possible to achieve th ...

Unable to submit form in Nextjs using react-bootstrap

Instructions To create a registration form, follow these steps: Fill out the form on the register page and then click submit. The react-bootstrap button will trigger the handleSubmit() function using onSubmit={}. Expected vs Actual Outcome I attempted va ...

Navigating with firebase authentication and angular routing

Currently, I am in the process of developing an ionic app using version 4. For this project, I have decided to utilize firestore as my database and implement firebase-authentication for user login and registration functionalities. However, I have encounter ...

Tips for generating an input element using JavaScript without the need for it to have the ":valid" attribute for styling with CSS

My simple input in HTML/CSS works perfectly, but when I tried to automate the process by writing a JavaScript function to create multiple inputs, I encountered an issue. The input created with JavaScript is already considered valid (from a CSS ":valid" sta ...

Exploring methods for testing an HTML page that utilizes jQuery for DOM manipulations

Recently, I was tasked with creating an HTML page that utilized jQuery DOM manipulations. For instance, upon clicking the submit button, a success or error message should be displayed. Testing these functionalities is something I'm familiar with in An ...

Generating 1,000 sets of 100,000 numerical sequences

I've been working on a project that has me scratching my head. The part I’m struggling with involves repeating a process 1,000 times and creating an array of 100,000 numbers. It's this specific aspect that’s got me stumped. Can someone take ...

Guide to setting the hiddenfield value within a listview using javascript or jquery

Here is the javascript code that I am using to retrieve the value from my textbox with autocompleteextender. <script type="text/javascript"> function txt_lect_in_AutoCompleteExtender_itemSelected(sender, e) { var hdEmpId = $get('& ...

What could be causing the audio file not to be received from the front end React to the Python server?

Here is the React code snippet: import React ,{ ChangeEvent, useState } from "react" const FileUpload: React.FC = () => { const [selectedFile, setFile] = useState<File| null>(null); const HandleAudioChange = (event:ChangeE ...

Starting Array index value at 1 in React js: A step-by-step guide

Is there a way to make the index value start from 1 instead of 0? {props.useraccountListData.useraccountTypeList.map((item, index) => ( {index} ))} The current output is starting from 0, 1, 2. However, I would like it to start from 1, 2, 3... ...

Tips for exchanging JSON data between HTML and PHP using jQuery Ajax?

Hello there! I am just starting to learn PHP and jQuery, and I have been experimenting with some code to understand how things work. However, I seem to be having issues with sending data back and forth between my webpage and the PHP file on the server. Her ...

Manipulating data in PHP with the help of JSON: Adding an array into a nested array

I am currently working on creating a JSON structure that needs to be sent back to Ajax. My goal is to include the key-value pair of 'para' => "Hello" inside the "content" section as shown below: { "sections": { "content": [{ ...

What could be causing the issue with res.clearCookie() not functioning properly post deployment on Vercel?

Initially, the application functions flawlessly on localhost. However, upon deployment to Vercel, an issue arises when users attempt to log out and the cookies are not clearing as intended with res.clearCookie(). Consequently, even after a page refresh, t ...

Executing JavaScript in Rails after dynamically adding content through AJAX

Looking for advice on integrating JavaScript functions into a Rails app that are triggered on elements added to the page post-load via AJAX. I've encountered issues where if I include the code in create.js.erb, the event fires twice. However, removing ...

Bug detected in the brfs plugin for browserify

I'm currently working on a project where I need to consolidate all the .html template files into a single bundle.js file by reading the content from each .html file. In my main.js, I have written the following code: var fs = require('fs'); ...

In Node.js, the module.exports function does not return anything

After creating a custom function called module.exports, const mongoose = require("mongoose"); const Loan = require("../models/loan_model"); function unpaidList() { Loan.aggregate([ { $group: { _id: "$ePaidunpaid", data: { $pus ...

Implementing Bootstrap attributes into a personalized Vue.js component

I have been tasked with incorporating a new html page into a vuejs project. The page is fully developed and utilizes jquery along with various elements from twitter-bootstrap. I have created a new component. NewPage.vue <template> <div id=" ...

The function get_the_category() is not compatible when used within the <figcaption> element

I'm encountering a strange issue. I'm attempting to incorporate a javascript gallery from this site into my WordPress theme. My goal is to show the post category as a figcaption, but when I insert my PHP code inside, it doesn't function prop ...