Trace  Hoeger

Trace Hoeger

1664204460

Suggest 7 Useful Templates Engines Libraries for Javascript

In this Javascript article, let's learn about Templating Engines: Suggest 7 Useful Templates Engines Libraries for Javascript

Table of contents:

  • JavaScript-Templates - < 1KB lightweight, fast & powerful JavaScript templating engine with zero dependencies.
  • t.js - A tiny JavaScript templating framework in ~400 bytes gzipped.
  • Pug - Robust, elegant, feature rich template engine for nodejs. (formerly known as Jade)
  • EJS - Effective JavaScript templating.
  • xtemplate - eXtensible Template Engine lib for node and the browser
  • marko - A fast, lightweight, HTML-based templating engine for Node.js and the browser with async, streaming, custom tags and CommonJS modules as compiled output.
  • swig - (Archived) A simple, powerful, and extendable Node.js and browser-based JavaScript template engine.

Templating Engines ?

A template engine enables you to use static template files in your application. At runtime, the template engine replaces variables in a template file with actual values, and transforms the template into an HTML file sent to the client. This approach makes it easier to design an HTML page.


Suggest 7 Useful Templates Engines Libraries for Javascript

  1. JavaScript Templates

1KB lightweight, fast & powerful JavaScript templating engine with zero dependencies. Compatible with server-side environments like node.js, module loaders like RequireJS and all web browsers.

Usage

Client-side

Install the blueimp-tmpl package with NPM:

npm install blueimp-tmpl

Include the (minified) JavaScript Templates script in your HTML markup:

<script src="js/tmpl.min.js"></script>

Add a script section with type "text/x-tmpl", a unique id property and your template definition as content:

<script type="text/x-tmpl" id="tmpl-demo">
  <h3>{%=o.title%}</h3>
  <p>Released under the
  <a href="{%=o.license.url%}">{%=o.license.name%}</a>.</p>
  <h4>Features</h4>
  <ul>
  {% for (var i=0; i<o.features.length; i++) { %}
      <li>{%=o.features[i]%}</li>
  {% } %}
  </ul>
</script>

"o" (the lowercase letter) is a reference to the data parameter of the template function (see the API section on how to modify this identifier).

View on GitHub


2.  t.js

A tiny javascript templating framework in ~400 bytes gzipped

t.js is a simple solution to interpolating values in an html string for insertion into the DOM via innerHTML.

Features

  • Simple interpolation: {{=value}}
  • Scrubbed interpolation: {{%unsafe_value}}
  • Name-spaced variables: {{=User.address.city}}
  • If/else blocks: {{value}} <<markup>> {{:value}} <<alternate markup>> {{/value}}
  • If not blocks: {{!value}} <<markup>> {{/!value}}
  • Object/Array iteration: {{@object_value}} {{=_key}}:{{=_val}} {{/@object_value}}
  • Multi-line templates (no removal of newlines required to render)
  • Render the same template multiple times with different data
  • Works in all modern browsers

How to use

var template = new t("<div>Hello {{=name}}</div>");
document.body.innerHtml = template.render({name: "World!"});

View on GitHub


3.  Pug

Pug – robust, elegant, feature rich template engine for Node.js

Pug is a high-performance template engine heavily influenced by Haml and implemented with JavaScript for Node.js and browsers. For bug reports, feature requests and questions, open an issue. For discussion join the chat room.


Installation

Package

To use Pug in your own JavaScript projects:

$ npm install pug

Command Line

After installing the latest version of Node.js, install with:

$ npm install pug-cli -g

and run with

$ pug --help

Syntax

Pug is a clean, whitespace sensitive syntax for writing HTML. Here is a simple example:

doctype html
html(lang="en")
  head
    title= pageTitle
    script(type='text/javascript').
      if (foo) bar(1 + 5);
  body
    h1 Pug - node template engine
    #container.col
      if youAreUsingPug
        p You are amazing
      else
        p Get on it!
      p.
        Pug is a terse and simple templating language with a
        strong focus on performance and powerful features.

Pug transforms the above to:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Pug</title>
    <script type="text/javascript">
      if (foo) bar(1 + 5);
    </script>
  </head>
  <body>
    <h1>Pug - node template engine</h1>
    <div id="container" class="col">
      <p>You are amazing</p>
      <p>
        Pug is a terse and simple templating language with a strong focus on
        performance and powerful features.
      </p>
    </div>
  </body>
</html>

View on GitHub


4.  ejs

Installation

$ npm install ejs

Features

  • Control flow with <% %>
  • Escaped output with <%= %> (escape function configurable)
  • Unescaped raw output with <%- %>
  • Newline-trim mode ('newline slurping') with -%> ending tag
  • Whitespace-trim mode (slurp all whitespace) for control flow with <%_ _%>
  • Custom delimiters (e.g. [? ?] instead of <% %>)
  • Includes
  • Client-side support
  • Static caching of intermediate JavaScript
  • Static caching of templates
  • Complies with the Express view system

Example

<% if (user) { %>
  <h2><%= user.name %></h2>
<% } %>

Try EJS online at: https://ionicabizau.github.io/ejs-playground/.

Basic usage

let template = ejs.compile(str, options);
template(data);
// => Rendered HTML string

ejs.render(str, data, options);
// => Rendered HTML string

ejs.renderFile(filename, data, options, function(err, str){
    // str => Rendered HTML string
});

It is also possible to use ejs.render(dataAndOptions); where you pass everything in a single object. In that case, you'll end up with local variables for all the passed options. However, be aware that your code could break if we add an option with the same name as one of your data object's properties. Therefore, we do not recommend using this shortcut.

View on GitHub


5.  xtemplate

eXtensible Template Engine lib for node and the browser

High Speed, eXtensible Template Engine lib on browser and nodejs. support async control, inheritance, include, logic expression, custom function and more.

View on GitHub


6.  Marko

A declarative, HTML-based language that makes building web apps fun

Marko is HTML re-imagined as a language for building dynamic and reactive user interfaces. Just about any valid HTML is valid Marko, but Marko extends the HTML language to allow building modern applications in a declarative way.

Among these extensions are conditionals, lists, state, and components. Marko supports both single-file components and components broken into separate files.

Single file component

The following single-file component renders a button and a counter with the number of times the button has been clicked.

click-count.marko

class {
    onCreate() {
        this.state = { count: 0 };
    }
    increment() {
        this.state.count++;
    }
}

style {
    .count {
        color: #09c;
        font-size: 3em;
    }
    .example-button {
        font-size: 1em;
        padding: 0.5em;
    }
}

<div.count>
    ${state.count}
</div>
<button.example-button on-click('increment')>
    Click me!
</button>

View on GitHub


7.  Swig

Take a swig of the best template engine for JavaScript.

Swig is an awesome, Django/Jinja-like template engine for node.js.

Features

  • Available for node.js and major web browsers!
  • Express compatible.
  • Object-Oriented template inheritance.
  • Apply filters and transformations to output in your templates.
  • Automatically escapes all output for safe HTML rendering.
  • Lots of iteration and conditionals supported.
  • Robust without the bloat.
  • Extendable and customizable. See Swig-Extras for some examples.
  • Great code coverage.

Need Help? Have Questions? Comments?

Installation

npm install swig

View on GitHub


Frequently asked questions about Templating Engines javascript

  • Is JavaScript a templating language?

JavaScript templating refers to the client side data binding method implemented with the JavaScript language. This approach became popular thanks to JavaScript's increased use, its increase in client processing capabilities, and the trend to outsource computations to the client's web browser.

  • What does templating engines do?

A template engine enables you to use static template files in your application. At runtime, the template engine replaces variables in a template file with actual values, and transforms the template into an HTML file sent to the client. This approach makes it easier to design an HTML page.

  • Do people still use template engines?

There are a number of template engines available today, and the more popular ones include Pug (fka Jade), Handlebars, EJS, Mustache, Swig, and others.

  • Is HTML a template engine?

Template Engines are tools that help us break HTML code into smaller pieces that we can reuse across multiple HTML files. They also give you the power to feed data into variables that help you simplify your code. You can only use template engines if you had a way to compile them into HTML


Related videos:

What is Templating Engine?


Related posts:

#javascript 

Suggest 7 Useful Templates Engines Libraries for Javascript
Reid  Rohan

Reid Rohan

1663014780

10 Best Templating Engines Allow You to Perform String interpolation

In today's post we will learn about 10 Best Templating Engines Allow You to Perform String interpolation.

What are templating engines used for?

A template engine enables you to use static template files in your application. At runtime, the template engine replaces variables in a template file with actual values, and transforms the template into an HTML file sent to the client. This approach makes it easier to design an HTML page.

Table of contents:

  • Mustache.js - Minimal templating with {{mustaches}} in JavaScript.
  • Handlebars.js - An extension to the Mustache templating language.
  • EJS - Effective JavaScript templating.
  • Hogan.js - A compiler for the Mustache templating language.
  • DoT - The fastest + concise JavaScript template engine for nodejs and browsers.
  • Dustjs - Asynchronous templates for the browser and node.js.
  • Eco - Embedded CoffeeScript templates.
  • JavaScript-Templates - < 1KB lightweight, fast & powerful JavaScript templating engine with zero dependencies.
  • T.js - A tiny JavaScript templating framework in ~400 bytes gzipped.
  • Pug - Robust, elegant, feature rich template engine for nodejs. (formerly known as Jade)

1 - Mustache.js: Minimal templating with {{mustaches}} in JavaScript.

mustache.js - Logic-less {{mustache}} templates with JavaScript

Install

You can get Mustache via npm.

$ npm install mustache --save

Usage

Below is a quick example how to use mustache.js:

var Mustache = require('mustache');

var view = {
  title: "Joe",
  calc: function () {
    return 2 + 4;
  }
};

var output = Mustache.render("{{title}} spends {{calc}}", view);

In this example, the Mustache.render function takes two parameters: 1) the mustache template and 2) a view object that contains the data and code needed to render the template.

Templates

A mustache template is a string that contains any number of mustache tags. Tags are indicated by the double mustaches that surround them. {{person}} is a tag, as is {{#person}}. In both examples we refer to person as the tag's key. There are several types of tags available in mustache.js, described below.

There are several techniques that can be used to load templates and hand them to mustache.js, here are two of them:

Include Templates

If you need a template for a dynamic part in a static website, you can consider including the template in the static HTML file to avoid loading templates separately. Here's a small example:

// file: render.js

function renderHello() {
  var template = document.getElementById('template').innerHTML;
  var rendered = Mustache.render(template, { name: 'Luke' });
  document.getElementById('target').innerHTML = rendered;
}
<html>
  <body onload="renderHello()">
    <div id="target">Loading...</div>
    <script id="template" type="x-tmpl-mustache">
      Hello {{ name }}!
    </script>

    <script src="https://unpkg.com/mustache@latest"></script>
    <script src="render.js"></script>
  </body>
</html>

View on Github

2 - Handlebars.js: An extension to the Mustache templating language.

Installing

See our installation documentation.

Usage

In general, the syntax of Handlebars.js templates is a superset of Mustache templates. For basic syntax, check out the Mustache manpage.

Once you have a template, use the Handlebars.compile method to compile the template into a function. The generated function takes a context argument, which will be used to render the template.

var source = "<p>Hello, my name is {{name}}. I am from {{hometown}}. I have " +
             "{{kids.length}} kids:</p>" +
             "<ul>{{#kids}}<li>{{name}} is {{age}}</li>{{/kids}}</ul>";
var template = Handlebars.compile(source);

var data = { "name": "Alan", "hometown": "Somewhere, TX",
             "kids": [{"name": "Jimmy", "age": "12"}, {"name": "Sally", "age": "4"}]};
var result = template(data);

// Would render:
// <p>Hello, my name is Alan. I am from Somewhere, TX. I have 2 kids:</p>
// <ul>
//   <li>Jimmy is 12</li>
//   <li>Sally is 4</li>
// </ul>

Full documentation and more examples are at handlebarsjs.com.

View on Github

3 - EJS: Effective JavaScript templating.

Installation

$ npm install ejs

Features

  • Control flow with <% %>
  • Escaped output with <%= %> (escape function configurable)
  • Unescaped raw output with <%- %>
  • Newline-trim mode ('newline slurping') with -%> ending tag
  • Whitespace-trim mode (slurp all whitespace) for control flow with <%_ _%>
  • Custom delimiters (e.g. [? ?] instead of <% %>)
  • Includes
  • Client-side support
  • Static caching of intermediate JavaScript
  • Static caching of templates
  • Complies with the Express view system

Example

<% if (user) { %>
  <h2><%= user.name %></h2>
<% } %>

Try EJS online at: https://ionicabizau.github.io/ejs-playground/.

Basic usage

let template = ejs.compile(str, options);
template(data);
// => Rendered HTML string

ejs.render(str, data, options);
// => Rendered HTML string

ejs.renderFile(filename, data, options, function(err, str){
    // str => Rendered HTML string
});

It is also possible to use ejs.render(dataAndOptions); where you pass everything in a single object. In that case, you'll end up with local variables for all the passed options. However, be aware that your code could break if we add an option with the same name as one of your data object's properties. Therefore, we do not recommend using this shortcut.

View on Github

4 - Hogan.js: A compiler for the Mustache templating language.

Why Hogan.js?

Why another templating library?

Hogan.js was written to meet three templating library requirements: good performance, standalone template objects, and a parser API.

Install

Node.js

npm install hogan.js

component

component install twitter/hogan.js

Compilation options

The second argument to Hogan.compile is an options hash.

var text = "my <%example%> template."
Hogan.compile(text, {delimiters: '<% %>'});

There are currently four valid options.

asString: return the compiled template as a string. This feature is used by hulk to produce strings containing pre-compiled templates.

sectionTags: allow custom tags that require opening and closing tags, and treat them as though they were section tags.

var text = "my {{_foo}}example{{/foo}} template."
Hogan.compile(text, { sectionTags: [{o: '_foo', c: 'foo'}]});

The value is an array of object with o and c fields that indicate names for custom section tags. The example above allows parsing of {{_foo}}{{/foo}}.

delimiters: A string that overrides the default delimiters. Example: "<% %>".

disableLambda: disables the higher-order sections / lambda-replace features of Mustache.

View on Github

5 - DoT: The fastest + concise JavaScript template engine for nodejs and browsers.

Created in search of the fastest and concise JavaScript templating function with emphasis on performance under V8 and nodejs. It shows great performance for both nodejs and browsers.

doT.js is fast, small and has no dependencies.

v2 !!!

v2.0.0-beta.1 is released - switching recommended!

See release notes.

To install:

npm install dot@beta

Note from the maintainer

doT is a really solid piece of software engineering (I didn’t create it) that is rarely updated exactly for this reason.

It took me years to grasp how it works even though it’s only 140 lines of code - it looks like magic.

I used it in my other projects (e.g. ajv) as the smallest, the fastest and the most functional (all three!) templating engine ever made, that is particularly useful in all code generation scenarios where manipulating AST is an overkill.

It’s a race car of templating engines - doT lacks bells and whistles that other templating engines have, but it allows to achive more than any other, if you use it right (YMMV).

Features

custom delimiters
runtime evaluation
runtime interpolation
compile-time evaluation
partials support
conditionals support
array iterators
encoding
control whitespace - strip or preserve
streaming friendly
use it as logic-less or with logic, it is up to you

View on Github

6 - Dustjs: Asynchronous templates for the browser and node.js.

Install

NPM

Important: We recommend that you lock your version of Dust to a specific minor version, instead of a major version. By default, NPM will add "dustjs-linkedin": "^2.x.y" to your package.json, which will install new minor versions automatically.

npm install --save --production dustjs-linkedin
# If you want the dustc compiler available globally
npm install --global --production dustjs-linkedin

If you want to add the Dust helpers or secure filters:

npm install --save --production dustjs-helpers
npm install --save --production dustjs-filters-secure

Bower

bower install --save dustjs-linkedin

Get Started

  • Read dustjs.com for guides, tutorials, and documentation.
  • Check out the examples/ directory in the repo for simple examples to help you get started using Dust in a variety of ways.

View on Github

7 - Eco: Embedded CoffeeScript templates.

Eco lets you embed CoffeeScript logic in your markup. It's like EJS and ERB, but with CoffeeScript inside the <% ... %>. Use it from Node.js to render your application's views on the server side, or compile your templates to JavaScript with the eco command-line utility and use them to dynamically render views in the browser.

Here's how an Eco template looks:

<% if @projects.length: %>
  <% for project in @projects: %>
    <a href="<%= project.url %>"><%= project.name %></a>
    <p><%= project.description %></p>
  <% end %>
<% else: %>
  No projects
<% end %>

Usage

Use eco.render() to render your templates. The first argument is the template source as a string. The second argument is the context object which contains your view state and any helper methods you want to call.

eco = require "eco"
fs  = require "fs"

template = fs.readFileSync __dirname + "/views/projects.html.eco", "utf-8"
console.log eco.render template, projects: [
  { name: "Mobile app", url: "/projects/1", description: "Iteration 1" },
  { name: "Home page redesign", url: "/projects/2" }
]

Eco is fully synchronous. If your template needs to access data from asynchronous operations, perform those first before calling render.

Language reference

Eco's syntax is simple:

  • <% expression %>: Evaluate a CoffeeScript expression without printing its return value.
  • <%= expression %>: Evaluate a CoffeeScript expression, escape its return value, and print it.
  • <%- expression %>: Evaluate a CoffeeScript expression and print its return value without escaping it.
  • <%= @property %>: Print the escaped value of the property property from the context object passed to render.
  • <%= @helper() %>: Call the helper method helper from the context object passed to render, then print its escaped return value.
  • <% @helper -> %>...<% end %>: Call the helper method helper with a function as its first argument. When invoked, the function will capture and return the content ... inside the tag.
  • <%% and %%> will result in a literal <% and %> in the rendered template, respectively.

View on Github

8 - JavaScript-Templates: < 1KB lightweight, fast & powerful JavaScript templating engine with zero dependencies.

Description

1KB lightweight, fast & powerful JavaScript templating engine with zero dependencies.
Compatible with server-side environments like Node.js, module loaders like RequireJS or webpack and all web browsers.

Usage

Client-side

Install the blueimp-tmpl package with NPM:

npm install blueimp-tmpl

Include the (minified) JavaScript Templates script in your HTML markup:

<script src="js/tmpl.min.js"></script>

Add a script section with type "text/x-tmpl", a unique id property and your template definition as content:

<script type="text/x-tmpl" id="tmpl-demo">
  <h3>{%=o.title%}</h3>
  <p>Released under the
  <a href="{%=o.license.url%}">{%=o.license.name%}</a>.</p>
  <h4>Features</h4>
  <ul>
  {% for (var i=0; i<o.features.length; i++) { %}
      <li>{%=o.features[i]%}</li>
  {% } %}
  </ul>
</script>

"o" (the lowercase letter) is a reference to the data parameter of the template function (see the API section on how to modify this identifier).

In your application code, create a JavaScript object to use as data for the template:

var data = {
  title: 'JavaScript Templates',
  license: {
    name: 'MIT license',
    url: 'https://opensource.org/licenses/MIT'
  },
  features: ['lightweight & fast', 'powerful', 'zero dependencies']
}

In a real application, this data could be the result of retrieving a JSON resource.

Render the result by calling the tmpl() method with the id of the template and the data object as arguments:

document.getElementById('result').innerHTML = tmpl('tmpl-demo', data)

View on Github

9 - T.js: A tiny JavaScript templating framework in ~400 bytes gzipped.

t.js is a simple solution to interpolating values in an html string for insertion into the DOM via innerHTML.

Features

  • Simple interpolation: {{=value}}
  • Scrubbed interpolation: {{%unsafe_value}}
  • Name-spaced variables: {{=User.address.city}}
  • If/else blocks: {{value}} <<markup>> {{:value}} <<alternate markup>> {{/value}}
  • If not blocks: {{!value}} <<markup>> {{/!value}}
  • Object/Array iteration: {{@object_value}} {{=_key}}:{{=_val}} {{/@object_value}}
  • Multi-line templates (no removal of newlines required to render)
  • Render the same template multiple times with different data
  • Works in all modern browsers

How to use

var template = new t("<div>Hello {{=name}}</div>");
document.body.innerHtml = template.render({name: "World!"});

For more advanced usage check the t_test.html.

View on Github

10 - Pug: Robust, elegant, feature rich template engine for nodejs. (formerly known as Jade)

Installation

Package

To use Pug in your own JavaScript projects:

$ npm install pug

Command Line

After installing the latest version of Node.js, install with:

$ npm install pug-cli -g

and run with

$ pug --help

Syntax

Pug is a clean, whitespace sensitive syntax for writing HTML. Here is a simple example:

doctype html
html(lang="en")
  head
    title= pageTitle
    script(type='text/javascript').
      if (foo) bar(1 + 5);
  body
    h1 Pug - node template engine
    #container.col
      if youAreUsingPug
        p You are amazing
      else
        p Get on it!
      p.
        Pug is a terse and simple templating language with a
        strong focus on performance and powerful features.

Pug transforms the above to:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Pug</title>
    <script type="text/javascript">
      if (foo) bar(1 + 5);
    </script>
  </head>
  <body>
    <h1>Pug - node template engine</h1>
    <div id="container" class="col">
      <p>You are amazing</p>
      <p>
        Pug is a terse and simple templating language with a strong focus on
        performance and powerful features.
      </p>
    </div>
  </body>
</html>

View on Github

Thank you for following this article.

Related videos:

Node JS Tutorial for Beginners - Template Engines

#javascript #template #engine #string 

10 Best Templating Engines Allow You to Perform String interpolation
Abdullah  Kozey

Abdullah Kozey

1662514153

Revealed 5 Best Angular Resize Libraries

In this article, we will learn about Revealed 5 Best Angular Resize Libraries

Angular is a development platform, built on TypeScript. As a platform, Angular includes:

  • A component-based framework for building scalable web applications
  • A collection of well-integrated libraries that cover a wide variety of features, including routing, forms management, client-server communication, and more
  • A suite of developer tools to help you develop, build, test, and update your code

Revealed 5 Best angular Resize Libraries

  1.  Angular-Resize-Element

An angular 4.0+ directive that allows an element to be resized

Demo

https://michaelkravchuk.github.io/angular-libs

Usage

Step 1: Install angular-resize-element

npm install angular-resize-element --save

Step 2: Import angular resize element module into your app module

....
import { AngularResizeElementModule } from 'angular-resize-element';

....

@NgModule({
    ...
    imports: [
        ....
        AngularResizeElementModule
    ],
    ....
})
export class AppModule { }

Step 3: Add HTML code

<div class="container" #container [style.width.px]="data.width" [style.height.px]="data.height">
    <div class="resize resize__right"
         (resize)="onResize($event)"
         [targetElement]="container"
         [direction]="AngularResizeElementDirection.RIGHT"
    ></div>

    <div class="resize resize__bottom--right"
         (resize)="onResize($event)"
         [targetElement]="container"
         [direction]="AngularResizeElementDirection.BOTTOM_RIGHT"
    ></div>
</div>

Or if you use angular component (and look at TS)

   [targetElement]="containerComponent"

Step 4: Add ts code

  public readonly AngularResizeElementDirection = AngularResizeElementDirection;
  public data: any = {};

  public onResize(evt: AngularResizeElementEvent): void {
        this.data.width = evt.currentWidthValue;
        this.data.height = evt.currentHeightValue;
        this.data.top = evt.currentTopValue;
        this.data.left = evt.currentLeftValue;
  }

and add ViewChild if you use angular component (don`t forget about breaking changes when you use *ngIf with ViewChild)

  @ViewChild('container',  {read: ElementRef})
  public readonly containerElement;

Step 5: Add css to angular.json config

 "styles": [
    ...
    "node_modules/angular-resize-element/bundles/style.scss"
],

Interfaces

enum AngularResizeElementDirection {
    TOP = 'top',
    TOP_RIGHT = 'top-right',
    RIGHT = 'right',
    BOTTOM_RIGHT = 'bottom-right',
    BOTTOM = 'bottom',
    BOTTOM_LEFT = 'bottom-left',
    LEFT = 'left',
    TOP_LEFT = 'top-left'
}

interface AngularResizeElementEvent {
    currentWidthValue: number;
    currentHeightValue: number;
    originalWidthValue: number;
    originalHeightValue: number;
    differenceWidthValue: number;
    differenceHeightValue: number;
    
    currentTopValue: number;
    currentLeftValue: number;
    originalTopValue: number;
    originalLeftValue: number;
    differenceTopValue: number;
    differenceLeftValue: number;

    originalEvent: MouseEvent;
}

View on GitHub

 

2.   angular-resize

AngularJS factory implementation of debounced window resize event handler.

Inject the resize factory into your application module:

angular.module('myApp', ['resize']);

Inject the resize factory into your application where you'd like to implement it.

angular
	.module('myApp')
	.controller('MainCtrl', function(resize) {
		var rs = resize.init({
			scope: $scope,
			resizedFn: function() { //window was resized! },
			debounce: 200
		});
	});

View on GitHub

 

3.   angular resizable element

Demo

https://mattlewis92.github.io/angular-resizable-element/

About

An angular 14.0+ directive that allows an element to be dragged and resized

Installation

Install through npm:

npm install angular-resizable-element

Then use it in your app like so:

import { Component } from '@angular/core';
import { ResizeEvent } from 'angular-resizable-element';

@Component({
  selector: 'demo-app',
  styles: [
    `
      .rectangle {
        position: relative;
        top: 200px;
        display: flex;
        align-items: center;
        justify-content: center;
        width: 300px;
        height: 150px;
        background-color: #fd4140;
        border: solid 1px #121621;
        color: #121621;
        margin: auto;
      }

      mwlResizable {
        box-sizing: border-box; // required for the enableGhostResize option to work
      }

      .resize-handle-top,
      .resize-handle-bottom {
        position: absolute;
        height: 5px;
        cursor: row-resize;
        width: 100%;
      }

      .resize-handle-top {
        top: 0;
      }

      .resize-handle-bottom {
        bottom: 0;
      }

      .resize-handle-left,
      .resize-handle-right {
        position: absolute;
        height: 100%;
        cursor: col-resize;
        width: 5px;
      }

      .resize-handle-left {
        left: 0;
      }

      .resize-handle-right {
        right: 0;
      }
    `,
  ],
  template: `
    <div
      class="rectangle"
      mwlResizable
      [enableGhostResize]="true"
      (resizeEnd)="onResizeEnd($event)"
    >
      <div
        class="resize-handle-top"
        mwlResizeHandle
        [resizeEdges]="{ top: true }"
      ></div>
      <div
        class="resize-handle-left"
        mwlResizeHandle
        [resizeEdges]="{ left: true }"
      ></div>
      <div
        class="resize-handle-right"
        mwlResizeHandle
        [resizeEdges]="{ right: true }"
      ></div>
      <div
        class="resize-handle-bottom"
        mwlResizeHandle
        [resizeEdges]="{ bottom: true }"
      ></div>
    </div>
  `,
})
export class MyComponent {
  onResizeEnd(event: ResizeEvent): void {
    console.log('Element was resized', event);
  }
}

// now use within your apps module
import { NgModule } from '@angular/core';
import { ResizableModule } from 'angular-resizable-element';

@NgModule({
  declarations: [MyComponent],
  imports: [ResizableModule],
  bootstrap: [MyComponent],
})
class MyModule {}

You may also find it useful to view the demo source.

View on GitHub

 

4.   angular-table-resize

An AngularJS module for resizing table columns!

Demo

You can try out a demo by clicking here. You can also use the demo as an example for implementing the module on your own page. The source can be found in the gh-pages branch

Installation

Bower

bower install angular-table-resize

NPM

npm install angular-table-resize

Quick Setup

Link style sheets

<link rel="stylesheet" href="angular-table-resize.css">

Import dependencies

<script src="jquery.js"></script>
<script src="angular.js"></script>

Import the module

<script src="angular-table-resize.js"></script>

Install the module

Add the module to your application

angular.module('myApplication', ['rzTable']);

On a HTML table tag put the rz-table directive

<table rz-table>...</table>

That wasn't so hard was it now?

View on GitHub

Thank you for following this article. thank you


Related videos:

Create Draggable and Resizable Modal with Angular

Related posts:

TAGS: #angular 

Revealed 5 Best Angular Resize Libraries
Hunter  Krajcik

Hunter Krajcik

1662084420

Simple Service Locator Where Existing instanse Is Lazy Singleton

Dependencies container written on pure dart

Documentation: in progress...

void main() {
  final container = DependenciesContainer(
      dependencies: {
        int: () => 5,
        String: () => '5',
      },
      lazySingletons: {String}
  );
  final str = container.dependency<String>(); // once created and returned
  final str2 = container.dependency<String>(); // already created and returned from cache
  // str and str2 are same instances
  container.clearSingleton<String>(); // removing from cache, next time call will return new one
  // not declared in singleton scope will return new one instance every time
  final integer = container.dependency<int>(); // once created
  final integer2 = container.dependency<int>(); // once created
  //integer and integer2 are different instances
}

Use this package as a library

Depend on it

Run this command:

With Dart:

 $ dart pub add dependencies_container

With Flutter:

 $ flutter pub add dependencies_container

This will add a line like this to your package's pubspec.yaml (and run an implicit dart pub get):

dependencies:
  dependencies_container: ^1.0.3

Alternatively, your editor might support dart pub get or flutter pub get. Check the docs for your editor to learn more.

Import it

Now in your Dart code, you can use:

import 'package:dependencies_container/dependencies_container.dart';

example/dependencies_container_example.dart

import 'package:dependencies_container/dependencies_container.dart';

void main() {
  final container = DependenciesContainer(
    dependencies: {
      int: () => 5,
      String: () => '5',
    },
  );
  final str = container.dependency<String>(); // once created and returned
  final str2 = container.dependency<String>(); // already created and returned from cache
  // str and str2 are same instances
  container.clearSingleton<String>(); // removing from cache, next time call will return new one
  // not declared in singleton scope will return new one instance every time
  final integer = container.dependency<int>(); // once created
  final integer2 = container.dependency<int>(); // once created
  //integer and integer2 are different instances
}

Original article source at: https://pub.dev/packages/dependencies_container 

#flutter #dart #container 

Simple Service Locator Where Existing instanse Is Lazy Singleton
Web  Dev

Web Dev

1660613560

How to Create a Draggable Div Element with HTML, CSS & JavaScript

This tutorial shows how to create a draggable div element with HTML, CSS & JavaScript. Create a Draggable Div in HTML CSS & JavaScript

Project Folder Structure:

Before we start coding, let us take a look at the project folder structure. We create a project folder called – ‘Draggable Div’. Inside this folder, we have three files. These files are – index.html, style.css and script.js.

The first file is the HTML document. Next, we have the stylesheet, and finally, we have the script file.

HTML:

We begin with the HTML code. First. copy the code provided to you below and paste it into your HTML document.

The HTML code creates an element that builds the structure of our project. In our case, the HTML code consists of a div with id-‘container’. Inside the container, we have a div with id – ‘draggable-elem’. You can have any kind of element inside this div. I have used a simple paragraph tag.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Draggable Div</title>
    <!-- Google Fonts -->
    <link
      href="https://fonts.googleapis.com/css2?family=Poppins:wght@500&display=swap"
      rel="stylesheet"
    />
    <!-- Stylesheet -->
    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <div id="container">
      <div id="draggable-elem">
        <p>Drag Me</p>
      </div>
    </div>
    <!-- Script -->
    <script src="script.js"></script>
  </body>
</html>

CSS:

We now style the elements created with HTML using CSS. The styling is completely optional. You can either skip it or customize the div according to your choice. Now copy the code provided to you below and paste it into your stylesheet.

body {
  padding: 0;
  margin: 0;
  background: linear-gradient(135deg, #c3a3f1, #6414e9);
}
#container {
  height: 100vh;
  width: 100vw;
  position: relative;
}
#draggable-elem {
  position: absolute;
  background-color: #ffffff;
  font-size: 1.6em;
  width: 7em;
  height: 7em;
  position: absolute;
  transform: translate(-50%, -50%);
  left: 50%;
  top: 50%;
  display: grid;
  place-items: center;
  font-family: "Poppins", sans-serif;
  border-radius: 0.3em;
  cursor: move;
}

Javascript:

We finally implement the functionality using Javascript. For this copy the code below and paste it into your script file. I have added comments for an explanation for each line of code to make it easier for you to understand.

let draggableElem = document.getElementById("draggable-elem");
let initialX = 0,
  initialY = 0;
let moveElement = false;

//Events Object
let events = {
  mouse: {
    down: "mousedown",
    move: "mousemove",
    up: "mouseup",
  },
  touch: {
    down: "touchstart",
    move: "touchmove",
    up: "touchend",
  },
};

let deviceType = "";

//Detech touch device
const isTouchDevice = () => {
  try {
    //We try to create TouchEvent (it would fail for desktops and throw error)
    document.createEvent("TouchEvent");
    deviceType = "touch";
    return true;
  } catch (e) {
    deviceType = "mouse";
    return false;
  }
};

isTouchDevice();

//Start (mouse down / touch start)
draggableElem.addEventListener(events[deviceType].down, (e) => {
  e.preventDefault();
  //initial x and y points
  initialX = !isTouchDevice() ? e.clientX : e.touches[0].clientX;
  initialY = !isTouchDevice() ? e.clientY : e.touches[0].clientY;

  //Start movement
  moveElement = true;
});

//Move
draggableElem.addEventListener(events[deviceType].move, (e) => {
  //if movement == true then set top and left to new X andY while removing any offset
  if (moveElement) {
    e.preventDefault();
    let newX = !isTouchDevice() ? e.clientX : e.touches[0].clientX;
    let newY = !isTouchDevice() ? e.clientY : e.touches[0].clientY;
    draggableElem.style.top =
      draggableElem.offsetTop - (initialY - newY) + "px";
    draggableElem.style.left =
      draggableElem.offsetLeft - (initialX - newX) + "px";
    initialX = newX;
    initialY = newY;
  }
});

//mouse up / touch end
draggableElem.addEventListener(
  events[deviceType].up,
  (stopMovement = (e) => {
    moveElement = false;
  })
);

draggableElem.addEventListener("mouseleave", stopMovement);
draggableElem.addEventListener(events[deviceType].up, (e) => {
  moveElement = false;
});

📁 Download Source Code: https://www.codingartistweb.com

#html #css #javascript #js #webdev 

How to Create a Draggable Div Element with HTML, CSS & JavaScript
曾 俊

曾 俊

1660459020

如何在 JavaScript 中创建线性仪表图

我们将展示如何快速创建一个酷炫的交互式线性仪表图表,突出显示世界各地的 Covid-19 疫苗接种数据。我们的图表将使我们能够在撰写本文时可视化 Covid-19 疫苗接种的状态,并将显示两种类型的数据——显示我们距离为全球人口部分和完全接种疫苗的中途目标还有多远。

线性量规封面图片

什么是线性仪表图?

鉴于正在创建的大量数据以及从数据中收集信息的众多可能性,数据可视化是一种非常宝贵的工具。数据可视化对于识别趋势、解释模式以及向目标受众传达复杂的想法特别有用。

线性仪表图表示显示所需值的垂直或水平线性刻度,带有颜色刻度以及单个或多个指针。可以根据所表示的数据在轴上设置数据范围的最小值和最大值。指针位置指示指标的当前值。

仪表图可以使用单个指针或标记组合显示单个值或多个值。指针可以是带有任何形状标记的针或线,例如圆形、正方形、矩形或三角形。

线性仪表图表类型是一种有效的可视化表示,用于显示值与所需数据点的距离。

线性量规的类型

线性仪表的几种类型是温度计图表,子弹图表,坦克图表和LED图表。水银温度计——由显示温度和指针值的小刻度组成——是线性仪表图的典型例子。

我们将要构建的线性仪表可视化

这是最终线性仪表图的预览。按照本教程了解我们如何使用 JavaScript 构建这个有趣且信息丰富的线性仪表图。

线性仪表图最终版本

构建 JavaScript 线性仪表的四个步骤

掌握 HTML 和 JavaScript 等技术的技能总是很有用的。但在本教程中,我们使用了一个 JS 图表库,即使只需要很少的技术知识,也可以更轻松地创建像线性仪表这样的引人注目的图表。

有几个JavaScript 图表库可以轻松地可视化数据,这里我们使用AnyChart创建线性仪表图。这个库很灵活,有大量的文档,它包含一些很好的例子。此外,它还有一个用于试验代码的游乐场,并且可以免费用于非商业用途。如果您想购买许可版本,您可以查看可用选项,如果您是教育机构或非营利组织,您可以在此处联系以获取免费许可。

制作 JavaScript 线性仪表的步骤

以下是创建线性仪表图的基本步骤:

  1. 创建一个基本的 HTML 页面。
  2. 包括必要的 JavaScript 文件。
  3. 添加数据。
  4. 为图表编写 JavaScript 代码。

让我们在下面详细了解这些步骤中的每一个。

1.创建一个基本的HTML页面

我们需要做的第一件事是制作一个 HTML 页面来保存我们的可视化。我们添加一个<div>块元素并给它一个 ID,以便我们以后可以引用它:

<html lang="en">
  <head>
    <title>JavaScript Linear Gauge</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>

的宽度和高度属性<div>设置为 100%,以便图表在整个屏幕上呈现。这些属性可以根据需要进行修改。

2. 包含必要的 JavaScript 文件

下一步是在 HTML 页面中引用 JS 链接。我们将在本教程中使用 AnyChart 库,所以让我们从他们的CDN中包含相应的文件。

要创建线性仪表图,我们需要添加三个脚本:核心模块线性仪表模块表格模块

<html lang="en">
  <head>
    <title>JavaScript Linear Gauge</title>
    <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 linear gauge will come here
    </script>
    <script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-core.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-linear-gauge.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-table.min.js"></script>
  </body>
</html>

3. 添加数据值

线性仪表图的数据是从Our World in Data中收集的,并包含在代码中。在该网站上,我们可以看到全世界每个大陆接种一剂和两剂 Covid疫苗的人的百分比。

因为(在撰写本文时)没有一个数字大于 50%,所以我们将所有线性仪表的轴的最大限制保持为 50%,并且我们比较了每个大陆与该标记的距离,以及全球数字。我们用 LED 表示至少部分接种疫苗的数字,用条形指针表示完全接种疫苗的数字。我们将在最后一步看到如何添加数据。

那么,我们的初始步骤都完成了,现在让我们添加代码,用 JavaScript 制作一个线性仪表图!

4. 为图表编写 JavaScript 代码

在添加任何代码之前,我们将所有内容封装在一个函数中,以确保其中的整个代码仅在页面加载后执行。

创建线性仪表图涉及几个步骤,并且比其他基本图表类型更复杂一些。但这并不意味着它非常困难,我们将通过每一步来了解图表是如何制作的。

定义仪表图的线性刻度和轴

我们的图表中有多个指针。因此,让我们从创建一个接受两个值的函数开始:一个用于条形指针,一个用于 LED 仪表。然后我们将创建一个仪表,设置数据,并将布局指定为水平。接下来,我们将设置刻度和轴的范围。我们将制作一个具有最小和最大范围的线性比例。对于轴,我们将定义属性并设置方向:

function drawGauge(value, settings) {
  // Create gauge with settings
  const gauge = anychart.gauges.linear();
  gauge.data([value, settings.value]);
  gauge.layout('horizontal');

  // Set scale for gauge
  const scale = anychart.scales.linear();
  scale.minimum(0).maximum(settings.maximum).ticks({ interval: 2 });

  // Set axis for gauge
  const axis = gauge.axis(0);
  axis.width('1%').offset('43%').scale(scale).orientation('bottom');
}

设置条形指针和标签

现在,我们将为条形系列创建条形指针和标签。给标签一个偏移量以避免与指针重叠:

// Create and set bar point
const barSeries = gauge.bar(0);

barSeries
  .scale(scale)
  .width('4%');

// Create and set label with actual data
const labelBar = barSeries.labels();
labelBar
  .enabled(true)
  .offsetY('-15px');

创建 LED 指针并设置颜色属性

在 LED 点中,我们将指定点之间的间隙,并使用 dimmer 属性设置剩余 LED 点的颜色以指示不亮的效果。我们还将声明点亮的 LED 点的色标:

// Create and set LED point
const ledPointer = gauge.led(1);

ledPointer
  .offset('10%')
  .width('30%')
  .count(settings.maximum)
  .scale(scale)
  .gap(0.55)
  .dimmer(function () {
    return '#eee';
  });

ledPointer.colorScale().colors(['#63b39b', '#63b39b']);

用每个数据点的目标值声明仪表

为了为每个大陆制作线性仪表,我们将为每个区域调用上面定义的函数及其数据。第一个数字表示目标值数据,第二个变量是带有 LED 数据的对象。maximum保持恒定 50,而是value每个数据点的完全接种疫苗人口的百分比值。该值将由指针显示:

// Create gauges
const world = drawGauge(13.68, { maximum: 50, value: 27.13 });
const europe = drawGauge(36.98, { maximum: 50, value: 47.28 });
const nAmerica = drawGauge(36.77, { maximum: 50, value: 46.53 });
const sAmerica = drawGauge(22.8, { maximum: 50, value: 40.54 });
const asia = drawGauge(10.14, { maximum: 50, value: 27.16 });
const oceania = drawGauge(9.75, { maximum: 50, value: 22.12 });
const africa = drawGauge(1.56, { maximum: 50, value: 3.04 });

设置线性仪表的布局

为了在另一个下显示每个线性仪表,我们将定义一个表格并将标题与每个数据点一起添加为单独的行。我们将添加布局的各种属性,例如对齐方式和字体大小。我们还将为第一行定义参数,因为它是标题,并将第一列的宽度属性设置为 100%,因为我们不再需要任何列:

// Create table to place gauges
const layoutTable = anychart.standalones.table();
layoutTable
  .hAlign('right')
  .vAlign('middle')
  .fontSize(14)
  .cellBorder(null);

// Put gauges into the layout table
layoutTable.contents([
  [null, 'Covid-19 Vaccination - How far are we from the halfway mark?'],
  ['World', world],
  ['Europe', europe],
  ['North America', nAmerica],
  ['South America', sAmerica],
  ['Asia', asia],
  ['Oceania', oceania],
  ['Africa', africa]
]);

// Set height for first row in layout table
layoutTable
  .getRow(0)
  .height(50)
  .fontSize(22)
  .hAlign('center');

// Set the first column to 100% width
layoutTable.getCol(0).width(100);

绘制图表

最后一步是引用<div>我们在上一步中添加的容器,并绘制图表:

// Set container id and initiate drawing
layoutTable.container('container');
layoutTable.draw();

就是这样。我们现在有一个功能齐全且美观的 JavaScript 线性仪表图!可以在CodePen上查看此线性量规初始版本的代码。

线性规初始版本

使图表可访问

确保尽可能多的人可以访问图表是一种很好的做法。因此,请记住 a11y,我们制作了更适合屏幕阅读器的线性仪表图的基本版本。您可以在此处查看此内容,还可以在 AnyChart JavaScript 库的文档中阅读有关此方面的更多信息。

自定义线性仪表

我们制作的默认线性仪表图表现在看起来很棒,但是进行一些修改将增强可读性并使图表更加出色。JavaScript 库不仅非常适合快速创建图表,还适合根据需要自定义可视化。图表库提供了许多用于控制图表行为和美观的配置选项。让我们对当前的线性仪表图进行一些小而有效的调整。

颜色修改

为了使线性仪表看起来更具凝聚力,让我们将条形指针的颜色属性设置为 LED 点的较暗版本。我们将通过指定栏的填充和描边属性来实现:

// Create and set bar point
const barSeries = gauge.bar(0);
barSeries
  .scale(scale)
  .width('4%')
  .fill('#296953')
  .stroke('#296953');

为我们的线性仪表图添加图例

由于我们为条形图、亮起和不亮起的 LED 指针使用了不同的颜色,因此最好提供一个图例来解释颜色。我们将制作一个图例并将其添加到图表标题下方:

// Create stand alone legend
const legend = anychart.standalones.legend();
legend
.position('center')
.items([
    { text: 'Fully vaccinated', iconFill: '#296953' },
    { text: 'Partially vaccinated', iconFill: '#63b39b' },
    { text: 'Not vaccinated', iconFill: '#eee' }
]);

工具提示格式

为了促进更好的数据通信,让我们通过以百分比形式显示值并指示仪表的最大值为 50% 来格式化工具提示以使其更具信息性:

// Set gauge tooltip
gauge
    .tooltip()
    .useHtml(true)
    .titleFormat('{%Value} %')
        .format(
        'Maximum on scale: ' +
        settings.maximum +
        ' %'
    );

在CodePen上查看此版本的完整代码。

轴和标签格式

我们要做的最后一件事是将所有数据值显示为百分比值以避免任何混淆。我们还将在标题下方的表格中添加一个副标题作为一行,以指示值是百分比。最后一件事是用更粗的字体美化条形标签。

线性规最终版

这个 JavaScript 线性仪表图的完整最终代码可以在CodePen上找到。

结论

在这个循序渐进的教程中,我们已经看到使用一个好的 JavaScript 库创建功能性和视觉上吸引人的 JavaScript 图表并不难。查看文档和示例,以更好地了解线性量规的特性和属性。如果对此图表或其他可视化有疑问,请提出任何问题。

AnyChart提供了多种图表选项,还有许多其他 JavaScript 图表库用于创建漂亮的可视化。

让我们都接种疫苗并保持健康,继续创造更多的可视化!

 来源:https ://www.sitepoint.com/create-linear-gauge-chart-javascript/

#javascript 

如何在 JavaScript 中创建线性仪表图
Iara  Simões

Iara Simões

1660429800

Como Criar Um Gráfico De Medidor Linear Em JavaScript

Mostraremos como criar rapidamente um gráfico de medidor linear interessante e interativo que destaca os dados de vacinação do Covid-19 em todo o mundo. Nosso gráfico nos permitirá visualizar o status da vacinação contra o Covid-19 no momento da redação e exibirá dois tipos de dados – mostrando a que distância estamos do objetivo intermediário de vacinar parcial e totalmente a população global.

imagem da capa do medidor linear

O que é um gráfico de medidor linear?

A visualização de dados é uma ferramenta inestimável, dada a grande quantidade de dados que estão sendo criados e as inúmeras possibilidades de coletar informações dos dados. A visualização de dados é particularmente útil para identificar tendências, interpretar padrões e comunicar ideias complexas ao público-alvo.

Um gráfico de medidor linear representa uma escala linear vertical ou horizontal que mostra os valores necessários, com uma escala de cores junto com ponteiros únicos ou múltiplos. Os valores mínimo e máximo do intervalo de dados podem ser definidos nos eixos de acordo com os dados que estão sendo representados. A posição do ponteiro indica o valor atual da métrica.

Um gráfico de medidor pode exibir um único valor ou vários valores usando um ponteiro individual ou uma combinação de marcadores. O ponteiro pode ser uma agulha ou uma linha com um marcador de qualquer forma, como um círculo, quadrado, retângulo ou triângulo.

O tipo de gráfico de medidor linear é uma representação visual eficaz para exibir quão próximos ou distantes os valores estão do ponto de dados desejado.

Tipos de medidores lineares

Os vários tipos de medidores lineares são gráfico de termômetro, gráfico de bala, gráfico de tanque e gráfico de LED. O termômetro de mercúrio — que consiste em pequenos tiques que exibem a temperatura com o valor do ponteiro — é um exemplo clássico de gráfico de medidor linear.

A visualização do medidor linear que estaremos construindo

Aqui está uma prévia do gráfico de medidor linear final. Siga este tutorial para saber como construímos este gráfico de medidor linear interessante e informativo com JavaScript.

versão final do gráfico de medidor linear

Os quatro passos para construir um medidor linear JavaScript

É sempre útil ter algumas habilidades com tecnologias como HTML e JavaScript. Mas neste tutorial, estamos usando uma biblioteca de gráficos JS que facilita a criação de gráficos atraentes, como o medidor linear, mesmo com o mínimo de conhecimento técnico.

Existem várias bibliotecas de gráficos JavaScript para visualizar dados com facilidade, e aqui estamos criando o gráfico de medidor linear com AnyChart . Esta biblioteca é flexível, com extensa documentação e contém alguns ótimos exemplos . Além disso, possui um playground para experimentar códigos e é gratuito para uso não comercial. Se você deseja comprar uma versão licenciada, pode conferir as opções disponíveis e, se for uma organização educacional ou sem fins lucrativos, pode entrar em contato para obter uma licença gratuita aqui .

As etapas para fazer um medidor linear JavaScript

Estas são as etapas básicas para criar um gráfico de medidor linear:

  1. Crie uma página HTML básica.
  2. Inclua os arquivos JavaScript necessários.
  3. Adicione os dados.
  4. Escreva o código JavaScript para o gráfico.

Vamos examinar cada uma dessas etapas em detalhes a seguir.

1. Crie uma página HTML básica

A primeira coisa que precisamos fazer é criar uma página HTML que conterá nossa visualização. Adicionamos um <div>elemento de bloco e damos a ele um ID para que possamos referenciá-lo mais tarde:

<html lang="en">
  <head>
    <title>JavaScript Linear Gauge</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>

Os atributos de largura e altura do <div>são definidos como 100% para que o gráfico seja renderizado em toda a tela. Esses atributos podem ser modificados de acordo com os requisitos.

2. Inclua os arquivos JavaScript necessários

A próxima etapa é fazer referência aos links JS na página HTML. Usaremos a biblioteca AnyChart para este tutorial, então vamos incluir os arquivos correspondentes de seu CDN .

Para criar um gráfico de medidor linear, precisaremos adicionar três scripts: o módulo principal , o módulo de medidor linear e o módulo de tabela :

<html lang="en">
  <head>
    <title>JavaScript Linear Gauge</title>
    <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 linear gauge will come here
    </script>
    <script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-core.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-linear-gauge.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-table.min.js"></script>
  </body>
</html>

3. Adicione os valores de dados

Os dados para o gráfico de medidor linear são coletados de Our World in Data e incluídos no código. Nesse site, podemos ver a porcentagem de pessoas que receberam uma e duas doses da vacina Covid para cada continente em todo o mundo.

Como (no momento em que escrevo) nenhum dos números é maior que 50%, mantivemos o limite máximo do eixo de todas as medidas lineares como 50% e comparamos a distância dessa marca de cada continente, bem como a figura global. Indicamos figuras pelo menos parcialmente vacinadas com representação de LED e os números totalmente vacinados com um ponteiro de barra. Veremos como os dados são adicionados na última etapa.

Então, nossos passos iniciais estão todos feitos, e agora vamos adicionar o código para fazer um gráfico de medidor linear com JavaScript!

4. Escreva o código JavaScript para o gráfico

Antes de adicionar qualquer código, colocamos tudo em uma função que garante que todo o código dentro dela seja executado apenas quando a página for carregada.

Criar um gráfico de medidor linear envolve algumas etapas e é um pouco mais complexo do que os outros tipos básicos de gráfico. Mas isso não significa que seja muito difícil, e passaremos por cada etapa para entender como o gráfico é feito.

Definindo a escala linear e o eixo para o gráfico de medidores

Temos vários ponteiros em nosso gráfico. Então, vamos começar fazendo uma função que aceita dois valores: um para o ponteiro da barra e outro para o medidor de LED. Em seguida, criaremos um medidor, definiremos os dados e especificaremos o layout como horizontal. Em seguida, definiremos o alcance das escalas e dos eixos. Faremos uma escala linear com os intervalos mínimo e máximo. Para o eixo, definiremos os atributos e definiremos a orientação:

function drawGauge(value, settings) {
  // Create gauge with settings
  const gauge = anychart.gauges.linear();
  gauge.data([value, settings.value]);
  gauge.layout('horizontal');

  // Set scale for gauge
  const scale = anychart.scales.linear();
  scale.minimum(0).maximum(settings.maximum).ticks({ interval: 2 });

  // Set axis for gauge
  const axis = gauge.axis(0);
  axis.width('1%').offset('43%').scale(scale).orientation('bottom');
}

Configurando o ponteiro da barra e o rótulo

Agora, vamos criar o ponteiro de barra e o rótulo para a série de barras. O rótulo recebe um deslocamento para evitar a sobreposição com o ponteiro:

// Create and set bar point
const barSeries = gauge.bar(0);

barSeries
  .scale(scale)
  .width('4%');

// Create and set label with actual data
const labelBar = barSeries.labels();
labelBar
  .enabled(true)
  .offsetY('-15px');

Criando o ponteiro de LED e definindo o atributo de cor

Nos pontos de LED, especificaremos o intervalo entre os pontos e usaremos a propriedade dimmer para definir a cor dos pontos de LED residuais para indicar um efeito apagado. Também declararemos a escala de cores dos pontos de LED acesos:

// Create and set LED point
const ledPointer = gauge.led(1);

ledPointer
  .offset('10%')
  .width('30%')
  .count(settings.maximum)
  .scale(scale)
  .gap(0.55)
  .dimmer(function () {
    return '#eee';
  });

ledPointer.colorScale().colors(['#63b39b', '#63b39b']);

Declarando os medidores com o valor alvo de cada ponto de dados

Para fazer o medidor linear para cada continente, chamaremos a função definida acima para cada região com seus dados. O primeiro número indica os dados do valor alvo e a segunda variável é um objeto com os dados do LED. O maximumpermanece uma constante 50, enquanto valueé o valor percentual da população totalmente vacinada para cada ponto de dados. Este valor será exibido pelo ponteiro:

// Create gauges
const world = drawGauge(13.68, { maximum: 50, value: 27.13 });
const europe = drawGauge(36.98, { maximum: 50, value: 47.28 });
const nAmerica = drawGauge(36.77, { maximum: 50, value: 46.53 });
const sAmerica = drawGauge(22.8, { maximum: 50, value: 40.54 });
const asia = drawGauge(10.14, { maximum: 50, value: 27.16 });
const oceania = drawGauge(9.75, { maximum: 50, value: 22.12 });
const africa = drawGauge(1.56, { maximum: 50, value: 3.04 });

Configurando o layout dos medidores lineares

Para exibir cada um dos medidores lineares um abaixo do outro, definiremos uma tabela e adicionaremos o título junto com cada ponto de dados como uma linha separada. Adicionaremos as várias propriedades do layout, como o alinhamento e o tamanho da fonte. Também definiremos parâmetros para a primeira linha, já que é o título, e definiremos o atributo largura da primeira coluna para 100%, pois não precisamos de mais colunas:

// Create table to place gauges
const layoutTable = anychart.standalones.table();
layoutTable
  .hAlign('right')
  .vAlign('middle')
  .fontSize(14)
  .cellBorder(null);

// Put gauges into the layout table
layoutTable.contents([
  [null, 'Covid-19 Vaccination - How far are we from the halfway mark?'],
  ['World', world],
  ['Europe', europe],
  ['North America', nAmerica],
  ['South America', sAmerica],
  ['Asia', asia],
  ['Oceania', oceania],
  ['Africa', africa]
]);

// Set height for first row in layout table
layoutTable
  .getRow(0)
  .height(50)
  .fontSize(22)
  .hAlign('center');

// Set the first column to 100% width
layoutTable.getCol(0).width(100);

Desenhando o gráfico

A última etapa é fazer referência ao <div>contêiner que adicionamos na etapa anterior e desenhar o gráfico:

// Set container id and initiate drawing
layoutTable.container('container');
layoutTable.draw();

E é isso. Agora temos um gráfico de medidor linear JavaScript totalmente funcional e bonito! O código para esta versão inicial do medidor linear pode ser visualizado no CodePen .

Versão inicial do medidor linear

Tornando o gráfico acessível

É sempre uma boa prática garantir que os gráficos sejam acessíveis ao maior número possível de pessoas. Assim, mantendo tudo em mente, criamos uma versão básica do gráfico de medidor linear que é mais adequada para leitores de tela. Você pode conferir isso aqui e também ler mais sobre esse aspecto na documentação da biblioteca JavaScript AnyChart.

Personalizando o medidor linear

O gráfico de medidor linear padrão que criamos parece incrível agora, mas fazer algumas modificações melhorará a legibilidade e tornará o gráfico ainda mais incrível. As bibliotecas JavaScript são perfeitas não apenas para criar gráficos rapidamente, mas também para personalizar as visualizações conforme necessário. As bibliotecas de gráficos oferecem muitas opções de configuração para controlar o comportamento e a estética dos gráficos. Vamos fazer alguns ajustes pequenos, mas eficazes, em nosso gráfico de medidor linear atual.

Modificação de cor

Para tornar o medidor linear mais coeso, vamos tornar o atributo de cor do ponteiro da barra uma versão mais escura dos pontos de LED. Faremos isso especificando os atributos de preenchimento e traçado da barra:

// Create and set bar point
const barSeries = gauge.bar(0);
barSeries
  .scale(scale)
  .width('4%')
  .fill('#296953')
  .stroke('#296953');

Adicionando uma legenda ao nosso gráfico de medidor linear

Como usamos cores diferentes para a barra, os ponteiros de LED acesos e não acesos, é uma boa prática fornecer uma legenda para explicar as cores. Faremos uma legenda e a adicionaremos abaixo do título do gráfico:

// Create stand alone legend
const legend = anychart.standalones.legend();
legend
.position('center')
.items([
    { text: 'Fully vaccinated', iconFill: '#296953' },
    { text: 'Partially vaccinated', iconFill: '#63b39b' },
    { text: 'Not vaccinated', iconFill: '#eee' }
]);

Formatação da dica de ferramenta

Para facilitar uma melhor comunicação de dados, vamos formatar a dica de ferramenta para torná-la mais informativa, exibindo os valores em forma de porcentagem e indicando que o valor máximo para o medidor é 50%:

// Set gauge tooltip
gauge
    .tooltip()
    .useHtml(true)
    .titleFormat('{%Value} %')
        .format(
        'Maximum on scale: ' +
        settings.maximum +
        ' %'
    );

Confira o código completo para esta versão no CodePen .

Formatação de eixos e rótulos

A última coisa que faremos é exibir todos os valores de dados como valores percentuais para evitar qualquer confusão. Também adicionaremos uma legenda como uma linha na tabela abaixo do título para indicar que os valores são porcentagens. Uma última coisa será embelezar os rótulos das barras com fontes mais ousadas.

Versão final do medidor linear

Todo o código final para este gráfico de medidor linear JavaScript pode ser encontrado no CodePen .

Conclusão

Neste tutorial passo a passo, vimos como criar gráficos JavaScript funcionais e visualmente atraentes não é muito difícil com uma boa biblioteca JavaScript. Confira a documentação e os exemplos para entender melhor os recursos e propriedades do medidor linear. Por favor, faça qualquer pergunta em caso de dúvida sobre este gráfico ou outras visualizações.

Existem várias opções de gráficos fornecidas pelo AnyChart e também existem muitas outras bibliotecas de gráficos JavaScript para criar belas visualizações.

Vamos todos nos vacinar e nos manter saudáveis ​​para continuar criando mais visualizações!

 Fonte: https://www.sitepoint.com/create-linear-gauge-chart-javascript/

#javascript 

Como Criar Um Gráfico De Medidor Linear Em JavaScript
Duong Tran

Duong Tran

1660428000

Cách Tạo Biểu Đồ Đo Tuyến Tính Trong JavaScript

Chúng tôi sẽ hướng dẫn cách tạo nhanh biểu đồ đo tuyến tính tương tác và thú vị làm nổi bật dữ liệu tiêm chủng Covid-19 trên khắp thế giới. Biểu đồ của chúng tôi sẽ cho phép chúng tôi hình dung tình trạng tiêm chủng Covid-19 tại thời điểm viết bài và sẽ hiển thị hai loại dữ liệu - cho biết chúng ta còn cách bao xa so với mục tiêu nửa đường là tiêm chủng một phần và toàn bộ cho dân số toàn cầu.

hình ảnh bìa máy đo tuyến tính

Biểu đồ đo tuyến tính là gì?

Trực quan hóa dữ liệu là một công cụ vô giá, với lượng lớn dữ liệu được tạo ra và nhiều khả năng thu thập thông tin từ dữ liệu. Trực quan hóa dữ liệu đặc biệt hữu ích để xác định xu hướng, diễn giải các mẫu và truyền đạt các ý tưởng phức tạp cho đối tượng mục tiêu.

Biểu đồ khổ tuyến tính đại diện cho thang đo tuyến tính dọc hoặc ngang hiển thị các giá trị cần thiết, với thang màu cùng với một hoặc nhiều con trỏ. Các giá trị tối thiểu và tối đa của phạm vi dữ liệu có thể được đặt trên các trục tùy theo dữ liệu được biểu diễn. Vị trí con trỏ cho biết giá trị hiện tại của chỉ số.

Biểu đồ đo có thể hiển thị một giá trị duy nhất hoặc nhiều giá trị bằng cách sử dụng một con trỏ riêng lẻ hoặc kết hợp các điểm đánh dấu. Con trỏ có thể là một kim hoặc một đường với điểm đánh dấu có hình dạng bất kỳ như hình tròn, hình vuông, hình chữ nhật hoặc hình tam giác.

Loại biểu đồ khổ tuyến tính là một biểu diễn trực quan hiệu quả để hiển thị mức độ gần hoặc xa của các giá trị so với điểm dữ liệu mong muốn.

Các loại đồng hồ đo tuyến tính

Một số loại đồng hồ đo tuyến tính là biểu đồ nhiệt kế, biểu đồ đạn, biểu đồ xe tăng và biểu đồ LED. Nhiệt kế thủy ngân - bao gồm các con ve nhỏ hiển thị nhiệt độ với giá trị con trỏ - là một ví dụ cổ điển của biểu đồ đo tuyến tính.

Hình ảnh hóa đơn vị đo tuyến tính mà chúng tôi sẽ xây dựng

Đây là một cái nhìn trước về biểu đồ đo tuyến tính cuối cùng. Thực hiện theo hướng dẫn này để tìm hiểu cách chúng tôi xây dựng biểu đồ đo tuyến tính thú vị và nhiều thông tin này bằng JavaScript.

biểu đồ khổ tuyến tính phiên bản cuối cùng

Bốn bước để tạo một JavaScript Linear Gauge

Việc có một số kỹ năng với các công nghệ như HTML và JavaScript luôn hữu ích. Nhưng trong hướng dẫn này, chúng tôi đang sử dụng thư viện biểu đồ JS giúp tạo các biểu đồ hấp dẫn như thước đo tuyến tính dễ dàng hơn ngay cả với kiến ​​thức kỹ thuật tối thiểu.

Có một số thư viện biểu đồ JavaScript để dễ dàng hiển thị dữ liệu và ở đây chúng tôi đang tạo biểu đồ đo tuyến tính với AnyChart . Thư viện này rất linh hoạt, với tài liệu phong phú và nó bao gồm một số ví dụ tuyệt vời . Hơn nữa, nó có một sân chơi để thử nghiệm với mã và miễn phí cho mục đích sử dụng phi thương mại. Nếu bạn muốn mua phiên bản được cấp phép, bạn có thể xem các tùy chọn có sẵn và nếu bạn là tổ chức giáo dục hoặc phi lợi nhuận, bạn có thể liên hệ để nhận giấy phép miễn phí tại đây .

Các bước để tạo JavaScript Linear Gauge

Đây là các bước cơ bản để tạo biểu đồ khổ tuyến tính:

  1. Tạo một trang HTML cơ bản.
  2. Bao gồm các tệp JavaScript cần thiết.
  3. Thêm dữ liệu.
  4. Viết mã JavaScript cho biểu đồ.

Chúng ta hãy xem xét chi tiết từng bước dưới đây.

1. Tạo một trang HTML cơ bản

Điều đầu tiên chúng ta cần làm là tạo một trang HTML để lưu giữ hình ảnh của chúng ta. Chúng tôi thêm một <div>phần tử khối và cung cấp cho nó một ID để chúng tôi có thể tham chiếu nó sau này:

<html lang="en">
  <head>
    <title>JavaScript Linear Gauge</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>

Thuộc tính chiều rộng và chiều cao của thuộc tính <div>này được đặt thành 100% để biểu đồ được hiển thị trên toàn bộ màn hình. Các thuộc tính này có thể được sửa đổi tùy theo yêu cầu.

2. Bao gồm các tệp JavaScript cần thiết

Bước tiếp theo là tham chiếu đến các liên kết JS trong trang HTML. Chúng tôi sẽ sử dụng thư viện AnyChart cho hướng dẫn này, vì vậy hãy bao gồm các tệp tương ứng từ CDN của chúng .

Để tạo biểu đồ khổ tuyến tính, chúng ta sẽ cần thêm ba tập lệnh: mô-đun cốt lõi , mô-đun máy đo tuyến tínhmô-đun bảng :

<html lang="en">
  <head>
    <title>JavaScript Linear Gauge</title>
    <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 linear gauge will come here
    </script>
    <script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-core.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-linear-gauge.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-table.min.js"></script>
  </body>
</html>

3. Thêm các giá trị dữ liệu

Dữ liệu cho biểu đồ khổ tuyến tính được thu thập từ Thế giới của chúng ta trong Dữ liệu và được đưa vào mã. Trên trang web đó, chúng tôi có thể thấy tỷ lệ phần trăm số người đã được tiêm một và hai liều vắc xin Covid cho mỗi châu lục trên toàn thế giới.

Bởi vì (tại thời điểm viết bài) không có con số nào lớn hơn 50%, chúng tôi đã giữ giới hạn tối đa của trục của tất cả các đồng hồ đo tuyến tính là 50% và chúng tôi so sánh khoảng cách từ mốc đó của mỗi lục địa, cũng như con số toàn cầu. Chúng tôi chỉ ra ít nhất các số liệu đã được tiêm chủng một phần với biểu thị bằng đèn LED và các số đã được tiêm chủng đầy đủ bằng một con trỏ vạch. Chúng ta sẽ xem cách dữ liệu được thêm vào trong bước cuối cùng.

Vậy là xong, các bước ban đầu của chúng ta đã xong, và bây giờ hãy thêm mã để tạo biểu đồ đo tuyến tính bằng JavaScript!

4. Viết mã JavaScript cho biểu đồ

Trước khi thêm bất kỳ mã nào, chúng tôi đặt mọi thứ trong một hàm đảm bảo rằng toàn bộ mã bên trong nó chỉ thực thi khi trang được tải.

Tạo biểu đồ khổ tuyến tính bao gồm một vài bước và phức tạp hơn một chút so với các loại biểu đồ cơ bản khác. Nhưng điều đó không có nghĩa là nó quá khó và chúng ta sẽ đi qua từng bước để hiểu cách biểu đồ được tạo ra.

Xác định tỷ lệ tuyến tính và trục cho biểu đồ đo

Chúng tôi có nhiều con trỏ trong biểu đồ của chúng tôi. Vì vậy, hãy bắt đầu với việc tạo một hàm chấp nhận hai giá trị: một cho con trỏ thanh và một cho đồng hồ đo LED. Sau đó, chúng tôi sẽ tạo một thước đo, đặt dữ liệu và chỉ định bố cục theo chiều ngang. Tiếp theo, chúng ta sẽ thiết lập phạm vi của tỷ lệ và trục. Chúng tôi sẽ tạo một thang đo tuyến tính với các phạm vi tối thiểu và tối đa. Đối với trục, chúng tôi sẽ xác định các thuộc tính và đặt hướng:

function drawGauge(value, settings) {
  // Create gauge with settings
  const gauge = anychart.gauges.linear();
  gauge.data([value, settings.value]);
  gauge.layout('horizontal');

  // Set scale for gauge
  const scale = anychart.scales.linear();
  scale.minimum(0).maximum(settings.maximum).ticks({ interval: 2 });

  // Set axis for gauge
  const axis = gauge.axis(0);
  axis.width('1%').offset('43%').scale(scale).orientation('bottom');
}

Đặt con trỏ thanh và nhãn

Bây giờ, chúng ta sẽ tạo con trỏ thanh và nhãn cho chuỗi thanh. Nhãn được cung cấp một độ lệch để tránh chồng chéo với con trỏ:

// Create and set bar point
const barSeries = gauge.bar(0);

barSeries
  .scale(scale)
  .width('4%');

// Create and set label with actual data
const labelBar = barSeries.labels();
labelBar
  .enabled(true)
  .offsetY('-15px');

Tạo con trỏ LED và thiết lập thuộc tính màu

Trong các điểm LED, chúng tôi sẽ chỉ định khoảng cách giữa các điểm và sử dụng thuộc tính điều chỉnh độ sáng để đặt màu của các điểm LED còn lại để chỉ ra hiệu ứng không sáng. Chúng tôi cũng sẽ khai báo thang màu của các điểm LED sáng:

// Create and set LED point
const ledPointer = gauge.led(1);

ledPointer
  .offset('10%')
  .width('30%')
  .count(settings.maximum)
  .scale(scale)
  .gap(0.55)
  .dimmer(function () {
    return '#eee';
  });

ledPointer.colorScale().colors(['#63b39b', '#63b39b']);

Khai báo các đồng hồ đo với giá trị mục tiêu của mỗi điểm dữ liệu

Để tạo thước đo tuyến tính cho mỗi lục địa, chúng tôi sẽ gọi hàm được xác định ở trên cho mọi khu vực với dữ liệu của nó. Số đầu tiên cho biết dữ liệu giá trị mục tiêu và biến thứ hai là một đối tượng có dữ liệu LED. Giá trị maximumkhông đổi vẫn là 50, trong khi đó valuelà giá trị phần trăm của dân số được tiêm chủng đầy đủ cho mỗi điểm dữ liệu. Giá trị này sẽ được hiển thị bởi con trỏ:

// Create gauges
const world = drawGauge(13.68, { maximum: 50, value: 27.13 });
const europe = drawGauge(36.98, { maximum: 50, value: 47.28 });
const nAmerica = drawGauge(36.77, { maximum: 50, value: 46.53 });
const sAmerica = drawGauge(22.8, { maximum: 50, value: 40.54 });
const asia = drawGauge(10.14, { maximum: 50, value: 27.16 });
const oceania = drawGauge(9.75, { maximum: 50, value: 22.12 });
const africa = drawGauge(1.56, { maximum: 50, value: 3.04 });

Thiết lập bố cục của đồng hồ đo tuyến tính

Để hiển thị từng đồng hồ đo tuyến tính dưới nhau, chúng tôi sẽ xác định một bảng và thêm tiêu đề cùng với mỗi điểm dữ liệu dưới dạng một hàng riêng biệt. Chúng tôi sẽ thêm các thuộc tính khác nhau của bố cục, chẳng hạn như căn chỉnh và kích thước phông chữ. Chúng tôi cũng sẽ xác định các tham số cho hàng đầu tiên, vì đó là tiêu đề và đặt thuộc tính width của cột đầu tiên thành 100% vì chúng tôi không cần thêm bất kỳ cột nào nữa:

// Create table to place gauges
const layoutTable = anychart.standalones.table();
layoutTable
  .hAlign('right')
  .vAlign('middle')
  .fontSize(14)
  .cellBorder(null);

// Put gauges into the layout table
layoutTable.contents([
  [null, 'Covid-19 Vaccination - How far are we from the halfway mark?'],
  ['World', world],
  ['Europe', europe],
  ['North America', nAmerica],
  ['South America', sAmerica],
  ['Asia', asia],
  ['Oceania', oceania],
  ['Africa', africa]
]);

// Set height for first row in layout table
layoutTable
  .getRow(0)
  .height(50)
  .fontSize(22)
  .hAlign('center');

// Set the first column to 100% width
layoutTable.getCol(0).width(100);

Vẽ biểu đồ

Bước cuối cùng là tham chiếu vùng <div>chứa mà chúng ta đã thêm ở bước trước và vẽ biểu đồ:

// Set container id and initiate drawing
layoutTable.container('container');
layoutTable.draw();

Và đó là nó. Bây giờ chúng ta có một biểu đồ đo tuyến tính JavaScript đầy đủ chức năng và đẹp mắt! Bạn có thể xem mã cho phiên bản ban đầu của thước đo tuyến tính này trên CodePen .

Phiên bản ban đầu của Máy đo tuyến tính

Làm cho Biểu đồ có thể truy cập được

Luôn luôn là một phương pháp hay để đảm bảo rằng nhiều người có thể truy cập các biểu đồ nhất có thể. Vì vậy, hãy ghi nhớ a11y, chúng tôi đã tạo một phiên bản cơ bản của biểu đồ đường đo tuyến tính phù hợp hơn với trình đọc màn hình. Bạn có thể kiểm tra điều này tại đây và cũng có thể đọc thêm về khía cạnh này trong tài liệu của thư viện JavaScript AnyChart.

Tùy chỉnh Máy đo tuyến tính

Biểu đồ đường đo tuyến tính mặc định mà chúng tôi đã tạo ra trông tuyệt vời ngay bây giờ, nhưng thực hiện một vài sửa đổi sẽ nâng cao khả năng đọc và làm cho biểu đồ thậm chí còn tuyệt vời hơn. Các thư viện JavaScript không chỉ hoàn hảo để tạo biểu đồ nhanh chóng mà còn để tùy chỉnh các hình ảnh trực quan theo yêu cầu. Các thư viện biểu đồ cung cấp rất nhiều tùy chọn cấu hình để kiểm soát hành vi và tính thẩm mỹ của biểu đồ. Hãy thực hiện một số chỉnh sửa nhỏ nhưng hiệu quả cho biểu đồ đo tuyến tính hiện tại của chúng tôi.

Sửa đổi màu sắc

Để làm cho thước đo tuyến tính trông gắn kết hơn, hãy làm cho thuộc tính màu của con trỏ thanh trở thành phiên bản tối hơn của các điểm LED. Chúng tôi sẽ điều đó bằng cách chỉ định các thuộc tính tô và nét của thanh:

// Create and set bar point
const barSeries = gauge.bar(0);
barSeries
  .scale(scale)
  .width('4%')
  .fill('#296953')
  .stroke('#296953');

Thêm chú giải vào biểu đồ khổ tuyến tính của chúng tôi

Vì chúng tôi đã sử dụng các màu sắc khác nhau cho thanh, con trỏ LED sáng và không sáng, nên việc cung cấp một chú giải để giải thích màu sắc là một phương pháp hay. Chúng tôi sẽ tạo một chú giải và thêm nó vào bên dưới tiêu đề của biểu đồ:

// Create stand alone legend
const legend = anychart.standalones.legend();
legend
.position('center')
.items([
    { text: 'Fully vaccinated', iconFill: '#296953' },
    { text: 'Partially vaccinated', iconFill: '#63b39b' },
    { text: 'Not vaccinated', iconFill: '#eee' }
]);

Định dạng chú giải công cụ

Để tạo điều kiện giao tiếp dữ liệu tốt hơn, hãy định dạng chú giải công cụ để làm cho nó có nhiều thông tin hơn bằng cách hiển thị các giá trị ở dạng phần trăm và chỉ ra rằng giá trị tối đa cho thước đo là 50%:

// Set gauge tooltip
gauge
    .tooltip()
    .useHtml(true)
    .titleFormat('{%Value} %')
        .format(
        'Maximum on scale: ' +
        settings.maximum +
        ' %'
    );

Kiểm tra toàn bộ mã cho phiên bản này trên CodePen .

Định dạng trục và nhãn

Điều cuối cùng chúng tôi sẽ làm là hiển thị tất cả các giá trị dữ liệu dưới dạng giá trị phần trăm để tránh bất kỳ sự nhầm lẫn nào. Chúng tôi cũng sẽ thêm phụ đề dưới dạng một hàng trong bảng bên dưới tiêu đề để cho biết rằng các giá trị là tỷ lệ phần trăm. Một điều cuối cùng sẽ là làm đẹp các nhãn thanh với phông chữ đậm hơn.

Phiên bản cuối cùng của Máy đo tuyến tính

Toàn bộ mã cuối cùng cho biểu đồ đo tuyến tính JavaScript này có thể được tìm thấy trên CodePen .

Sự kết luận

Trong hướng dẫn từng bước này, chúng ta đã thấy cách tạo các biểu đồ JavaScript hấp dẫn về mặt chức năng và trực quan không quá khó với một thư viện JavaScript tốt. Kiểm tra tài liệu và ví dụ để hiểu rõ hơn về các tính năng và đặc tính của khổ tuyến tính. Vui lòng đặt bất kỳ câu hỏi nào nếu nghi ngờ về biểu đồ này hoặc các hình ảnh trực quan khác.

Có nhiều tùy chọn biểu đồ được cung cấp bởi AnyChart và có nhiều thư viện biểu đồ JavaScript khác cũng để tạo hình ảnh trực quan đẹp mắt.

Tất cả chúng ta hãy đi tiêm phòng và giữ gìn sức khỏe để bắt đầu với việc tạo ra nhiều hình dung hơn!

 Nguồn: https://www.sitepoint.com/create-linear-gauge-chart-javascript/

#javascript 

Cách Tạo Biểu Đồ Đo Tuyến Tính Trong JavaScript
Saul  Alaniz

Saul Alaniz

1660426200

Crear Un Gráfico De Indicadores Lineales En JavaScript

Le mostraremos cómo crear rápidamente un gráfico de indicador lineal atractivo e interactivo que destaque los datos de vacunación contra el Covid-19 en todo el mundo. Nuestro gráfico nos permitirá visualizar el estado de la vacunación contra el covid-19 en el momento de escribir este artículo y mostrará dos tipos de datos, que mostrarán lo lejos que estamos del objetivo medio de vacunar parcial y totalmente a la población mundial.

imagen de portada de calibre lineal

¿Qué es un gráfico de calibre lineal?

La visualización de datos es una herramienta invaluable, dada la gran cantidad de datos que se crean y las numerosas posibilidades para obtener información de los datos. La visualización de datos es particularmente útil para identificar tendencias, interpretar patrones y comunicar ideas complejas al público objetivo.

Un gráfico de indicadores lineales representa una escala lineal vertical u horizontal que muestra los valores requeridos, con una escala de colores junto con punteros únicos o múltiples. Los valores mínimo y máximo del rango de datos se pueden establecer sobre los ejes de acuerdo con los datos que se representan. La posición del puntero indica el valor actual de la métrica.

Un gráfico de indicadores puede mostrar un solo valor o varios valores utilizando un puntero individual o una combinación de marcadores. El puntero puede ser una aguja o una línea con un marcador de cualquier forma, como un círculo, un cuadrado, un rectángulo o un triángulo.

El tipo de gráfico de indicador lineal es una representación visual eficaz para mostrar qué tan cerca o lejos están los valores del punto de datos deseado.

Tipos de calibres lineales

Los diversos tipos de medidores lineales son el gráfico de termómetro, el gráfico de viñetas, el gráfico de tanque y el gráfico de LED. El termómetro de mercurio, que consiste en marcas menores que muestran la temperatura con el valor del puntero, es un ejemplo clásico de un gráfico de calibre lineal.

La visualización de calibre lineal que construiremos

Aquí hay un adelanto del gráfico de calibre lineal final. Siga este tutorial para aprender cómo creamos este interesante e informativo gráfico de indicadores lineales con JavaScript.

versión final del gráfico de calibre lineal

Los cuatro pasos para construir un indicador lineal de JavaScript

Siempre es útil tener algunas habilidades con tecnologías como HTML y JavaScript. Pero en este tutorial, estamos usando una biblioteca de gráficos JS que facilita la creación de gráficos atractivos como el indicador lineal, incluso con conocimientos técnicos mínimos.

Hay varias bibliotecas de gráficos de JavaScript para visualizar datos con facilidad, y aquí estamos creando el gráfico de indicadores lineales con AnyChart . Esta biblioteca es flexible, con una extensa documentación , y consta de algunos excelentes ejemplos . Además, tiene un área de juegos para experimentar con el código y es gratuito para uso no comercial. Si desea comprar una versión con licencia, puede consultar las opciones disponibles , y si es una organización educativa o sin fines de lucro, puede ponerse en contacto para obtener una licencia gratuita aquí .

Los pasos para hacer un indicador lineal de JavaScript

Estos son los pasos básicos para crear un gráfico de indicadores lineales:

  1. Crea una página HTML básica.
  2. Incluya los archivos JavaScript necesarios.
  3. Agrega los datos.
  4. Escriba el código JavaScript para el gráfico.

Veamos cada uno de estos pasos en detalle a continuación.

1. Crea una página HTML básica

Lo primero que debemos hacer es crear una página HTML que contenga nuestra visualización. Agregamos un <div>elemento de bloque y le damos una ID para que podamos hacer referencia a él más tarde:

<html lang="en">
  <head>
    <title>JavaScript Linear Gauge</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>

Los atributos de ancho y alto de <div>están configurados al 100% para que el gráfico se represente en toda la pantalla. Estos atributos se pueden modificar según los requisitos.

2. Incluya los archivos JavaScript necesarios

El siguiente paso es hacer referencia a los enlaces JS en la página HTML. Usaremos la biblioteca AnyChart para este tutorial, así que incluyamos los archivos correspondientes de su CDN .

Para crear un gráfico de indicador lineal, necesitaremos agregar tres scripts: el módulo principal , el módulo de indicador lineal y el módulo de tabla :

<html lang="en">
  <head>
    <title>JavaScript Linear Gauge</title>
    <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 linear gauge will come here
    </script>
    <script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-core.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-linear-gauge.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-table.min.js"></script>
  </body>
</html>

3. Agregue los valores de los datos

Los datos para el gráfico de indicadores lineales se recopilan de Our World in Data y se incluyen en el código. En ese sitio, podemos ver el porcentaje de personas que han recibido una y dos dosis de la vacuna Covid para cada continente en todo el mundo.

Debido a que (en el momento de escribir este artículo) ninguno de los números supera el 50 %, hemos mantenido el límite máximo del eje de todos los indicadores lineales en el 50 % y comparamos qué tan lejos de esa marca está cada continente, así como la cifra global. Indicamos las cifras al menos parcialmente vacunadas con representación LED y los números completamente vacunados con un puntero de barra. Veremos cómo se agregan los datos en el último paso.

Entonces, todos nuestros pasos iniciales están listos, ¡y ahora agreguemos el código para hacer un gráfico de indicador lineal con JavaScript!

4. Escriba el código JavaScript para el gráfico

Antes de agregar cualquier código, encerramos todo en una función que se asegura de que todo el código dentro se ejecute solo una vez que se carga la página.

Crear un gráfico de indicadores lineales implica un par de pasos y es un poco más complejo que los otros tipos de gráficos básicos. Pero eso no significa que sea muy difícil, y repasaremos cada paso para entender cómo se hace el gráfico.

Definición de la escala lineal y el eje para el gráfico de indicadores

Tenemos varios punteros en nuestro gráfico. Entonces, comencemos creando una función que acepte dos valores: uno para el puntero de barra y otro para el indicador LED. Luego crearemos un indicador, estableceremos los datos y especificaremos el diseño como horizontal. A continuación, estableceremos el rango de las escalas y los ejes. Haremos una escala lineal con los rangos mínimo y máximo. Para el eje, definiremos los atributos y estableceremos la orientación:

function drawGauge(value, settings) {
  // Create gauge with settings
  const gauge = anychart.gauges.linear();
  gauge.data([value, settings.value]);
  gauge.layout('horizontal');

  // Set scale for gauge
  const scale = anychart.scales.linear();
  scale.minimum(0).maximum(settings.maximum).ticks({ interval: 2 });

  // Set axis for gauge
  const axis = gauge.axis(0);
  axis.width('1%').offset('43%').scale(scale).orientation('bottom');
}

Configuración del puntero de barra y la etiqueta

Ahora, crearemos el puntero de la barra y la etiqueta para la serie de barras. La etiqueta recibe un desplazamiento para evitar la superposición con el puntero:

// Create and set bar point
const barSeries = gauge.bar(0);

barSeries
  .scale(scale)
  .width('4%');

// Create and set label with actual data
const labelBar = barSeries.labels();
labelBar
  .enabled(true)
  .offsetY('-15px');

Creación del puntero LED y configuración del atributo de color

En los puntos LED, especificaremos el espacio entre los puntos y usaremos la propiedad del atenuador para establecer el color de los puntos LED residuales para indicar un efecto no iluminado. También declararemos la escala de colores de los puntos LED encendidos:

// Create and set LED point
const ledPointer = gauge.led(1);

ledPointer
  .offset('10%')
  .width('30%')
  .count(settings.maximum)
  .scale(scale)
  .gap(0.55)
  .dimmer(function () {
    return '#eee';
  });

ledPointer.colorScale().colors(['#63b39b', '#63b39b']);

Declaración de los indicadores con el valor objetivo de cada punto de datos

Para hacer el indicador lineal para cada continente, llamaremos a la función definida anteriormente para cada región con sus datos. El primer número indica los datos del valor objetivo y la segunda variable es un objeto con los datos del LED. maximumpermanece constante en 50, mientras que es el valuevalor porcentual de la población completamente vacunada para cada punto de datos. Este valor será mostrado por el puntero:

// Create gauges
const world = drawGauge(13.68, { maximum: 50, value: 27.13 });
const europe = drawGauge(36.98, { maximum: 50, value: 47.28 });
const nAmerica = drawGauge(36.77, { maximum: 50, value: 46.53 });
const sAmerica = drawGauge(22.8, { maximum: 50, value: 40.54 });
const asia = drawGauge(10.14, { maximum: 50, value: 27.16 });
const oceania = drawGauge(9.75, { maximum: 50, value: 22.12 });
const africa = drawGauge(1.56, { maximum: 50, value: 3.04 });

Configuración del diseño de los indicadores lineales

Para mostrar cada uno de los indicadores lineales uno debajo del otro, definiremos una tabla y agregaremos el título junto con cada punto de datos como una fila separada. Agregaremos las diversas propiedades del diseño, como la alineación y el tamaño de fuente. También definiremos parámetros para la primera fila, ya que es el título, y estableceremos el atributo de ancho de la primera columna al 100 %, ya que no necesitamos más columnas:

// Create table to place gauges
const layoutTable = anychart.standalones.table();
layoutTable
  .hAlign('right')
  .vAlign('middle')
  .fontSize(14)
  .cellBorder(null);

// Put gauges into the layout table
layoutTable.contents([
  [null, 'Covid-19 Vaccination - How far are we from the halfway mark?'],
  ['World', world],
  ['Europe', europe],
  ['North America', nAmerica],
  ['South America', sAmerica],
  ['Asia', asia],
  ['Oceania', oceania],
  ['Africa', africa]
]);

// Set height for first row in layout table
layoutTable
  .getRow(0)
  .height(50)
  .fontSize(22)
  .hAlign('center');

// Set the first column to 100% width
layoutTable.getCol(0).width(100);

Dibujar el gráfico

El último paso es hacer referencia al <div>contenedor que agregamos en el paso anterior y dibujar el gráfico:

// Set container id and initiate drawing
layoutTable.container('container');
layoutTable.draw();

Y eso es. ¡Ahora tenemos un gráfico de calibre lineal de JavaScript completamente funcional y hermoso! El código de esta versión inicial del indicador lineal se puede ver en CodePen .

Versión inicial de calibre lineal

Hacer que el gráfico sea accesible

Siempre es una buena práctica asegurarse de que los gráficos sean accesibles para la mayor cantidad de personas posible. Entonces, teniendo todo en cuenta, creamos una versión básica del gráfico de indicadores lineales que se adapta mejor a los lectores de pantalla. Puede consultar esto aquí y también leer más sobre este aspecto en la documentación de la biblioteca AnyChart JavaScript.

Personalización del indicador lineal

El gráfico de indicador lineal predeterminado que hemos creado se ve increíble en este momento, pero hacer algunas modificaciones mejorará la legibilidad y hará que el gráfico sea aún más impresionante. Las bibliotecas de JavaScript son perfectas no solo para crear gráficos rápidamente, sino también para personalizar las visualizaciones según sea necesario. Las bibliotecas de gráficos ofrecen muchas opciones de configuración para controlar el comportamiento y la estética de los gráficos. Hagamos algunos ajustes pequeños pero efectivos a nuestro gráfico de indicadores lineales actual.

Modificación de color

Para hacer que el indicador lineal se vea más cohesivo, hagamos que el atributo de color del puntero de barra sea una versión más oscura de los puntos LED. Lo haremos especificando los atributos de relleno y trazo de la barra:

// Create and set bar point
const barSeries = gauge.bar(0);
barSeries
  .scale(scale)
  .width('4%')
  .fill('#296953')
  .stroke('#296953');

Agregar una leyenda a nuestro gráfico de indicadores lineales

Dado que hemos usado diferentes colores para la barra, los punteros LED iluminados y no iluminados, es una buena práctica proporcionar una leyenda para explicar los colores. Haremos una leyenda y la agregaremos debajo del título del gráfico:

// Create stand alone legend
const legend = anychart.standalones.legend();
legend
.position('center')
.items([
    { text: 'Fully vaccinated', iconFill: '#296953' },
    { text: 'Partially vaccinated', iconFill: '#63b39b' },
    { text: 'Not vaccinated', iconFill: '#eee' }
]);

Formato de información sobre herramientas

Para facilitar una mejor comunicación de datos, formateemos la información sobre herramientas para que sea más informativa mostrando los valores en forma de porcentaje e indicando que el valor máximo para el indicador es 50%:

// Set gauge tooltip
gauge
    .tooltip()
    .useHtml(true)
    .titleFormat('{%Value} %')
        .format(
        'Maximum on scale: ' +
        settings.maximum +
        ' %'
    );

Consulte el código completo de esta versión en CodePen .

Formato de ejes y etiquetas

Lo último que haremos será mostrar todos los valores de los datos como valores porcentuales para evitar confusiones. También agregaremos un subtítulo como fila en la tabla debajo del título para indicar que los valores son porcentajes. Una última cosa será embellecer las etiquetas de la barra con fuentes más audaces.

Versión final de calibre lineal

El código final completo para este gráfico de indicadores lineales de JavaScript se puede encontrar en CodePen .

Conclusión

En este tutorial paso a paso, hemos visto cómo crear gráficos de JavaScript funcionales y visualmente atractivos no es demasiado difícil con una buena biblioteca de JavaScript. Consulte la documentación y los ejemplos para comprender mejor las características y propiedades del indicador lineal. Haga cualquier pregunta si tiene dudas sobre este gráfico u otras visualizaciones.

Hay múltiples opciones de gráficos proporcionadas por AnyChart , y también hay muchas otras bibliotecas de gráficos de JavaScript para crear hermosas visualizaciones.

¡Vacunémonos todos y mantengámonos saludables para seguir creando más visualizaciones!

 Fuente: https://www.sitepoint.com/create-linear-gauge-chart-javascript/

#javascript 

Crear Un Gráfico De Indicadores Lineales En JavaScript
伊藤  直子

伊藤 直子

1660424700

JavaScript でリニア ゲージ チャートを作成する

世界中の Covid-19 ワクチン接種データを強調する、クールでインタラクティブな線形ゲージ チャートをすばやく作成する方法を紹介します。私たちのグラフは、執筆時点での Covid-19 ワクチン接種の状況を視覚化することを可能にし、2 種類のデータを表示します。これは、世界人口に部分的および完全にワクチン接種するという中間目標からどれだけ離れているかを示します。

リニアゲージカバー画像

リニア ゲージ チャートとは

膨大な量のデータが作成され、データから情報を収集する可能性が数多くあることを考えると、データの視覚化は非常に貴重なツールです。データの視覚化は、傾向の特定、パターンの解釈、複雑なアイデアの対象者への伝達に特に役立ちます。

線形ゲージ チャートは、必要な値を示す垂直または水平の線形スケールを表し、カラー スケールと 1 つまたは複数のポインターを備えています。データ範囲の最小値と最大値は、表示されるデータに従って、軸上に設定できます。ポインターの位置は、メトリックの現在の値を示します。

ゲージ チャートでは、個々のポインターまたはマーカーの組み合わせを使用して、単一の値または複数の値を表示できます。ポインターは、円、正方形、長方形、三角形などの任意の形状のマーカーが付いた針または線にすることができます。

線形ゲージ チャート タイプは、値が目的のデータ ポイントにどれだけ近いか、またはどれだけ離れているかを表示するための効果的な視覚的表現です。

リニアゲージの種類

リニア ゲージには、温度計チャート、ブレット チャート、タンク チャート、LED チャートなどがあります。水銀温度計は、ポインター値で温度を表示する小さな目盛りで構成されており、リニア ゲージ チャートの典型的な例です。

構築する線形ゲージの視覚化

これは、最終的な線形ゲージ チャートのこっそりのぞき見です。このチュートリアルに従って、この興味深く有益な線形ゲージ チャートを JavaScript で作成する方法を学びましょう。

リニア ゲージ チャート最終版

JavaScript リニア ゲージを構築するための 4 つのステップ

HTML や JavaScript などのテクノロジに関するスキルを持っていると、常に役に立ちます。しかし、このチュートリアルでは、最小限の技術的知識でもリニア ゲージのような魅力的なグラフを簡単に作成できるようにする JS グラフ作成ライブラリを使用しています。

データを簡単に視覚化するためのJavaScript グラフ作成ライブラリがいくつかあります。ここでは、AnyChartを使用して線形ゲージ グラフを作成しています。このライブラリは柔軟で、豊富なドキュメントがあり、いくつかの優れた例で構成されています。さらに、コードを試すための遊び場があり、非営利目的での使用は無料です。ライセンス版を購入したい場合は、利用可能なオプションを確認してください。教育機関または非営利団体の場合は、こちらから無料ライセンスを入手できます。

JavaScript リニア ゲージを作成する手順

以下は、線形ゲージ チャートを作成するための基本的な手順です。

  1. 基本的な HTML ページを作成します。
  2. 必要な JavaScript ファイルを含めます。
  3. データを追加します。
  4. グラフの JavaScript コードを記述します。

これらの各ステップについて、以下で詳しく見ていきましょう。

1. 基本的な HTML ページを作成する

最初に、ビジュアライゼーションを保持する HTML ページを作成する必要があります。ブロック要素を追加し<div>て ID を付与し、後で参照できるようにします。

<html lang="en">
  <head>
    <title>JavaScript Linear Gauge</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>

の幅と高さの属性は<div>100% に設定されているため、グラフは画面全体に表示されます。これらの属性は、要件に従って変更できます。

2. 必要な JavaScript ファイルを含める

次のステップは、HTML ページで JS リンクを参照することです。このチュートリアルでは AnyChart ライブラリを使用するため、対応するファイルをCDNから含めましょう。

リニア ゲージ チャートを作成するには、コア モジュールリニア ゲージ モジュール、およびテーブル モジュールの 3 つのスクリプトを追加する必要があります。

<html lang="en">
  <head>
    <title>JavaScript Linear Gauge</title>
    <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 linear gauge will come here
    </script>
    <script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-core.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-linear-gauge.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-table.min.js"></script>
  </body>
</html>

3. データ値を追加する

線形ゲージ チャートのデータは、Our World in Dataから収集され、コードに含まれています。そのサイトでは、全世界の各大陸で1 回または 2 回の Covidワクチン接種を受けた人の割合を確認できます。

(執筆時点では) 50% を超える数値は存在しないため、すべてのリニア ゲージの軸の上限を 50% に維持し、各大陸がそのマークからどれだけ離れているかを比較します。世界的な数字だけでなく。少なくとも部分的にワクチン接種された数字は LED 表示で示され、完全にワクチン接種された数字はバー ポインターで示されます。最後のステップでデータがどのように追加されるかを見ていきます。

これで、最初のステップはすべて完了しました。コードを追加して、JavaScript で線形ゲージ チャートを作成しましょう。

4. チャートの JavaScript コードを書く

コードを追加する前に、ページが読み込まれたときにのみコード全体が実行されるように、すべてを関数で囲みます。

線形ゲージ チャートの作成にはいくつかの手順が必要で、他の基本的なチャート タイプよりも少し複雑です。しかし、それは非常に難しいという意味ではありません。チャートがどのように作成されるかを理解するために、各ステップを進めていきます。

ゲージ チャートの線形スケールと軸の定義

チャートには複数のポインターがあります。それでは、2 つの値を受け入れる関数を作成することから始めましょう。1 つはバー ポインター用で、もう 1 つは LED ゲージ用です。次に、ゲージを作成し、データを設定して、レイアウトを水平に指定します。次に、スケールと軸の範囲を設定します。最小範囲と最大範囲で線形スケールを作成します。軸については、属性を定義し、方向を設定します。

function drawGauge(value, settings) {
  // Create gauge with settings
  const gauge = anychart.gauges.linear();
  gauge.data([value, settings.value]);
  gauge.layout('horizontal');

  // Set scale for gauge
  const scale = anychart.scales.linear();
  scale.minimum(0).maximum(settings.maximum).ticks({ interval: 2 });

  // Set axis for gauge
  const axis = gauge.axis(0);
  axis.width('1%').offset('43%').scale(scale).orientation('bottom');
}

バーポインタとラベルの設定

次に、バー ポインターとバー シリーズのラベルを作成します。ポインターとのオーバーラップを避けるために、ラベルにはオフセットが与えられます。

// Create and set bar point
const barSeries = gauge.bar(0);

barSeries
  .scale(scale)
  .width('4%');

// Create and set label with actual data
const labelBar = barSeries.labels();
labelBar
  .enabled(true)
  .offsetY('-15px');

LED ポインターの作成と色属性の設定

LED ポイントでは、ポイント間のギャップを指定し、dimmer プロパティを使用して残りの LED ポイントの色を設定し、非点灯効果を示します。点灯している LED ポイントのカラー スケールも宣言します。

// Create and set LED point
const ledPointer = gauge.led(1);

ledPointer
  .offset('10%')
  .width('30%')
  .count(settings.maximum)
  .scale(scale)
  .gap(0.55)
  .dimmer(function () {
    return '#eee';
  });

ledPointer.colorScale().colors(['#63b39b', '#63b39b']);

各データ ポイントの目標値を使用してゲージを宣言する

各大陸の線形ゲージを作成するために、データを使用してすべての地域に対して上記で定義した関数を呼び出します。最初の数値は目標値データを示し、2 番目の変数は LED データを持つオブジェクトです。maximumは一定の 50 のままですvalueが、 は各データ ポイントの完全にワクチン接種された人口のパーセント値です。この値はポインターによって表示されます。

// Create gauges
const world = drawGauge(13.68, { maximum: 50, value: 27.13 });
const europe = drawGauge(36.98, { maximum: 50, value: 47.28 });
const nAmerica = drawGauge(36.77, { maximum: 50, value: 46.53 });
const sAmerica = drawGauge(22.8, { maximum: 50, value: 40.54 });
const asia = drawGauge(10.14, { maximum: 50, value: 27.16 });
const oceania = drawGauge(9.75, { maximum: 50, value: 22.12 });
const africa = drawGauge(1.56, { maximum: 50, value: 3.04 });

リニア ゲージのレイアウトの設定

各リニア ゲージを上下に表示するには、テーブルを定義し、タイトルを各データ ポイントと共に個別の行として追加します。配置やフォント サイズなど、レイアウトのさまざまなプロパティを追加します。また、最初の行はタイトルなのでパラメーターを定義し、最初の列の width 属性を 100% に設定します。これ以上の列は必要ないからです。

// Create table to place gauges
const layoutTable = anychart.standalones.table();
layoutTable
  .hAlign('right')
  .vAlign('middle')
  .fontSize(14)
  .cellBorder(null);

// Put gauges into the layout table
layoutTable.contents([
  [null, 'Covid-19 Vaccination - How far are we from the halfway mark?'],
  ['World', world],
  ['Europe', europe],
  ['North America', nAmerica],
  ['South America', sAmerica],
  ['Asia', asia],
  ['Oceania', oceania],
  ['Africa', africa]
]);

// Set height for first row in layout table
layoutTable
  .getRow(0)
  .height(50)
  .fontSize(22)
  .hAlign('center');

// Set the first column to 100% width
layoutTable.getCol(0).width(100);

チャートを描く

最後のステップは<div>、前のステップで追加したコンテナーを参照し、グラフを描画することです。

// Set container id and initiate drawing
layoutTable.container('container');
layoutTable.draw();

以上です。完全に機能する美しい JavaScript 線形ゲージ チャートが完成しました。リニア ゲージのこの初期バージョンのコードは、CodePenで表示できます。

リニアゲージ初期バージョン

グラフをアクセス可能にする

できるだけ多くの人がグラフにアクセスできるようにすることは、良い習慣です。そのため、a11y を念頭に置いて、スクリーン リーダーにより適した線形ゲージ チャートの基本バージョンを作成しました。こちらで確認できます。また、AnyChart JavaScript ライブラリのドキュメントでこの側面について詳しく読むこともできます。

リニア ゲージのカスタマイズ

作成したデフォルトの線形ゲージ チャートは今のところ見栄えがしますが、いくつかの変更を加えることで読みやすさが向上し、チャートがさらに素晴らしいものになります。JavaScript ライブラリは、グラフをすばやく作成するだけでなく、必要に応じて視覚化をカスタマイズするのにも最適です。チャート ライブラリは、チャートの動作と美学を制御するための多くの構成オプションを提供します。現在のリニア ゲージ チャートに小さいながらも効果的な微調整を加えてみましょう。

色の変更

線形ゲージをよりまとまりのあるものにするために、バー ポインターの色属性を LED ポイントのより暗いバージョンにしましょう。バーの塗りと線の属性を指定することでそれを実現します。

// Create and set bar point
const barSeries = gauge.bar(0);
barSeries
  .scale(scale)
  .width('4%')
  .fill('#296953')
  .stroke('#296953');

線形ゲージ チャートに凡例を追加する

バー、点灯および非点灯の LED ポインターに異なる色を使用したため、色を説明する凡例を提供することをお勧めします。凡例を作成し、チャートのタイトルの下に追加します。

// Create stand alone legend
const legend = anychart.standalones.legend();
legend
.position('center')
.items([
    { text: 'Fully vaccinated', iconFill: '#296953' },
    { text: 'Partially vaccinated', iconFill: '#63b39b' },
    { text: 'Not vaccinated', iconFill: '#eee' }
]);

ツールチップの書式設定

より良いデータ通信を促進するために、値をパーセンテージ形式で表示し、ゲージの最大値が 50% であることを示すことで、ツールチップをフォーマットして、より情報を提供できるようにしましょう。

// Set gauge tooltip
gauge
    .tooltip()
    .useHtml(true)
    .titleFormat('{%Value} %')
        .format(
        'Maximum on scale: ' +
        settings.maximum +
        ' %'
    );

CodePenでこのバージョンのコード全体を確認してください。

軸とラベルの書式設定

最後に、混乱を避けるために、すべてのデータ値をパーセンテージ値として表示します。また、タイトルの下のテーブルにサブタイトルを行として追加して、値がパーセンテージであることを示します。最後の 1 つのことは、バーのラベルをより太字のフォントで美しくすることです。

リニアゲージ最終バージョン

この JavaScript 線形ゲージ チャートの最終的なコード全体はCodePenにあります。

結論

この段階的なチュートリアルでは、優れた JavaScript ライブラリを使用すれば、機能的で視覚的に魅力的な JavaScript グラフを作成することがそれほど難しくないことを確認しました。ドキュメントと例を確認して、リニア ゲージの機能とプロパティをよりよく理解してください。このチャートや他のビジュアライゼーションについて疑問がある場合は、質問してください。

AnyChartには複数のチャート オプションが用意されており、他にも美しい視覚化を作成するための JavaScript チャート作成ライブラリが多数あります。

予防接種を受けて健康を維持し、より多くのビジュアライゼーションを作成していきましょう!

 ソース: https://www.sitepoint.com/create-linear-gauge-chart-javascript/

#javascript 

JavaScript でリニア ゲージ チャートを作成する
Léon  Peltier

Léon Peltier

1660422600

Créer Un Graphique De Jauge Linéaire En JavaScript

Nous montrerons comment créer rapidement un graphique de jauge linéaire cool et interactif qui met en évidence les données de vaccination Covid-19 dans le monde. Notre graphique nous permettra de visualiser l'état de la vaccination contre le Covid-19 au moment de la rédaction et affichera deux types de données - montrant à quelle distance nous sommes de l'objectif à mi-chemin de la vaccination partielle et complète de la population mondiale.

image de couverture de jauge linéaire

Qu'est-ce qu'un graphique à jauge linéaire ?

La visualisation des données est un outil inestimable, compte tenu de la grande quantité de données créées et des nombreuses possibilités de glaner des informations à partir des données. La visualisation des données est particulièrement utile pour identifier les tendances, interpréter les modèles et communiquer des idées complexes au public cible.

Un graphique à jauge linéaire représente une échelle linéaire verticale ou horizontale qui affiche les valeurs requises, avec une échelle de couleurs ainsi qu'un ou plusieurs pointeurs. Les valeurs minimales et maximales de la plage de données peuvent être définies sur les axes en fonction des données représentées. La position du pointeur indique la valeur actuelle de la métrique.

Un graphique à jauge peut afficher une ou plusieurs valeurs à l'aide d'un pointeur individuel ou d'une combinaison de marqueurs. Le pointeur peut être une aiguille ou une ligne avec un marqueur de n'importe quelle forme comme un cercle, un carré, un rectangle ou un triangle.

Le type de graphique à jauge linéaire est une représentation visuelle efficace pour afficher à quel point les valeurs sont proches ou éloignées du point de données souhaité.

Types de jauges linéaires

Les différents types de jauges linéaires sont le tableau de thermomètre, le tableau à puces, le tableau de réservoir et le tableau à LED. Le thermomètre à mercure - composé de graduations mineures qui affichent la température avec la valeur du pointeur - est un exemple classique de graphique à jauge linéaire.

La visualisation de jauge linéaire que nous allons construire

Voici un aperçu du graphique de jauge linéaire final. Suivez ce didacticiel pour savoir comment nous construisons ce graphique à jauge linéaire intéressant et informatif avec JavaScript.

graphique à jauge linéaire version finale

Les quatre étapes pour créer une jauge linéaire JavaScript

Il est toujours utile d'avoir des compétences avec des technologies comme HTML et JavaScript. Mais dans ce didacticiel, nous utilisons une bibliothèque de graphiques JS qui facilite la création de graphiques convaincants comme la jauge linéaire, même avec des connaissances techniques minimales.

Il existe plusieurs bibliothèques de graphiques JavaScript pour visualiser facilement les données, et ici nous créons le graphique à jauge linéaire avec AnyChart . Cette bibliothèque est flexible, avec une documentation complète , et elle se compose d' excellents exemples . De plus, il dispose d'un terrain de jeu pour expérimenter le code et est gratuit pour une utilisation non commerciale. Si vous souhaitez acheter une version sous licence, vous pouvez consulter les options disponibles , et si vous êtes une organisation éducative ou à but non lucratif, vous pouvez nous contacter pour une licence gratuite ici .

Les étapes pour créer une jauge linéaire JavaScript

Voici les étapes de base pour créer un graphique à jauge linéaire :

  1. Créez une page HTML de base.
  2. Incluez les fichiers JavaScript nécessaires.
  3. Ajoutez les données.
  4. Écrivez le code JavaScript du graphique.

Examinons chacune de ces étapes en détail ci-dessous.

1. Créez une page HTML de base

La première chose que nous devons faire est de créer une page HTML qui contiendra notre visualisation. Nous ajoutons un <div>élément de bloc et lui donnons un ID afin que nous puissions le référencer plus tard :

<html lang="en">
  <head>
    <title>JavaScript Linear Gauge</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>

Les attributs largeur et hauteur du <div>sont définis sur 100 % afin que le graphique soit restitué sur tout l'écran. Ces attributs peuvent être modifiés selon les besoins.

2. Incluez les fichiers JavaScript nécessaires

L'étape suivante consiste à référencer les liens JS dans la page HTML. Nous utiliserons la bibliothèque AnyChart pour ce didacticiel, incluons donc les fichiers correspondants à partir de leur CDN .

Pour créer un graphique à jauge linéaire, nous devrons ajouter trois scripts : le module de base , le module de jauge linéaire et le module de table :

<html lang="en">
  <head>
    <title>JavaScript Linear Gauge</title>
    <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 linear gauge will come here
    </script>
    <script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-core.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-linear-gauge.min.js"></script>
    <script src="https://cdn.anychart.com/releases/8.10.0/js/anychart-table.min.js"></script>
  </body>
</html>

3. Ajoutez les valeurs de données

Les données du graphique à jauge linéaire sont collectées à partir de Our World in Data et incluses dans le code. Sur ce site, on peut voir le pourcentage de personnes ayant reçu une et deux doses de vaccin Covid pour chaque continent dans le monde entier.

Parce que (au moment de la rédaction) aucun des nombres n'est supérieur à 50 %, nous avons maintenu la limite maximale de l'axe de toutes les jauges linéaires à 50 %, et nous comparons à quelle distance de cette marque se trouve chaque continent, ainsi que le chiffre global. Nous indiquons au moins les chiffres partiellement vaccinés avec une représentation LED, et les chiffres entièrement vaccinés avec un pointeur de barre. Nous verrons comment les données sont ajoutées dans la dernière étape.

Alors, nos premières étapes sont terminées, et maintenant ajoutons le code pour créer un graphique à jauge linéaire avec JavaScript !

4. Écrivez le code JavaScript du graphique

Avant d'ajouter du code, nous enfermons tout dans une fonction qui s'assure que tout le code qu'elle contient ne s'exécute qu'une fois la page chargée.

La création d'un graphique à jauge linéaire implique quelques étapes et est un peu plus complexe que les autres types de graphiques de base. Mais cela ne veut pas dire que c'est très difficile, et nous passerons par chaque étape pour comprendre comment le graphique est fait.

Définition de l'échelle linéaire et de l'axe du graphique de jauge

Nous avons plusieurs pointeurs dans notre graphique. Alors, commençons par créer une fonction qui accepte deux valeurs : une pour le pointeur de la barre et une pour la jauge LED. Nous allons ensuite créer une jauge, définir les données et spécifier la disposition horizontale. Ensuite, nous allons définir la plage des échelles et des axes. Nous allons créer une échelle linéaire avec les plages minimale et maximale. Pour l'axe, nous allons définir les attributs et définir l'orientation :

function drawGauge(value, settings) {
  // Create gauge with settings
  const gauge = anychart.gauges.linear();
  gauge.data([value, settings.value]);
  gauge.layout('horizontal');

  // Set scale for gauge
  const scale = anychart.scales.linear();
  scale.minimum(0).maximum(settings.maximum).ticks({ interval: 2 });

  // Set axis for gauge
  const axis = gauge.axis(0);
  axis.width('1%').offset('43%').scale(scale).orientation('bottom');
}

Réglage du pointeur de barre et de l'étiquette

Nous allons maintenant créer le pointeur de barre et l'étiquette de la série de barres. L'étiquette reçoit un décalage pour éviter le chevauchement avec le pointeur :

// Create and set bar point
const barSeries = gauge.bar(0);

barSeries
  .scale(scale)
  .width('4%');

// Create and set label with actual data
const labelBar = barSeries.labels();
labelBar
  .enabled(true)
  .offsetY('-15px');

Création du pointeur LED et définition de l'attribut de couleur

Dans les points LED, nous allons spécifier l'écart entre les points et utiliser la propriété dimmer pour définir la couleur des points LED résiduels pour indiquer un effet non éclairé. Nous déclarerons également l'échelle de couleur des points LED allumés :

// Create and set LED point
const ledPointer = gauge.led(1);

ledPointer
  .offset('10%')
  .width('30%')
  .count(settings.maximum)
  .scale(scale)
  .gap(0.55)
  .dimmer(function () {
    return '#eee';
  });

ledPointer.colorScale().colors(['#63b39b', '#63b39b']);

Déclarer les jauges avec la valeur cible de chaque point de données

Pour faire la jauge linéaire pour chaque continent, nous appellerons la fonction définie ci-dessus pour chaque région avec ses données. Le premier nombre indique les données de la valeur cible et la seconde variable est un objet avec les données de la LED. Le maximumreste une constante de 50, tandis que valuereprésente la valeur en pourcentage de la population entièrement vaccinée pour chaque point de données. Cette valeur sera affichée par le pointeur :

// Create gauges
const world = drawGauge(13.68, { maximum: 50, value: 27.13 });
const europe = drawGauge(36.98, { maximum: 50, value: 47.28 });
const nAmerica = drawGauge(36.77, { maximum: 50, value: 46.53 });
const sAmerica = drawGauge(22.8, { maximum: 50, value: 40.54 });
const asia = drawGauge(10.14, { maximum: 50, value: 27.16 });
const oceania = drawGauge(9.75, { maximum: 50, value: 22.12 });
const africa = drawGauge(1.56, { maximum: 50, value: 3.04 });

Réglage de la disposition des jauges linéaires

Pour afficher chacune des jauges linéaires l'une sous l'autre, nous allons définir un tableau et ajouter le titre avec chaque point de données sur une ligne distincte. Nous ajouterons les différentes propriétés de la mise en page, telles que l'alignement et la taille de la police. Nous allons également définir des paramètres pour la première ligne, puisqu'il s'agit du titre, et définir l'attribut width de la première colonne sur 100 % puisque nous n'avons plus besoin de colonnes :

// Create table to place gauges
const layoutTable = anychart.standalones.table();
layoutTable
  .hAlign('right')
  .vAlign('middle')
  .fontSize(14)
  .cellBorder(null);

// Put gauges into the layout table
layoutTable.contents([
  [null, 'Covid-19 Vaccination - How far are we from the halfway mark?'],
  ['World', world],
  ['Europe', europe],
  ['North America', nAmerica],
  ['South America', sAmerica],
  ['Asia', asia],
  ['Oceania', oceania],
  ['Africa', africa]
]);

// Set height for first row in layout table
layoutTable
  .getRow(0)
  .height(50)
  .fontSize(22)
  .hAlign('center');

// Set the first column to 100% width
layoutTable.getCol(0).width(100);

Dessiner le graphique

La dernière étape consiste à référencer le <div>conteneur que nous avons ajouté à l'étape précédente et à dessiner le graphique :

// Set container id and initiate drawing
layoutTable.container('container');
layoutTable.draw();

Et c'est tout. Nous avons maintenant un graphique de jauge linéaire JavaScript entièrement fonctionnel et magnifique ! Le code de cette version initiale de la jauge linéaire peut être consulté sur CodePen .

Version initiale de jauge linéaire

Rendre le graphique accessible

C'est toujours une bonne pratique de s'assurer que les graphiques sont accessibles au plus grand nombre. Donc, en gardant tout à l'esprit, nous avons créé une version de base du graphique à jauge linéaire qui convient mieux aux lecteurs d'écran. Vous pouvez vérifier cela ici et également en savoir plus sur cet aspect dans la documentation de la bibliothèque JavaScript AnyChart.

Personnalisation de la jauge linéaire

Le graphique à jauge linéaire par défaut que nous avons créé semble génial en ce moment, mais quelques modifications amélioreront la lisibilité et rendront le graphique encore plus impressionnant. Les bibliothèques JavaScript sont parfaites non seulement pour créer rapidement des graphiques, mais aussi pour personnaliser les visualisations selon les besoins. Les bibliothèques de graphiques offrent de nombreuses options de configuration pour contrôler le comportement et l'esthétique des graphiques. Apportons quelques modifications mineures mais efficaces à notre graphique à jauge linéaire actuel.

Changement de couleur

Pour rendre la jauge linéaire plus cohérente, faisons de l'attribut de couleur du pointeur de la barre une version plus sombre des points LED. Nous le ferons en spécifiant les attributs fill et stroke de la barre :

// Create and set bar point
const barSeries = gauge.bar(0);
barSeries
  .scale(scale)
  .width('4%')
  .fill('#296953')
  .stroke('#296953');

Ajout d'une légende à notre graphique à jauge linéaire

Étant donné que nous avons utilisé différentes couleurs pour la barre, les pointeurs LED allumés et non allumés, il est recommandé de fournir une légende pour expliquer les couleurs. Nous allons créer une légende et l'ajouter sous le titre du graphique :

// Create stand alone legend
const legend = anychart.standalones.legend();
legend
.position('center')
.items([
    { text: 'Fully vaccinated', iconFill: '#296953' },
    { text: 'Partially vaccinated', iconFill: '#63b39b' },
    { text: 'Not vaccinated', iconFill: '#eee' }
]);

Formatage des info-bulles

Pour faciliter une meilleure communication des données, formatons l'info-bulle pour la rendre plus informative en affichant les valeurs sous forme de pourcentage et en indiquant que la valeur maximale de la jauge est de 50 % :

// Set gauge tooltip
gauge
    .tooltip()
    .useHtml(true)
    .titleFormat('{%Value} %')
        .format(
        'Maximum on scale: ' +
        settings.maximum +
        ' %'
    );

Découvrez le code complet de cette version sur CodePen .

Formatage des axes et des étiquettes

La dernière chose que nous ferons est d'afficher toutes les valeurs de données sous forme de pourcentages pour éviter toute confusion. Nous ajouterons également un sous-titre sous forme de ligne dans le tableau sous le titre pour indiquer que les valeurs sont des pourcentages. Une dernière chose sera d'embellir les étiquettes des barres avec des polices plus audacieuses.

Version finale de la jauge linéaire

Le code final complet de ce graphique de jauge linéaire JavaScript peut être trouvé sur CodePen .

Conclusion

Dans ce tutoriel étape par étape, nous avons vu comment créer des graphiques JavaScript fonctionnels et visuellement attrayants n'est pas trop difficile avec une bonne bibliothèque JavaScript. Consultez la documentation et les exemples pour mieux comprendre les caractéristiques et les propriétés de la jauge linéaire. Veuillez poser des questions en cas de doute sur ce graphique ou d'autres visualisations.

Il existe plusieurs options de graphique fournies par AnyChart , et il existe également de nombreuses autres bibliothèques de graphiques JavaScript pour créer de belles visualisations.

Faisons tous vacciner et restons en bonne santé pour continuer à créer plus de visualisations !

 Source : https://www.sitepoint.com/create-linear-gauge-chart-javascript/

#javascript 

Créer Un Graphique De Jauge Linéaire En JavaScript
Hoang  Kim

Hoang Kim

1659960601

Cách để Xây Dựng Một Thùng Chứa đơn Giản Bằng Cách Sử Dụng Gola

Xin chào các bạn, tiếp tục với loạt bài Sâu vào vùng chứa, chúng ta đã biết rằng các vùng chứa được xây dựng từ Không gian tên và Nhóm Linux, và để tìm hiểu sâu hơn về nó, chúng ta sẽ tìm hiểu cách xây dựng vùng chứa của riêng bạn bằng cách sử dụng Golang.

Xây dựng một vùng chứa

Tạo một tệp có tên container.govà viết một số mã đơn giản như sau.


package main

import (
	"os"
)

func main() {
	
}

func must(err error) {
	if err != nil {
		panic(err)
	}
}

Nếu bạn đã quen thuộc với Docker thì bạn biết một lệnh để chạy vùng chứa docker run <container> <command>, ví dụ:

docker run busybox echo "A"

Bạn sẽ thấy vùng chứa chạy và in chữ “A” và nếu bạn chạy lệnh sau:

docker run -it busybox sh

Hộp chứa chạy và vỏ sẽ gắn vào nó.

/ #

Nếu chúng ta nhập một lệnh bây giờ, lệnh đó đang chạy trong vùng chứa.

/ # hostname
d12ccc0e00a0
/ # ps
PID   USER     TIME  COMMAND
1     root      0:00 sh
9     root      0:00 ps

Lệnh tên máy chủ không in tên máy chủ của máy chủ in tên máy chủ của một vùng chứa và lệnh ps chỉ in hai quá trình.

Bây giờ chúng ta sẽ xây dựng một vùng chứa tương tự như trên bằng cách sử dụng Golang, cập nhật container.gonhư sau.

package main

import (
	"os"
)

// docker run <image> <command>
// go run container.go run <command>
func main() {
	switch os.Args[1] {
	case "run":
		run()
	default:
		panic("Error")
	}
}

func run() {

}

func must(err error) {
	if err != nil {
		panic(err)
	}
}

Chúng tôi thêm một hàm được đặt tên run()và trong hàm chính, chúng tôi sử dụng cú pháp switch case để kiểm tra xem khi chúng tôi chạy chương trình với cờ là run, nó sẽ chạy run()hàm. Bây giờ khi chúng ta chạy lệnh go run container.go run, nó sẽ tương tự như khi chúng ta chạy docker run.

Tiếp theo, chúng tôi cập nhật run()chức năng như sau.

package main

import (
	"os"
  "os/exec"
)

// docker run <image> <command>
// go run container.go run <command>
func main() {
	switch os.Args[1] {
	case "run":
		run()
	default:
		panic("Error")
	}
}

func run() {
        cmd := exec.Command(os.Args[2], os.Args[3:]...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	must(cmd.Run())
}

func must(err error) {
	if err != nil {
		panic(err)
	}
}

Chúng tôi sử dụng os/execgói để thực thi các lệnh nhập của người dùng được lưu trữ trong os.Argsmảng, ví dụ: khi chúng tôi nhập go run container.go run echo “A”, thì os.Argssẽ có giá trị là:

Args[0] = "container.go"
Args[1] = "run"
Args[2] = "echo"
Args[3] = "A"

Giá trị mà chúng ta cần chuyển vào giá trị mà chúng exec.Command()ta nhận được từ chỉ mục hai của os.Args. Cú pháp của Command()hàm như sau.

exec.Command(name string, arg ...string)

Hàm nhận đối số đầu tiên là lệnh mà nó sẽ thực thi và các giá trị còn lại là đối số của lệnh đó.

Bây giờ, hãy thử chạy lệnh tương tự như docker run -it busybox shvới chương trình của bạn.

go run container.go run sh

Bạn sẽ thấy rằng nó hầu như giống nhau khi bạn chạy lệnh docker.

#

Chúng tôi đã thực hiện thành công bước đầu tiên 😁, nhưng khi bạn nhập lệnh tên máy chủ, nó sẽ in tên máy chủ của máy chủ của chúng tôi, không phải của vùng chứa.

# hostname
LAPTOP-2COB82RG

Nếu bạn gõ lệnh thay đổi tên máy chủ trong chương trình của chúng tôi, nó cũng sẽ ảnh hưởng đến bên ngoài của máy chủ.

# hostnamectl set-hostname container

exitvà nhập, bây giờ bên ngoài máy chủ, chúng ta gõ tên máy sẽ thấy nó đã được thay đổi.

Chương trình của chúng ta hiện chỉ đang chạy lệnh sh hoàn toàn không phải vùng chứa, tiếp theo, chúng ta sẽ đi qua từng bước để xây dựng vùng chứa. Như chúng ta biết vùng chứa được xây dựng từ Không gian tên Linux.

Không gian tên

Không gian tên cung cấp môi trường cách ly giúp chúng tôi chạy một quy trình độc lập với các quy trình khác trên cùng một máy chủ. Tại thời điểm viết bài, có sáu không gian tên như sau,

  • PID : Không gian tên PID cung cấp cho các quy trình một tập hợp các ID quy trình (PID) độc lập với các không gian tên khác. Không gian tên PID thực hiện quy trình đầu tiên được tạo trong nó được gán với PID 1.
  • MNT : Gắn kết các điểm gắn điều khiển không gian tên và cung cấp cho bạn khả năng gắn kết và ngắt kết nối các thư mục mà không ảnh hưởng đến các không gian tên khác.
  • NET: Các không gian tên mạng tạo ra ngăn xếp mạng của chúng cho quá trình này.
  • UTS: Không gian tên chia sẻ thời gian UNIX cho phép một tiến trình có tên máy chủ và tên miền riêng biệt.
  • NGƯỜI DÙNG: Không gian tên người dùng tạo bộ UIDS và GIDS của riêng họ cho quá trình.
  • IPC: Không gian tên IPC cô lập các quy trình khỏi giao tiếp giữa các quy trình, điều này ngăn các quy trình trong các không gian tên IPC khác nhau sử dụng.

Chúng tôi sẽ sử dụng không gian tên PID, UTS và MNT trong chương trình Golang của chúng tôi.

Không gian tên UTS

Điều đầu tiên chúng ta cần tách biệt là tên máy chủ để chương trình của chúng ta có tên máy chủ của nó. Cập nhật container.go:

package main

import (
  "os"
  "os/exec"
  "syscall"
)

// docker run <image> <command>
// go run container.go run <command>
func main() {
	switch os.Args[1] {
	case "run":
		run()
	default:
		panic("Error")
	}
}

func run() {
        cmd := exec.Command(os.Args[2], os.Args[3:]...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Cloneflags: syscall.CLONE_NEWUTS,
	}

	must(cmd.Run())
}

func must(err error) {
	if err != nil {
		panic(err)
	}
}

Để sử dụng không gian tên Linux trong Go, chúng tôi chỉ cần chuyển cờ không gian tên mà chúng tôi muốn sử dụng trong đó cmd.SysProcAttr.

cmd.SysProcAttr = &syscall.SysProcAttr{
    Cloneflags: syscall.CLONE_NEWUTS,
}

Bây giờ chúng ta hãy thử lại.

go run container.go run sh

Chạy lệnh để thay đổi tên máy chủ.

# hostnamectl set-hostname wsl
# hostname
wsl

exitvà nhập, bây giờ bên ngoài máy chủ, bạn gõ lệnh tên máy chủ và bạn sẽ thấy tên máy chủ của máy chủ không thay đổi chút nào. Chúng tôi đã hoàn thành bước tiếp theo trong việc xây dựng vùng chứa 😁.

Tuy nhiên, để chương trình của chúng ta giống một thùng chứa hơn, chúng ta cần thực hiện thêm một số việc. Như bạn có thể thấy khi chúng ta chạy docker run -it busybox shvà sau đó gõ tên máy chủ, nó sẽ có tên máy chủ của nó, không giống như khi chúng ta chạy chương trình và chúng ta phải gõ lệnh thủ công để thay đổi tên máy chủ. Cập nhật container.go.

package main

import (
	"os"
	"os/exec"
	"syscall"
)

// docker run <image> <command>
// ./container run <command>
func main() {
	switch os.Args[1] {
	case "run":
		run()
	case "child":
		child()
	default:
		panic("Error")
	}
}

func run() {
	cmd := exec.Command("/proc/self/exe", append([]string{"child"}, os.Args[2:]...)...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Cloneflags: syscall.CLONE_NEWUTS,
	}

	must(cmd.Run())
}

func child() {
	syscall.Sethostname([]byte("container"))

	cmd := exec.Command(os.Args[2], os.Args[3:]...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	must(cmd.Run())
}

func must(err error) {
	if err != nil {
		panic(err)
	}
}

chúng ta thêm một hàm khác được đặt tên child()và trong hàm run, chúng ta thực thi hàm con bằng cách exec.Command.

exec.Command("/proc/self/exe", append([]string{"child"}, os.Args[2:]...)...)

Chúng ta thay đổi đối số đầu tiên thành /proc/self/exe, lệnh này sẽ tự thực thi chương trình với đối số con. Tiến trình con bây giờ chạy trong không gian tên UTS cô lập và chúng tôi thay đổi tên máy chủ bằng hàm syscall.Sethostname([]byte(“container”)).

go run container.go run sh-> /proc/self/exe child sh-> syscall.Sethostname([]byte("container"))->exec.Command("sh")

Hãy thử lại lần nữa.

go run container.go run sh

Gõ tên máy chủ và bạn sẽ thấy quy trình của mình có tên máy chủ riêng.

# hostname
container

Vậy là chúng ta đã hoàn thành bước tiếp theo rồi 😁.

Tiếp theo, bạn thử gõ lệnh ps để liệt kê tiến trình và xem nó có giống như khi chúng ta chạy docker run không?

# ps
PID   TTY      TIME     CMD
11254 pts/3    00:00:00 sudo
11255 pts/3    00:00:00 bash
17530 pts/3    00:00:00 go
17626 pts/3    00:00:00 container
17631 pts/3    00:00:00 exe
17636 pts/3    00:00:00 sh
17637 pts/3    00:00:00 ps

Không giống chút nào, các quy trình bạn thấy là các quy trình bên ngoài máy chủ.

Không gian tên PID

Chúng tôi sẽ sử dụng không gian tên PID để tạo một quy trình với một tập hợp các ID quy trình (PID) độc lập. Cập nhật container.gonhư sau.

func run() {
 cmd := exec.Command("/proc/self/exe", append([]string{"child"}, os.Args[2:]...)...)
 cmd.Stdin = os.Stdin
 cmd.Stdout = os.Stdout
 cmd.Stderr = os.Stderr
 cmd.SysProcAttr = &syscall.SysProcAttr{
  Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID,
 }
 must(cmd.Run())
}

Chúng ta chỉ cần thêm một lá cờ là được syscall.CLONE_NEWPID, bây giờ chúng ta hãy chạy lại.

go run container.go run sh# ps
PID   TTY      TIME     CMD
11254 pts/3    00:00:00 sudo
11255 pts/3    00:00:00 bash
17530 pts/3    00:00:00 go
17626 pts/3    00:00:00 container
17631 pts/3    00:00:00 exe
17636 pts/3    00:00:00 sh
17637 pts/3    00:00:00 ps

Gì? Nó không thay đổi chút nào. Tại sao?

Khi chúng tôi chạy chương trình ps, nó sẽ nhận được thông tin quy trình trong /procthư mục trong Linux, hãy thử.

ls /proc

Bây giờ, hệ thống tệp của quy trình của bạn trông giống như máy chủ lưu trữ, vì hệ thống tệp của nó được kế thừa từ máy chủ hiện tại, hãy thay đổi điều đó.

Không gian tên MNT

Cập nhật container.gonhư sau.

package main

import (
	"os"
	"os/exec"
	"syscall"
)

// docker run <image> <command>
// ./container run <command>
func main() {
	switch os.Args[1] {
	case "run":
		run()
	case "child":
		child()
	default:
		panic("Error")
	}
}

func run() {
	cmd := exec.Command("/proc/self/exe", append([]string{"child"}, os.Args[2:]...)...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID | syscall.CLONE_NEWNS,
	}

	must(cmd.Run())
}

func child() {
	syscall.Sethostname([]byte("container"))
	must(syscall.Chdir("/"))
	must(syscall.Mount("proc", "proc", "proc", 0, ""))

	cmd := exec.Command(os.Args[2], os.Args[3:]...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	must(cmd.Run())
}

func must(err error) {
	if err != nil {
		panic(err)
	}
}

Chúng tôi sử dụng syscall.CLONE_NEWNScờ để tạo một quy trình với không gian tên MNT và thay đổi hệ thống tệp.

syscall.Chdir("/")
syscall.Mount("proc", "proc", "proc", 0, "")

Bây giờ, chúng ta hãy chạy lại.

go run container.go run sh

Nhập lệnh ps.

# ps
PID TTY      TIME     CMD
1   pts/3    00:00:00 exe
7   pts/3    00:00:00 sh
8   pts/3    00:00:00 ps

Chúng tôi đã thành công 😁.

Sự kết luận

Vì vậy, chúng ta đã biết cách xây dựng một vùng chứa đơn giản bằng cách sử dụng Golang, nhưng trên thực tế, vùng chứa sẽ có nhiều thứ khác, chẳng hạn như Nhóm để giới hạn tài nguyên của quy trình, tạo không gian tên USER và gắn kết tệp từ vùng chứa đến máy chủ, v.v.

Liên kết: https://faun.pub/deep-into-container-build-your-own-container-with-golang-98ef93f42923

#go #golang #container

Cách để Xây Dựng Một Thùng Chứa đơn Giản Bằng Cách Sử Dụng Gola

Как создать простой контейнер с помощью Golang

Привет, ребята, продолжая серию «Углубление в контейнер», мы уже знаем, что контейнеры создаются из пространств имен и групп Linux, и чтобы узнать об этом глубже, мы собираемся узнать, как создать свой собственный контейнер с помощью Golang.

Создание контейнера

Создайте файл с именем container.goи напишите простой код следующим образом.


package main

import (
	"os"
)

func main() {
	
}

func must(err error) {
	if err != nil {
		panic(err)
	}
}

Если вы знакомы с Docker, то знаете, что команда для запуска контейнера docker run <container> <command>, например:

docker run busybox echo "A"

Вы увидите запуск контейнера и печать буквы «A», и если вы выполните следующую команду:

docker run -it busybox sh

Контейнер запустится, и к нему прикрепится оболочка.

/ #

Если мы введем команду сейчас, эта команда будет запущена в контейнере.

/ # hostname
d12ccc0e00a0
/ # ps
PID   USER     TIME  COMMAND
1     root      0:00 sh
9     root      0:00 ps

Команда hostname не печатает имя хоста сервера, который печатает имя хоста контейнера, а команда ps печатает только два процесса.

Теперь мы создадим аналогичный контейнер, как показано выше, используя Golang, обновив его container.goследующим образом.

package main

import (
	"os"
)

// docker run <image> <command>
// go run container.go run <command>
func main() {
	switch os.Args[1] {
	case "run":
		run()
	default:
		panic("Error")
	}
}

func run() {

}

func must(err error) {
	if err != nil {
		panic(err)
	}
}

Мы добавляем функцию с именем, run()и в основной функции мы используем синтаксис case case, чтобы проверить, что когда мы запускаем программу с флагом запуска, она будет запускать run()функцию. Теперь, когда мы запускаем команду go run container.go run, она будет похожа на то, когда мы запускаем docker run.

Далее мы обновляем run()функцию следующим образом.

package main

import (
	"os"
  "os/exec"
)

// docker run <image> <command>
// go run container.go run <command>
func main() {
	switch os.Args[1] {
	case "run":
		run()
	default:
		panic("Error")
	}
}

func run() {
        cmd := exec.Command(os.Args[2], os.Args[3:]...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	must(cmd.Run())
}

func must(err error) {
	if err != nil {
		panic(err)
	}
}

Мы используем os/execпакет для выполнения пользовательских команд ввода, которые хранятся в os.Argsмассиве, например, когда мы набираем go run container.go run echo “A”, тогда os.Argsбудет иметь значение:

Args[0] = "container.go"
Args[1] = "run"
Args[2] = "echo"
Args[3] = "A"

Значение, которое нам нужно передать, exec.Command()мы получаем из индекса two из os.Args. Синтаксис Command()функции следующий.

exec.Command(name string, arg ...string)

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

Теперь попробуйте запустить ту же команду, что и в docker run -it busybox shвашей программе.

go run container.go run sh

Вы увидите, что это в основном то же самое, когда вы запустите команду docker.

#

Мы успешно сделали первый шаг 😁, но когда вы вводите команду hostname, она будет печатать имя хоста нашего сервера, а не контейнера.

# hostname
LAPTOP-2COB82RG

Если вы наберете команду для изменения имени хоста в нашей программе, это повлияет и на внешний сервер.

# hostnamectl set-hostname container

Введите exitи введите, теперь вне сервера, мы вводим имя хоста, мы увидим, что оно было изменено.

Наша программа в настоящее время просто запускает команду sh, а не контейнер, далее мы пройдем каждый шаг, чтобы создать контейнер. Как мы знаем, контейнер построен из пространств имен Linux.

Пространства имен

Пространства имен обеспечивают среду изоляции, которая помогает нам запускать процесс независимо от других процессов на том же сервере. На момент написания статьи существует шесть следующих пространств имен:

  • PID : пространство имен PID предоставляет процессам независимый набор идентификаторов процессов (PID) из других пространств имен. Пространство имен PID делает первый процесс, созданный в нем, назначенным с PID 1.
  • MNT : Пространства имен монтирования управляют точками монтирования и позволяют монтировать и размонтировать папки, не затрагивая другие пространства имен.
  • NET: сетевые пространства имен создают свой сетевой стек для процесса.
  • UTS: Пространства имен UNIX с разделением времени позволяют процессу иметь отдельное имя хоста и доменное имя.
  • ПОЛЬЗОВАТЕЛЬ: Пространства имен пользователей создают собственный набор UIDS и GIDS для процесса.
  • IPC: пространства имен IPC изолируют процессы от взаимодействия между процессами, что предотвращает использование процессов в разных пространствах имен IPC.

Мы будем использовать пространства имен PID, UTS и MNT в нашей программе Golang.

пространство имен UTS

Первое, что нам нужно изолировать, — это имя хоста, чтобы у нашей программы было имя хоста. Обновление container.go:

package main

import (
  "os"
  "os/exec"
  "syscall"
)

// docker run <image> <command>
// go run container.go run <command>
func main() {
	switch os.Args[1] {
	case "run":
		run()
	default:
		panic("Error")
	}
}

func run() {
        cmd := exec.Command(os.Args[2], os.Args[3:]...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Cloneflags: syscall.CLONE_NEWUTS,
	}

	must(cmd.Run())
}

func must(err error) {
	if err != nil {
		panic(err)
	}
}

Чтобы использовать пространства имен Linux в Go, мы просто передаем флаг пространства имен, который хотим использовать в cmd.SysProcAttr.

cmd.SysProcAttr = &syscall.SysProcAttr{
    Cloneflags: syscall.CLONE_NEWUTS,
}

Теперь попробуем еще раз.

go run container.go run sh

Запустите команду, чтобы изменить имя хоста.

# hostnamectl set-hostname wsl
# hostname
wsl

Введите exitи введите, теперь вне сервера, вы вводите команду hostname, и вы увидите, что имя хоста сервера вообще не изменилось. Мы завершили следующий этап создания контейнера 😁.

Однако, чтобы наша программа больше походила на контейнер, нам нужно сделать еще несколько вещей. Как вы можете видеть, когда мы запускаем, docker run -it busybox shа затем вводим имя хоста, оно будет иметь свое имя хоста, а не то, что мы запускаем программу, и нам нужно вручную ввести команду для изменения имени хоста. Обновить container.go.

package main

import (
	"os"
	"os/exec"
	"syscall"
)

// docker run <image> <command>
// ./container run <command>
func main() {
	switch os.Args[1] {
	case "run":
		run()
	case "child":
		child()
	default:
		panic("Error")
	}
}

func run() {
	cmd := exec.Command("/proc/self/exe", append([]string{"child"}, os.Args[2:]...)...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Cloneflags: syscall.CLONE_NEWUTS,
	}

	must(cmd.Run())
}

func child() {
	syscall.Sethostname([]byte("container"))

	cmd := exec.Command(os.Args[2], os.Args[3:]...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	must(cmd.Run())
}

func must(err error) {
	if err != nil {
		panic(err)
	}
}

мы добавляем другую функцию с именем child()и в функции запуска мы выполняем дочернюю функцию с помощью exec.Command.

exec.Command("/proc/self/exe", append([]string{"child"}, os.Args[2:]...)...)

Мы меняем первый аргумент на /proc/self/exe, эта команда автоматически запустит программу с дочерним аргументом. Теперь дочерний процесс работает в изолированных пространствах имен UTS, и мы меняем имя хоста с помощью функции syscall.Sethostname([]byte(“container”)).

go run container.go run sh-> /proc/self/exe child sh-> syscall.Sethostname([]byte("container"))->exec.Command("sh")

Давай попробуем снова.

go run container.go run sh

Введите имя хоста, и вы увидите, что у вашего процесса есть собственное имя хоста.

# hostname
container

Итак, мы завершили следующий этап 😁.

Затем попробуйте ввести команду ps, чтобы просмотреть список процессов, и посмотрите, совпадает ли он с запуском docker run?

# ps
PID   TTY      TIME     CMD
11254 pts/3    00:00:00 sudo
11255 pts/3    00:00:00 bash
17530 pts/3    00:00:00 go
17626 pts/3    00:00:00 container
17631 pts/3    00:00:00 exe
17636 pts/3    00:00:00 sh
17637 pts/3    00:00:00 ps

Совсем не то, что процессы, которые вы видите, — это процессы вне сервера.

пространство имен PID

Мы будем использовать пространство имен PID для создания процесса с независимым набором идентификаторов процессов (PID). Обновите container.goследующим образом.

func run() {
 cmd := exec.Command("/proc/self/exe", append([]string{"child"}, os.Args[2:]...)...)
 cmd.Stdin = os.Stdin
 cmd.Stdout = os.Stdout
 cmd.Stderr = os.Stderr
 cmd.SysProcAttr = &syscall.SysProcAttr{
  Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID,
 }
 must(cmd.Run())
}

Нам просто нужно добавить один флаг syscall.CLONE_NEWPID, теперь давайте снова запустим.

go run container.go run sh# ps
PID   TTY      TIME     CMD
11254 pts/3    00:00:00 sudo
11255 pts/3    00:00:00 bash
17530 pts/3    00:00:00 go
17626 pts/3    00:00:00 container
17631 pts/3    00:00:00 exe
17636 pts/3    00:00:00 sh
17637 pts/3    00:00:00 ps

Какая? Он совсем не меняется. Почему?

Когда мы запустим программу ps, она получит информацию о процессе в /procпапке в Linux, попробуем.

ls /proc

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

пространство имен MNT

Обновите container.goследующим образом.

package main

import (
	"os"
	"os/exec"
	"syscall"
)

// docker run <image> <command>
// ./container run <command>
func main() {
	switch os.Args[1] {
	case "run":
		run()
	case "child":
		child()
	default:
		panic("Error")
	}
}

func run() {
	cmd := exec.Command("/proc/self/exe", append([]string{"child"}, os.Args[2:]...)...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID | syscall.CLONE_NEWNS,
	}

	must(cmd.Run())
}

func child() {
	syscall.Sethostname([]byte("container"))
	must(syscall.Chdir("/"))
	must(syscall.Mount("proc", "proc", "proc", 0, ""))

	cmd := exec.Command(os.Args[2], os.Args[3:]...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	must(cmd.Run())
}

func must(err error) {
	if err != nil {
		panic(err)
	}
}

Мы используем syscall.CLONE_NEWNSфлаг для создания процесса с пространствами имен MNT и изменения файловой системы.

syscall.Chdir("/")
syscall.Mount("proc", "proc", "proc", 0, "")

Теперь снова побежим.

go run container.go run sh

Введите команду ps.

# ps
PID TTY      TIME     CMD
1   pts/3    00:00:00 exe
7   pts/3    00:00:00 sh
8   pts/3    00:00:00 ps

У нас получилось 😁.

Вывод

Итак, мы знаем, как создать простой контейнер с помощью Golang, но на самом деле в контейнере будет много других вещей, таких как Cgroups для ограничения ресурсов процесса, создание пространств имен USER и монтирование файлов из контейнера на сервер и т. д.

Ссылка: https://faun.pub/deep-into-container-build-your-own-container-with-golang-98ef93f42923

#go #golang #container

Как создать простой контейнер с помощью Golang
田辺  亮介

田辺 亮介

1659946080

如何使用 Golang 構建一個簡單的容器

大家好,繼續深入容器系列,我們已經知道容器是由 Linux 命名空間和 Cgroups 構建的,為了更深入地了解它,我們將學習如何使用 Golang 構建自己的容器。

構建容器

創建一個名為的文件container.go並編寫一些簡單的代碼,如下所示。


package main

import (
	"os"
)

func main() {
	
}

func must(err error) {
	if err != nil {
		panic(err)
	}
}

如果您熟悉 Docker,那麼您知道運行容器的命令是docker run <container> <command>,例如:

docker run busybox echo "A"

您將看到容器運行並打印字母“A”,如果您運行以下命令:

docker run -it busybox sh

容器運行並且外殼將附加到它。

/ #

如果我們現在鍵入命令,則該命令正在容器中運行。

/ # hostname
d12ccc0e00a0
/ # ps
PID   USER     TIME  COMMAND
1     root      0:00 sh
9     root      0:00 ps

hostname 命令不打印打印容器主機名的服務器的主機名,而 ps 命令只打印兩個進程。

現在我們將使用 Golang 構建與上述類似的容器,更新container.go如下。

package main

import (
	"os"
)

// docker run <image> <command>
// go run container.go run <command>
func main() {
	switch os.Args[1] {
	case "run":
		run()
	default:
		panic("Error")
	}
}

func run() {

}

func must(err error) {
	if err != nil {
		panic(err)
	}
}

我們在 main 函數中添加了一個名為run()and 的函數,我們使用 switch case 語法來檢查當我們運行帶有 run 標誌的程序時,它將運行該run()函數。現在當我們運行命令時go run container.go run,它會和我們運行時類似docker run

接下來,我們更新run()函數如下。

package main

import (
	"os"
  "os/exec"
)

// docker run <image> <command>
// go run container.go run <command>
func main() {
	switch os.Args[1] {
	case "run":
		run()
	default:
		panic("Error")
	}
}

func run() {
        cmd := exec.Command(os.Args[2], os.Args[3:]...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	must(cmd.Run())
}

func must(err error) {
	if err != nil {
		panic(err)
	}
}

我們使用該os/exec包執行存儲在os.Args數組中的用戶輸入命令,例如,當我們鍵入 時go run container.go run echo “A”os.Args將具有以下值:

Args[0] = "container.go"
Args[1] = "run"
Args[2] = "echo"
Args[3] = "A"

我們需要exec.Command()從 的索引 2 中獲得的值傳遞給os.Args。函數的語法Command()如下。

exec.Command(name string, arg ...string)

該函數採用第一個參數,即它將執行的命令,其餘值是該命令的參數。

docker run -it busybox sh現在,嘗試運行與您的程序相同的命令。

go run container.go run sh

當你運行 docker 命令時,你會發現它幾乎是一樣的。

#

我們已經成功邁出了第一步😁,但是當你輸入主機名命令時,它會打印我們服務器的主機名,而不是容器的主機名。

# hostname
LAPTOP-2COB82RG

如果您在我們的程序中鍵入更改主機名的命令,它也會影響服務器外部。

# hostnamectl set-hostname container

輸入exit並輸入,現在在服務器外部,我們輸入主機名,我們將看到它已更改。

我們的程序目前只是運行 sh 命令而不是容器,接下來,我們將通過每個步驟來構建容器。正如我們所知,容器是從 Linux 命名空間構建的。

命名空間

命名空間提供了隔離環境,幫助我們在同一台服務器上運行獨立於其他進程的進程。在撰寫本文時,有如下六個命名空間,

  • PID:PID 命名空間為進程提供了一組來自其他命名空間的獨立進程 ID (PID)。PID 命名空間使在其中創建的第一個進程分配有 PID 1。
  • MNT:掛載命名空間控制掛載點,並為您提供掛載和卸載文件夾而不影響其他命名空間。
  • NET:網絡命名空間為進程創建它們的網絡堆棧。
  • UTS: UNIX 分時命名空間允許一個進程擁有單獨的主機名和域名。
  • USER:用戶命名空間為進程創建自己的一組 UIDS 和 GIDS。
  • IPC: IPC 命名空間將進程與進程間通信隔離開來,這可以防止不同 IPC 命名空間中的進程使用。

我們將在 Golang 程序中使用 PID、UTS 和 MNT 命名空間。

UTS 命名空間

我們需要隔離的第一件事是主機名,以便我們的程序有它的主機名。更新container.go

package main

import (
  "os"
  "os/exec"
  "syscall"
)

// docker run <image> <command>
// go run container.go run <command>
func main() {
	switch os.Args[1] {
	case "run":
		run()
	default:
		panic("Error")
	}
}

func run() {
        cmd := exec.Command(os.Args[2], os.Args[3:]...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Cloneflags: syscall.CLONE_NEWUTS,
	}

	must(cmd.Run())
}

func must(err error) {
	if err != nil {
		panic(err)
	}
}

要在 Go 中使用 Linux 命名空間,我們只需傳遞要在cmd.SysProcAttr.

cmd.SysProcAttr = &syscall.SysProcAttr{
    Cloneflags: syscall.CLONE_NEWUTS,
}

現在讓我們再試一次。

go run container.go run sh

運行命令以更改主機名。

# hostnamectl set-hostname wsl
# hostname
wsl

鍵入exit並輸入,現在在服務器外部,鍵入主機名命令,您將看到服務器的主機名根本沒有改變。我們已經完成了構建容器的下一步😁。

然而,為了讓我們的程序更像一個容器,我們需要做更多的事情。正如你所看到的,當我們運行docker run -it busybox sh然後鍵入主機名時,它將有它的主機名,不像我們運行程序,我們必須手動鍵入命令來更改主機名。更新container.go

package main

import (
	"os"
	"os/exec"
	"syscall"
)

// docker run <image> <command>
// ./container run <command>
func main() {
	switch os.Args[1] {
	case "run":
		run()
	case "child":
		child()
	default:
		panic("Error")
	}
}

func run() {
	cmd := exec.Command("/proc/self/exe", append([]string{"child"}, os.Args[2:]...)...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Cloneflags: syscall.CLONE_NEWUTS,
	}

	must(cmd.Run())
}

func child() {
	syscall.Sethostname([]byte("container"))

	cmd := exec.Command(os.Args[2], os.Args[3:]...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	must(cmd.Run())
}

func must(err error) {
	if err != nil {
		panic(err)
	}
}

我們添加了另一個名為child()and 在 run 函數中的函數,我們執行子函數exec.Command

exec.Command("/proc/self/exe", append([]string{"child"}, os.Args[2:]...)...)

我們將第一個參數更改為/proc/self/exe,此命令將使用子參數自動執行程序。子進程現在在隔離的 UTS 命名空間中運行,我們使用函數更改主機名syscall.Sethostname([]byte(“container”))

go run container.go run sh-> /proc/self/exe child sh-> syscall.Sethostname([]byte("container"))->exec.Command("sh")

讓我們再試一次。

go run container.go run sh

鍵入主機名,您將看到您的進程有自己的主機名。

# hostname
container

這樣我們就完成了下一步😁。

接下來嘗試輸入ps命令列出進程,看看是不是和我們運行docker run時一樣?

# ps
PID   TTY      TIME     CMD
11254 pts/3    00:00:00 sudo
11255 pts/3    00:00:00 bash
17530 pts/3    00:00:00 go
17626 pts/3    00:00:00 container
17631 pts/3    00:00:00 exe
17636 pts/3    00:00:00 sh
17637 pts/3    00:00:00 ps

根本不像,您看到的進程是服務器外部的進程。

PID 命名空間

我們將使用 PID 命名空間來創建具有一組獨立進程 ID (PID) 的進程。更新container.go如下。

func run() {
 cmd := exec.Command("/proc/self/exe", append([]string{"child"}, os.Args[2:]...)...)
 cmd.Stdin = os.Stdin
 cmd.Stdout = os.Stdout
 cmd.Stderr = os.Stderr
 cmd.SysProcAttr = &syscall.SysProcAttr{
  Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID,
 }
 must(cmd.Run())
}

我們只需要添加一個標誌 is syscall.CLONE_NEWPID,現在讓我們再次運行。

go run container.go run sh# ps
PID   TTY      TIME     CMD
11254 pts/3    00:00:00 sudo
11255 pts/3    00:00:00 bash
17530 pts/3    00:00:00 go
17626 pts/3    00:00:00 container
17631 pts/3    00:00:00 exe
17636 pts/3    00:00:00 sh
17637 pts/3    00:00:00 ps

什麼?它根本沒有改變。為什麼?

當我們運行 ps 程序時,它會在 Linux 的文件夾中獲取進程信息/proc,讓我們試試。

ls /proc

現在,您的進程的文件系統看起來與主機相同,因為它的文件系統是從當前服務器繼承的,讓我們改變它。

MNT 命名空間

更新container.go如下。

package main

import (
	"os"
	"os/exec"
	"syscall"
)

// docker run <image> <command>
// ./container run <command>
func main() {
	switch os.Args[1] {
	case "run":
		run()
	case "child":
		child()
	default:
		panic("Error")
	}
}

func run() {
	cmd := exec.Command("/proc/self/exe", append([]string{"child"}, os.Args[2:]...)...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID | syscall.CLONE_NEWNS,
	}

	must(cmd.Run())
}

func child() {
	syscall.Sethostname([]byte("container"))
	must(syscall.Chdir("/"))
	must(syscall.Mount("proc", "proc", "proc", 0, ""))

	cmd := exec.Command(os.Args[2], os.Args[3:]...)
	cmd.Stdin = os.Stdin
	cmd.Stdout = os.Stdout
	cmd.Stderr = os.Stderr

	must(cmd.Run())
}

func must(err error) {
	if err != nil {
		panic(err)
	}
}

我們使用syscall.CLONE_NEWNSflag 來創建具有 MNT 命名空間的進程,並更改文件系統。

syscall.Chdir("/")
syscall.Mount("proc", "proc", "proc", 0, "")

現在,讓我們再次運行。

go run container.go run sh

鍵入 ps 命令。

# ps
PID TTY      TIME     CMD
1   pts/3    00:00:00 exe
7   pts/3    00:00:00 sh
8   pts/3    00:00:00 ps

我們成功了😁。

結論

所以我們知道如何使用 Golang 構建一個簡單的容器,但實際上,容器還有很多其他的東西,比如 Cgroups 限制進程的資源,創建 USER 命名空間,以及從容器中掛載文件到服務器等等……

鏈接:https ://faun.pub/deep-into-container-build-your-own-container-with-golang-98ef93f42923

#go #golang #container #docker

如何使用 Golang 構建一個簡單的容器
Hans  Marvin

Hans Marvin

1659938820

How to Build A Simple Container using Golang

Hi guys, continuing with the series of Deep into Container, we already know that containers are built from Linux Namespaces and Cgroups, and to learn more deeply about it, we’re going to learn how to build your own container using Golang.

the container will have many other things, like Cgroups to limit the process’s resources, create USER namespaces, and mount files from the container to the server, etc…

See more at: https://faun.pub/deep-into-container-build-your-own-container-with-golang-98ef93f42923

#go #golang #container

How to Build A Simple Container using Golang