求教高手如何java绘画出一条趋势线?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求教高手如何java绘画出一条趋势线?相关的知识,希望对你有一定的参考价值。

尝试用JFreeChart 画,没画出来,又想jxl或poi调Excel里的方法画,不知道有没有相关的方法,求教高人。

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Stroke;
import java.awt.event.ComponentEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Arc2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.Rectangle2D;

import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Charts2D extends JFrame

public Charts2D()
super("2D Charts");
setSize(720, 280);
getContentPane().setLayout(new GridLayout(1, 3, 10, 0));
getContentPane().setBackground(Color.white);

int[] xData = new int[8];
int[] yData = new int[8];
for (int i = 0; i < xData.length; i++)
xData[i] = i;
yData[i] = (int) (Math.random() * 100);
if (i > 0)
yData[i] = (yData[i - 1] + yData[i]) / 2;


JChart2D chart = new JChart2D(JChart2D.LineChart, xData.length, xData, yData,
"Line Chart");
chart.setStroke(new BasicStroke(5f, BasicStroke.CAP_ROUND,
BasicStroke.JOIN_MITER));
chart.setLineColor(new Color(0, 28, 28));
getContentPane().add(chart);

chart = new JChart2D(JChart2D.ColumnChart, xData.length, xData, yData,
"Column Chart");
GradientPaint gp = new GradientPaint(0, 100, Color.white, 0, 300,
Color.blue, true);
chart.setGradient(gp);
chart.setEffectIndex(JChart2D.Gradientffect);
chart.setDrawShadow(true);
getContentPane().add(chart);

chart = new JChart2D(JChart2D.PieChart, xData.length, xData, yData,
"Pie Chart");
ImageIcon icon = new ImageIcon("largeJava2slogo.GIF");
chart.setForegroundImage(icon.getImage());
chart.setEffectIndex(JChart2D.ImageEffect);
chart.setDrawShadow(true);
getContentPane().add(chart);

WindowListener wndCloser = new WindowAdapter()
public void windowClosing(WindowEvent e)
System.exit(0);

;
addWindowListener(wndCloser);

setVisible(true);


public static void main(String argv[])
new Charts2D();




class JChart2D extends JPanel
public static final int LineChart = 0;

public static final int ColumnChart = 1;

public static final int PieChart = 2;

public static final int PLainEffect = 0;

public static final int Gradientffect = 1;

public static final int ImageEffect = 2;

protected int m_chartType = LineChart;

protected JLabel titleLabel;

protected ChartPanel chartPanel;

protected int dataLength;

protected int[] xData;

protected int[] yData;

protected int xMin;

protected int xMax;

protected int yMin;

protected int yMax;

protected double[] pieData;

protected int m_effectIndex = PLainEffect;

protected Stroke stroke;

protected GradientPaint gradient;

protected Image foregroundImage;

protected Color lineColor = Color.black;

protected Color columnColor = Color.blue;

protected int columnWidth = 12;

protected boolean drawShadow = false;

public JChart2D(int type, int nData, int[] yData, String text)
this(type, nData, null, yData, text);


public JChart2D(int type, int nData, int[] xD, int[] yD, String text)
super(new BorderLayout());
setBackground(Color.white);
titleLabel = new JLabel(text, JLabel.CENTER);
add(titleLabel, BorderLayout.NORTH);

m_chartType = type;

if (xData == null)
xData = new int[nData];
for (int k = 0; k < nData; k++)
xData[k] = k;

if (yD == null)
throw new IllegalArgumentException("yData can't be null");
if (nData > yD.length)
throw new IllegalArgumentException("Insufficient yData length");
if (nData > xD.length)
throw new IllegalArgumentException("Insufficient xData length");
dataLength = nData;
xData = xD;
yData = yD;

xMin = xMax = 0; // To include 0 into the interval
yMin = yMax = 0;
for (int k = 0; k < dataLength; k++)
xMin = Math.min(xMin, xData[k]);
xMax = Math.max(xMax, xData[k]);
yMin = Math.min(yMin, yData[k]);
yMax = Math.max(yMax, yData[k]);

if (xMin == xMax)
xMax++;
if (yMin == yMax)
yMax++;

if (m_chartType == PieChart)
double sum = 0;
for (int k = 0; k < dataLength; k++)
yData[k] = Math.max(yData[k], 0);
sum += yData[k];

pieData = new double[dataLength];
for (int k = 0; k < dataLength; k++)
pieData[k] = yData[k] * 360.0 / sum;


chartPanel = new ChartPanel();
add(chartPanel, BorderLayout.CENTER);


public void setEffectIndex(int effectIndex)
m_effectIndex = effectIndex;
repaint();


public int getEffectIndex()
return m_effectIndex;


public void setStroke(Stroke s)
stroke = s;
chartPanel.repaint();


public void setForegroundImage(Image img)
foregroundImage = img;
repaint();


public Image getForegroundImage()
return foregroundImage;


public Stroke getStroke()
return stroke;


public void setGradient(GradientPaint g)
gradient = g;
repaint();


public GradientPaint getGradient()
return gradient;


public void setColumnWidth(int c)
columnWidth = c;
chartPanel.calcDimensions();
chartPanel.repaint();


public int setColumnWidth()
return columnWidth;


public void setColumnColor(Color c)
columnColor = c;
chartPanel.repaint();


public Color getColumnColor()
return columnColor;


public void setLineColor(Color c)
lineColor = c;
chartPanel.repaint();


public Color getLineColor()
return lineColor;


public void setDrawShadow(boolean d)
drawShadow = d;
chartPanel.repaint();


public boolean getDrawShadow()
return drawShadow;


class ChartPanel extends JComponent
int xMargin = 5;

int yMargin = 5;

int pieGap = 10;

int m_x;

int m_y;

int m_w;

int m_h;

ChartPanel()
enableEvents(ComponentEvent.COMPONENT_RESIZED);


protected void processComponentEvent(ComponentEvent e)
calcDimensions();


public void calcDimensions()
Dimension d = getSize();
m_x = xMargin;
m_y = yMargin;
m_w = d.width - 2 * xMargin;
m_h = d.height - 2 * yMargin;
if (m_chartType == ColumnChart)
m_x += columnWidth / 2;
m_w -= columnWidth;



public int xChartToScreen(int x)
return m_x + (x - xMin) * m_w / (xMax - xMin);


public int yChartToScreen(int y)
return m_y + (yMax - y) * m_h / (yMax - yMin);


public void paintComponent(Graphics g)
int x0 = 0;
int y0 = 0;
if (m_chartType != PieChart)
g.setColor(Color.black);
x0 = xChartToScreen(0);
g.drawLine(x0, m_y, x0, m_y + m_h);
y0 = yChartToScreen(0);
g.drawLine(m_x, y0, m_x + m_w, y0);


Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);

if (stroke != null)
g2.setStroke(stroke);

GeneralPath path = new GeneralPath();
switch (m_chartType)
case LineChart:
g2.setColor(lineColor);
path.moveTo(xChartToScreen(xData[0]),
yChartToScreen(yData[0]));
for (int k = 1; k < dataLength; k++)
path.lineTo(xChartToScreen(xData[k]),
yChartToScreen(yData[k]));
g2.draw(path);
break;

case ColumnChart:
for (int k = 0; k < dataLength; k++)
xMax++;
int x = xChartToScreen(xData[k]);
int w = columnWidth;
int y1 = yChartToScreen(yData[k]);
int y = Math.min(y0, y1);
int h = Math.abs(y1 - y0);
Shape rc = new Rectangle2D.Double(x, y, w, h);
path.append(rc, false);
xMax--;


if (drawShadow)
AffineTransform s0 = new AffineTransform(1.0, 0.0, 0.0,
-1.0, x0, y0);
s0.concatenate(AffineTransform.getScaleInstance(1.0, 0.5));
s0.concatenate(AffineTransform.getShearInstance(0.5, 0.0));
s0.concatenate(new AffineTransform(1.0, 0.0, 0.0, -1.0,
-x0, y0));
g2.setColor(Color.gray);
Shape shadow = s0.createTransformedShape(path);
g2.fill(shadow);


if (m_effectIndex == Gradientffect && gradient != null)
g2.setPaint(gradient);
g2.fill(path);
else if (m_effectIndex == ImageEffect
&& foregroundImage != null)
fillByImage(g2, path, 0);
else
g2.setColor(columnColor);
g2.fill(path);

g2.setColor(lineColor);
g2.draw(path);
break;

case PieChart:
double start = 0.0;
double finish = 0.0;
int ww = m_w - 2 * pieGap;
int hh = m_h - 2 * pieGap;
if (drawShadow)
ww -= pieGap;
hh -= pieGap;


for (int i = 0; i < dataLength; i++)
finish = start + pieData[i];
double f1 = Math.min(90 - start, 90 - finish);
double f2 = Math.max(90 - start, 90 - finish);
Shape shp = new Arc2D.Double(m_x, m_y, ww, hh, f1, f2 - f1,
Arc2D.PIE);
double f = (f1 + f2) / 2 * Math.PI / 180;
AffineTransform s1 = AffineTransform.getTranslateInstance(
pieGap * Math.cos(f), -pieGap * Math.sin(f));
s1.translate(pieGap, pieGap);
Shape piece = s1.createTransformedShape(shp);
path.append(piece, false);
start = finish;


if (drawShadow)
AffineTransform s0 = AffineTransform.getTranslateInstance(
pieGap, pieGap);
g2.setColor(Color.gray);
Shape shadow = s0.createTransformedShape(path);
g2.fill(shadow);


if (m_effectIndex == Gradientffect && gradient != null)
g2.setPaint(gradient);
g2.fill(path);
else if (m_effectIndex == ImageEffect
&& foregroundImage != null)
fillByImage(g2, path, 0);
else
g2.setColor(columnColor);
g2.fill(path);


g2.setColor(lineColor);
g2.draw(path);
break;



protected void fillByImage(Graphics2D g2, Shape shape, int xOffset)
if (foregroundImage == null)
return;
int wImg = foregroundImage.getWidth(this);
int hImg = foregroundImage.getHeight(this);
if (wImg <= 0 || hImg <= 0)
return;
g2.setClip(shape);
Rectangle bounds = shape.getBounds();
for (int i = bounds.x + xOffset; i < bounds.x + bounds.width; i += wImg)
for (int j = bounds.y; j < bounds.y + bounds.height; j += hImg)
g2.drawImage(foregroundImage, i, j, this);



来源http://www.java2java.com/CN/Code/Java/2D-Graphics-GUI/Demobarchartandpiechart.htm
非常好的一个网站
参考技术A 是画到jsp页面的话可以参考下jqplot这个jquery插件,
如果想单机程序实现的话下面有段程序是画曲线的,如果用类似方法画趋势线的话,可以出效果,但是估计画出来都没什么适用价值:

import java.awt.geom.QuadCurve2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class DrawLine

/**
* @param args
*/
public static void main(String[] args)
// TODO Auto-generated method stub
BufferedImage image=new BufferedImage(100,100,BufferedImage.TYPE_INT_RGB);
QuadCurve2D.Double quXian=new QuadCurve2D.Double(50,50,0,100,0,0);
image.createGraphics().draw(quXian);
File file=new File("c:\\abc.jpg");
try
javax.imageio.ImageIO.write(image, "jpg", file);
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();



本回答被提问者和网友采纳
参考技术B 楼主,把你的单线程服务放在servlet中实现就行,
tomcat ,weblogic等web容器会内部自动实现多线程(不需要你担心)

如何在 plotly express scatter 中只为多种颜色设置一条趋势线?

【中文标题】如何在 plotly express scatter 中只为多种颜色设置一条趋势线?【英文标题】:How to have just one trendline for multiple colors in plotly express scatter? 【发布时间】:2020-02-21 00:36:01 【问题描述】:

我想创建一个只有一条趋势线的散点图。 Plotly express 为点列表中的每种颜色创建不同的趋势线。

import plotly.express as px

value = [15, 20, 35, 40, 48]
years = [2010, 2011, 2012, 2013, 2014]
colors = ['red', 'red', 'blue', 'blue', 'blue']

fig = px.scatter(
    x=years,
    y=value,
    trendline='ols',
    color=colors
)

fig.show()

有没有办法为所有点创建一条趋势线?

剧情:

提前致谢!

【问题讨论】:

【参考方案1】:

随着 Plotly 5.2.1 (2021-08-13)using px.scatter() 的发布,您可以指定:

trendline_scope = 'overall'

情节 1 - trendline_scope = 'overall'

如果趋势线的绿色不符合您的喜好,您可以通过以下方式进行更改:

 trendline_color_override = 'black'

情节 2 - trendline_color_override = 'black'

trendline_scope 的另一个选项是 trace,它产生:

情节 3 - trendline_scope = 'trace'

完整代码:

import plotly.express as px

df = px.data.tips()
fig = px.scatter(df, x="total_bill", y="tip",
                 color="sex",
                 trendline="ols",
                 trendline_scope = 'overall',
#                trendline_scope = 'trace'
                 trendline_color_override = 'black'
                )
fig.show()

旧版本的上一个答案:


由于您没有特别要求内置的 plotly express 功能,您可以轻松地在px.Scatter() 上构建并使用statsmodels.OLSadd_traces(go.Scatter()) 获得您想要的:

剧情:

代码:

import plotly.express as px
import plotly.graph_objs as go
import statsmodels.api as sm

value = [15, 20, 35, 40, 48]
years = [2010, 2011, 2012, 2013, 2014]
colors = ['red', 'red', 'blue', 'blue', 'blue']

# your original setup
fig = px.scatter(
    x=years,
    y=value,
    color=colors
)

# linear regression
regline = sm.OLS(value,sm.add_constant(years)).fit().fittedvalues

# add linear regression line for whole sample
fig.add_traces(go.Scatter(x=years, y=regline,
                          mode = 'lines',
                          marker_color='black',
                          name='trend all')
                          )
fig

你可以同时拥有它:

剧情:

代码更改:只需添加trendline='ols'

fig = px.scatter(
    x=years,
    y=value,
    trendline='ols',
    color=colors
)

【讨论】:

这将一直有效,直到在 plotly.express 中创建该功能;) @jgmh 今天的好计划胜过明天的完美计划 =)【参考方案2】:

目前没有此功能的内置功能,不,很遗憾!但这是个好主意,我创建了一个问题建议将其作为补充:https://github.com/plotly/plotly.py/issues/1846

【讨论】:

以上是关于求教高手如何java绘画出一条趋势线?的主要内容,如果未能解决你的问题,请参考以下文章

求教高手------Asp。Net中如何防止SQL注入,即如何过滤关键字

求教高手:如何在NDKr5下用单独的静态库编译

java问题 ~~求教高手 13) 以下关于异常的说法,错误的是

来求教一个pacman更新的问题,求高手指导

求教高手,初学javaweb,有一个关于抽奖后台程序的疑惑

新人学BBOX,向高手求教……