Search code examples
javascriptjsf-2primefacesd3.jsliferay-6

Is there a trick to using d3 charts in jsf?


I am using Prime Faces in Liferay, What is the trick to getting the D3 examples to show up in jsf land specifically Prime Faces on Liferay. The example I am trying to make work in JSF is this one: How would d3.js difference chart example work with json data?


Solution

  • I figured it out. The trick is to reference a div element instead of body. All of the examples I have seen use "body".In a portal container you don't want to use body as that will put you outside of your port let. A div is required and must be referenced as in the javascript. I have included the new code below

        <%@ page import="javax.portlet.WindowState" %>
        <%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %>
        <%@ taglib uri="http://alloy.liferay.com/tld/aui" prefix="aui" %>
    
    
        <portlet:defineObjects />
    
        <form action="<portlet:actionURL />" method="post" name="<portlet:namespace />fm">
        <div id="svgContainer" ></div>
        <script type="text/javascript" >
        var margin = {top: 20, right: 20, bottom: 30, left: 50},
            width = 960 - margin.left - margin.right,
            height = 500 - margin.top - margin.bottom;
    
        var parseDate = d3.time.format("%Y%m%d").parse;
    
        var x = d3.time.scale()
            .range([0, width]);
    
        var y = d3.scale.linear()
            .range([height, 0]);
    
        var xAxis = d3.svg.axis()
            .scale(x)
            .orient("bottom");
    
        var yAxis = d3.svg.axis()
            .scale(y)
            .orient("left");
    
        var line = d3.svg.area()
            .interpolate("basis")
            .x(function(d) { return x(d.date); })
            .y(function(d) { return y(d["student"]); });
    
        var area = d3.svg.area()
            .interpolate("basis")
            .x(function(d) { return x(d.date); })
            .y1(function(d) { return y(d["student"]); });
    
        var svg = d3.select("#svgContainer").append("svg")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + margin.top + margin.bottom)
          .append("g")
            .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
        var count =0;
    
        d3.json("<%=request.getContextPath()%>/data/data.json", function(error, data) {
          if(error) return console.warn(error);
              data.data.forEach(function(d) {
                d.date = parseDate(d.date);
                d["student"]= +d["student"];
                d["average"] = +d["average"];
                count++;
    
              });
    
          x.domain(d3.extent(data.data, function(d) { return d.date; }));
    
          y.domain([
            d3.min(data.data, function(d) { return Math.min(d["student"], d["average"]); }),
            d3.max(data.data, function(d) { return Math.max(d["student"], d["average"]); })
          ]);
    
          svg.datum(data.data);
    
          svg.append("clipPath")
              .attr("id", "clip-below")
            .append("path")
              .attr("d", area.y0(height));
    
          svg.append("clipPath")
              .attr("id", "clip-above")
            .append("path")
              .attr("d", area.y0(0));
    
          svg.append("path")
              .attr("class", "area above")
              .attr("clip-path", "url(#clip-above)")
              .attr("d", area.y0(function(d) { return y(d["average"]); }));
    
          svg.append("path")
              .attr("class", "area below")
              .attr("clip-path", "url(#clip-below)")
              .attr("d", area);
    
          svg.append("path")
              .attr("class", "line")
              .attr("d", line);
    
          svg.append("g")
              .attr("class", "x axis")
              .attr("transform", "translate(0," + height + ")")
              .call(xAxis);
    
          svg.append("g")
              .attr("class", "y axis")
              .call(yAxis)
            .append("text")
              .attr("transform", "rotate(-90)")
              .attr("y", 6)
              .attr("dy", ".71em")
              .style("text-anchor", "end")
              .text("Grades");
        });
    
    
    
        </script>
        </form>