private void finishPathFragment(final WDataSeries series) { if (this.pathFragment_.getSegments().isEmpty()) { return; } this.painter_.save(); this.painter_.setWorldTransform( new WTransform(this.currentScale_, 0, 0, this.currentScale_, 0, 0)); WTransform currentTransform = new WTransform(1.0 / this.currentScale_, 0, 0, 1.0 / this.currentScale_, 0, 0) .multiply(this.chart_.getZoomRangeTransform()); this.painter_.setPen(new WPen(PenStyle.NoPen)); this.painter_.setBrush(new WBrush(BrushStyle.NoBrush)); this.painter_.setShadow(series.getShadow()); if (series.getMarker() != MarkerType.CrossMarker && series.getMarker() != MarkerType.XCrossMarker && series.getMarker() != MarkerType.AsteriskMarker && series.getMarker() != MarkerType.StarMarker) { this.painter_.setBrush(this.currentBrush_); if (!series.getShadow().isNone()) { this.painter_.drawStencilAlongPath( this.marker_, currentTransform.map(this.pathFragment_), false); } this.painter_.setShadow(new WShadow()); } this.painter_.setPen(this.currentPen_); if (!series.getShadow().isNone()) { this.painter_.setBrush(new WBrush(BrushStyle.NoBrush)); } this.painter_.drawStencilAlongPath( this.marker_, currentTransform.map(this.pathFragment_), false); this.painter_.restore(); this.pathFragment_.assign(new WPainterPath()); }
@Override public void setStroke(Stroke stroke) { BasicStroke basicStroke = (BasicStroke) stroke; PenCapStyle capStyle = PenCapStyle.FlatCap; switch (basicStroke.getEndCap()) { case BasicStroke.CAP_BUTT: capStyle = PenCapStyle.FlatCap; break; case BasicStroke.CAP_ROUND: capStyle = PenCapStyle.RoundCap; break; case BasicStroke.CAP_SQUARE: capStyle = PenCapStyle.SquareCap; break; } PenJoinStyle joinStyle = PenJoinStyle.BevelJoin; switch (basicStroke.getLineJoin()) { case BasicStroke.JOIN_BEVEL: joinStyle = PenJoinStyle.BevelJoin; break; case BasicStroke.JOIN_MITER: joinStyle = PenJoinStyle.MiterJoin; break; case BasicStroke.JOIN_ROUND: joinStyle = PenJoinStyle.RoundJoin; break; } WPen pen = painter.getPen().clone(); pen.setCapStyle(capStyle); pen.setJoinStyle(joinStyle); currentPenStyle = PenStyle.NoPen; if (basicStroke.getLineWidth() > 0) { float[] dashArray = basicStroke.getDashArray(); if (dashArray != null) { if (dashArray.length < 2) currentPenStyle = PenStyle.SolidLine; else if (dashArray.length <= 3) { if (dashArray[0] >= dashArray[1]) currentPenStyle = PenStyle.DashLine; else currentPenStyle = PenStyle.DotLine; } else if (dashArray.length <= 5) currentPenStyle = PenStyle.DashDotLine; else currentPenStyle = PenStyle.DashDotDotLine; } else currentPenStyle = PenStyle.SolidLine; WTransform t = painter.getCombinedTransform(); float width = basicStroke.getLineWidth(); if (!t.isIdentity()) { WTransform.TRSRDecomposition d = new WTransform.TRSRDecomposition(); t.decomposeTranslateRotateScaleRotate(d); width /= (Math.abs(d.sx) + Math.abs(d.sy)) / 2.0; } pen.setWidth(new WLength(width)); } pen.setStyle(currentPenStyle); painter.setPen(pen); }
public void newValue( final WDataSeries series, double x, double y, double stackY, int xRow, int xColumn, int yRow, int yColumn) { if (!Double.isNaN(x) && !Double.isNaN(y)) { WPointF p = this.chart_.map( x, y, series.getAxis(), this.getCurrentXSegment(), this.getCurrentYSegment()); if (!this.marker_.isEmpty()) { WPen pen = series.getMarkerPen().clone(); SeriesIterator.setPenColor( pen, series, xRow, xColumn, yRow, yColumn, ItemDataRole.MarkerPenColorRole); if (this.chart_.isSeriesSelectionEnabled() && this.chart_.getSelectedSeries() != null && this.chart_.getSelectedSeries() != series) { pen.setColor(WCartesianChart.lightenColor(pen.getColor())); } WBrush brush = series.getMarkerBrush().clone(); SeriesIterator.setBrushColor( brush, series, xRow, xColumn, yRow, yColumn, ItemDataRole.MarkerBrushColorRole); double scale = this.calculateMarkerScale(series, xRow, xColumn, yRow, yColumn, series.getMarkerSize()); if (this.chart_.isSeriesSelectionEnabled() && this.chart_.getSelectedSeries() != null && this.chart_.getSelectedSeries() != series) { brush.setColor(WCartesianChart.lightenColor(brush.getColor())); } if (!(this.series_ != null) || !brush.equals(this.currentBrush_) || !pen.equals(this.currentPen_) || scale != this.currentScale_) { if (this.series_ != null) { this.finishPathFragment(this.series_); } this.series_ = series; this.currentBrush_ = brush; this.currentPen_ = pen; this.currentScale_ = scale; } this.pathFragment_.moveTo(this.hv(p)); } if (series.getType() != SeriesType.BarSeries) { WString toolTip = series.getModel().getToolTip(yRow, yColumn); if (!(toolTip.length() == 0)) { if (!(!EnumUtils.mask( series.getModel().flags(yRow, yColumn), ItemFlag.ItemHasDeferredTooltip) .isEmpty() || !EnumUtils.mask(series.getModel().flags(yRow, yColumn), ItemFlag.ItemIsXHTMLText) .isEmpty())) { WTransform t = this.painter_.getWorldTransform(); p = t.map(this.hv(p)); WCircleArea circleArea = new WCircleArea(); circleArea.setCenter(new WPointF(p.getX(), p.getY())); circleArea.setRadius(5); circleArea.setToolTip(toolTip); this.chart_.addDataPointArea(series, xRow, xColumn, circleArea); } else { this.chart_.hasDeferredToolTips_ = true; } } } } }
private AffineTransform toAffineTransform(WTransform t) { return new AffineTransform( t.getM11(), t.getM12(), t.getM21(), t.getM22(), t.getM31(), t.getM32()); }
protected void paintEvent(WPaintDevice paintDevice) { if (!(this.chart_ != null) || !this.chart_.cObjCreated_) { return; } if (this.chart_.getSeries(this.seriesColumn_).getType() != SeriesType.LineSeries && this.chart_.getSeries(this.seriesColumn_).getType() != SeriesType.CurveSeries) { if (this.getMethod() == WPaintedWidget.Method.HtmlCanvas) { StringBuilder ss = new StringBuilder(); ss.append("jQuery.removeData(").append(this.getJsRef()).append(",'sobj');"); ss.append("\nif (") .append(this.getObjJsRef()) .append(") {") .append(this.getObjJsRef()) .append(".canvas.style.cursor = 'auto';") .append("setTimeout(") .append(this.getObjJsRef()) .append(".repaint,0);}\n"); this.doJavaScript(ss.toString()); } logger.error( new StringWriter() .append("WAxisSliderWidget is not associated with a line or curve series.") .toString()); return; } WPainter painter = new WPainter(paintDevice); boolean horizontal = this.chart_.getOrientation() == Orientation.Vertical; double w = horizontal ? this.getWidth().getValue() : this.getHeight().getValue(); double h = horizontal ? this.getHeight().getValue() : this.getWidth().getValue(); boolean autoPadding = this.autoPadding_; if (autoPadding && EnumUtils.mask(paintDevice.getFeatures(), WPaintDevice.FeatureFlag.HasFontMetrics) .equals(0) && this.labelsEnabled_) { logger.error( new StringWriter() .append( "setAutoLayout(): device does not have font metrics (not even server-side font metrics).") .toString()); autoPadding = false; } if (autoPadding) { if (horizontal) { if (this.labelsEnabled_) { this.setSelectionAreaPadding(0, EnumSet.of(Side.Top)); this.setSelectionAreaPadding( (int) (this.chart_ .getAxis(Axis.XAxis) .calcMaxTickLabelSize(paintDevice, Orientation.Vertical) + 10), EnumSet.of(Side.Bottom)); this.setSelectionAreaPadding( (int) Math.max( this.chart_ .getAxis(Axis.XAxis) .calcMaxTickLabelSize(paintDevice, Orientation.Horizontal) / 2, 10.0), EnumSet.of(Side.Left, Side.Right)); } else { this.setSelectionAreaPadding(0, EnumSet.of(Side.Top)); this.setSelectionAreaPadding(5, EnumSet.of(Side.Left, Side.Right, Side.Bottom)); } } else { if (this.labelsEnabled_) { this.setSelectionAreaPadding(0, EnumSet.of(Side.Right)); this.setSelectionAreaPadding( (int) Math.max( this.chart_ .getAxis(Axis.XAxis) .calcMaxTickLabelSize(paintDevice, Orientation.Vertical) / 2, 10.0), EnumSet.of(Side.Top, Side.Bottom)); this.setSelectionAreaPadding( (int) (this.chart_ .getAxis(Axis.XAxis) .calcMaxTickLabelSize(paintDevice, Orientation.Horizontal) + 10), EnumSet.of(Side.Left)); } else { this.setSelectionAreaPadding(0, EnumSet.of(Side.Right)); this.setSelectionAreaPadding(5, EnumSet.of(Side.Top, Side.Bottom, Side.Left)); } } } double left = horizontal ? this.getSelectionAreaPadding(Side.Left) : this.getSelectionAreaPadding(Side.Top); double right = horizontal ? this.getSelectionAreaPadding(Side.Right) : this.getSelectionAreaPadding(Side.Bottom); double top = horizontal ? this.getSelectionAreaPadding(Side.Top) : this.getSelectionAreaPadding(Side.Right); double bottom = horizontal ? this.getSelectionAreaPadding(Side.Bottom) : this.getSelectionAreaPadding(Side.Left); double maxW = w - left - right; WRectF drawArea = new WRectF(left, 0, maxW, h); List<WAxis.Segment> segmentsBak = new ArrayList<WAxis.Segment>(this.chart_.getAxis(Axis.XAxis).segments_); double renderIntervalBak = this.chart_.getAxis(Axis.XAxis).renderInterval_; this.chart_ .getAxis(Axis.XAxis) .prepareRender( horizontal ? Orientation.Horizontal : Orientation.Vertical, drawArea.getWidth()); final WRectF chartArea = this.chart_.chartArea_; WRectF selectionRect = null; { double u = -this.chart_.xTransformHandle_.getValue().getDx() / (chartArea.getWidth() * this.chart_.xTransformHandle_.getValue().getM11()); selectionRect = new WRectF(0, top, maxW, h - (top + bottom)); this.transform_.setValue( new WTransform( 1 / this.chart_.xTransformHandle_.getValue().getM11(), 0, 0, 1, u * maxW, 0)); } WRectF seriesArea = new WRectF(left, top + 5, maxW, h - (top + bottom + 5)); WTransform selectionTransform = this.hv(new WTransform(1, 0, 0, 1, left, 0).multiply(this.transform_.getValue())); WRectF rect = selectionTransform.map(this.hv(selectionRect)); painter.fillRect(this.hv(new WRectF(left, top, maxW, h - top - bottom)), this.background_); painter.fillRect(rect, this.selectedAreaBrush_); final double TICK_LENGTH = 5; final double ANGLE1 = 15; final double ANGLE2 = 80; double tickStart = 0.0; double tickEnd = 0.0; double labelPos = 0.0; AlignmentFlag labelHFlag = AlignmentFlag.AlignCenter; AlignmentFlag labelVFlag = AlignmentFlag.AlignMiddle; final WAxis axis = this.chart_.getAxis(Axis.XAxis); if (horizontal) { tickStart = 0; tickEnd = TICK_LENGTH; labelPos = TICK_LENGTH; labelVFlag = AlignmentFlag.AlignTop; } else { tickStart = -TICK_LENGTH; tickEnd = 0; labelPos = -TICK_LENGTH; labelHFlag = AlignmentFlag.AlignRight; } if (horizontal) { if (axis.getLabelAngle() > ANGLE1) { labelHFlag = AlignmentFlag.AlignRight; if (axis.getLabelAngle() > ANGLE2) { labelVFlag = AlignmentFlag.AlignMiddle; } } else { if (axis.getLabelAngle() < -ANGLE1) { labelHFlag = AlignmentFlag.AlignLeft; if (axis.getLabelAngle() < -ANGLE2) { labelVFlag = AlignmentFlag.AlignMiddle; } } } } else { if (axis.getLabelAngle() > ANGLE1) { labelVFlag = AlignmentFlag.AlignBottom; if (axis.getLabelAngle() > ANGLE2) { labelHFlag = AlignmentFlag.AlignCenter; } } else { if (axis.getLabelAngle() < -ANGLE1) { labelVFlag = AlignmentFlag.AlignTop; if (axis.getLabelAngle() < -ANGLE2) { labelHFlag = AlignmentFlag.AlignCenter; } } } } EnumSet<AxisProperty> axisProperties = EnumSet.of(AxisProperty.Line); if (this.labelsEnabled_) { axisProperties.add(AxisProperty.Labels); } if (horizontal) { axis.render( painter, axisProperties, new WPointF(drawArea.getLeft(), h - bottom), new WPointF(drawArea.getRight(), h - bottom), tickStart, tickEnd, labelPos, EnumSet.of(labelHFlag, labelVFlag)); WPainterPath line = new WPainterPath(); line.moveTo(drawArea.getLeft() + 0.5, h - (bottom - 0.5)); line.lineTo(drawArea.getRight(), h - (bottom - 0.5)); painter.strokePath(line, this.chart_.getAxis(Axis.XAxis).getPen()); } else { axis.render( painter, axisProperties, new WPointF(this.getSelectionAreaPadding(Side.Left) - 1, drawArea.getLeft()), new WPointF(this.getSelectionAreaPadding(Side.Left) - 1, drawArea.getRight()), tickStart, tickEnd, labelPos, EnumSet.of(labelHFlag, labelVFlag)); WPainterPath line = new WPainterPath(); line.moveTo(this.getSelectionAreaPadding(Side.Left) - 0.5, drawArea.getLeft() + 0.5); line.lineTo(this.getSelectionAreaPadding(Side.Left) - 0.5, drawArea.getRight()); painter.strokePath(line, this.chart_.getAxis(Axis.XAxis).getPen()); } WPainterPath curve = new WPainterPath(); { WTransform t = new WTransform(1, 0, 0, 1, seriesArea.getLeft(), seriesArea.getTop()) .multiply( new WTransform( seriesArea.getWidth() / chartArea.getWidth(), 0, 0, seriesArea.getHeight() / chartArea.getHeight(), 0, 0)) .multiply(new WTransform(1, 0, 0, 1, -chartArea.getLeft(), -chartArea.getTop())); if (!horizontal) { t.assign( new WTransform( 0, 1, 1, 0, this.getSelectionAreaPadding(Side.Left) - this.getSelectionAreaPadding(Side.Right) - 5, 0) .multiply(t) .multiply(new WTransform(0, 1, 1, 0, 0, 0))); } curve.assign(t.map(this.chart_.pathForSeries(this.seriesColumn_))); } { WRectF leftHandle = this.hv(new WRectF(-5, top, 5, h - top - bottom)); WTransform t = new WTransform(1, 0, 0, 1, left, -top) .multiply( new WTransform() .translate(this.transform_.getValue().map(selectionRect.getTopLeft()))); painter.fillRect(this.hv(t).map(leftHandle), this.handleBrush_); } { WRectF rightHandle = this.hv(new WRectF(0, top, 5, h - top - bottom)); WTransform t = new WTransform(1, 0, 0, 1, left, -top) .multiply( new WTransform() .translate(this.transform_.getValue().map(selectionRect.getTopRight()))); painter.fillRect(this.hv(t).map(rightHandle), this.handleBrush_); } if (this.selectedSeriesPen_ != this.seriesPen_ && !this.selectedSeriesPen_.equals(this.seriesPen_)) { WPainterPath clipPath = new WPainterPath(); clipPath.addRect(this.hv(selectionRect)); painter.setClipPath(selectionTransform.map(clipPath)); painter.setClipping(true); painter.setPen(this.getSelectedSeriesPen()); painter.drawPath(curve); WPainterPath leftClipPath = new WPainterPath(); leftClipPath.addRect( this.hv(new WTransform(1, 0, 0, 1, -selectionRect.getWidth(), 0).map(selectionRect))); painter.setClipPath( this.hv( new WTransform(1, 0, 0, 1, left, -top) .multiply( new WTransform() .translate( this.transform_.getValue().map(selectionRect.getTopLeft())))) .map(leftClipPath)); painter.setPen(this.getSeriesPen()); painter.drawPath(curve); WPainterPath rightClipPath = new WPainterPath(); rightClipPath.addRect( this.hv(new WTransform(1, 0, 0, 1, selectionRect.getWidth(), 0).map(selectionRect))); painter.setClipPath( this.hv( new WTransform(1, 0, 0, 1, left - selectionRect.getRight(), -top) .multiply( new WTransform() .translate( this.transform_.getValue().map(selectionRect.getTopRight())))) .map(rightClipPath)); painter.drawPath(curve); painter.setClipping(false); } else { painter.setPen(this.getSeriesPen()); painter.drawPath(curve); } if (this.getMethod() == WPaintedWidget.Method.HtmlCanvas) { WApplication app = WApplication.getInstance(); StringBuilder ss = new StringBuilder(); ss.append("new Wt3_3_5.WAxisSliderWidget(") .append(app.getJavaScriptClass()) .append(",") .append(this.getJsRef()) .append(",") .append(this.getObjJsRef()) .append(",") .append("{chart:") .append(this.chart_.getCObjJsRef()) .append(",transform:") .append(this.transform_.getJsRef()) .append(",rect:function(){return ") .append(rect.getJsRef()) .append("},drawArea:") .append(drawArea.getJsRef()) .append(",series:") .append(this.seriesColumn_) .append("});"); this.doJavaScript(ss.toString()); } Utils.copyList(segmentsBak, this.chart_.getAxis(Axis.XAxis).segments_); this.chart_.getAxis(Axis.XAxis).renderInterval_ = renderIntervalBak; }