可視化框架設計-數據類型

數據類型

  • 數據的分類方式
  • 數據類型的設計-度量
  • 更多

簡介

數據可視化的本質就是將數據映射到圖形,不一樣數據類型的數據適合的圖形屬性也不同,本章講解數據分類和G2是如何設計數據分類。圖形屬性在下一章節視覺通道中講解。算法

數據類型

c-1

數據的類型能夠按照兩種分類方式: 
* 數據天然的分類 
* 數據是否連續數組

數據天然的分類

按照數據的天然分類,能夠將數值類型分爲: 
* 名詞:常見的名詞,不關心順序,好比國家的名稱 
* 有序:有序的分類,例如警報信息,從低到高分爲黃色警告、橙色警告和紅色警告 
* 間隔:有間隔的數字,不考慮0的意義。例如溫度,0度不表明沒有溫度 
* 比例:表示字段之間存在比例關係,0必須有意義。dom

image

數據是否連續

按照數據是否連續劃分的方式: 
+ 分類(定性)數據,又分爲有序的分類和無序的分類 
+ 連續(定量)數據,連續不間斷的數值,時間也是一種連續的數據類型ide

 

首先咱們來看一下下面的數據:函數

[
{"month":"一月","temperature":7,"city":"tokyo"}, {"month":"二月","temperature":6.9,"city":"newYork"}, {"month":"三月","temperature":9.5,"city":"tokyo"}, {"month":"四月","temperature":14.5,"city":"tokyo"}, {"month":"五月","temperature":18.2,"city":"berlin"} ]

其中:month 表明月份,temperature 表明溫度,city 表明城市網站

  • 上面數據中monthcity都是離散的分類,可是又有所差別。month是有序的分類類型,而city是無序的分類類型。
  • temperature 是連續的數字

如何設計數據類型-度量

咱們在G2中將數據類型按照是否連續來劃分,每種分類設計成不一樣的度量(Scale),度量用於完成如下功能:spa

  • 將數據轉換到 0-1 範圍內,方便將數據映射到位置、顏色、大小等圖形屬性。
  • 將轉換過的數據從 0-1 的範圍內反轉到原始值。例如 分類a 轉換成 0.2,那此時 0.2反轉回來的值就是分類a
  • 將數據劃分,用於在座標軸上、圖例上顯示數值的範圍、分類等信息設計

    • 分類信息展現在圖例上

    image

    • 肯定顯示在座標軸上座標點 30,40,50,60,70

    image

因此每種度量必須包含如下信息:code

  • 定義域(domain),分類度量指的是各類分類,連續度量的最小值、最大值
  • 值域(range),將分類、連續數據映射到範圍,默認 0-1
  • 座標點(ticks),用於顯示在圖例或者座標軸上,對於分類度量,座標點就是分類類型;連續的數據類型,須要計算出對人比較友好的座標點、友好的座標間距,例如: 
    • 1,2,3,4,5
    • 0, 5,10,15,20
    • 0.001, 0.005,0.010 
      而不是:
    • 1.1,2.1,3.1,4.1
    • 12,22,32,42,52

支持的度量

G2中提供了下面幾種度量orm

image

  • identity,常量類型的數值,也就是說數據的某個字段是不變的常量;
  • linear,連續的數字 [1,2,3,4,5];
  • cat,分類, [‘男’,’女’];
  • time,連續的時間類型;
  • log,連續非線性的 Log 數據 將 [1,10,100,1000] 轉換成[0,1,2,3];
  • pow,連續非線性的 pow 數據 將 [2,4,8,16,32] 轉換成 [1,2,3,4,5];
  • timeCat,非連續的時間,好比股票的時間不包括週末或者未開盤的日期。

image

屬性和接口設計

度量共有的屬性:

屬性名 說明
type 度量類型
range 度量轉換的值域,默認是[0,1]
alias 別名,大多數數據集合的字段名都是英文,有時候須要定義中文名稱,便於在圖例、提示信息上顯示
ticks 支持的座標點,能夠在圖例、座標軸上顯示,座標點的計算後面詳細介紹
tickCount 座標點的個數,不一樣類型的度量默認值不一樣
formatter 輸出字段時的格式化函數,會影響數據在座標軸、圖例、提示信息(tooltip)上的顯示

linear

連續的數據類型的基類,包含如下特殊的屬性

屬性名 說明
min 定義域的最小值
max 定義域的最大值
tickCount 連續類型的度量,默認生成座標點的個數是5
tickInterval 用於指定座標軸各個標度點的間距,是原始數據之間的間距差值,tickCount 和 tickInterval 不能夠同時聲明
nice 是否根據人對數字識別的友好度,來調整min和max。例如 min:3,max: 97,若是nice: true,那麼會自動調整爲:min: 0,max: 100

cat

分類類型度量的特殊屬性

屬性名 說明
values 當前字段的分類值

G2建立圖表的時候,values字段通常會自動從數據中取得,可是如下2中情形下須要用戶手動指定

  • 須要指定分類的順序時,例如:type 字段有’最大’,’最小’和’適中’3種類型,咱們想指定這些分類在座標軸或者圖例上的順序時:

    [
    {a: 'a1', b:'b1', type: '最小'}, {a: 'a2', b:'b2', type: '最大'}, {a: 'a3', b:'b3', type: '適中'} ] var defs = { 'type': {type: 'cat',values: ['最小','適中','最大']} };

    若是不聲明度量的values字段,那麼默認的順序是:‘最小’,‘最大’,‘適中’

  • 若是數據中的分類類型使用枚舉的方式表示,那也也須要指定values

    [
    {a: 'a1', b:'b1', type: 0}, {a: 'a2', b:'b2', type: 2}, {a: 'a3', b:'b3', type: 1} ] var defs = { 'type': {type: 'cat',values: ['最小','適中','最大']} }; 

    必須指定’cat’類型,values的值按照索引跟枚舉類型一一對應

time

time類型是一種特殊的連續型數值,因此咱們將time類型的度量定義爲linear的子類,除了支持全部通用的屬性和linear度量的屬性外,還有本身特殊的屬性:

屬性名 說明
mask 數據的格式化格式 默認:’yyyy-mm-dd’

目前支持 2 種類型的時間(time)類型:

  • 時間戳的數字形式, 1436237115500 // new Date().getTime()
  • 時間字符串: ‘2015-03-01’, ‘2015-03-01 12:01:40’, ‘2015/01/05’,’2015-03-01T16:00:00.000Z’

格式化日期時mask的佔位符:

  • y: year
  • m: month
  • d: date
  • H: hour
  • M: minute
  • s: second

log

log類型的數據能夠將很是大範圍的數據映射到一個均勻的範圍內,這種度量是linear的子類,支持全部通用的屬性和linear度量的屬性,特有的屬性:

屬性名 說明
base Log 的基數,默認是2

如下情形下建議使用log度量

  • 散點圖時數據的分佈很是廣,同時數據分散在幾個區間內。例如 分佈在 0-100, 10000 - 100000, 1千萬 - 1億內,這時候適合使用log 度量
  • 使用熱力圖時,數據分佈不均勻時也會出現只有很是高的數據點附近纔有顏色,此時須要使用log度量,對數據進行log處理。

pow

pow類型的數據也是linear類型的一個子類,除了支持全部通用的屬性和linear度量的屬性外也有本身的屬性:

屬性名 說明
exponent 指數,默認是2

timeCat

timeCat類型的數據,是一種日期數據,可是不是連續的日期。例如表明存在股票交易的日期,此時若是使用time類型,那麼節假日沒有數據,折線圖、k線圖會斷裂,因此此時使用timeCat的度量表示分類的日期,默認會對數據作排序。

屬性名 說明
tickCount 此時須要設置座標點的個數
mask 數據的格式化格式

image

度量座標點的計算

度量的信息須要在圖例、座標軸上顯示時,不可能所有顯示全部的數據,那麼就須要選取一些表明性的數據顯示在圖例、座標軸上,咱們稱這些數據爲ticks(座標點),不一樣的類型的度量計算ticks(座標點)的算法各不同,咱們這裏提供3類度量ticks(座標點)的計算:

  • 分類度量,包括 cat,timeCat
  • 連續類型度量,包括linear,log,pow
  • 時間類型度量,包括time

分類度量的計算

分類度量通常狀況下不須要計算ticks,直接將全部的分類在圖例、座標軸上顯示出來便可

可是當分類類型的數值過多,同時分類間有順序關係時能夠省略掉一些分類例如:

image

計算時須要使用到的屬性:

  • values: 當前度量的分類值,若是未指定,則直接從數據源中提取
  • tickCount: 保留幾個座標點

分類的ticks計算很是簡單個

  • 均勻的從values中取tickCount個座標點
  • 爲了保證values第一個和最後一個value都在ticks中,取值的間隔是 (values.length - 1) / (tickCount - 1),則保證values第一個和最後一個value都在ticks中

整除的場景:

var values= ["第一週","第二週","第三週","第四周","第五週","第六週","第七週","第八週","第九周"]; var tickCount = 5; // 因爲 values.length = 9; // 平均間隔 step = (9 - 1) / (5 - 1) = 2; var ticks = ["第一週","第三週","第五週","第七週","第九周"] 

不能整除:

var values= ["第一週","第二週","第三週","第四周","第五週"]; var tickCount = 4; // 因爲 values.length = 5; // 平均間隔 step = (5 - 1) / (4 - 1) = 4/3; 取整 step = 1; // 捨棄了第四周 var ticks = ["第一週","第二週","第三週","第五週"]

連續數據度量的計算

連續數據類型計算座標點須要考慮如下問題:

  • 座標點必須是對人友好的數據(nice numbers),不能簡單的均分的方式計算座標點。 
    例如 min: 3,max: 97,tickCount: 6,若是平均劃分則會生成 ticks: [3, 21.8,40.6,59.4,78.2,97],咱們理想的方式是ticks: [0, 20, 40, 60, 80, 100]
  • 計算的數值範圍不肯定,有多是 0, 100, 1000 也有多是 0.01,0.02,0.03

連續數據座標點的計算方式以下:

  • 指定一個逼近數組 [1,2,5,10],用於計算對人友好的tickInterval
  • 根據傳入的min,max,tickCount 計算 tickInterval,將tickInterval的值轉換到 0-10之間,保留轉換的係數,例如min: 0, max: 9003,tickCount = 4,n那麼計算的tickInterval = 3001 變成 3.001,係數是1000,而後在逼近數組中找到一個逼近值,以 3.001爲示例 
    • 能夠選擇向上逼近(最終生成的座標點個數小於tickCount),得出逼近值 5
    • 或者選擇向下逼近(最終生成的座標點的個數大於tickCount),得出逼近值 2
    • 或者四捨五入(有可能會多,有可能會少),得出逼近值5
  • 將獲得的逼近值乘之前面求得的係數1000, 
    • 若是逼近值是5,tickInterval = 1000 * 5 = 5000, 將min,和max取tickInterval的倍數,最終計算出來的ticks : [0, 5000, 10000]
    • 若是逼近值是2,tickInterval = 1000 * 2 = 2000, 將min,和max取tickInterval的倍數,最終計算出來的ticks :[0, 2000, 4000, 6000, 8000, 1000]

僞代碼以下:

var snapArray = [0, 2, 5,10]; var min = 0; var max = 9003; var tickCount = 4; var tickInterval = (max - min) / (tickCount - 1); // 3001; var factor = getFactor(tickInterval)// 1000,若是value > 10 則不斷除以10 直到除數 1<value<10,若是value < 1,則不斷乘以10, 直到 1< value < 10 var snapValue = snap(snapArray, tickInterval / factor, 'ceil'); // 向上逼近,逼近值5 var tickInterval = snapValue * factor; var min = snapMultiple(tickInterval, min, 'floor')// 向下取tickInterval的整數倍,0 var max = snapMultiple(tickInterval,max, 'ceil') //向上取tickInterval的整數倍,15000 var ticks = []; for(var i = min; i <= max; i+= tickInterval){ ticks.push(i); } return ticks;

注意事項 
* snapArray 能夠進行調整,數組內部值越多,間距越小,計算出來的tickCount跟預期的差距越小 
* min,必須向下取tickInterval的倍數,max ,必須向上取tickInterval的倍數

時間類型的度量計算座標點

時間類型的數據是連續數據,可是不適合連續數據度量的計算方式緣由在於:

  • 時間戳的數值比較大,包含毫秒信息,取對人友好的數值格式化出來的時間不必定對人友好,如 1466677570000,是 ’2016 18:26:10‘
  • 對於日期的間隔大於月份,大於年的數據集,無法取得固定的tickInterval,由於月份和年的時間間隔並不相等

因此時間類型的度量須要本身的算法,算法以下:

  • 根據min,max 和 tickCount計算tickInterval;
  • 計算tickInterval 佔一年的比例,yfactor = interval / yms(一年的毫秒數) 
    • 若是yfactor > 0.51,也就是時間間隔大於半年,取min和max的年份,按照年計算ticks 
      例如: min: 2001-05-02, max: 2015-10-12, tickCount = 6,此時ticks = [2001-01-01,2004-01-01 2007-01-01,2010-01-01, 2013-01-01, 2016-01-01]
    • 若是0.0834 < yfactor < 0.51,時間間隔大於一個月,那麼就按月的倍數來計算ticks 
      例如: min: 2001-05-02,max: 2002-04-03, tickCount = 5, 此時ticks = [2001-05-01, 2001-07-01, 2001-09-01, 2001-11-01, 2002-02-01, 2002-04-01, 2001-06-01]
    • 若是時間間隔大於1天,按照天的倍數計算;若是時間間隔大於一個小時,按照小時的倍數計算。。。。而後按照分、秒、毫秒計算ticks

注意事項:

  • tickCount的值也沒法肯定最終生成的ticks的個數
  • 必須保證計算出來的ticks的第一個值小於min,最後一個值大於max

更多

本章講解了數據分類和G2如何設計數據分類,而且提供了計算座標點(ticks)的方法,圖例和座標軸顯示的文本所有由本章講解的度量所決定,下一章節講解視覺通道,並講解視覺通道跟數據分類的關係。

G2網站:https://g2.alipay.com/

相關文章
相關標籤/搜索