Js+Css 制作簡易柱狀圖。


項目中遇到需要柱狀圖。

本項目原來也有相關差不多的內容,但是柱狀圖是服務端直接拼接HTML代碼輸出,一大堆麻煩 一大堆。。。(不知道公司哪個大神發明的哇)。。

網上找了個插件,改了下,效果如下了

看起來很不錯 用法也簡單 只需要傳兩個數組就OK了,據說原來的代碼是日本人寫的,很不錯的。

 

但是 樣式和項目原來的不一樣,網站要求統一呀。於是想着 自己寫一個算了。

Js代碼如下:

//------------------------------------------------------------------
//功能:客戶端JS生成柱狀圖
//用法:
//        <head>
//           <title></title>
//           <link href="fei_histogram.css" rel="stylesheet" type="text/css" />
//           <script src="fei_histogram.js" type="text/javascript"></script>
//            <script type="text/javascript">
//                window.onload = function () {
//                    var vbar = new fei.jsimg.histogram();
//                    vbar.x = [20, 40, 60, 80, 100, 120];
//                    vbar.y = ["ZB1", "ZB2", "ZB3", "ZB4", "ZB5", "ZB6"];
//                    vbar.data = [10, 33, 38, 26, 59, 112];
//                    //            vbar.width = 500;
//                    //            vbar.height = 200;
//                    //            vbar.dataformat = "{0}%";
//                    vbar.render("vbarTest");
//                }
//            </script>
//        </head>
//        <body>
//            <div id="vbarTest">
//            </div>
//        </body>
//
//作者:苗建龍   編寫日期:2012-05-08
//------------------------------------------------------------------

fei = { jsimg: {} }
fei.jsimg.histogram = function (x, y, data) {
    this.width = 800;                                                       //圖片寬度
    this.height = 300;                                                      //圖片高度
    this.barwidth = 50;                                                     //柱子寬度
    this.x = x || [1, 2, 3, 4, 5, 6];                                       //x軸刻度
    this.y = y || ["ZB1", "ZB2", "ZB3", "ZB4", "ZB5", "ZB6"];               //y軸刻度
    this.data = data || [0, 0, 0, 0, 0, 0];                                 //數據
    this.dataformat = "";                                                   //x軸和數據的格式:如 可表示為 "{0}%"
    this.vbarBg = "http://www.cnblogs.com/App_Themes/Default/Images/Primacy/kaohe.gif";      //柱子背景圖路徑
    this.isshowHq = true;                                                   //是否顯示紅旗
    this.hqImg = "<img src='http://www.cnblogs.com/App_Themes/Default/Images/Primacy/hongqi.gif' Width='36px' Height='32px'/>"; //紅旗圖片
}

fei.jsimg.histogram.prototype.draw = function () {
    this._set_max_value();
    this._draw_container();
    this._draw_container_rows();
    this._draw_container_cols();
}

fei.jsimg.histogram.prototype._set_max_value = function () {
    this.max_x = 0;
    this.max_data = 0;
    for (var i = 0; i < this.x.length; i++) {
        if (this.x[i] >= this.max_x) {
            this.max_x = this.x[i];
        }
    }
    for (var i = 0; i < this.data.length; i++) {
        if (this.data[i] >= this.max_data) {
            this.max_data = this.data[i];
        }
    }
}

fei.jsimg.histogram.prototype._draw_container = function () {
    this.histogramimg = document.createElement("ul"); //容器:ul
    this.addclass(this.histogramimg, "fei_histogram_container_style");
    this.histogramimg.style.cssText = "height: " + this.height + "px !important;" + "width: " + this.width + "px;";
}

fei.jsimg.histogram.prototype._draw_container_rows = function () {
    this.rows = document.createElement("li"); //行的集合:結構為<li>{div集合}</li>
    this.addclass(this.rows, "fei_histogram_container_rows_style");
    this.rows.style.cssText = "height:" + this.height + "px";

    var xheigth = this.height / this.x.length; //行之間的間隔
    for (var i = this.x.length - 1; i >= 0; i--) {
        var row = document.createElement("div"); //單行:div
        row.style.cssText = "height:" + (xheigth - 1) + "px";

        var row_p = document.createElement("p"); //行的刻度文字:x軸刻度
        if (this.dataformat == "" || !this.dataformat) {
            row_p.innerHTML = this.x[i].toString();
        }
        else {
            row_p.innerHTML = this.dataformat.replace("{0}", this.x[i].toString());
        }
        row.appendChild(row_p);

        this.rows.appendChild(row);
    }
    this.histogramimg.appendChild(this.rows);
}

fei.jsimg.histogram.prototype._draw_container_cols = function () {
    var ywidth = this.width / this.data.length; //算出列寬
    var col_ul_li_left = (ywidth - this.barwidth) / 2;
    for (var i = 0; i < this.data.length; i++) {
        var col = document.createElement("li"); //列:li
        var left = i * ywidth; //列到x軸的距離
        this.addclass(col, "fei_histogram_container_col_style");
        col.style.cssText = "left: " + left + "px;height:" + (this.height + 1) + "px;width: " + ywidth + "px;";
        col.innerHTML = this.y[i].toString() + "<br/>";
        if (this.isshowHq && this.data[i] == this.max_data) {
            col.innerHTML += this.hqImg;
        }


        /*---柱子---*/
        var barul = document.createElement("ul");
        var barli = document.createElement("li");
        if (this.dataformat == "" || !this.dataformat) {
            barli.innerHTML = this.data[i].toString();
        }
        else {
            barli.innerHTML = this.dataformat.replace("{0}", this.data[i].toString());
        }
        barli.style.cssText = "height: " + this.data[i] * this.height / this.max_x + "px;" +
            "left: " + col_ul_li_left + "px;width: " + this.barwidth + "px;" +
            "background: url('" + this.vbarBg + "') no-repeat scroll 0 0 #DDDDDD;";
        barul.appendChild(barli);


        col.appendChild(barul);

        this.histogramimg.appendChild(col);
    }
}

fei.jsimg.histogram.prototype.addclass = function (elements, value) {
    if (!elements.className) {
        elements.className = value;
    }
    else {
        newClass = elements.className;
        newClass += " ";
        newClass += value;
        elements.className = newClass;
    }
}

fei.jsimg.histogram.prototype.render = function (id) {
    this.container = document.getElementById(id);
    this.draw();
    this.container.appendChild(this.histogramimg);
}

  代碼有很多不合理的地方 本來打算把柱子等元素提出來寫成獨立的類  但是。。。。為了省事,就這么寫了。

另外 還要Css支持,原理是Css控制ul實現。Css文件如下:

.fei_histogram_container_style
{
    background: none repeat-x scroll 0 0 #FFFFFF !important;
    border: 2px solid #0063BE;
    list-style: none outside none;
    margin: 0 4.8px 16px 35px;
    padding: 0;
    position: relative;
}
.fei_histogram_container_rows_style
{
    left: 0;
    width: 100%;
    z-index: 1;
    bottom: 0;
    position: absolute;
    text-align: center;
}
.fei_histogram_container_rows_style div
{
    border-top: medium none;
    position: relative;
    text-align: center;
    list-style: none outside none;
    border-top: 1px dotted #41A3E2;
}
.fei_histogram_container_rows_style div p
{
    position: absolute;
    right: 101%;
    top: -11pt;
    text-align: center;
    list-style: none outside none;
}

.fei_histogram_container_col_style
{
    bottom: 0px;
    position: absolute;
    text-align: center;
    border-right: 1px dotted #41A3E2;
    z-index: 2;
    list-style: none outside none;
}

.fei_histogram_container_col_style ul
{
    list-style: none outside none;
    text-align: center;
}

.fei_histogram_container_col_style li
{
    color: #000000;
    bottom: 0px;
    position: absolute;
    text-align: center;
    list-style: none outside none;
}

  把這兩文件引入到項目中,用法:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
    <link href="fei_histogram.css" rel="stylesheet" type="text/css" />
    <script src="fei_histogram.js" type="text/javascript"></script>
    <script type="text/javascript">
        window.onload = function () {
            var vbar = new fei.jsimg.histogram();
            vbar.x = [20, 40, 60, 80, 100, 120];
            vbar.y = ["Y1", "Y2", "Y3", "Y4", "Y5", "Y6","Y7"];
            vbar.data = [10, 33, 38, 26, 59, 92,96];
            //            vbar.width = 500;
            //            vbar.height = 200;
            //            vbar.dataformat = "{0}%";
            vbar.render("vbarTest");
        }
    </script>
</head>
<body>
    <div id="vbarTest">
    </div>
</body>
</html>

里面各種屬性可以自行設置,效果如下:

哦,樣式不好看不是我的錯,我是為了和項目保持一致。。 -_-。

完畢,收工。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM