ChartDirectorPanel 图形展现组件

相比于上一次提到的图形组件来说,这个更加炫酷,展现效果更加丰富。但是有缺点:不能够托拉拽。

只能给数据,达到一个展示的作用。

上图:

代码展现(很简单):

 

private void loadChart() {
        jPanel6.getAlignmentX();
        Dimension d1 = jPanel6.getMaximumSize();
        Dimension d2 = jPanel6.getMinimumSize();

        d2 = jPanel6.getSize();

        jPanel6.removeAll();
        //填充 图形
        String[][] ChartData = new String[5][days + 1];
        String[] ChartIndex = new String[days + 1];

        List<String[]> tmp = service.getRepAllInfoPerDay(planid, pdate, dateType, String.valueOf(days));
        List<String[]> tmp_xl = service.getRepEquTypeInfoPerDay(planid, pdate, dateType, "XL", String.valueOf(days));
        List<String[]> tmp_jz = service.getRepEquTypeInfoPerDay(planid, pdate, dateType, "JZ", String.valueOf(days));
        List<String[]> tmp_mx = service.getRepEquTypeInfoPerDay(planid, pdate, dateType, "MX", String.valueOf(days));
        List<String[]> tmp_zb = service.getRepEquTypeInfoPerDay(planid, pdate, dateType, "ZB", String.valueOf(days));
        if (tmp != null) {
            for (int i = 0; i < tmp.size(); i++) {
                String[] info = tmp.get(i);
                String[] info_xl = tmp_xl.get(i);
                String[] info_jz = tmp_jz.get(i);
                String[] info_mx = tmp_mx.get(i);
                String[] info_zb = tmp_zb.get(i);

                ChartIndex[i] = (String) info[0];
                ChartData[0][i] = (String) info[1];
                ChartData[1][i] = (String) info_xl[1];
                ChartData[2][i] = (String) info_jz[1];
                ChartData[3][i] = (String) info_mx[1];
                ChartData[4][i] = (String) info_zb[1];

            }
        }

        //生成ChartDirector
        ChartDirectorPanel demo = new ChartDirectorPanel();
        demo.setData(ChartData);
        demo.setLabels(ChartIndex);

        demo.setXTitle("时间");
        demo.setYTitle("检修数");
        demo.setLineName(new String[]{"所有设备", "线路", "机组", "母线", "主变"});
        demo.setLabelStep(7);//柱子和柱子之间的间隔
        demo.setLineType("2");//0:普通曲线;1:带区间的曲线 2:叠加柱状图;3:多柱状图;4:柱状图(多组)
        demo.createChart(jPanel6);

    }

这好东西的源码我也就收藏了。

 

 

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.qctc.view.common.frame.pub;

import ChartDirector.BarLayer;
import ChartDirector.Chart;
import ChartDirector.ChartViewer;
import ChartDirector.DrawArea;
import ChartDirector.Layer;
import ChartDirector.LegendBox;
import ChartDirector.LineLayer;
import ChartDirector.PlotArea;
import ChartDirector.SplineLayer;
import ChartDirector.TTFText;
import ChartDirector.TextBox;
import ChartDirector.TrackCursorAdapter;
import ChartDirector.XYChart;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import javax.swing.JPanel;

/**
 *
 * @author Administrator
 */
public class ChartDirectorPanel {

    private XYChart c = null;
    private String[][] myData = null;
    private String[] myLabels = null;
    private String[] LineName = null;
    private int myTitle_FontSize = 12;
    private String myTitle = "";
    private String myXTitle = "";
    private String myYTitle = "";
    private int myLabelStep = 1;
    private int PanelWidth, PanelHeight;
    private String lineType = "";//0:普通曲线;1:带区间的曲线;2:叠加柱状图;3:多柱状图
    private int[][] myColor = new int[][]{{0xff0000, 0x00ff00}, {0x00ff00, 0x0000CC},
    {0x0000CC, 0xFF00FF}, {0xFF00FF, 0xFF9900}, {0xFF9900, 0x000000}, {0x000000, 0x66FFFF}, {0x66FFFF, 0xff0000}, {0x77FFFF, 0xffff00}, {0x88FFFF, 0xffee00}, {0x99FFFF, 0xffdd00}, {0xaaFFFF, 0xffcc00}};
    //上下限数组 若采用区间图需设置
    private String[] upperY = null;
    private String[] lowerY = null;
    private String uplimtName;
    private String downlimtName;
    private String showMsg = "";

    public void setUplimtName(String uplimtName) {
        this.uplimtName = uplimtName;
    }

    public void setDownlimtName(String downlimtName) {
        this.downlimtName = downlimtName;
    }

    /**
     * 设置曲线区间下限
     *
     * @param lowerY
     */
    public void setLowerY(String[] lowerY) {
        this.lowerY = lowerY;
    }

    /**
     * 设置曲线区间上限
     *
     * @param upperY
     */
    public void setUpperY(String[] upperY) {
        this.upperY = upperY;
    }

    /**
     * 设置曲线类型
     *
     * @param linetype 0:普通;1:带区间;2:叠加柱状图;3:多柱状图;4:柱状图(多组)
     * @return
     */
    public String setLineType(String linetype) {
        this.lineType = linetype;
        return lineType;
    }

    /**
     * 设置图上显示信息
     *
     * @param showMsg
     * @return
     */
    public String setShowMsg(String msg) {
        this.showMsg = msg;
        return showMsg;
    }

    /**
     * 设置x轴坐标标签显示间隔
     *
     * @param lStep
     * @return
     */
    public int setLabelStep(int lStep) {
        this.myLabelStep = lStep;
        return myLabelStep;
    }

    /**
     * 设置x轴标题
     *
     * @param xTitle
     * @return
     */
    public String setXTitle(String xTitle) {
        this.myXTitle = xTitle;
        return myXTitle;
    }

    /**
     * 设置y轴标题
     *
     * @param yTitle
     * @return
     */
    public String setYTitle(String yTitle) {
        this.myYTitle = yTitle;
        return myYTitle;
    }

    /**
     * 设置曲线标题
     *
     * @param title
     * @return
     */
    public String setTitle(String title) {
        this.myTitle = title;
        return myTitle;
    }

    /**
     * 设置曲线数据
     *
     * @param data
     * @return
     */
    public String[][] setData(String[][] data) {
        this.myData = data;
        return myData;
    }

    /**
     * 设置曲线x轴坐标标签
     *
     * @param labels
     * @return
     */
    public String[] setLabels(String[] labels) {
        this.myLabels = labels;
        return myLabels;
    }

    /**
     * 设置各个曲线名称
     *
     * @param linename
     * @return
     */
    public String[] setLineName(String[] linename) {
        this.LineName = linename;
        return LineName;
    }

    private void viewer_MouseMovedPlotArea(MouseEvent e) {
        ChartViewer viewer = (ChartViewer) e.getSource();
        trackLineLabel((XYChart) viewer.getChart(), viewer.getPlotAreaMouseX());
        viewer.updateDisplay();

        // Hide the track cursor when the mouse leaves the plot area
        viewer.removeDynamicLayer("MouseExitedPlotArea");
    }

    private void trackLineLabel(XYChart c, int mouseX) {
        // Clear the current dynamic layer and get the DrawArea object to draw on it.
        DrawArea d = c.initDynamicLayer();

        // The plot area object
        PlotArea plotArea = c.getPlotArea();

        // Get the data x-value that is nearest to the mouse, and find its pixel coordinate.
        double xValue = c.getNearestXValue(mouseX);
        int xCoor = c.getXCoor(xValue);

        // Draw a vertical track line at the x-position
        d.vline(plotArea.getTopY(), plotArea.getBottomY(), xCoor, d.dashLineColor(0x000000, 0x0101));

        // Draw a label on the x-axis to show the track line position.
        String xlabel = "<*font,bgColor=000000*> " + c.xAxis().getFormattedLabel(xValue)
                + " <*/font*>";
        TTFText t = d.text(xlabel, "宋体 Bold", 9);

        // Restrict the x-pixel position of the label to make sure it stays inside the chart image.
        int xLabelPos = Math.max(0, Math.min(xCoor - t.getWidth() / 2, c.getWidth() - t.getWidth()));
        t.draw(xLabelPos, plotArea.getBottomY() + 6, 0xffffff);

        // Iterate through all layers to draw the data labels
        for (int i = 0; i < c.getLayerCount(); ++i) {
            Layer layer = c.getLayerByZ(i);

            // The data array index of the x-value
            int xIndex = layer.getXIndexOf(xValue);

            // Iterate through all the data sets in the layer
            for (int j = 0; j < layer.getDataSetCount(); ++j) {
                ChartDirector.DataSet dataSet = layer.getDataSetByZ(j);

                // Get the color and position of the data label
                int color = dataSet.getDataColor();
                int yCoor = c.getYCoor(dataSet.getPosition(xIndex), dataSet.getUseYAxis());

                // Draw a track dot with a label next to it for visible data points in the plot area
                if ((yCoor >= plotArea.getTopY()) && (yCoor <= plotArea.getBottomY()) && (color
                        != Chart.Transparent)) {

                    d.circle(xCoor, yCoor, 4, 4, color, color);

                    String label = "<*font,bgColor=" + Integer.toHexString(color) + "*> " + c.formatValue(
                            dataSet.getValue(xIndex), "{value|P4}") + " <*/font*>";
                    t = d.text(label, "宋体 Bold", 9);

                    // Draw the label on the right side of the dot if the mouse is on the left side the chart,
                    // and vice versa. This ensures the label will not go outside the chart image.
                    if (xCoor <= (plotArea.getLeftX() + plotArea.getRightX()) / 2) {
                        t.draw(xCoor + 5, yCoor, 0xffffff, Chart.Left);
                    } else {
                        t.draw(xCoor - 5, yCoor, 0xffffff, Chart.Right);
                    }
                }
            }
        }
    }

    /**
     * 生成曲线
     *
     * @param myPanel
     * @param index
     */
    public void createChart(JPanel myPanel) {

//        myPanel.removeAll();
        PanelWidth = myPanel.getWidth() - 7;
        PanelHeight = myPanel.getHeight();

        if (PanelWidth < 0 || PanelHeight < 0) {
//            System.out.println("chart zone < 0");
            return;
        }

        ChartViewer viewer = new ChartViewer();
        viewer.addTrackCursorListener(new TrackCursorAdapter() {
            public void mouseMovedPlotArea(MouseEvent e) {
                viewer_MouseMovedPlotArea(e);
            }
        });

        Chart.setLicenseCode("SXZVFNRN9MZ9L8LGA0E2B1BB");
//        viewer.setBackground(Color.red);
        double[][] chart_data = this.formatData(myData);
        double[] UpLimit = this.formatData(upperY);
        double[] DownLimit = this.formatData(lowerY);

        // X轴刻度
        String[] labels = myLabels;

//        c = new XYChart(PanelWidth, PanelHeight, 0xe0e0ff, 0x000000, 1);
        c = new XYChart(PanelWidth, PanelHeight);
        //c.setRoundedFrame();//边界角圆化

        c.setBackground(14080479);
        c.setDefaultFonts("宋体 Bold");

        //设置曲线标题
        c.addTitle(myTitle, "隶书 Bold", 12);
        //Y轴标签
        c.yAxis().setTitle(myYTitle, "宋体 Bold", 10);
        //X轴标签
        c.xAxis().setTitle(myXTitle, "宋体 Bold", 10);

        // 设置X轴刻度
        c.xAxis().setLabels(labels);
        // X轴刻度间隔
        c.xAxis().setLabelStep(myLabelStep);
        if (lineType.equals("1")) {
            this.setMaxMin(chart_data, UpLimit, DownLimit);
        } else if (lineType.equals("0")) {
            this.setMaxMin(chart_data, null, null);
        } else if (lineType.equals("2")) {
            this.setMaxMin(chart_data, null, null);
        } else if (lineType.equals("3")) {
            this.setMaxMin(chart_data, null, null);
        } else if (lineType.equals("4")) {
            this.setMaxMin(chart_data, null, null);
        }

        TextBox title = c.addTitle(myTitle, "宋体", myTitle_FontSize);
        title.setMargin2(0, 0, 12, 12);

        LegendBox legendBox = c.addLegend(70, title.getHeight() - 10, false, "宋体", 9);
        legendBox.setAlignment(Chart.TopLeft);
        legendBox.setBackground(Chart.Transparent, Chart.Transparent);

        c.setPlotArea(60, 30, c.getWidth() - 66, c.getHeight() - 60,
                0xe8f0f8, -1, Chart.Transparent, c.dashLineColor(0x888888, Chart.DotLine), -1);

        c.addText(c.getWidth() - 30, title.getHeight() + 20,
                "<*font=Times New Roman 宋体,size=9,color=FF9900*>" + showMsg + "<*/*>").setAlignment(Chart.BottomRight);

        c.addLegend(60, 4, false, "宋体 Bold", 10).setBackground(Chart.Transparent);

        if (lineType.equals("0")) {//普通
            c.setBackground(c.linearGradientColor(0, 0, 0, c.getHeight() / 2, 0xe8f0f8, 0xaaccff), 0x88aaee);
            LineLayer layer = c.addLineLayer2();
            layer.setLineWidth(2);
            if (chart_data != null) {
                for (int k = 0; k < chart_data.length; k++) {
                    layer.addDataSet(chart_data[k], getMyColor()[k][0], LineName[k]);
                }
            } else {
                double[] data = new double[96];
                for (int i = 0; i < data.length; i++) {
                    data[i] = 11;
                }
                layer.addDataSet(data, getMyColor()[0][0], "");
            }
        } else if (lineType.equals("1")) {//区间图
            SplineLayer splineLayer = c.addSplineLayer(chart_data[1], getMyColor()[2][0], LineName[1]);
            splineLayer.setLineWidth(2);
            LineLayer lineLayer = c.addLineLayer2();
            lineLayer.addDataSet(chart_data[0], getMyColor()[0][0], LineName[0]);//计划曲线
            if (uplimtName == null || "".equals(uplimtName)) {
                uplimtName = "上限";
            }
            if (downlimtName == null || "".equals(downlimtName)) {
                downlimtName = "下 限";
            }
            lineLayer.addDataSet(UpLimit, getMyColor()[1][0], uplimtName);
            lineLayer.addDataSet(DownLimit, getMyColor()[1][0], downlimtName);

            lineLayer.setLineWidth(2);

            /*绘出区域部分*/
            c.addInterLineLayer(lineLayer.getLine(1), lineLayer.getLine(2), 0x8099ff99, 0x8099ff99);
            c.addInterLineLayer(splineLayer.getLine(0), lineLayer.getLine(1), 0xff0000, Chart.Transparent);
            c.addInterLineLayer(splineLayer.getLine(0), lineLayer.getLine(2), Chart.Transparent, 0x0000ff);

        } else if (lineType.equals("2")) {//叠加柱状图
            // add by maowenzhao
            double maxy = 3;
            BarLayer layer = c.addBarLayer2(Chart.Stack, 5);

            layer.setBarShape(Chart.CircleShape);
            layer.setAggregateLabelStyle();
            layer.setDataLabelStyle();
            layer.setLineWidth(1);

            if (chart_data != null) {
                for (int k = 0; k < chart_data.length; k++) {
                    if (k == 0) {
                        for (int m = 0; m < chart_data[k].length; m++) {
                            if (chart_data[k][m] > maxy) {
                                maxy = chart_data[k][m];
                            }
                        }
                        continue;
                    }
                    layer.addDataSet(chart_data[k], getMyColor()[k][0], LineName[k]);
                }
            } else {
                double[] data = new double[96];
                for (int i = 0; i < data.length; i++) {
                    data[i] = 11;
                }
                layer.addDataSet(data, getMyColor()[0][0], "");
            }

            c.yAxis().setLinearScale(0, maxy);//设置最大最下区间
        } else if (lineType.equals("3")) {//多柱状图
            // add by huanghongwei 
            double maxy = 1;
            BarLayer layer = c.addBarLayer2(Chart.Side, 0);
            //layer.setBarShape(Chart.CircleShape);

            if (chart_data != null) {
                for (int k = 0; k < chart_data.length; k++) {

                    layer.addDataSet(chart_data[k], getMyColor()[k][0], LineName[k]);
                }
            } else {
                double[] data = new double[96];
                for (int i = 0; i < data.length; i++) {
                    data[i] = 11;
                }
                layer.addDataSet(data, getMyColor()[0][0], "");
            }

            //c.yAxis().setLinearScale(0, maxy);//设置最大最下区间
        } else if (lineType.equals("4")) {//柱状图 多组多颜色
            c.addTitle(myTitle, "隶书 Bold", 14);
            c.xAxis().setLabels(labels).setFontAngle(315);
            //背景颜色
            c.setBackground(c.linearGradientColor(0, 0, 0, c.getHeight() / 2, 0xe8f0f8, 0xaaccff), 0x88aaee);
//            c.setRoundedFrame();
            c.setDropShadow();
            //BarLayer layer = c.addBarLayer2(Chart.Side, 0);              
            if (chart_data != null) {
                for (int k = 0; k < chart_data.length; k++) {
                    BarLayer layer = c.addBarLayer3(chart_data[k]);
                    layer.setBorderColor(Chart.Transparent, Chart.softLighting(Chart.Left));
                    layer.setBarShape(Chart.CircleShape);
                    layer.set3D(10);
                    //layer.addDataSet(chart_data[k],colors[k]);//.setDataColor(-1, Chart.softLighting(Chart.Left));
                }
            } else {
                double[] data = new double[96];
                for (int i = 0; i < data.length; i++) {
                    data[i] = 11;
                }
                c.addBarLayer3(data);
                //layer.addDataSet(data, myColor[0][0], "");
            }
        } else if (lineType.equals("5")) {//区间图加柱图
            c.setBackground(c.linearGradientColor(0, 0, 0, c.getHeight() / 2, 0xe8f0f8, 0xaaccff), 0x88aaee);
            LineLayer lineLayer = c.addLineLayer2();
            lineLayer.addDataSet(chart_data[0], getMyColor()[0][0], LineName[0]);//计划曲线

            lineLayer.addDataSet(UpLimit, getMyColor()[1][0], LineName[1]);
            lineLayer.addDataSet(DownLimit, getMyColor()[1][0], LineName[2]);

            lineLayer.addDataSet(chart_data[1], getMyColor()[2][0], LineName[3]);
            lineLayer.addDataSet(chart_data[2], getMyColor()[3][0], LineName[4]);

            lineLayer.setLineWidth(2);
//            BarLayer layer = c.addBarLayer();
//            layer.addDataSet(chart_data[1], getMyColor()[3][0], LineName[3]);
//            layer.addDataSet(chart_data[2], getMyColor()[6][0], LineName[4]);
//            c.addBarLayer(chart_data[1]).setBorderColor(-1,1);
//            c.addBarLayer(chart_data[2]);
            /*绘出区域部分*/
            c.addInterLineLayer(lineLayer.getLine(1), lineLayer.getLine(2), 0x8099ff99, 0x8099ff99);

        } else if (lineType.equals("8")) {//折线图加柱图1,单柱状图上边有一曲线

            c.setPlotArea(60, 30, c.getWidth() - 120, c.getHeight() - 62,
                    0xe8f0f8, -1, Chart.Transparent, c.dashLineColor(0x888888, Chart.DotLine), -1);
            c.setBackground(c.linearGradientColor(0, 0, 0, c.getHeight() / 2, 0xe8f0f8, 0xaaccff), 0x88aaee);
            LineLayer lineLayer = c.addLineLayer();

            lineLayer.addDataSet(chart_data[0], getMyColor()[0][0], LineName[0]).setDataSymbol(Chart.CircleSymbol, 9, 0xffff00);

            lineLayer.setLineWidth(4);
            BarLayer barLayer = c.addBarLayer2(Chart.Side, 0);
            barLayer.addDataSet(chart_data[1], getMyColor()[1][0], LineName[1]);
            // barLayer.addDataSet(chart_data[2], getMyColor()[2][0], LineName[2]);
            barLayer.set3D(5);
            double max1 = 0d;
            double min1 = 0d;
            double min2 = 0d;
            double max2 = 0d;
            for (int i = 0; i < chart_data[1].length; i++) {
                max1 = max1 > chart_data[1][i] ? max1 : chart_data[1][i];
                //max2 = max2 > chart_data[2][i] ? max2 : chart_data[2][i];
                min1 = min1 < chart_data[1][i] ? min1 : chart_data[1][i];
            }
            for (int i = 0; i < chart_data[0].length; i++) {
                max2 = max2 > chart_data[0][i] ? max2 : chart_data[0][i];
                //max2 = max2 > chart_data[2][i] ? max2 : chart_data[2][i];
                min2 = min2 < chart_data[0][i] ? min2 : chart_data[0][i];
            }
            c.yAxis().setLinearScale(min2-Math.abs(min2*0.2), max2+Math.abs(max2*0.2));
//            if (max1 > max2) {
            c.yAxis2().setLinearScale( min1-Math.abs(min1*0.2), max1+Math.abs(max1*0.2));
//            } else {
//                c.yAxis2().setLinearScale(0, 1.8 * max2);
//            }

            barLayer.setBarShape(Chart.CircleShape);
//            barLayer.set3D(10);
            barLayer.setUseYAxis2();

            c.addInterLineLayer(lineLayer.getLine(1), lineLayer.getLine(2), 0x8099ff99, 0x8099ff99);

        }
        // 绘出Chart
        viewer.setMinimumSize(new Dimension(0, 0));
//        viewer.setImage(c.makeImage());
//        viewer.setImageMap(c.getHTMLImageMap("clickable", "",
//                "title='[{dataSetName}] " + myXTitle + " {xLabel}: {value} " + myYTitle + "'"));
        viewer.setChart(c);
        myPanel.add(viewer, java.awt.BorderLayout.CENTER);
        myPanel.validate();
    }

    /**
     * 格式化数据
     *
     * @param data
     * @return
     */
    private double[][] formatData(String[][] data) {
        if (data == null || data.length < 1) {
            return null;
        }

        double[][] rtn = new double[data.length][data[0].length];

        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[i].length; j++) {
                if (data[i][j] == null || data[i][j].equals("") || data[i][j].equals("null")) {
                    rtn[i][j] = Chart.NoValue;
                } else {
                    rtn[i][j] = Double.parseDouble(data[i][j]);
                }
            }
        }

        return rtn;
    }

    /**
     * 格式化数据
     *
     * @param data
     * @return
     */
    private double[] formatData(String[] data) {
        if (data == null || data.length < 1) {
            return null;
        }

        double[] rtn = new double[data.length];

        for (int i = 0; i < data.length; i++) {
            if (data[i] == null || data[i].equals("") || data[i].equals("null")) {
                rtn[i] = Chart.NoValue;
            } else {
                rtn[i] = Double.parseDouble(data[i]);
            }
        }

        return rtn;
    }

    /**
     * 设置y轴刻度最大、最小值
     *
     * @param data
     * @param c
     */
    private void setMaxMin(double[][] data, double[] sx, double[] xx) {
        if (data == null || data.length < 1) {
            return;
        }
        double maxv = -999999999;
        double minv = 999999999;
        for (int i = 0; i < data.length; i++) {
            for (int j = 0; j < data[i].length; j++) {
                if (data[i][j] < Chart.NoValue - 10) {
                    if (data[i][j] < minv) {
                        minv = data[i][j];
                    }
                    if (data[i][j] > maxv) {
                        maxv = data[i][j];
                    }
                }
            }
        }

        if (sx != null) {
            for (int i = 0; i < sx.length; i++) {
                if (sx[i] > maxv) {
                    maxv = sx[i];
                }
            }
        }

        if (xx != null) {
            for (int i = 0; i < xx.length; i++) {
                if (xx[i] < minv) {
                    minv = xx[i];
                }
            }
        }

        if (maxv <= -999999990 || minv >= 999999990) {
        } else {
            if (maxv > 0) {
                maxv = maxv * 1.05;
            } else {
                maxv = maxv * 0.95;
            }
            if (minv > 0) {
                minv = minv * 0.95;
            } else {
                minv = minv * 1.05;
            }
            c.yAxis().setLinearScale(minv, maxv);
        }
    }

    /**
     * @return the myColor
     */
    public int[][] getMyColor() {
        return myColor;
    }

    /**
     * @param myColor the myColor to set
     */
    public void setMyColor(int[][] myColor) {
        this.myColor = myColor;
    }
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值