Dependency Injection Containers in JavaScript

JavaScript is capable of many techniques due to its nature in flexibility. In this post, we will be going over the dependency injection container.

This pattern actually provides the same goal as dependency injection, but in a more flexible and powerful way by acting as the container that houses dependencies of functions (or classes) that require them in times they need it, such as during their initialization phase.

Dependency Injection Without the Container

Let’s quickly refresh our minds on what dependency injection is, what it looks like in code, what problems it solves, and what problems it suffers from.

Dependency injection is a pattern that helps to avoid hard coding dependencies in modules, giving the caller the power to change them and provide their own if they wanted to, in one place.

These dependencies can be injected into the constructor (instantiation) phase or can be set later with a setter method:

class Frog {
  constructor(name, gender) {
    this.name = name
    this.gender = gender
  }
  
  jump() {
    console.log('jumped')
  }
}

class Toad {
  constructor(habitat, name, gender) {
    this.habitat = habitat
    this.frog = new Frog(name, gender)
  }
}

const mikeTheToad = new Toad('land', 'mike', 'male')

Frog.js

There are some issues with this.

Issue #1

If we needed to change how Toad was constructed and it required something fragile like the positioning of arguments or the data structure of them, we would have to manually change the code since it is hardcoded into their block of code.

An example of this scenario is when there is a breaking change in the Frog class.

For one, if Frog added a third parameter in its constructor like weight:

class Frog {
  constructor(name, gender, weight) {
    this.name = name
    this.gender = gender
    this.weight = weight
  }
  
  jump() {
    console.log('jumped')
  }
}

Frog.js

Then our Toad must be updated because this new dependency was added into our Frog instantiation:

class Toad {
  constructor(habitat, name, gender, weight) {
    this.habitat = habitat
    this.frog = new Frog(name, gender, weight)
  }
}

Toad.js

So, if we kept it this way, how many times do you think you would end up having to change Toad if you were in some frog startup company and that was one of the first pieces of code you started with?

Issue #2

You have to know what dependency to use for Toad every time.

We have to know that Toad now needs four arguments in the exact same order for it to initiate an instance of Frog correctly, even their data types, otherwise bugs can easily occur.

And it can seem quite awkward if you know that a Toad is essentially a frog, so knowing that, you might accidentally assume that Toad would be extending Frog then.

So, then you realize that an instance of Frog is being created inside Toad instead, and now you get all confused because you’re an intelligent human being and the code was just throwing you off — realizing that the code does not align properly with the real world.

Issue #3

Unnecessarily involves more code.

With the dependency injection pattern, these problems are solved by inversing the control of the way the dependencies are instantiated:

class Frog {
  constructor({ name, gender, weight }) {
    this.name = name
    this.gender = gender
    this.weight = weight
  }
  
  jump() {
    console.log('jumped')
  }
}

class Toad {
  constructor(habitat, frog) {
    this.habitat = habitat
    this.frog = frog
  }
}

FrogToad.js

OK, that was easy. Now, when there’s another breaking change to Frog (such as the arguments being put into a JavaScript object), we don’t even have to touch Toad or waste brain cells reading Toad, then Frog, then back to Toad, etc.

That’s because we can now just change the part where we create an instance of Toad (which is better than having to go inside and change stuff in the Toad implementation, which is bad practice!

It shouldn’t have to worry about how frog is constructed, it should only know that it takes a frog as an argument and stores it in its .frog property to use later. You take charge of its dependencies now.

const mikeTheToad = new Toad(
  'land',
  new Frog({
    name: 'mike',
    gender: 'male',
    weight: 12.5,
  }),
)

mikeTheToad.js

So, we just practiced some clean code practices by abstracting out implementation details of Frog away from the Toad constructor. It makes sense: does Toad even have to care about how Frog is constructed? If anything, it should have just extended it!

Dependency Injection Container (DIC) Pattern

Now that we’ve refreshed our minds on dependency injection, let’s talk about the dependency injection container!

So, why do we need the DIC pattern and why isn’t the dependency injection without the container enough in tough situations?

Here’s the problem: It’s simply just not scalable. The larger your project becomes, the more you start losing confidence in maintaining your code in the long run because then, it just becomes a mess over time.

In addition, you also have to get the order of injecting dependencies in the correct order so that you don’t fall into the issue of something being undefined when you’re instantiating something.

So, in essence, six months later, our code can evolve to something like this:

class Frog {
  constructor({ name, gender, weight }) {
    this.name = name
    this.gender = gender
    this.weight = weight
  }
  
  jump() {
    console.log('jumped')
  }
  
  setHabitat(habitat) {
    this.habitat = habitat
  }
}

class Toad extends Frog {
  constructor(options) {
    super(options)
  }
  
  leap() {
    console.log('leaped')
  }
}

class Person {
  constructor() {
    this.id = createId()
  }
  
  setName(name) {
    this.name = name
    return this
  }
  
  setGender(gender) {
    this.gender = gender
    return this
  }
  
  setAge(age) {
    this.age = age
    return this
  }
}

function createId() {
  var idStrLen = 32
  var idStr = (Math.floor(Math.random() * 25) + 10).toString(36) + '_'
  idStr += new Date().getTime().toString(36) + '_'
  do {
    idStr += Math.floor(Math.random() * 35).toString(36)
  } while (idStr.length < idStrLen)
  return idStr
}

class FrogAdoptionFacility {
  constructor(name, description, location) {
    this.name = name
    this.description = description
    this.location = location
    this.contracts = {}
    this.adoptions = {}
  }
  
  createContract(employee, client) {
    const contractId = createId()
    this.contracts[contractId] = {
      id: contractId,
      preparer: employee,
      client,
      signed: false,
    }
    return this.contracts[contractId]
  }
  
  signContract(id, signee) {
    this.contracts[id].signed = true
  }
  
  setAdoption(frogOwner, frogOwnerLicense, frog, contract) {
    const adoption = {
      [frogOwner.id]: {
        owner: {
          firstName: frogOwner.owner.name.split(' ')[0],
          lastName: frogOwner.owner.name.split(' ')[1],
          id: frogOwner.id,
        },
        frog,
        contract,
        license: {
          id: frogOwnerLicense.id,
        },
      },
    }
    this.adoptions[contract.id] = adoption
  }
  
  getAdoption(id) {
    return this.adoptions[id]
  }
}

class FrogParadiseLicense {
  constructor(frogOwner, licensePreparer, frog, location) {
    this.id = createId()
    this.client = {
      firstName: frogOwner.name.split(' ')[0],
      lastName: frogOwner.name.split(' ')[1],
      id: frogOwner.id,
    }
    this.preparer = {
      firstName: licensePreparer.name.split(' ')[0],
      lastName: licensePreparer.name.split(' ')[1],
      id: licensePreparer.id,
    }
    this.frog = frog
    this.location = `${location.street} ${location.city} ${location.state} ${location.zip}`
  }
}

class FrogParadiseOwner {
  constructor(frogOwner, frogOwnerLicense, frog) {
    this.id = createId()
    this.owner = {
      id: frogOwner.id,
      firstName: frogOwner.name.split(' ')[0],
      lastName: frogOwner.name.split(' ')[1],
    }
    this.license = frogOwnerLicense
    this.frog = frog
  }
  
  createDocument() {
    return JSON.stringify(this, null, 2)
  }
}

FrogApp.js

The whole adoption process ends when setAdoption from FrogAdoptionFacility is called.

Let’s pretend you start developing code using these classes and ended up with a working version like so:

const facilityTitle = 'Frog Paradise'

const facilityDescription =
  'Your new one-stop location for fresh frogs from the sea! ' +
  'Our frogs are housed with great care from the best professionals all over the world. ' +
  'Our frogs make great companionship from a wide variety of age groups, from toddlers to ' +
  'senior adults! What are you waiting for? ' +
  'Buy a frog today and begin an unforgettable adventure with a companion you dreamed for!'

const facilityLocation = {
  address: '1104 Bodger St',
  suite: '#203',
  state: 'NY',
  country: 'USA',
  zip: 92804,
}

const frogParadise = new FrogAdoptionFacility(
  facilityTitle,
  facilityDescription,
  facilityLocation,
)

const mikeTheToad = new Toad({
  name: 'mike',
  gender: 'male',
  weight: 12.5,
})

const sally = new Person()
sally
  .setName('sally tran')
  .setGender('female')
  .setAge(27)
  
const richardTheEmployee = new Person()
richardTheEmployee
  .setName('richard rodriguez')
  .setGender('male')
  .setAge(77)
  
const contract = frogParadise.createContract(richardTheEmployee, sally)
frogParadise.signContract(contract.id, sally)

const sallysLicense = new FrogParadiseLicense(
  sally,
  richardTheEmployee,
  mikeTheToad,
  facilityLocation,
)

const sallyAsPetOwner = new FrogParadiseOwner(sally, sallysLicense, mikeTheToad)
frogParadise.setAdoption(sallyAsPetOwner, sallysLicense, mikeTheToad, contract)

const adoption = frogParadise.getAdoption(contract.id)
console.log(JSON.stringify(adoption, null, 2))

FrogApp.js

If we run the code, it will work and create a new adoption object that looks like this:

{
  "t_k8pgj8gh_k4ofadkj2x4yluemfgvmm": {
    "owner": {
      "firstName": "sally",
      "lastName": "tran",
      "id": "t_k8pgj8gh_k4ofadkj2x4yluemfgvmm"
    },
    "frog": {
      "name": "mike",
      "gender": "male",
      "weight": 12.5
    },
    "contract": {
      "id": "m_k8pgj8gh_kdfr55oui28c88lisswak",
      "preparer": {
        "id": "n_k8pgj8gh_uxlbmbflwjrj4cqgjyvyw",
        "name": "richard rodriguez",
        "gender": "male",
        "age": 77
      },
      "client": {
        "id": "h_k8pgj8gh_hkqvp4f3uids8uj00i47d",
        "name": "sally tran",
        "gender": "female",
        "age": 27
      },
      "signed": true
    },
    "license": {
      "id": "y_k8pgj8gh_0qnwm9po0cj7p3vgsedu3"
    }
  }
}

adoption.json

We’ve got a pretty nice app — a frog adoption facility where customers can come and adopt a frog. But the adoption process is not a simple give/receive money transaction.

We’re pretending that there’s a law requiring this process to be conducted for every frog adoption facility handing frogs to their new owners.

So, it requires the facility (Frog Paradise) to generate a contract that requires the customer’s signature.

Then, a license is also created on the spot that the customer needs to have on them for legal protection. And finally, the adoption is completed after all is done.

Take a look at the FrogOwner class:

class FrogParadiseOwner {
  constructor(frogOwner, frogOwnerLicense, frog) {
    this.id = createId()
    this.owner = frogOwner
    this.license = frogOwnerLicense
    this.frog = frog
  }
  
  createDocument() {
    return JSON.stringify(this, null, 2)
  }
}

FrogParadiseOwner.js

It has three dependencies: frogOwner, frogOwnerLicense, andfrog.

Let’s pretend there was an update with frogOwner (an instance of Person) and it changed to become an instance of Client:

class Client extends Person {
  
  setName(name) {
    this.name = name
  }
}

Client.js

Now, calls to initializing FrogParadiseOwner need to be updated.

But what if we had initialized FrogParadiseOwner throughout several locations of our code? If our code gets longer and the number of these instances increases, the more it becomes an issue to maintain.

This is where the dependency injection container can make the difference because you would only need to change your code in one location.

This is what a dependency injection container can look like:

import parseFunction from 'parse-function'

const app = parseFunction({
  ecmaVersion: 2017,
})

class DIC {
  constructor() {
    this.dependencies = {}
    this.factories = {}
  }
  
  register(name, dependency) {
    this.dependencies[name] = dependency
  }
  
  factory(name, factory) {
    this.factories[name] = factory
  }
  
  get(name) {
    if (!this.dependencies[name]) {
      const factory = this.factories[name]
      if (factory) {
        this.dependencies[name] = this.inject(factory)
      } else {
        throw new Error('No module found for: ' + name)
      }
    }
    return this.dependencies[name]
  }
  
  inject(factory) {
    const fnArgs = app.parse(factory).args.map((arg) => this.get(arg))
    return new factory(...fnArgs)
  }
}

DIC.js

With this in place, it becomes as easy as this to update changes:

class Client extends Person {
  setName(name) {
    this.name = name
  }
}

const dic = new DIC()
dic.register('frogOwner', Client)
dic.register('frogOwnerLicense', sallysLicense)
dic.register('frog', mikeTheToad)
dic.factory('frog-owner', FrogParadiseOwner)

const frogOwner = dic.get('frog-owner')

Client.js

Now, instead of directly initializing it like before and having to change all other instances of the code:

const frogOwner = new FrogParadiseOwner(Client, sallysLicense, mikeTheToad)
// some other location
const frogOwner2 = new FrogParadiseOwner(...)
// some other location
const frogOwner3 = new FrogParadiseOwner(...)
// some other location
const frogOwner4 = new FrogParadiseOwner(...)
// some other location
const frogOwner5 = new FrogParadiseOwner(...)

frogOwnerInstances.js
You can instead use the DIC to update it once and you won’t need to change any other parts of your code, because we reversed the direction of the flow for that to the container:

// Update here only by passing the dependency to the DIC
const dic = new DIC()
dic.register('frogOwner', Client)
dic.register('frogOwnerLicense', sallysLicense)
dic.register('frog', mikeTheToad)
dic.factory('frog-owner', FrogParadiseOwner)

const frogOwner = dic.get('frog-owner')

DIC.js

Let’s explain what the DIC is doing:

You insert any classes or functions you want to be resolved by the DIC by passing it into the .factory() method, which gets stored into the .factory property.

This is image title

For each of those functions passed into .factory, you would have to register their arguments using .register() so that they can be picked up when the container is initializing the requested function.

They get picked up from the .dependencies property. You can add things to the dependencies using the .dependencies() method.
This is image title

When you want to retrieve something, you use .get with some key. It uses the key to look through its dependencies and if it finds something there, it will return it.

Otherwise, it will proceed to look through its factories and if it finds something, it will treat it as a function that you want it to resolve.

This is image title

Then it passes the invocation to .inject in which it reads the names of the function’s dependencies (arguments) and grabs them from its .dependencies property, invoking the function and injecting its arguments, returning the result.

This is image title

In our code examples, I used the parse-function to allow the inject method to grab the names of a function’s arguments.

To do it without the library, you can add an extra argument to .get and have it pass down to its .inject like this:

class DIC {
  constructor() {
    this.dependencies = {}
    this.factories = {}
  }
  
  register(name, dependency) {
    this.dependencies[name] = dependency
  }
  
  factory(name, factory) {
    this.factories[name] = factory
  }
  
  get(name, args) {
    if (!this.dependencies[name]) {
      const factory = this.factories[name]
      if (factory) {
        this.dependencies[name] = this.inject(factory, args)
      } else {
        throw new Error('No module found for: ' + name)
      }
    }
    return this.dependencies[name]
  }
  
  inject(factory, args = []) {
    const fnArgs = args.map((arg) => this.get(arg))
    return new factory(...fnArgs)
  }
}

DependencyInjectionContainer.js

const dic = new DIC()
dic.register('frogOwner', Client)
dic.register('frogOwnerLicense', sallysLicense)
dic.register('frog', mikeTheToad)
dic.factory('frog-owner', FrogParadiseOwner)

const frogOwner = dic.get('frog-owner', [
  'frogOwner',
  'frogOwnerLicense',
  'frog',
])

console.log('frog-owner', JSON.stringify(frogOwner, null, 2))

DIC.js

Nonetheless, we still get the same result:

{
  "id": "u_k8q16rjx_fgrw6b0yb528unp3trokb",
  "license": {
    "id": "m_k8q16rjk_jipoch164dsbpnwi23xin",
    "client": {
      "firstName": "sally",
      "lastName": "tran",
      "id": "b_k8q16rjk_0xfqodlst2wqh0pxcl91j"
    },
    "preparer": {
      "firstName": "richard",
      "lastName": "rodriguez",
      "id": "g_k8q16rjk_f13fbvga6j2bjfmriir63"
    },
    "frog": {
      "name": "mike",
      "gender": "male",
      "weight": 12.5
    },
    "location": "undefined undefined NY 92804"
  },
  "frog": {
    "name": "mike",
    "gender": "male",
    "weight": 12.5
  }
}

adoptionResult.json

Conclusion

And that concludes this post! I hope you found this to be valuable and look out for more in the future!

#javascript #programming

What is GEEK

Buddha Community

Dependency Injection Containers in JavaScript
危 思

危 思

1685029320

如何使用 JavaScript 创建等值线图

在本 JavaScript 教程中,我们将了解如何使用 JavaScript 创建等值线图。在本教程中,以英国女王伊丽莎白二世的国事访问作为数据示例,逐步学习使用 JavaScript 创建等值线图。

你准备好学习如何像老板一样用 JavaScript创建等值线图了吗?地图是一种可视化数据的强大方式,但从头开始构建地图可能是一项艰巨的任务。别担心,我是来帮忙的!

在本教程中,我将逐步指导您完成构建 JavaScript 等值线图的过程。为了让事情更有趣,我们将以伊丽莎白二世女王的国事访问为例来展示这种地图的力量。

准备好用令人惊叹的数据可视化给您自己和您的观众留下深刻印象,让我们一起开始这段激动人心的旅程吧!

什么是等值线图?

等值线图是一种专题地图,它使用颜色来表示不同地区或地缘政治区域内特定数量的值。地图被划分为区域或多边形,每个区域的颜色代表可视化数据的值。通常,较深的颜色表示较高的值,而较浅的颜色表示较低的值。

因此,正如我提到的,在本教程中,我们将创建一个基于 JS 的等值线图来展示英国女王伊丽莎白二世对世界各地的国事访问。通过使用不同的颜色来代表每个地区的访问次数,我们可以很容易地识别出女王访问最频繁的区域。最终的交互式等值区地图将如下所示:

如何构建基本等值线图

使用 JavaScript 创建等值线图似乎具有挑战性,但不要害怕!只需遵循四个简单的步骤:

  1. 设置一个 HTML 页面来显示地图。
  2. 添加所有必需的 JavaScript 文件。
  3. 包括数据。
  4. 编写渲染地图所需的 JavaScript 代码。

完成这四个步骤后,您将拥有一个漂亮的等值线图,可以准确地表示您的数据。因此,让我们更详细地研究每个步骤,并学习如何轻松创建令人惊叹的 JavaScript 等值线图!

1. 设置一个 HTML 页面来显示等值线图

要开始创建等值线图,第一步是设置一个带有div元素的 HTML 页面,并为其提供一个唯一 ID 以便稍后引用它。

我将元素的宽度和高度设置div为 100% 以在整个页面上呈现地图,但您可以调整这些值以满足您的需要。此div元素将成为图表的容器,ID 将用于在 JavaScript 代码中引用它。那么,让我们开始为即将推出的等值区地图创建 HTML 页面吧! 

<html>
  <head>
    <title>JavaScript Choropleth Map</title>
    <style type="text/css">      
      html, body, #container { 
        width: 100%; height: 100%; margin: 0; padding: 0; 
      } 
    </style>
  </head>
  <body>
    <div id="container"></div>
  </body>
</html>

2. 添加所有必要的 JavaScript 文件

为了轻松地为网络创建数据可视化,我使用了一个带有内置实用程序和函数的JavaScript 图表库。有了大量可用的此类JS 库,创建图表和地图的过程在本质上和大多数库的逻辑上都是相似的。在本教程中,我使用的是AnyChart JS 图表库,因为它对初学者友好,具有大量文档和大量示例来帮助您入门。

需要在<head>HTML 页面的部分链接所需的 JS 脚本。这些脚本包括 Core 和 Geo Maps 模块以及包含世界地图地理数据的文件,所有这些都可以在 CDN 上获得。我还将使用另外两个脚本文件将数据连接到等值线图。一个是数据适配器,它可以帮助加载数据,另一个是Proj4js,这是一个 JavaScript 库,可以将坐标从一个坐标系转换到另一个坐标系,这样数据就可以准确地绘制在地图上。

<html>
  <head>
    <title>JavaScript Choropleth Map</title>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-base.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-map.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.11.0/geodata/custom/world/world.js"></script>
    <style type="text/css">      
      html, body, #container { 
        width: 100%; height: 100%; margin: 0; padding: 0; 
      } 
    </style>
  </head>
  <body>  
    <div id="container"></div>
    <script>
      // All the code for the JS choropleth map will come here
    </script>
  </body>
</html>

3.包括数据

好吧,让我们加载数据并绘制在 JS choropleth 地图上!首先,我从维基百科收集了伊丽莎白二世女王国事访问的数据,并将其放在一个 JSON 文件中,以便于访问。你可以在这里找到它。

所有必要的文件都已链接在<head>HTML 页面的部分中。因此,可以使用页面正文中标记loadJsonFile()内的方法来加载包含女王访问数据的 JSON 文件。<script>

anychart.data.loadJsonFile(<fileURL>, function (data) {});

伟大的!现在一切都已准备就绪,是时候继续旅程的主要部分了:创建等值线地图可视化!我们开工吧!

4. 编写渲染地图所需的 JavaScript 代码

您只需几行 JS 代码即可获得渲染的等值线图。首先,确保所有代码都在函数内部anychart.onDocumentReady(),以便在执行任何其他操作之前页面已完全加载。加载数据文件后,设置数据、创建地图并设置地理数据。

<script>

  anychart.onDocumentReady(function() {

    // load data from a json file
    anychart.data.loadJsonFile('https://gist.githubusercontent.com/shacheeswadia/8f45da54d9bf2032fee201dbfc79e0e4/raw/5d10d58f40b4a1d994cef36dbc64545ef90ead80/queenVisits.json',
    function (data) {
    
      // create a dataset
      let dataSet = anychart.data.set(data);

      // create a map instance
      let map = anychart.map();

      // set the geodata
      map.geoData("anychart.maps.world");

      // the rest of the JS code will be here
	
    });

  });

</script>

choropleth()现在,使用函数和加载的数据创建一个系列。对于着色,让我们根据皇家网站上的颜色设置具有四种不同深浅蓝色的线性色标。按照惯例,一个国家的阴影越深,该地区的访问量就越高。

// create a choropleth series
let series = map.choropleth(dataSet);

// set the map colors
series
  .colorScale(
     anychart.scales.linearColor("#f2f2f2", "#42a5f5", "#1976d2", "#233580")
   );

最后,给地图一个标题,设置容器,绘制生成的地图。

// set the map title
map.title("State Visits Made by Queen Elizabeth II");

// set the container
map.container('container');

// initiate the map drawing
map.draw();

瞧!一张美观实用的等值线图已经准备就绪!看看它的外观。您可以在下面找到完整的代码或在此处查看和使用它。

基本等值线图

<html>
  <head>
    <title>JavaScript Choropleth Map</title>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-base.min.js"></script>
    <script data-fr-src="https://cdn.anychart.com/releases/8.11.0/js/anychart-map.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.11.0/geodata/custom/world/world.js"></script>
    <style type="text/css">      
      html, body, #container { 
        width: 100%; height: 100%; margin: 0; padding: 0; 
      } 
    </style>
  </head>
  <body>  
    <div id="container"></div>
    <script>
      anychart.onDocumentReady(function () {
        // load data from a json file
        anychart.data.loadJsonFile(
          "https://gist.githubusercontent.com/shacheeswadia/8f45da54d9bf2032fee201dbfc79e0e4/raw/5d10d58f40b4a1d994cef36dbc64545ef90ead80/queenVisits.json",
          function (data) {
            // create a dataset
            let dataSet = anychart.data.set(data);
            // create a map instance
            let map = anychart.map();
            // set the geodata
            map.geoData("anychart.maps.world");
            // create a choropleth series
            let series = map.choropleth(dataSet);
            // set the map colors
            series
              .colorScale(
                anychart.scales.linearColor("#f2f2f2", "#42a5f5", "#1976d2", "#233580")
              );
            // set the map title
            map.title("State Visits Made by Queen Elizabeth II");
            // set the container
            map.container("container");
            // initiate the map drawing
            map.draw();
          }
        );
      });
    </script>
  </body>
</html>

如何自定义等值线图

现有的 choropleth 地图已经令人印象深刻,但让我向您展示如何使它更有洞察力和吸引力!在以下步骤中,我将演示如何自定义等值线图以增加更多视觉吸引力和交互性:

  1. 通过将鼠标悬停在地图区域上来修改颜色。
  2. 添加颜色图例。
  3. 改进工具提示和标题格式。
  4. 添加缩放控件。

1.将鼠标悬停在区域上修改颜色

您可以通过修改悬停区域的颜色使地图更具视觉吸引力。默认情况下,悬停区域变为灰色,但您可以将其更改为基色的深色阴影以使其更直观。这可以通过在悬停时更改区域的填充颜色并使用该darken()功能来实现。

series
  .hovered()
  .fill(function (d) {
    return anychart.color.darken(d.sourceColor, 0.2);
  });

2. 添加颜色图例

向等值线图添加颜色图例始终是一个好主意,因为它可以帮助您的观众理解地图中使用的值和颜色。

要添加颜色图例,您只需要启用颜色范围。这将自动创建一个图例,表示什么颜色表示什么值。默认情况下,颜色范围是禁用的。要启用它,您只需要添加几行代码:

map.colorRange()
  .enabled(true);

瞧!您现在有一个美丽且信息丰富的颜色图例来补充您的等值线图。

3.改进工具提示和标题格式

让我们通过改进工具提示和标题格式将等值线图提升到一个新的水平。工具提示是展示附加信息的强大方式,通过启用 HTML 来自定义工具提示和设置值的格式,它们可以做得更好。

我认为添加自定义文本并指出女王访问悬停国家的次数会很好。此外,可以处理英国的具体案例,以展示女王曾住在那里。

通过这些更改,工具提示不仅提供了更多信息,而且在视觉上也更具吸引力。用户将在了解有关女王旅行的有趣事实的同时享受工具提示的俏皮语气。

map
  .title()
  .enabled(true)
  .useHtml(true)
  .text(
    '<span style="color: #c8102e; font-size:18px;">State visits made by Queen Elizabeth II</span>' +
      <span style="font-size: 15px;">(The Queen is the most widely travelled head of state in history)</span>'
  );

除了自定义工具提示之外,为什么不使用 HTML 增强图表标题呢?例如,副标题将提供更多上下文,而自定义文本样式将使其大放异彩。

series
  .tooltip() 
  .useHtml(true)
  .format(function (d) {
    if (d.name == "United Kingdom") {
      return "<h6 style='font-size:14px; font-weight:400; margin: 0.2rem 0;'>The Queen lived here.</h6>";
    } else {
      return (
        "<h6 style='font-size:14px; font-weight:400; margin: 0.2rem 0;'>The Queen visited <b>" +
          d.value + "</b> times.</h6>"
      );
    }
  });

4. 添加缩放控件

向世界地图添加缩放控件是允许用户放大特定感兴趣区域的好方法。首先,将所需的脚本和 CSS 链接添加到 HTML 文档的<head>部分。完成此操作后,您只需几行代码即可创建缩放控件并在地图上呈现它们。 

<script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-exports.min.js"></script>
<script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-ui.min.js"></script>

<link rel="stylesheet" type="text/css" href="https://cdn.anychart.com/releases/8.11.0/css/anychart-ui.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.anychart.com/releases/8.11.0/fonts/css/anychart-font.min.css">
var zoomController = anychart.ui.zoom();
zoomController.render(map);

值得注意的是,缩放功能在处理大型且详细的等值线图时特别有用。在这种情况下,这可能是允许用户更详细地探索特定区域或兴趣领域的好方法。

现在,坐下来欣赏您美丽的 JavaScript 等值线图吧!通过添加自定义颜色、颜色图例、改进的工具提示和标题以及缩放控件,它是一种互动且引人入胜的可视化效果,一定会给人留下深刻印象。请参阅下面此项目的完整代码,并随意使用它并在此处查看等值线图的完整交互式版本

Choropleth 地图决赛

<html>
  <head>
    <title>JavaScript Choropleth Map</title>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-base.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-map.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.11.0/geodata/custom/world/world.js"></script>
    <style type="text/css">      
      html, body, #container { 
        width: 100%; height: 100%; margin: 0; padding: 0; 
      } 
    </style>
  </head>
  <body>  
    <div id="container"></div>
    <script>
      anychart.onDocumentReady(function () {
        // load data from a json file
        anychart.data.loadJsonFile(
          "https://gist.githubusercontent.com/shacheeswadia/8f45da54d9bf2032fee201dbfc79e0e4/raw/5d10d58f40b4a1d994cef36dbc64545ef90ead80/queenVisits.json",
          function (data) {
            // create a dataset
            let dataSet = anychart.data.set(data);
            // create a map instance
            let map = anychart.map();
            // set the geodata
            map.geoData("anychart.maps.world");
            // create a choropleth series
            let series = map.choropleth(dataSet);
            // set the map colors
            series.colorScale(
              anychart.scales.linearColor("#f2f2f2", "#42a5f5", "#1976d2", "#233580")
            );
            // customize the colors in the hovered state
            series.hovered().fill(function (d) {
              return anychart.color.darken(d.sourceColor, 0.2);
            });
            // create the map legend
            map.colorRange().enabled(true);
            // create zoom controls
            let zoomController = anychart.ui.zoom();
            zoomController.render(map);
            // customize the tooltip text
            series
              .tooltip()
              .useHtml(true)
              .format(function (d) {
                if (d.name == "United Kingdom") {
                  return "<h6 style='font-size:14px; font-weight:400; margin: 0.2rem 0;'>The Queen lived here.</h6>";
                } else {
                  return (
                    "<h6 style='font-size:14px; font-weight:400; margin: 0.2rem 0;'>The Queen visited <b>" +
                    d.value +
                    "</b> times.</h6>"
                  );
                }
              });
            // set the map title
            map
              .title()
              .enabled(true)
              .useHtml(true)
              .text(
                '<span style = "color: #c8102e; font-size:18px;">State Visits Made by Queen Elizabeth II</span>' +
                  '<br/><span style="font-size: 15px;">The Queen is the most widely traveled head of state in history</span>'
              );
            // set the container
            map.container("container");
            // initiate the map drawing
            map.draw();
          }
        );
      });
    </script>
  </body>
</html>

结论

Сhoropleth 地图是在地理范围内可视化数据的强大工具。使用 JavaScript,您可以创建令人惊叹的交互式应用程序,以清晰简洁的方式传达复杂的信息。

无论您是追踪君主的旅行还是可视化流行病的传播,都有无限可能。所以,尽情发挥您的想象力,开始通过数据的视角探索世界吧!

文章来源:https: //dzone.com

#javascript 

Adam Daniels

Adam Daniels

1684295339

How to Create Heatmap with JavaScript

In this tutorial, you will learn how to create an interactive heatmap with JavaScript. Create your own interactive JavaScript heatmaps. 

Data visualization is a powerful tool that helps us make sense of complex data. With it, we can spot patterns and trends that might take much more time to become obvious just by looking at raw numbers.

One particularly useful chart type is the heatmap, and I’m excited to teach you how to create one with JavaScript in this tutorial.

What is a Heatmap?

A heatmap is a two-dimensional representation of the magnitude of a phenomenon through colors. It provides a quick visual summary of high and low values in the data.

For instance, did you know that an average of 108 people died per day in road accidents in the U.S. in 2021? Using a heatmap chart, we can analyze the days and times of fatal accidents. This will be the visualization we will be building during the tutorial.

So, grab your cup of coffee and let's dive into this step-by-step guide. By the end, you'll have the skills to easily create your own interactive JavaScript heatmaps.

The Heatmap Chart We'll Build

Here is how the final JS-based heatmap chart will look:

heatmapchart-006

Ready to dive in? Let's go!

How to Make a JavaScript Heatmap

Great, let's start creating a simple yet beautiful heatmap chart using JavaScript. With just four easy-to-follow steps, you'll have a stunning interactive heatmap in no time.

Don't worry about any complicated coding or overwhelming technicalities. We'll keep things straightforward and easy to understand.

1. Create an HTML Page

First things first, we need to create a web page that'll hold our super-cool heatmap. We start by making a basic HTML page, complete with a div element to hold our chart. Let’s also specify the style of the div to make it stretch over the whole page. Don't worry, it’s easy-peasy:

<html>
  <head>
    <title>Heatmap in JavaScript</title>
    <style type="text/css">      
      html, body, #container { 
        width: 100%; margin: 0; padding: 0; 
      } 
    </style>
  </head>
  <body>
    <div id="container"></div>
  </body>
</html>

2. Include the Required JavaScript Files

Okay, let's be real: building a JS heatmap from scratch would be a real pain in the you-know-what. Instead, we're gonna take the easier route and use a JavaScript charting library.

There are a ton of various JS charting libraries out there. For this project, we're gonna go with the AnyChart JS library, which supports heatmap charts and is free for personal and other non-profit purposes.

To make things work, we need to add a couple of scripts to our web page's <head> section. Specifically, we need to include the base and heatmap modules. Sounds easy, right?

<html>
  <head>
    <title>Heatmap in JavaScript</title>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-core.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-heatmap.min.js"></script> 
    <style type="text/css">      
      html, body, #container { 
        width: 100%; margin: 0; padding: 0; 
      } 
    </style>
  </head>
  <body>  
    <div id="container"></div>
    <script>
      // All the code for the JS heatmap will come here
    </script>
  </body>
</html>

3. Add the Data

Each chart is complete with the data, right? We’re gonna grab our data from the NSC website and add it to our HTML file in the proper format.

For our heatmap, each data point needs to include an x value (day), a y value (hour), and a heat value (number of accidents). We'll wrap this data in a function that we'll call when we create the JS chart.

function getData() {
  return [
    {
      x: "Monday",
      y: "Midnight–3:59 a.m.",
      heat: 705
    },
    {
      x: "Monday",
      y: "4:00–7:59 a.m.",
      heat: 713
    },
    {
      x: "Monday",
      y: "8:00–11:59 a.m.",
      heat: 657
    },
    {
      x: "Monday",
      y: "Noon–3:59 p.m.",
      heat: 957
    },
    {
      x: "Monday",
      y: "4:00–7:59 p.m.",
      heat: 1137
    },
    {
      x: "Monday",
      y: "8:00–11:59 p.m.",
      heat: 956
    },
    {
      x: "Tuesday",
      y: "Midnight–3:59 a.m.",
      heat: 482
    },
    {
      x: "Tuesday",
      y: "4:00–7:59 a.m.",
      heat: 641
    },
    {
      x: "Tuesday",
      y: "8:00–11:59 a.m.",
      heat: 631
    },
    {
      x: "Tuesday",
      y: "Noon–3:59 p.m.",
      heat: 905
    },
    {
      x: "Tuesday",
      y: "4:00–7:59 p.m.",
      heat: 1137
    },
    {
      x: "Tuesday",
      y: "8:00–11:59 p.m.",
      heat: 986
    },
    {
      x: "Wednesday",
      y: "Midnight–3:59 a.m.",
      heat: 465
    },
    {
      x: "Wednesday",
      y: "4:00–7:59 a.m.",
      heat: 616
    },
    {
      x: "Wednesday",
      y: "8:00–11:59 a.m.",
      heat: 627
    },
    {
      x: "Wednesday",
      y: "Noon–3:59 p.m.",
      heat: 914
    },
    {
      x: "Wednesday",
      y: "4:00–7:59 p.m.",
      heat: 1159
    },
    {
      x: "Wednesday",
      y: "8:00–11:59 p.m.",
      heat: 1066
    },
    {
      x: "Thursday",
      y: "Midnight–3:59 a.m.",
      heat: 584
    },
    {
      x: "Thursday",
      y: "4:00–7:59 a.m.",
      heat: 718
    },
    {
      x: "Thursday",
      y: "8:00–11:59 a.m.",
      heat: 660
    },
    {
      x: "Thursday",
      y: "Noon–3:59 p.m.",
      heat: 966
    },
    {
      x: "Thursday",
      y: "4:00–7:59 p.m.",
      heat: 1161
    },
    {
      x: "Thursday",
      y: "8:00–11:59 p.m.",
      heat: 1186
    },
    {
      x: "Friday",
      y: "Midnight–3:59 a.m.",
      heat: 715
    },
    {
      x: "Friday",
      y: "4:00–7:59 a.m.",
      heat: 747
    },
    {
      x: "Friday",
      y: "8:00–11:59 a.m.",
      heat: 738
    },
    {
      x: "Friday",
      y: "Noon–3:59 p.m.",
      heat: 1056
    },
    {
      x: "Friday",
      y: "4:00–7:59 p.m.",
      heat: 1426
    },
    {
      x: "Friday",
      y: "8:00–11:59 p.m.",
      heat: 1631
    },
    {
      x: "Saturday",
      y: "Midnight–3:59 a.m.",
      heat: 1383
    },
    {
      x: "Saturday",
      y: "4:00–7:59 a.m.",
      heat: 641
    },
    {
      x: "Saturday",
      y: "8:00–11:59 a.m.",
      heat: 635
    },
    {
      x: "Saturday",
      y: "Noon–3:59 p.m.",
      heat: 1034
    },
    {
      x: "Saturday",
      y: "4:00–7:59 p.m.",
      heat: 1400
    },
    {
      x: "Saturday",
      y: "8:00–11:59 p.m.",
      heat: 1593
    },
    {
      x: "Sunday",
      y: "Midnight–3:59 a.m.",
      heat: 1486
    },
    {
      x: "Sunday",
      y: "4:00–7:59 a.m.",
      heat: 695
    },
    {
      x: "Sunday",
      y: "8:00–11:59 a.m.",
      heat: 564
    },
    {
      x: "Sunday",
      y: "Noon–3:59 p.m.",
      heat: 932
    },
    {
      x: "Sunday",
      y: "4:00–7:59 p.m.",
      heat: 1292
    },
    {
      x: "Sunday",
      y: "8:00–11:59 p.m.",
      heat: 1211
    }
  ];
}

4. Write the Necessary JS Code for the Chart

Here's the fun part: it's time to write the JavaScript code that'll make our heatmap chart look amazing.

We'll enclose everything in a function to ensure the code only executes when the page is ready. We'll create the graph using the heatmap() function and add the data we created in the previous step.

let chart = anychart.heatMap(getData());

Then, we'll give the chart a descriptive title:

chart.title("Fatal Car Crashes in U.S. in 2021 by Time of Day and Day of Week”);

Finally, we'll set the container reference and draw the chart. Voilà!

сhart.container('container’);
chart.draw();

And there you have it. With just a little bit of HTML and JavaScript, you can create a totally rad interactive heatmap. You can see the entire code of this JS-based heatmap below and check it out live here. After that, we'll learn how to customize our heatmap in all kinds of fun ways.

heatmapchart-001

<html>
  <head>
    <title>Heatmap in JavaScript</title>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-core.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-heatmap.min.js"></script> 
    <style type="text/css">      
      html, body, #container { 
        width: 100%; margin: 0; padding: 0; 
      } 
    </style>
  </head>
  <body>  
    <div id="container"></div>
    <script>
      anychart.onDocumentReady(function () {
        // create a heatmap
        let chart = anychart.heatMap(getData());
        // name the heatmap
        chart.title("Fatal Car Crashes in U.S. in 2021 by Time of Day and Day of Week");
        // set the container for the heatmap
        chart.container("container");
        // draw the heatmap
        chart.draw();
      });
      // add the data
      function getData() {
        return [
          {
            x: "Monday",
            y: "Midnight–3:59 a.m.",
            heat: 705
          },
          {
            x: "Monday",
            y: "4:00–7:59 a.m.",
            heat: 713
          },
          {
            x: "Monday",
            y: "8:00–11:59 a.m.",
            heat: 657
          },
          {
            x: "Monday",
            y: "Noon–3:59 p.m.",
            heat: 957
          },
          {
            x: "Monday",
            y: "4:00–7:59 p.m.",
            heat: 1137
          },
          {
            x: "Monday",
            y: "8:00–11:59 p.m.",
            heat: 956
          },
          {
            x: "Tuesday",
            y: "Midnight–3:59 a.m.",
            heat: 482
          },
          {
            x: "Tuesday",
            y: "4:00–7:59 a.m.",
            heat: 641
          },
          {
            x: "Tuesday",
            y: "8:00–11:59 a.m.",
            heat: 631
          },
          {
            x: "Tuesday",
            y: "Noon–3:59 p.m.",
            heat: 905
          },
          {
            x: "Tuesday",
            y: "4:00–7:59 p.m.",
            heat: 1137
          },
          {
            x: "Tuesday",
            y: "8:00–11:59 p.m.",
            heat: 986
          },
          {
            x: "Wednesday",
            y: "Midnight–3:59 a.m.",
            heat: 465
          },
          {
            x: "Wednesday",
            y: "4:00–7:59 a.m.",
            heat: 616
          },
          {
            x: "Wednesday",
            y: "8:00–11:59 a.m.",
            heat: 627
          },
          {
            x: "Wednesday",
            y: "Noon–3:59 p.m.",
            heat: 914
          },
          {
            x: "Wednesday",
            y: "4:00–7:59 p.m.",
            heat: 1159
          },
          {
            x: "Wednesday",
            y: "8:00–11:59 p.m.",
            heat: 1066
          },
          {
            x: "Thursday",
            y: "Midnight–3:59 a.m.",
            heat: 584
          },
          {
            x: "Thursday",
            y: "4:00–7:59 a.m.",
            heat: 718
          },
          {
            x: "Thursday",
            y: "8:00–11:59 a.m.",
            heat: 660
          },
          {
            x: "Thursday",
            y: "Noon–3:59 p.m.",
            heat: 966
          },
          {
            x: "Thursday",
            y: "4:00–7:59 p.m.",
            heat: 1161
          },
          {
            x: "Thursday",
            y: "8:00–11:59 p.m.",
            heat: 1186
          },
          {
            x: "Friday",
            y: "Midnight–3:59 a.m.",
            heat: 715
          },
          {
            x: "Friday",
            y: "4:00–7:59 a.m.",
            heat: 747
          },
          {
            x: "Friday",
            y: "8:00–11:59 a.m.",
            heat: 738
          },
          {
            x: "Friday",
            y: "Noon–3:59 p.m.",
            heat: 1056
          },
          {
            x: "Friday",
            y: "4:00–7:59 p.m.",
            heat: 1426
          },
          {
            x: "Friday",
            y: "8:00–11:59 p.m.",
            heat: 1631
          },
          {
            x: "Saturday",
            y: "Midnight–3:59 a.m.",
            heat: 1383
          },
          {
            x: "Saturday",
            y: "4:00–7:59 a.m.",
            heat: 641
          },
          {
            x: "Saturday",
            y: "8:00–11:59 a.m.",
            heat: 635
          },
          {
            x: "Saturday",
            y: "Noon–3:59 p.m.",
            heat: 1034
          },
          {
            x: "Saturday",
            y: "4:00–7:59 p.m.",
            heat: 1400
          },
          {
            x: "Saturday",
            y: "8:00–11:59 p.m.",
            heat: 1593
          },
          {
            x: "Sunday",
            y: "Midnight–3:59 a.m.",
            heat: 1486
          },
          {
            x: "Sunday",
            y: "4:00–7:59 a.m.",
            heat: 695
          },
          {
            x: "Sunday",
            y: "8:00–11:59 a.m.",
            heat: 564
          },
          {
            x: "Sunday",
            y: "Noon–3:59 p.m.",
            heat: 932
          },
          {
            x: "Sunday",
            y: "4:00–7:59 p.m.",
            heat: 1292
          },
          {
            x: "Sunday",
            y: "8:00–11:59 p.m.",
            heat: 1211
          }
        ];
      }
    </script>
  </body>
</html>

This heatmap is both visually appealing and informative. Upon examining the chart, it becomes clear that there are certain times when the number of accidents is significantly higher. It is unsurprising to see that these peak times are during weekends and the darker hours of the day.

But there's a lot more we can do with our heatmap...

How to Customize a JS Heatmap

As we saw, having the basic chart ready was really simple and fast. But there is so much more we can do to enhance the heatmap. It's not so difficult, either.

How to Change the Color Palette

We can use a diverging colour palette to make our JavaScript heatmap more effective in highlighting the data. This type of color scheme helps to emphasize the difference between high and low values, with less being good and more being alarming.

We can define four colors and value ranges using an ordinal color scale and then set the chart colors to use that color scale. This way, we can create a heatmap that quickly draws the viewer's attention to the most significant data points.

Here's the code to do that:

let colorScale = anychart.scales.ordinalColor();
colorScale.ranges([
  { less: 500, color: "#B0D8A4" },
  { from: 500, to: 900, color: "#FEE191" },
  { from: 900, to: 1300, color: "#FD8060" },
  { greater: 1300, color: "#CC333F" }
]);
chart.colorScale(colorScale);

And here's the result:

heatmapchart-002

How to Modify the Hover Styling

When we change the color palette of our heatmap, we also need to modify the hover colors to match the base colors. This is simple to achieve with the color.darken function.

We can set the chart settings and hover chart settings to ensure that the hover colors match the base colors. This allows us to create a visually consistent and easy-to-read heatmap, making it more effective in communicating the underlying data.

chart
  .hovered()
  .fill(function () {
    return anychart.color.darken(this.sourceColor, 0.25);
  });

heatmapchart-003

How to Change the Labels

By default, the labels on our heatmap show the actual numbers. But we can customize the labels to provide greater flexibility and make the chart easier to read.

We can enable HTML for the labels to allow for greater formatting options. Then, we can configure the labels to display as 'low' to 'extreme' based on the value of the tile. We can also make the 'high' and 'extreme' values appear in bold to make them stand out.

// enable html for the labels
chart.labels().useHtml(true);

// configure the labels
chart.labels().format(function () {
  var heat = this.heat;
  if (heat < 500) return "Low";
  if (heat < 1000) return "Medium";
  if (heat < 1500) return "<span style='font-weight:bold'>High</span>";
  if (heat >= 1500) return "<span style='font-weight:bold'>Extreme</span>";
});

heatmapchart-004

In the final version, I decided to ultimately remove the labels since the colors are quite indicative of the values.

How to Format the Title and Tooltip

Now it's time to make our JS heatmap visualization even more exciting with some formatting tweaks.

First, we'll enable HTML for the tooltip, so we can customize it with some eye-catching formatting. We'll display the number of accidents in the heading and the day as well as the timing in the body of the tooltip. This will add more context and help the user to better understand the data.

chart.tooltip().title().useHtml(true);
chart
  .tooltip()
  .useHtml(true)
  .titleFormat(function () {
    return "Accidents - " + this.heat;
  })
  .format(function () {
    return (
      '<span style="color: #CECECE">Day: </span>' +
      this.x +
      "<br/>" +
      '<span style="color: #CECECE">Time: </span>' +
      this.y
    );
  });

Let’s also add a bit of padding under the main title to make it more spaced out and visually appealing:

chart
  .title()
  .enabled(true)
  .text("Fatal Car Crashes in U.S. in 2021 by Time of Day and Day of Week")
  .padding([0, 0, 20, 0]);	

Here's what those modifcations look like:

heatmapchart-005

How to Modify the Axes

For better readability, we can add padding between the axes labels and the chart tiles and remove the axes lines since the tiles form a boundary by themselves.

chart.xAxis().stroke(null);
chart.yAxis().stroke(null);
chart.yAxis().labels().padding([0, 10, 0, 0]);
chart.xAxis().labels().padding([0, 0, 10, 0]);

And there you have it! With just a few aesthetic changes, we've transformed a simple heatmap into a stunning visualization that really drives home a powerful message. You can check it out below with the full source code, and you can take a closer look at the interactive version of the heatmap and play with the code live here.

heatmapchart-006-1

<html>
  <head>
    <title>Heatmap in JavaScript</title>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-core.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-heatmap.min.js"></script> 
    <style type="text/css">      
      html, body, #container { 
        width: 100%; margin: 0; padding: 0; 
      } 
    </style>
  </head>
  <body>  
    <div id="container"></div>
    <script>
      anychart.onDocumentReady(function () {
        // create a heatmap
        var chart = anychart.heatMap(getData());
        // set a custom color scale
        var colorScale = anychart.scales.ordinalColor();
        colorScale.ranges([
          { less: 500, color: "#B0D8A4" },
          { from: 500, to: 900, color: "#FEE191" },
          { from: 900, to: 1300, color: "#FD8060" },
          { greater: 1300, color: "#CC333F" }
        ]);
        chart.colorScale(colorScale);
        // style the coloring in the hovered state
        chart
          .hovered()
          .fill(function () {
            return anychart.color.darken(this.sourceColor, 0.25);
          });
        // hide the labels
        chart.labels(false);
        // customize the axes
        chart.xAxis().stroke(null);
        chart.yAxis().stroke(null);
        chart.yAxis().labels().padding([0, 10, 0, 0]);
        chart.xAxis().labels().padding([0, 0, 10, 0]);
        // set the tooltip
        chart.tooltip().title().useHtml(true);
        chart
          .tooltip()
          .useHtml(true)
          .titleFormat(function () {
            return "Accidents - " + this.heat;
          })
          .format(function () {
            return (
              '<span style="color: #CECECE">Day: </span>' +
              this.x +
              "<br/>" +
              '<span style="color: #CECECE">Time: </span>' +
              this.y
            );
          });
        // name the heatmap
        chart
          .title()
          .enabled(true)
          .text("Fatal Car Crashes in U.S. in 2021 by Time of Day and Day of Week")
          .padding([0, 0, 20, 0]);
        // set the container for the heatmap
        chart.container("container");
        // draw the heatmap
        chart.draw();
      });
      // add the data
      function getData() {
        return [
          {
            x: "Monday",
            y: "Midnight–3:59 a.m.",
            heat: 705
          },
          {
            x: "Monday",
            y: "4:00–7:59 a.m.",
            heat: 713
          },
          {
            x: "Monday",
            y: "8:00–11:59 a.m.",
            heat: 657
          },
          {
            x: "Monday",
            y: "Noon–3:59 p.m.",
            heat: 957
          },
          {
            x: "Monday",
            y: "4:00–7:59 p.m.",
            heat: 1137
          },
          {
            x: "Monday",
            y: "8:00–11:59 p.m.",
            heat: 956
          },
          {
            x: "Tuesday",
            y: "Midnight–3:59 a.m.",
            heat: 482
          },
          {
            x: "Tuesday",
            y: "4:00–7:59 a.m.",
            heat: 641
          },
          {
            x: "Tuesday",
            y: "8:00–11:59 a.m.",
            heat: 631
          },
          {
            x: "Tuesday",
            y: "Noon–3:59 p.m.",
            heat: 905
          },
          {
            x: "Tuesday",
            y: "4:00–7:59 p.m.",
            heat: 1137
          },
          {
            x: "Tuesday",
            y: "8:00–11:59 p.m.",
            heat: 986
          },
          {
            x: "Wednesday",
            y: "Midnight–3:59 a.m.",
            heat: 465
          },
          {
            x: "Wednesday",
            y: "4:00–7:59 a.m.",
            heat: 616
          },
          {
            x: "Wednesday",
            y: "8:00–11:59 a.m.",
            heat: 627
          },
          {
            x: "Wednesday",
            y: "Noon–3:59 p.m.",
            heat: 914
          },
          {
            x: "Wednesday",
            y: "4:00–7:59 p.m.",
            heat: 1159
          },
          {
            x: "Wednesday",
            y: "8:00–11:59 p.m.",
            heat: 1066
          },
          {
            x: "Thursday",
            y: "Midnight–3:59 a.m.",
            heat: 584
          },
          {
            x: "Thursday",
            y: "4:00–7:59 a.m.",
            heat: 718
          },
          {
            x: "Thursday",
            y: "8:00–11:59 a.m.",
            heat: 660
          },
          {
            x: "Thursday",
            y: "Noon–3:59 p.m.",
            heat: 966
          },
          {
            x: "Thursday",
            y: "4:00–7:59 p.m.",
            heat: 1161
          },
          {
            x: "Thursday",
            y: "8:00–11:59 p.m.",
            heat: 1186
          },
          {
            x: "Friday",
            y: "Midnight–3:59 a.m.",
            heat: 715
          },
          {
            x: "Friday",
            y: "4:00–7:59 a.m.",
            heat: 747
          },
          {
            x: "Friday",
            y: "8:00–11:59 a.m.",
            heat: 738
          },
          {
            x: "Friday",
            y: "Noon–3:59 p.m.",
            heat: 1056
          },
          {
            x: "Friday",
            y: "4:00–7:59 p.m.",
            heat: 1426
          },
          {
            x: "Friday",
            y: "8:00–11:59 p.m.",
            heat: 1631
          },
          {
            x: "Saturday",
            y: "Midnight–3:59 a.m.",
            heat: 1383
          },
          {
            x: "Saturday",
            y: "4:00–7:59 a.m.",
            heat: 641
          },
          {
            x: "Saturday",
            y: "8:00–11:59 a.m.",
            heat: 635
          },
          {
            x: "Saturday",
            y: "Noon–3:59 p.m.",
            heat: 1034
          },
          {
            x: "Saturday",
            y: "4:00–7:59 p.m.",
            heat: 1400
          },
          {
            x: "Saturday",
            y: "8:00–11:59 p.m.",
            heat: 1593
          },
          {
            x: "Sunday",
            y: "Midnight–3:59 a.m.",
            heat: 1486
          },
          {
            x: "Sunday",
            y: "4:00–7:59 a.m.",
            heat: 695
          },
          {
            x: "Sunday",
            y: "8:00–11:59 a.m.",
            heat: 564
          },
          {
            x: "Sunday",
            y: "Noon–3:59 p.m.",
            heat: 932
          },
          {
            x: "Sunday",
            y: "4:00–7:59 p.m.",
            heat: 1292
          },
          {
            x: "Sunday",
            y: "8:00–11:59 p.m.",
            heat: 1211
          }
        ];
      }
    </script>
  </body>
</html>

Conclusion

In conclusion, data visualization is an incredibly powerful tool that can help us uncover important insights from our data. And with JavaScript, creating beautiful and impactful charts, such as a heatmap, can be a breeze.

So don't be afraid to experiment with different chart types, styles, and libraries to create your own hard-hitting visualizations. And above all, remember to stay safe out there on the roads!

Source: https://www.freecodecamp.org

#javascript 

Cyril  Parisian

Cyril Parisian

1684926180

How to Create a Choropleth Map with JavaScript

In this JavaScript tutorial we will Learn about How to Create a Choropleth Map with JavaScript. Learn to create a choropleth map with JavaScript step by step in this tutorial, with Queen Elizabeth II's state visits as an example of data.

Are you ready to learn how to create a choropleth map with JavaScript like a boss? Maps are a powerful way to visualize data, but building one from scratch can be a daunting task. Don't worry, I'm here to help!

In this tutorial, I'll guide you through the process of building a JavaScript choropleth map step by step. And to make things more interesting, we’ll use Queen Elizabeth II's state visits as an example to showcase the power of this type of map.

Get ready to impress yourself and your audience with stunning data visualizations, and let's get started on this exciting journey together!

What Is a Choropleth Map?

A choropleth map is a type of thematic map that uses color to represent values of a specific quantity within different regions or geopolitical areas. The map is divided into areas or polygons, and the color of each area represents the value of the data being visualized. Typically, darker shades of color indicate higher values, while lighter shades represent lower values.

So, as I mentioned, in this tutorial, we'll be creating a JS-based choropleth map to showcase Queen Elizabeth II's state visits around the world. By using different colors to represent the number of visits in each region, we can easily identify which areas the Queen visited the most frequently. The final interactive choropleth map will look like this:

How To Build a Basic Choropleth Map

Creating a choropleth map with JavaScript may seem challenging, but fear not! There are just four simple steps to follow:

  1. Set up an HTML page to display the map.
  2. Add all the necessary JavaScript files.
  3. Include the data.
  4. Write the required JavaScript code to render the map.

Once you've completed these four steps, you'll have a beautiful choropleth map that accurately represents your data. So, let's dive into each step in more detail and learn how to easily create a stunning JavaScript choropleth map!

1. Set up an HTML Page To Display the Choropleth Map

To start creating the choropleth map, the first step is to set up an HTML page with a div element and give it a unique ID to reference it later.

I’ll set the width and height of the div element to 100% to render the map on the whole page, but you can adjust these values to suit your needs. This div element will be the container for the chart, and the ID will be used to reference it in the JavaScript code. So, let's get started by creating the HTML page for the upcoming choropleth map! 

<html>
  <head>
    <title>JavaScript Choropleth Map</title>
    <style type="text/css">      
      html, body, #container { 
        width: 100%; height: 100%; margin: 0; padding: 0; 
      } 
    </style>
  </head>
  <body>
    <div id="container"></div>
  </body>
</html>

2. Add All the Necessary JavaScript Files

To easily create data visualizations for the web, I use a JavaScript charting library with in-built utilities and functions. With the vast number of such JS libraries available, the process for creating charts and maps is similar in essence and logic across most of them. In this tutorial, I am using the AnyChart JS charting library as it is beginner-friendly, with extensive documentation and plenty of examples to help you get started.

It is needed to link the required JS scripts in the <head> section of the HTML page. These scripts include the Core and Geo Maps modules and the file that contains geodata for the world map, all of which are available on the CDN. I'll also use two more script files to connect the data to the choropleth map. One is the Data Adapter, which will help load the data, and the other is Proj4js, a JavaScript library that will transform the coordinates from one coordinate system to another so the data can be plotted on the map accurately.

<html>
  <head>
    <title>JavaScript Choropleth Map</title>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-base.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-map.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.11.0/geodata/custom/world/world.js"></script>
    <style type="text/css">      
      html, body, #container { 
        width: 100%; height: 100%; margin: 0; padding: 0; 
      } 
    </style>
  </head>
  <body>  
    <div id="container"></div>
    <script>
      // All the code for the JS choropleth map will come here
    </script>
  </body>
</html>

3. Include the Data

Alright, let's get the data loaded up and plotted on the JS choropleth map! First things first, I have collected the data on the state visits made by Queen Elizabeth II from Wikipedia and put it in a JSON file for easy access. You can find it here.

All the necessary files are already linked in the <head> section of the HTML page. So it’s possible to use the loadJsonFile() method inside a <script> tag in the body of the page to load the JSON file containing the Queen's state visits data.

anychart.data.loadJsonFile(<fileURL>, function (data) {});

Great! Now that everything is set up and ready to go, it's time to move on to the main part of the journey: creating the choropleth map visualization! Let's do this!

4. Write the Required JavaScript Code To Render the Map

You can get the choropleth map rendered with just a few lines of JS code. First, make sure that all the code is inside the function anychart.onDocumentReady() so that the page is fully loaded before executing anything else. Once the data file is loaded, set the data, create the map, and set the geodata.

<script>

  anychart.onDocumentReady(function() {

    // load data from a json file
    anychart.data.loadJsonFile('https://gist.githubusercontent.com/shacheeswadia/8f45da54d9bf2032fee201dbfc79e0e4/raw/5d10d58f40b4a1d994cef36dbc64545ef90ead80/queenVisits.json',
    function (data) {
    
      // create a dataset
      let dataSet = anychart.data.set(data);

      // create a map instance
      let map = anychart.map();

      // set the geodata
      map.geoData("anychart.maps.world");

      // the rest of the JS code will be here
	
    });

  });

</script>

Now, create a series with the choropleth() function and the loaded data. For the coloring, let’s set up a linear color scale with four different shades of blue based on the colors on the royal website. As per convention, the darker the shade of a country, the higher the number of visits to that region.

// create a choropleth series
let series = map.choropleth(dataSet);

// set the map colors
series
  .colorScale(
     anychart.scales.linearColor("#f2f2f2", "#42a5f5", "#1976d2", "#233580")
   );

Finally, give a title to the map, set the container, and draw the resulting map.

// set the map title
map.title("State Visits Made by Queen Elizabeth II");

// set the container
map.container('container');

// initiate the map drawing
map.draw();

And voila! A beautiful and functional choropleth map is ready! Check out how it looks. You can find the entire code below or view and play with it here.

Basic Choropleth Map

<html>
  <head>
    <title>JavaScript Choropleth Map</title>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-base.min.js"></script>
    <script data-fr-src="https://cdn.anychart.com/releases/8.11.0/js/anychart-map.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.11.0/geodata/custom/world/world.js"></script>
    <style type="text/css">      
      html, body, #container { 
        width: 100%; height: 100%; margin: 0; padding: 0; 
      } 
    </style>
  </head>
  <body>  
    <div id="container"></div>
    <script>
      anychart.onDocumentReady(function () {
        // load data from a json file
        anychart.data.loadJsonFile(
          "https://gist.githubusercontent.com/shacheeswadia/8f45da54d9bf2032fee201dbfc79e0e4/raw/5d10d58f40b4a1d994cef36dbc64545ef90ead80/queenVisits.json",
          function (data) {
            // create a dataset
            let dataSet = anychart.data.set(data);
            // create a map instance
            let map = anychart.map();
            // set the geodata
            map.geoData("anychart.maps.world");
            // create a choropleth series
            let series = map.choropleth(dataSet);
            // set the map colors
            series
              .colorScale(
                anychart.scales.linearColor("#f2f2f2", "#42a5f5", "#1976d2", "#233580")
              );
            // set the map title
            map.title("State Visits Made by Queen Elizabeth II");
            // set the container
            map.container("container");
            // initiate the map drawing
            map.draw();
          }
        );
      });
    </script>
  </body>
</html>

How to Customize a Choropleth Map

The existing choropleth map is already impressive, but let me show you how to make it even more insightful and engaging! In the following steps, I'll demonstrate how you can customize the choropleth map to add more visual appeal and interactivity:

  1. Modify the colors by hovering over map areas.
  2. Add a color legend.
  3. Improve the tooltip and the title format.
  4. Add zoom controls.

1. Modify the Colors by Hovering Over the Areas

You can make the map more visually appealing by modifying the colors of the hovered regions. By default, hovered regions become gray, but you can change this to a darker shade of the base color to make it more intuitive. This can be achieved by changing the fill color of the region when it is hovered and using the darken() function.

series
  .hovered()
  .fill(function (d) {
    return anychart.color.darken(d.sourceColor, 0.2);
  });

2. Add a Color Legend

Adding a color legend to your choropleth map is always a great idea, as it can help your audience understand the values and colors used in the map.

To add a color legend, you only need to enable the color range. This will automatically create a legend that represents what color indicates what value. By default, the color range is disabled. To enable it, you just need to add a few lines of code:

map.colorRange()
  .enabled(true);

And voila! You now have a beautiful and informative color legend to complement your choropleth map.

3. Improve the Tooltip and Title Format

Let's take the choropleth map to the next level by improving the tooltip and the title format. Tooltips are a powerful way to showcase additional information, and they can be made even better by enabling HTML for customizing the tooltip and formatting the value.

I thought it would be nice to add a custom text and indicate how many times the Queen visited the hovered country. Additionally, the specific case of the United Kingdom can be handled to showcase that the Queen lived there.

With these changes, the tooltip is not only more informative but also more visually appealing. The users will enjoy the playful tone of the tooltip while learning interesting facts about the Queen's travels.

map
  .title()
  .enabled(true)
  .useHtml(true)
  .text(
    '<span style="color: #c8102e; font-size:18px;">State visits made by Queen Elizabeth II</span>' +
      <span style="font-size: 15px;">(The Queen is the most widely travelled head of state in history)</span>'
  );

In addition to customizing the tooltip, why not enhance the chart title using HTML? For example, a subtitle will provide more context, and custom text styling will make it all shine.

series
  .tooltip() 
  .useHtml(true)
  .format(function (d) {
    if (d.name == "United Kingdom") {
      return "<h6 style='font-size:14px; font-weight:400; margin: 0.2rem 0;'>The Queen lived here.</h6>";
    } else {
      return (
        "<h6 style='font-size:14px; font-weight:400; margin: 0.2rem 0;'>The Queen visited <b>" +
          d.value + "</b> times.</h6>"
      );
    }
  });

4. Add Zoom Controls

Adding zoom controls to a world map can be a great way to allow users to zoom into specific areas of interest. To get started, add the required scripts and CSS links to your HTML document's <head> section. Once you have done this, you can create the zoom controls and render them on the map with just a few lines of code. 

<script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-exports.min.js"></script>
<script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-ui.min.js"></script>

<link rel="stylesheet" type="text/css" href="https://cdn.anychart.com/releases/8.11.0/css/anychart-ui.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.anychart.com/releases/8.11.0/fonts/css/anychart-font.min.css">
var zoomController = anychart.ui.zoom();
zoomController.render(map);

It's worth noting that the zoom feature can be particularly useful when working with large and detailed choropleth maps. In this case, it can be a great way to allow users to explore specific regions or areas of interest in more detail.

And now, just sit back and admire your beautiful JavaScript choropleth map! With the addition of customized colors, a color legend, improved tooltips and titles, and zoom controls, it’s an interactive and engaging visualization that is sure to impress. See the complete code for this project below, and feel free to play with it and see the choropleth map’s full interactive version live here.

Choropleth Map Final

<html>
  <head>
    <title>JavaScript Choropleth Map</title>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-base.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-map.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.11.0/geodata/custom/world/world.js"></script>
    <style type="text/css">      
      html, body, #container { 
        width: 100%; height: 100%; margin: 0; padding: 0; 
      } 
    </style>
  </head>
  <body>  
    <div id="container"></div>
    <script>
      anychart.onDocumentReady(function () {
        // load data from a json file
        anychart.data.loadJsonFile(
          "https://gist.githubusercontent.com/shacheeswadia/8f45da54d9bf2032fee201dbfc79e0e4/raw/5d10d58f40b4a1d994cef36dbc64545ef90ead80/queenVisits.json",
          function (data) {
            // create a dataset
            let dataSet = anychart.data.set(data);
            // create a map instance
            let map = anychart.map();
            // set the geodata
            map.geoData("anychart.maps.world");
            // create a choropleth series
            let series = map.choropleth(dataSet);
            // set the map colors
            series.colorScale(
              anychart.scales.linearColor("#f2f2f2", "#42a5f5", "#1976d2", "#233580")
            );
            // customize the colors in the hovered state
            series.hovered().fill(function (d) {
              return anychart.color.darken(d.sourceColor, 0.2);
            });
            // create the map legend
            map.colorRange().enabled(true);
            // create zoom controls
            let zoomController = anychart.ui.zoom();
            zoomController.render(map);
            // customize the tooltip text
            series
              .tooltip()
              .useHtml(true)
              .format(function (d) {
                if (d.name == "United Kingdom") {
                  return "<h6 style='font-size:14px; font-weight:400; margin: 0.2rem 0;'>The Queen lived here.</h6>";
                } else {
                  return (
                    "<h6 style='font-size:14px; font-weight:400; margin: 0.2rem 0;'>The Queen visited <b>" +
                    d.value +
                    "</b> times.</h6>"
                  );
                }
              });
            // set the map title
            map
              .title()
              .enabled(true)
              .useHtml(true)
              .text(
                '<span style = "color: #c8102e; font-size:18px;">State Visits Made by Queen Elizabeth II</span>' +
                  '<br/><span style="font-size: 15px;">The Queen is the most widely traveled head of state in history</span>'
              );
            // set the container
            map.container("container");
            // initiate the map drawing
            map.draw();
          }
        );
      });
    </script>
  </body>
</html>

Conclusion

Сhoropleth maps are a powerful tool for visualizing data on a geographic scale. Using JavaScript, you can create stunning interactive ones that communicate complex information in a clear and concise manner.

Whether you're tracking the travels of a monarch or visualizing the spread of a pandemic, the possibilities are endless. So, let your imagination run wild and start exploring the world through the lens of data!

Article source: https://dzone.com

#javascript 

Mélanie  Faria

Mélanie Faria

1684958580

Como criar um mapa coroplético com JavaScript

Neste tutorial de JavaScript, aprenderemos como criar um mapa coroplético com JavaScript. Aprenda a criar um mapa coroplético com JavaScript passo a passo neste tutorial, com as visitas de estado da Rainha Elizabeth II como exemplo de dados.

Você está pronto para aprender a criar um mapa coroplético com JavaScript como um chefe? Os mapas são uma maneira poderosa de visualizar dados, mas criar um do zero pode ser uma tarefa assustadora. Não se preocupe, estou aqui para ajudar!

Neste tutorial, guiarei você passo a passo pelo processo de construção de um mapa coroplético em JavaScript. E para tornar as coisas mais interessantes, usaremos as visitas de Estado da Rainha Elizabeth II como exemplo para mostrar o poder desse tipo de mapa.

Prepare-se para impressionar a si mesmo e ao seu público com visualizações de dados impressionantes e vamos começar juntos nessa emocionante jornada!

O que é um mapa coroplético?

Um mapa coroplético é um tipo de mapa temático que usa cores para representar valores de uma quantidade específica em diferentes regiões ou áreas geopolíticas. O mapa é dividido em áreas ou polígonos, e a cor de cada área representa o valor dos dados que estão sendo visualizados. Normalmente, tons mais escuros de cor indicam valores mais altos, enquanto tons mais claros representam valores mais baixos.

Portanto, como mencionei, neste tutorial, criaremos um mapa coroplético baseado em JS para mostrar as visitas de Estado da Rainha Elizabeth II ao redor do mundo. Ao usar cores diferentes para representar o número de visitas em cada região, podemos identificar facilmente quais áreas a Rainha visitou com mais frequência. O mapa coroplético interativo final ficará assim:

Como construir um mapa coroplético básico

Criar um mapa coroplético com JavaScript pode parecer desafiador, mas não tema! Existem apenas quatro passos simples a seguir:

  1. Configure uma página HTML para exibir o mapa.
  2. Adicione todos os arquivos JavaScript necessários.
  3. Incluir os dados.
  4. Escreva o código JavaScript necessário para renderizar o mapa.

Depois de concluir essas quatro etapas, você terá um belo mapa coroplético que representa com precisão seus dados. Então, vamos mergulhar em cada etapa com mais detalhes e aprender como criar facilmente um impressionante mapa coroplético em JavaScript!

1. Configure uma página HTML para exibir o mapa coroplético

Para começar a criar o mapa coroplético, o primeiro passo é configurar uma página HTML com um divelemento e dar a ele um ID exclusivo para referenciá-lo posteriormente.

Definirei a largura e a altura do divelemento como 100% para renderizar o mapa na página inteira, mas você pode ajustar esses valores para atender às suas necessidades. Esse divelemento será o contêiner do gráfico e o ID será usado para fazer referência a ele no código JavaScript. Então, vamos começar criando a página HTML para o próximo mapa coroplético! 

<html>
  <head>
    <title>JavaScript Choropleth Map</title>
    <style type="text/css">      
      html, body, #container { 
        width: 100%; height: 100%; margin: 0; padding: 0; 
      } 
    </style>
  </head>
  <body>
    <div id="container"></div>
  </body>
</html>

2. Adicione todos os arquivos JavaScript necessários

Para criar facilmente visualizações de dados para a Web, uso uma biblioteca de gráficos JavaScript com funções e utilitários integrados. Com o grande número de tais bibliotecas JS disponíveis, o processo de criação de gráficos e mapas é semelhante em essência e lógica na maioria deles. Neste tutorial, estou usando a biblioteca de gráficos AnyChart JS, pois é amigável para iniciantes, com extensa documentação e muitos exemplos para ajudá-lo a começar.

É necessário vincular os scripts JS necessários na <head>seção da página HTML. Esses scripts incluem os módulos Core e Geo Maps e o arquivo que contém dados geográficos para o mapa-múndi, todos disponíveis no CDN. Também usarei mais dois arquivos de script para conectar os dados ao mapa coroplético. Um é o Data Adapter, que ajudará a carregar os dados, e o outro é o Proj4js , uma biblioteca JavaScript que transformará as coordenadas de um sistema de coordenadas em outro para que os dados possam ser plotados no mapa com precisão.

<html>
  <head>
    <title>JavaScript Choropleth Map</title>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-base.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-map.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.11.0/geodata/custom/world/world.js"></script>
    <style type="text/css">      
      html, body, #container { 
        width: 100%; height: 100%; margin: 0; padding: 0; 
      } 
    </style>
  </head>
  <body>  
    <div id="container"></div>
    <script>
      // All the code for the JS choropleth map will come here
    </script>
  </body>
</html>

3. Inclua os dados

Tudo bem, vamos carregar os dados e plotá-los no mapa coroplético JS! Em primeiro lugar, coletei os dados sobre as visitas de estado feitas pela rainha Elizabeth II da Wikipedia e os coloquei em um arquivo JSON para facilitar o acesso. Você pode encontrá-lo aqui .

Todos os arquivos necessários já estão vinculados na <head>seção da página HTML. Assim é possível usar o loadJsonFile()método dentro de uma <script>tag no corpo da página para carregar o arquivo JSON contendo os dados das visitas de estado da Rainha.

anychart.data.loadJsonFile(<fileURL>, function (data) {});

Ótimo! Agora que tudo está configurado e pronto, é hora de passar para a parte principal da jornada: criar a visualização do mapa coroplético! Vamos fazer isso!

4. Escreva o código JavaScript necessário para renderizar o mapa

Você pode obter o mapa coroplético renderizado com apenas algumas linhas de código JS. Primeiro, certifique-se de que todo o código esteja dentro da função anychart.onDocumentReady()para que a página seja totalmente carregada antes de executar qualquer outra coisa. Depois que o arquivo de dados for carregado, defina os dados, crie o mapa e defina os dados geográficos.

<script>

  anychart.onDocumentReady(function() {

    // load data from a json file
    anychart.data.loadJsonFile('https://gist.githubusercontent.com/shacheeswadia/8f45da54d9bf2032fee201dbfc79e0e4/raw/5d10d58f40b4a1d994cef36dbc64545ef90ead80/queenVisits.json',
    function (data) {
    
      // create a dataset
      let dataSet = anychart.data.set(data);

      // create a map instance
      let map = anychart.map();

      // set the geodata
      map.geoData("anychart.maps.world");

      // the rest of the JS code will be here
	
    });

  });

</script>

Agora, crie uma série com a choropleth()função e os dados carregados. Para a coloração, vamos configurar uma escala de cores linear com quatro tons diferentes de azul com base nas cores do site real. De acordo com a convenção, quanto mais escuro o tom de um país, maior o número de visitas a essa região.

// create a choropleth series
let series = map.choropleth(dataSet);

// set the map colors
series
  .colorScale(
     anychart.scales.linearColor("#f2f2f2", "#42a5f5", "#1976d2", "#233580")
   );

Por fim, dê um título ao mapa, defina o contêiner e desenhe o mapa resultante.

// set the map title
map.title("State Visits Made by Queen Elizabeth II");

// set the container
map.container('container');

// initiate the map drawing
map.draw();

E voilá! Um mapa coroplético bonito e funcional está pronto! Confira como fica. Você pode encontrar o código completo abaixo ou ver e brincar com ele aqui .

Mapa Coroplétrico Básico

<html>
  <head>
    <title>JavaScript Choropleth Map</title>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-base.min.js"></script>
    <script data-fr-src="https://cdn.anychart.com/releases/8.11.0/js/anychart-map.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.11.0/geodata/custom/world/world.js"></script>
    <style type="text/css">      
      html, body, #container { 
        width: 100%; height: 100%; margin: 0; padding: 0; 
      } 
    </style>
  </head>
  <body>  
    <div id="container"></div>
    <script>
      anychart.onDocumentReady(function () {
        // load data from a json file
        anychart.data.loadJsonFile(
          "https://gist.githubusercontent.com/shacheeswadia/8f45da54d9bf2032fee201dbfc79e0e4/raw/5d10d58f40b4a1d994cef36dbc64545ef90ead80/queenVisits.json",
          function (data) {
            // create a dataset
            let dataSet = anychart.data.set(data);
            // create a map instance
            let map = anychart.map();
            // set the geodata
            map.geoData("anychart.maps.world");
            // create a choropleth series
            let series = map.choropleth(dataSet);
            // set the map colors
            series
              .colorScale(
                anychart.scales.linearColor("#f2f2f2", "#42a5f5", "#1976d2", "#233580")
              );
            // set the map title
            map.title("State Visits Made by Queen Elizabeth II");
            // set the container
            map.container("container");
            // initiate the map drawing
            map.draw();
          }
        );
      });
    </script>
  </body>
</html>

Como personalizar um mapa coroplético

O mapa coroplético existente já é impressionante, mas deixe-me mostrar como torná-lo ainda mais perspicaz e envolvente! Nas etapas a seguir, demonstrarei como você pode personalizar o mapa coroplético para adicionar mais apelo visual e interatividade:

  1. Modifique as cores passando o mouse sobre as áreas do mapa.
  2. Adicione uma legenda de cor.
  3. Melhore a dica de ferramenta e o formato do título.
  4. Adicione controles de zoom.

1. Modifique as cores passando o mouse sobre as áreas

Você pode tornar o mapa visualmente mais atraente modificando as cores das regiões sobrevoadas. Por padrão, as regiões sobrevoadas ficam cinza, mas você pode alterar isso para um tom mais escuro da cor base para torná-lo mais intuitivo. Isso pode ser obtido alterando a cor de preenchimento da região ao passar o mouse sobre ela e usando a darken()função.

series
  .hovered()
  .fill(function (d) {
    return anychart.color.darken(d.sourceColor, 0.2);
  });

2. Adicione uma legenda de cor

Adicionar uma legenda de cores ao seu mapa coroplético é sempre uma ótima ideia, pois pode ajudar seu público a entender os valores e cores usados ​​no mapa.

Para adicionar uma legenda de cores, você só precisa ativar o intervalo de cores. Isso criará automaticamente uma legenda que representa qual cor indica qual valor. Por padrão, o intervalo de cores está desativado. Para ativá-lo, basta adicionar algumas linhas de código:

map.colorRange()
  .enabled(true);

E voilá! Agora você tem uma bela e informativa legenda de cores para complementar seu mapa coroplético.

3. Melhore a dica de ferramenta e o formato do título

Vamos levar o mapa coroplético para o próximo nível, melhorando a dica de ferramenta e o formato do título. As dicas de ferramentas são uma maneira poderosa de mostrar informações adicionais e podem ser ainda melhores habilitando o HTML para personalizar a dica de ferramenta e formatar o valor.

Achei que seria bom adicionar um texto personalizado e indicar quantas vezes a Rainha visitou o país pairado. Além disso, o caso específico do Reino Unido pode ser tratado para mostrar que a rainha viveu lá.

Com essas mudanças, a dica de ferramenta não é apenas mais informativa, mas também visualmente mais atraente. Os usuários apreciarão o tom lúdico da dica de ferramenta enquanto aprendem fatos interessantes sobre as viagens da Rainha.

map
  .title()
  .enabled(true)
  .useHtml(true)
  .text(
    '<span style="color: #c8102e; font-size:18px;">State visits made by Queen Elizabeth II</span>' +
      <span style="font-size: 15px;">(The Queen is the most widely travelled head of state in history)</span>'
  );

Além de personalizar a dica de ferramenta, por que não aprimorar o título do gráfico usando HTML? Por exemplo, uma legenda fornecerá mais contexto e um estilo de texto personalizado fará com que tudo se destaque.

series
  .tooltip() 
  .useHtml(true)
  .format(function (d) {
    if (d.name == "United Kingdom") {
      return "<h6 style='font-size:14px; font-weight:400; margin: 0.2rem 0;'>The Queen lived here.</h6>";
    } else {
      return (
        "<h6 style='font-size:14px; font-weight:400; margin: 0.2rem 0;'>The Queen visited <b>" +
          d.value + "</b> times.</h6>"
      );
    }
  });

4. Adicionar controles de zoom

Adicionar controles de zoom a um mapa-múndi pode ser uma ótima maneira de permitir que os usuários aumentem o zoom em áreas específicas de interesse. Para começar, adicione os scripts necessários e os links CSS à <head>seção do seu documento HTML. Depois de fazer isso, você pode criar os controles de zoom e renderizá-los no mapa com apenas algumas linhas de código. 

<script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-exports.min.js"></script>
<script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-ui.min.js"></script>

<link rel="stylesheet" type="text/css" href="https://cdn.anychart.com/releases/8.11.0/css/anychart-ui.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.anychart.com/releases/8.11.0/fonts/css/anychart-font.min.css">
var zoomController = anychart.ui.zoom();
zoomController.render(map);

Vale a pena notar que o recurso de zoom pode ser particularmente útil ao trabalhar com mapas coropléticos grandes e detalhados. Nesse caso, pode ser uma ótima maneira de permitir que os usuários explorem regiões específicas ou áreas de interesse com mais detalhes.

E agora, sente-se e admire seu belo mapa coroplético JavaScript! Com a adição de cores personalizadas, uma legenda de cores, dicas de ferramentas e títulos aprimorados e controles de zoom, é uma visualização interativa e envolvente que certamente impressionará. Veja o código completo deste projeto abaixo e sinta-se à vontade para brincar com ele e ver a versão interativa completa do mapa coroplético ao vivo aqui .

Final do mapa coroplético

<html>
  <head>
    <title>JavaScript Choropleth Map</title>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-base.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-map.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.11.0/geodata/custom/world/world.js"></script>
    <style type="text/css">      
      html, body, #container { 
        width: 100%; height: 100%; margin: 0; padding: 0; 
      } 
    </style>
  </head>
  <body>  
    <div id="container"></div>
    <script>
      anychart.onDocumentReady(function () {
        // load data from a json file
        anychart.data.loadJsonFile(
          "https://gist.githubusercontent.com/shacheeswadia/8f45da54d9bf2032fee201dbfc79e0e4/raw/5d10d58f40b4a1d994cef36dbc64545ef90ead80/queenVisits.json",
          function (data) {
            // create a dataset
            let dataSet = anychart.data.set(data);
            // create a map instance
            let map = anychart.map();
            // set the geodata
            map.geoData("anychart.maps.world");
            // create a choropleth series
            let series = map.choropleth(dataSet);
            // set the map colors
            series.colorScale(
              anychart.scales.linearColor("#f2f2f2", "#42a5f5", "#1976d2", "#233580")
            );
            // customize the colors in the hovered state
            series.hovered().fill(function (d) {
              return anychart.color.darken(d.sourceColor, 0.2);
            });
            // create the map legend
            map.colorRange().enabled(true);
            // create zoom controls
            let zoomController = anychart.ui.zoom();
            zoomController.render(map);
            // customize the tooltip text
            series
              .tooltip()
              .useHtml(true)
              .format(function (d) {
                if (d.name == "United Kingdom") {
                  return "<h6 style='font-size:14px; font-weight:400; margin: 0.2rem 0;'>The Queen lived here.</h6>";
                } else {
                  return (
                    "<h6 style='font-size:14px; font-weight:400; margin: 0.2rem 0;'>The Queen visited <b>" +
                    d.value +
                    "</b> times.</h6>"
                  );
                }
              });
            // set the map title
            map
              .title()
              .enabled(true)
              .useHtml(true)
              .text(
                '<span style = "color: #c8102e; font-size:18px;">State Visits Made by Queen Elizabeth II</span>' +
                  '<br/><span style="font-size: 15px;">The Queen is the most widely traveled head of state in history</span>'
              );
            // set the container
            map.container("container");
            // initiate the map drawing
            map.draw();
          }
        );
      });
    </script>
  </body>
</html>

Conclusão

Os mapas Сhoropleth são uma ferramenta poderosa para visualizar dados em escala geográfica. Usando JavaScript, você pode criar impressionantes interativos que comunicam informações complexas de maneira clara e concisa.

Esteja você acompanhando as viagens de um monarca ou visualizando a propagação de uma pandemia, as possibilidades são infinitas. Então, deixe sua imaginação correr solta e comece a explorar o mundo através das lentes dos dados!

Fonte do artigo: https://dzone.com

#javascript 

Как создать картографическую карту с помощью JavaScript

В этом уроке по JavaScript мы узнаем, как создать картограмму с помощью JavaScript. В этом руководстве вы научитесь шаг за шагом создавать картограмму с помощью JavaScript, используя в качестве примера данные о государственных визитах королевы Елизаветы II.

Готовы ли вы научиться создавать картограмму с помощью JavaScript, как босс? Карты — это мощный способ визуализации данных, но создание карты с нуля может оказаться непростой задачей. Не волнуйтесь, я здесь, чтобы помочь!

В этом уроке я шаг за шагом проведу вас через процесс создания картограммы JavaScript. И чтобы сделать вещи более интересными, мы будем использовать государственные визиты королевы Елизаветы II в качестве примера, чтобы продемонстрировать силу этого типа карты.

Приготовьтесь произвести впечатление на себя и свою аудиторию потрясающими визуализациями данных, и давайте начнем это увлекательное путешествие вместе!

Что такое картограмма?

Картограмма — это тип тематической карты, в которой цвет используется для представления значений определенной величины в разных регионах или геополитических областях. Карта разделена на области или полигоны, и цвет каждой области представляет значение визуализируемых данных. Как правило, более темные оттенки цвета указывают на более высокие значения, а более светлые оттенки — на более низкие значения.

Итак, как я уже упоминал, в этом уроке мы создадим картограмму на основе JS, чтобы продемонстрировать государственные визиты королевы Елизаветы II по всему миру. Используя разные цвета для обозначения количества посещений в каждом регионе, мы можем легко определить, какие районы посещала королева чаще всего. Окончательная интерактивная картограмма будет выглядеть так:

Как построить базовую картограмму

Создание картограммы с помощью JavaScript может показаться сложной задачей, но не бойтесь! Всего четыре простых шага:

  1. Настройте HTML-страницу для отображения карты.
  2. Добавьте все необходимые файлы JavaScript.
  3. Включите данные.
  4. Напишите необходимый код JavaScript для визуализации карты.

После того, как вы выполните эти четыре шага, у вас будет красивая картограмма, которая точно представляет ваши данные. Итак, давайте углубимся в каждый шаг более подробно и узнаем, как легко создать потрясающую карту JavaScript!

1. Настройте HTML-страницу для отображения картограммы

Чтобы приступить к созданию картограммы, первым шагом является настройка HTML-страницы с divэлементом и присвоение ему уникального идентификатора для ссылки на него позже.

Я установлю ширину и высоту элемента divна 100%, чтобы отобразить карту на всей странице, но вы можете настроить эти значения в соответствии со своими потребностями. Этот divэлемент будет контейнером для диаграммы, а идентификатор будет использоваться для ссылки на него в коде JavaScript. Итак, давайте начнем с создания HTML-страницы для предстоящей картограммы! 

<html>
  <head>
    <title>JavaScript Choropleth Map</title>
    <style type="text/css">      
      html, body, #container { 
        width: 100%; height: 100%; margin: 0; padding: 0; 
      } 
    </style>
  </head>
  <body>
    <div id="container"></div>
  </body>
</html>

2. Добавьте все необходимые файлы JavaScript

Чтобы легко создавать визуализации данных для Интернета, я использую библиотеку диаграмм JavaScript со встроенными утилитами и функциями. При наличии огромного количества таких JS-библиотек процесс создания диаграмм и карт схож по сути и логике в большинстве из них. В этом руководстве я использую библиотеку диаграмм AnyChart JS, поскольку она удобна для начинающих, содержит обширную документацию и множество примеров, которые помогут вам начать работу.

Он нужен для того, чтобы связать необходимые JS-скрипты в <head>разделе HTML-страницы. Эти сценарии включают в себя модули Core и Geo Maps, а также файл, содержащий геоданные для карты мира, все они доступны в CDN. Я также буду использовать еще два файла сценария для подключения данных к картограмме. Одним из них является адаптер данных, который поможет загрузить данные, а другим — Proj4js , библиотека JavaScript, которая преобразует координаты из одной системы координат в другую, чтобы данные можно было точно нанести на карту.

<html>
  <head>
    <title>JavaScript Choropleth Map</title>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-base.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-map.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.11.0/geodata/custom/world/world.js"></script>
    <style type="text/css">      
      html, body, #container { 
        width: 100%; height: 100%; margin: 0; padding: 0; 
      } 
    </style>
  </head>
  <body>  
    <div id="container"></div>
    <script>
      // All the code for the JS choropleth map will come here
    </script>
  </body>
</html>

3. Включите данные

Хорошо, давайте загрузим данные и нанесем их на картограмму JS! Прежде всего, я собрал данные о государственных визитах королевы Елизаветы II из Википедии и поместил их в файл JSON для быстрого доступа. Вы можете найти это здесь .

Все необходимые файлы уже связаны в <head>разделе HTML-страницы. Таким образом, можно использовать loadJsonFile()метод внутри <script>тега в теле страницы для загрузки файла JSON, содержащего данные о посещениях штата королевой.

anychart.data.loadJsonFile(<fileURL>, function (data) {});

Большой! Теперь, когда все настроено и готово к работе, пришло время перейти к основной части путешествия: созданию визуализации картограммы! Давай сделаем это!

4. Напишите необходимый код JavaScript для визуализации карты

Вы можете отобразить картограмму всего несколькими строками кода JS. Во-первых, убедитесь, что весь код находится внутри функции anychart.onDocumentReady(), чтобы страница была полностью загружена, прежде чем выполнять что-либо еще. После загрузки файла данных задайте данные, создайте карту и задайте геоданные.

<script>

  anychart.onDocumentReady(function() {

    // load data from a json file
    anychart.data.loadJsonFile('https://gist.githubusercontent.com/shacheeswadia/8f45da54d9bf2032fee201dbfc79e0e4/raw/5d10d58f40b4a1d994cef36dbc64545ef90ead80/queenVisits.json',
    function (data) {
    
      // create a dataset
      let dataSet = anychart.data.set(data);

      // create a map instance
      let map = anychart.map();

      // set the geodata
      map.geoData("anychart.maps.world");

      // the rest of the JS code will be here
	
    });

  });

</script>

Теперь создайте серию с choropleth()функцией и загруженными данными. Для раскраски давайте настроим линейную цветовую шкалу с четырьмя различными оттенками синего на основе цветов на королевском веб-сайте. Согласно соглашению, чем темнее оттенок страны, тем выше количество посещений этого региона.

// create a choropleth series
let series = map.choropleth(dataSet);

// set the map colors
series
  .colorScale(
     anychart.scales.linearColor("#f2f2f2", "#42a5f5", "#1976d2", "#233580")
   );

Наконец, дайте название карте, установите контейнер и нарисуйте результирующую карту.

// set the map title
map.title("State Visits Made by Queen Elizabeth II");

// set the container
map.container('container');

// initiate the map drawing
map.draw();

И вуаля! Красивая и функциональная картограмма готова! Посмотрите, как это выглядит. Вы можете найти весь код ниже или посмотреть и поиграть с ним здесь .

Базовая картограмма

<html>
  <head>
    <title>JavaScript Choropleth Map</title>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-base.min.js"></script>
    <script data-fr-src="https://cdn.anychart.com/releases/8.11.0/js/anychart-map.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.11.0/geodata/custom/world/world.js"></script>
    <style type="text/css">      
      html, body, #container { 
        width: 100%; height: 100%; margin: 0; padding: 0; 
      } 
    </style>
  </head>
  <body>  
    <div id="container"></div>
    <script>
      anychart.onDocumentReady(function () {
        // load data from a json file
        anychart.data.loadJsonFile(
          "https://gist.githubusercontent.com/shacheeswadia/8f45da54d9bf2032fee201dbfc79e0e4/raw/5d10d58f40b4a1d994cef36dbc64545ef90ead80/queenVisits.json",
          function (data) {
            // create a dataset
            let dataSet = anychart.data.set(data);
            // create a map instance
            let map = anychart.map();
            // set the geodata
            map.geoData("anychart.maps.world");
            // create a choropleth series
            let series = map.choropleth(dataSet);
            // set the map colors
            series
              .colorScale(
                anychart.scales.linearColor("#f2f2f2", "#42a5f5", "#1976d2", "#233580")
              );
            // set the map title
            map.title("State Visits Made by Queen Elizabeth II");
            // set the container
            map.container("container");
            // initiate the map drawing
            map.draw();
          }
        );
      });
    </script>
  </body>
</html>

Как настроить картограмму

Существующая картограмма уже впечатляет, но позвольте мне показать вам, как сделать ее еще более проницательной и увлекательной! В следующих шагах я покажу, как можно настроить картограмму, чтобы добавить больше визуальной привлекательности и интерактивности:

  1. Измените цвета, наведя курсор на область карты.
  2. Добавьте цветовую легенду.
  3. Улучшить всплывающую подсказку и формат заголовка.
  4. Добавьте элементы управления масштабированием.

1. Измените цвета, наведя курсор на области

Вы можете сделать карту более визуально привлекательной, изменив цвета выбранных областей. По умолчанию наведенные области становятся серыми, но вы можете изменить это на более темный оттенок основного цвета, чтобы сделать его более интуитивно понятным. Этого можно добиться, изменив цвет заливки региона при наведении на него и используя функцию darken().

series
  .hovered()
  .fill(function (d) {
    return anychart.color.darken(d.sourceColor, 0.2);
  });

2. Добавьте цветовую легенду

Добавление цветовой легенды к вашей картограмме — всегда отличная идея, так как это может помочь вашей аудитории понять значения и цвета, используемые на карте.

Чтобы добавить цветовую легенду, вам нужно только включить цветовой диапазон. Это автоматически создаст легенду, которая представляет, какой цвет указывает какое значение. По умолчанию цветовой диапазон отключен. Чтобы включить его, вам просто нужно добавить несколько строк кода:

map.colorRange()
  .enabled(true);

И вуаля! Теперь у вас есть красивая и информативная цветовая легенда, дополняющая вашу карту.

3. Улучшите формат всплывающей подсказки и заголовка

Давайте поднимем картограмму на новый уровень, улучшив всплывающую подсказку и формат заголовка. Всплывающие подсказки — это мощный способ демонстрации дополнительной информации, и их можно сделать еще лучше, включив HTML для настройки всплывающей подсказки и форматирования значения.

Я подумал, что было бы неплохо добавить собственный текст и указать, сколько раз королева посещала зависшую страну. Кроме того, можно рассмотреть конкретный случай Соединенного Королевства, чтобы продемонстрировать, что королева жила там.

Благодаря этим изменениям всплывающая подсказка стала не только более информативной, но и визуально более привлекательной. Пользователи будут наслаждаться игривым тоном всплывающей подсказки, узнавая интересные факты о путешествиях королевы.

map
  .title()
  .enabled(true)
  .useHtml(true)
  .text(
    '<span style="color: #c8102e; font-size:18px;">State visits made by Queen Elizabeth II</span>' +
      <span style="font-size: 15px;">(The Queen is the most widely travelled head of state in history)</span>'
  );

В дополнение к настройке всплывающей подсказки, почему бы не улучшить заголовок диаграммы с помощью HTML? Например, подзаголовок предоставит больше контекста, а настраиваемый стиль текста заставит все это сиять.

series
  .tooltip() 
  .useHtml(true)
  .format(function (d) {
    if (d.name == "United Kingdom") {
      return "<h6 style='font-size:14px; font-weight:400; margin: 0.2rem 0;'>The Queen lived here.</h6>";
    } else {
      return (
        "<h6 style='font-size:14px; font-weight:400; margin: 0.2rem 0;'>The Queen visited <b>" +
          d.value + "</b> times.</h6>"
      );
    }
  });

4. Добавьте элементы управления масштабированием

Добавление элементов управления масштабированием на карту мира может быть отличным способом, позволяющим пользователям масштабировать определенные области, представляющие интерес. Для начала добавьте необходимые скрипты и ссылки CSS в <head>раздел HTML-документа. Сделав это, вы можете создать элементы управления масштабированием и отобразить их на карте, написав всего несколько строк кода. 

<script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-exports.min.js"></script>
<script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-ui.min.js"></script>

<link rel="stylesheet" type="text/css" href="https://cdn.anychart.com/releases/8.11.0/css/anychart-ui.min.css">
<link rel="stylesheet" type="text/css" href="https://cdn.anychart.com/releases/8.11.0/fonts/css/anychart-font.min.css">
var zoomController = anychart.ui.zoom();
zoomController.render(map);

Стоит отметить, что функция масштабирования может быть особенно полезна при работе с большими и подробными картограммами. В этом случае это может быть отличным способом позволить пользователям более подробно изучить определенные регионы или области, представляющие интерес.

А теперь просто расслабьтесь и любуйтесь своей прекрасной картограммой JavaScript! Благодаря добавлению настраиваемых цветов, цветовой легенды, улучшенных всплывающих подсказок и заголовков, а также элементов управления масштабированием эта интерактивная и привлекательная визуализация обязательно впечатлит. См. полный код для этого проекта ниже, и не стесняйтесь играть с ним и увидеть полную интерактивную версию карты choropleth здесь .

Финальная карта хороплет

<html>
  <head>
    <title>JavaScript Choropleth Map</title>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-base.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.11.0/js/anychart-map.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.11.0/geodata/custom/world/world.js"></script>
    <style type="text/css">      
      html, body, #container { 
        width: 100%; height: 100%; margin: 0; padding: 0; 
      } 
    </style>
  </head>
  <body>  
    <div id="container"></div>
    <script>
      anychart.onDocumentReady(function () {
        // load data from a json file
        anychart.data.loadJsonFile(
          "https://gist.githubusercontent.com/shacheeswadia/8f45da54d9bf2032fee201dbfc79e0e4/raw/5d10d58f40b4a1d994cef36dbc64545ef90ead80/queenVisits.json",
          function (data) {
            // create a dataset
            let dataSet = anychart.data.set(data);
            // create a map instance
            let map = anychart.map();
            // set the geodata
            map.geoData("anychart.maps.world");
            // create a choropleth series
            let series = map.choropleth(dataSet);
            // set the map colors
            series.colorScale(
              anychart.scales.linearColor("#f2f2f2", "#42a5f5", "#1976d2", "#233580")
            );
            // customize the colors in the hovered state
            series.hovered().fill(function (d) {
              return anychart.color.darken(d.sourceColor, 0.2);
            });
            // create the map legend
            map.colorRange().enabled(true);
            // create zoom controls
            let zoomController = anychart.ui.zoom();
            zoomController.render(map);
            // customize the tooltip text
            series
              .tooltip()
              .useHtml(true)
              .format(function (d) {
                if (d.name == "United Kingdom") {
                  return "<h6 style='font-size:14px; font-weight:400; margin: 0.2rem 0;'>The Queen lived here.</h6>";
                } else {
                  return (
                    "<h6 style='font-size:14px; font-weight:400; margin: 0.2rem 0;'>The Queen visited <b>" +
                    d.value +
                    "</b> times.</h6>"
                  );
                }
              });
            // set the map title
            map
              .title()
              .enabled(true)
              .useHtml(true)
              .text(
                '<span style = "color: #c8102e; font-size:18px;">State Visits Made by Queen Elizabeth II</span>' +
                  '<br/><span style="font-size: 15px;">The Queen is the most widely traveled head of state in history</span>'
              );
            // set the container
            map.container("container");
            // initiate the map drawing
            map.draw();
          }
        );
      });
    </script>
  </body>
</html>

Заключение

Картограммы — мощный инструмент для визуализации данных в географическом масштабе. Используя JavaScript, вы можете создавать потрясающие интерактивные приложения, которые передают сложную информацию в ясной и лаконичной форме.

Отслеживаете ли вы путешествия монарха или визуализируете распространение пандемии, возможности безграничны. Итак, дайте волю своему воображению и начните исследовать мир через призму данных!

Источник статьи: https://dzone.com

#javascript