PercenCharts.vue 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <template>
  2. <div :style="{display:'inline-block',height:'500px',width:'680px'}" ref="chartsRef" >
  3. </div>
  4. </template>
  5. <script setup>
  6. import {reactive, onMounted, ref,watch} from "vue";
  7. import {getXAxis,getNongDataTotal,getSeries,getYAxisParams,getTwoMonthDateStr,getNSData} from "./common";
  8. import * as echarts from "echarts";
  9. let myChart = null;
  10. let props = defineProps({
  11. title: {//标题,物候期
  12. type: String,
  13. default: "",
  14. },
  15. targetField:{//物候期指标字段
  16. type: String,
  17. default: "",
  18. },
  19. targetName:{//物候期指标名称
  20. type: String,
  21. default: "",
  22. },
  23. last:{
  24. type:Boolean,
  25. default:false
  26. },
  27. bgColor:{
  28. type:String,
  29. default:'#F5F5F5'
  30. },
  31. treeId:{
  32. type:Number,
  33. default:null
  34. },
  35. currentPeriod:{
  36. type: Object,
  37. default: new Object()
  38. },
  39. })
  40. const chartsRef = ref(null);
  41. const treeGrowData = ref(null);
  42. let intFields = ['flowerLength','yield'];
  43. let percent = true;
  44. let nzNames = [];
  45. let numberInterval = null;
  46. const nzv = ref([]);
  47. const treeNSData = ref([]);
  48. const option = reactive({
  49. backgroundColor:props.bgColor,
  50. "title": {
  51. "text": "",
  52. show:true,
  53. },
  54. animation: true,
  55. "tooltip": [{
  56. "trigger": "item",
  57. formatter:function(data){
  58. if(data.data.value < 0){
  59. return data.seriesName;
  60. }
  61. if(percent){
  62. return data.name+"<br/>"+data.seriesName+" : "+(data.data.value * 100).toFixed(0) + "%";
  63. }else{
  64. return data.name+"<br/>"+data.seriesName+" : "+(data.data.value).toFixed(2);
  65. }
  66. }
  67. }],
  68. "grid": {
  69. "left": "3%",
  70. "right": "3%",
  71. show: true,
  72. z: 0,
  73. containLabel: true,
  74. backgroundColor: "rgba(0,0,0,0)",
  75. borderWidth: 1,
  76. borderColor: "#ccc"
  77. },
  78. "xAxis": {
  79. "type": "category",
  80. "boundaryGap": true,
  81. "data": [],
  82. axisLabel: {
  83. formatter: function (value, index) {
  84. // 返回自定义格式的标签
  85. return value.substr(5,10);
  86. }
  87. },
  88. minorTick: {
  89. show: false
  90. },
  91. minorSplitLine: {
  92. show: true
  93. },
  94. splitLine: {
  95. show: true
  96. }
  97. },
  98. "yAxis": {
  99. "type": "value",
  100. interval:0.1,
  101. min: -1, // 自定义最小值
  102. max: 1, // 自定义最大值
  103. axisLabel: {
  104. show: true,
  105. interval: 'auto',
  106. formatter: function(value,index){
  107. if(value < 0){
  108. for(let i=0;i< nzNames.length;i++){
  109. if((value * 100).toFixed(0) == (nzv.value[i] * 100).toFixed(0)){
  110. return nzNames[i];
  111. }
  112. }
  113. return "";
  114. }else{
  115. if(percent){
  116. value = (value * 100).toFixed(0)
  117. if(value % 20 == 0){
  118. return value + "%";
  119. }
  120. }else{
  121. if(numberInterval != null && Math.ceil(value) % numberInterval == 0){
  122. return Math.ceil(value);
  123. }else{
  124. return "";
  125. }
  126. }
  127. }
  128. }
  129. }
  130. },
  131. "series": [
  132. ]
  133. });
  134. watch(() => props.currentPeriod, (newVal, oldVal) => {
  135. getGrowData(props.treeId,function(){
  136. //不是整数的指标,最小值为0
  137. getTreeNSData(function(){
  138. refreshChart();
  139. });
  140. });
  141. })
  142. function changeType(){
  143. getTreeNSData(function(){
  144. refreshChart();
  145. });
  146. }
  147. function refreshChart(){
  148. //y轴
  149. //不是整数的指标,最小值为0
  150. if(intFields.indexOf(props.targetField) != -1){
  151. percent = false;
  152. }else{
  153. percent = true;
  154. }
  155. let [min1,max1,interval1,nzNames1,nzv1] = getYAxisParams(props.targetField,props.currentPeriod,treeGrowData.value,percent)
  156. option.title.text = props.title;
  157. nzNames = nzNames1;
  158. nzv.value = nzv1;
  159. option.yAxis.interval = interval1;
  160. option.yAxis.min = min1;
  161. option.yAxis.max = max1;
  162. numberInterval = interval1*3;
  163. //x轴
  164. option.xAxis.data = getXAxis();
  165. //series
  166. let series = getSeries(props.currentPeriod,props.targetName,props.targetField,treeGrowData.value);
  167. // option.series = series;
  168. console.log(series);
  169. //农事活动
  170. let nsSeries = getNSData(treeNSData.value,props.currentPeriod,nzv.value);
  171. option.series = series.concat(nsSeries);
  172. console.log(JSON.stringify(option));
  173. if(myChart){
  174. myChart.clear();
  175. myChart.setOption(option);
  176. }
  177. }
  178. async function getTreeNSData(callback){
  179. if(treeNSData.value && treeNSData.value.length != 0){
  180. callback();
  181. return;
  182. }
  183. let forms2 = {treeId:props.treeId,dateRange:getTwoMonthDateStr(),direction:0,sortField:['startDate'],page:1,limit:10000}
  184. let {code,data} = await VE_API.tree.siteList(forms2);
  185. if(code == 0){
  186. treeNSData.value = getNongDataTotal(data);
  187. callback();
  188. }
  189. }
  190. async function getGrowData(treeId,callback){
  191. if(treeGrowData.value != null){
  192. callback();
  193. }
  194. let forms = new FormData();
  195. forms.append("treeId",treeId);
  196. let list = [];
  197. //生长数据列表
  198. let {code,data} = await VE_API.tree.treeGrowData(forms);
  199. if(code == 0){
  200. list = data;
  201. }
  202. treeGrowData.value = list;
  203. callback();
  204. }
  205. const autoWidth = ref(option.xAxis.data.length * 60)
  206. onMounted(async ()=>{
  207. myChart = echarts.init(chartsRef.value,{width:"90%"});
  208. })
  209. defineExpose({
  210. changeType
  211. })
  212. </script>