简体   繁体   中英

Using D3 in Rails ActiveAdmin

I am building an application in Ruby-on-Rails 4. I have designed an administration site using ActiveAdmin. It works great but now I would like to add a chart to my index pages using D3.js through the rendering of a partial. I have been very impressed by the D3.js library, but I am realy new at it so I have been trying some developments as a training.

I have not found anything about thsi specific case on the internet so I try to do so from this nice tutorial : Using D3 in Rails . I have included the D3.js library followinh this tutorial. My partial looks like this:

#app/views/admin/_chart.html.erb
<h3>HELLO WORLD!</h3>
<svg id="graph"></svg>

and the admin user.file looks like this :

#app/admin/user.rb
collection_action :data, method: :post do
    respond_to do |format|
          format.json {
            render :json => [1,2,3,4,5]
          }
     end
  end

Then I have the script below in assets/javascript/graph.js:

$.ajax({
           type: "GET",
           contentType: "application/json; charset=utf-8",
           url: 'data',
           dataType: 'json',
           success: function (data) {
               draw(data);
           },
           error: function (result) {
               error();
           }
       });

function draw(data) {
    var color = d3.scale.category20b();
    var width = 420,
        barHeight = 20;

    var x = d3.scale.linear()
        .range([0, width])
        .domain([0, d3.max(data)]);

    var chart = d3.select("#graph")
        .attr("width", width)
        .attr("height", barHeight * data.length);

    var bar = chart.selectAll("g")
        .data(data)
        .enter().append("g")
        .attr("transform", function (d, i) {
                  return "translate(0," + i * barHeight + ")";
              });

    bar.append("rect")
        .attr("width", x)
        .attr("height", barHeight - 1)
        .style("fill", function (d) {
                   return color(d);
              });

    bar.append("text")
        .attr("x", function (d) {
                  return x(d) - 10;
              })
        .attr("y", barHeight / 2)
        .attr("dy", ".35em")
        .style("fill", "white")
        .text(function (d) {
                  return d;
              });
}

function error() {
    console.log("error");
}

When I display the page, the partial is correctly load (at least the title) and there is room for a chart, but it is empty. I have no error in the console so I may not even upload the graph.js file or the data may not be transfered to the chats. Or both. Anyway, I really don't know why neither understand, so your help would be very appreciated. Thank you

S.

[EDIT]

I have changed the route in the route.rb file:

resources :users do
    collection do
    ...
    get :data , :defaults => { :format => 'json' }
    end
end

Then I changed the name of the js file from graph.js to users.js. Then, I changed url to : 'users/data':

    $.ajax({
               type: "GET",
               contentType: "application/json; charset=utf-8",
               url: 'users/data',
               dataType: 'json',
               success: function (data) {
                   draw(data);
               },
               error: function (result) {
                   error();
               }
           });
...

This way I can display the chart in my application's index page. However, I still cannot display it in ActiveAdmin... I am wondering if it is because I haven't correctly include d3 in ActiveAdmin (within the vendor folder) or if it is a route problem.

Ok, I found a way to dispaly a simple D3 bar chart in my Active Admin pages.

This is what I did to display the chart in to the /admin/users page:

#app/admin/user.rb

ActiveAdmin.register User do
...
  collection_action :data, :method => :get do
      respond_to do |format|
      format.json {
        render :json => [1,2,3,4,5]
      }
      end
  end

#app/views/admin/_charts.html.erb

<h3>User chart</h3>
<svg id="graph"></svg>
<script type="text/javascript">
$.ajax({
           type: "GET",
           contentType: "application/json; charset=utf-8",
           url: 'users/data',
           dataType: 'json',
           success: function (data) {
               draw(data);
           },
           error: function (result) {
               error();
           }
       });

function draw(data) {
    var color = d3.scale.category20b();
    var width = 420,
        barHeight = 20;

    var x = d3.scale.linear()
        .range([0, width])
        .domain([0, d3.max(data)]);

    var chart = d3.select("#graph")
        .attr("width", width)
        .attr("height", barHeight * data.length);

    var bar = chart.selectAll("g")
        .data(data)
        .enter().append("g")
        .attr("transform", function (d, i) {
                  return "translate(0," + i * barHeight + ")";
              });

    bar.append("rect")
        .attr("width", x)
        .attr("height", barHeight - 1)
        .style("fill", function (d) {
                   return color(d);
              });

    bar.append("text")
        .attr("x", function (d) {
                  return x(d) - 10;
              })
        .attr("y", barHeight / 2)
        .attr("dy", ".35em")
        .style("fill", "white")
        .text(function (d) {
                  return d;
              });
}

function error() {
    console.log("error");
}
</script>

Then, to display it the dashboard :

#app/admin/dashboard.rb

ActiveAdmin.register_page "Dashboard" do
...
  section do
    div do
      render 'admin/users/charts'
    end
  end
...
end

I hope this will be usefull for you. Now, I am going to try to pass data to another kind of chart.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM