数据可视化 地图和音乐可视化

<html>
<head>
    <meta charSet="utf-8">
    <title>基于GeoJSON绘制北京地图</title>
    <style>
        .province {
            stroke: black;
            stroke-width: 1px;
        }

        .southchinasea {
            stroke: black;
            stroke-width: 1px;
            fill: red;
        }
        body {
            background-image: url("https://img.mp.itc.cn/q_70,c_zoom,w_640/upload/20161019/b2a9d777c3734024bae19464c9f487ba_th.jpeg");
            background-size: cover;
            background-position: center;
        }

    </style>
</head>
<body>
<script src="https://d3js.org/d3.v7.min.js" charSet="utf-8"></script>
<script>
    var width = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) * 0.98;
    var height = (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) * 2;

    var svg = d3.select("body").append("svg")
        .attr("width", width)
        .attr("height", height);

    var projection = d3.geoMercator()
        .center([116.3956, 39.93])
        .scale(10000)
        .translate([width / 2, height / 2]);

    //定义地形路径生成器
    var geoPath = d3.geoPath()
        .projection(projection);	//设定投影

    console.log(geoPath);
    //颜色比例尺
    var color = d3.schemePaired;           //d3.schemeBlues[9];       //d3.schemeCategory10;
    console.log(color);

    //请求ChinaGeo.json
    d3.json("hebei.json").then(function (data) {           //100000_full.json  A2_100000_full.json

        console.log(data);
        var scaleColor = d3.scaleOrdinal()
            .domain(d3.range(data.features.length))
            .range(d3.schemeCategory10);

        var groups = svg.append("g");

        groups.selectAll("path")
            .data(data.features)
            .enter()
            .append("path")
            .attr("class", "province")
            .attr("stroke", "black")
            .attr("fill", (d, i) => color[i % 12])
            .attr("d", (d, i) => geoPath(d));	//使用路径生成器

        var texts = svg.selectAll(".texts")
            .data(data.features)
            .enter()
            .append("text")
            .attr("class", "texts")
            .text(function (d, i) {
                return d.properties.name + "-" + i;
            })
            .attr("transform", function (d) {
                var centroid = geoPath.centroid(d),
                    x = centroid[0],
                    y = centroid[1];
                return "translate(" + x + ", " + y + ")";
            })
            .attr('fill', '999')
            .attr("font-size", "35px");
        svg.append("text")
            .attr("font-size", "40px")
            .attr("font-family", "Fantasy")
            .attr("text-anchor", "middle")
            .attr("x", w / 2)
            .attr("y", h / 17)
            .text("河北省地图");
    });
</script>
</body>
</html>

 音乐可视化


<html>
<head>
    <meta charSet="utf-8">
    <title>基于D3的音乐可视化</title>
</head>
<body>
<audio id="audioElement" src="sb.mp3" controls="controls"></audio>
<script src="d3.v3.min.js" charset="utf-8"></script>
<script>
    var audioCtx = new (window.AudioContext || window.webkitAudioContext)();
    var audioElement = document.getElementById('audioElement');
    var audioSrc = audioCtx.createMediaElementSource(audioElement);
    var analyser = audioCtx.createAnalyser();

    //绑定分析器到音频媒体元素
    audioSrc.connect(analyser);
    audioSrc.connect(audioCtx.destination);

    var frequencyData = new Uint8Array(100);
    var width = 1200;
    var height =500;
    var innerR = 80;//内半径
    var r = Math.floor(Math.random() * 255);
    var g = Math.floor(Math.random() * 255);
    var b = Math.floor(Math.random() * 255);
    var dataset=new Array(100);
    for(var i=0;i<dataset.length;i++){
        dataset[i]=new Array();
        dataset[i][0]=120;
        dataset[i][1]=100+Math.floor(Math.random()*(255-100));
    }
    //转化数据为适合生成饼图的对象数组
    var pie = d3.layout.pie()
        .value(function(d){return d[0];});

    var arcPath=d3.svg.arc()//内外半径
        .innerRadius(innerR);

    var svg=d3.select("body")
        .append("svg")
        .attr("width",width)
        .attr("height",height);

    var arcs=svg.selectAll("path")
        .data(pie(dataset))//原生数据-->起止角度
        .enter()
        .append("path")
        .attr("transform", "translate(" + width/2 + "," + height/2 + ")")
        .attr("fill",function(d,i){//填充颜色
            return 'rgb(0,152,'+dataset[i][1]+')';
        })
        .attr("stroke","#FFF")
        .attr("d",function(d,i){
            arcPath.outerRadius(dataset[i][1]);
            return arcPath(d);   //起止角度(内外半径)——>路径的参数
        });

    // 连续循环更新
    function renderChart() {
        requestAnimationFrame(renderChart);
        analyser.getByteFrequencyData(frequencyData);
        //console.log(frequencyData);
        svg.selectAll('path')
            .data(pie(dataset))
            .attr("fill",function(d,i){//填充颜色
                return 'rgb(0,0,'+frequencyData[i]+')';
            })
            .attr("d",function(d,i){
                arcPath.outerRadius(frequencyData[i]+ innerR);
                return arcPath(d);
            });
    }
    renderChart();
</script>
</body>
</html>

 canvas特效

 

<!DOCTYPE html>
<html>
<head>
    <meta charSet="utf-8">
    <title>浮雕和雕刻特效</title>
</head>
<style>
    body {
        text-align: center;
        background-color: #f9f9f9;
        font-size: 16px;
        font-family: "Microsoft YaHei", sans-serif;
    }

    button {
        margin-top: 20px;
        padding: 10px;
        background-color: #4CAF50;
        color: white;
        border: none;
        cursor: pointer;
        border-radius: 3px;
        box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.2);
        transition: all 0.2s ease-in-out;
    }

    button:hover {
        transform: scale(1.05);
    }
</style>
<body>
<center>
    <h2>浮雕和雕刻特效</h2>
    <button id="embossBtn">浮雕</button>
    <button id="engraveBtn">雕刻</button>
    <br/><br/>
    <canvas id="myCanvas" width="600" height="400" style="border:1px solid #c3c3c3;"></canvas>
    <script type="text/javascript">
        var c=document.getElementById("myCanvas");
        var cxt=c.getContext("2d");
        var img=new Image()
        img.src="a.jpg"
        img.onload = function () {
            cxt.drawImage(img, 0, 0);
        }

        function emboss() {
            var imageData = cxt.getImageData(0, 0, c.width, c.height);
            var data = imageData.data;

            for (var i = 0; i < data.length; i += 4) {
                if (i < c.width * 4 || i > data.length - c.width * 4) {
                    continue;
                }

                var x = (i / 4) % c.width;
                if (x === 0 || x === c.width - 1) {
                    continue;
                }

                var r1 = data[i - c.width * 4 + 0];
                var g1 = data[i - c.width * 4 + 1];
                var b1 = data[i - c.width * 4 + 2];

                var r2 = data[i - 4 + 0];
                var g2 = data[i - 4 + 1];
                var b2 = data[i - 4 + 2];

                var r3 = data[i + 4 + 0];
                var g3 = data[i + 4 + 1];
                var b3 = data[i + 4 + 2];

                var r4 = data[i + c.width * 4 + 0];
                var g4 = data[i + c.width * 4 + 1];
                var b4 = data[i + c.width * 4 + 2];

                var gray1 = (r1 + g1 + b1) / 3;
                var gray2 = (r2 + g2 + b2) / 3;
                var gray3 = (r3 + g3 + b3) / 3;
                var gray4 = (r4 + g4 + b4) / 3;

                var xDiff = (gray2 + gray2 + gray2 - gray4 - gray4 - gray4);
                var yDiff = (gray1 + gray1 + gray1 - gray3 - gray3 - gray3);
                var gray = parseInt(Math.sqrt(xDiff * xDiff + yDiff * yDiff) * 0.8);
                if (gray > 255) {
                    gray = 255;
                }

                data[i + 0] = gray;
                data[i + 1] = gray;
                data[i + 2] = gray;
            }

            cxt.putImageData(imageData, 0, 0);
        }

        function engrave() {
            var imageData = cxt.getImageData(0, 0, c.width, c.height);
            var data = imageData.data;

            for (var i = 0; i < data.length; i += 4) {
                data[i + 0] = 255 - data[i + 0];
                data[i + 1] = 255 - data[i + 1];
                data[i + 2] = 255 - data[i + 2];
            }

            cxt.putImageData(imageData, 0, 0);
        }

        var embossBtn = document.getElementById('embossBtn');
        var engraveBtn = document.getElementById('engraveBtn');

        embossBtn.addEventListener('click', function() {
            emboss();
        });

        engraveBtn.addEventListener('click', function() {
            engrave();
        });
    </script>
</center>
</body>
</html>

灰度等高线

 

<html>
<head>
    <meta charSet="utf-8">
    <script src="https://d3js.org/d3.v5.min.js"></script>
</head>
<style>
    body {
        text-align: center;
        background-color: #f9f9f9;
        font-size: 16px;
        font-family: "Microsoft YaHei", sans-serif;
    }

    button {
        margin-top: 20px;
        padding: 10px;
        background-color: #4CAF50;
        color: white;
        border: none;
        cursor: pointer;
        border-radius: 3px;
        box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.2);
        transition: all 0.2s ease-in-out;
    }

    button:hover {
        transform: scale(1.05);
    }

    svg {
        display: block;
        margin: 0 auto;
        border: 1px solid #ddd;
        box-shadow: 0px 2px 5px rgba(0, 0, 0, 0.2);
    }
</style>
<body>
<center>
    <h2>使用D3绘制等高线图</h2>
    <hr width=70%></hr>
    <button id="gray">原图</button>
    <button id="contour">登高线图</button>
    <svg id="mySvg" width="600" height="400" style="border:1px solid #c3c3c3;"></svg>
    <script type="text/javascript">
        var svg=d3.select("#mySvg");
        var img=new Image()
        img.src="unknow.jpg"
        img.onload = function () {
            var canvas = document.createElement("canvas");
            canvas.width = this.width;
            canvas.height = this.height;
            var ctx = canvas.getContext("2d");
            ctx.drawImage(this, 0, 0);
            var data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;

            // 灰度化处理
            var grayData = new Array(canvas.width * canvas.height);
            for (var i = 0; i < grayData.length; i++) {
                grayData[i] = (data[i * 4 + 0] + data[i * 4 + 1] + data[i * 4 + 2]) / 3.0 / 256.0;
            }

            // 定义颜色比例尺
            var colorScale = d3.scaleSequential()
                .domain([0, 64])
                .interpolator(d3.interpolateGreens);

            // 初始化等高线数据
            var contours = d3.contours()
                .size([canvas.width, canvas.height])
                .thresholds(d3.range(0, 1, 0.1))(dataToValues(data));

            // 绘制登高线图
            function drawContour() {
                svg.selectAll("path").remove();
                svg.selectAll("path")
                    .data(contours)
                    .enter().append("path")
                    .attr("d", d3.geoPath(d3.geoIdentity().scale(5)))
                    .attr("fill", function(d) { return colorScale(d.value); })
                    .attr("stroke", "red")
                    .attr("stroke-width", 1);
            }

            // 绘制灰度图
            function drawGray() {
                svg.selectAll("path").remove();
                svg.append("image")
                    .attr("xlink:href", canvas.toDataURL())
                    .attr("width", canvas.width)
                    .attr("height", canvas.height);
            }

            // 将原始数据转换为等高线数据
            function dataToValues(data) {
                var values = new Array(canvas.width * canvas.height);
                for (var i = 0; i < values.length; i++) {
                    values[i] = grayData[i];
                }
                return values;
            }

            // 监听按钮点击事件
            d3.select("#gray").on("click", drawGray);
            d3.select("#contour").on("click", drawContour);

            // 默认绘制等高线图
            drawContour();
        }
    </script>
</center>
</body>
</html>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值