In the realm of HTML Canvas, polygons intricately intertwine with one another

Currently, I am attempting to create multiple polygons from a large JSON file. Instead of being separate, the polygons seem to be connected in some way.

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

The project is being developed in next.js.

Below are the relevant code snippets:

Canvas.tsx

// ../components/Canvas.tsx

import React, { useRef, useEffect } from 'react'

const Canvas = props => {
  
  const canvasRef = useRef(null)
  
  useEffect(() => {
    const canvas: any = canvasRef.current
    const context = canvas.getContext('2d')

    context.fillStyle = '#FF0000'
    context.beginPath()
    { props.x.map((pointx, i) => context.lineTo(0.25 * pointx, 0.25 * props.y[i])) } // Scaled down to 25% of original size
    context.closePath()
    context.fill()
  }, [])
  
  return <canvas ref={canvasRef} {...props} width={props.width} height={props.height} style={{ zIndex: 20, position: 'absolute', objectFit: 'contain' }}/>
}

export default Canvas

index.tsx

import React, { ReactElement, useEffect, useRef, useState } from 'react'
import Image from 'next/image'
import dynamic from "next/dynamic";
import data from '../public/11_regions-copy.json'
import Canvas from '../components/Canvas';


export const getServerSideProps = async () => {

  let xTemp: any[] = []
  let yTemp: any[] = []

  for (var i = 0; i < Object.keys(data).length; i++) {
    xTemp.push(data[i].all_points_x)
    yTemp.push(data[i].all_points_y)
  }
  for (var j = 0; j < Object.keys(data).length; j++) {
    let xArray = xTemp[j]
    xArray.push(xArray[0])

    let yArray = yTemp[j]
    yArray.push(yArray[0])
  }
  
  let x = [].concat.apply([], xTemp);
  let y = [].concat.apply([], yTemp);


  return {
    props: {
      x,
      y
    },
  }
}

function Home({ x, y }: any): ReactElement {

  return (
    <div>
      <Canvas width={1680} height={756} x={x} y={y} />
    </div>
  )
}

export default Home

JSON file used: json

If you have any insights or suggestions, please feel free to share them!

Answer №1

The issue arises when you merge all regions from your data source into a single extended path. This occurs within the getServerSideProps function (which can be a bit clumsy by the way).

Therefore, your data structure appears as follows:

{
    "0": {

        "all_points_x": [ ... ],
        "all_points_y": [ ... ]
    },
    "1": {
        "all_points_x": [ ... ],
        "all_points_y": [ ... ]
    },
    // ...
}

Your getServerSideProps transforms it into this format:

{
    props: {
        x: [ ... ],
        y: [ ... ],
    }
}

This results in drawing a single long path as shown here:

context.beginPath()
{ props.x.map((pointx, i) => context.lineTo(0.25 * pointx, 0.25 * props.y[i])) }
context.closePath()
context.fill()

To achieve the desired outcome, instead of merging all regions into one path, draw each region as a separate path using the following approach:

// For instance, `data` could be fetched like:
// const data = await (await fetch('11_regions-copy.json')).json();

Object.values(data).forEach(({all_points_x: x, all_points_y: y}) => {
  ctx.beginPath();

  x.forEach((x, i) => {
    ctx.lineTo(0.25 * x, 0.25 * y[i]);
  });

  ctx.closePath();
  ctx.fill();
});

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


In response to Kaiido's suggestion, you could consider drawing a single path by utilizing the moveTo method.

ctx.beginPath();

Object.values(data).forEach(({all_points_x: x, all_points_y: y}) => {
  ctx.moveTo(0.25 * x[0], 0.25 * y[0]);

  x.forEach((x, i) => {
    ctx.lineTo(0.25 * x, 0.25 * y[i]);
  });
});

ctx.closePath();
ctx.fill();

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

How can a div tag and its class be nested using CSS in Angular?

Can someone help me with nesting a div tag with the "error" class in CSS? <div [class]="{error: condition}">{{ message }}</div> I want to know how to have the .error selector inside the div selector in the CSS file. Note: The error ...

Steps for creating an npm package from the /build folder of Create React App

Hello! I am currently working on an app developed using the create-react-app boilerplate. After compiling and building it with npm run build, I now want to transform the /build folder into an npm package for easy use in other projects as a micro app. Can ...

Creating responsive divs on my webpage

Although I have browsed through various posts with similar questions, none of the solutions seem to work for me. I will make sure to include all relevant information related to my issue and explain why I am unable to resolve it on my own. Currently, I am ...

Deactivating button depending on the state of a child component in React

I am facing an issue with integrating a countdown component as a child component. I am trying to enable/disable a button based on the counter state, but I can't seem to access the value correctly. Here is what I have attempted so far: import React fr ...

Developing with Next.js Multi Zone has never been easier with the introduction of Fast Refresh

I am currently facing a challenge while using Next.js and multi zones for our web applications. The issue I'm encountering is that webpackDevMiddleware only detects changes in the current app I am working on. My network setup involves Docker, and I wo ...

JQuery hover effect for dynamically added elements

Currently, I am working on a webpage that will trigger an ajax call upon loading. The response data in JSON format will be processed and the elements will then be added to the DOM as shown below: $.ajax({ type: 'POST', url: "http://mysite.de ...

"Creating varying lengths of time with useSpring: A Step-by-Step Guide

Is there a way for my component to have an animation that fully displays in 0.3s when my mouse enters, but disappears in 0.1s when my mouse leaves? Currently, with useSpring, I can only define one duration for both scenarios. How can I set different dura ...

The event listener function is not functioning properly on images generated by JavaScript

I'm currently working on placing multiple images on a grid in the center of the page and would like to include a function that triggers when each individual image is clicked. The images are dynamically created using JavaScript and inserted into the do ...

What are the steps for generating website endpoints using search query outcomes?

I am currently working on a ReactJS website as a part of my web development bootcamp project. One interesting feature I have incorporated is a search functionality that uses Flask routes to connect ReactJS endpoints (../Language.js) with my Sqlite3 databa ...

Reducing the Distance Between Columns in Bootstrap 4

I am currently working on embedding two websites onto my own website. The idea is to showcase these websites side by side within a custom-sized iframe that adjusts responsively based on the viewport size. To achieve this, I am utilizing Bootstrap 4's ...

The property 'tz' of ABP Property does not exist within the type 'moment'

I acquired the .NET Core & ReactJS template from aspnetboilerplate.com. I successfully initialized the database. After navigating to the reactjs folder, I executed the npm install and npm start commands. An error message stating: Property 'tz&apo ...

Arrange the icons in multiple rows to ensure an equal distribution of icons on each row

There are 12 image icons displayed in a row within div elements using display: inline-block. However, when the browser window is resized, I would like the icons to be arranged on two or more rows so that each row contains an equal number of icons. ...

What are the steps to update your profile picture using Angular?

In my Angular 6 application, I am implementing an image upload feature with the following code: Html: <img [src]="url ? url : 'https://www.w3schools.com/howto/img_avatar.png'"> <br/> <input type='file' (change)="onSelec ...

External CSS file for Demandware platform

My boss was supposed to train me this year on demandaware knowledge, but ended up quitting, leaving me in the dark. I am scheduled to attend workshops later this year, but for now I am relying on Google and stackoverflow for guidance. Currently, I am wor ...

reactjs search bar with filtered results

Having an issue creating a search bar in reactjs. // Here is the endpoint structure export const getCountPoiCategoryProvinsi = (provinsi) => { return new Promise((resolve, reject) => { axios .get( `${baseUrl}/api/dashboard/v1/get ...

What is the process for deleting certain code from a main component within a React webpage without altering the main component itself?

I have a main component named Layout.jsx that includes the essential elements for the website such as the navigation bar and meta tags. It also contains a Google tag to track analytics across the entire site. Now, I have a specific webpage for Google Ads w ...

Sentry is causing issues with the build of my Next.js application

After integrating Sentry into my Next.js project, I have encountered an error that is preventing the application from building. The same error also occurs at runtime, but what confuses me is why it's affecting the build process. Is there a way to conf ...

CSS - Apply a captivating background to specific columns within a grid layout

Wow, I'm really struggling with CSS and this particular issue has me perplexed. I need to add background colors to specific columns but not all of them. The problem is that the padding gets messed up when I do this. Imagine having a headache while try ...

Aligning text vertically in the center using Bootstrap

How can I center text vertically within a division with a height of 100vh? Here's what I've tried: .about-header { height: 100vh; background: #000; } .about-header p { font-size: 5em; } <link rel="stylesheet" href="https://maxcdn.boot ...

Unknown individual, yet revealed by the investigator

I'm attempting to develop a dynamic list in react.js generateList = () =>{ return this.state.user.map((u)=>{ console.log(u); return <li onClick={this.handleClick} id={u} name={u}>{u}</li>; }); } The hand ...