Beispiel #1
0
 private void defineBar(String basicDef, ElementDefinition elementDef) {
   if (vis.fRange != null || vis.stacked) {
     // Stacked or range element goes from higher of the pair of values to the lower
     out.add("var y0 =", elementDef.y.left).endStatement();
     out.add("var y1 =", elementDef.y.right).endStatement();
     defineHorizontalExtentFunctions(elementDef, true);
     out.add(basicDef);
     out.addChained("attr('y', function(d) { return Math.min(y0(d), y1(d)) } )");
     out.addChained("attr('height', function(d) {return Math.abs(y0(d) - y1(d)) })");
   } else {
     // Simple element; drop from the upper value to the baseline
     out.add("var y =", elementDef.y.center).endStatement();
     defineHorizontalExtentFunctions(elementDef, true);
     out.add(basicDef);
     if (vis.coords == VisTypes.Coordinates.transposed) {
       out.addChained("attr('y', 0)")
           .addChained("attr('height', function(d) { return Math.max(0,y(d)) })");
     } else {
       out.addChained("attr('y', y)")
           .addChained(
               "attr('height', function(d) {return Math.max(0,geom.inner_height - y(d)) }) ");
     }
   }
   defineHorizontalExtent(elementDef);
 }
Beispiel #2
0
 private void defineText(String basicDef, ElementDefinition elementDef) {
   out.add(basicDef);
   out.addChained("attr('x'," + elementDef.x.center + ")");
   out.addChained("attr('y'," + elementDef.y.center + ")");
   out.addChained("attr('dy', '0.35em').text(labeling.content)");
   labelBuilder.addFontSizeAttribute(vis);
 }
Beispiel #3
0
 private void defineVerticalExtent(ElementDefinition elementDef) {
   String top, height;
   if (elementDef.y.left != null) {
     // Use the left and right values
     top = "function(d) { return Math.min(y0(d), y1(d)) }";
     height = "function(d) { return Math.abs(y1(d) - y0(d)) }";
   } else {
     // The height can either be a function or a numeric value
     if (elementDef.y.size.startsWith("function")) top = "function(d) { return y(d) - h(d)/2 }";
     else top = "function(d) { return y(d) - h/2 }";
     height = "h";
   }
   out.addChained("attr('y', ", top, ")");
   out.addChained("attr('height', ", height, ")");
 }
Beispiel #4
0
 private void writeCoordEnter() {
   // Added rounded styling if needed
   ModelUtil.Size size = ModelUtil.getRoundRectangleRadius(vis);
   if (size != null)
     out.addChained(
             "attr('rx'," + size.valueInPixels(8) + ").attr('ry', " + size.valueInPixels(8) + ")")
         .ln();
   out.endStatement().onNewLine().ln();
 }
Beispiel #5
0
  private void defineHorizontalExtent(ElementDefinition elementDef) {
    String left, width;
    if (elementDef.x.left != null) {
      // Use the left and right values
      left = "function(d) { return Math.min(x0(d), x1(d)) }";
      width = "function(d) { return Math.abs(x1(d) - x0(d)) }";
    } else {
      // The width can either be a function or a numeric value
      if (elementDef.x.size.startsWith("function")) left = "function(d) { return x(d) - w(d)/2 }";
      else left = "function(d) { return x(d) - w/2 }";
      width = "w";
    }
    out.addChained("attr('x', ", left, ")");

    // Sadly, browsers are inconsistent in how they handle width. It can be considered either a
    // style or a
    // positional attribute, so we need to specify as both to make all browsers happy
    out.addChained("attr('width', ", width, ")");
    out.addChained("style('width', ", width, ")");
  }
Beispiel #6
0
  private void definePathsAndSplits(ElementDefinition elementDef) {

    // Define y or (y0, y1)
    defineVerticalExtentFunctions(elementDef, false);

    // First deal with the case of wedges (polar intervals)
    if (vis.tElement == VisTypes.Element.bar && vis.coords == VisTypes.Coordinates.polar) {
      out.add("var path = d3.svg.arc().outerRadius(geom.inner_radius).innerRadius(0)").ln();
      out.addChained("outerRadius(geom.inner_radius).innerRadius(0)").ln();
      if (vis.fRange == null && !vis.stacked) out.addChained("startAngle(0).endAngle(y)");
      else out.addChained("startAngle(y0).endAngle(y1)");
      out.endStatement();
      return;
    }

    // Now actual paths

    // Define the x function
    out.add("var x =", elementDef.x.center).endStatement();

    if (vis.tElement == VisTypes.Element.area) {
      if (vis.fRange == null && !vis.stacked)
        out.add("var path = d3.svg.area().x(x).y1(y).y0(function(d) { return scale_y(0) })");
      else out.add("var path = d3.svg.area().x(x).y1(y1).y0(y0)");
    } else if (vis.tElement.producesSingleShape) {
      // Choose the top line if there is a range (say for stacking)
      String yDef = elementDef.y.right == null ? "y" : "y1";
      if (vis.fSize.size() == 1) {
        out.add("var path = BrunelD3.sizedPath().x(x).y(" + yDef + ")");
        String size = elementDef.y.size != null ? elementDef.y.size : elementDef.overallSize;
        out.addChained("r(" + size + ")");
      } else {
        out.add("var path = d3.svg.line().x(x).y(" + yDef + ")");
      }
    }
    if (vis.tUsing == VisTypes.Using.interpolate) {
      out.add(".interpolate()");
    }
    out.endStatement();
    constructSplitPath();
  }
Beispiel #7
0
  private void writeCoordinateLabelingAndAesthetics(ElementDetails details) {
    // Define colors using the color function
    if (!vis.fColor.isEmpty()) out.addChained("style(" + details.colorAttribute + ", color)");

    // Define line width if needed
    if (details.needsStrokeSize) out.addChained("style('stroke-width', size)");

    // Define opacity
    if (!vis.fOpacity.isEmpty()) {
      out.addChained("style('fill-opacity', opacity)")
          .addChained("style('stroke-opacity', opacity)");
    }

    out.endStatement();

    labelBuilder.addTooltips(details);

    // We do not add labels if the element IS a label
    if (labelBuilder.needed() && vis.tElement != VisTypes.Element.text) {
      labelBuilder.addLabels(details);
    }
  }
Beispiel #8
0
  public void generate() {

    if (diagram != null) out.onNewLine().comment("Data structures for a", vis.tDiagram, "diagram");

    ElementDetails details = makeDetails(); // Create the details of what the element should be
    ElementDefinition elementDef = buildElementDefinition(); // And the coordinate definitions

    // Define paths needed in the element, and make data splits
    if (details.producesPath) definePathsAndSplits(elementDef);

    if (labelBuilder.needed())
      labelBuilder.defineLabeling(details, vis.itemsLabel, false); // Labels

    modifyGroupStyleName(); // Diagrams change the name so CSS style sheets will work well

    // Define the data and main element into which shapes will be placed
    out.add("var d3Data =", details.dataSource).endStatement();

    out.add("var element = main.selectAll('*').data(d3Data,", getKeyFunction(), ")").endStatement();

    // Define what happens when data is added ('enter')
    out.add("element.enter().append('" + details.elementType + "')");
    out.add(".attr('class', ", details.classes, ")");

    if (diagram != null) diagram.writeDiagramEnter();
    else writeCoordEnter();

    // When data changes (including being added) update the items
    // These fire for both 'enter' and 'update' data

    if (diagram != null) {
      out.add("BrunelD3.trans(element,transitionMillis)");
      diagram.writeDefinition(details);
    } else {
      writeCoordinateDefinition(details, elementDef);
      writeCoordinateLabelingAndAesthetics(details);
    }

    // This fires when items leave the system
    out.onNewLine().ln().add("BrunelD3.trans(element.exit(),transitionMillis/3)");
    out.addChained("style('opacity', 0.5).remove()").endStatement();
  }
Beispiel #9
0
 private void defineCircle(String basicDef, ElementDefinition elementDef) {
   out.add(basicDef);
   out.addChained("attr('cx'," + elementDef.x.center + ")");
   out.addChained("attr('cy'," + elementDef.y.center + ")");
   out.addChained("attr('r'," + halve(elementDef.overallSize) + ")");
 }