用d3.js对信号处理的结果数据作图,得到可缩放交互的动态SVG图

d3.js 有何用

D3.js is a JavaScript library for manipulating documents based on data. D3 helps you bring data to life using HTML, SVG, and CSS. D3’s emphasis on web standards gives you the full capabilities of modern browsers without tying yourself to a proprietary framework, combining powerful visualization components and a data-driven approach to DOM manipulation.

D3.js 是一个强大的通用数据可视化工具。吕之华著电子工业出版社出版的《精通D3.js交互式数据可视化高级编程》对D3.js 有专门论述。可做参照。

用 D3.js 进行数据曲线的动态作图也很方便。只要在html文件中引入

<script src="https://d3js.org/d3.v5.min.js"></script>

即可。或下载d3.v5.min.js到本地,再行引入。

应用例

html文件:

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>D3.js SVG多折线图表DEMO演示</title>
    <link rel="stylesheet" href="css/style.css" media="screen" type="text/css" />
</head>
<body>
  <script src="js/d3.v3.min.js"></script>
  <script src="js/index.js"></script>
</body>
</html>

其中,核心代码为在body标签内引入的两行:

  <script src="js/d3.v3.min.js"></script>
  <script src="js/index.js"></script>

数据在js/index.js 文件中,数据格式如下:

{'x':1.00E+02,'y':3.50E+02},
{'x':1.04E+02,'y':3.21E+02},
{'x':1.08E+02,'y':2.46E+02},
{'x':1.11E+02,'y':1.54E+02},
{'x':1.15E+02,'y':8.06E+01},
......

js 文件:


//************************************************************
// Data notice the structure
//************************************************************

var data = 	[
  [
{'x':1.00E+02,'y':3.50E+02},
{'x':1.04E+02,'y':3.21E+02},
{'x':1.08E+02,'y':2.46E+02},
{'x':1.11E+02,'y':1.54E+02},
{'x':1.15E+02,'y':8.06E+01},
{'x':1.19E+02,'y':5.38E+01},
{'x':1.23E+02,'y':8.31E+01},
{'x':1.26E+02,'y':1.56E+02},
{'x':1.30E+02,'y':2.43E+02},
{'x':1.34E+02,'y':3.12E+02},
{'x':1.38E+02,'y':3.35E+02},
{'x':1.41E+02,'y':3.07E+02},
{'x':1.45E+02,'y':2.40E+02},
{'x':1.49E+02,'y':1.61E+02},
{'x':1.53E+02,'y':1.01E+02},
{'x':1.56E+02,'y':8.09E+01},
{'x':1.60E+02,'y':1.07E+02},
{'x':1.64E+02,'y':1.65E+02},
{'x':1.68E+02,'y':2.33E+02},
{'x':1.71E+02,'y':2.84E+02},
{'x':1.75E+02,'y':3.00E+02},
{'x':1.79E+02,'y':2.78E+02},
{'x':1.83E+02,'y':2.28E+02},
{'x':1.86E+02,'y':1.73E+02},
{'x':1.90E+02,'y':1.32E+02},
{'x':1.94E+02,'y':1.19E+02},
{'x':1.98E+02,'y':1.37E+02},
{'x':2.01E+02,'y':1.77E+02},
{'x':2.05E+02,'y':2.22E+02},
{'x':2.09E+02,'y':2.55E+02},
{'x':2.13E+02,'y':2.65E+02},
{'x':2.16E+02,'y':2.50E+02},
{'x':2.20E+02,'y':2.18E+02},
{'x':2.24E+02,'y':1.82E+02},
{'x':2.28E+02,'y':1.55E+02},
{'x':2.31E+02,'y':1.46E+02},
{'x':2.35E+02,'y':1.58E+02},
{'x':2.39E+02,'y':1.84E+02},
{'x':2.43E+02,'y':2.16E+02},
{'x':2.46E+02,'y':2.41E+02},
{'x':2.50E+02,'y':2.50E+02},
{'x':2.54E+02,'y':2.41E+02},
{'x':2.58E+02,'y':2.16E+02},
{'x':2.61E+02,'y':1.84E+02},
{'x':2.65E+02,'y':1.58E+02},
{'x':2.69E+02,'y':1.46E+02},
{'x':2.73E+02,'y':1.55E+02},
{'x':2.76E+02,'y':1.82E+02},
{'x':2.80E+02,'y':2.18E+02},
{'x':2.84E+02,'y':2.50E+02},
{'x':2.88E+02,'y':2.65E+02},
{'x':2.91E+02,'y':2.55E+02},
{'x':2.95E+02,'y':2.22E+02},
{'x':2.99E+02,'y':1.77E+02},
{'x':3.03E+02,'y':1.37E+02},
{'x':3.06E+02,'y':1.19E+02},
{'x':3.10E+02,'y':1.32E+02},
{'x':3.14E+02,'y':1.73E+02},
{'x':3.18E+02,'y':2.28E+02},
{'x':3.21E+02,'y':2.78E+02},
{'x':3.25E+02,'y':3.00E+02},
{'x':3.29E+02,'y':2.84E+02},
{'x':3.33E+02,'y':2.33E+02},
{'x':3.36E+02,'y':1.65E+02},
{'x':3.40E+02,'y':1.07E+02},
{'x':3.44E+02,'y':8.09E+01},
{'x':3.48E+02,'y':1.01E+02},
{'x':3.51E+02,'y':1.61E+02},
{'x':3.55E+02,'y':2.40E+02},
{'x':3.59E+02,'y':3.07E+02},
{'x':3.63E+02,'y':3.35E+02},
{'x':3.66E+02,'y':3.12E+02},
{'x':3.70E+02,'y':2.43E+02},
{'x':3.74E+02,'y':1.56E+02},
{'x':3.78E+02,'y':8.31E+01},
{'x':3.81E+02,'y':5.38E+01},
{'x':3.85E+02,'y':8.06E+01},
{'x':3.89E+02,'y':1.54E+02},
{'x':3.93E+02,'y':2.46E+02},
{'x':3.96E+02,'y':3.21E+02},
{'x':4.00E+02,'y':3.50E+02},
{'x':4.04E+02,'y':3.21E+02},
{'x':4.08E+02,'y':2.46E+02},
{'x':4.11E+02,'y':1.54E+02},
{'x':4.15E+02,'y':8.06E+01},
{'x':4.19E+02,'y':5.38E+01},
{'x':4.23E+02,'y':8.31E+01},
{'x':4.26E+02,'y':1.56E+02},
{'x':4.30E+02,'y':2.43E+02},
{'x':4.34E+02,'y':3.12E+02},
{'x':4.38E+02,'y':3.35E+02},
{'x':4.41E+02,'y':3.07E+02},
{'x':4.45E+02,'y':2.40E+02},
{'x':4.49E+02,'y':1.61E+02},
{'x':4.53E+02,'y':1.01E+02},
{'x':4.56E+02,'y':8.09E+01},
{'x':4.60E+02,'y':1.07E+02},
{'x':4.64E+02,'y':1.65E+02},
{'x':4.68E+02,'y':2.33E+02},
{'x':4.71E+02,'y':2.84E+02},
{'x':4.75E+02,'y':3.00E+02},
{'x':4.79E+02,'y':2.78E+02},
{'x':4.83E+02,'y':2.28E+02},
{'x':4.86E+02,'y':1.73E+02},
{'x':4.90E+02,'y':1.32E+02},
{'x':4.94E+02,'y':1.19E+02},
{'x':4.98E+02,'y':1.37E+02},
{'x':5.01E+02,'y':1.77E+02},
{'x':5.05E+02,'y':2.22E+02},
{'x':5.09E+02,'y':2.55E+02},
{'x':5.13E+02,'y':2.65E+02},
{'x':5.16E+02,'y':2.50E+02},
{'x':5.20E+02,'y':2.18E+02},
{'x':5.24E+02,'y':1.82E+02},
{'x':5.28E+02,'y':1.55E+02},
{'x':5.31E+02,'y':1.46E+02},
{'x':5.35E+02,'y':1.58E+02},
{'x':5.39E+02,'y':1.84E+02},
{'x':5.43E+02,'y':2.16E+02},
{'x':5.46E+02,'y':2.41E+02},
{'x':5.50E+02,'y':2.50E+02},
{'x':5.54E+02,'y':2.41E+02},
{'x':5.58E+02,'y':2.16E+02},
{'x':5.61E+02,'y':1.84E+02},
{'x':5.65E+02,'y':1.58E+02},
{'x':5.69E+02,'y':1.46E+02},
{'x':5.73E+02,'y':1.55E+02},
{'x':5.76E+02,'y':1.82E+02},
{'x':5.80E+02,'y':2.18E+02},
{'x':5.84E+02,'y':2.50E+02},
{'x':5.88E+02,'y':2.65E+02},
{'x':5.91E+02,'y':2.55E+02},
{'x':5.95E+02,'y':2.22E+02},
{'x':5.99E+02,'y':1.77E+02},
{'x':6.03E+02,'y':1.37E+02},
{'x':6.06E+02,'y':1.19E+02},
{'x':6.10E+02,'y':1.32E+02},
{'x':6.14E+02,'y':1.73E+02},
{'x':6.18E+02,'y':2.28E+02},
{'x':6.21E+02,'y':2.78E+02},
{'x':6.25E+02,'y':3.00E+02},
{'x':6.29E+02,'y':2.84E+02},
{'x':6.33E+02,'y':2.33E+02},
{'x':6.36E+02,'y':1.65E+02},
{'x':6.40E+02,'y':1.07E+02},
{'x':6.44E+02,'y':8.09E+01},
{'x':6.48E+02,'y':1.01E+02},
{'x':6.51E+02,'y':1.61E+02},
{'x':6.55E+02,'y':2.40E+02},
{'x':6.59E+02,'y':3.07E+02},
{'x':6.63E+02,'y':3.35E+02},
{'x':6.66E+02,'y':3.12E+02},
{'x':6.70E+02,'y':2.43E+02},
{'x':6.74E+02,'y':1.56E+02},
{'x':6.78E+02,'y':8.31E+01},
{'x':6.81E+02,'y':5.38E+01},
{'x':6.85E+02,'y':8.06E+01},
{'x':6.89E+02,'y':1.54E+02},
{'x':6.93E+02,'y':2.46E+02},
{'x':6.96E+02,'y':3.21E+02},
{'x':7.00E+02,'y':3.50E+02},
{'x':7.04E+02,'y':3.21E+02},
{'x':7.08E+02,'y':2.46E+02},
{'x':7.11E+02,'y':1.54E+02},
{'x':7.15E+02,'y':8.06E+01},
{'x':7.19E+02,'y':5.38E+01},
{'x':7.23E+02,'y':8.31E+01},
{'x':7.26E+02,'y':1.56E+02},
{'x':7.30E+02,'y':2.43E+02},
{'x':7.34E+02,'y':3.12E+02},
{'x':7.38E+02,'y':3.35E+02},
{'x':7.41E+02,'y':3.07E+02},
{'x':7.45E+02,'y':2.40E+02},
{'x':7.49E+02,'y':1.61E+02},
{'x':7.53E+02,'y':1.01E+02},
{'x':7.56E+02,'y':8.09E+01},
{'x':7.60E+02,'y':1.07E+02},
{'x':7.64E+02,'y':1.65E+02},
{'x':7.68E+02,'y':2.33E+02},
{'x':7.71E+02,'y':2.84E+02},
{'x':7.75E+02,'y':3.00E+02},
{'x':7.79E+02,'y':2.78E+02},
{'x':7.83E+02,'y':2.28E+02},
{'x':7.86E+02,'y':1.73E+02},
{'x':7.90E+02,'y':1.32E+02},
{'x':7.94E+02,'y':1.19E+02},
{'x':7.98E+02,'y':1.37E+02},
{'x':8.01E+02,'y':1.77E+02},
{'x':8.05E+02,'y':2.22E+02},
{'x':8.09E+02,'y':2.55E+02},
{'x':8.13E+02,'y':2.65E+02},
{'x':8.16E+02,'y':2.50E+02},
{'x':8.20E+02,'y':2.18E+02},
{'x':8.24E+02,'y':1.82E+02},
{'x':8.28E+02,'y':1.55E+02},
{'x':8.31E+02,'y':1.46E+02},
{'x':8.35E+02,'y':1.58E+02},
{'x':8.39E+02,'y':1.84E+02},
{'x':8.43E+02,'y':2.16E+02},
{'x':8.46E+02,'y':2.41E+02},
  ],

  [
{'x':0,'y':200},
{'x':900,'y':200},
  ],

  [
{'x':0,'y':50},
{'x':900,'y':50},
  ],

  [
{'x':0,'y':350},
{'x':900,'y':350},
  ],

];

var colors = [
  'steelblue',
  'green',
  'red',
  'purple'
]


//************************************************************
// Create Margins and Axis and hook our zoom function
//************************************************************
var margin = {top: 20, right: 30, bottom: 30, left: 50},
  width = 960 - margin.left - margin.right,
  height = 500 - margin.top - margin.bottom;
  
var x = d3.scale.linear()
  .domain([0, 900])
  .range([0, width]);

var y = d3.scale.linear()
  .domain([0, 400])
  .range([height, 0]);
  
var xAxis = d3.svg.axis()
  .scale(x)
  .tickSize(-height)
  .tickPadding(10)	
  .tickSubdivide(true)	
  .orient("bottom");	
  
var yAxis = d3.svg.axis()
  .scale(y)
  .tickPadding(10)
  .tickSize(-width)
  .tickSubdivide(true)	
  .orient("left");
  
var zoom = d3.behavior.zoom()
  .x(x)
  .y(y)
  .scaleExtent([1, 10])
  .on("zoom", zoomed);	
  
  
//************************************************************
// Generate our SVG object
//************************************************************	
var svg = d3.select("body").append("svg")
  .call(zoom)
  .attr("width", width + margin.left + margin.right)
  .attr("height", height + margin.top + margin.bottom)
  .append("g")
  .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

svg.append("g")
  .attr("class", "x axis")
  .attr("transform", "translate(0," + height + ")")
  .call(xAxis);

svg.append("g")
  .attr("class", "y axis")
  .call(yAxis);

svg.append("g")
  .attr("class", "y axis")
  .append("text")
  .attr("class", "axis-label")
  .attr("transform", "rotate(-90)")
  .attr("y", (-margin.left) + 10)
  .attr("x", -height/2)
  .text('Axis Label');	

svg.append("clipPath")
  .attr("id", "clip")
  .append("rect")
  .attr("width", width)
  .attr("height", height);
  
  
//************************************************************
// Create D3 line object and draw data on our SVG object
//************************************************************
var line = d3.svg.line()
  .interpolate("linear")	
  .x(function(d) { return x(d.x); })
  .y(function(d) { return y(d.y); });		
  
svg.selectAll('.line')
  .data(data)
  .enter()
  .append("path")
  .attr("class", "line")
  .attr("clip-path", "url(#clip)")
  .attr('stroke', function(d,i){ 			
  	return colors[i%colors.length];
  })
  .attr("d", line);		
  
//************************************************************
// Draw points on SVG object based on the data given
//************************************************************
var points = svg.selectAll('.dots')
  .data(data)
  .enter()
  .append("g")
  .attr("class", "dots")
  .attr("clip-path", "url(#clip)");	

points.selectAll('.dot')
  .data(function(d, index){ 		
  	var a = [];
  	d.forEach(function(point,i){
  		a.push({'index': index, 'point': point});
  	});		
  	return a;
  })
  .enter()
  .append('circle')
  .attr('class','dot')
  .attr("r", 2.5)
  .attr('fill', function(d,i){ 	
  	return colors[d.index%colors.length];
  })	
  .attr("transform", function(d) { 
  	return "translate(" + x(d.point.x) + "," + y(d.point.y) + ")"; }
  );
  
//************************************************************
// Zoom specific updates
//************************************************************
function zoomed() {
  svg.select(".x.axis").call(xAxis);
  svg.select(".y.axis").call(yAxis);   
  svg.selectAll('path.line').attr('d', line);  

  points.selectAll('circle').attr("transform", function(d) { 
  	return "translate(" + x(d.point.x) + "," + y(d.point.y) + ")"; }
  );  
}

修改 .attr("r", 2.5)即可修改作图打点的大小。

作图结果:
用d3.js对信号处理的结果数据作图,得到可缩放交互的动态SVG图

通过鼠标可对曲线缩放观察。

用d3.js对信号处理的结果数据作图,得到可缩放交互的动态SVG图

更多例子

可以显示音频信号的波形和频谱。与Wavosaur所得结果对比。

用d3.js对信号处理的结果数据作图,得到可缩放交互的动态SVG图

用d3.js对信号处理的结果数据作图,得到可缩放交互的动态SVG图

演示代码下载

请参照:https://pan.baidu.com/s/1dgsfy18ccEKBHHwkBm_yfQ