PlotLayoutSVG constructor

PlotLayoutSVG(DivElement plotDiv, bool withCanvas)

Creates a plot layout to be contained in plotDiv. For additional 2D html drawings contourCanvas is created if withCanvas is true.

Implementation

PlotLayoutSVG(this.plotDiv, bool withCanvas) {
  // will contain the entire plot
  plotAreaRect = math.Rectangle<int>(
      borderAreaSize,
      borderAreaSize,
      plotDiv.clientWidth - 2 * borderAreaSize,
      plotDiv.clientHeight - 2 * borderAreaSize);

  // all coordinates in the following rectangles are are relative to plotRect
  dataInsets = math.Rectangle<int>(borderAreaSize, borderAreaSize, 0, 0);

  // will contain the polylines and the legend
  dataAreaRect = math.Rectangle<int>(
      yaxAreaWidth,
      dataInsets.top,
      plotAreaRect.width - yaxAreaWidth - dataInsets.left,
      plotAreaRect.height - xaxAreaHeight);

  // will contain the x axis tic marks and text labels
  xaxisRect = math.Rectangle<int>(
      dataAreaRect.left,
      dataAreaRect.top + dataAreaRect.height,
      dataAreaRect.width,
      xaxAreaHeight);

  // will contain the y axis tic marks and text labels
  yaxisRect = math.Rectangle<int>(dataAreaRect.left - yaxAreaWidth,
      dataAreaRect.top, yaxAreaWidth, dataAreaRect.height);

  // will contain all axes and the data area (polylines and legend)
  plotArea = SvgSvgElement();
  SVG.setAttr(plotArea, {
    SVG.WIDTH: "${plotAreaRect.width}",
    SVG.HEIGHT: "${plotAreaRect.height}",
  });

  // will contain polylines and legend
  dataArea = SvgSvgElement();
  SVG.setAttr(dataArea, {
    SVG.X: "${dataAreaRect.left}",
    SVG.Y: "${dataAreaRect.top}",
    SVG.WIDTH: "${dataAreaRect.width}",
    SVG.HEIGHT: "${dataAreaRect.height}",
  });

  // a border around the data area
  dataAreaBorder = RectElement();
  SVG.setAttr(dataAreaBorder, {
    SVG.X: "${dataAreaRect.left}",
    SVG.Y: "${dataAreaRect.top}",
    SVG.WIDTH: "${dataAreaRect.width}",
    SVG.HEIGHT: "${dataAreaRect.height}",
    SVG.FILL: "none",
    SVG.STROKE: "darkgreen",
    SVG.STROKE_WIDTH: "2"
  });

  if (withCanvas) {
    // Put the first contour in its own canvas. More canvases needed for more contours!
    contourCanvas =
        CanvasElement(width: plotAreaRect.width, height: plotAreaRect.height);
    contourCanvas.style
      ..left = "0px" // could be omitted, 0 is default
      ..top = "0px"
      ..position = "absolute"
      ..backgroundColor = "transparent"
      // pointerEvents = none means: The canvas will not catch mouse or touch events. Instead, the
      // events pass through to the parent, which is plotDiv. There, all events are catched and treated.
      // NOTE: pointerEvents is still experimental, test on all devices!
      // If not working, event leisteners must be directly attached to the canvas and be delegated to the
      // central treatment from there, which is a little more laborious!
      ..pointerEvents = "none";
  }

  // now stack the plot containers.
  // needed to position 2d canvas and its contents properly:
  plotDiv.style.position = "relative";
  plotArea.append(dataArea);
  plotArea.append(dataAreaBorder); // draw above dataArea
  // add canvas before plotArea, so plotArea will be above it
  if (contourCanvas != null) {
    plotDiv.append(contourCanvas);
  }
  plotDiv.append(plotArea);
}