d3动态坐标轴

 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>动态坐标轴</title>
    <link rel="stylesheet" type="text/css" href="../../css/styles.css"/>
    <script type="text/javascript" src="../../lib/d3.js"></script>
</head>
<body>

<div class="control-group">
    <button onclick="rescale()">重新生成坐标轴</button>
</div>



<script type="text/javascript">
    let height = 500,
        width = 500,
        margin = 30,
        xAxis, yAxis, xAxisLength, yAxisLength;
    xAxisLength = width - 2*margin;
    yAxisLength = height - 2*margin;


    //创建一个svg标签画布
    //后面还要创建一个g标签,用于画坐标系
    let svg = d3.select("body").append("svg")
        .attr("class", "axis")
        .attr("width", width)
        .attr("height", height)
        .style("background-color","#cedb9c");


    /**
     * 创建坐标轴
* 一个坐标轴包含:尺度、刻度、相对位置
* 尺度:一个映射关系,请业务数据映射到画布的线上,所有要有两组数据,一组为业务数据,另外一组则是画布的一个线段
* 刻度:类似米尺上的刻度,比如一厘米一大格,中间又有一些代表毫米的小格
* 相对位置:米尺是个实物,而这里的刻度是画在画布上的,就是刻度在画布上的位置
*/ function renderXAxis() { //domain是值就是d3.svg.axis坐标系的x与y的值 //svg.axis就是业务数据坐标系,其数据是有业务含义的 //range的值是svg画布像素的长度,意思就是要将业务数据domain画在(映射到)svg画布的指定长度范围内 let scale = d3.scale.linear() .domain([0,100]) .range([0,xAxisLength]);
xAxis
= d3.svg.axis() .scale(scale) .tickSubdivide(1) .orient("bottom");

//<sgv class="axis"><g class="x-axis" >...<g class="y-axis" ... svg.append(
"g") .attr("class","x-axis") .attr("transform",function () { return "translate("+margin+","+(xAxisLength+margin)+")"; }) .call(xAxis); } function renderYAxis() { let scale = d3.scale.linear() .domain([100,0]) .range([0,yAxisLength]) yAxis = d3.svg.axis() .scale(scale) .tickSubdivide(1) .orient("left");
//坐标轴是以svg标签下的g标签为画板的 svg.append(
"g") .attr("class","y-axis") .attr("transform",function () { return "translate("+margin+","+margin+")"; }) .call(yAxis); } /** * X坐标轴对应的网格线对应的两个点 * 一个是坐标系原点(0,0) * 一个是Y轴的终点(0,-yAxisLength) */ function renderXGridLines() { //通常坐标重构前都会删除已有的图形,尽管有时它不并存在 d3.selectAll("g.x-axis g.tick") .select("line.grid-line") .remove(); //然后重新选取新的图形 let lines = d3.selectAll("g.x-axis g.tick") .append("line") .classed("grid-line",true); //图形中涉及的坐标系是SVG坐标系,上负下正,右正 lines.attr("x1",0) .attr("y1",0) .attr("x2",0) .attr("y2",-yAxisLength); } /** * Y坐标轴对应的网格线对应的两个点 * 一个是坐标系原点(0,0) * 一个是X轴的终点(xAxisLength,0) */ function renderYGridLines() { //通常坐标重构前都会删除已有的图形,尽管有时它不并存在 d3.selectAll("g.y-axis g.tick") .select("line.grid-line") .remove(); //然后重新选取新的图形 let lines = d3.selectAll("g.y-axis g.tick") .append("line") .classed("grid-line",true); lines.attr("x1",0) .attr("y1",0) .attr("x2",xAxisLength) .attr("y2",0); } /** * 通过改变坐标轴的尺度来重构坐标系 */ function rescale() { let max = Math.round(Math.random()*100); let duration = 5000; xAxis.scale().domain([0,max]); //构建坐标轴会在g标签中添加class为tick的g标签,删除这个就相当于删除了坐标轴 //call方法中会自动删除,所以这里不需要这一步了 // d3.selectAll("g.x-axis g.tick") // .remove(); d3.select("g.x-axis") .transition() .duration(duration) .call(xAxis); yAxis.scale().domain([max,0]); d3.select("g.y-axis") .transition() .duration(duration) .call(yAxis); renderXGridLines(); renderYGridLines(); } renderXAxis(); renderYAxis(); renderXGridLines(); renderYGridLines(); </script> </body> </html>

 

附css样式 css/styles.css

body {
    font-family: "helvetica";
}

button {
    margin: 0 7px 0 0;
    background-color: #f5f5f5;
    border: 1px solid #dedede;
    border-top: 1px solid #eee;
    border-left: 1px solid #eee;

    font-size: 12px;
    line-height: 130%;
    text-decoration: none;
    font-weight: bold;
    color: #565656;
    cursor: pointer;
}

.box {
    width: 200px;
    height: 200px;
    margin: 40px;
    float: left;
    text-align: center;
    border: #969696 solid thin;
    padding: 5px;
}

.red {
    background-color: #e9967a;
    color: #f0f8ff;
}

.blue {
    background-color: #add8e6;
    color: #f0f8ff;
}

.cell {
    min-width: 40px;
    min-height: 20px;
    margin: 5px;
    float: left;
    text-align: center;
    border: #969696 solid thin;
    padding: 5px;
}

.fixed-cell {
    min-width: 40px;
    min-height: 20px;
    margin: 5px;
    position: fixed;
    text-align: center;
    border: #969696 solid thin;
    padding: 5px;
}

.h-bar {
    min-height: 15px;
    min-width: 10px;
    background-color: steelblue;
    margin-bottom: 2px;
    font-size: 11px;
    color: #f0f8ff;
    text-align: right;
    padding-right: 2px;
}

.v-bar {
    min-height: 1px;
    min-width: 30px;
    background-color: #4682b4;
    margin-right: 2px;
    font-size: 10px;
    color: #f0f8ff;
    text-align: center;
    width: 10px;
    display: inline-block;
}

.baseline {
    height: 1px;
    background-color: black;
}

.clear {
    clear: both;
}

.selected {
    background-color: #f08080;
}

.control-group {
    padding-top: 10px;
    margin: 10px;
}

.table {
    width: 70%;
}

.table td, th {
    padding: 5px;
}

.table-header {
    background-color: #00AFEF;
    font-weight: bold;
}

.table-row-odd {
    background-color: #f0f8ff;
}

.table-row-odd {
    background-color: #d3d3d3;
}

.code {
    display: inline-block;
    font-style: italic;
    background-color: #d3d3d3;
    border: #969696 solid thin;
    padding: 10px;
    margin-top: 10px;
    margin-bottom: 10px;
}

.countdown{
    width: 150px;
    height: 150px;
    font-size: 5em;
    font-weight: bold;
}

.axis path, .axis line {
    fill: none;
    stroke: #000;
    shape-rendering: crispEdges;
}

.axis text {
    font: 10px sans-serif;
}

.axis .grid-line{
    stroke: black;
    shape-rendering: crispEdges;
    stroke-opacity: .2;
}

.line{
    fill: none;    
    stroke: steelblue;
    stroke-width: 2;
}

.dot {
  fill: #fff;
  stroke: steelblue;
}

.area {
    stroke: none;
    fill: steelblue;
    fill-opacity: .2;
}

.pie text{
    fill: white;
    font-weight: bold;
}

.circle {
    stroke: none;
    fill: red;
    fill-opacity: .7;
}

.cross {
    stroke: none;
    fill: blue;
    fill-opacity: .7;
}

.diamond {
    stroke: none;
    fill: green;
    fill-opacity: .7;
}

.square{
    stroke: none;
    fill: yellow;
    fill-opacity: .7;
}

.triangle-down{
    stroke: none;
    fill: blueviolet;
    fill-opacity: .7;
}

.triangle-up{
    stroke: none;
    fill: darkred;
    fill-opacity: .7;
}

.bubble{
    fill-opacity: .3;
}

.bar{
    stroke: none;
    fill: steelblue;
}

 

posted @ 2020-06-14 10:40  方诚  阅读(940)  评论(0编辑  收藏  举报