d3.js 教程 模仿echarts柱狀圖

由于最近工作不是很忙,隧由把之前的charts項目用d3.js重寫的一下,其實d3.js文檔很多,但是入門不是很難,可是想真的能做一個完成的,交互良好的圖還是要下一番功夫的。今天在echarts找到了一個柱狀圖,如圖。

模仿了一番,廢話不多說。下面就開始我們的代碼(注意是D3.v4版本)。

1. js 類

class Bar {constructor() {this._width = 1000;this._height = 700;this._padding = 10;this._offset = 35;this._margins = {right: 40,bottom: 40,left: 40,top: 40};this._scaleX = d3.scaleBand().rangeRound([0, this._width - this._margins.left - this._margins.right]);this._scaleY = d3.scaleLinear().range([this._height - this._margins.top - this._margins.bottom, 0]);this._color = '#3398DB';this._data = [];this._svg = null;this._body = null;this._tooltip = null;this._shadow = null;this._ticks = 5;this._key = 'key';this._value = 'value';}render() {if(!this._tooltip) {this._tooltip = d3.select('body').append('div').style('left', '40px').style('top', '30px').attr('class', 'tooltip').html('');}if(!this._svg) {this._svg = d3.select('body').append('svg').attr('width', this._width).attr('height', this._height)this.renderAxes();this.renderClipPath();}this.renderBody();}renderAxes() {let axes = this._svg.append('g').attr('class', 'axes');this.renderXAxis(axes);this.renderYAxis(axes);}renderXAxis(axes) {let xAxis = d3.axisBottom().scale(this._scaleX)axes.append('g').attr('class', 'x axis').attr('transform', `translate(${this.xStart()}, ${this.yStart()})`).call(xAxis)}renderYAxis(axes) {let yAxis = d3.axisLeft().scale(this._scaleY).ticks(this._ticks);axes.append('g').attr('class', 'y axis').attr('transform', `translate(${this.xStart()}, ${this.yEnd()})`).call(yAxis)d3.selectAll('.y .tick').append('line').attr('class', 'grid-line').attr('x1', 0).attr('y1', 0).attr('x2', this.quadrantWidth()).attr('y2', 0)}renderClipPath() {this._svg.append('defs').append('clip-path').attr('id', 'body-clip').append('rect').attr('x', 0).attr('y', 0).attr('width', this.quadrantWidth()).attr('height', this.quadrantHeight())}renderBody() {if(!this._body) {this._body = this._svg.append('g').attr('class', 'body').attr('transform', `translate(${this._margins.left},${this._margins.top})`).attr('clip-path', 'url(#clipPath)')this.renderShadow()}this.renderBar();this.listenMousemove();}renderShadow() {this._shadow = this._body.append('rect').attr('x', 0).attr('y', 0).attr('width', this.everyWidth()).attr('height', this._scaleY(0)).attr('fill', '#000').attr('fill-opacity', 0)}renderBar() {let barElements = this._body.selectAll('rect.bar').data(this._data);let barEnter =  barElements.enter().append('rect').attr('class', 'bar').attr('x', d => this._scaleX(d[this._key]) + this.everyWidth() * 0.18).attr('y', () => this._scaleY(0)).attr('width', this.everyWidth() * 0.64).attr('height', () => this.quadrantHeight() - this._scaleY(0))let barUpdate = barEnter.merge(barElements).transition().duration(800).ease(d3.easeCubicOut).attr('y', d => this._scaleY(d[this._value])).attr('height', d => {console.log(this.quadrantHeight() - this._scaleY(d[this._value]))return this.quadrantHeight() - this._scaleY(d[this._value])});let barExit = barElements.exit().transition().attr('y', () => this._scaleY(0)).attr('height', () => this.quadrantHeight() - this._scaleY(0)).remove();}listenMousemove() {this._svg.on('mousemove', () => {let px = d3.event.offsetX;let py = d3.event.offsetY;if(px < this.xEnd() && px > this.xStart() && py < this.yStart() && py > this.yEnd()) {this.renderShadowAndTooltip(px, py, px - this.xStart());} else {this.hideShadowAndTooltip();}})}renderShadowAndTooltip(x, y, bodyX) {let cutIndex = Math.floor(bodyX / this.everyWidth());this._shadow.transition().duration(50).ease(d3.easeLinear).attr('fill-opacity', .12).attr('x', cutIndex * this.everyWidth());if(x > this.quadrantWidth() - this._tooltip.style('width').slice(0,-2) - this._padding * 2) {x = x - this._tooltip.style('width').slice(0,-2) - this._padding * 2 - this._offset * 2;}if(y > this.quadrantHeight() - this._tooltip.style('height').slice(0,-2) - this._padding * 2) {y = y - this._tooltip.style('height').slice(0,-2) - this._padding * 2 - this._offset * 2;}this._tooltip.html(`${this._data[cutIndex][this._key]}<br/>數量統計: ${this._data[cutIndex][this._value]}`).transition().duration(100).ease(d3.easeLinear).style('display', 'inline-block').style('opacity', .6).style('left', `${x + this._offset + this._padding}px`).style('top', `${y + this._offset + this._padding}px`);
    }hideShadowAndTooltip() {
    this._shadow.transition().duration(10).attr('fill-opacity', 0);
    this._tooltip.transition().duration(50).style('opacity', 0).on('end', function() {d3.select(this).style('display', 'none')})
  }everyWidth() {
return this.quadrantWidth() / this._data.length;}quadrantWidth() {return this._width - this._margins.left - this._margins.right;}quadrantHeight() {return this._height - this._margins.top - this._margins.bottom;}xStart() {return this._margins.left;}xEnd() {return this._width - this._margins.right;}yStart() {return this._height - this._margins.bottom;}yEnd() {return this._margins.top;}scaleX(a) {this._scaleX = this._scaleX.domain(a);}scaleY(a) {this._scaleY = this._scaleY.domain(a)}key(k) {if(!arguments.length) return this._key;this._key = k;this.scaleX(this._data.map(d => d[this._key]))return this;}value(v) {if(!arguments.length) return this._value;this._value = v;let arr = this._data.map(d => d[this._value]);let ele = Math.pow(10, d3.max(arr).toString().length - 1);let max = Math.ceil(d3.max(arr) / ele) * ele;this.scaleY([0, max]);return this;}data(data) {if(!arguments.length) return this._data;this._data = data;return this;} }

2 CSS 文件很簡單

.domain {stroke-width: 2;fill: none;stroke: #888;shape-rendering: crispEdges;
}
.x .tick line {opacity: 0  ;
}
.tick text {font-size: 14px;
}
.grid-line {fill: none;stroke: #888;opacity: .4;shape-rendering: crispEdges;
}
.bar {fill: #3398DB;
}
.tooltip{font-size: 15px;width: auto;padding: 10px;height: auto;position: absolute;text-align: center;background-color: #000000;opacity: .6;border-radius:5px;color: #ffffff;display: none;
}

3 加下來就是html文件

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>$Title$</title><link rel="stylesheet" type="text/css" href="css/base.css"/><script type="text/javascript" src="js/d3.v4.js"></script><script type="text/javascript" src="js/bar.js"></script>
</head>
<body>
<script>var dataset = [{date: 'Mon', label: 15},{date: 'Tue', label: 52},{date: 'Wed', label: 200},{date: 'Thu', label: 235},{date: 'Fri', label: 390},{date: 'Sat', label: 330},{date: 'Sun', label: 221}];var bar = new Bar();bar.data(dataset).key('date').value('label').render();
</script>
</body>
</html>

4 接著是效果圖

新上手的朋友們可以先學習一下ES6,然后在學習類的思想,d3.v3和v4 v5的版本差異比較大,直接學習d3.v4就可以了,最最后推薦一本書。D3 4.x數據可視化實戰手冊。這本書比較基礎但是能夠通過它養成良好的d3編程習慣。祝大家d3學習順利。

如果想下載代碼或者預覽這個DEMO請移步到原文!!!

原文鏈接:http://www.bettersmile.cn

轉載于:https://www.cnblogs.com/vadim-web/p/11456188.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/248174.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/248174.shtml
英文地址,請注明出處:http://en.pswp.cn/news/248174.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

簡單的動畫函數封裝(2)

<div></div><!-- <span></span> --><button class"btn1">點擊500</button><button class"btn2">點擊800</button>div{width: 100px;height: 100px;background-color: red;position: absolute;top: …

【蔡勒公式 】根據給定的年月日求出對應星期幾

蔡勒公式 蔡勒&#xff08;Zeller&#xff09;公式&#xff0c;是一個計算星期的公式&#xff0c;隨便給一個日期&#xff0c;就能用這個公式推算出是星期幾。時間復雜度&#xff1a;O(1)。具體的在紅書P229有。 若要計算的日期是在1582年10月4日或之前&#xff0c;公式則為&am…

MFC的程序,不想顯示窗口,任務欄里也不顯示

在dialog的oninitdialog里設置如下屬性&#xff0c;很簡單&#xff0c;網上一些亂七八糟的做法&#xff0c;一行代碼就能搞定啊 SetWindowPos(&CWnd::wndNoTopMost,0,0,0,0,SWP_HIDEWINDOW); ModifyStyleEx(WS_EX_APPWINDOW, WS_EX_TOOLWINDOW); 轉載于:https://www.cnblog…

放大鏡制作(2)—此方法比較容易理解

<div class"box" id"box"><!--左側的盒子--><div class"left_img"><!--圖片--><img src"images/small.jpg" class"aaa" alt"小圖片"/><!--黃色小盒子--><div class"…

call / apply / bind

對于 call / apply / bind 來說&#xff0c;他們的首要目的是用于改變執行上下文的 this 指針。 call / apply 對 call / apply 的使用&#xff0c;一般都如下&#xff0c;用于改變執行環境的上下文。只是 call 接受的是一個一個的參數&#xff0c;而 apply 則是接受的是一個參…

js(Dom+Bom)第八天—Swiper(插件)

Swiper插件(庫) 01-基本介紹 Swiper 是一款免費以及輕量級的移動設備觸控滑塊的js框架&#xff0c;使用硬件加速過渡&#xff08;如果該設備支持的話&#xff09;。主要使用于移動端的網站、移動web apps&#xff0c;native apps和hybrid apps。主要是為IOS而設計的&#xff…

第七節:EF Core調用SQL語句和存儲過程

一. 查詢類(FromSql) 1.說明 A. SQL查詢必須返回實體的所有屬性字段。 B. 結果集中的列名必須與屬性映射到的列名相匹配。 C. SQL查詢不能包含關聯數據 D. 除Select以為的其它SQL語句無法運行。 2.調用SQL語句的幾種情況 A. 基本的原生SQL查詢 B. 利用$內插語法進行傳遞 C. 原生…

沒用的一些水貨

1. 不遞歸的子函數加上inline會跑的很快。 2. 在稠密圖中用dijkstra堆優化會導致跑的很慢。 3. 連著開幾個數組的話&#xff0c;有可能越界了評測機卻返回WA。 4. 如果你用的Dev-C&#xff0c;那么有的時候會出現一些莫名其妙的編譯錯誤。請檢查是否存在未關閉的代碼生成的.exe…

js(Dom+Bom)第八天

JavaScript 移動端事件介紹 touch事件類型 移動設備上無法使用鼠標&#xff0c;當手指按下屏幕的時候會觸發 click,mousedown,mouseup事件&#xff0c;但是在移動設備上有專門的事件&#xff1a; touch 備注&#xff1a; 在移動端touch事件需要通過事件監聽的方式添加touchsta…

程序員計算器HEX、EDC、OCT等等的意思

binary 二進制 對應的是 BINoctal 八進制的 ---- OCThexadecimal 十六進制的 --- HEXdecimal 十進制的 -- DEC 轉載于:https://www.cnblogs.com/132818Creator/p/11459984.html

為什么mysql 5.7.24啟停不顯示錯誤信息?log-error_verbosity參數

關鍵詞&#xff1a;log-error_verbosity &#xff0c;mysql啟停沒有信息&#xff0c;mysql啟停不顯示錯誤信息&#xff0c;mysql不顯示啟停信息 原因就是因為 log-error_verbosity 2 被設置成了1/2&#xff0c;需要設置成3才行。 轉載自&#xff1a;https://www.cnblogs.com/k…

ASP.NET Core 3.0中使用動態控制器路由

原文&#xff1a;Dynamic controller routing in ASP.NET Core 3.0 作者&#xff1a;Filip W 譯文&#xff1a;https://www.cnblogs.com/lwqlun/p/11461657.html 譯者&#xff1a;Lamond Lu 譯者注 今天在網上看到了這篇關于ASP.NET Core動態路由的文章&#xff0c;感覺蠻有意思…

Petrozavodsk Winter Camp, Warsaw U, 2014, A The Carpet

一個地圖上有若干障礙&#xff0c;問允許出現一個障礙的最大子矩形為多大&#xff1f; 最大子矩形改編 #include<bits/stdc.h> using namespace std; #define rep(i, j, k) for (int i int(j); i < int(k); i) #define dwn(i, j, k) for (int i int(j); i > int…

d3.js 教程 模仿echarts折線圖

今天我們來仿echarts折線圖,這個圖在echarts是折線圖堆疊&#xff0c;但是我用d3改造成了普通的折線圖&#xff0c;只為了大家學習&#xff08;其實在簡單的寫一個布局就可以&#xff09;。廢話不多說商行代碼。 1 制作 Line 類 class Line {constructor() {this._width 1100;…

vue中v-for的使用

本人正在開始學習Vue,每天寫寫基礎的記錄,希望對大家有幫助,如有錯誤還望指出,我也是一個小白,也希望大家能一起進步 v-for指令的使用: 1.循環普通數組 item in list 中的item是自己個想寫什么名寫什么名 另一種寫法 i 表示索引值 2.循環對象數組 3.循環普通對象 4.迭代數字 注…

js高級第一天

JavaScript面向對象 1.1兩大編程思想&#xff1a; 1、面向過程 ? 面向過程&#xff1a;POP(Process-oriented programming) 面向過程就是分析出解決問題所需要的步驟&#xff0c;然后用函數把這些步驟一步一步實現&#xff0c;使用的時候再一個一個的依次調用就可以了。 ?…

d3.js 教程 模仿echarts legend功能

上一節記錄沒有加上echarts的legend功能&#xff0c;這一小節補一下。 1. 數據 我們可以從echarts中看出&#xff0c;折線數據并不是我們傳進入的原始數據&#xff08;多數情況下我們也不會修改原始數據&#xff09;&#xff0c;而是原始數組的一個備份而已。備份數組的方法有很…

小程序2-基本架構講解(一)WXSS樣式

項目里邊生成了不同類型的文件: .json 后綴的 JSON 配置文件.wxml 后綴的 WXML 模板文件.wxss 后綴的 WXSS 樣式文件.js 后綴的 JS 腳本邏輯文件WXSS 樣式 WXSS (WeiXin Style Sheets)是一套樣式語言&#xff0c;用于描述 WXML 的組件樣式。WXSS 具有 CSS 大部分的特性 新增了尺…

js高級—tab欄切換(面向對象做法)

<main><h4>Js 面向對象 動態添加標簽頁</h4><div class"tabsbox" id"tab"><!-- tab 標簽 --><nav class"fisrstnav"><ul><li class"liactive"><span>測試1</span><sp…