Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I have a page which I am trying to show multiple NVD3 charts on tabs. I see on the NVD3 site that they store all chart names ahead of time but I am not sure how I should do this.

I have graph models which get stored in the database and then my page must dynamically render all of the charts and appropriate javascript on the fly. So far only the last graph constructed shows :(

I render this partial for each graph

<%if graph.present?%>
    <%@graph = graph%>
<%end%>

<%if @graph.data.empty?%>
<%= render 'graphs/no_graph'%>
<%else%>
<script type="text/javascript">
    $(document).ready(function() {
        var data = $('#chart_<%=@graph.id%>').data('data');

        reloadGraph(data);

        $('a[data-toggle="tab"]').on('shown', function(e) {
            reloadGraph(data)
        })
    })
    function reloadGraph(data) {
        nv.addGraph(function() {
            var chart = nv.models.multiBarChart();

            chart.yAxis.axisLabel('Monthly (kWh)');

            d3.select('#chart_<%=@graph.id%> svg').datum(data).transition().duration(500).call(chart);

            nv.utils.windowResize(chart.update);


            return chart;
        });
    }
</script>

<%=content_tag :div, id: "chart_#{@graph.id}",class: 'chart', data: {data: graph.monthly_data} do%>
<svg></svg>
<%end%>
<%end%>

On the NVD3 site they start off with:

var MainExample, ExampleOne, Example2

etc.

Then in their constuction call they assign e.g. MainExample = chart

Any advice on how I should structure this in rails??

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
172 views
Welcome To Ask or Share your Answers For Others

1 Answer

Ok so there were no takers on answering here but basically it turns out that you have to store the dynamic objects in an array like

var charts = []

Then loop through the charts with a each_with_index and use the index to reference the various charts

in your each_with_index loop which is essentially rendering out the javascript a piece at a time, you render out the creation of each dynamic graph.

Mine looked like this (un-polished but working fine)

<script type="text/javascript">
var graphs = []
var data = []
    $(document).ready(function(){
        /*Render out the bargraphs js*/
        <%graphs.each_with_index do |graph, index|%>

            data[<%=index%>] = $('#chart_<%= graph.id%>').data('data');

            nv.addGraph(function() {
                <%if graph.type == "BarGraph"%>
                    var chart = nv.models.multiBarChart().margin({left: 80, bottom: 30});
                <%else%>
                    var chart = nv.models.lineChart().margin({left: 80, bottom: 30});
                    chart.xAxis
                        .tickFormat(function(d) { return d3.time.format('%H:%M')(new Date(d)); })
                <%end%>

                chart.yAxis
                    .axisLabel('kVA')

                d3.select('#chart_<%= graph.id%>    svg')
                            .datum(data[<%=index%>])
                            .transition()
                            .duration(500)
                            .call(chart);

                nv.utils.windowResize(chart.update);
                graphs[<%=index%>] = chart
                return chart;
            });
        <%end%>

            $('a[data-toggle="tab"]').on('shown', function(e) {
                $.each(graphs, function(index, graph){
                    graph.update()
                })
            })
    })
</script>

<div class="row-fluid">
    <div class="span12">
        <ul class="nav nav-tabs" id="graph_tabs">
            <%graphs.each_with_index do |graph, index|%>
            <li <%= index == 0 ? "class=active" : ''%>>
                <a href="#graph_tab_<%= graph.id%>" data-toggle="tab">
                    <%= graph.description%>
                </a>
            </li>
            <%end%>
        </ul>

        <div class="tab-content">
            <%graphs.each_with_index do |graph, index|%>
                <div id='graph_tab_<%=graph.id%>' class="tab-pane fade <%= index == 0 ? "active in" : ''%>">
                    <%=render "graphs/#{graph.type.downcase}", graph:graph%>
                </div>
            <%end%>
        </div>
    </div>
</div>

The funny bit at the end is a very handy trick to get the graphs to re render when you are using bootstrap tabs otherwise they don't render properly.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...