Try to run luckysheet using “npm install luckysheet” , getting errors like $ is not defined

i tried to install luckysheet using npm i luckysheet but,
it just called import luckysheet from “luckysheet”;

after getting the error message Uncaught ReferenceError: $ is not defined
at luckysheet.umd.js:9:1
at luckysheet.umd.js:1:1

do i have to add jquery? or is there another way?

but if I run using codesandbox there is no error

here is the codeandbox link: https://codesandbox.io/s/luckysheet-import-dan-export-6bpuf9?file=/src/App.js:157-193

Delete All Discord Messages I Sent

im using this persons sourse code I found on github. So I can delete the messages I sent to particular users on discord. But when i put my userId and discord authorization token in the code and pasted it into console.log on firefox i get this error

Source map error: Error: request failed with status 403
Resource URL: https://discord.com/assets/40532.476e4293de2fc7733cf0.css
Source Map URL: 40532.476e4293de2fc7733cf0.css.map

Uncaught (in promise) TypeError: messages.map is not a function
clearMessages debugger eval code:19
promise callbackclearMessages debugger eval code:18
clearMessages debugger eval code:23
promise callback
clearMessages debugger eval code:23
clearMessages debugger eval code:23
promise callbackclearMessages debugger eval code:23
clearMessages debugger eval code:23
promise callback
clearMessages debugger eval code:23
clearMessages debugger eval code:23

I tried looking this up and trying to understand this please note i know nothing about javascript i am barely of somewhat knowleage in HTML and CSS

so i realize at least that map im guessing like css is the actual command “fuction” but it needs to know what map = to im guessing?

any help would be a universe send!

I was expecting for all my messages on a certain discord dm to be deleted after i pasted this javascript code into the console.log of firefox inspect manager aka dev tools

Extract values from SQL Query String

Given a sql query string, I want to extract all the critical information from the string, for eg; table name, filters, limit, etc.

const sql = select * from products where id=1 and description like '%thick and crispy%';

const filters = [
"id=1",
"description like '%thick and crispy%'"
];

My first thought is to use Regex, and split the string at where,and clause.

const filters = sql.split(/ and /gi);

ps: Regex shown is only for understanding.

And, this would work fine for most the cases, until the values itself doesn’t contain these regex search terms.
In above example, if you see, description value itself contains and word. This would cause the string getting splitted at unexpected place.

Is there any better way to handle this problem with Regex or javascript?

ps: SQL queries are generally case insensitive, so we can’t split by minding the case sensitivity. The sql Query shown above is provided by users, for which, we can’t control the case sensitivity in a certain manner.

Note: I’ve kept the example easy to keep it understandable. But in live environment, we need to watch all possible clauses: LIKE, OR, AND, IN, etc., and there can be multiple AND, OR filters provided in the query string.

JavaScript recursive/circular regexps

I have an ANTLR4 grammar file and there is a pair of circularly-dependent rules, if you can call them that. Here are those rules:

`call
: ID LPAREN (expr (COMMA expr)*)? RPAREN ;

expr
: operand
| call
| NOT expr
| expr (AND|OR|ADD|SUB|MUL|DIV) expr
| expr LSQUARE expr RSQUARE
;`

call references expr, and expr references call. What I’m looking for is a way to implement such string checks using JavaScript RegExp. It would also help to have some sort of recursive RegExp for the expr rule, but something tells me that whatever could solve the circular dependency issue would solve the recursion issue as well. If it exists, that is 🙂

I tried:

  • Using (?R)? in the regexp, but JavaScript’s RegExps don’t seem to have this functionality
  • Using XRegExp.matchRecursive, but, judging by the API description and by what I got then playing around with it, it is not exactly what I’m looking for
  • Creating my own custom RecursiveRegExp class with an overridden constructor and exec() method, but it appears that I’m not skilled in JS enough to pull off something like this 🙂

Is there a way to, perhaps, insert a “link” to another RegExp into a RegExp literal, or something like that?

Loggingout shows Cannot read properties of undefined (reading ‘name’)

When I logout on the Profile Page, the website briefly shows this. But the website is working perfectly fine, this compiled with problems only shows When I logout on the Profile Page. When I logout anywhere else this doesn’t happen. I’ve been trying to find the error since last night, please help me find the error because I’m losing my mind.

pic1

code of ProfileScreen.js

import React, { useEffect } from 'react';
import Header from '../components/Header';
import ProfileTabs from '../components/profileComponents/ProfileTabs';
import Orders from './../components/profileComponents/Orders';
import moment from 'moment';
import { useDispatch, useSelector } from 'react-redux';
import { getUserDetails } from '../Redux/Actions/userActions';

const ProfileScreen = () => {
  window.scrollTo(0, 0);

  const dispatch = useDispatch();

  const userLogin = useSelector((state) => state.userLogin);
  const { userInfo } = userLogin;

  useEffect(() => {
    dispatch(getUserDetails('profile'));
  }, [dispatch]);

  return (
    <>
      <Header />
      <div className="container mt-lg-5 mt-3">
        <div className="row align-items-start">
          <div className="col-lg-4 p-0 shadow ">
            <div className="author-card pb-0 pb-md-3">
              <div className="author-card-cover"></div>
              <div className="author-card-profile row">
                <div className="author-card-avatar col-md-5">
                  <img src="./images/user.png" alt="userprofileimage" />
                </div>
                <div className="author-card-details col-md-7">
                  <h5 className="author-card-name mb-2">
                    <strong>{userInfo.name}</strong>
                  </h5>
                  <span className="author-card-position">
                    <>Joined {moment(userInfo.createdAt).format('LL')}</>
                  </span>
                </div>
              </div>
            </div>
            <div className="wizard pt-3 ">
              <div class="d-flex align-items-start">
                <div
                  class="nav align-items-start flex-column col-12 nav-pills me-3 "
                  id="v-pills-tab"
                  role="tablist"
                  aria-orientation="vertical"
                >
                  <button
                    class="nav-link active"
                    id="v-pills-home-tab"
                    data-bs-toggle="pill"
                    data-bs-target="#v-pills-home"
                    type="button"
                    role="tab"
                    aria-controls="v-pills-home"
                    aria-selected="true"
                  >
                    Profile Settings
                  </button>
                  <button
                    class="nav-link d-flex justify-content-between"
                    id="v-pills-profile-tab"
                    data-bs-toggle="pill"
                    data-bs-target="#v-pills-profile"
                    type="button"
                    role="tab"
                    aria-controls="v-pills-profile"
                    aria-selected="false"
                  >
                    Orders List
                    <span className="badge2">3</span>
                  </button>
                </div>
              </div>
            </div>
          </div>

          {/* panels */}
          <div
            class="tab-content col-lg-8 pb-5 pt-lg-0 pt-3"
            id="v-pills-tabContent"
          >
            <div
              class="tab-pane fade show active"
              id="v-pills-home"
              role="tabpanel"
              aria-labelledby="v-pills-home-tab"
            >
              <ProfileTabs />
            </div>
            <div
              class="tab-pane fade"
              id="v-pills-profile"
              role="tabpanel"
              aria-labelledby="v-pills-profile-tab"
            >
              <Orders />
            </div>
          </div>
        </div>
      </div>
    </>
  );
};

export default ProfileScreen;

code of ProfileTabs.js

import React, { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import Toast from './../LoadingError/Toast';
import Message from './../LoadingError/Error';
import Loading from './../LoadingError/Loading';
import { toast } from 'react-toastify';
import { updateUserProfile } from '../../Redux/Actions/userActions';

const ProfileTabs = () => {
  const [name, setName] = useState('');
  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');
  const [confirmPassword, setConfirmPassword] = useState('');
  const toastId = React.useRef(null);

  const Toastobjects = {
    pauseOnFocusLoss: false,
    draggable: false,
    pauseOnHover: false,
    autoClose: 2000,
  };

  const dispatch = useDispatch();

  const userDetails = useSelector((state) => state.userDetails);
  const { loading, error, user } = userDetails;

  const userUpdateProfile = useSelector((state) => state.userUpdateProfile);
  const { loading: updateLoading } = userUpdateProfile;

  useEffect(() => {
    if (user) {
      setName(user.name);
      setEmail(user.email);
    }
  }, [dispatch, user]);

  const submitHandler = (e) => {
    e.preventDefault();
    if (password !== confirmPassword) {
      if (!toast.isActive(toastId.current)) {
        toastId.current = toast.error('Passwords Do Not Match', Toastobjects);
      }
    } else {
      dispatch(updateUserProfile({ id: user._id, name, email, password }));
      if (!toast.isActive(toastId.current)) {
        toastId.current = toast.success('Profile Updated', Toastobjects);
      }
    }
  };

  return (
    <>
      <Toast />
      {error && <Message variant="alert-danger">{error}</Message>}
      {loading && <Loading />}
      {updateLoading && <Loading />}
      <form className="row  form-container" onSubmit={submitHandler}>
        <div className="col-md-6">
          <div className="form">
            <label for="account-fn">UserName</label>
            <input
              className="form-control"
              type="text"
              required
              value={name}
              onChange={(e) => setName(e.target.value)}
            />
          </div>
        </div>

        <div className="col-md-6">
          <div className="form">
            <label for="account-email">Email Address</label>
            <input
              className="form-control"
              type="email"
              required
              value={email}
              onChange={(e) => setEmail(e.target.value)}
            />
          </div>
        </div>
        <div className="col-md-6">
          <div className="form">
            <label for="account-pass">New Password</label>
            <input
              className="form-control"
              type="password"
              required
              value={password}
              onChange={(e) => setPassword(e.target.value)}
            />
          </div>
        </div>
        <div className="col-md-6">
          <div className="form">
            <label for="account-confirm-pass">Confirm Password</label>
            <input
              className="form-control"
              type="password"
              required
              value={confirmPassword}
              onChange={(e) => setConfirmPassword(e.target.value)}
            />
          </div>
        </div>
        <button type="submit">Update Profile</button>
      </form>
    </>
  );
};

export default ProfileTabs;

How do i invoke the signalr connection.on from the controllers

I am using the SQL service broker to send notifications from the ms SQL database to the controller when there is a change. It triggers fine. I set up a console.wrtieline to see if it triggers and it does get triggered when the database has a change. But What I’m trying to do is when there’s a database change I want this to get fired off await _hubContext.Clients.All.SendAsync("DatabaseChanged", "it changed"); However, when I do use that nothing happens. Then I tried to create an object from the DatabaseHub. Unfortunately, I can’t do that. It just gives me System null errors. I also tried to take out _hubContext out from the listener.TableChanged into the Account method and nothing gets called either. How do I call the javascript on function from the controller?

controller:


public class ProfileController : Controller
    {
        private readonly UserManager<ApplicationUser> _UM;
        private readonly FlubrContext _FC;
        private readonly IWebHostEnvironment _webHostEnvironment;
        private readonly IHubContext<DatabaseHub> _hubContext;

        public ProfileController(UserManager<ApplicationUser> UM, FlubrContext FC, IWebHostEnvironment webHostEnvironment, IHubContext<DatabaseHub> hubContext)
        {
            _UM = UM;
            _FC = FC;
            _webHostEnvironment = webHostEnvironment;
            _hubContext = hubContext;
        }
        public IActionResult Index()
        {
            return View();
        }

        public async Task<IActionResult> Account(string id)
        {
            await _hubContext.Clients.All.SendAsync("DatabaseChanged", "it changed");
            ViewBag.change = "hey";
            var connection = "Server=(local)\sqlexpress;Database=Flubr;Trusted_Connection=True;MultipleActiveResultSets=true";
            var listener = new SqlDependencyEx(connection, "Flubr", "UserMessage");
            listener.TableChanged += async (o, e) => {
                await _hubContext.Clients.All.SendAsync("DatabaseChanged", "it changed");
                Console.WriteLine("it changed");

            };
            listener.Start();
         }
      }


javascript:


@section Scripts {
    <script src="~/lib/signalr/dist/browser/signalr.js"></script>
    <script>
        const connection = new signalR.HubConnectionBuilder()
            .withUrl("/databaseHub")
            .build();

        connection.on("DatabaseChanged", (message) => {
            alert(message)
            console.log(message)
        });

        connection.start().catch((err) => console.error(err.toString()));
    </script>
}



hub:


namespace Flubr
{
    public class DatabaseHub: Hub
    {

      
    }
}


start up class


using Flubr.Areas.Identity.Data;
using Flubr.Repository;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Flubr
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews();
            services.AddDbContext<FlubrContext>(o => o.UseSqlServer(Configuration.GetConnectionString("FlubrContextConnection")));
            services.AddHttpContextAccessor();
            services.AddSignalR(o =>
            {

                o.EnableDetailedErrors = true;

            });
            services.AddControllers().AddJsonOptions(o =>
            {

                o.JsonSerializerOptions.PropertyNamingPolicy = null;

            });
            services.AddRazorPages();

            services.AddSingleton<SignalHub>();
            services.AddSingleton<DatabaseHub>();
            services.AddScoped<MessagesRepository>();


        }




            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                    app.UseBrowserLink();
                }
                else
                {
                    app.UseExceptionHandler("/Home/Error");
                    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                    app.UseHsts();
                }
                app.UseHttpsRedirection();
                app.UseStaticFiles();

                app.UseRouting();

                app.UseAuthentication();

                app.UseAuthorization();



                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllerRoute(
                        name: "default",
                        pattern: "{controller=Home}/{action=index}/{id?}");
                    endpoints.MapRazorPages();
                    endpoints.MapHub<SignalHub>("/SignalHub");
                    endpoints.MapHub<SignalHub>("/DatabaseHub");
                });

            }
        }
}


when typing on canvas-backspace key types the character backspace instead of deleting the characters

I have the following code on my razor page. When I click the backspace key then it starts typing backspace. below is the screen shot:
enter image description here

below is the JavaScript code:

<script>
        var tempContext = null;
        var x = 100
        window.onload = function () {
            var canvas = document.getElementById("canvas");
            console.log(canvas.parentNode.clientWidth);
            canvas.width = canvas.parentNode.clientWidth;
            canvas.height = canvas.parentNode.clientHeight;
            tempContext = canvas.getContext("2d");
            tempContext.fillStyle = "blue";
            tempContext.font = "20px Journal";

            canvas.focus();
            window.addEventListener('keydown', doKeyDown, true);

        }

        function doKeyDown(e) {

            tempContext.fillText(e.key, x, 60);
            x += 9
            e.preventDefault();

        }
</script>

below is the canvas:

   <div id="my_painter">
        <canvas id="canvas" tabindex="0"></canvas>
    </div>

any help will be greatly appreciated.

Check if mouse exists to hover

How can I check if the user has a cursor to hover on things, preferably using javacscript? (Using bootstrap too)

if (hasCursor()) {
  doCode();
}

I tried just checking if it is a touch device, but my laptop is a 2-in-1, so I cant test it.

IgApiClient – IgNotFoundError in DiscordJS

Well, when running the bot the console leaves an error that the user of the USERID variable was not found. The rest of the code is fine I guess. Here is the code

const {IgApiClient} = require('instagram-private-api');
const { Client, GatewayIntentBits } = require('discord.js');

const TOKEN = '';
const USERINSTAGRAM = '';
const PASSINSTAGRAM = '';
const CHANNEL = '';
const USERID = '';

async function main() {
    const ig = new IgApiClient();
    ig.state.generateDevice(USERINSTAGRAM);
    await ig.account.login(USERINSTAGRAM, PASSINSTAGRAM);
    const client = new Client({
        intents: [
            GatewayIntentBits.Guilds,
            GatewayIntentBits.GuildMessages,
            GatewayIntentBits.MessageContent,
            GatewayIntentBits.GuildMembers,
        ],
    });
    await client.login(TOKEN);
    const channel = await client.channels.fetch(CHANNEL);
    let lastPostID;
    const feed = ig.feed.user(USERID);
    const posts = await feed.items();
    if (posts.length > 0) {
        lastPostID = posts[0].id;
    }
    setInterval(async () => {
        const posts = await feed.items();
        if (posts.length > 0 && posts[0].id !== lastPostID) {
            lastPostID = posts[0].id;
            channel.send(`El usuario ha publicado un nuevo post en Instagram: ${posts[0].code}`);
            await sendPost(ig, channel, posts);
        }
    }, 60 * 1000); // 1 minuto 
    }

    main();

and here is the terminal error msg:

C:UsersadminDesktopBotnode_modulesinstagram-private-apidistcorerequest.js:103
return new errors_1.IgNotFoundError(response);
^

IgNotFoundError: GET /api/v1/feed/user/xxxxx/ – 404 Not Found;
at Request.handleResponseError (C:UsersadminDesktopBotnode_modulesinstagram-private-apidistcorerequest.js:103:20)
at Request.send (C:UsersadminDesktopBotnode_modulesinstagram-private-apidistcorerequest.js:54:28)
at async UserFeed.request (C:UsersadminDesktopBotnode_modulesinstagram-private-apidistfeedsuser.feed.js:21:26)
at async UserFeed.items (C:UsersadminDesktopBotnode_modulesinstagram-private-apidistfeedsuser.feed.js:31:22)
at async main (C:UsersadminDesktopBotpruebagit.js:26:19)
Node.js v18.15.0

The user is well written, is not a private account and has a post in their feed

What can I pass in the .then() method?

I’m trying to do the second point of Sequencing animation – Learn web development | MND (https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Sequencing_animations)

and i came out whit a solution that works, but i don’t understand why it works.



const aliceTumbling = [
    { transform: 'rotate(0) scale(1)' },
    { transform: 'rotate(360deg) scale(0)' }
  ];
  
const aliceTiming = {
    duration: 2000,
    iterations: 1,
    fill: 'forwards'
}

const alice1 = document.querySelector("#alice1");
const alice2 = document.querySelector("#alice2");
const alice3 = document.querySelector("#alice3");


function sinc_animation() {
  const one = alice1.animate(aliceTumbling, aliceTiming)
  one.finished.then(() => alice2.animate(aliceTumbling, aliceTiming).finished)
  .then(() => alice3.animate(aliceTumbling, aliceTiming))
};

sinc_animation();

here i wanted to animate the third alice when the second one was done, so at first i just put in the first .then((onFulfilled)):

alice2.animate(aliceTumbling, aliceTiming)

But the third one started right after the second one started because the .then((onFulfilled)) promise was considered fulfilled at the start of the animation.

So how come the code above is able to animate alice2 if I’m passing a promise returned by the .animate() object in the .then() method?

CheckboxTable from material UI is not updating on props change

I am building an admin system and I want to list the users in a table – and be able to perform bulk commands — like bulk delete, bulk update flags – pagination.

<CheckboxTable
  header={this.getUserTableData().header}
  rows={this.getUserTableData().rows}
  handleAction={this.handleAction}
  otherActions={this.getUserTableData().otherActions}
  rowsPerPage={7}
/>

enter image description here

I’ve placed the codebase into a sandbox but I can’t seem to fix the sandbox error – useLocation().

The issue I’m having is that the table doesn’t update when the commands are sent back to the parent and the parent component has made the changes and returns new table data back down. I am unsure how to fix the issue as I need to push the row information into a state on the child to handle pagination changes inside the child itself.

— current sandbox (broken in setup)
https://codesandbox.io/s/codepen-with-react-forked-uv5l0e?file=/src/components/CheckboxTable/CheckboxTable.js:3848-3888

I want to send to the component an object from the parent that gives the head,row and action details so various callbacks and selectedids can come back to the parent to perform those operations.

   getUserTableData() {

    console.log("this.state.users", this.state.users.people);

    let rows = [];

    for (let i=0; i < this.state.users.people.length; ++i) {
      console.log("this.state.users.people[i]", this.state.users.people[i]);
  
      let obj = {
        "id": this.state.users.people[i].id,
        "name": <NavLink to={"/users/"+this.state.users.people[i].id} activeClassName="selected">{this.state.users.people[i].name}</NavLink>,
        "isTrial": this.state.users.people[i].isTrial,
        "isVIP": this.state.users.people[i].isVIP,
        "createdAt": moment(this.state.users.people[i].createdAt).format('DD-MM-YYYY hh:mm:ss'),
      }

      rows.push(obj);
    }


    let table = {
      header: [
        "id",
        "name",
        "isTrial",
        "isVIP",
        "createdAt",
      ],
      rows: rows,
      otherActions: [
        //{
        //  "label" : "Filter",
        //  "action": "filter",
        //  "icon" : <FilterListIcon />
        //},
        {
          "label" : "Trial",
          "action": "trial",
          "icon" : <FreeBreakfastIcon />
        },
        {
          "label" : "VIP",
          "action": "vip",
          "icon" : <LabelImportantIcon />
        },
        {
          "label" : "Delete",
          "action": "delete",
          "icon" : <DeleteIcon />
        }      
      ]
    }

    return table
  }

source work – material ui sorting/selecting table

sandbox – https://codesandbox.io/s/vk7cqh?file=/demo.js

this is based on the material ui table – https://mui.com/material-ui/react-table/#sorting-amp-selecting – but my component takes a table object from the parent — I tried to recreate this https://codesandbox.io/s/vk7cqh?file=/demo.js without hardcoding the data inside the component and running createData procedurally.

this.state = {
  "users": {
    "people" : [
      {
        "id": "1234",
        "name": "Joel Kip",
        "isTrial": false,
        "isVIP" : true,
        "createdAt": "2023-03-25 16:00:00"
      },
      {
        "id": "1236",
        "name": "Billy Kip",
        "isTrial": false,
        "isVIP" : false,
        "createdAt": "2023-03-25 16:00:00"
      }
    ]
  }
}

It would be good to get the functionality working if you delete a user for example or set another action like isTrial to true — get the padding dense and re-instate sorting. Also I had to expose the ID to get the checkbox selection to work – I am unsure as to how to hide this visually from the current implementation

So when an admin clicks on a bulk icon – it triggers an action like this — in the parent.

  handleAction(action, selectedItems) {
    console.log("data",action,selectedItems)

    if(action === "delete"){
      this.deleteUsers(selectedItems[0]);
    }
  }

  deleteUsers(id){

    let that = this;
    this.props.deleteUsers(id, "getToken()", function(resp) {
      if(resp){
        that.fetchUsers(); // get new updated data -- but this is where the new data props are not affecting the table
      }
    });

  }

enter image description here

D3 v7 Force Graph: Images are not showing up

I successfully managed to build a force graph with my data. Now I wanted to display a separate image for each node, but the two approaches I find to accomplish this won’t work.

This is the first one:

var node = svg
.append("g")
.attr("class", "nodes")
.selectAll("circle")
.data(graph.nodes)
.enter()
.append("circle")
.attr("r", entityRadius)
.call(drag(simulation))
.attr("fill", "url(#bgPattern)");

defs
.append("svg:pattern")
.attr("width", 150)
.attr("height", 150)
.attr("id", "bgPattern")
.append("svg:image")
.data(graph.nodes)
.attr("xlink:href", function (d) {
  return "../assets/images/" + d.compressed;
})
.attr("width", 150)
.attr("height", 150)
.attr("x", 0)
.attr("y", -20);
node.attr("fill", "url(#bgPattern)");

Which works, but only shows one image for some reason. The function only runs once.

And the other one is this:

 node
.append("image")
.attr("xlink:href", function (d) {
  return "../assets/images/" + d.compressed;
})
.attr("width", 150)
.attr("height", 150)
.attr("x", -75)
.attr("y", -75);

Which successfully places an individual image element inside of each circle element, but never renders it.

Images in Circle Elements are not showing up

Does anyone have an idea what is wrong with this code?

Here is the full code with the two approaches:

function blogGraph(graph) {
  const width = window.innerWidth;
  const height = window.innerHeight;

  const sourceRadius = 45;
  const entityRadius = 35;

  var svg = d3
    .select("#networkGraph")
    .append("svg")
    .attr("width", width)
    .attr("height", height)
    .call(
      d3.zoom().on("zoom", function (event) {
        svg.attr("transform", event.transform);
      })
    )
    .append("g");

  var simulation = d3
    .forceSimulation()
    .force(
      "link",
      d3.forceLink().id(function (d) {
        return d.id;
      })
    )
    .force(
      "charge",
      d3.forceManyBody().strength(-2000).theta(0.5).distanceMax(500)
    )
    .force(
      "collision",
      d3.forceCollide().radius(function (d) {
        return d.radius;
      })
    )
    .force("center", d3.forceCenter(width / 2, height / 2));

  var defs = svg.append("defs");

  defs
    .append("radialGradient")
    .attr("id", "entity-gradient")
    .attr("cx", "50%")
    .attr("cy", "50%")
    .attr("r", "50%")
    .selectAll("stop")
    .data([
      { offset: "50%", color: "#ffffff" },
      { offset: "100%", color: "#CCCCCC" },
    ])
    .enter()
    .append("stop")
    .attr("offset", function (d) {
      return d.offset;
    })
    .attr("stop-color", function (d) {
      return d.color;
    });

  defs
    .append("svg:pattern")
    .attr("width", 150)
    .attr("height", 150)
    .attr("id", "bgPattern")
    .append("svg:image")
    .data(graph.nodes)
    .attr("xlink:href", function (d) {
      return "../assets/images/" + d.compressed;
    })
    .attr("width", 150)
    .attr("height", 150)
    .attr("x", 0)
    .attr("y", -20);

  var link = svg
    .append("g")
    .selectAll("line")
    .data(graph.links)
    .enter()
    .append("line");

  link.style("stroke", "#aaa");

  var node = svg
    .append("g")
    .attr("class", "nodes")
    // .selectAll("img")
    // .data(graph.nodes)
    // .enter()
    // .append("img")
    // .attr("xlink:href", function (d) {
    //   return "../assets/images/" + d.compressed;
    // })
    // .attr("width", 150)
    // .attr("height", 150)
    // .attr("x", -150)
    // .attr("y", -150);
    .selectAll("circle")
    .data(graph.nodes)
    .enter()
    .append("circle")
    .attr("r", entityRadius)
    .call(drag(simulation));
  // .attr("fill", "url(#bgPattern)");

  node
    .append("image")
    .attr("xlink:href", function (d) {
      return "../assets/images/" + d.compressed;
    })
    .attr("width", 150)
    .attr("height", 150)
    .attr("x", -75)
    .attr("y", -75);

  node
    .style("fill-opacity", "0.5")
    // .style("fill", "#cccccc")
    .style("stroke", "#424242")
    .style("stroke-width", "1px");

  var label = svg
    .append("g")
    .attr("class", "labels")
    .selectAll("text")
    .data(graph.nodes)
    .enter()
    .append("text")
    .text(function (d) {
      return d.title;
    })
    .attr("class", "label");

  label.style("text-anchor", "middle").style("font-size", function (d) {
    return d.title == "technology"
      ? Math.min(
          2 * entityRadius,
          ((2 * entityRadius - 8) / this.getComputedTextLength()) * 15
        ) + "px"
      : Math.min(
          2 * sourceRadius,
          ((2 * sourceRadius - 8) / this.getComputedTextLength()) * 15
        ) + "px";
  });

  label
    .on("mouseover", function (d) {
      tooltip.html(`${d.title}`);
      return tooltip.style("visibility", "visible");
    })
    .on("mousemove", function (event) {
      return tooltip
        .style("top", event.pageY - 10 + "px")
        .style("left", event.pageX + 10 + "px");
    });

  node
    .on("mouseover", function (d) {
      tooltip.html(`${d.title}`);
      return tooltip.style("visibility", "visible");
    })
    .on("mousemove", function (event) {
      return tooltip
        .style("top", event.pageY - 10 + "px")
        .style("left", event.pageX + 10 + "px");
    })
    .on("mouseout", function () {
      return tooltip.style("visibility", "hidden");
    });

  simulation.nodes(graph.nodes).on("tick", ticked);

  simulation.force("link").links(graph.links);

  function ticked() {
    link
      .attr("x1", function (d) {
        return d.source.x;
      })
      .attr("y1", function (d) {
        return d.source.y;
      })
      .attr("x2", function (d) {
        return d.target.x;
      })
      .attr("y2", function (d) {
        return d.target.y;
      });

    node
      .attr("cx", function (d) {
        return d.x + 5;
      })
      .attr("cy", function (d) {
        return d.y - 3;
      });

    label
      .attr("x", function (d) {
        return d.x;
      })
      .attr("y", function (d) {
        return d.y;
      });
  }

  function drag(simulation) {
    function dragstarted(event) {
      if (!event.active) simulation.alphaTarget(0.3).restart();
      event.subject.fx = event.subject.x;
      event.subject.fy = event.subject.y;
    }

    function dragged(event) {
      event.subject.fx = event.x;
      event.subject.fy = event.y;
    }

    function dragended(event) {
      if (!event.active) simulation.alphaTarget(0);
      event.subject.fx = null;
      event.subject.fy = null;
    }

    return d3
      .drag()
      .on("start", dragstarted)
      .on("drag", dragged)
      .on("end", dragended);
  }

  var tooltip = d3
    .select("body")
    .append("div")
    .style("position", "absolute")
    .style("visibility", "hidden")
    .style("color", "white")
    .style("padding", "8px")
    .style("background-color", "#626D71")
    .style("border-radius", "6px")
    .style("text-align", "center")
    .style("width", "auto")
    .text("");
}

var nodesUrl = "https://www.fabianschober.com/json/nodes.json"; 
var linksUrl = "https://www.fabianschober.com/json/links.json";

Promise.all([d3.json(nodesUrl), d3.json(linksUrl)]).then((res) => {
  // console.log(res);
  blogGraph({ nodes: res[0], links: res[1] });
});
<html>
  <head>
    <link rel="stylesheet" href="./styles.css" />
    <script src="https://d3js.org/d3.v7.min.js"></script>
    <script src="./ForceGraph.js"></script>
  </head>

  <body>
    <div id="networkGraph"></div>
  </body>
</html>

PS: The Json Files are getting blocked by CORS, but you may get the idea…

Putting the name on Canvas

I want to create a canvas on my web page that will let the users type their name in “Journal” font. I have the following code, but, as you can see in dokeyDown, I can only type “Z”. How can I make it for all the alphabets so that users can type their full name. Do I need to specify keyId for each alphabet or is their any easier way? Below is what I have

<div id="my_painter">
    <canvas id="canvas" tabindex="0"></canvas>
</div>
<script>
    var tempContext = null;
    window.onload = function () {
        var canvas = document.getElementById("canvas");
        console.log(canvas.parentNode.clientWidth);
        canvas.width = canvas.parentNode.clientWidth;
        canvas.height = canvas.parentNode.clientHeight;        
        tempContext = canvas.getContext("2d");
        tempContext.fillStyle = "blue";
        tempContext.font = "20px Journal";
        canvas.addEventListener('keydown', doKeyDown, true);
        canvas.focus();        
        window.addEventListener('keydown', doKeyDown, true);
       
    }

function doKeyDown(e) {
        var keyID = e.keyCode ? e.keyCode : e.which;
        if (keyID === 90) {
            tempContext.fillText("A", 100, 60);
            e.preventDefault();
        }
    }

Any help will be greatly appreciated

Add Key/Pair value to an object dynamically

This is how my data looks:

[
 {
    "key": 111,
    "Students_Info": [
      {
        "recordId": 111,
        "position": 1 ------>How do I insert this ?
      }
     ],
     "Adress_Info":{
        "city" : Delhi
     }
   },
   {
    "key": 222,
    "Students_Info": [
      {
        "recordId": 222,
        "position": 2 ------>How do I insert this ?
      }
     ],
     "Adress_Info":{
        "city" : Delhi
     }
   }
]

Suppose if the total array count is 2 I need to insert their positions in the mentioned place above.

This is what I tried

data.forEach((element, value) => {
    data.push("position:"+ value)
});

But this has syntax errors and I’m not sure how to insert them.