DojoD3BarChart.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. define([
  2. "dojo/_base/declare",
  3. "dojo/_base/lang",
  4. "./DojoD3",
  5. "./Mapping",
  6. "dojo/text!./templates/DojoD3BarChart.css"
  7. ], function (declare, lang,
  8. DojoD3, Mapping,
  9. css) {
  10. return declare([Mapping, DojoD3], {
  11. mapping: {
  12. barChart: {
  13. display: "Bar Chart Data",
  14. fields: {
  15. label: "Label",
  16. value: "Value"
  17. }
  18. }
  19. },
  20. constructor: function (mappings, target) {
  21. if (mappings)
  22. this.setFieldMappings(mappings);
  23. if (target)
  24. this.renderTo(target);
  25. },
  26. renderTo: function (_target) {
  27. _target = lang.mixin({
  28. css: css,
  29. margin: { top: 0, right: 0, bottom: 20, left: 50 }
  30. }, _target);
  31. this.inherited(arguments);
  32. this.SvgG
  33. .style("fill", "none")
  34. ;
  35. this.x = d3.scale.ordinal()
  36. .rangeRoundBands([0, this.target.width - (this.target.margin.left + this.target.margin.right)], .1);
  37. this.y = d3.scale.linear()
  38. .range([this.target.height - (this.target.margin.top + this.target.margin.bottom), 0])
  39. ;
  40. this.xAxis = d3.svg.axis()
  41. .scale(this.x)
  42. .orient("bottom")
  43. ;
  44. this.yAxis = d3.svg.axis()
  45. .scale(this.y)
  46. .orient("left")
  47. ;
  48. this.SvgG
  49. .attr("transform", "translate(" + this.target.margin.left + "," + this.target.margin.top + ")")
  50. ;
  51. this.SvgX = this.Svg.append("g")
  52. .attr("transform", "translate(" + this.target.margin.left + "," + (this.target.height - this.target.margin.bottom) + ")")
  53. .attr("class", "x axis")
  54. .call(this.xAxis)
  55. ;
  56. this.SvgY = this.Svg.append("g")
  57. .attr("transform", "translate(" + this.target.margin.left + "," + this.target.margin.top + ")")
  58. .attr("class", "y axis")
  59. .call(this.yAxis)
  60. ;
  61. this.update([]);
  62. },
  63. display: function (data) {
  64. if (data)
  65. this.setData(data);
  66. var data = this.getMappedData();
  67. this.x.domain(data.map(function (d) { return d.label; }));
  68. this.y.domain([0, d3.max(data, function (d) { return d.value; })]);
  69. this.Svg.selectAll("g.y.axis").transition()
  70. .call(this.yAxis)
  71. ;
  72. this.Svg.selectAll("g.x.axis").transition()
  73. .call(this.xAxis)
  74. ;
  75. this.update(data);
  76. },
  77. update: function (data) {
  78. // DATA JOIN
  79. // Join new data with old elements, if any.
  80. var bar = this.SvgG.selectAll(".bar").data(data);
  81. // UPDATE
  82. // Update old elements as needed.
  83. bar
  84. .attr("class", "bar")
  85. ;
  86. // ENTER
  87. // Create new elements as needed.
  88. bar.enter().append("rect")
  89. .attr("class", "bar")
  90. .on("click", lang.hitch(this, function (d) {
  91. var evt = {};
  92. evt[this.getFieldMapping("label")] = d.label;
  93. this.emit("click", evt);
  94. }))
  95. .append("title").text(lang.hitch(this, function (d) { return d.value; }))
  96. ;
  97. // ENTER + UPDATE
  98. // Appending to the enter selection expands the update selection to include
  99. // entering elements; so, operations on the update selection after appending to
  100. // the enter selection will apply to both entering and updating nodes.
  101. bar.transition()
  102. .attr("x", lang.hitch(this, function (d) { return this.x(d.label); }))
  103. .attr("width", this.x.rangeBand())
  104. .attr("y", lang.hitch(this, function (d) { return this.y(d.value); }))
  105. .attr("height", lang.hitch(this, function (d) { return this.target.height - (this.target.margin.top + this.target.margin.bottom) - this.y(d.value); }))
  106. ;
  107. // EXIT
  108. // Remove old elements as needed.
  109. bar.exit().remove();
  110. }
  111. });
  112. });