亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

node環(huán)境下給echarts圖表加文案

shuibo / 1852人閱讀

摘要:開發(fā)環(huán)境開發(fā)語言開發(fā)依賴的包圖表的寬度是先把最終要呈現(xiàn)的效果貼出來,見下圖查看配置項(xiàng)及實(shí)例,給圖表增加額外的文本塊,只有一個(gè)屬性似乎可以實(shí)現(xiàn),它指的是原生圖形元素組件,可以由多種類型組成,如,結(jié)合給的實(shí)例,看起來很不錯(cuò),馬上開干。

開發(fā)環(huán)境:node
開發(fā)語言:javascript
開發(fā)依賴的包:

node-charts

canvas

圖表的寬度是1000
先把最終要呈現(xiàn)的效果貼出來,見下圖:

查看charts配置項(xiàng)及實(shí)例,給圖表增加額外的文本塊,只有一個(gè)屬性graphic【?grafik】似乎可以實(shí)現(xiàn),它指的是原生圖形元素組件,可以由多種類型組成,如image, text, circle, sector, ring, polygon, polyline, ...,結(jié)合給的實(shí)例,看起來很不錯(cuò),so easy!馬上開干。

代碼如下:

var node_echarts = require("node-echarts");
var Path = require("path");
const text = "我的電腦只有4G運(yùn)行內(nèi)存,采用默認(rèn)的idea配置,內(nèi)存在30分鐘內(nèi)會(huì)飚到 >80% ,同時(shí)會(huì)發(fā)生OOM!Chrome就不敢打開!通過上面的配置可以將內(nèi)存使用降低一半以上,只有idea和chrome 的話,內(nèi)存才剛剛 40% 。下面的可以看也可以不看了,下面的分析是別人就行了分析,通過閱讀可見他的電腦內(nèi)存的確不?。?6G的macbook pro),對(duì)于我們學(xué)生黨,默默的使用著4G內(nèi)存的電腦,就不多說上面了!不過,參與討論的一位開發(fā)者給筆者發(fā)了一份他的設(shè)置,雖然是針對(duì)同個(gè)項(xiàng)目,該設(shè)置卻極其復(fù)雜。筆者對(duì)自己的設(shè)置并無不滿,但非常好奇,這些完全不同的設(shè)置對(duì)比 JetBrains 提供的默認(rèn)設(shè)置。";

const config = {
  legend: { bottom: 0, show: true, data: ["身份證數(shù)量", "環(huán)比增長(zhǎng)率"] },
  xAxis: [
    {
      type: "category",
      data: [
        "201701",
        "201702",
        "201703",
        "201704",
        "201705",
        "201706",
        "201707",
        "201708",
        "201709",
        "201710",
        "201711",
        "201712",
        "201801"
      ],
      axisLabel: { interval: 0 },
      axisPointer: { type: "shadow" },
      splitLine:{show: false}
    }
  ],
  yAxis: [
    { type: "value", axisLabel: { formatter: null }  },
    { type: "value", axisLabel: { formatter: "{value}%" }}
  ],
  series: [
    {
      type: "bar",
      name: "身份證數(shù)量",
      data: [
        23620000,
        21060000,
        26420000,
        30180000,
        31430000,
        34100000,
        33740000,
        40170000,
        39910000,
        38420000,
        49300000,
        50710000,
        46550000
      ],
      yAxisIndex: 0
    },
    {
      type: "line",
      name: "環(huán)比增長(zhǎng)率",
      data: [
        -23,
        -12.13,
        20.26,
        12.46,
        4,
        7.82,
        -1.09,
        16.02,
        -0.65,
        -3.88,
        22.05,
        2.79,
        -8.95
      ],
      yAxisIndex: 1
    }
  ],
  color: ["#4498f6", "#d9e96c"],
  graphic: [
    {
                 type: "text",
                 left: "10%",
                 bottom: "bottom",
                 style: {
                     fill: "#333",
                     text: text,
                     font: "14px Microsoft YaHei"
                 }
     }
 ],
};

node_echarts({
  width: 1000,
  height: 400,
  option: config, 
  path: Path.join(__dirname, "./charts.png")
});

process.exit();

效果如下圖:

問題有倆:

只有一行,后面的文字都被截?cái)嗔?/p>

覆蓋了圖例的文字,沒有間距

第2個(gè)問題很好解決,熟悉echarts配置的話,給grid的bottom,legend的bottom設(shè)個(gè)值,但這個(gè)值是動(dòng)態(tài)的,和文案的行數(shù)有關(guān)系,先定一個(gè)基值,假如只有一行,grid的bottom為90,legend的bottom為35,每多一行,就多加15,偽代碼如下:

const config = {
  legend: { bottom: 3 * 15 + 35, show: true, data: ["身份證數(shù)量", "環(huán)比增長(zhǎng)率"] },
  grid: {bottom:  3 * 15 + 90}
...

要得到具體的行數(shù),其實(shí)是解決第1個(gè)問題,所以最核心的問題是在限定的寬度里怎么計(jì)算一段文字的行數(shù)?
先算下一行能放多少個(gè)字符,中英文都算一個(gè)字符,以都是中文來算,這樣算下得到結(jié)果是63,行數(shù) = Math.ceil(字符總長(zhǎng)度/63)。得到行數(shù)后,還要知道每行的字符是什么,畢竟換行是要這樣的:

...
  graphic: [
    {
                 type: "text",
                 left: "10%",
                 bottom: "bottom",
                 style: {
                     fill: "#333",
                     text: ["text","text2", "text3"].join("
"),
                     font: "14px Microsoft YaHei"
                 }
     }
 ],
...

想了半天,代碼出來了

...
const buildText = (result=text) => {
    const graphicY = 15;
    let texts = [];
    let gridBottom = 90;
    let legendBottom = 35;
    

    const rlen = 63; // 一行最多的字符長(zhǎng)度
    const len = result.length; // 所有字符長(zhǎng)度
    // 大于一行
    if (len > rlen) {
      const temp = Math.ceil(len / rlen); // 總行數(shù)
      const arr = result.split(""); // 把文案分割為每個(gè)字符
      const newArrs = {};
      // 循環(huán)總行數(shù)
      for (let k = 0; k < temp; k++) {
        newArrs[k] = []; // 存儲(chǔ)每行的字符

        for (let i = rlen * k; i < rlen * (k + 1); i++) {
          if(arr[i] != undefined)
            newArrs[k].push(arr[i]);
        }
      }
      for(let j in newArrs){
        texts.push(newArrs[j].join(""));
      }
      const lastLen = texts.length-1;
      gridBottom =  lastLen * graphicY + gridBottom;
      legendBottom = lastLen * graphicY + legendBottom;
    } else {
      texts = [result];
    }
   // console.log(texts);

    return {
      graphic: [
        {
          type: "text",
          left: "10%",
          bottom: "bottom",
          style: {
            fill: "#333",
            text: texts.join("
"),
            font: "14px Microsoft YaHei"
          }
        }
      ],
      gridBottom: gridBottom,
      legendBottom: legendBottom
    };
  }
const texts = buildText();
const config = {
...
 legend: {  bottom: texts.legendBottom, show: true, data: ["身份證數(shù)量", "環(huán)比增長(zhǎng)率"] },
  grid:{ bottom: texts.gridBottom},
...
}
config.graphic = texts.graphic;

得到效果如下:

換行了,但是每行的字符不一樣,而且沒行間距,擠得慌。說明計(jì)算每一行的長(zhǎng)度的方法不對(duì),中文和英文的寬度不一樣,需要知道每個(gè)字符的寬度才行,然后graphic不是支持image嘛,我就換個(gè)思路,把文字換成圖片吧,因?yàn)楹蚦anvas相關(guān),google一把“canvas 文字換行”后,找到這篇canvas文本繪制自動(dòng)換行、字間距、豎排等實(shí)現(xiàn),再此安利下這位作者,他寫的博文都是滿滿的干貨,canvas中有一個(gè)很有用的API:measureText,用來計(jì)算字符寬度,把文字變成圖片的代碼如下:

var fs = require("fs")
var path = require("path")
var Canvas = require("canvas")
const maxWidth = 1000;
let height = 20;
const text = "我的電腦只有4G運(yùn)行內(nèi)存,采用默認(rèn)的idea配置,內(nèi)存在30分鐘內(nèi)會(huì)飚到 >80% ,同時(shí)會(huì)發(fā)生OOM!Chrome就不敢打開!通過上面的配置可以將內(nèi)存使用降低一半以上,只有idea和chrome 的話,內(nèi)存才剛剛 40% 。下面的可以看也可以不看了,下面的分析是別人就行了分析,通過閱讀可見他的電腦內(nèi)存的確不?。?6G的macbook pro),對(duì)于我們學(xué)生黨,默默的使用著4G內(nèi)存的電腦,就不多說上面了!不過,參與討論的一位開發(fā)者給筆者發(fā)了一份他的設(shè)置,雖然是針對(duì)同個(gè)項(xiàng)目,該設(shè)置卻極其復(fù)雜。筆者對(duì)自己的設(shè)置并無不滿,但非常好奇,這些完全不同的設(shè)置對(duì)比 JetBrains 提供的默認(rèn)設(shè)置。";
const rlen = 63; // 一行最多的字符長(zhǎng)度
const len = text.length; // 所有字符長(zhǎng)度
const temp = Math.ceil(len / rlen); // 總行數(shù)

var canvas = Canvas.createCanvas(maxWidth, temp * height)
var ctx = canvas.getContext("2d")

ctx.globalAlpha = 1
ctx.font = "14px Microsoft Yahei"
ctx.lineWidth = 1
ctx.fillStyle = "#000"

const arrText = text.split("");
let line = "";
let y = 20;
const lineHeight = 25;
  // 核心思路是這段代碼,循環(huán)每個(gè)字符,當(dāng)字符寬度大于最大寬度就換行,且Y坐標(biāo)也增加
  for (var n = 0; n < arrText.length; n++) {
      var testLine = line + arrText[n];
      var metrics = ctx.measureText(testLine);
      var testWidth = metrics.width;
      if (testWidth > maxWidth && n > 0) {
        ctx.fillText(line, 0, y);
        line = arrText[n];
        y += lineHeight;
      } else {
        line = testLine;
      }
    //  console.log(line)
  }
  console.log(line)
  ctx.fillText(line, 0, y);

canvas.createPNGStream().pipe(fs.createWriteStream(path.join(__dirname, "text.png")))

拿到的圖片如下:

然后修改graphic

...
  graphic:[{
                 type: "image",
                 left: "10%",
                 bottom: "bottom",
                 style: {
                     image: path.join(__dirname, "text.png")
                     width: 1000,
                     height: 200  
                 }
     }],
   ...

可是圖片沒有生成,上面這段代碼沒有發(fā)生作用。查了源代碼,也沒找到原因,只好提個(gè)issue。這又回到起點(diǎn),不過計(jì)算字符長(zhǎng)度的方法采用上述方法

const buildText = (text=text) => {
  const graphicY = 15;
  let gridBottom = 90;
  let legendBottom = 35;
  const maxWidth = 900;
  const canvas = createCanvas(maxWidth,100);
  const ctx = canvas.getContext("2d");
  ctx.font = "normal 14px SongTi";
  const arrText = text.split("");
  let line = "";
  const newArrs = [];
  for (var n = 0; n < arrText.length; n++) {
      var testLine = line + arrText[n];
      var metrics = ctx.measureText(testLine);
      var testWidth = metrics.width;
     
      if (testWidth > maxWidth & n>0) {
        line = arrText[n];
        newArrs.push(testLine.substr(0, testLine.length-1));
      } else {
        line = testLine;
      }
  }
  newArrs.push(line);
  //console.log(newArrs);
  const row = newArrs.length;
  if (row > 1) {
    gridBottom = row * graphicY + gridBottom;
    legendBottom = row * graphicY + legendBottom;
  }
 
  return {
    graphic:[
        {
          type: "text",
          left: "10%",
          bottom: "bottom",
          style: {
            fill: "#333",
            text: newArrs.join("
"),
            font: "14px Songti"
          }
        }
      ],
    gridBottom: gridBottom,
    legendBottom: legendBottom
  };
}

得到的效果如下:

行間距的問題沒解決,想到graphic既然是數(shù)組,把每行拆開作為多帶帶的對(duì)象,bottom的值都不一樣。

const buildText = (text=text) =>{
  const graphicY = 15;
  const lineY = 20; // 設(shè)置每行文字bottom的基值
  let gridBottom = 90;
  let legendBottom = 35;
  const maxWidth = 900;
  const canvas = createCanvas(maxWidth,100);
  const ctx = canvas.getContext("2d");
  ctx.font = "normal 14px SongTi";
  const arrText = text.split("");
  let line = "";
  const newArrs = [];
  for (var n = 0; n < arrText.length; n++) {
      var testLine = line + arrText[n];
      var metrics = ctx.measureText(testLine);
      var testWidth = metrics.width;
     
      if (testWidth > maxWidth & n>0) {
        line = arrText[n];
        newArrs.push(testLine.substr(0, testLine.length-1));
      } else {
        line = testLine;
      }
  }
  newArrs.push(line);
  //console.log(newArrs);
  const row = newArrs.length; // 總行數(shù)
  if (row > 1) {
    gridBottom = row * graphicY + gridBottom;
    legendBottom = row * graphicY + legendBottom;
  }
  let graphics = [];
  // 循環(huán)每行文字 
  for (let k=0; k < row; k++){
     const temp = {
      type: "text",
      left: "5%",
      bottom: (row-1-k) * lineY, // 數(shù)值越大,越靠前
      style: {
        fill: "#333",
        text: [`${newArrs[k]}`].join("
"),
        font: "14px SongTi"
      }
    }
    graphics.push(temp);
  }
 // console.log(graphics);
  return {
    graphic: graphics,
    gridBottom: gridBottom,
    legendBottom: legendBottom
  };

至此,問題都解決了。

最終的源代碼傳送門:github

總結(jié)

了解echarts坐標(biāo)系
熟悉echarts基本配置
熟悉echarts graphic配置
了解canvas基本API
熟悉數(shù)學(xué)
對(duì)于數(shù)字要保持敏感,不要寫死了

多搜索,多嘗試,多思考才會(huì)變通

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/93630.html

相關(guān)文章

  • 使用vue框架開發(fā)兩年以上工作經(jīng)驗(yàn)的前端工程師面試題

    摘要:瀏覽器兼容性事件綁定一框架使用的是什么如何避免樣式污染,以及改變其樣式引入插件的方式如何按需引入安裝二的生命周期的使用生命周期鉤子函數(shù)包含的組件緩存與排除的組件不緩存,優(yōu)先級(jí)大于的作用中一般處理什么問題三如何封裝組件組件封裝過么如何 瀏覽器兼容性(ie)1.事件綁定 vue一. UI框架使用的是什么? 1.1 如何避免樣式污染,以及改變其樣式;1.2 vue-cli 引入插件的方式? ...

    wind3110991 評(píng)論0 收藏0
  • 每周前端開源推薦第六期

    摘要:每周前端開源推薦第六期從名字就可以很容易的看出該項(xiàng)目的作用,解壓縮。同時(shí)支持瀏覽器和。是任務(wù)調(diào)度的項(xiàng)目。初始化定義人物每三分鐘觸發(fā)一次觸發(fā)一個(gè)交互式學(xué)習(xí)的方式。強(qiáng)烈建議大家先去體驗(yàn)一下的介紹是由百度團(tuán)隊(duì)開發(fā)的一款開源圖表項(xiàng)目。 每周前端開源推薦第六期 43081j / rar.js Pure-JavaScript RAR reader using AJAX, File API...

    Salamander 評(píng)論0 收藏0
  • 每周前端開源推薦第六期

    摘要:每周前端開源推薦第六期從名字就可以很容易的看出該項(xiàng)目的作用,解壓縮。同時(shí)支持瀏覽器和。是任務(wù)調(diào)度的項(xiàng)目。初始化定義人物每三分鐘觸發(fā)一次觸發(fā)一個(gè)交互式學(xué)習(xí)的方式。強(qiáng)烈建議大家先去體驗(yàn)一下的介紹是由百度團(tuán)隊(duì)開發(fā)的一款開源圖表項(xiàng)目。 每周前端開源推薦第六期 43081j / rar.js Pure-JavaScript RAR reader using AJAX, File API...

    channg 評(píng)論0 收藏0
  • 每周前端開源推薦第六期

    摘要:每周前端開源推薦第六期從名字就可以很容易的看出該項(xiàng)目的作用,解壓縮。同時(shí)支持瀏覽器和。是任務(wù)調(diào)度的項(xiàng)目。初始化定義人物每三分鐘觸發(fā)一次觸發(fā)一個(gè)交互式學(xué)習(xí)的方式。強(qiáng)烈建議大家先去體驗(yàn)一下的介紹是由百度團(tuán)隊(duì)開發(fā)的一款開源圖表項(xiàng)目。 每周前端開源推薦第六期 43081j / rar.js Pure-JavaScript RAR reader using AJAX, File API...

    worldligang 評(píng)論0 收藏0
  • React Native使用百度Echarts顯示圖表

    摘要:今天我就來介紹下在中如何使用來顯示各種圖表。首先需要在我們的項(xiàng)目中安裝組件,該組件是兼容和安卓雙平臺(tái)的。組件主要有三個(gè)屬性圖表的相關(guān)配置和數(shù)據(jù)。圖表的高度,默認(rèn)值是。解決方法將中的代碼修改為同時(shí)將文件拷貝到安卓項(xiàng)目下面的文件夾中。 本文原創(chuàng)首發(fā)于公眾號(hào):ReactNative開發(fā)圈 Echarts是百度推出的免費(fèi)開源的圖表組件,功能豐富,涵蓋各行業(yè)圖表。相信很多同學(xué)在網(wǎng)頁端都使用過。今...

    Lucky_Boy 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<