欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Highcharts?圖表中圖例顯示狀態(tài)存儲的功能設(shè)計詳解

 更新時間:2023年03月14日 09:56:28   作者:麥索  
這篇文章主要介紹了Highcharts?圖表中圖例顯示狀態(tài)存儲的功能設(shè)計詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

需求背景

公司前端使用 Highcharts 構(gòu)建圖表,圖表的圖例支持點擊顯示或隱藏相應(yīng)的指標(biāo)?,F(xiàn)在有需求后端需要存儲用戶在前端點擊后顯示圖表的狀態(tài),對于已經(jīng)隱藏的圖例相應(yīng)的指標(biāo)線下次進入頁面后依然隱藏。

這樣做的目的是簡化圖表信息和去除噪音,有些信息對于某些用戶來說是不太關(guān)心的,用戶取消顯示它們是合理的。

需求方案

方案一

使用數(shù)據(jù)庫枚舉值,將圖表的存儲狀態(tài)枚舉。這是一種實現(xiàn)上比較簡單的方案,但是其組合較多,圖例越多所需要添加的枚舉值就越多,原本的圖表狀態(tài)中有兩個圖例可以進行此操作,因此使用了這種方案。

現(xiàn)在需要將這個功能擴展到 4 個圖表,未來又可能擴展到更多圖表,所以這種簡單的方案已經(jīng)不適用了。

方案二

使用一個數(shù)據(jù)庫 JSON 類型字段存儲圖例的是否顯示的狀態(tài),其結(jié)構(gòu)類似下面這樣:

{
"chart_1":{
"legend_1":true,
"legend_2":true,
"legend_3":true,
"legend_4":true,
"legend_5":true,
"legend_6":true,
"legend_7":false,
"legend_8":false
},
"chart_2":{
"legend_1":true,
"legend_2":true,
"legend_3":true,
"legend_4":true,
"legend_5":true
},
"chart_3":{
"legend_1":true,
"legend_2":true,
"legend_3":true,
"legend_4":true
},
"chart_3":{
"legend_1":true,
"legend_2":true,
"legend_3":true,
"legend_4":true,
"legend_5":true,
"legend_6":true,
"legend_7":true
}
}

這樣使用一個字段將所有圖表的圖例狀態(tài)都在一個地方維護,而且避免了過多枚舉值的問題。但在實際項目中因為每個用戶都有這樣一個值需要在數(shù)據(jù)庫中維護,所以它會占用大量的數(shù)據(jù)庫存儲空間,在工程質(zhì)量和未來成本控制上與工程目標(biāo)不符。

方案三

對方案二進行改進,存儲給每個圖表存儲一個 int 值,實際這個 int 值可以在代碼中轉(zhuǎn)換成二進制,用每個二進制值位的 0 和 1 來標(biāo)示圖例是否該顯示。其存儲結(jié)構(gòu)如下:

{
"chart_1": 15,
"chart_2": 31,
"chart_3": 127,
"chart_3": 252
}

同時對于大部分用戶而言很可能是不會對默認圖表做出更改,那么我們可以在代碼中維護一個默認值,當(dāng)數(shù)據(jù)庫中相應(yīng)值與默認值一致時,無需實際存儲到數(shù)據(jù)庫中,在用戶獲取信息時直接返回默認值即可。

代碼實現(xiàn)

后端使用的是 PHP 的 Laravel 框架,首先在相應(yīng)的 Model 里我新增了一些類似下面的常量:

public const BITMAP_INDEXES_BY_LEGEND_IDENTIFIER_BY_CHART_NAME = [
'chart_1' => [
'legend_1' => 7,
'legend_2' => 6,
'legend_3' => 5,
'legend_4' => 4,
'legend_5' => 3,
'legend_6' => 2,
'legend_7' => 1,
'legend_8' => 0,
],
'chart_2' => [
'legend_1' => 3,
'legend_2' => 2,
'legend_3' => 1,
'legend_4' => 0,
],
'chart_3' => [
'legend_1' => 6,
'legend_2' => 5,
'legend_3' => 4,
'legend_4' => 3,
'legend_5' => 2,
'legend_6' => 1,
'legend_7' => 0,
],
'chart_4' => [
'legend_1' => 4,
'legend_2' => 3,
'legend_3' => 2,
'legend_4' => 1,
'legend_5' => 0,
],
];
// Each bit of a bitmap is like a bucket, which stores the displayed or hidden state.
public const DEFAULT_CHART_LEGEND_VISIBILITIES = [
'chart_1' => 0b1111,
'chart_2' => 0b11111,
'chart_3' => 0b1111111,
'chart_4' => 0b11111100,
];

BITMAP_INDEXES_BY_LEGEND_IDENTIFIER_BY_CHART_NAME 維護的是每個圖例在 bitmap 中的存儲位置,這樣在圖例增加時只需維護相應(yīng)的 chart 的存儲位置即可,不會影響到其他圖表的圖例存儲。

DEFAULT_CHART_LEGEND_VISIBILITIES 定義了圖例的默認值,當(dāng)用戶未做更改時可以直接返回其值,在存儲時可進行比對,如果值一致就不存儲到數(shù)據(jù)庫里了。

在定義完這兩個常量后,需要做的就是對存儲和獲取的過程給予相應(yīng)的處理,Laravel 的 Model 提供了訪問器和設(shè)置器的功能,我可以利用這個機制對值進行處理,因此我在 model 里新增了以下方法:

/**
* @return array<string,array<string,bool>>
*/
public function getChartLegendVisibilitiesAttribute(?string $value): array
{
$value = $value !== null ? \Safe\json_decode($value, true) : [];
$value += self::DEFAULT_CHART_LEGEND_VISIBILITIES;
$chart_legend_visibilities = [];
/** @var string $chart_name */
foreach ($value as $chart_name => $legend_visibilities_bitmap) {
foreach (self::BITMAP_INDEXES_BY_LEGEND_IDENTIFIER_BY_CHART_NAME[$chart_name] as $legend_identifier => $bitmap_index) {
$chart_legend_visibilities[$chart_name][$legend_identifier] = (bool) (($legend_visibilities_bitmap >> $bitmap_index) & 1);
}
}
ksort($chart_legend_visibilities);
return $chart_legend_visibilities;
}
/**
* @param array<string,array<string,bool>>|null $value
*
* @return void
*/
public function setChartLegendVisibilitiesAttribute(?array $value): void
{
if ($value !== null) {
$chart_legend_visibilities = [];
foreach ($value as $chart_name => $legend_visibilities) {
$legend_visibilities_bitmap = 0;
foreach ($legend_visibilities as $legend_identifier => $legend_visibility) {
$bitmap_index = self::BITMAP_INDEXES_BY_LEGEND_IDENTIFIER_BY_CHART_NAME[$chart_name][$legend_identifier];
$legend_visibilities_bitmap |= ($legend_visibility & true) << $bitmap_index;
}
if ($legend_visibilities_bitmap !== self::DEFAULT_CHART_LEGEND_VISIBILITIES[$chart_name]) {
$chart_legend_visibilities[$chart_name] = $legend_visibilities_bitmap;
}
}
$value = $chart_legend_visibilities === [] ? null : \Safe\json_encode($chart_legend_visibilities);
}
$this->attributes[self::COLUMN_CHART_LEGEND_VISIBILITIES] = $value;
}

這樣我所要實現(xiàn)的功能基本在這里完成了。現(xiàn)在所要做的就是在控制器里對返回的圖表數(shù)據(jù)的狀態(tài)進行綁定:

/**
* @param array<string,array<int|string,mixed>> $chart_data
* @param \App\Models\UserExtra $user_extra
* @param string $chart_name
*
* @return array<string,array<int|string,mixed>>
*/
private static function getChartLegendVisibility(array $chart_data, UserExtra $user_extra, string $chart_name): array
{
$legend_label_id_by_store_index = array_flip(UserExtra::BITMAP_INDEXES_BY_LEGEND_IDENTIFIER_BY_CHART_NAME[$chart_name]);
$legend_visibilities = $user_extra->chart_legend_visibilities[$chart_name];
foreach ($chart_data['series'] as $series_index => $series) {
$key = array_shift($legend_label_id_by_store_index);
$chart_data['series'][$series_index]['id'] = $key;
$chart_data['series'][$series_index]['visible'] = $legend_visibilities[$key];
}
return $chart_data;
}

$chart_data 傳遞的是構(gòu)建好的 Highcharts 需要的數(shù)據(jù),這部分可以參考 Highcharts 的文檔。這個函數(shù)的目的就是將每個圖例的數(shù)據(jù)與我們所維護的圖例是否顯示的數(shù)據(jù)綁定,之后再提供修改圖例顯示狀態(tài)的 API 即可實現(xiàn)這個功能。

以上就是Highcharts 圖表中圖例顯示狀態(tài)存儲的功能設(shè)計詳解的詳細內(nèi)容,更多關(guān)于Highcharts 顯示狀態(tài)存儲的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論