如何用d3.js 画多项目柱状图画一张地图

17:59 提问
D3js在画出地图上,根据城市的坐标,在每个坐标的地方画一个光标,像在发光的那种动画效果.
这个网站上的光标点一样,刚开始学D3感觉一直都画不出来
画了好长时间,求助啊,大神们!
按赞数排序
我就是照着这个画出的地图,然后我有一个记录城市坐标的csv文件,csv对每个城市都有坐标显示
//显示地区名字
function chinaText(circles,texts){
d3.csv('json/china-cities.csv',function(c){
//坐标点实现圆点
circles.selectAll("circle")
.enter().append("svg:circle")
.attr("cx", function(d,i){return projection([d.lon,d.lat])[0];})
.attr("cy",function(d,i){return projection([d.lon,d.lat])[1];})
.attr("r",3)
.attr('fill','red');
//坐标点显示城市名字
texts.selectAll("text")
.append("svg:text")
.text(function(d){
.attr("x", function(d){
var local=projection([d.lon,d.lat]);
if(d.lon=='113.5575191')
return (local[0]-30);
else return local[0];})
.attr("y",function(d){
var local=projection([d.lon,d.lat]);
if(d.lat=='39.1439299') return (local[1]+10);
else return local[1];
.attr('fill','white')
.attr('font-size','14px');
--------------这是部分csv文件的数据---
117..1439299
显示地图和每个城市的原点,原点旁边的城市名字都可以正常显示--
然后我想像显示原点一样,把显示原点的代码换成显示成光点,发光的点,刚学d3js 对html5也不是很熟,知道思路,奈何语法不熟悉啊!大牛帮帮忙呗!
其他相关推荐如何使用 D3 在地图上实现实时画圈的效果 - Doggy的博客 - CSDN博客
如何使用 D3 在地图上实现实时画圈的效果
如何使用 D3 在地图上实现实时画圈的效果
标签: D3,map, particle
使用 D3 绘制地图后,空白着的地图没什么吸引力,假设我们绘制了张中国地图,我们将销售中心标示在地图上,然后销售中心每卖出一件商品,就在该销售中心所对应的地图绘制弹出一个圆圈,该圆圈缓慢放大,然后在2秒内淡出。代码应该如何实现呢?
首先,当卖出一件商品时,获取该销售中心的经纬度,然后调用以下函数:
particle([lat, lng]);
该函数的具体定义如下:
var chinaMap = svg.append('g')
.attr("id","chinaMap");
function particle(point) {
var m = projection(point);
if(m[0] && m[1]) {
chinaMap.insert("circle")
.attr("cx", m[0])
.attr("cy", m[1])
.attr("r", 1e-6)
.style("stroke-width", '0.04em')
.style("stroke", '#31a354')
.style("stroke-opacity", 1)
.transition()
.duration(2000)
.ease(Math.sqrt)
.attr("r", 50)
.style("fill","none")
.style("stroke-width", '0.1em')
.style("stroke-opacity", 1e-6)
.remove();
projection 函数的定义:
var width = $("#main").width(),
height = $("#main").height();
var projection = d3.geo.mercator()
.center([105,33.5])
.scale(width*0.6)
.translate([width/2,height/2]);
我的热门文章d3.js实现立体柱图的方法详解
作者:勿忘初心梦于歌
字体:[ ] 类型:转载 时间:
这篇文章主要给大家介绍了利用d3.js实现立体柱图的方法,文中给出了详细的介绍和示例代码供大家参考学习,需要的朋友们下面来一起看看吧。
众所周知随着大数据时代的来临,数据可视化的重要性也越来越凸显,那么今天就基于d3.js今天给大家带来可视化基础图表柱图进阶:立体柱图,之前介绍过了的文章,感兴趣的朋友们可以看一看。
d3.js是一个操作svg的图表库,d3封装了图表的各种算法.对d3不熟悉的朋友可以到d3.js官网学习d3.js.
另外感谢司机大傻(声音像张学友一样性感的一流装逼手)和司机呆(呆萌女神)等人对d3.js进行翻译!
&!DOCTYPE html&
&html lang="en"&
&meta charset="UTF-8"&
&title&Title&/title&
margin: 0;
padding: 0;
div.tip-hill-div {
background: rgba(0, 0, 0, 0.7);
padding: 10
border-radius: 5
font-family: Microsoft Y
div.tip-hill-div & h1 {
font-size: 14
div.tip-hill-div & h2 {
font-size: 12
&div id="chart"&&/div&
当前使用d3.v4+版本
&script src="d3-4.js"&&/script&
图表所需数据
var data = [{
"letter": "白皮鸡蛋",
"child": {
"category": "0",
"value": "459.00"
"letter": "红皮鸡蛋",
"child": {
"category": "0",
"value": "389.00"
"letter": "鸡蛋",
"child": {
"category": "0",
"value": "336.00"
"letter": "牛肉",
"child": {
"category": "0",
"value": "282.00"
"letter": "羊肉",
"child": {
"category": "0",
"value": "249.00"
"letter": "鸭蛋",
"child": {
"category": "0",
"value": "242.00"
"letter": "红薯",
"child": {
"category": "0",
"value": "222.00"
"letter": "白菜",
"child": {
"category": "0",
"value": "182.00"
"letter": "鸡肉",
"child": {
"category": "0",
"value": "102.00"
图表的一些基础配置数据
var margin = {
right: 50,
bottom: 50,
var svgWidth = 1000;
var svgHeight = 500;
//创建各个面的颜色数组
var mainColorList = ['#f6e242', '#ebec5b', '#d2ef5f', '#b1d894','#97d5ad', '#82d1c0', '#70cfd2', '#63c8ce', '#50bab8', '#38a99d'];
var topColorList = ['#e9d748', '#d1d252', '#c0d75f', '#a2d37d','#83d09e', '#68ccb6', '#5bc8cb', '#59c0c6', '#3aadab', '#2da094'];
var rightColorList = ['#dfce51', '#d9db59', '#b9d54a', '#9ece7c','#8ac69f', '#70c3b1', '#65c5c8', '#57bac0', '#42aba9', '#2c9b8f'];
var svg = d3.select('#chart')
.append('svg')
.attr('width', svgWidth)
.attr('height', svgHeight)
.attr('id', 'svg-column');
创建X轴序数比例尺
function addXAxis() {
var transform = d3.geoTransform({
point: function (x, y) {
this.stream.point(x, y)
//定义几何路径
var path = d3.geoPath()
.projection(transform);
xLinearScale = d3.scaleBand()
.domain(data.map(function (d) {
.range([0, svgWidth - margin.right - margin.left], 0.1);
var xAxis = d3.axisBottom(xLinearScale)
.ticks(data.length);
var xAxisG = svg.append("g")
.call(xAxis)
.attr("transform", "translate(" + (margin.left) + "," + (svgHeight - margin.bottom) + ")");
//删除原X轴
xAxisG.select("path").remove();
xAxisG.selectAll('line').remove();
//绘制新的立体X轴
xAxisG.append("path")
type: "Polygon",
coordinates: [
[svgWidth - margin.right - margin.left, 15],
[svgWidth + 20 - margin.right - margin.left, 0],
.attr("d", path)
.attr('fill', 'rgb(187,187,187)');
xAxisG.selectAll('text')
.attr('font-size', '18px')
.attr('fill', '#646464')
.attr('transform', 'translate(0,20)');
dataProcessing(xLinearScale)//核心算法
你可能注意到了,上面代码中不仅使用了序数比例尺,还有地理路径生成器,因为需要生成立体的柱图,所以需要讲原本的X轴删除,自己重新进行绘制.下图是自己重新绘制出来的path路径:
创建Y轴线性比例尺
var yLinearS
//创建y轴的比例尺渲染y轴
function addYScale() {
yLinearScale = d3.scaleLinear()
.domain([0, d3.max(data, function (d, i) {
return d.child.value * 1;
}) * 1.2])
.range([svgHeight - margin.top - margin.bottom, 0]);
//定义Y轴比例尺以及刻度
var yAxis = d3.axisLeft(yLinearScale)
.ticks(6);
var yAxisG = svg.append("g")
.call(yAxis)
.attr('transform', 'translate(' + (margin.left + 10) + "," + margin.top + ")");
yAxisG.selectAll('text')
.attr('font-size', '18px')
.attr('fill', '#636363');
//删除原Y轴路径和tick
yAxisG.select("path").remove();
yAxisG.selectAll('line').remove();
创建Y轴时同样需要把原来的路径和tick删除,下图是效果:
到这,我们的基础搭建完毕,下面就是核心算法
为了实现最终效果,我希望大家在理解的时候能把整个立体柱图分解一下.
我实现立体柱图的思路是通过2个path路径和一个rect进行拼凑.
正面是一个rect,上面和右面利用path路径生成.
利用三角函数,通过给定的angle角度计算上面的一个点就可以知道其他所有点的位置进而进行绘制.
通过上图可以看到,一个立体柱图我们只需要知道7个点的位置就能够绘制出来.
并且已知正面rect4个红色点的位置.已知柱子的宽度和高度,那么只要求出Top面左上角点的位置,就可以知道余下绿色点的位置.具体算法如下:
//核心算法思路是Big boss教的,我借花献佛
function dataProcessing(xLinearScale) {
var angle = Math.PI / 2.3;
for (var i = 0; i & data. i++) {
var d = data[i];
var depth = 10;
d.ow = xLinearScale.bandwidth() * 0.7;
d.ox = xLinearScale(d.letter);
x: Math.cos(angle) * d.ow,
y: -Math.sin(angle) - depth
x: d.p1.x + d.ow,
x: d.p2.x,
y: d.p2.y + d.oh
最终我们还要鼠标进行交互,所以先添加tip生成函数
//tip的创建方法(方法来自敬爱的鸣哥)
var tipTimerConfig = {
longer: 0,
target: null,
exist: false,
winEvent: window.event,
boxHeight: 398,
boxWidth: 376,
maxWidth: 376,
maxHeight: 398,
tooltip: null,
showTime: 3500,
hoverTime: 300,
displayText: "",
show: function (val, e) {
"use strict";
if (e != null) {
me.winEvent =
me.displayText =
me.calculateBoxAndShow();
me.createTimer();
calculateBoxAndShow: function () {
"use strict";
var _x = 0;
var _y = 0;
var _w = document.documentElement.scrollW
var _h = document.documentElement.scrollH
var wScrollX = window.scrollX || document.body.scrollL
var wScrollY = window.scrollY || document.body.scrollT
var xMouse = me.winEvent.x + wScrollX;
if (_w - xMouse & me.boxWidth) {
_x = xMouse - me.boxWidth - 10;
var _yMouse = me.winEvent.y + wScrollY;
if (_h - _yMouse & me.boxHeight + 18) {
_y = _yMouse - me.boxHeight - 25;
_y = _yMouse + 18;
me.addTooltip(_x, _y);
addTooltip: function (page_x, page_y) {
"use strict";
me.tooltip = document.createElement("div");
me.tooltip.style.left = page_x + "px";
me.tooltip.style.top = page_y + "px";
me.tooltip.style.position = "absolute";
me.tooltip.style.width = me.boxWidth + "px";
me.tooltip.style.height = me.boxHeight + "px";
me.tooltip.className = "three-tooltip";
var divInnerHeader = me.createInner();
divInnerHeader.innerHTML = me.displayT
me.tooltip.appendChild(divInnerHeader);
document.body.appendChild(me.tooltip);
createInner: function () {
"use strict";
var divInnerHeader = document.createElement('div');
divInnerHeader.style.width = me.boxWidth + "px";
divInnerHeader.style.height = me.boxHeight + "px";
return divInnerH
ClearDiv: function () {
"use strict";
var delDiv = document.body.getElementsByClassName("three-tooltip");
for (var i = delDiv.length - 1; i &= 0; i--) {
document.body.removeChild(delDiv[i]);
createTimer: function (delTarget) {
"use strict";
var delTip = me.
var delTarget = tipTimerConfig.
var removeTimer = window.setTimeout(function () {
if (delTip != null) {
document.body.removeChild(delTip);
if (tipTimerConfig.target == delTarget) {
me.exist =
clearTimeout(removeTimer);
} catch (e) {
clearTimeout(removeTimer);
}, me.showTime);
hoverTimerFn: function (showTip, showTarget) {
"use strict";
var showTarget = tipTimerConfig.
var hoverTimer = window.setInterval(function () {
if (tipTimerConfig.target != showTarget) {
clearInterval(hoverTimer);
} else if (!tipTimerConfig.exist && (new Date()).getTime() - me.longer & me.hoverTime) {
tipTimerConfig.show(showTip);
tipTimerConfig.exist =
clearInterval(hoverTimer);
} catch (e) {
clearInterval(hoverTimer);
}, tipTimerConfig.hoverTime);
var createTooltipTableData = function (info) {
var ary = [];
ary.push("&div class='tip-hill-div'&");
ary.push("&h1&品种信息:" + info.letter + "&/h1&");
ary.push("&h2&成交量: " + info.child.value);
ary.push("&/div&");
return ary.join("");
核心算法写完,就到了最终的渲染了
function addColumn() {
function clumnMouseover(d) {
d3.select(this).selectAll(".transparentPath").attr("opacity", 0.8);
// 添加 div
tipTimerConfig.target =
tipTimerConfig.longer = new Date().getTime();
tipTimerConfig.exist =
//获取坐标
tipTimerConfig.winEvent = {
x: event.clientX - 100,
y: event.clientY
tipTimerConfig.boxHeight = 50;
tipTimerConfig.boxWidth = 140;
tipTimerConfig.ClearDiv();
tipTimerConfig.hoverTimerFn(createTooltipTableData(d));
function clumnMouseout(d) {
d3.select(this).selectAll(".transparentPath").attr("opacity", 1);
tipTimerConfig.target =
tipTimerConfig.ClearDiv();
var g = svg.selectAll('.g')
.data(data)
.append('g')
.on("mouseover", clumnMouseover)
.on("mouseout", clumnMouseout)
.attr('transform', function (d) {
return "translate(" + (d.ox + margin.left + 20) + "," + (svgHeight - margin.bottom + 15) + ")"
g.transition()
.duration(2500)
.attr("transform", function (d) {
return "translate(" + (d.ox + margin.left + 20) + ", " + (yLinearScale(d.child.value) + margin.bottom - 15) + ")"
g.append('rect')
.attr('x', 0)
.attr('y', 0)
.attr("class", "transparentPath")
.attr('width', function (d, i) {
.attr('height', function (d) {
.style('fill', function (d, i) {
return mainColorList[i]
.transition()
.duration(2500)
.attr("height", function (d, i) {
return svgHeight - margin.bottom - margin.top - yLinearScale(d.child.value);
g.append('path')
.attr("class", "transparentPath")
.attr('d', function (d) {
return "M0,0 L" + d.p1.x + "," + d.p1.y + " L" + d.p2.x + "," + d.p2.y + " L" + d.ow + ",0 L0,0";
.style('fill', function (d, i) {
return topColorList[i]
g.append('path')
.attr("class", "transparentPath")
.attr('d', function (d) {
return "M" + d.ow + ",0 L" + d.p2.x + "," + d.p2.y + " L" + d.p3.x + "," + d.p3.y + " L" + d.ow + "," + d.oh + " L" + d.ow + ",0"
.style('fill', function (d, i) {
return rightColorList[i]
.transition()
.duration(2500)
.attr("d", function (d, i) {
return "M" + d.ow + ",0 L" + d.p2.x + "," + d.p2.y + " L" + d.p3.x + "," + (d.p3.y + svgHeight - margin.top - margin.bottom - yLinearScale(d.child.value)) + " L" + d.ow + "," + (svgHeight - margin.top - margin.bottom - yLinearScale(d.child.value)) + " L" + d.ow + ",0"
由于需要考虑动画,所以对渲染时的柱子位置进行了处理.对这方面不理解的话可以留言讨论.
以上就是这篇文章的全部内容了,希望本文的内容对大家学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具}

我要回帖

更多关于 d3.js 画圆 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信