⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stackedcylinderrenderer.java

📁 加入Jfreechart1.05直接运行即可.(立体圆柱表示水位效果)使用Jfreechart实现的层叠圆柱体效果.
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
				if (baseIndex < 0)
				{
					result.add(new Object[] { null, new Double(base) });
					baseIndex = 0;
				}
				negBase = negBase + v; // '+' because v is negative
				result.add(0, new Object[] { new Integer(-s),
						new Double(negBase) });
				baseIndex++;
			}
		}
//		System.out.println("this StackedCylinder createStackedValueList.");
		return result;

	}

	/**
	 * Draws the visual representation of one data item from the chart (in fact,
	 * this method does nothing until it reaches the last item for each
	 * category, at which point it draws all the items for that category).
	 * 
	 * @param g2
	 *            the graphics device.
	 * @param state
	 *            the renderer state.
	 * @param dataArea
	 *            the plot area.
	 * @param plot
	 *            the plot.
	 * @param domainAxis
	 *            the domain (category) axis.
	 * @param rangeAxis
	 *            the range (value) axis.
	 * @param dataset
	 *            the data.
	 * @param row
	 *            the row index (zero-based).
	 * @param column
	 *            the column index (zero-based).
	 * @param pass
	 *            the pass index.
	 */
	public void drawItem(
			Graphics2D g2, 
			CategoryItemRendererState state, //An object that retains temporary state information for a CategoryItemRenderer
			Rectangle2D dataArea, 
			CategoryPlot plot, 
			CategoryAxis domainAxis,
			ValueAxis rangeAxis, 
			CategoryDataset dataset, 
			int row, 
			int column,
			int pass)
	{
		// wait till we are at the last item for the row then draw the
		// whole stack at once
		if (row < dataset.getRowCount() - 1)
		{
			return;
		}
		Comparable category = dataset.getColumnKey(column);  //列主键

		List values = createStackedValueList(
				dataset, 
				dataset.getColumnKey(column),//列主键 
				getBase(), //基线
				this.renderAsPercentages);//列百分比标志

		Rectangle2D adjusted = new Rectangle2D.Double(
				dataArea.getX(), 
				dataArea.getY()	+ getYOffset(), 
				dataArea.getWidth() - getXOffset(), 
				dataArea.getHeight() - getYOffset());

		PlotOrientation orientation = plot.getOrientation();

		// handle rendering separately for the two plot orientations...
		if (orientation == PlotOrientation.HORIZONTAL)
		{
			drawStackHorizontal(values, category, g2, state, adjusted, plot,
					domainAxis, rangeAxis, dataset);
		} else
		{
			drawStackVertical(values, category, g2, state, adjusted, plot,
					domainAxis, rangeAxis, dataset);
		}

	}

	/**
	 * Draws a stack of bars for one category, with a horizontal orientation.
	 * 
	 * @param values
	 *            the value list.
	 * @param category
	 *            the category.
	 * @param g2
	 *            the graphics device.
	 * @param state
	 *            the state.  //An object that retains temporary state information for a CategoryItemRenderer
	 * @param dataArea
	 *            the data area (adjusted for the 3D effect).
	 * @param plot
	 *            the plot.
	 * @param domainAxis
	 *            the domain axis.
	 * @param rangeAxis
	 *            the range axis.
	 * @param dataset
	 *            the dataset.
	 * 
	 * @since 1.0.4
	 */
	protected void drawStackHorizontal(
			List values, 
			Comparable category, //列主键
			Graphics2D g2, 
			CategoryItemRendererState state,
			Rectangle2D dataArea, 
			CategoryPlot plot, 
			CategoryAxis domainAxis,
			ValueAxis rangeAxis, 
			CategoryDataset dataset)
	{
		System.out.println("into the StackedCylinder drawStackHorizontal.");

		int column = dataset.getColumnIndex(category);
		
		/**
		 * CategoryAxis  //An axis that displays categories. 
		 * CategoryAxis.getCategoryMiddle() //Returns the middle coordinate for the specified category.
		 */
		double barX0 = domainAxis.getCategoryMiddle(column, dataset
				.getColumnCount(), dataArea, plot.getDomainAxisEdge())
				- state.getBarWidth() / 2.0;  //获取中间坐标减去宽度的一半,回到开始x坐标
		double barW = state.getBarWidth();

		// a list to store the series index and bar region, so we can draw
		// all the labels at the end...
		List itemLabelList = new ArrayList();

		// draw the blocks
		boolean inverted = rangeAxis.isInverted();
		int blockCount = values.size() - 1; //一列的分块总数
		for (int k = 0; k < blockCount; k++)
		{
			int index = (inverted ? blockCount - k - 1 : k);
			Object[] prev = (Object[]) values.get(index);
			Object[] curr = (Object[]) values.get(index + 1);
			int series = 0;
			if (curr[0] == null)
			{
				series = -((Integer) prev[0]).intValue();
			} 
			else
			{
				series = ((Integer) curr[0]).intValue();
				if (series < 0)
				{
					series = -((Integer) prev[0]).intValue();
				}
			}
			
			
			/**
			 * ValueAxis.valueToJava2D
			 * Converts a data value to a coordinate in Java2D space, 
			 * assuming that the axis runs along one edge of the specified dataArea.
			 * 前一个坐标 List values[] have Object[](index,基线值+stackValue)
			 */
			double v0 = ((Double) prev[1]).doubleValue();
			double vv0 = rangeAxis.valueToJava2D(v0, dataArea, plot
					.getRangeAxisEdge());

			double v1 = ((Double) curr[1]).doubleValue();
			double vv1 = rangeAxis.valueToJava2D(v1, dataArea, plot
					.getRangeAxisEdge());

			
			Shape[] faces = createHorizontalBlock(barX0, barW, vv0, vv1,
					inverted);//x轴开始坐标,bar宽度,
			
//			Shape[] faces =  createHorizontalBlockCylinded(barX0, barW, vv0, vv1);
			
			
			/**
			 * getItemPaint(int row, int column) //extends class AbstractRenderer 
			 * Returns the paint used to fill data items as they are drawn.
			 */
			Paint fillPaint = getItemPaint(series, column);
			Paint outlinePaint = getItemOutlinePaint(series, column);
			g2.setStroke(getItemOutlineStroke(series, column));

			for (int f = 0; f < 6; f++)  //draw cubical six faces
			{
				g2.setPaint(fillPaint);
				g2.fill(faces[f]);
				g2.setPaint(outlinePaint);
				g2.draw(faces[f]);
			}

			/**
			 * GeneralPath.getBoundes2D()
			 * Returns the bounding box of the path
			 * faces[5] is front
			 */
			itemLabelList.add(new Object[] { new Integer(series),
					faces[5].getBounds2D(),
					BooleanUtilities.valueOf(v0 < getBase()) });

			// add an item entity, if this information is being collected
			EntityCollection entities = state.getEntityCollection();
			if (entities != null)
			{
				addItemEntity(entities, dataset, series, column, faces[5]);
			}

		}

		/**
		 * itemLableList storage every block information
		 */
		for (int i = 0; i < itemLabelList.size(); i++)
		{
			Object[] record = (Object[]) itemLabelList.get(i);
			int series = ((Integer) record[0]).intValue();
			Rectangle2D bar = (Rectangle2D) record[1];
			boolean neg = ((Boolean) record[2]).booleanValue(); //is negative
			// getItemLabelGenerator(int row, int column) 
			// Returns the item label generator for a data item.
			CategoryItemLabelGenerator generator = getItemLabelGenerator(
					series, column);
			if (generator != null && isItemLabelVisible(series, column))
			{
				drawItemLabel(g2, dataset, series, column, plot, generator,
						bar, neg);
			}

		}
	}
	

	/**
	 * Creates an array of shapes representing the six sides of a block in a
	 * horizontal stack.
	 * 
	 * @param x0
	 *            left edge of bar (in Java2D space).
	 * @param width
	 *            the width of the bar (in Java2D units).
	 * @param y0
	 *            the base of the block (in Java2D space).
	 * @param y1
	 *            the top of the block (in Java2D space).
	 * @param inverted
	 *            a flag indicating whether or not the block is inverted (this
	 *            changes the order of the faces of the block).
	 * 
	 * @return The sides of the block.
	 */
	private Shape[] createHorizontalBlock(double x0, double width, double y0,
			double y1, boolean inverted)// x轴开始坐标,bar宽度,前一个y轴基线点,当前y轴基线点
	{
		Shape[] result = new Shape[6];
		
		/**
		 * Point2D : The Double class defines a point specified in double precision.
		 * The Point2D class defines a point representing a location in (x, y) coordinate space.
		 * This class is only the abstract superclass for all objects that store a 2D coordinate. 
		 * The actual storage representation of the coordinates is left to the subclass.
		 */
		Point2D p00 = new Point2D.Double(y0, x0);
		Point2D p01 = new Point2D.Double(y0, x0 + width);
		Point2D p02 = new Point2D.Double(p01.getX() + getXOffset(), p01.getY()
				- getYOffset());
		Point2D p03 = new Point2D.Double(p00.getX() + getXOffset(), p00.getY()
				- getYOffset());

		Point2D p0 = new Point2D.Double(y1, x0);
		Point2D p1 = new Point2D.Double(y1, x0 + width);
		Point2D p2 = new Point2D.Double(p1.getX() + getXOffset(), p1.getY()
				- getYOffset());
		Point2D p3 = new Point2D.Double(p0.getX() + getXOffset(), p0.getY()
				- getYOffset());

		/**
		 * The GeneralPath class represents a geometric path 
		 * constructed from straight lines, and quadratic 
		 * and cubic (Bézier) curves. It can contain multiple subpaths.
		 */
		GeneralPath bottom = new GeneralPath();  //底部
		bottom.moveTo((float) p1.getX(), (float) p1.getY());
		bottom.lineTo((float) p01.getX(), (float) p01.getY());
		bottom.lineTo((float) p02.getX(), (float) p02.getY());
		bottom.lineTo((float) p2.getX(), (float) p2.getY());
		bottom.closePath();

		GeneralPath top = new GeneralPath();  //顶部
		top.moveTo((float) p0.getX(), (float) p0.getY());
		top.lineTo((float) p00.getX(), (float) p00.getY());
		top.lineTo((float) p03.getX(), (float) p03.getY());
		top.lineTo((float) p3.getX(), (float) p3.getY());
		top.closePath();

		GeneralPath back = new GeneralPath();  //
		back.moveTo((float) p2.getX(), (float) p2.getY());
		back.lineTo((float) p02.getX(), (float) p02.getY());
		back.lineTo((float) p03.getX(), (float) p03.getY());
		back.lineTo((float) p3.getX(), (float) p3.getY());
		back.closePath();

		GeneralPath front = new GeneralPath();
		front.moveTo((float) p0.getX(), (float) p0.getY());
		front.lineTo((float) p1.getX(), (float) p1.getY());
		front.lineTo((float) p01.getX(), (float) p01.getY());
		front.lineTo((float) p00.getX(), (float) p00.getY());
		front.closePath();

		GeneralPath left = new GeneralPath();
		left.moveTo((float) p0.getX(), (float) p0.getY());
		left.lineTo((float) p1.getX(), (float) p1.getY());
		left.lineTo((float) p2.getX(), (float) p2.getY());
		left.lineTo((float) p3.getX(), (float) p3.getY());
		left.closePath();

		GeneralPath right = new GeneralPath();
		right.moveTo((float) p00.getX(), (float) p00.getY());
		right.lineTo((float) p01.getX(), (float) p01.getY());
		right.lineTo((float) p02.getX(), (float) p02.getY());
		right.lineTo((float) p03.getX(), (float) p03.getY());
		right.closePath();
		
		
		result[0] = bottom;
		result[1] = back;
		if (inverted)
		{
			result[2] = right;
			result[3] = left;
		} else
		{
			result[2] = left;
			result[3] = right;
		}
		result[4] = top;
		result[5] = front;
		return result;
	}

	/**
	 * Draws a stack of bars for one category, with a vertical orientation.
	 * 
	 * @param values
	 *            the value list.
	 * @param category
	 *            the category.
	 * @param g2
	 *            the graphics device.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -