How to use PieChartRenderer (ArcGIS) in javascript

In my user interface, I want to display data per neighborhood via a pie chart, whereby different age groups correspond to different pieces of the pie chart. Relevant code:

import { setDefaultOptions, loadModules } from "esri-loader";
import PieChartRenderer from "@arcgis/core/renderers/PieChartRenderer.js";


const buurten_2023_v1_age = new FeatureLayer({
  id: "buurten_2023_v1_age",
  url: "https://services.arcgis.com/zmBQLV64TsFvEpV0/arcgis/rest/services/buurten_2023_v1_age/FeatureServer",
  spatialReference: { wkid: 28992 },
  hasZ: false,
  outFields: ["BU_NAAM", "P_00_14_JR", "P_15_24_JR"],
  renderer: new PieChartRenderer({
    size: 10,
    attributes: [
      {
        color: [255, 69, 0, 0.4],
        label: "Perc 0-14",
        field: "P_00_14_JR",
      },
      {
        color: [255, 69, 255, 0.4],
        label: "Perc 15-24",
        field: "P_15_24_JR",
      },
     ],
     outline: {
      width: 1.5,
      color: "white",
     },
    }),
  });

I also have "@arcgis/core": "^4.30.8" in my package.json

Currently, the pie chart visualization does not work. In the console, I get:

4.18/:73  [esri.core.Accessor] Accessor#set Invalid property value, value needs to be one ,
of 'esri.renderers.HeatmapRenderer', 'esri.renderers.SimpleRenderer', 
'esri.renderers.UniqueValueRenderer', 'esri.renderers.ClassBreaksRenderer', 
'esri.renderers.DotDensityRenderer', 'esri.renderers.DictionaryRenderer', or a plain object
 that can autocast (having .type = 'heatmap', 'simple', 'unique-value', 'class-breaks', 
'dot-density', 'dictionary')

How can I fix this problem, so that the pie charts render correctly in the user interface.

How to extend nested zod schema keys, without modifying original schema?

I have the following Zod schema:

const schema = z.object({
    nested1: z.object({
        nested2: z.object({
            nested3: z.string(),
            dummy1: z.string(),
            dummy2: z.string(),
        }),
    }),
});

And I try to build a new schema which would look like the original but with some .catch() statements:

const secondSchema = z.object({
    nested1: z.object({
        nested2: z.object({
            nested3: z.string().catch(null),
            dummy1: z.string(),
            dummy2: z.string(),
        }),
    }),
});

I would like to extend the original schema with the least duplicate code.
Right now the fields dummy1 and dummy2 are duplicated.

I try to get something like:

const secondSchema = schema.extend({
    nested1: z.object({
        nested2: z.object({
            nested3: z.string().catch(null),
        }),
    }),
});

But this code would remove dummy1 and dummy2 off the schema because I overwrite nested2

How can I do it with least duplicate code?

How to detecting and measuring edges of real world objects in AR using WebXR?

I am trying to build an AR measure App. The user will be able to measure distances using AR ( WebXR ). I have figured out the distance measure part and it is working fine. Currently I am using hit test to mark points and using those points to measure distance.

function render(_: DOMHighResTimeStamp, frame?: XRFrame) {
  if (!frame)
    return;

  const referenceSpace = renderer.xr.getReferenceSpace();
  const session = renderer.xr.getSession();
  if (!hitTestSourceRequested) {
    session.requestReferenceSpace('viewer').then((referenceSpace) => {
      session.requestHitTestSource({space: referenceSpace}).then((source) => {
        hitTestSource = source;
      });
    });
    session.requestReferenceSpace('local').then(edgeDetection.setReferenceSpace.bind(edgeDetection));
    session.addEventListener('end', () => {
      hitTestSourceRequested = false;
      hitTestSource = null;
    });
    hitTestSourceRequested = true;
  }

  if (hitTestSource) {
    const hitTestResults = frame.getHitTestResults(hitTestSource);
    if (hitTestResults.length) {
      const hit = hitTestResults[0];
      reticle.visible = true;
      reticle.matrix.fromArray(hit.getPose(referenceSpace)!.transform.matrix);
    } else {
      reticle.visible = false;
    }

    activeShape?.updateShape(reticle.matrix);
  }

  labels.forEach((label) => {
    const pos = toScreenPosition(label.point, renderer.xr.getCamera());
    label.div.style.transform = `translate(-50%, -50%) translate(${pos.x}px, ${pos.y}px)`;
  });

  edgeDetection.setupGLBinding(session)
  edgeDetection.detectEdges(frame).then();

  renderer.render(scene, camera);

} 

Now I want to add a feature where the user will be a able to measure distance by detecting contours of real world objects. Like say if there is a rope the user would like to measure, they can just point to that and the contour of the rope will be detected and highlighted automatically.

I have figured out the contour detection part also, using raw camera access from WebXR I get the camera frame. Then I use OpenCV to get the edges.

private async processImage(imageData: ImageData) {
    await this.cvLoaded;

    const src = cv.matFromImageData(imageData);

    cv.cvtColor(src, this.gray, cv.COLOR_RGBA2GRAY);
    src.delete();

    cv.threshold(this.gray, this.edges, 100, 255, cv.THRESH_BINARY);
    cv.findContours(this.edges, this.contours, this.hierarchy, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE);

    const minPerimeter = 50; // Adjust this value as needed

    // Convert contours to 3D vectors
    const contours3D: Array<Array<THREE.Vector3>> = [];
    for (let i = 0; i < this.contours.size(); i++) {
      const contour = this.contours.get(i);
      const perimeter = cv.arcLength(contour, true);
      if (perimeter >= minPerimeter) {
        const pts = contour.data32S;
        const points3D: Array<THREE.Vector3> = [];
        for (let j = 0; j < pts.length; j += 2) {
          const x = pts[j];
          const y = pts[j + 1];
          const vector = this.convertTo3D(x, y);
          points3D.push(vector);
        }
        contours3D.push(points3D);
      }
    }
 }

All this is working fine and I am getting edges the problem is I don’t know how to convert from the coordinates of the contours ( x, y ) to AR space coordinates ( x, y, z ). This is what I have tried, but is not working ( the coronates is wrong )

private convertTo3D(x: number, y: number) {
    const vector = new THREE.Vector3(
      (x / window.innerWidth) * 2 - 1,
      -(y / window.innerHeight) * 2 + 1,
      0
    );
    vector.unproject(this.camera);
    return vector;
  }

What is the correct way to convert the coordinates here? Is there any better way to measure edges in AR other than what I am doing?

Angular 18 @for returning ERROR TypeError: newCollection[Symbol.iterator] is not a function

I decided to start working in the latest Angular version (Angular 18.1) so far I was working with versions 7 to 14…

I just tried making a lil dummy app to showcase a list of movies…

I made a really basic service that gets some data from an API and show this data in a list in html…

I have decided to use the new @for syntax from the latest angular version but now I am getting this error: ERROR TypeError: newCollection[Symbol.iterator] is not a function

Is this related to new version of nagular or am beeing blind and have overlooked an issue in my code?

EDIT: Console.log works.

Here is the component.ts code:

export class MovielistComponent implements OnInit{
  movies: movie[] = [];
  constructor(
    private movieService: GetMoviesService,
  ) { }
  ngOnInit() {
    this.getMoviesList();
  }

  getMoviesList() {
    this.movieService.getMovies().subscribe(
      data => {
        this.movies = data;
        console.log('Movies: ', this.movies);
      }
    )
  }

}

Here is the html file code:

<ul>
  @for (movie of movies; track movie.attributes) {
    <li>{{ movie.attributes.name }}</li>
  } @empty {
    <li>There are no items.</li>
  }
</ul>

And here is the model.ts code:

export interface movie {
  id: number,
  attributes: {
    name: string,
    imageUrl: string,
    synopsis: string,
    year: string,
    genre: string,
  }
}

As requested here is the API response:

{
    "data": [
        {
            "id": 1,
            "attributes": {
                "name": "The Shawshank Redemption",
                "imageUrl": "https://m.media-amazon.com/images/M/MV5BNDE3ODcxYzMtY2YzZC00NmNlLWJiNDMtZDViZWM2MzIxZDYwXkEyXkFqcGdeQXVyNjAwNDUxODI@._V1_FMjpg_UY1800_.jpg",
                "synopsis": "Over the course of several years, two convicts form a friendship, seeking consolation and, eventually, redemption through basic compassion.",
                "year": "1994",
                "genre": "drama",
                "createdAt": "2024-07-16T12:34:06.769Z",
                "updatedAt": "2024-07-16T12:36:29.952Z",
                "publishedAt": "2024-07-16T12:36:29.951Z"
            }
        },
        {
            "id": 2,
            "attributes": {
                "name": "The Godfather",
                "imageUrl": "https://m.media-amazon.com/images/M/MV5BM2MyNjYxNmUtYTAwNi00MTYxLWJmNWYtYzZlODY3ZTk3OTFlXkEyXkFqcGdeQXVyNzkwMjQ5NzM@._V1_FMjpg_UY1982_.jpg",
                "synopsis": "Don Vito Corleone, head of a mafia family, decides to hand over his empire to his youngest son, Michael. However, his decision unintentionally puts the lives of his loved ones in grave danger.",
                "year": "1972",
                "genre": "crime, drama",
                "createdAt": "2024-07-16T12:36:14.143Z",
                "updatedAt": "2024-07-16T12:36:15.723Z",
                "publishedAt": "2024-07-16T12:36:15.720Z"
            }
        },
        {
            "id": 3,
            "attributes": {
                "name": "The Dark Knight",
                "imageUrl": "https://m.media-amazon.com/images/M/MV5BMTMxNTMwODM0NF5BMl5BanBnXkFtZTcwODAyMTk2Mw@@._V1_FMjpg_UY2048_.jpg",
                "synopsis": "When the menace known as the Joker wreaks havoc and chaos on the people of Gotham, Batman must accept one of the greatest psychological and physical tests of his ability to fight injustice.",
                "year": "2008",
                "genre": "action, crime, drama, thriller",
                "createdAt": "2024-07-22T09:37:42.564Z",
                "updatedAt": "2024-07-22T09:38:19.346Z",
                "publishedAt": "2024-07-22T09:38:19.343Z"
            }
        }
    ],
    "meta": {
        "pagination": {
            "page": 1,
            "pageSize": 25,
            "pageCount": 1,
            "total": 3
        }
    }
}

electron communication between 2 renderers using messagePort and contextIsolation=true

I am new to electron and all the documentation on the electron docs use contextIsolation=false to enable port to be set globally on window object of the renderer.

I have 2 apps being served and loaded in electron using BrowserWindow with contextIsolation=true to limited access to app’s javascript.

Can MessageChannel be used to communicate between these 2 apps/BrowserWindows?

main.js

const { app, BrowserWindow, ipcMain } = require('electron');
const { MessageChannelMain } = require('electron/main');

let mainWindow;

app.on('ready', () => {
    mainWindow = new BrowserWindow({
        webPreferences: {
            contextIsolation: true,
            preload: path.join(__dirname, 'preload.js')
        }
    });

    mainWindow.loadURL('your-url');

    ipcMain.on('request-port', (event) => {
        const { port1, port2 } = new MessageChannelMain();
        event.sender.postMessage('port', null, [port2]);
        // You can now use port1 for communication in the main process
        port1.on('message', (event) => {
            console.log('Message from renderer:', event.data);
        });
    });
});

preload.js

const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('electronAPI', {
    requestPort: () => ipcRenderer.send('request-port')
});

window.addEventListener('message', (event) => {
    if (event.data === 'port') {
        const [port] = event.ports;
        window.messagePort = port;
        port.onmessage = (event) => {
            console.log('Message from main process:', event.data);
        };
    }
});

Here window.addEventListener(‘message’) is never executed. Also, the window object in the callback differs from the actual window object due to contextIsolation.

client.js

document.addEventListener('DOMContentLoaded', () => {
    window.electronAPI.requestPort();

    document.getElementById('sendMessage').addEventListener('click', () => {
        if (window.messagePort) {
            window.messagePort.postMessage('Hello from renderer!');
        }
    });
});

Mapbox-gl-draw setting the drawing color of different polygons

I want to be able to have my own custom buttons that call the «start draw polygon» function from mapbox-gl-draw. The idea is to pass what type of polygon it is (custom definition), so that I in the «create polygon» section can set the right color for the polygons.

Example: custom-button-1 lets you draw a red polygon of type «operation area» and custom-button-2 a blue one of type/name «lifecycle tree area». I have created the two buttons, and I do engage the «polygon draw mode» when clicking on my buttons, but they both end up being red which is the default/fallback color in the styles.

Here is a shortened version of mye Mapbox Draw initializer file:


import MapboxDraw from '@mapbox/mapbox-gl-draw';

export function initializeDrawTools(map) {
  const draw = new MapboxDraw({
    displayControlsDefault: false,
    userProperties: true,
    controls: {
      line_string: true,
      trash: true,
      polygon: true,
      point: true,
    },
    styles: [

// Set the fill and stroke style for the polygon
{
  id: 'gl-draw-polygon-fill',
  type: 'fill',
  filter: ['all', ['==', '$type', 'Polygon'], ['!=', 'mode', 'static']],
  paint: {
    'fill-color': [
      'case',
      ['==', ['get', 'user_draw_type'], 'operation-area'], '#00ff00', // Green
      ['==', ['get', 'user_draw_type'], 'lifecycle-tree-area'], '#0000ff', // Blue
      '#ff0000', // Red (default color)
    ],
    'fill-opacity': 0.3,
  },
},
]
});
}

Here is my function that the custom buttons calls:

export function activateDrawMode (map, draw, category, type) {
  if(category === 'polygon') {
    draw.changeMode('draw_polygon');
    map.on('draw.create', (e) => {
      console.log('e: ', e)
      feature = e.features[0];
      feature.properties.user_draw_type = type; // type === operation-area
      draw.add(feature);
    });
  }
}

In the console.log(‘e:’, e) I can see that the right property is being set, but the color of the polygon is still wrong… My only quess is that the property is being set after the style has already been decided so that it dosent know the features properties? If that makes sense.

Is there any other way of setting the drawing color of a polygon?

If I add it as hardcoded geojson like this, it works, but I want the user to be able to draw its own polygons:

  map.on('load', function () {
    map.addSource('polygon', {
      'type': 'geojson',
      'data': {
        'type': 'Feature',
        'properties': {
          'user_draw_type': 'operation-area' // Set the property here
        },
        'geometry': {
          'type': 'Polygon',
          'coordinates': [
            [
              [
                7.981685543413164,
                59.20133952768455
              ],
              [
                7.979057210222379,
                59.1885800447414
              ],
              [
                8.006263825512974,
                59.18468278810954
              ],
              [
                8.007310245455415,
                59.20867131238393
              ],
              [
                7.976252600208284,
                59.21691495637782
              ],
              [
                7.981685543413164,
                59.20133952768455
              ]
            ]
          ]
        }
      }
    });

    map.addLayer({
      'id': 'polygon',
      'type': 'fill',
      'source': 'polygon',
      'layout': {},
      'paint': {
        'fill-color': [
          'case',
          ['==', ['get', 'user_draw_type'], 'operation-area'], '#00ff00', // Green
          ['==', ['get', 'user_draw_type'], 'lifecycle-tree-area'], '#0000ff', // Blue
          '#ff0000', // Red (default color)
        ],
        'fill-opacity': 0.3,
      }
    });
  });

How Can I insert a div into svg? [closed]

I’m trying to put a react component into a svg and I did it but the items (elements) of the component are overflowing out of the svg path boundries.

I want the svg path boundaries to not overflow the react component out of its boundaries.
here is the code –

<svg className=" responsive-svg" viewBox="0 0 1410 867" fill="none" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMin slice">
                            <defs>
                                <clipPath id="clip-path">
                                    <path d="M1314.77 0.862305C1300.15 0.862305 1288.31 19.06545 1288.31 41.9884V79.2315C1288.31 101.1545 1276.46 118.92645 1261.84 118.92645H26.7689C12.1537 118.92645 0.305664 136.99845 0.305664 158.622V402.5625C0.305664 424.185 12.1537 442.257 26.769 442.257H52.2516C66.8668 442.257 78.7148 460.329 78.7148 481.9525V535.257V649.746V826.2435C78.7148 847.867 90.5628 865.939 105.178 865.939H1097.03C1111.65 865.939 1123.5 847.867 1123.5 826.2435V729.1365C1123.5 707.513 1135.35 689.441 1149.96 689.441H1381.84C1396.46 689.441 1408.31 671.369 1408.31 649.746V409.9515C1408.31 409.9395 1408.31 409.926 1408.31 409.914C1408.3 407.478 1408.3 405.036 1408.31 402.6C1408.31 402.588 1408.31 402.576 1408.31 402.5625V230.0625V158.622V41.9884C1408.31 19.06545 1396.46 0.862305 1381.84 0.862305H1314.77Z" fill="white" />

                                </clipPath>
                            </defs>
                            <path d="M1314.77 0.862305C1300.15 0.862305 1288.31 19.06545 1288.31 41.9884V79.2315C1288.31 101.1545 1276.46 118.92645 1261.84 118.92645H26.7689C12.1537 118.92645 0.305664 136.99845 0.305664 158.622V402.5625C0.305664 424.185 12.1537 442.257 26.769 442.257H52.2516C66.8668 442.257 78.7148 460.329 78.7148 481.9525V535.257V649.746V826.2435C78.7148 847.867 90.5628 865.939 105.178 865.939H1097.03C1111.65 865.939 1123.5 847.867 1123.5 826.2435V729.1365C1123.5 707.513 1135.35 689.441 1149.96 689.441H1381.84C1396.46 689.441 1408.31 671.369 1408.31 649.746V409.9515C1408.31 409.9395 1408.31 409.926 1408.31 409.914C1408.3 407.478 1408.3 405.036 1408.31 402.6C1408.31 402.588 1408.31 402.576 1408.31 402.5625V230.0625V158.622V41.9884C1408.31 19.06545 1396.46 0.862305 1381.84 0.862305H1314.77Z" fill="white" />
                            <foreignObject x="50" y="50" width="200" height="200">
                                <Games />
                            </foreignObject> 
                         
                        </svg>

Interactjs with Iframe becomes glitchy

I am using interactjs to create drag drop between iframe and parent.

The issue: When I start dragging and drops it anywhere outside dropzone , it still fire droped event.

HTML:

<div id="yes-drop" class="draggable"> Draggable Element </div>
<iframe></iframe>`


JS:
`
const position = { x: 0, y: 0 };
const iframe = document.querySelector("iframe");

const iframeDoc = iframe.contentDocument;
const html = `
<style>

.dropzone{
  height:100%;
  width:100%;
  border:solid red 1px;
}

.drop-activated{
  background:blue;
}

</style>
  <div id="drop-zone" class="dropzone"></div>
`;

iframeDoc.open();
// console.debug('Iframe writing html : ',html);
iframeDoc.write(html);

interact(".draggable").draggable({
  listeners: {
    start(event) {
      console.log(event.type, event.target);
    },
    move(event) {
      position.x += event.dx;
      position.y += event.dy;

      event.target.style.transform = `translate(${position.x}px, ${position.y}px)`;
    },
  },
});

interact(".dropzone", { context: iframeDoc })
  .dropzone({
    accept: "#yes-drop",
    ondrop: function (event) {
      alert(event.relatedTarget.id + " was dropped into " + event.target.id);
    },
    ondropdeactivate: function (event) {
      console.log("drop deactivate");
      event.target.classList.remove("drop-activated");
    },
  })
  .on("dropactivate", function (event) {
    event.target.classList.add("drop-activated");
  });

Here is the link to codepen for implementation – Interact JS Iframe

Download Trigger in JSX

I have this code which works just as I want it to work on desktop, but on a mobile device it asks me right after when I run this function to download the file, it asks if I want to download and then where to open it with. Example photos included.

Basically, I want to have a workaround for the pop-up download. Can I write something that will click that “download”? Or something else so it will maybe open the PDF file right after when it downloaded. I’m using react-device-detect for the isMobile.

     let od = orderData.BarcodeFile;
     if (!orderData.BarcodeFile.endsWith('.pdf')) {
      od = orderData.BarcodeFile;
      od += '.pdf';
     }  
    
      setFileNamer(od);

      const encodedFileName = encodeURIComponent(od);
      const response = await axios.get(`${process.env.REACT_APP_AAA}${encodedFileName}`, {
        responseType: 'blob'
      });

    
      const url = window.URL.createObjectURL(new Blob([response.data]));

      const link = document.createElement('a');
      link.href = url;
      link.setAttribute('download', od);
      document.body.appendChild(link);
      link.click();


      link.parentNode.removeChild(link);

      setDownloaded(true);

image 1

image 2

image 3

How make own d3.arc function?

I try make own d3.arc function but can’t count arc’s large-arc-flag and sweep-flag.

createArc (bands) {
    const innerRadius = this.maxRadius * 0.8
    const outerRadius = this.maxRadius * 0.95
    const startAngle = this.scaleLinear(bands[0])
    const endAngle = this.scaleLinear(bands[1])
    const MX = Math.cos(startAngle) * outerRadius
    const MY = -Math.sin(startAngle) * outerRadius
    const A1X = Math.cos(endAngle) * outerRadius
    const A1Y = -Math.sin(endAngle) * outerRadius
    const LX = Math.cos(endAngle) * innerRadius
    const LY = -Math.sin(endAngle) * innerRadius
    const A2X = Math.cos(startAngle) * innerRadius
    const A2Y = -Math.sin(startAngle) * innerRadius
    return `M${MX},${MY}A${outerRadius},${outerRadius},0,0,1,${A1X},${A1Y}L${LX},${LY}A${innerRadius},${innerRadius},0,0,0,${A2X},${A2Y}Z`
}

Example of bands parameter([100, 110])
I get coords and radiuses for arc but can’t understand how to count arc’s large-arc-flag and sweep-flag. (0,1 and 0,0 in example above)

How can to determine from js if the HTML attribute disabled was originally present?

Let’s say we have a non-disabled input element

<input id="empDate" name="empDate" type="date"/>

which is subsequently disabled via js

document.getElementById("empDate").disabled=true

the live status can be determined by

document.getElementById("empDate").getAttribute("disabled")

which returns an empty string indicated it is present

How to determine from js if the HTML attribute disabled was originally present?

Combine array of objects into one object [closed]

I would like to do something similar to this, but what I care is combining the object properties.
I have an array as below:

const arr = [
  { 
   a: [1,2,3],
   b: [...],
   c: [...],
   d: 'String A',
  },
  { 
   a: [1,2,4],
   b: [...],
   c: [...],
   d: 'String B',
  },
  { 
   a: [2,5,6],
   b: [...],
   c: [...],
   d: 'String C',
  },
]

Now I would like to combine those objects into one object but in the same time combine the properties from the arrays. The output would be:

[
 {
   a: [1,2,3,4,5,6],
   b: [...],
   c: [...],
   d: 'String A',
 }
]

Couple of notes:

  • arrays b and c are similar to the array a, so we should just combine them
  • I don’t care about the array order (example array a sorted) in the newly create array
  • any property that is a string (like d) simply the value from the first object should be taken

React conditional rendering and smooth animations/transitions

What is the proper/most efficient way to achieve smooth animation with conditional rendering a component in React? I read on other posts that one of the ways to achieve this is to have a state and set it to false on the end of animation/transition using onAnimationEnd and onTransitionEnd like in the following example:

const [isEnabled, setIsEnabled] = useState(true);
const divRef = useRef(null);

return(
   <>
      {isEnabled && <div onAnimationEnd={(e) => {if (e.animationName === 'closeDivAnim') setIsEnabled(false)}} isactive={isEnabled.toString()}></div>}
      <button onClick={() => divRef.current.setAttribute('isactive', 'false')}>Close div</button>
   </>
)

But to me, that seems like an unreliable approach (correct me if i’m wrong). Another approach which seemed more reliable to me was to follow the same concept but to set the state using a setTimeOut with the duration of the animation in a useEffect hook. All these approaches “get the job done” but what is the propper way to achieve a smooth mount/unmount of a component.

I am new to React so any intel would be highly appreciated!

How do i navigate from a reactnative application, which containe a login component. If login credential are correct navigae to homepage component

i have to implement react native application where a login component loads asks for userid and pass. if both are authenticated navigate to component name Homepage which stores homepage of application.

i require solution for app i am implementing it using react-native-cli.

unable to setup the project every time it raises error for navigation routes.