【问题标题】:How can I create custom shaped graphs?如何创建自定义形状的图形?
【发布时间】:2012-06-19 01:09:49
【问题描述】:

我需要创建一个具有自定义形状的图表。例如:为了代表人口,我需要创建一个人形,在其中我将显示统计数据和数据。是否有任何 javascript 库可以帮助我做到这一点? D3 js 会帮助我吗?

感谢任何帮助。

谢谢。

【问题讨论】:

    标签: javascript css graph charts raphael


    【解决方案1】:

    您甚至可以尝试使用这种使用两张图片并相互叠加的方法。

    假设您想要一个人类字体真棒图标作为图表,使用 http://fa2png.io/ 将图标转换为 .png 图像,然后在下面的代码中使用它。

    http://codepen.io/FDfranklin/pen/yGbCK

    <script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script>
    
    <div class="container">
        <div class="bw"></div>
        <div class="show"></div>
        <div id="bar" data-total="100">
            <div class="text">Currently at <br/><span>70</span><br><i>Click To Give</div>
        </div>
    </div>
    

    @import url(http://fonts.googleapis.com/css?family=Concert+One);

    html, body {
      margin: 0 auto;
    }
    
    .container {
      width:450px;
      height:328px;
      position:relative;
      display:inline-block;
      vertical-align:top;
      background-clip:content-box;
    }
    .bw {
      width:100%;
      height:100%;
      position:absolute;
      bottom:0; background:url(http://fdfranklin.com/usf-bull-bw.png) fixed left top;
      background-clip:content-box;
    }
    .show {
      width:100%;
      height:0%;
      position:absolute;
      bottom:0; background:url(http://fdfranklin.com/usf-bull.png) fixed left top;
      background-clip:content-box;
    }
    
    #bar {
      width: 100%;
      height: 0%;
      position: absolute;
      bottom: 0;
      border-top: 1px dashed black;
    
      .load {
          opacity: 1;
        }
    
    
      div {
        position: absolute;
        line-height: 22px;
        width: 110px;
        top: -40px;
        right: -113px;
        font-family: arial, sans-serif;
        font-size: 16px;
        text-align: center;
        color: white;
        cursor: pointer;
        border: 1px solid #ccc;
        border-radius: 8px;
        background: #2f574b;
        transition: background 700ms ease-in-out;
        opacity: 0;
        -webkit-transition: opacity 3s ease-in, background 700ms ease-in-out;
        -moz-transition: opacity 3s ease-in, background 700ms ease-in-out;
        -o-transition: opacity 3s ease-in, background 700ms ease-in-out;
        -ms-transition: opacity 3s ease-in, background 700ms ease-in-out;
        transition: opacity 3s ease-in, background 700ms ease-in-out;
    
          &:hover {
          background: #B1A875;
        }
    
        span {
          font-family: 'Concert One', sans-serif;
          line-height: 30px;
          font-size: 34px;
          color: #white;;
        }
      }
    }
    

    <script>
    percent = $('#bar div span').html();
    total = $('#bar').attr('data-total');
    percentStart = 0;
    
    setInterval(function() {
      $('.show').css('height',percentStart/total*100+'%');
      $('#bar').css('height',percentStart/total*100+'%');
      $('#bar div span').html('%'+percentStart);
      if(percentStart<percent) {percentStart=percentStart+1;}
    },35);
    
    $("#bar div").addClass("load");
    
    </script>
    

    【讨论】:

      【解决方案2】:

      我不知道“人形”这个东西,我认为没有任何工具可以做到这一点。

      但是,我遇到的最好和最接近的资源是 Highcharts 它有各种饼图、样条曲线、条形图等。您需要以交互方式绘制数据。

      我还建议您查看Google Charts。 Highcharts 不提供的一件事是基于地图的数据绘图。 Google 有一个名为 GeoMap 的东西,用于绘制具有特定位置的数据信息,例如全球某个小镇

      【讨论】:

        【解决方案3】:

        或者,一种简单的方法是设置重复的背景图像并根据您的计数更改 DIV 宽度/高度。好处是在任何浏览器中几乎不会影响性能,因为 DIV 高度和重复图像背景都经过了相当优化。

        想法是选择一个图块大小(例如:25 x 11)并将其分成两个 DIV。在上图中,第一个 DIV 在视觉上负责两行,因为它们没有被分解(最大宽度)。第二个 DIV 显示最后一行,因为它的宽度表示部分数字。

        function draw_guys( num, row_width ) {
            var whole = Math.floor( num / row_width ) * row_width;
            var rows = whole / row_width;
            var remainder = num - whole;
        
            // at this point, first div height should be 11 * rows,
            // and second div width should be remainder * 25
            // $("div1").css( ... etc.
        }
        

        有关工作示例,请参阅此 Facebook IPO 计算器:http://www.voanews.com/content/how-long-would-it-take-you-to-earn-as-much-as-facebook-shareholders/667093.html

        【讨论】:

          【解决方案4】:

          有任意数量的 javascript 库可用于编写此类代码,但如果您发现任何“人口图”的行为与您所描述的开箱即用相同,我会感到惊讶。

          我最近在 RaphaelJS 上做了很多工作,根据您的用例,您可以用很少的工作从头开始编写一个简单的图表。考虑一下:

          var figurePath = "m67.55634,478.32968c-8.13657,-2.48874 -14.5806,-8.08679 -16.4212,-14.26556c-0.73347,-2.46204 -1.08294,-52.8298 -1.08687,-156.62885l-0.00574,-152.99986l-4.12245,0l-4.12245,0l0,57.75455c0,56.61781 -0.04195,57.82326 -2.13101,61.24794c-2.70588,4.43591 -5.74459,6.5144 -11.69161,7.99719c-8.79226,2.19217 -18.40762,-1.9938 -21.86059,-9.51678c-2.22165,-4.84039 -2.07695,-133.9393 0.15908,-141.94215c5.04025,-18.03902 21.36259,-32.81751 40.39913,-36.578c10.0279,-1.98091 102.7426,-2.00536 112.74093,-0.02971c10.18434,2.01237 18.93166,6.56422 26.67169,13.87918c7.96135,7.52412 11.67772,13.62765 14.44972,23.73145c1.93217,7.04254 2.03873,10.81412 2.03873,72.15891c0,56.07582 -0.21188,65.2007 -1.58522,68.26476c-2.13536,4.76425 -4.33276,6.9068 -9.23622,9.00589c-8.13713,3.48325 -18.47925,1.24234 -23.2908,-5.04663l-2.47462,-3.23438l-0.28067,-58.8461l-0.2807,-58.84612l-4.09941,0l-4.09944,0l0,153.75127c0,168.54004 0.40904,157.34918 -5.98071,163.62524c-5.04742,4.95758 -10.19456,6.83295 -18.75407,6.83295c-8.55949,0 -13.70664,-1.87537 -18.75407,-6.83295c-6.26537,-6.1539 -5.98071,-1.38409 -5.98071,-100.21561l0,-90.34155l-4.12245,0l-4.12248,0l0,90.34155c0,73.62247 -0.25719,90.91376 -1.38974,93.4332c-2.07629,4.61884 -6.59314,9.17279 -11.33463,11.42776c-4.56992,2.17331 -14.94501,3.1835 -19.23141,1.87241zm23.18207,-395.70253c-12.45886,-4.14828 -20.1591,-10.54255 -25.6095,-21.26616c-3.01675,-5.93541 -3.23429,-7.07562 -3.23429,-16.95192c0,-9.99342 0.18727,-10.94311 3.33264,-16.8991c15.71025,-29.74877 61.06589,-29.82171 76.74945,-0.12342c3.24734,6.14913 3.39783,6.92425 3.39783,17.50292c0,10.17379 -0.23299,11.51108 -2.88087,16.53765c-4.4481,8.44392 -11.01797,14.60091 -19.99178,18.73535c-6.96733,3.21001 -8.73656,3.60972 -17.18201,3.8817c-7.08677,0.2282 -10.69254,-0.12219 -14.58147,-1.41702z";
          
          var figure = canvas.path( figurePath )
              .attr( { fill: 'red', stroke: 'black', 'stroke-width': 3, transform: 'S0.86,0.85 0,0 T0,0', 'fill-opacity': 0, 'stroke-opacity': .5 } )
              .animate( { 'fill-opacity': 0.5, 'stroke-opacity': 1.0, transform: 'S1,1 0,0' }, 1000, '>', function()
                  {
                      var text = canvas.text( 100, 150, "Population:\n10,250" )
                                      .attr( { 'font-size': 16, fill: 'black', stroke: 'none', 'font-weight': 400, 'font-family': 'Arial,Helvetica,sans-serif', 'fill-opacity': 0 } )
                                      .animate( { 'fill-opacity': 1.0 }, 1000 );
                  } );
          
          var figure2 = canvas.path( figurePath )
              .attr( { fill: 'blue', stroke: 'black', 'stroke-width': 3, transform: 'S0.43,0.43 0,0 T250,125', 'fill-opacity': 0, 'stroke-opacity': .5 } )
              .animate( { 'fill-opacity': 0.5, 'stroke-opacity': 1.0, transform: 'S0.6,0.6 0,0 T250,100' }, 1000, '>', function()
                  {
                      var text = canvas.text( 312, 190, "Population:\n6,632" )
                                      .attr( { 'font-size': 12, fill: 'black', stroke: 'none', 'font-weight': 400, 'font-family': 'Arial,Helvetica,sans-serif', 'fill-opacity': 0 } )
                                      .animate( { 'fill-opacity': 1.0 }, 1000 );
                  } );        
          

          或者,看看小提琴:

          - http://jsfiddle.net/kevindivdbyzero/McSzB/
          - http://jsfiddle.net/kevindivdbyzero/mSX8e/2/
          

          【讨论】:

          • 嗨,你的例子对我来说看起来很棒......但我需要的是一个单一的数字,里面有不同的数据阴影。例如:在一个人体结构中,我们可以以堆积图的形式显示。因此,在一个人体结构中会有不同的颜色深浅,可以区分不同的人物
          • 你是怎么想出图形路径的?我的意思是你怎么知道如何创造一个人物形象的价值?如果我想在同一个人物中用两种不同的颜色显示两个不同的值怎么办?
          • 至于路径:我找到了一个公共域 svg,然后使用 svg-edit 将其缩小到您在此处看到的比例(顺便说一下,svg-edit 非常适合简单的编辑任务) .
          • 至于数据的分离……让我稍微修改一下我的小提琴。
          • 这并不理想,但您基本上可以重用相同的路径并将clip-rect应用于与当前区域对应的片段。不过,这可能足以满足您的需求。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-02-11
          • 1970-01-01
          • 2019-04-27
          • 2017-06-17
          相关资源
          最近更新 更多