• D3.js 力导向图(小气泡围绕中心气泡)


    html

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <title>气泡图1</title>
    <meta name="Generator" content="EditPlus">
    <meta name="Author" content="">
    <meta name="Keywords" content="">
    <meta name="Description" content="">
    
    
    
    
    <!-- 
    <script src='https://touzi.sina.com.cn/view/public/js/common.js?id=20160708102080'></script> --
    <script src="https://ssl-finance.sina.com.cn/xdemo/touziyi/js/circleForceMore.js" charset="gbk"></script>
    <script src="https://ssl-finance.sina.com.cn/xdemo/js/touziyi2/circleforce.js" charset="gbk"></script>
    <script src="https://ssl-finance.sina.com.cn/xdemo/touziyi/js/stockHotChart.js" charset="gbk"></script>
    <script src="https://touzi.sina.com.cn/view/public/js/theme/index.js?id=20160708102080"></script>
    <script src="https://touzi.sina.com.cn/view/public/js/pageload.js"></script> --
    <script type="text/javascript" src='https://ssl-finance.sina.com.cn/sinafinancesdk/js/sf_sdk.js'></script>  --
    <script src="https://ns.sinaimg.cn/finance/tzy/js/jq.js" charset="utf-8"></script> --
    -->
      <script src="jquery-1.11.1.min.js"></script>
        <script src="d3.3.5.js"></script>
        
    <script type="text/javascript">
    //此处为点击页面打开的链接
    new fChart({conc_url:"http://baidu.com",
                stock_url:"http://sina.com",w:1500,h:600}).init();
    //构图
    function force(option_){
    
        var width=option_.w,//848,
            height=option_.h,//560,
            padding=3,
            clusterPadding=30,
            maxRadius=50,
            riseColor='#EC4E4B',
            fallColor='#00AE66',
            zeroColor='#969696';
        var n=60,
            m=6;
        //每个群集父节点
        var parentNodes = new Array(m);
    
        var color = d3.scale.category10().domain(d3.range(m));
    
        function creatA(n_,m_){
            var arr=[],a=0;
    
            for(var i=0;i<n_;i++){
                if(i%m_==0 && i!=0)a++;
    
                arr.push(a);
            }
    
            return arr;
        }
    
        var b= creatA(n,m);
        var c=0;
        var nodes = d3.range(n).map(function() {
            var i = b[c],//Math.floor(Math.random() * m),
                r = (c%m)==0 ? 45:10;//Math.sqrt((i + 1) / m * -Math.log(Math.random())) * maxRadius;
            var d = {
                cluster: i,
                radius: r,
                name:'a',
                zf:'0',
                x: Math.cos(i / m * 2 * Math.PI) * 500 + width/2 + Math.random(),
                y: Math.sin(i / m * 2 * Math.PI) * 500 + height/2  + Math.random()
            };
            if (!parentNodes[i] || (r > parentNodes[i].radius)) parentNodes[i] = d;
            c++;
            return d;
        });
    
        var node;
        var clickStatus=0;
        var chuc=0;
        function _init(){
            var force = d3.layout.force().nodes(nodes)
                        .size([width,height])  
                        .gravity(0)
                        //.linkStrength(0) 
                        .charge(0);
    
            var svg = d3.select("#chart-svg").append("svg")
                        .attr("width", width)
                        .attr("height", height);
            //var drag = force.drag().on("dragstart", dragstart);
            var dragend = force.drag().on("dragend", dragendX)
                                        .on('dragstart', dragstart);
    
            var offsetX=0,offsetY=0;
            function dragendX(){
                offsetX-=d3.event.sourceEvent.x;
                offsetY-=d3.event.sourceEvent.y;
    
                offsetX=Math.abs(offsetX);
                offsetY=Math.abs(offsetY);
            }
    
            function dragstart(){
                offsetX=d3.event.sourceEvent.x;
                offsetY=d3.event.sourceEvent.y;
            }
            //构建图表和数字
            node = svg.selectAll('g')
                    .data(nodes)
                    .enter().append("g")
                    .style('cursor','pointer')
                    .on('click',function(d){
                        var url;
                        //根据半径确定是个股气泡还是题材气泡
                        if(d.radius<45){//个股
                            url=option_.conc_url+d.stockCode;
                        }else{//题材
                            url=option_.stock_url+d.concUniCode;
                        }
                        window.open(url);
                    });
    
            node.append('circle')
                .style("fill",function(d){
                    if(d.radius>55) d.radius=44;
                    var c='#ffffff';
                    if(d.zf>0 && d.radius<45)c=riseColor;
                    if(d.zf<0 && d.radius<45)c=fallColor;
                    if(d.zf==0&& d.radius<45)c=zeroColor;
                    return c;
                })
                .style('stroke',function(d){
                    var c=riseColor;
                    if(d.zf>0) c=riseColor;
                    if(d.zf<0) c=fallColor;
                    if(d.zf==0)c=zeroColor;
                    return c;
                });
    
            node.append('text')
                .attr('alignment-baseline','middle')
                .attr('text-anchor','middle')
                .text(function(d){
                    return d.name;
                })
                .style('font-size',function(d){
                    var size='12px';
                    if(d.radius>45)size='12px';
                    return size;
                })
                .style('fill',function(d){
                    var c='#ffffff';
                    if(d.radius>45 && d.zf>0) c=riseColor;
                    if(d.radius>45 && d.zf<=0) c=fallColor;
                    if(d.radius>45 && d.zf==0) c=zeroColor;
                    if(d.radius<45 && d.zf==0) c=zeroColor;
                    return c;
                })
                .attr('x',function(d){
                    if(this.getComputedTextLength()>d.radius*2 && d.radius<45){
    
                        var top=d.name.substring(0,2);
                        var bot=d.name.substring(2,d.name.length);
    
                        d3.select(this).text(function(){return '';});
    
                        d3.select(this).append('tspan')
                            .attr('x',0)
                            .attr('y',-5)
                            .text(function(){return top;});
    
                        d3.select(this).append('tspan')
                            .attr('x',0)
                            .attr('y',10)
                            .text(function(){return bot;});
                        return '';
                    }
                });
    
            node.transition()
                .duration(750)
                //.delay(function(d, i) { return i * 5; })
                .select('circle').attrTween("r", function(d) {
                    var i = d3.interpolate(0, d.radius);
                    return function(t) { return d.radius = i(t);
                };
            });
    
            force.on('tick',_tick).start();
            force.on('end',function(){
                clickStatus=1;
                chuc=1;
            });
        }
    
        function _update(){
            //d3.select("#chart-svg").remove();
            document.getElementById('chart-svg').innerHTML='';
            node=null;
    
            _init();
        }
    
        function _tick(e){
    
            var alpha=50 * e.alpha * e.alpha;
            node.each(function(d){
                var cluster = parentNodes[d.cluster];
                // For cluster nodes, apply custom gravity.
                if (cluster === d) return;
    
                if(chuc==0){
                    var bab=(d.cluster%2 == 0)? 1:2;
                    var cac= d.cluster>4 ? d.cluster-5:d.cluster;
    
                    cluster.x=cac*option_.w*9/48 + 160;
                    cluster.y=bab*option_.h/3; 
                }
    
                var x = d.x - cluster.x,
                    y = d.y - cluster.y,
                    l = Math.sqrt(x * x + y * y),
                    r = d.radius + cluster.radius;
                if (l != r) {
                    l = (l - r) / l * alpha;
                    d.x -= x *= l;
                    d.y -= y *= l;
                    cluster.x += x;
                    cluster.y += y;
                }
            })
            .each(function(d){
                var quadtree = d3.geom.quadtree(nodes);
                var alpha2=0.5;
    
                var r = d.radius + 50 + clusterPadding,
                    nx1 = d.x - r,
                    nx2 = d.x + r,
                    ny1 = d.y - r,
                    ny2 = d.y + r;
    
                quadtree.visit(function(quad, x1, y1, x2, y2) {
                    if (quad.point && (quad.point !== d)) {
                        var x = d.x - quad.point.x,
                            y = d.y - quad.point.y,
                            l = Math.sqrt(x * x + y * y),
                            r = d.radius + quad.point.radius + (d.cluster === quad.point.cluster ? padding : clusterPadding);
                        if (l < r) {
                            l = (l - r) / l * alpha2;
                            d.x -= x *= l;
                            d.y -= y *= l;
                            quad.point.x += x;
                            quad.point.y += y;
                        }
                    }
                    return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
                });
            })
            .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")"; })
            .select('circle')
            .attr('r',  function(d) { if(d.name==' ')return 0;return d.radius; });
        }
    
        this.nodes=nodes;
        this.init=_init;
        this.update=_update;
    }
    
    //处理数据
    function fChart(option_){
    
        var _chart=new force(option_);//填充图表数据
        
    
    
        function _update(){
           _init(true);
        }
    
        function _init(update_){
            //加载题材列表
            $.post("3.json",null,function(fdata){
                //此处是因为中心气泡的排列规则并未按照数据的顺序,因此在此处写死
                var array=[0,36,12,48,24,30,6,42,18,54];
                for(var i=0;i<10;i++){
                    var concInfo=fdata.dataObj[i];
                    var x1=array[i];
                    _chart.nodes[x1].name   =concInfo.name;
                    _chart.nodes[x1].zf     =concInfo.zf;
                    _chart.nodes[x1].concUniCode=concInfo.code;
                    _chart.nodes[x1].radius=55; //50 + 50 * Math.abs(concInfo.zf)/100 || 5;
                    /*绝对值大于10则圆圈显示固定大小
                    if(Math.abs(concInfo.zf)>10){
                        _chart.nodes[i*6].radius= 50 + 50 * Math.abs(10)/100 || 5;
                    }*/
                    //_chart.nodes[i*6].stockNum=concInfo.num;//个股个数,暂时用不到
                    //var j=0;
                    //i*6-- 0,6,12,18,24,30,36,42,48,54  0,0,K=0;K<5;k++ 1,2,3,4,5 | 1,6 k=5;k<10;k++ 6,7,8,9,10  | 2 k=10;k<15;k++
                    //k=i*5;k<i*5+5;k++ 
                   console.log(concInfo.name+"--"+x1);
                   var y=x1;       
                   for(var k=i*5;k<i*5+5;k++){
                       y++;
                       /*
                       if(k%5 == 0){
                           j++;
                       }*/
                       var stockInfo=fdata.dataObj1[k];
                       //console.log(stockInfo.name+"--"+y);
                       //console.log(stockInfo);
                       _chart.nodes[y].name  = stockInfo.name;
                       _chart.nodes[y].zf    = stockInfo.zf;
                       _chart.nodes[y].stockCode= stockInfo.code;
                       _chart.nodes[y].radius=44;// 20 + Math.abs(stockInfo.zf) * 200 || 10;
                       /*绝对值大于10则圆圈显示固定大小
                       if(Math.abs(stockInfo.zf)>10){
                           _chart.nodes[y].radius= 20 + Math.abs(10) * 200 || 10;
                       }*/
                       
                   }
                   
                }
                console.log(_chart);
                update_?_chart.update():_chart.init();
            },"json");
        
        }
    
        this.init=_init;
        this.update=_update;
    }
    
    </script>
    
    
    </head>
    
    <body>
        <div id="chart-svg" style="position: relative; font-family: 'Microsoft Yahei', Arial, sans-serif '">
            
        </div>
        
        <div id="chartpopupsk"
            style="position: absolute; color: rgb(255, 255, 255); font-family: 'Microsoft Yahei', Arial, sans-serif; font-size: 12px; min- 185px; height: 60px; display: none; left: 388.212px; top: 635.789px; background-color: rgba(62, 62, 62, 0.8);">
            <div style="float: left; padding: 10px 0 0 10px;">
                <div id="chartpopup_name" style="font-size: 14px; border-right: 1px solid #aaa; padding: 0 5px 0 0;">个股名称暂无</div>
                <div id="chartpopup_code" style="text-align: center; border-right: 1px solid #aaa; padding: 0 5px 0 0;">个股编码暂无</div>
            </div>
            <div style="padding: 10px 10px 0 0; float: right;">
                <div id="chartpopup_price"
                    style="text-align: right; font-size: 14px;">价格暂无</div>
                <div style="text-align: right;">
                    <span id="chartpopup_zde" style="color: rgb(241, 18, 0);">数字1暂无</span>
                    <span id="chartpopup_zdf" style="color: rgb(241, 18, 0);">数字2暂无</span>
                </div>
            </div>
        </div>
    
        <!--  
        <div id="chartpopupzt"
            style="position: absolute; color: rgb(255, 255, 255); font-family: 'Microsoft Yahei', Arial, sans-serif; font-size: 14px; min- 150px; height: 70px; display: none; padding: 5px 10px 10px; left: 887.245px; top: 527.972px; background-color: rgba(62, 62, 62, 0.8);">
            <div>
                <div id="chartpopup_zt_name"
                    style="text-align: center; font-size: 16px; padding: 5px;">概念名称暂无</div>
                <div>
                    股票涨幅<span id="chartpopup_zt_zf"
                        style="color: rgb(241, 18, 0);">涨幅暂无</span>
                </div>
                <div>
                    股票个数<span id="chartpopup_zt_nm">股票个数暂无</span>
                </div>
            </div>
        </div>-->
    </body>
    </html>

    json

    {"data":"","dataObj":[{"code":"5001001166","hotIndex":"7505.98","name":"题材1","zf":"0.05274"},{"code":"5001001302","hotIndex":"5352.67","name":"题材2","zf":"-0.003784"},{"code":"5001000357","hotIndex":"5115.53","name":"题材3","zf":"0.040465"},{"code":"5001001287","hotIndex":"4934.29","name":"题材4","zf":"0.037267"},{"code":"5001001291","hotIndex":"4197.84","name":"题材5","zf":"0.01795"},{"code":"5001000624","hotIndex":"3813.37","name":"题材6","zf":"-0.001294"},{"code":"5001000451","hotIndex":"3810.7","name":"题材7","zf":"0.019308"},{"code":"5001001012","hotIndex":"3613.85","name":"题材8","zf":"0.020218"},{"code":"5001000982","hotIndex":"3497.48","name":"题材9","zf":"0.020191"},{"code":"5001001284","hotIndex":"3457.36","name":"题材10","zf":"0.013875"}],"dataObj1":[{"code":"2010000126","hotIndex":"6571.93","name":"东旭光电","zf":"10.0195"},{"code":"2010002543","hotIndex":"4328.09","name":"宝泰隆","zf":"9.9747"},{"code":"2010002038","hotIndex":"3757.63","name":"中科电气","zf":"10.0291"},{"code":"2010001972","hotIndex":"3546.53","name":"乐通股份","zf":"8.4665"},{"code":"2010002892","hotIndex":"3480.18","name":"珈伟股份","zf":"7.8632"},{"code":"2010001784","hotIndex":"2996.16","name":"国统股份","zf":"10.016"},{"code":"2010003068","hotIndex":"2877.65","name":"蒙草生态","zf":"-3.4151"},{"code":"2010001776","hotIndex":"2443.15","name":"云投生态","zf":"-1.4216"},{"code":"2010001147","hotIndex":"2208.07","name":"龙建股份","zf":"1.8031"},{"code":"2010002505","hotIndex":"2173.17","name":"铁汉生态","zf":"-3.4373"},{"code":"2010000781","hotIndex":"2816.38","name":"铜峰电子","zf":"10.0509"},{"code":"2010000015","hotIndex":"2521.94","name":"中国宝安","zf":"6.2323"},{"code":"2010002289","hotIndex":"1275.64","name":"江海股份","zf":"2.5496"},{"code":"2010001629","hotIndex":"1181.2","name":"江苏国泰","zf":"1.1536"},{"code":"2010001386","hotIndex":"1136.15","name":"法拉电子","zf":"1.3538"},{"code":"2010000126","hotIndex":"6571.93","name":"东旭光电","zf":"10.0195"},{"code":"2010001798","hotIndex":"1639.66","name":"合力泰","zf":"5.4404"},{"code":"2010001861","hotIndex":"1558.01","name":"水晶光电","zf":"2.9678"},{"code":"2010002696","hotIndex":"1275.42","name":"星星科技","zf":"1.5805"},{"code":"2010002204","hotIndex":"1201.57","name":"劲胜精密","zf":"0.4021"},{"code":"2010000681","hotIndex":"4048.28","name":"杭钢股份","zf":"10."},{"code":"2010002639","hotIndex":"2745.97","name":"洲明科技","zf":"10."},{"code":"2010002601","hotIndex":"2661.1","name":"安利股份","zf":"9.9904"},{"code":"2010001447","hotIndex":"2195.83","name":"杭萧钢构","zf":"7.8886"},{"code":"2010002661","hotIndex":"1636.1","name":"日上集团","zf":"2.046"},{"code":"2010000290","hotIndex":"3106.11","name":"格力电器","zf":"-0.4078"},{"code":"2010002660","hotIndex":"2741.59","name":"比亚迪","zf":"-1.1271"},{"code":"2010000453","hotIndex":"2710.36","name":"中信国安","zf":"3.1383"},{"code":"2010002821","hotIndex":"2161.52","name":"京威股份","zf":"0.2034"},{"code":"2010000758","hotIndex":"2102.06","name":"亚星客车","zf":"7.0877"},{"code":"2010002593","hotIndex":"4557.87","name":"欣旺达","zf":"10.0073"},{"code":"2010000437","hotIndex":"3147.83","name":"超声电子","zf":"7.931"},{"code":"2010002660","hotIndex":"2741.59","name":"比亚迪","zf":"-1.1271"},{"code":"2010000077","hotIndex":"2654.75","name":"德赛电池","zf":"7.7908"},{"code":"2010001612","hotIndex":"2482.51","name":"苏州固锝","zf":"7.4681"},{"code":"2010002513","hotIndex":"3344.","name":"力源信息","zf":"9.9753"},{"code":"2010001410","hotIndex":"3148.05","name":"长电科技","zf":"8.3427"},{"code":"2010001908","hotIndex":"2318.31","name":"超华科技","zf":"5.7273"},{"code":"2010001828","hotIndex":"1998.2","name":"歌尔股份","zf":"2.1038"},{"code":"2010001930","hotIndex":"1745.42","name":"汉威电子","zf":"2.0426"},{"code":"2010000453","hotIndex":"2710.36","name":"中信国安","zf":"3.1383"},{"code":"2010002166","hotIndex":"1588.49","name":"南都电源","zf":"1.8414"},{"code":"2010001744","hotIndex":"1540.49","name":"江特电机","zf":"3.3256"},{"code":"2010001696","hotIndex":"1230.78","name":"拓邦股份","zf":"1.9737"},{"code":"2010000188","hotIndex":"1208.8","name":"佛山照明","zf":"0.8364"},{"code":"2010000942","hotIndex":"3502.58","name":"四川金顶","zf":"10.0142"},{"code":"2010000379","hotIndex":"3182.66","name":"山西三维","zf":"10.0236"},{"code":"2010000696","hotIndex":"2995.21","name":"商赢环球","zf":"4.3464"},{"code":"2010000781","hotIndex":"2816.38","name":"铜峰电子","zf":"10.0509"},{"code":"2010000701","hotIndex":"2793.84","name":"维科精华","zf":"9.9819"}],"dataObj2":null,"dataObj3":null,"flag":true,"msg":"成功"}

  • 相关阅读:
    Android Studio:xxx is not an enclosing class 错误的解决方法
    SpringMVC验证框架Validation特殊用法
    在Spring MVC中使用注解的方式校验RequestParams
    Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC
    Bean Validation 技术规范特性概述
    JSR 303
    SpringMVC学习
    javax.validation.UnexpectedTypeException: No validator could be found for constraint 'org.hibernate.validator.constraints.Length' validating type
    SpringAOP拦截Controller,Service实现日志管理(自定义注解的方式)
    Spring AspectJ切入点语法详解
  • 原文地址:https://www.cnblogs.com/xcxcxcxc/p/5900616.html
Copyright © 2020-2023  润新知