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); }
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); }
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, ")"); }
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(); }
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, ")"); }
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(); }
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); } }
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(); }
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) + ")"); }