The company is going to develop a large screen for data visualization. After studying the data for several days, we sent out our research results, hoping to help you (the content is long).

Method 1: Use CSS transform property and design percentage and scal () method:

Step 1: Write a component, width = 100vw,height = 100%, as the background for the large screen display

<template> <div class="screen-adapter"> <div class="content-wrap" :style="style"> <slot /> </div> </div> </template> <style lang="scss"> .screen-adapter { width: 100vw; min-height: 100%; max-height: 100vh; overflow: hidden; background: url(".. /.. /assets/charts/icon-bg.png") no-repeat; background-size: 100% 100%; } </style>Copy the code

Step 2: According to the design drawings provided by the design students, the percentage of each part of the area can be calculated. For example, the total size is W * H, and the width and height of one icon is W1 * H1, so as to realize the general cutting diagram. In this case, 1- >2 can be obtained:

<template> <div class="screen-adapter"> <div class="content-wrap" :style="style"> <slot /> </div> </div> </template> <script> export default { name: 'ScreenAdapter', data() { return { style: { width: `${this.w}px`, height: ` ${this. H} px `, transform: 'scale (1) translate (50%, 50%)', / / the default scaling, vertical, horizontal center}}; }, props: {w: {// Props props: Number, default: 1600,}, h: {// Props props: Number, default: 1200,},},}; </script> <style lang="scss"> .screen-adapter { width: 100vw; min-height: 100%; max-height: 100vh; overflow: hidden; background: url(".. /.. /assets/charts/icon-bg.png") no-repeat; background-size: 100% 100%; .content-wrap { transform-origin: 0 0; position: absolute; top: 50%; left: 50%; padding: 18px 64px; } } </style>Copy the code

Step 3: Based on step 2, you need to calculate the zoom ratio and set the zoom ratio according to the specific size of the large screen. It should be noted that the binding resize event must not forget to shake, and the page destruction do not forget to remove the listening event:

<template> <div class="screen-adapter"> <div class="content-wrap" :style="style"> <slot /> </div> </div> </template> <script> export default { name: 'ScreenAdapter', data() { return { style: { width: `${this.w}px`, height: ` ${this. H} px `, transform: 'scale (1) translate (50%, 50%)', / / the default scaling, vertical, horizontal center}}; }, props: {w: {// Props: Number, default: 1600,}, h: {// Props: Number, default: 1600,}, h: { 1200, }, }, mounted() { this.setScale(); this.onresize = this.debounce(() => this.setScale(), 100); window.addEventListener('resize', this.onresize); }, the methods: {/ / stabilization debounce (fn, t) {const delay = t | | 500; let timer; // eslint-disable-next-line func-names return function () { // eslint-disable-next-line prefer-rest-params const args = arguments; if (timer) { clearTimeout(timer); } const context = this; timer = setTimeout(() => { timer = null; fn.apply(context, args); }, delay); }; }, // get the scaling scale getScale() {console.log(window.innerheight, window.innerWidth); const w = window.innerWidth / this.w; const h = window.innerHeight / this.h; return w < h ? w : h; SetScale () {this.style.transform = 'scale(${this.getScale()}) translate(-50%, -50%)'; }, }, beforeDestroy() { window.removeEventListener('resize', this.onresize); }}; </script> <style lang="scss"> .screen-adapter { width: 100vw; min-height: 100%; max-height: 100vh; overflow: hidden; background: url(".. /.. /assets/charts/icon-bg.png") no-repeat; background-size: 100% 100%; .content-wrap { transform-origin: 0 0; position: absolute; top: 50%; left: 50%; padding: 18px 64px; } } </style>Copy the code

Step 4: After most of this is done, just put the components in the slot

Chart. Vue is a data visualization page; Screenadapter. vue is a page adaptive component; Card.vue is the outer box of each chart; Everything else is every chart

Chart.vue page is as follows:

Page adaptation effects are as follows

2000 * 1500

1600 * 1200

Method 2: Adaptation scheme for VW and VH of large screen:

Common screen resolutions

  • 1280 * 720: Old computer screens, rarely seen today
  • 1366 * 768: Common LCD display
  • 1920 * 1080: HD LCD monitor
  • 2560 * 1440:2K HD monitor
  • 3840 * 2160:4K HD display

Adaptive difficulties

  • Be compatible with resolutions of different screen sizes so that the page looks and scales properly on different screen resolutions
  • Different resolution, display scene is different, can not be fixed dead PX units
  • Some charts are adaptive in ways that require special treatment

So vw and VH

  • Screen viewport width = 100vw
  • Screen viewport height = 100vh
  • Vw and Vh are also standard units in CSS, as are PX, REM, and %

Vw and VH adaptation scheme

  • According to the size of the design draft, willpxPro rata conversionvwandvh
  • The conversion formula is as follows

‘Assume the size of the design draft is 1920*1080 (be sure to ask the size of the UI design draft before doing this)

That is: Page width =1920px page height =1080px We all know that page width = 100VW page width =100vh so at a screen resolution of 1920x by 1080px, 1920px =100vw and 1080px =100vh, For a 300px and 200px div, the width and height of the work are calculated in units of VW and vh as follows: VwDiv = (300px / 1920px) * 100vw vhDiv = (200px / 1080px) * 100vh so the width and height of individual divs are calculated at 1920*1080 screen resolution and when the screen is zoomed in or out, Div is still vw and VH in width and height, and will automatically adapt to different screen resolutionsCopy the code

‘But it’s not practical to do it manually every time, so I need to wrap a handler that does it for me automatically

I’m using SCSS here

  • insrc/stylesLet’s go ahead and create a new oneutils.scssFile, define the width and height of the design draft two variables
  • Use the BUILT-IN SCSS heremath.divFunction, define twovwandvhComputation function of
  • We pass in specific pixel values that help us automatically calculate vw and Vh values

utils.scss

Our larger screen has an aspect ratio of 4:3; `

/ / the use of SCSS math functions, https://sass-lang.com/documentation/breaking-changes/slash-div @ use "sass: math"; $designWidth:1600; $designHeight:1200; @function vw($px) {@return math.div($px, $designWidth) * 100vw; } @function vh($px) {@return math.div($px, $designHeight) * 100vh; }Copy the code

`

Use mode dependencies

Install the node package of the corresponding version before using it

  • “Sass” : “^ 1.26.5”,
  • “Sass – loader”, “^ 8.0.2”,

The path configuration

I’m using vue2.6 and VUe-cli3, so I just need to configure the utils. SCSS path in vue.config.js to use it globally

Vue.config.js (only the configuration related to this method is shown)

`

const path = require('path'); const StyleLintPlugin = require('stylelint-webpack-plugin'); const CompressionPlugin = require('compression-webpack-plugin'); const defaultSettings = require('./src/settings.js'); function resolve(dir) { return path.join(__dirname, dir); } const name = defaultSettings.title; // page title const port = process.env.port || process.env.npm_config_port || 8066; // dev port const devUrl = process.env.DEV_URL; // dev url module.exports = { publicPath: '/', outputDir: 'dist', assetsDir: 'static', lintOnSave: process.env.NODE_ENV === 'development', productionSourceMap: false, devServer: { port, open: true, overlay: { warnings: false, errors: true, }, proxy: { // detail: https://cli.vuejs.org/config/#devserver-proxy [process.env.VUE_APP_BASE_API]: { target: devUrl, changeOrigin: true, ws: false, }, }, }, configureWebpack: { // provide the app's title in webpack's name field, so that // it can be accessed in index.html to inject the correct title. name, resolve: { alias: { '@': resolve('src'), }, }, performance: { maxEntrypointSize: 400000, maxAssetSize: 250000, }, }, css: { loaderOptions: Sass: {prependData: '@import "@/styles/utils. SCSS "; ', }, less: { javascriptEnabled: true, }, }, }, };Copy the code

‘used in. Vue files

`

<script> export default{ name: "Box",} </script> <style lang=" SCSS "scoped ="scoped"> vw(400); height: vh(300); font-size: vh(16); background-color: black; margin: vw(20); border: vh(2) solid red; } </style>Copy the code

`

Special usage

Sometimes it is not only used in.vue files, such as DOM elements created dynamically in JS

It may be rendered directly into HTML

let oDiv = document.createElement('div')
document.body.appendChild(oDiv)
Copy the code

In this case, I use the following two methods to style the div I created

1. Define some global classes

Create a new global. SCSS file and import it in main.js

global.scss

    .global-div{
        width: vw(300);
        height: vw(200);
        background-color: green;
    }
    
Copy the code

main.js

import './styles/global.scss'
Copy the code

To use it, give the div you created a className,

let oDiv = document.createElement('div')
oDiv.className = "global-div"
Copy the code

2. Define js style handlers

This is similar to the SCSS handler, but uses pure JS to convert PX to VW and vH

Create a new styleutil.js file with the following contents

Const designWidth = 1920; const designHeight = 1080; Function (_px) {return _px * 100.0 / designWidth + 'vw'; }, // function (_px) {return _px * 100.0 / designHeight + 'vh'; }}; export default styleUtil;Copy the code

When used, set width height property separately

import styleUtil from "./src/utils/styleUtil.js"
 
let oDiv = document.createElement('div')
oDiv.style.width = styleUtil.px2vw(300)
oDiv.style.height = styleUtil.px2vh(200)
oDiv.style.margin = styleUtil.px2vh(20)
Copy the code

The downside of this approach is that the screen size changes and you need to manually refresh to adjust

This method refers to the address

Method three: You can use DataV

You can refer to DataV for details

You can choose which method to use according to the specific needs of the project