在选择下拉列表时切换d3图表

时间:2015-11-30 10:31:16

标签: javascript jquery d3.js

您好我在我的模块中实现了D3.js图表​​。我需要根据我的下拉选择,我的图表类型会相应更新。

JsFiddle

我有sample.json个文件从json检索数据。

{
    "sample2": [{
        "time": 1387212120,
        "open": 368,
        "close": 275,
        "high": 380,
        "low": 158
    }, {
        "time": 1387212130,
        "open": 330,
        "close": 350,
        "high": 389,
        "low": 310
    }, {
        "time": 1387212140,
        "open": 213,
        "close": 253,
        "high": 289,
        "low": 213
    }, {
        "time": 1387212150,
        "open": 180,
        "close": 150,
        "high": 189,
        "low": 110
    }, {
        "time": 1387212160,
        "open": 310,
        "close": 350,
        "high": 389,
        "low": 310
    }]
}

1 个答案:

答案 0 :(得分:3)

Line是您在演示中选择的默认图表。因此,您应该在下拉列表中默认选择该选项(目前,我已将'line'作为代码段中的第一个选项,默认情况下将被选中)。另请注意,绑定到饼图路径的数据不正确。您应该如下所示绑定数据,并且由于饼图需要绘制多个路径,因此您应该使用selectAllenter方法。

var container = canvas.selectAll(".arc")
      .data(pie(sample2))
      .enter().append("path")

而不是

 canvas.append("path")
       .datum(sample2);

在饼图和其他图表之间切换时,隐藏/显示x和y轴。

// loading sample.json
var sample2 = {
  "sample2": [{
    "time": 1387212120,
    "open": 368,
    "close": 275,
    "high": 380,
    "low": 158
  }, {
    "time": 1387212130,
    "open": 330,
    "close": 350,
    "high": 389,
    "low": 310
  }, {
    "time": 1387212140,
    "open": 213,
    "close": 253,
    "high": 289,
    "low": 213
  }, {
    "time": 1387212150,
    "open": 180,
    "close": 150,
    "high": 189,
    "low": 110
  }, {
    "time": 1387212160,
    "open": 310,
    "close": 350,
    "high": 389,
    "low": 310
  }]
};

sample2 = sample2.sample2
  // date manipulation to format UTC to js Date obj
sample2.forEach(function(d) {
  d.time = new Date(d.time * 1000);
});

// helpers and constants
var margin = {
  "top": 50,
  "right": 100,
  "bottom": 56,
  "left": 50
};
var width = 930 - margin.right - margin.left;
var height = 582 - margin.top - margin.bottom;
var radius = Math.min(width, height) / 2;
var timeFormat = d3.time.format("%c");
var X = width / sample2.length * 0.25;

// find data range
var xDomain = d3.extent(sample2, function(d, i) {
  return d.time;
});
var yMin = d3.min(sample2, function(d) {
  return Math.min(d.low);
});
var yMax = d3.max(sample2, function(d) {
  return Math.max(d.high);
});

// scales, add 10pc padding to x-domain
var xScale = d3.time.scale()
  .domain(xDomain);

var arc = d3.svg.arc()
  .innerRadius(radius - 100)
  .outerRadius(radius - 20);


xScale.domain([-0.1, 1.1].map(xScale.invert))
  .range([margin.left, width - margin.right]);

var yScale = d3.scale.linear()
  .domain([yMin, yMax])
  .range([height - margin.top, margin.bottom]);

// set up axes
var xAxis = d3.svg.axis()
  .scale(xScale)
  .orient("bottom")
  .ticks(10)
  .tickPadding(10);
// .tickFormat(timeFormat)

var yAxis = d3.svg.axis()
  .scale(yScale)
  .orient("right")
  .tickValues(yScale.domain());

// set up chart types
var area = d3.svg.area()
  .x(function(d) {
    return xScale(d.time);
  })
  .y0(height - margin.bottom)
  .y1(function(d) {
    return yScale(d.close);
  });

var line = d3.svg.line().interpolate("monotone")
  .x(function(d) {
    return xScale(d.time);
  })
  .y(function(d) {
    return yScale(d.close);
  });

var pie = d3.layout.pie()
  .value(function(d) {
    return d.time;
  })
  .sort(null);

// create svg container and offset
var canvas = d3.select("body").append("svg")
  .attr({
    "width": width,
    "height": height
  })
  .append("g")
  .attr("transform", "translate(" + margin.top / 2 + "," + margin.left / 2 + ")");

var color = d3.scale.category20();
// gridsk
canvas.append("svg:rect")
  .attr({
    "width": width - margin.right - margin.left,
    "height": height - margin.bottom - margin.top,
    "class": "plot",
    "transform": "translate(" + margin.top + "," + margin.bottom + ")"
  });

// chart options by type
var chartDraw = {

  candle: function() {

    canvas.selectAll("line.candle")
      .data(sample2)
      .enter()
      .append("svg:line")
      .attr({
        "class": "candle alt-view",
        "x1": function(d, i) {
          return xScale(d.time) - X * 0.5;
        },
        "x2": function(d, i) {
          return xScale(d.time) - X * 0.5;
        },
        "y1": function(d, i) {
          return yScale(d.high);
        },
        "y2": function(d, i) {
          return yScale(d.low);
        },
        "stroke": "black"
      });

    canvas.selectAll("rect.candle")
      .data(sample2)
      .enter()
      .append("svg:rect")
      .attr({
        "class": "candle alt-view",
        "width": function(d) {
          return X
        },
        "x": function(d, i) {
          return xScale(d.time) - X;
        },
        "y": function(d, i) {
          return yScale(Math.max(d.open, d.close));
        },
        "height": function(d, i) {
          return yScale(Math.min(d.open, d.close)) - yScale(Math.max(d.open, d.close));
        },
        "fill": function(d) {
          return d.open > d.close ? "#dc432c" : "#0CD1AA"
        },
        "stroke": "gray"
      });

  },

  line: function() {

    canvas.append("path")
      .datum(sample2)
      .attr("class", "line alt-view")
      .attr("d", line);
  },

  pie: function() {
    var container = canvas.selectAll(".arc")
      .data(pie(sample2))
      .enter().append("path")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
      .attr("class", "pie alt-view")
      .attr("fill", function(d, i) {
        return color(i);
      })
      .attr("d", arc)
      .each(function(d) {
        this._current = d;
      });
  },

  area: function() {

    canvas.append("path")
      .datum(sample2)
      .attr("class", "area alt-view")
      .attr("d", area);
  }
};


// draw axes
canvas.append('g').classed("axis", true).call(xAxis)
  .attr('transform', 'translate(0, ' + (height - margin.bottom) + ')');
canvas.append('g').classed("axis", true).call(yAxis)
  .attr('transform', 'translate(' + (width - margin.right) + ', 0)');

// drop down menu
var chartOptions = ["line", "candle", "area", "pie"];
var dropdown = d3.select("body").append("foreignObject")
  .attr({
    "height": 100,
    "width": 300,
    "transform": "translate(" + margin.left * 1.3 + "," + margin.top * 0.7 + ")"
  })
  .append("xhtml:select")
  .on("change", function() {

    d3.selectAll(".alt-view").remove();

    selected = this.value;

    if (selected == "line") {
      canvas.selectAll(".axis").style("display", "block");
      canvas.select(".plot").style("display", "block");
      chartDraw.line();
    } else if (selected == "area") {
      canvas.selectAll(".axis").style("display", "block");
      canvas.select(".plot").style("display", "block");
      chartDraw.area();
    } else if (selected == "candle") {
      canvas.selectAll(".axis").style("display", "block");
      canvas.select(".plot").style("display", "block");
      chartDraw.candle();
    } else if (selected == "pie") {
      canvas.selectAll(".axis").style("display", "none");
      canvas.select(".plot").style("display", "none");
      chartDraw.pie();
    }

  })
  .attr("id", "drop-down")
  .selectAll("option")
  .data(chartOptions)
  .enter()
  .append("option")
  .text(function(d) {
    return d;
  })
  .attr("value", function(d) {
    return d;
  });


// default chart
chartDraw.line();
.line {
  fill: none;
  stroke: #0CD1AA;
  stroke-width: 3px;
}
.area {
  fill: #0cd1aa;
  stroke: #dc432c;
  stroke-width 0.5;
}
.plot {
  fill: lightblue;
  opacity: 0.5;
}
<script src="http://d3js.org/d3.v3.min.js"></script>
<script src="inlet.js"></script>
<link src="style.css" />

<body></body>