国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
前端圖表可視化的應(yīng)用實(shí)踐總結(jié)

需求簡(jiǎn)介

騰訊企鵝輔導(dǎo)在學(xué)生上課結(jié)束后推送“學(xué)習(xí)報(bào)告”,是課程所提供的一項(xiàng)重要服務(wù)。家長(zhǎng)在“學(xué)習(xí)報(bào)告”中能查看孩子上課時(shí)間及互動(dòng)情況,答題及掌握知識(shí)點(diǎn),作業(yè)考試分?jǐn)?shù),班級(jí)排名等諸多數(shù)據(jù),繼而讓學(xué)生家長(zhǎng)及時(shí)掌握孩子的學(xué)習(xí)情況。

此次改版升級(jí)是針對(duì)舊學(xué)習(xí)報(bào)告的的數(shù)據(jù)和展示進(jìn)行的一次優(yōu)化:增加考試模塊、知識(shí)點(diǎn)采用更簡(jiǎn)單的表達(dá)形式、在視覺(jué)交互上更加年輕活潑、并運(yùn)用了更多數(shù)據(jù)圖表可視化在其數(shù)據(jù)展示中。

考試模塊-數(shù)據(jù)圖表可視化的應(yīng)用

1.數(shù)據(jù)可視化組件庫(kù)的選擇及應(yīng)用

在考試模塊中,需要展示學(xué)生成績(jī)變化趨勢(shì)的曲線圖,而這需要用到第三方的可視化組件庫(kù),繼而快速回憶起比較知名的幾款:國(guó)外的HighChart,百度家的Echart,阿里的AntV(移動(dòng)端F2)等。當(dāng)然也希望騰訊有一天也能有同樣知名好用的的可視化組件庫(kù)。

在選擇可視化組件庫(kù)時(shí),我們主要考慮以下幾點(diǎn):1.能夠良好支持移動(dòng)端且輕量。2.支持React。3.具備足夠自由的可定制化配置樣式的能力。

其中第三點(diǎn)尤其重要,因?yàn)檫@里要準(zhǔn)確還原交互視覺(jué)(不得不說(shuō)我們交互和視覺(jué)給的要求很高)。根據(jù)經(jīng)驗(yàn),縱使強(qiáng)大的可視化組件庫(kù)配置非常繁多,但往往可配置的內(nèi)容太多,根本找不到用什么配置項(xiàng)達(dá)到目的,而且一些配置相互影響,變化很多。

最終我們發(fā)現(xiàn)并使用了Recharts。它是一個(gè)使用React和D3構(gòu)建的Redefined圖表庫(kù)。具備以下特性:

  • 支持React組件,聲明式的標(biāo)簽,寫(xiě)圖表和寫(xiě) HTML 一樣簡(jiǎn)單。

  • 原生SVG支持,依賴(lài)于輕量級(jí)的 D3 子模塊構(gòu)建 SVG 元素。

  • 接口式的 API,解決各種個(gè)性化的需求。

以下是部分需求代碼,展示了其用法和特性:

<ResponsiveContainer width="100%" height={200}>        <LineChart data={data}>          <CartesianGrid horizontal={false} strokeDasharray="2 3" />          <Line type={lineStyle} dataKey="avgScore" stroke="#CCCCCC" fill="#CCCCCC"            label={              <CustomizedLabel direction="down" data={data}                relateKey="actualScore"/>            }            isAnimationActive={false}  />          <Line            type={lineStyle} dataKey="actualScore" stroke="#08CB6A" fill="#08CB6A"            label={<CustomizedLabel data={data} relateKey="avgScore" />}            isAnimationActive={false} />          <Legend            align="left" verticalAlign="top" iconSize={4}            iconType="rect" height={36}            formatter={(value) => {              return { actualScore: '我的成績(jī)', avgScore: '班級(jí)平均分' }[value];            }}            wrapperStyle={{              left: -13,              fontSize: 12,            }} />          <XAxis            dataKey="name" padding={{ left: padding, right: padding }}  axisLine={false} tickLine={false} />          <YAxis domain={[-8, 108]} hide />        </LineChart>      </ResponsiveContainer>

除了樣式配置項(xiàng)外,還提供了諸如“strokeDasharray”貼近原生SVG的配置項(xiàng)。對(duì)于熟悉SVG的同學(xué)就能能很準(zhǔn)確寫(xiě)圖形樣式了。

2. 如何畫(huà)好一根曲線[貝塞爾曲線]

說(shuō)道貝塞爾曲線,前端的同學(xué)很容易想到的是CSS transition中的cubic-bezier,一般是起始點(diǎn)和兩個(gè)控制點(diǎn) 來(lái)生成兩點(diǎn)間的一條曲線,也就是常用三階貝塞爾曲線。關(guān)于貝塞爾曲線就不再贅述了,其原理和SVG中Path中貝塞爾曲線的使用,可查閱下面兩篇文章。貝塞爾曲線原理
SVG Path 曲線

OK,根據(jù)需求,我們考試成績(jī)已經(jīng)確定兩個(gè)點(diǎn)了,那么這根曲線到底具被怎樣的“性格”,彎一點(diǎn)還是平滑一點(diǎn)?但是這需要和視覺(jué)的同學(xué)反復(fù)調(diào)整得出一個(gè)讓她滿意的“參數(shù)”。當(dāng)然如果要做到完全滿意,可能還要針對(duì)不同情況計(jì)算不同的參數(shù)。

下面代碼為:通過(guò)D3 shape(可視化的圖形基元),除了終點(diǎn),兩個(gè)控制點(diǎn)的x值通過(guò)參數(shù)設(shè)置。將其實(shí)例作為props 的type值傳入Recharts中的<Line/>中,即可得到想要的曲線。

BezierLineShape.prototype = {  lineStart() {    this._x0 = this._x1 = this._y0 = this._y1 = this._t0 = NaN;    this._point = 0;    console.log('lineStart', this._line, this._point);  },  lineEnd() {    console.log('lineEnd', this._line, this._point);  },  point(x, y) {    console.log('point', x, y, this._line);    (x = +x), (y = +y);    if (x === this._x1 && y === this._y1) {      return;    }     switch (this._point) {      case 0: {        this._point = 1;        this._x1 = x;        this._y1 = y;        this._context.moveTo(x, y);        break;      }      case 1: {        const mint = (x - this._x1) * 0.35;//此為控制點(diǎn)位置參數(shù)        const x1 = this._x1 + mint;        const y1 = this._y1;        const x2 = x - mint;        const y2 = y;        this._x1 = x;        this._y1 = y;        console.log('bezierCurveTo', x1, y1, x2, y2, x, y);        this._context.bezierCurveTo(x1, y1, x2, y2, x, y);        break;      }      default:        break;    }  },};
最后效果圖:

基于SVG做的客制化修改

Scalable Vector Graphics,意思為可縮放的矢量圖形,它基于XML,是一種開(kāi)放標(biāo)準(zhǔn)的矢量圖形語(yǔ)言。recharts提供基于react組件的寫(xiě)法,去寫(xiě)可定制化svg圖形。比如下面:用組件svg 來(lái)定制的Label的位置樣式。

export default class CustomizedLabel extends React.PureComponent {  static defaultProps = {    direction: 'up', //    stroke: '#777',  };  render() {    const { x, y, stroke, value, direction, index, relateKey, data } = this.props;     let settedDirect = direction;    try {      const relateValue = data[index][relateKey];      if (value > relateValue) {        settedDirect = 'up';      } else if (value < relateValue) {        settedDirect = 'down';      }    } catch (e) {      // BJ_Report    }    const dy = settedDirect === 'up' ? -10 : 18;    return (      <text x={x} y={y} dy={dy} fill={stroke} fontSize={14} textAnchor="middle">        {value}      </text>    );  }}

學(xué)習(xí)回顧-輪播柱狀圖結(jié)合實(shí)現(xiàn)

在學(xué)習(xí)回顧模塊,用戶可以左右滑動(dòng)/點(diǎn)擊柱狀圖,來(lái)切換不同課程信息展示。很顯然可以通過(guò)一個(gè)輪播組件來(lái)實(shí)現(xiàn),但是這個(gè)模塊還具備柱狀圖的展示。要選擇一個(gè)兼具輪播和圖表的組件,還要保證兩者的功能和樣式都可按需求定制。顯然這并不容易,即便存在這樣組件也要花上不少時(shí)間去尋找和篩選。

這時(shí)就要權(quán)衡,到底是在一個(gè)輪播組件添加圖表,還是改造圖表組件為輪播。這里我選擇基于輪播組件來(lái)寫(xiě)里面的柱狀圖的這個(gè)方案。原因是:這里的柱狀圖并不復(fù)雜,可以用dom+css樣式來(lái)實(shí)現(xiàn),并且正好實(shí)現(xiàn)樣式定制化的需求。雖然圖表組件(比如antV的F2)也提供類(lèi)似滑動(dòng)圖表的功能,但是由于輪播不是它主要特性,諸如多item展示以及居中item選中等特性,改起來(lái)也不容易。

確定在輪播組件實(shí)現(xiàn)柱狀圖方案后,發(fā)現(xiàn)在實(shí)現(xiàn)仍有難點(diǎn):第一個(gè)item的左邊和最后一個(gè)item的右邊仍有虛線軸。最開(kāi)始想到通過(guò)添加空item來(lái)實(shí)現(xiàn),但實(shí)際需求是在滑至第一個(gè)和最后一個(gè)是不允許繼續(xù)滑動(dòng)的,所以不能直接添加空item。

那怎么辦呢?我們都知道輪播都是由視窗加container組成,通過(guò)計(jì)算定位container的位置來(lái)輪播。我不能在container里面直接添加DOM元素,否則會(huì)影響輪播組件的計(jì)算。但是我們可以在container前后添加偽元素,這樣就不會(huì)妨礙輪播定位的計(jì)算了。

.time-chart-item:nth-of-type(1):after {  content: '';  width: pxToRem(116);  height: pxToRem(144);  display: block;  position: absolute;  background: url(./img/dashline.png) pxToRem(29) 0 no-repeat,    url(./img/dashline.png) pxToRem(29+58) 0 no-repeat;  top: pxToRem(28);  left: pxToRem(-116);}

這里有個(gè)平時(shí)很少用到的background的都多背景方法,由于左右兩邊最多有兩根虛線展示,backgound設(shè)置兩個(gè)虛線圖片即可。

本次上課-如何用CSS mask實(shí)現(xiàn)狀態(tài)條

當(dāng)看到視覺(jué)稿 學(xué)生在線時(shí)間狀態(tài)條的時(shí)候,一眼看去ok完全沒(méi)有難度,不就一個(gè)簡(jiǎn)單的狀態(tài)條嗎,只不過(guò)不連續(xù)罷了。寫(xiě)個(gè)div,overflow-hidden,只需計(jì)算綠色塊的width值和left值即可,擼起袖子就是干,十分鐘搞定。

可是設(shè)計(jì)走查時(shí),卻逃不過(guò)視覺(jué)設(shè)計(jì)同學(xué)的火眼金睛:“這里的綠色應(yīng)該是覆蓋灰色邊框上面的!”接下來(lái)為了滿足視覺(jué)同學(xué)的要求可花費(fèi)了不少功夫。因?yàn)樵诰€狀態(tài)條及其相關(guān)計(jì)算已經(jīng)寫(xiě)好,最開(kāi)始沒(méi)有使用圖表組件,因?yàn)槲矣X(jué)得這很簡(jiǎn)單,不需要?dú)㈦u用牛刀,直接CSS可以實(shí)現(xiàn)。

寫(xiě)來(lái)改寫(xiě)代碼,為了讓綠色在線條覆蓋背景border,我將綠色狀態(tài)條覆蓋在上層,但這又出現(xiàn)另外一個(gè)問(wèn)題。綠色條塊左右兩側(cè)由于不被父級(jí)overflowhiden遮住,在值未達(dá)到極值時(shí),無(wú)法做到圓角轉(zhuǎn)直線的效果。

傳統(tǒng)的辦法

在外面再套一層div,position設(shè)置為relative,設(shè)置圓角和overflow hidden,綠色塊相對(duì)于這一層div定位,如果溢出就會(huì)被裁剪。

css遮罩

css 有一個(gè) -webkit-mask 屬性。它所提供類(lèi)似于遮罩到的能力,讓原本CSS無(wú)法實(shí)現(xiàn)的shape通過(guò)圖片也能做到??戳讼旅孢@個(gè)圖就清楚了。

那么怎么應(yīng)用-webkit-mask來(lái)實(shí)現(xiàn)不連續(xù)的狀態(tài)條呢?其實(shí)只需要一個(gè)非透明的極小的png圖,計(jì)算好寬度以及位置,再進(jìn)行樣式設(shè)置即可。

這里的-webkit-mask和所有background的多背景圖使用是一樣的,需要注意的是,這里的第一個(gè)參數(shù)值不要把它誤會(huì)成是的x值,而是圖片的x%與容器x%的重合點(diǎn),這里很容易出錯(cuò)。以下是計(jì)算的代碼和生成的css樣式:

const maskArray = [];InClassState.map((item) => {  const { start_inclass: start, end_inclass: end } = item;  const left = (start - lessonBeginTime) / allTime;  const width = (end - start) / allTime;  const maskLeft = left / (1 - width);  maskArray.push(`url(${maskimg}) no-repeat ${maskLeft.toFixed(2) * 100}% 0/  ${width * 100}% 100%`);});style.WebkitMask = maskArray.join(',');
-webkit-mask:url(//fudao.qq.com/block_0bb81cb….png) 0% 0px / 60% 100% no-repeat, url(//fudao.qq.com/block_0bb81cb….png) 76% 0px / 15% 100% no-repeat,url(//fudao.qq.com/block_0bb81cb….png) 106% 0px / 15% 100% no-repeat;

只需要通過(guò)一個(gè)元素。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
3000字/16張炫酷動(dòng)態(tài)圖,推薦一款好用到爆的Python可視化利器
VUE中快速添加水印的幾種方式
基于Vue的前端架構(gòu),我做了這15點(diǎn)
推薦30款最佳的數(shù)據(jù)可視化工具
大數(shù)據(jù)與數(shù)據(jù)可視化(4)
推薦7個(gè)數(shù)據(jù)可視化工具,讓你的信息快速生成可視化
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服