草庐IT

javascript - android 2.3 上的 d3.js 可视化

coder 2025-03-02 原文

我知道 2.3 的 android 浏览器不支持 SVG,但我想知道我是否可以使用 Canvg 将 d3.js SVG 可视化转换为 Canvas 。在客户端。浏览器是否能够解析 SVG 元素,或者这种从 SVG 到 Canvas 的转换是否需要在服务器端进行?提前致谢!

// Grab data from server...

var btoken = window.location.search.split( 'bearer_token=')[1].split('&')[0]; 
var endpoint = "http://dcaps-staging.media.mit.edu:8080/api/reality_analysis_service/get_reality_analysis_data?document_key=radialData&bearer_token=" + btoken;
console.log(endpoint);
  d3.json(endpoint, function(json){
  console.log(json);

  var data = json.radialData.data;
  var csvdata; 
      csvdata = data;

    //var data


var output_ = '';
for( property in data) {
output_ += property +':' + data[property]+';';
}
console.log(output_);

  var meta = json.radialData.meta;
  var capitalMeta = [];
  for (i = 0; i < meta.length; i++){
      capitalMeta.push(capitaliseFirstLetter(meta[i]));
  }

console.log(window.innerWidth, window.innerHeight )

//var width = 335,
  //  height = 340,
  var width = window.innerWidth - 5,
      height = window.innerHeight - (window.innerHeight * .35),
    outerRadius = height / 2 - 10,
    innerRadius = 120;

var angle = d3.scale.linear()
    .range([0, 2 * Math.PI]);

var radius = d3.scale.linear()
    .range([0, outerRadius]);

var z = d3.scale.category20();
var whiteColor = d3.rgb(255,255,255);
var redColor = d3.rgb(200,100,50);
var newColor = d3.rgb(100,100,100);
var pink = d3.rgb(238,98,226);

var stack = d3.layout.stack()
    .offset("zero")//.offset(function(d) { return d.y0; })
    .values(function(d) { return d.values; })
    .x(function(d, i) { return i; })
    .y(function(d) { return d.value; });

var replaceY0 = 0;

var nest = d3.nest()
    .key(function(d) { return d.layer; });

var line = d3.svg.line.radial()
    .interpolate("cardinal-closed")
    .angle(function(d,i) { return angle(i); })
    .radius(function(d) { return radius(replaceY0 + d.y); });


var lowestValues = [];

// parse response for lowest values
for (i = 0; i < csvdata.length; i++){
  if (csvdata[i].layer == "averageLow"){
      lowestValues.push(csvdata[i].value);
  }
}

var area = d3.svg.area.radial()
    .interpolate("cardinal-closed")
    .angle(function(d, i) { return angle(i); })
    //.innerRadius(function(d) { return radius(replaceY0); })
    .innerRadius(function(d, i) {
        if (d.layer == "User"){ // Hardcoded check right now, might change later...data tag must have USER in it...
          return radius(d.y);
        }
        else{
        return radius(lowestValues[i]);
      }
    })
    .outerRadius(function(d) { return radius(replaceY0 + d.y); });

var heightPadding = 20;
var widthPadding = 2;

var svg = d3.select("#radial_chart").append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "translate(" + ((width / 2) + widthPadding) + "," + ((height / 2) + heightPadding) + ")");

//console.log("data : ", data);
//console.log("svg : ", svg);

var output_SVG = '';
for( property in svg[0][0]) {
output_SVG += property +':' + data[property]+';';
}
console.log(output_SVG);

  var layers = stack(nest.entries(data));

  // Hardcoded swap for User and Average High
  var swapper = layers[2];
  layers[2] = layers[1];
  layers[1] = swapper;


//  console.log("LAYERS : ",layers);
console.log(capitalMeta[0]);

  // Extend the domain slightly to match the range of [0, 2π].
  angle.domain([0, layers.length]);
  //radius.domain([0, d3.max(data, function(d) { console.log("d.y0: ",d.y0); console.log("d.y: ",d.y); return d.y + replaceY0; })]);
  radius.domain([0, 10]);
  var x = svg.selectAll(".axis");
  alert(svg.toString());
  // create Axis
  svg.selectAll(".axis")
      .data(d3.range(angle.domain()[1]))
    .enter().append("g")
      .attr("class", "axis")
      .attr("transform", function(d) { return "rotate(" + angle(d) * 180 / Math.PI + ")"; })
    .call(d3.svg.axis()
      .scale(radius.copy().range([-5, -outerRadius]))
      .ticks(5)
      .orient("left"))
    .append("text")
      .attr("y", 
        function (d) {
          if (window.innerWidth < 455){
            console.log("innerWidth less than 455: ",window.innerWidth);
            return -(window.innerHeight * .33);
          }
          else{
            console.log("innerWidth greater than 455: ",window.innerWidth);
            return -(window.innerHeight * .33);
          }
        })
      .attr("dy", ".71em")
      .attr("text-anchor", "middle")
      .text(function(d, i) { return capitalMeta[i]; })
      .attr("style","font-size:12px;");

  svg.selectAll(".layer")
      .data(layers)
    .enter().append("path")
      .attr("class", "layer")
      .attr("d", function(d) { return area(d.values); })
      .style("fill",
        function(d, i) 
        {
          if (i === 0){
            return whiteColor;
          }
          else if (i == 1){
            return z(i);
          }
          else
          return newColor; 
        })
      .style("opacity",.6)
      .style("stroke",function(d, i){
       if (i == 0)
        return whiteColor;
      else if (i == 2)
        return pink;
      else if (i == 1)
        return whiteColor;
      })
      .style("stroke-width",function(d, i){

       if (i == 1){
          return 0;
        }
        else if (i == 0)
          return 0;
        else
          return 7;
      });
alert('finished');



/*

 // Create the svg drawing canvas...
      var canvas = d3.select("#radial_chart")
        .append("svg:svg")
          .attr("width", 300)//canvasWidth)
          .attr("height", 75)//canvasHeight);
          .attr("id","legend");

legendOffset = 35;
  legendMarginLeft = 60;

var arrayOfTypes = ["User","Average High-Low"];

      // Plot the bullet circles...
      canvas.selectAll("circle")
        .data(arrayOfTypes).enter().append("svg:circle") // Append circle elements
          .attr("cx", legendMarginLeft)// barsWidthTotal + legendBulletOffset)
    .attr("cy", function(d, i) { return legendOffset + i*25; } )
          .attr("stroke-width", ".5")
          .style("fill", function(d, i) { 
          if (i == 0)
            return pink;
          else
            return z(i) }) // Bar fill color
          .attr("r", 10);

      // Create hyper linked text at right that acts as label key...
      canvas.selectAll("a.legend_link")
        .data(arrayOfTypes) // Instruct to bind dataSet to text elements
        .enter().append("svg:a") // Append legend elements
      .append("text")
              .attr("text-anchor", "left")
              .attr("x", legendMarginLeft+15)
        .attr("y", function(d, i) { return legendOffset + i*24 - 10; })
              .attr("dx", 5)
              .attr("dy", "1em") // Controls padding to place text above bars
              .text(function(d, i) { return arrayOfTypes[i];})
              .style("color","white")
*/

//                 canvg();
    alert('finished');


  });

function capitaliseFirstLetter(string) {
      return string.charAt(0).toUpperCase() + string.slice(1);
}

最佳答案

Android does support Canvas ,所以这当然是一个不错的选择(就 SVG 支持而言,you are right that Android 2.3 is not compatible)。

在d3中其实可以直接使用canvas;这是 Mike Bostock 所做的比较,通过一个简单的例子展示了使用 SVG 和 Canvas 之间的区别:

Canvas Swarm/SVG Swarm

请记住,您不仅限于 SVG 或 Canvas;例如,www.nytimes.com/interactive已经看到将 d3.js 与 HTML 元素一起用于可视化(我怀疑更好的跨浏览器支持)。
请参阅:http://www.nytimes.com/interactive/2012/02/13/us/politics/2013-budget-proposal-graphic.html

关于javascript - android 2.3 上的 d3.js 可视化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11617215/

有关javascript - android 2.3 上的 d3.js 可视化的更多相关文章

  1. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  2. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  3. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  4. ruby - Ruby 中的波形可视化 - 2

    我即将开始一个将录制和编辑音频文件的项目,我正在寻找一个好的库(最好是Ruby,但会考虑Java或.NET以外的任何库)以进行实时可视化波形。有人知道我应该从哪里开始搜索吗? 最佳答案 要流入浏览器的数据量很大。Flash或Flex图表可能是唯一能提高内存效率的解决方案。Javascript图表往往会因大型数据集而崩溃。 关于ruby-Ruby中的波形可视化,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.c

  5. 安卓apk修改(Android反编译apk) - 2

    最近因为项目需要,需要将Android手机系统自带的某个系统软件反编译并更改里面某个资源,并重新打包,签名生成新的自定义的apk,下面我来介绍一下我的实现过程。APK修改,分为以下几步:反编译解包,修改,重打包,修改签名等步骤。安卓apk修改准备工作1.系统配置好JavaJDK环境变量2.需要root权限的手机(针对系统自带apk,其他软件免root)3.Auto-Sign签名工具4.apktool工具安卓apk修改开始反编译本文拿Android系统里面的Settings.apk做demo,具体如何将apk获取出来在此就不过多介绍了,直接进入主题:按键win+R输入cmd,打开命令窗口,并将路

  6. ruby-on-rails - Ruby - 如何从 ruby​​ 上的 .pfx 文件中提取公钥、rsa 私钥和 CA key - 2

    我有一个.pfx格式的证书,我需要使用ruby​​提取公共(public)、私有(private)和CA证书。使用shell我可以这样做:#ExtractPublicKey(askforpassword)opensslpkcs12-infile.pfx-outfile_public.pem-clcerts-nokeys#ExtractCertificateAuthorityKey(askforpassword)opensslpkcs12-infile.pfx-outfile_ca.pem-cacerts-nokeys#ExtractPrivateKey(askforpassword)o

  7. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  8. 带有 attr_accessor 的类上的 Ruby instance_eval - 2

    我了解instance_eval和class_eval之间的基本区别。我在玩弄时发现的是一些涉及attr_accessor的奇怪东西。这是一个例子:A=Class.newA.class_eval{attr_accessor:x}a=A.newa.x="x"a.x=>"x"#...expectedA.instance_eval{attr_accessor:y}A.y="y"=>NoMethodError:undefinedmethod`y='forA:Classa.y="y"=>"y"#WHATTT?这是怎么回事:instance_eval没有访问我们的A类(对象)然后它实际上将它添加到

  9. ruby-on-rails - rails 上的 ruby : radio buttons for collection select - 2

    我有一个集合选择:此方法的单选按钮是什么?谢谢 最佳答案 Rails3中没有这样的助手。在Rails4中,它是collection_radio_buttons. 关于ruby-on-rails-rails上的ruby:radiobuttonsforcollectionselect,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/18525986/

  10. ruby - 将命令行上的变量传递给 Cucumber 测试 - 2

    我正在尝试将cucumber项目的用户名和密码置于版本控制之外。有没有办法在命令行上手动将用户名和密码等变量传递给Cucumber脚本?我的备份计划是将它们放在一个YML文件中,然后将该文件添加到gitignore,这样它们就不会被置于版本控制中。 最佳答案 所以,我看到了您对铁皮人的评论,答案是肯定的。cucumberPASSWORD=my_passwordPASSWORD被设置为环境变量,您可以通过将其引用为ENV['PASSWORD']来使用它的值。例如,browser.text_field(:id=>'pwd').setEN

随机推荐