bubble.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. ;(function() {
  2. var extra = {}
  3. c3.chart.internal.fn.additionalConfig = {
  4. data_pairs: []
  5. }
  6. c3.chart.internal.fn.beforeInit = function(config) {
  7. var that = this
  8. // update internals only when chart type is "bubble"
  9. if (config.data.type !== 'bubble') {
  10. return
  11. }
  12. // Set extra to ba able to be used in other part
  13. this.extra = extra
  14. extra.getKey = function(x, y) {
  15. return x + '::' + y
  16. }
  17. this.config.data_type = 'scatter'
  18. this.config.axis_x_padding = 0
  19. this.config.axis_y_padding = 0
  20. this.config.axis_x_tick_centered = true
  21. this.config.axis_x_tick_format = function(d) {
  22. return extra.names[d]
  23. }
  24. this.config.axis_y_tick_format = function(d) {
  25. return extra.names[d]
  26. }
  27. if (!config.color || !config.color.pattern) {
  28. this.config.color_pattern = ['#1f77b4']
  29. }
  30. this.config.point_r = function(d) {
  31. var names = extra.names,
  32. values = extra.values,
  33. base_length = extra.base_length,
  34. x = names[d.x],
  35. y = d.id,
  36. key = extra.getKey(x, y),
  37. value = !values[key] ? 0 : values[key],
  38. max,
  39. max_r,
  40. max_area,
  41. a,
  42. area,
  43. r
  44. if (!base_length) {
  45. base_length = extra.base_length = d3.min([
  46. that.svg
  47. .select('.c3-axis.c3-axis-y path')
  48. .node()
  49. .getTotalLength(),
  50. that.svg
  51. .select('.c3-axis.c3-axis-x path')
  52. .node()
  53. .getTotalLength()
  54. ])
  55. }
  56. max = d3.max(
  57. Object.keys(values).map(function(key) {
  58. return values[key]
  59. })
  60. )
  61. max_r = base_length / (names.length * 2)
  62. max_area = max_r * max_r * Math.PI
  63. a = max_area / max
  64. area = value * a
  65. r = Math.sqrt(area / Math.PI)
  66. return r
  67. }
  68. this.config.point_sensitivity = 25
  69. this.config.point_focus_expand_enabled = false
  70. this.config.legend_show = false
  71. if (!config.tooltip || !config.tooltip.contents) {
  72. this.config.tooltip_contents = function(
  73. d,
  74. defaultTitleFormat,
  75. defaultValueFormat,
  76. color
  77. ) {
  78. var x = extra.names[d[0].x],
  79. y = d[0].name,
  80. v = extra.values[extra.getKey(x, y)],
  81. text
  82. text = "<table class='" + this.CLASS.tooltip + "'>"
  83. text += "<tr><th colspan='2'>" + x + '&nbsp;/&nbsp;' + y + '</th></tr>'
  84. text += "<tr><td class='value'>" + (!v ? 0 : v) + '</td></tr>'
  85. text += '</table>'
  86. return text
  87. }
  88. }
  89. // construct bubble chart data and setup config based on the values
  90. var xs = this.config.data_pairs.map(function(pair) {
  91. return pair.x
  92. }),
  93. ys = this.config.data_pairs.map(function(pair) {
  94. return pair.y
  95. })
  96. extra.names = d3
  97. .set(xs.concat(ys))
  98. .values()
  99. .sort()
  100. this.config.axis_y_tick_values = extra.names.map(function(name, i) {
  101. return i
  102. })
  103. var data_xs = {}
  104. extra.names.forEach(function(name) {
  105. data_xs[name] = name + '_x'
  106. })
  107. var data_columns_xs = Object.keys(data_xs).map(function(key) {
  108. return [data_xs[key]].concat(
  109. extra.names.map(function(name, i) {
  110. return i
  111. })
  112. )
  113. })
  114. var data_columns_values = extra.names.map(function(name, i) {
  115. return [name].concat(
  116. extra.names.map(function(name) {
  117. return i
  118. })
  119. )
  120. })
  121. this.config.data_xs = data_xs
  122. this.config.data_columns = data_columns_xs.concat(data_columns_values)
  123. var values = {}
  124. this.config.data_pairs.forEach(function(pair) {
  125. if (!pair.x || !pair.y) {
  126. throw 'x and y are required in data.'
  127. }
  128. values[extra.getKey(pair.x, pair.y)] = pair.value
  129. })
  130. extra.values = values
  131. this.config.axis_x_min = this.config.axis_y_min = -0.5
  132. this.config.axis_x_max = this.config.axis_y_max = extra.names.length - 0.5
  133. }
  134. })(window)