d3.js——对柱状图和折线图的封装


1、js调用

稍后加上

2、封装的js

function DrawChart(option) {
    //如果没有参数,则返回
    if (!option) {
        return;
    }
    if (!option.data || !option.containerId || !option.chartSize || !option.serials || !option.xAxis) {
        return;
    }
    var dataset = option.data;
    //if (dataset.length < 2) {
    //    return;
    //}

    var serials = option.serials;
    if (serials.length == 0) {
        return;
    }

    //设置图表的区域大小
    var margin = { top: 30, right: 40, bottom: 80, left: 50 };
    if (option.margin) {
        margin = option.margin;
    }
    var chartSize = option.chartSize;
    var w = chartSize.x - margin.left - margin.right;
    var h = chartSize.y - margin.top - margin.bottom;
    var legendSize = 20;
    var legendDistance = 40 + margin.top;


    //X轴处理
    //----------x轴数据范围
    var xFactor = option.xAxis.xFactor;
    var i;
    var xRange = [];
    for (i = 0; i < dataset.length; i++) {
        xRange.push(xFactor(dataset[i]));
    }

    //----------x轴处理
    var tickCount = option.xAxis.tickCount ? option.xAxis.tickCount : 5;
    var xScale; //x轴尺度变换
    var xAxis; //X轴刻度
    var tickInterval = option.xAxis.allTick ? 1 : Math.round(xRange.length / tickCount); //刻度间距(时间刻度用)
    var rangeBand = w * 0.8 / dataset.length;
    switch (option.xAxis.type) {
        case "ordinal":
            //x轴的序数尺度变换
     
            switch (option.chartType) {
                case "bar":
                         xScale = d3.scale.ordinal()
                                      .domain(xRange)
                                      .rangeRoundBands([0, w], 0.1); //设置值域
                    break;
                    
                case "line":
                    xScale = d3.scale.ordinal()
                                 .domain(xRange)
                                 .rangePoints([0, w], 1);
                    break;
                default:
               
                    break;
            }
          
            xAxis = d3.svg.axis()
             .scale(xScale)  //设置x轴的尺度变换
             .orient("bottom").ticks(tickCount); //设置坐标轴刻度方向
            
            break;
        case "number":
            break;
        case "date":
            xScale = d3.time.scale()
                .domain(d3.extent(xRange, function (d) { return d; }))
                .rangeRound([0, w]);

            //定义x轴 
            xAxis = d3.svg.axis()
                .scale(xScale)  //设置x轴的尺度变换
                .orient("bottom") //设置坐标轴刻度方向
                .ticks(d3.time.day, tickInterval)
                .tickFormat(d3.time.format(option.xAxis.format));
            break;
    }

    //Y轴处理
    //---------y轴最小值
    var yMin = d3.min(dataset, function (d) {
        if (serials.length == 1) {
            return serials[0].yFactor(d);
        } else {
            var minValue = serials[0].yFactor(d);
            for (var j = 0; j < serials.length; j++) {
                var value = serials[j].yFactor(d);
                minValue = (minValue < value ? minValue : value);
            }
            return minValue;
        }
    });
    //---------y轴最大值
    var yMax = d3.max(dataset, function (d) {
        if (serials.length == 1) {
            return serials[0].yFactor(d);
        } else {
            var maxValue = serials[0].yFactor(d);
            for (var j = 0; j < serials.length; j++) {
                var value = serials[j].yFactor(d);
                maxValue = (maxValue > value ? maxValue : value);
            }
            return maxValue;
        }
    });

    var hasZeroY = false;
    switch(option.chartType) {
        case "bar":
            if (yMax >= 0 && yMin <= 0) {
                hasZeroY = true;
            } else if (yMax < 0) {
                yMax = 0;
                hasZeroY = false;
            } else if (yMin > 0) {
                yMin = 0;
                hasZeroY = false;
            }
                
            break;
        default:
            break;
            
    }
    //-----------上下增加5%,
  
    var rangeExtent = (yMax - yMin) * 0.05;
    if (yMin >= 0) {
        yMax = yMax + rangeExtent;
        yMin = yMin <= rangeExtent ? 0 : yMin - rangeExtent;
    } else if (yMax <= 0) {
        yMax = Math.abs(yMax) <= rangeExtent ? 0 : yMax + rangeExtent;
        yMin = yMin - rangeExtent;
    } else {
        yMax = yMax + rangeExtent;
        yMin = yMin - rangeExtent;
    }


    //-----------y轴尺度变换
    var yScale = d3.scale.linear()
        .domain([yMin, yMax]) //设置定义域为【0,最大值】
        .range([h, 0]); //设置值域
    //-----------定义y轴  
    var yAxis = d3.svg.axis()
        .scale(yScale)
        .orient("left")
        .ticks(5); //设置最多有5个刻度

    //画图形
    var container = d3.select("#" + option.containerId);
    container.select("svg").remove();

    //Create SVG element
    var chart = container//选中DOM中的目标元素
        .append("svg")//为目标元素附加上一个svg子元素
        .attr("width", w + margin.left + margin.right)//设置这个svg的宽
        .attr("height", h + margin.top + margin.bottom)//设置这个svg的高
       // .append("g")
      //  .attr("transform", "translate(" + margin.left + "," + margin.top + ")")
        .attr("style", "padding:20px;");

    var svg = chart.append("g")
       // .attr("width", w)
       // .attr("height", h)
        .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
    //-----------画标题
    //给图表添加一个标题
    chart.append("text")
        .attr("x", (w / 2))
        .attr("y", 0)
        .attr("text-anchor", "middle")
        .attr("class", option.title.cls)
        .text(option.title.text);

    //-----------画X轴
    //Create X axis  
    svg.append("g")
        .attr("class", "xAxis")
        .attr("transform", "translate(0," + h + ")")//设置距下边界的距离  
        .call(xAxis)
        .selectAll("text").style("text-anchor", "end").attr("dx", "-.8em").attr("dy", ".15em").attr("transform", "rotate(-45)");

    //-----------画Y轴
    //Create Y axis  
    svg.append("g")
        .attr("class", "yAxis")
        .attr("transform", "translate(0,0)")//设置轴距左边界的距离
        .call(yAxis);
    
    switch(option.chartType) {
        case "bar":
            if (hasZeroY) {
                svg.append("g")
                    .attr("class", "xAxis")
                    .append("line")
                    .attr("y1", yScale(0))
                    .attr("y2", yScale(0))
                    .attr("x1", 0)
                    .attr("x2", w);
            }
            break;
        default:
            break;
    }

    
    //-----------画序列
    var k, serial;
    for (k = 0; k < serials.length; k++) {
        serial = serials[k];
        var yFactor = serial.yFactor;
        
        var dataFormat = ",n";
        if (serial.dataFormat) {
            dataFormat = serial.dataFormat;
        }
        var d3Format = d3.format(dataFormat);
        
        switch (option.chartType) {
            case "line":

                //为SVG添加折线
                var line = d3.svg.line()
                    // .interpolate("linear")
                    .x(function (d) {
                        return xScale(xFactor(d));
                    })
                    .y(function (d) {
                        return yScale(yFactor(d));
                    });

                svg.append("path")
                    .datum(dataset)
                    .attr("class", serial.g.pathCls)
                    .attr("d", line);

                //折线添加 图标
                svg.selectAll(".circle")
                    .data(dataset)
                    .enter()
                    .append("circle")
                    .attr("cx", function (d) {
                        return xScale(xFactor(d));
                    })
                    .attr("cy", function (d) {
                        return yScale(yFactor(d));
                    })
                    .attr("r", 3)
                    .append("title")
                    .text(function (d) {
                        return serial.tip.replace("{0}", d3Format(yFactor(d)));//d3Format(yFactor(d))
                    });
                break;
                
            case "bar":
                //为SVG添加条形
                svg.selectAll(".bar")
                    .data(dataset)
                    .enter().append("rect")
                    .attr("class", function (d) { return yFactor(d) < 0 ? "bar negative" : "bar positive"; })
                    .attr("x", function (d) { return xScale(xFactor(d)); })
                    .attr("width", rangeBand)
                    .attr("y", function (d) { return yScale(Math.max(yFactor(d), 0)); })
                    .attr("height", function (d) { return Math.abs(yScale(yFactor(d)) - yScale(0)); })
                    .append("title")
                    .text(function (d) {
                        return serial.tip.replace("{0}", d3Format(yFactor(d)));
                    });
                break;
        }
        

    }

    //-----------画图例
    var legendCount = serials.length;
    for (k = 0; k < serials.length; k++) {
        serial = serials[k];
        var legend = serial.legend;
        if (legend) {
            chart.append("rect")
                .attr("x", w * (k + 1) / (legendCount + 1))
                .attr("y", h + legendDistance)
                .attr("width", legendSize)
                .attr("height", legendSize)
                .attr("class", legend.cls);

            chart.append("text")
                .attr("x", w * (k + 1) / (legendCount + 1) + legendSize)
                .attr("y", h + legendDistance + 15)
                .style("font-size", "14px")
                .text(legend.text);
        }
    }
}



转载于:https://my.oschina.net/u/1416844/blog/368936

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值