Use package react-svg-radar-chart to create Radar chart ReactJS

Create a basic ReactJS App using the create-react-app Post here.

Our final aim is to generate a Radar Chart using the npmjs package react-svg-radar-chart. Also, the dot markings on the chart should be able to show the current index and key, values on the chart on Hover as shown below.

Install the Package in your Project by running the following command in the Terminal:

npm install react-svg-radar-chart

Replace the code for the index.js file as shown below:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));

Create the App.js file for the App component and add the below code:

import React, { Component } from "react";
import MyComp from "./MyComp";
import MyRadarComp from "./MyRadarComp";

export default class App extends Component {
    render() {
        return (
          <div className="App">
            <MyRadarComp />
          </div>
        );
      }
}

Create MyRadarComp.js file and add the below code:

import React from 'react';
 
import RadarChart from 'react-svg-radar-chart';
import 'react-svg-radar-chart/build/css/index.css'
 
export default class MyRadarComp extends React.Component {
  render() {
    const tooltipstyle = {
        position: 'relative',
        display: 'inline-block',
        borderBottom: '1px dotted black'
    }

    const tooltiptextstyle = {
        visibility: 'hidden',
        width: '220px',
        backgroundColor: 'black',
        color: '#fff',
        textAlign: 'center',
        borderRadius: '6px',
        padding: '5px 0',
    
        /* Position the tooltip */
        position: 'absolute',
        zIndex: '1',
    }

 	 const data = [
      {
        data: {
          battery: 0.5,
          design: .7,
          useful: 0.985,
          speed: 0.57,
          weight: 0.7
        },
        meta: { color: 'blue' }
      },
      {
        data: {
          battery: 0.6,
          design: .85,
          useful: 0.5,
          speed: 0.6,
          weight: 0.7
        },
        meta: { color: 'red' }
      },
      {
            data: {
              battery: 0.7,
              design: .8,
              useful: 0.9,
              speed: 0.67,
              weight: 0.8
            },
            meta: { color: '#58FCEC' }
        }
    ];
 
    const captions = {
      // columns
      battery: 'Battery Capacity',
      design: 'Design',
      useful: 'Usefulness',
      speed: 'Speed',
      weight: 'Weight'
    };

    const noSmoothing = points => {
        let d = 'M' + points[0][0].toFixed(4) + ',' + points[0][1].toFixed(4);
        for (let i = 1; i < points.length; i++) {
          d += 'L' + points[i][0].toFixed(4) + ',' + points[i][1].toFixed(4);
        }
        return d + 'z';
      };
       
      const defaultOptions = {
        size: 200,
        axes: true, // show axes?
        scales: 3, // show scale circles?
        captions: true, // show captions?
        captionMargin: 10,
        dots: true, // show dots?
        zoomDistance: 1.2, // where on the axes are the captions?
        setViewBox: (options) => `-${options.captionMargin} 0 ${options.size + options.captionMargin * 2} ${options.size}`, // custom viewBox ?
        smoothing: noSmoothing, // shape smoothing function
        axisProps: () => ({ className: 'axis' }),
        scaleProps: () => ({ className: 'scale', fill: 'none' }),
        shapeProps: () => ({ className: 'shape' }),
        captionProps: () => ({
          className: 'caption',
          textAnchor: 'middle',
          fontSize: 10,
          fontFamily: 'sans-serif'
        }),
        dotProps: () => ({
          className: 'dot',
          mouseEnter: (dot) => { 
              document.getElementById("tooltip").innerText = "index: " + dot.idx + ", key: " + dot.key + ", value: " + dot.value;
              document.getElementById("tooltip").style.visibility = "visible";
            },
          mouseLeave: (dot) => { 
              document.getElementById("tooltip").innerText = "";
              document.getElementById("tooltip").style.visibility = "hidden";
            }
        })
      };
 
    return (
      <div>
        <RadarChart
            captions={{
              // columns
              battery: 'Battery Capacity',
              design: 'Design',
              useful: 'Usefulness',
              speed: 'Speed',
              weight: 'Weight'
            }}
            data={data}
            size={400}
            options={defaultOptions}
          />
          <div id="divtool" style={tooltipstyle}><label id="tooltip" style={tooltiptextstyle}></label></div>
        </div>
    );
  }
}

Run the Project:

npm start

A few points about the MyRadarComp component:

  1. The code is taken from the npmjs package sample provided in the package description.
  2. I’ve modified the css a bit to show the dots on the chart and also show the values on the Hover event of the dots.
  3. The caption labels and the data property names should match in order to correctly display the data.

Setup Github Repo from Visual Studio Code

  1. Create the Project or directory on your file system. My local folder is called formik-sample. You can also create using the create-react-app Post here for a sample ReactJS App.
  2. Create a repository on Github. I’ve named it sample-form-reactjs.
  3. Click on Clone or Download. Copy the SSH link.
  4. Open the local folder in VS Code as created in Step 1.
  5. In the Terminal Window in VS Code, type the following commands: git config –global user.name pulkit.gemini@gmail.com git clone git@github.com:pulkitgulati/sample-form-reactjs.git
  6. After this is done, just follow the same steps for git stage/commit/push etc.

For # 3:

However, if Step 5. gives error like below:

Check your network firewall settings if you’re doing it from Office. Try it out from your home and it should work.

Unable to find type System.Windows.MessageBox error PowerShell

If you’re using a Message Box in your PowerShell script, chances are you’re running into this error while running the script in a PowerShell window.
But this error does not occur in PowerShell ISE.

If you generally run the command in PowerShell as below and you get the error:

[System.Windows.MessageBox]::Show("Test box")

Then try adding the Type using the below command and run the above command again:

Add-Type -AssemblyName PresentationFramework
[System.Windows.MessageBox]::Show("Test box")

The above type is part of the PresentationFramework.dll that was added with WPF.

The other type is the System.Windows.Forms which was added with Windows Forms, and exists within the Windows Forms assemblies.

So, add the type as below:

Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.MessageBox]::Show("Test box")

You can add these types in your script as per your need. If you’re script uses Params, just add the Add-Type line below it.

Using Fetch with React example async await

I’ve created a basic React App as described in my previous post. This is just a demo on how you can use fetch API to load data in the componentDidMount() lifecycle method with/without
async/await. I’ve not used any error handling yet.

The basic structure of the React App contains index.js and index.html files.

Replace the code of the index.js file as below:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(<App />, document.getElementById('root'));

Create App.js file under the src directory and add the below code:

import React, { Component } from "react";
import MyComp from "./MyComp";
export default class App extends Component {
    render() {
        return (
          <div className="App">
            <MyComp />
          </div>
        );
      }
}

It’s time to create MyComp which is the sample component that will call the placeholder JSON API to show the list of users using Fetch GET request.

The code for MyComp is as shown below:

import React from "react";
export default class MyComp extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            usernames : []
        };
    }
    componentDidMount() {
        fetch('https://jsonplaceholder.typicode.com/users')
            .then(res => res.json())
            .then(json => this.setState({ usernames: json }));
    }
    render() {
        return(
            <div>
                Hey guys!
                <ul>
                {this.state.usernames.map(user => (
                    <li key={user.username}>
                    Hello, {user.username}
                    </li>
                ))}
                </ul>
            </div>
        );
    }
}

Run the App using as below:

npm start

The above code is now using async/await. It is a clean asynchronous way to call the API by writing unblocking code just like promises and callbacks.

Run the following command in the terminal:

npm i @babel/preset-env @babel/plugin-transform-runtime @babel/runtime --save

Replace the componentDidMount() code as below:

async componentDidMount() {
        const response = await fetch(`https://jsonplaceholder.typicode.com/users`);
        const json = await response.json();
        this.setState({ usernames: json });
    }

The async function which in this case is the componentDidMount contains the await expression that pauses the execution of the async function. It waits until the passed Promise is resolved. It then resumes the async function’s execution and evaluates as the resolved value.

Run the App again to see the results which are the same in this case.

Managing Custom Errors with Asp.net

You never want your users to see that yellow screen which shows up when a run-time or design-time error occurs in Asp.Net. However, a developer might want to see the error which may help in finding out the issue.

We have the following Custom error modes in Asp.net that can be set in web.config file:

  • Off: shows the actual error on the screen for all users.
  • On: shows only the custom error page and not the error details to all users.
  • RemoteOnly: shows the error details only to the local users where the Application is running. But does not show it to the outside users.

We recently faced a scenario where one of our Asp.Net Application was returning 3xx series status code from IIS Server for non-existent pages. This was flagged as a possible Security flaw by the team.
e.g. https://abc.com/xyz.aspx

So, if the page xyz.aspx does not exist, the Server will return 404 status code by default.

The following CustomErrors setting by default will give 404 status code:

<customErrors mode="Off" defaultRedirect="Error.htm"/>

We have used CustomErrors in our Web.config file which by the default behaviour of Asp.Net will make the IIS send the following response…
• With status code 302: Found, which effectively means a redirect
• Having a Location response header where the resource should be requested (in this case, the generic error page).
In the end, because the generic error page is static and does not change, when that is requested over same session IIS may return the response 304: Not modified.

Asp.Net CustomErrors setting in Web.Config file:

<customErrors mode="On" defaultRedirect="Error.htm"/>

The below setting produces the same result:

<customErrors mode="On" defaultRedirect="Error.htm">
    <error statusCode="404" redirect="FileNotFound.htm" />
</customErrors>

Similarly, you can manage other status codes.

The default behaviour of Asp.Net returning 3xx series status codes is by design for redirect done by Custom Errors and could be a false Security alert.

Replace Error values in Power BI data model

Here is the Sample Excel data source I’ve created for this Example. Here we will replace the error values in our Query Editor. MyCol3 is Sum of the first 2 columns. Once imported in the data model in Power BI, the 2 rows with values a and b in MyCol2 will show Error in MyCol3.

Import the Excel as below:
Get Data->Excel->Select the Excel file from which you want to import->Select the Sheet you created with the Preview.

Importing the sheet shows the following dialog box:

The data model is shown as below in Power BI:

Right-click on MyCol3 and select Edit Query. This will open the Query Editor.

In the Query Editor, right-click on MyCol3 and Select Replace Errors:

Same option is available in Replace Values drop-down menu under Home Tab in the Ribbon.

Enter the required value to replace with Error and click OK:

The Final values in the data model will be visible as below:


The Applied Steps in the Query Editor will be shown as below for Sheet1 data model:

Click on Close & Apply in the Home Tab to save your changes.

Similar steps can be used to Replace Error values in Excel using Power Query.

Prevent form submission with Javascript button click

Suppose you have a html form and you need to prevent the submission of a form based on the input provided in a textbox.
The html input type should be “button” in this case.

<input type="button" value="Submit" onclick="checkInput();">

Below is the Javascript code that gets called on the button click:

function checkInput() {
	var form = document.getElementById('form1');
	var str = document.getElementById("txtBox").value; 
	if (str == "") {
		var r = confirm("Do you want to add the detail in the input box?");
		if (r == true) {
			document.getElementById("txtBox").focus();
		} else {
			form.submit();
		}
	}
	else {
		form.submit();
	}
}

The above code will submit the form if field is not blank. If the field is blank, focus gets set to the textbox field named “txtBox” when clicking on OK button. Clicking on Cancel will again submit the form.