| | |
| | | /** |
| | | * param_data_basic |
| | | * |
| | | * @author zt generator |
| | | * @author zt generator |
| | | * @since 1.0.0 2024-07-11 |
| | | */ |
| | | @Service |
| | | public class ParamDataBasicService extends BaseService<ParamDataBasicDao, ParamData> { |
| | | public class ParamDataBasicService extends BaseService<ParamDataBasicDao, ParamData> { |
| | | |
| | | /** |
| | | * 分页查询 |
| | |
| | | */ |
| | | public List<ParamData> page(QueryFilter queryFilter) { |
| | | List<ParamData> list = baseDao.getAI(queryFilter.getQueryParams()); |
| | | for (ParamData data : list) { |
| | | if (data.getBasicMtbfOperatingRatio() == null || data.getBasicMtbfOperatingRatio() == 0.0) { |
| | | data.setBasicMtbfOperatingRatio(1.0); |
| | | } |
| | | } |
| | | return TreeUtils.build(list); |
| | | } |
| | | |
| | |
| | | } |
| | | |
| | | public void compute(Long shipId) { |
| | | baseDao.compute(shipId,4); |
| | | baseDao.compute(shipId,3); |
| | | baseDao.compute(shipId,2); |
| | | baseDao.compute(shipId, 4); |
| | | baseDao.compute(shipId, 3); |
| | | baseDao.compute(shipId, 2); |
| | | baseDao.compute2(shipId); |
| | | } |
| | | } |
| | |
| | | import com.zt.common.annotation.QueryParam; |
| | | import com.zt.common.db.query.QueryFilter; |
| | | import com.zt.common.servlet.Result; |
| | | import com.zt.common.utils.UUIDUtil; |
| | | import com.zt.common.validator.AssertUtils; |
| | | import com.zt.common.validator.ValidatorUtils; |
| | | import com.zt.common.validator.group.AddGroup; |
| | |
| | | import com.zt.common.validator.group.UpdateGroup; |
| | | import com.zt.life.core.service.ZtProductService; |
| | | import com.zt.life.dto.ImportErrDto; |
| | | import com.zt.life.modules.mainPart.basicInfo.model.ParamData; |
| | | import com.zt.life.modules.mainPart.basicInfo.model.ProductImg; |
| | | import com.zt.life.modules.mainPart.basicInfo.model.XhProductModel; |
| | | import com.zt.life.modules.mainPart.basicInfo.service.ParamDataService; |
| | | import com.zt.life.modules.mainPart.basicInfo.service.XhProductModelService; |
| | | import com.zt.life.modules.mainPart.sysPictureBase.service.SysPictureBaseService; |
| | | import com.zt.life.util.ImportUtil; |
| | |
| | | |
| | | @Autowired |
| | | private SysPictureBaseService sysPictureBaseService; |
| | | |
| | | @Autowired |
| | | private ParamDataService paramDataService; |
| | | |
| | | @GetMapping("page") |
| | | @ApiOperation("分页") |
| | |
| | | if (xhProductModel.getSort() == null || xhProductModel.getSort() < no) { |
| | | xhProductModel.setSort(no + 1); |
| | | } |
| | | if (xhProductModel.getProductType().equals("2")){ |
| | | Long id = UUIDUtil.generateId(); |
| | | xhProductModel.setId(id); |
| | | xhProductModel.setShipId(id); |
| | | |
| | | ParamData data =new ParamData(); |
| | | data.setShipId(id); |
| | | data.setProductId(id); |
| | | data.setPageCode("expect"); |
| | | paramDataService.insert(data); |
| | | } |
| | | |
| | | xhProductModelService.insert(xhProductModel); |
| | | |
| | | return Result.ok(); |
| | |
| | | } |
| | | |
| | | public List<Map<String, Object>> importProductExcel(MultipartFile mutFile, String progressId, Long shipId) { |
| | | int count = 0; |
| | | Date beginDate = new Date(); |
| | | List<Map<String, Object>> list = new ArrayList<>();//存储所有的导入状态 |
| | | Map<String, Object> map;//存储每一行的状态 |
| | |
| | | isOrNot.put("是", 1); |
| | | isOrNot.put("否", 0); |
| | | |
| | | //获取是否有数据,如果有则删除数据 |
| | | /* List<XhProductModel> productList = this.getByShipId(shipId); |
| | | List<ParamData> dataList = paramDataService.getByShipId(shipId); |
| | | if (productList.size() > 0) { |
| | | this.deleteByShipId(shipId); |
| | | } |
| | | if (dataList.size() > 0) { |
| | | paramDataService.deleteByShipId(shipId); |
| | | }*/ |
| | | |
| | | try { |
| | | // 获取导入文件的后缀名 |
| | | String fileName = mutFile.getOriginalFilename(); |
| | |
| | | assert workbook != null; //断言如果[boolean表达式]为true,则程序继续执行。 如果为false,则程序抛出AssertionError,并终止执行。 |
| | | int sheets = workbook.getNumberOfSheets(); |
| | | |
| | | //List<LifeManagement> lifeManagementList = new ArrayList<LifeManagement>(); |
| | | Long curXtId = null; |
| | | Long curFxtId = null; |
| | | Long curSbId = null; |
| | |
| | | insertSb = false; |
| | | CacheUtils.put(progressId, "speed", CommonUtils.getPercent(j, num)); |
| | | CacheUtils.put(progressId, "msg", "共" + num + "行,已完成第" + j + "行"); |
| | | /* boolean isToggleXt = false; |
| | | boolean isToggleFxt = false;*/ |
| | | |
| | | row1 = j + 1; |
| | | String pattern = "yyyy-MM-dd"; |
| | | Row row = sheet.getRow(row1); |
| | | String sort = com.zt.core.shiro.ImportUtil.getCellValue(row, 0, pattern); //序号 |
| | | /* if (StringUtils.isNotBlank(com.zt.core.shiro.ImportUtil.getCellValue(row, 1, pattern))) { |
| | | if (!com.zt.core.shiro.ImportUtil.getCellValue(row, 1, pattern).equals(xt)) { |
| | | isToggleXt = true; |
| | | xtId = UUIDUtil.generateId(); |
| | | } |
| | | xt = com.zt.core.shiro.ImportUtil.getCellValue(row, 1, pattern); //系统 |
| | | } |
| | | |
| | | if (StringUtils.isNotBlank(com.zt.core.shiro.ImportUtil.getCellValue(row, 2, pattern)) && !isToggleXt) { |
| | | fxt = com.zt.core.shiro.ImportUtil.getCellValue(row, 2, pattern); //分系统 |
| | | fxtId = UUIDUtil.generateId(); |
| | | isToggleFxt = true; |
| | | } else if (isToggleXt) { |
| | | if (StringUtils.isNotBlank(com.zt.core.shiro.ImportUtil.getCellValue(row, 2, pattern))) { |
| | | fxt = com.zt.core.shiro.ImportUtil.getCellValue(row, 2, pattern); //分系统 |
| | | fxtId = UUIDUtil.generateId(); |
| | | isToggleFxt = true; |
| | | } else { |
| | | fxt = null; |
| | | isToggleFxt = true; |
| | | } |
| | | }*/ |
| | | |
| | | String xt = com.zt.core.shiro.ImportUtil.getCellValue(row, 1, pattern); //系统 |
| | | String fxt = com.zt.core.shiro.ImportUtil.getCellValue(row, 2, pattern); |
| | |
| | | ImportUtil.updateErrMap(errMap, "导入异常" + e.getMessage(), "", row1); |
| | | //err++; |
| | | } |
| | | /* if (batchList.size() > 0 && err == 0) { |
| | | super.insertBatch(batchList, 100); |
| | | baseDao.updateOldId(); |
| | | } |
| | | if (batchUpdateList.size() > 0) { |
| | | super.updateBatch(batchUpdateList, 100); |
| | | }*/ |
| | | |
| | | Date nowDate = new Date(); |
| | | String msg = "产品模型导入时间:" + CommonUtils.getDatePoor(nowDate, beginDate) + "\r\n"; |
| | | System.out.println(msg); |
| | |
| | | availability = (String) jsonArray2.getJSONObject(j).get("availability"); |
| | | } |
| | | } |
| | | |
| | | String[] arr = availability.split(" "); |
| | | // 遍历子字符串数组,将每个元素转换为double并存储到double数组中 |
| | | for (int a = 0; a < arr.length; a++) { |
| | |
| | | import com.zt.life.modules.mainPart.taskReliability.dto.ProductStatusDto; |
| | | import com.zt.life.modules.mainPart.taskReliability.dto.TaskModelCheckResult; |
| | | import com.zt.life.modules.mainPart.taskReliability.model.*; |
| | | import com.zt.life.modules.mainPart.utils.GetStringSpace; |
| | | import org.dom4j.Document; |
| | | import org.dom4j.DocumentHelper; |
| | | import org.dom4j.Element; |
| | |
| | | import org.springframework.stereotype.Service; |
| | | import org.springframework.transaction.annotation.Transactional; |
| | | |
| | | import java.awt.*; |
| | | import java.io.BufferedReader; |
| | | import java.io.InputStream; |
| | | import java.io.InputStreamReader; |
| | |
| | | * @since 1.0.0 2024-03-20 |
| | | */ |
| | | @Service |
| | | public class SimulatAssessService extends BaseService<SimulatAssessDao, SimulatAssess> { |
| | | public class SimulatAssessService extends BaseService<SimulatAssessDao, SimulatAssess> { |
| | | private static final Logger logger = LoggerFactory.getLogger(SimulatAssessService.class); |
| | | private static final String RELIA_SIM_TASK_TYPE_SIMULATION = "calcreq"; |
| | | |
| | |
| | | x2 = x1 + status.getTimes() * pointNumPerHour + 5; |
| | | JSONObject lineJson = new JSONObject(templetsStrMap.get(status.getStatus())); |
| | | setlineXy(lineJson, x1, y, x2, y, ""); |
| | | |
| | | JsonUtils2.setJsonValueByPath(lineJson,"data/status".split("/"),status.getStatus()); |
| | | JsonUtils2.setJsonValueByPath(lineJson,"data/startTimes".split("/"),String.format("%.4f", x1)); |
| | | JsonUtils2.setJsonValueByPath(lineJson,"data/endTimes".split("/"),String.format("%.4f", x1 + status.getTimes())); |
| | | JsonUtils2.setJsonValueByPath(lineJson, "id".split("/"), UUIDUtil.generateId().toString()); |
| | | x1 = x2 - 5; |
| | | jsonArray.add(lineJson); |
| | |
| | | int spaceWitdth = 80; |
| | | x1 = -spaceWitdth; |
| | | x2 = -11; |
| | | y = -100; |
| | | y = -130; |
| | | String[] tlArr = "O,F,I,S,M".split(","); |
| | | for (String s : tlArr) { |
| | | JSONObject f = templetsMap.get(s); |
| | |
| | | //阶段模型及刻度 |
| | | x1 = 0; |
| | | x2 = 0; |
| | | double y1 = -60; |
| | | y = -30; |
| | | double y2 = -10; |
| | | JSONObject modelJson = new JSONObject(templetsStrMap.get("model")); |
| | | double y1 = -100; |
| | | y = -70; |
| | | double y2 = -50; |
| | | |
| | | setlineXy(modelJson, x1, y1, x1, y2, null); |
| | | JSONObject modelJson = new JSONObject(templetsStrMap.get("model")); |
| | | setlineXy(modelJson, 2, y1, 2, y2, null); |
| | | jsonArray.add(modelJson); |
| | | double totalHours = 0; |
| | | for (int i = 0; i < modelDtoList.size(); i++) { |
| | | JSONObject modelJson2 = new JSONObject(templetsStrMap.get("model")); |
| | | SimulatAssessTaskPhaseModel modelDto = modelDtoList.get(i); |
| | | totalHours = totalHours + modelDto.getGkDuration(); |
| | | x2 = x2 + modelDto.getGkDuration() * pointNumPerHour; |
| | | double gkPoint = modelDto.getGkDuration() * pointNumPerHour; |
| | | x2 = x2 + gkPoint; |
| | | if (i < modelDtoList.size() - 1) { |
| | | setlineXy(modelJson2, x2, y1, x2, y, null); |
| | | } else { |
| | |
| | | modelName = modelRbd.getModelName(); |
| | | modelId = modelRbd.getId().toString(); |
| | | } |
| | | |
| | | Map<String, Integer> mapSpace = GetStringSpace.getStringSpaceSize(modelName, null, 18); |
| | | JSONObject textJson = new JSONObject(templetsStrMap.get("text")); |
| | | JsonUtils2.setJsonValueByPath(textJson, "data/dataId".split("/"), modelId); |
| | | JsonUtils2.setJsonValueByPath(textJson, "id".split("/"), UUIDUtil.generateId().toString()); |
| | | JsonUtils2.setJsonValueByPath(textJson, "attrs/label/textWrap/text".split("/"), modelName); |
| | | JsonUtils2.setJsonValueByPath(textJson, "position/x".split("/"), x1 + 30); |
| | | |
| | | JsonUtils2.setJsonValueByPath(textJson, "size/width".split("/"), mapSpace.get("width") + 20); |
| | | |
| | | double x11 = x1 + ((gkPoint - mapSpace.get("width") - 20) / 2); |
| | | JsonUtils2.setJsonValueByPath(textJson, "position/x".split("/"), x11); |
| | | JsonUtils2.setJsonValueByPath(textJson, "position/y".split("/"), y1); |
| | | jsonArray.add(textJson); |
| | | x1 = x2; |
| | |
| | | setlineXy(modelJson3, 0, y, x2, y, null); |
| | | jsonArray.add(modelJson3); |
| | | |
| | | double curPointHour = 10, periodHour = 50; |
| | | Integer curPointHour = 50, periodHour = 50; |
| | | while (curPointHour < totalHours) { |
| | | JSONObject modelJson4 = new JSONObject(templetsStrMap.get("model")); |
| | | double x = curPointHour * pointNumPerHour; |
| | | setlineXy(modelJson4, x, y, x, y, null); |
| | | setlineXy(modelJson4, x, y, x, y2, null); |
| | | jsonArray.add(modelJson4); |
| | | curPointHour += 10.0; |
| | | |
| | | Map<String, Integer> mapSpace = GetStringSpace.getStringSpaceSize(curPointHour.toString(), null, 20); |
| | | JSONObject textJson = new JSONObject(templetsStrMap.get("text")); |
| | | JsonUtils2.setJsonValueByPath(textJson, "id".split("/"), UUIDUtil.generateId().toString()); |
| | | JsonUtils2.setJsonValueByPath(textJson, "attrs/label/textWrap/text".split("/"), curPointHour.toString()); |
| | | |
| | | JsonUtils2.setJsonValueByPath(textJson, "size/width".split("/"), mapSpace.get("width") + 20); |
| | | |
| | | double x11 = x - mapSpace.get("width") / 2 - 5; |
| | | JsonUtils2.setJsonValueByPath(textJson, "position/x".split("/"), x11); |
| | | JsonUtils2.setJsonValueByPath(textJson, "position/y".split("/"), y2); |
| | | jsonArray.add(textJson); |
| | | |
| | | curPointHour += periodHour; |
| | | } |
| | | |
| | | |
| | | return jsonObject.toString(); |
| | | } |
| | |
| | | JsonUtils2.setJsonValueByPath(lineJson, "source/y".split("/"), y1); |
| | | JsonUtils2.setJsonValueByPath(lineJson, "target/x".split("/"), x2); |
| | | JsonUtils2.setJsonValueByPath(lineJson, "target/y".split("/"), y2); |
| | | JsonUtils2.setJsonValueByPath(lineJson, "id".split("/"), UUIDUtil.generateId().toString()); |
| | | if (text != null) { |
| | | JsonUtils2.setArrJsonValueByPath(lineJson, "labels".split("/"), null, "0", "attrs/text/text", ""); |
| | | } |
| | |
| | | command += " -ip " + redisHost + " -port " + redisPort; |
| | | command += " -taskType " + RELIA_SIM_TASK_TYPE_SIMULATION + " -taskId " + simulatAssess.getId().toString(); |
| | | logger.info("cmd命令为:" + command); |
| | | if(System.getProperty("os.name").toLowerCase().indexOf("windows") > -1){ |
| | | if (System.getProperty("os.name").toLowerCase().indexOf("windows") > -1) { |
| | | process = Runtime.getRuntime().exec(new String[]{"cmd", "/c", command}); |
| | | }else if(System.getProperty("os.name").toLowerCase().indexOf("linux") > -1){ |
| | | } else if (System.getProperty("os.name").toLowerCase().indexOf("linux") > -1) { |
| | | process = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", command}); |
| | | }else{ |
| | | } else { |
| | | throw new Exception("暂不支持该操作系统,进行启动算法库计算!"); |
| | | } |
| | | is = process.getInputStream(); |
| | | // 以命令行方式调用算法库时,接口约定返回的结果是utf-8编码 |
| | | br = new BufferedReader(new InputStreamReader(is,"utf-8")); |
| | | br = new BufferedReader(new InputStreamReader(is, "utf-8")); |
| | | String line = br.readLine(); |
| | | logger.info("算法库返回结果:" + line); |
| | | // int exitCode = process.waitFor(); // 异步方式,不等待算法库计算完毕,所以要注释掉该行 |
| | |
| | | // 仿真次数 |
| | | jsonObject.put("simulate_times", simulatAssess.getSimulatFrequency()); |
| | | // 采样周期 |
| | | jsonObject.put("timeslice", simulatAssess.getSamplPeriod()/60.0); // 单位统一换算为小时 |
| | | jsonObject.put("timeslice", simulatAssess.getSamplPeriod() / 60.0); // 单位统一换算为小时 |
| | | jsonObject.put("result_home", resultHome); |
| | | jsonObject.put("seed", 1000); |
| | | redisTemplate.opsForValue().set(key, jsonObject.toJSONString()); |
| | |
| | | } |
| | | |
| | | private void addRepairModelsTag(List<RepairModel> repairModels, |
| | | Element root) { |
| | | Element root) { |
| | | Element ele = null; |
| | | Element repairModelsTag = root.addElement("repair_models"); |
| | | for (RepairModel repairModel : repairModels) { |
| | |
| | | } |
| | | |
| | | private void calcTaskPhaseModelDuration(TaskPhase taskPhase, |
| | | List<TaskPhaseModel> taskPhaseModelAll) { |
| | | List<TaskPhaseModel> taskPhaseModelAll) { |
| | | List<TaskPhaseModel> taskPhaseModels = taskPhaseModelDao.getListByPhaseId(taskPhase.getId()); |
| | | double totalRate = taskPhaseModels.stream().mapToDouble(TaskPhaseModel::getOperatConditDurationRate).sum(); |
| | | double sum = 0.0; |
| | |
| | | taskPhaseModelAll.add(taskPhaseModel); |
| | | } |
| | | // 把零头补到最后一个工况模型 |
| | | double duration = taskPhaseModels.get(taskPhaseModels.size()-1).getOperatConditDuration(); |
| | | taskPhaseModels.get(taskPhaseModels.size()-1).setOperatConditDuration(duration + taskPhase.getPhaseDuration() - sum); |
| | | double duration = taskPhaseModels.get(taskPhaseModels.size() - 1).getOperatConditDuration(); |
| | | taskPhaseModels.get(taskPhaseModels.size() - 1).setOperatConditDuration(duration + taskPhase.getPhaseDuration() - sum); |
| | | } |
| | | |
| | | private List<TaskPhase> calcTaskPhaseDuration(Task task) { |
| | |
| | | sum += duration; |
| | | } |
| | | // 把零头补到最后一个阶段 |
| | | double duration = taskPhases.get(taskPhases.size()-1).getPhaseDuration(); |
| | | taskPhases.get(taskPhases.size()-1).setPhaseDuration(duration + task.getTaskDuration() - sum); |
| | | double duration = taskPhases.get(taskPhases.size() - 1).getPhaseDuration(); |
| | | taskPhases.get(taskPhases.size() - 1).setPhaseDuration(duration + task.getTaskDuration() - sum); |
| | | |
| | | return taskPhases; |
| | | } |
New file |
| | |
| | | package com.zt.life.modules.mainPart.utils; |
| | | |
| | | import java.awt.*; |
| | | import java.awt.font.FontRenderContext; |
| | | import java.awt.geom.AffineTransform; |
| | | import java.util.HashMap; |
| | | import java.util.Map; |
| | | |
| | | public class GetStringSpace { |
| | | public static Map<String, Integer> getStringSpaceSize(String text, String fontFamily, int fontSize) { |
| | | fontFamily = fontFamily == null ? "" : fontFamily; |
| | | fontSize = fontSize == 0 ? 10 : fontSize; |
| | | AffineTransform affinetransform = new AffineTransform(); |
| | | FontRenderContext frc = new FontRenderContext(affinetransform, true, true); |
| | | Font font = new Font(fontFamily, Font.PLAIN, fontSize); |
| | | /* int textwidth = (int)(font.getStringBounds(text, frc).getWidth()); |
| | | int textheight = (int)(font.getStringBounds(text, frc).getHeight());*/ |
| | | Map<String, Integer> result = new HashMap<>(); |
| | | result.put("width", (int) font.getStringBounds(text, frc).getWidth()); |
| | | result.put("height", (int) font.getStringBounds(text, frc).getHeight()); |
| | | return result; |
| | | } |
| | | } |
| | |
| | | <mapper namespace="com.zt.life.modules.mainPart.baseReliability.dao.ParamDataBasicDao"> |
| | | <update id="compute"> |
| | | update param_data f, |
| | | ( |
| | | SELECT |
| | | c.*, |
| | | CASE |
| | | WHEN WeightedFailure IS NOT NULL |
| | | AND WeightedFailure > 0 THEN |
| | | 1 / WeightedFailure ELSE 0 |
| | | END AS basic_mtbf_regulate, |
| | | CASE |
| | | WHEN WeightedFailure IS NOT NULL |
| | | AND WeightedFailure > 0 THEN |
| | | WeightedMTTR / WeightedFailure ELSE 0 |
| | | END AS repair_mttcr |
| | | FROM |
| | | ( |
| | | SELECT |
| | | c.id, |
| | | c.name, |
| | | sum( |
| | | CASE |
| | | WHEN b.product_type < 5 THEN |
| | | 1 * 1 / basic_mtbf_regulate |
| | | WHEN a.reliab_distrib_type = 1 THEN |
| | | 1 * a.basic_mtbf_operating_ratio / a.basic_mtbf_regulate |
| | | WHEN a.reliab_distrib_type = 2 THEN |
| | | 1 * a.basic_mtbf_operating_ratio / a.basic_mtbf_regul_succ_rate |
| | | ELSE 0 END |
| | | ) AS WeightedFailure, |
| | | sum( |
| | | CASE |
| | | WHEN b.product_type < 5 THEN |
| | | 1 * 1 * a.repair_mttcr / a.basic_mtbf_regulate |
| | | WHEN a.repairable = 1 and a.reliab_distrib_type = 1 THEN |
| | | 1 * a.basic_mtbf_operating_ratio * a.repair_mttcr / a.basic_mtbf_regulate |
| | | WHEN a.repairable = 1 and a.reliab_distrib_type = 2 THEN |
| | | 1 * a.basic_mtbf_operating_ratio * a.repair_mttcr / a.basic_mtbf_regul_succ_rate |
| | | ELSE 0 |
| | | END |
| | | ) AS WeightedMttr |
| | | FROM |
| | | param_data a, |
| | | product_model b, |
| | | product_model c |
| | | WHERE 1 = 1 |
| | | and c.ship_id = ${shipId} and c.product_type = ${productType} and c.is_delete = 0 |
| | | and b.ship_id = ${shipId} and b.pid = c.id and b.is_delete = 0 |
| | | and a.IS_DELETE = 0 and a.product_id = b.id |
| | | AND ( (b.product_type = 5 AND a.basic_join_compute = 1 |
| | | and (( |
| | | a.reliab_distrib_type = 1 |
| | | AND a.basic_mtbf_regulate > 0 |
| | | ) |
| | | OR ( a.reliab_distrib_type = 2 AND a.basic_mtbf_regul_succ_rate > 0 )) |
| | | ) |
| | | || (b.product_type < 5 AND a.basic_mtbf_regulate > 0 ) ) |
| | | GROUP BY c.id,c.name |
| | | ) c |
| | | )d set f.basic_mtbf_regulate = d.basic_mtbf_regulate, |
| | | f.repair_mttcr = d.repair_mttcr |
| | | ( |
| | | SELECT c.*, |
| | | CASE |
| | | WHEN WeightedFailure IS NOT NULL |
| | | AND WeightedFailure > 0 THEN |
| | | 1 / WeightedFailure |
| | | ELSE 0 |
| | | END AS basic_mtbf_regulate, |
| | | CASE |
| | | WHEN WeightedFailure IS NOT NULL |
| | | AND WeightedFailure > 0 THEN |
| | | WeightedMTTR / WeightedFailure |
| | | ELSE 0 |
| | | END AS repair_mttcr |
| | | FROM ( |
| | | SELECT c.id, |
| | | c.name, |
| | | sum( |
| | | CASE |
| | | WHEN b.product_type < 5 THEN |
| | | 1 * 1 / basic_mtbf_regulate |
| | | WHEN a.reliab_distrib_type = 1 THEN |
| | | 1 * a.basic_mtbf_operating_ratio / a.basic_mtbf_regulate |
| | | WHEN a.reliab_distrib_type = 2 THEN |
| | | 1 * a.basic_mtbf_operating_ratio / a.basic_mtbf_regul_succ_rate |
| | | ELSE 0 END |
| | | ) AS WeightedFailure, |
| | | sum( |
| | | CASE |
| | | WHEN b.product_type < 5 THEN |
| | | 1 * 1 * a.repair_mttcr / a.basic_mtbf_regulate |
| | | WHEN a.repairable = 1 and a.reliab_distrib_type = 1 THEN |
| | | 1 * a.basic_mtbf_operating_ratio * a.repair_mttcr / |
| | | a.basic_mtbf_regulate |
| | | WHEN a.repairable = 1 and a.reliab_distrib_type = 2 THEN |
| | | 1 * a.basic_mtbf_operating_ratio * a.repair_mttcr / |
| | | a.basic_mtbf_regul_succ_rate |
| | | ELSE 0 |
| | | END |
| | | ) AS WeightedMttr |
| | | FROM param_data a, |
| | | product_model b, |
| | | product_model c |
| | | WHERE 1 = 1 |
| | | and c.ship_id = ${shipId} |
| | | and c.product_type = ${productType} |
| | | and c.is_delete = 0 |
| | | and b.ship_id = ${shipId} |
| | | and b.pid = c.id |
| | | and b.is_delete = 0 |
| | | and a.IS_DELETE = 0 |
| | | and a.product_id = b.id |
| | | AND ((b.product_type = 5 AND a.basic_join_compute = 1 |
| | | and (( |
| | | a.reliab_distrib_type = 1 |
| | | AND a.basic_mtbf_regulate > 0 |
| | | ) |
| | | OR (a.reliab_distrib_type = 2 AND a.basic_mtbf_regul_succ_rate > 0)) |
| | | ) |
| | | || (b.product_type < 5 AND a.basic_mtbf_regulate > 0)) |
| | | GROUP BY c.id, c.name |
| | | ) c |
| | | ) d |
| | | set f.basic_mtbf_regulate = d.basic_mtbf_regulate, |
| | | f.repair_mttcr = d.repair_mttcr |
| | | where f.product_id = d.id; |
| | | </update> |
| | | |
| | | <update id="compute2"> |
| | | UPDATE param_data a, product_model b |
| | | SET ai = basic_mtbf_regulate / (basic_mtbf_regulate + repair_mttcr) |
| | | where b.ship_id = ${shipId} |
| | | where b.ship_id = ${shipId} |
| | | </update> |
| | | |
| | | <select id="getAI" resultType="com.zt.life.modules.mainPart.basicInfo.model.ParamData"> |
| | |
| | | FROM product_model a |
| | | LEFT JOIN param_data b ON b.product_id = a.id and b.is_delete = 0 |
| | | where a.is_delete = 0 |
| | | and a.ship_id = ${shipId} |
| | | or a.id =${shipId} |
| | | and a.product_type <> 10 |
| | | and a.ship_id = ${shipId} |
| | | or a.id = ${shipId} |
| | | ORDER BY a.product_type, a.sort |
| | | </select> |
| | | |
| | |
| | | await this.$tip.success() |
| | | this.$refs.dialog.close() |
| | | this.$emit('refreshDataList') |
| | | this.map.clear() |
| | | } |
| | | } |
| | | } |
| | |
| | | import {getUUID} from '../../../../packages/utils' |
| | | |
| | | export default { |
| | | name: 'RBD-edit-img', |
| | | name: 'model-view', |
| | | props: { |
| | | projectId: { |
| | | type: String |
| | |
| | | let res = await this.$http.get('/basicInfo/XhProductModel/getTaskProductList') |
| | | this.productList = res.data |
| | | console.log(this.productList, ' async getTaskProductList()') |
| | | this.onProductSelected(this.productList[0]) |
| | | }, |
| | | onProductSelected(data) { |
| | | console.log(data, ' onProductSelected(data)') |
| | | this.dataForm.productId = data.id |
| | | this.$refs.tableObj.query() |
| | | this.selectTask(data) |
| | | }, |
| | | tableRowClassName( |
| | | { |
| | |
| | | }, |
| | | // 表单提交 |
| | | async formSubmit() { |
| | | /* let flag = true |
| | | if (this.time + Number(this.dataForm.phaseDurationRate)-Number(this.oldTime) > 1) { |
| | | this.$alert("请重新设置当前时长比分配") |
| | | flag = false |
| | | } |
| | | if (!flag) { |
| | | return |
| | | }*/ |
| | | let res = await this.$http[!this.dataForm.id ? 'post' : 'put']('/taskReliability/TaskPhase/', this.dataForm) |
| | | if (res.success) { |
| | | await this.$tip.success() |
| | |
| | | this.isChange = true |
| | | return |
| | | } |
| | | /* for (let i = 0; i < this.$refs.tableObj.dataList.length; i++) { |
| | | if (this.$refs.tableObj.dataList[i] != this.lastSaveData[i]) { |
| | | console.log(i,'no') |
| | | console.log(this.$refs.tableObj.dataList[i],'this.$refs.tableObj.dataList[i]') |
| | | console.log(this.lastSaveData[i],'this.lastSaveData[i]') |
| | | this.isChange = true |
| | | return |
| | | } |
| | | }*/ |
| | | this.isChange = false |
| | | }, |
| | | |
| | |
| | | height="600px" |
| | | border @selection-change="table.selectionChangeHandle" |
| | | :header-cell-style="{'text-align':'center'}"> |
| | | <!-- <el-table-column type="selection" width="40"/>--> |
| | | <el-table-column prop="phaseName" label="阶段" align="left"/> |
| | | <el-table-column prop="equipType" label="设备类型" align="center"/> |
| | | <el-table-column prop="status" label="强制不可修" width="160" align="center"> |
| | |
| | | </el-col> |
| | | <el-col :span="20"> |
| | | <div style="margin-top: 20px"> |
| | | <div id="container" style="border: 1px solid #EAEBEE;border-radius: 6px; |
| | | <div id="timeDiagram" style="border: 1px solid #EAEBEE;border-radius: 6px; |
| | | box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);"> |
| | | </div> |
| | | </div> |
| | |
| | | </div> |
| | | </el-row> |
| | | <el-dialog v-dialogDrag title="模型设计" top="1vh" width='95%' :visible.sync="dialogVisible2" v-if="dialogVisible2"> |
| | | <RBDEditImg ref="rbdEditImg"></RBDEditImg> |
| | | <model-view ref="modelView"></model-view> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | |
| | | import SimulatCurve from "./SimulatCurve"; |
| | | import ProductModelTree from "../basicInfo/ProductModelTree"; |
| | | import {Graph, Shape, Addon, Cell} from '@antv/x6' |
| | | import RBDEditImg from './RBD-edit-img' |
| | | import ModelView from "./ModelView"; |
| | | |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | | knob:HTMLDivElement, |
| | | dialogVisible2: false, |
| | | timers: '', |
| | | shape: '', |
| | |
| | | }, |
| | | mounted() { |
| | | this.getProductList() |
| | | |
| | | }, |
| | | components: { |
| | | ModelView, |
| | | ProductModelTree, |
| | | SimulatCurve, |
| | | }, |
| | |
| | | console.log(document.documentElement.clientWidth, 'document.documentElement.clientWidth') |
| | | console.log(document.documentElement.clientHeight, 'document.documentElement.clientHeight') |
| | | this.graph = new Graph({ |
| | | container: document.getElementById('container'), |
| | | container: document.getElementById('timeDiagram'), |
| | | width: document.documentElement.clientWidth, |
| | | height: document.documentElement.clientHeight - 220, |
| | | // async: true, |
| | |
| | | }) |
| | | } |
| | | }, |
| | | onToolItemCreated({tool}) { |
| | | const handle = tool |
| | | const options = handle.options |
| | | if (options && options.index % 2 === 1) { |
| | | tool.setAttrs({fill: 'red'}) |
| | | } |
| | | }, |
| | | autoResize: true, |
| | | history: true, |
| | | // panning: { |
| | | // enabled: true, |
| | | // }, |
| | | scroller: { |
| | | enabled: true, |
| | | pageVisible: true, |
| | |
| | | minScale: 0.1, |
| | | maxScale: 10, |
| | | }, |
| | | connecting: { |
| | | router: { |
| | | name: 'normal', |
| | | // args: { |
| | | // padding: 1, |
| | | // }, |
| | | }, |
| | | connector: { |
| | | name: 'rounded', |
| | | args: { |
| | | radius: 8, |
| | | createEdge() { |
| | | return new Shape.Edge({ |
| | | data: { |
| | | id: '', |
| | | status: '', |
| | | startTime:'', |
| | | endTime: '', |
| | | }, |
| | | }, |
| | | // anchor: 'center', |
| | | connectionPoint: 'anchor', |
| | | snap: { |
| | | radius: 20, |
| | | }, |
| | | createEdge() { |
| | | return new Shape.Edge({ |
| | | attrs: { |
| | | line: { |
| | | stroke: '#A2B1C3', |
| | | strokeWidth: 2, |
| | | targetMarker: 'classic' |
| | | } |
| | | }, |
| | | tools: { |
| | | name: 'vertices', |
| | | }, |
| | | labels: [{ |
| | | attrs: { |
| | | body: { |
| | | stroke: '#5F95FF', |
| | | }, |
| | | text: { |
| | | // fontFamily: '仿宋', |
| | | text: '' |
| | | } |
| | | }, |
| | | }], |
| | | zIndex: 0, |
| | | }) |
| | | }, |
| | | // validateConnection({targetMagnet}) { |
| | | // return !!targetMagnet |
| | | // }, |
| | | }, |
| | | highlighting: { |
| | | magnetAdsorbed: { |
| | | name: 'stroke', |
| | | args: { |
| | | attrs: { |
| | | fill: '#5F95FF', |
| | | stroke: '#5F95FF', |
| | | }, |
| | | attrs: { |
| | | line: { |
| | | stroke: '#A2B1C3', |
| | | strokeWidth: 2, |
| | | sourceMarker: 'none', |
| | | targetMarker: 'none' |
| | | } |
| | | }, |
| | | }, |
| | | tools: { |
| | | name: 'vertices', |
| | | }, |
| | | zIndex: 0, |
| | | }) |
| | | }, |
| | | resizing: { |
| | | enabled: true, |
| | | restricted: true |
| | | }, |
| | | rotating: true, |
| | | selecting: { |
| | | enabled: true, |
| | | rubberband: true, |
| | | rubberEdge: true, |
| | | showNodeSelectionBox: true, |
| | | }, |
| | | snapline: true, |
| | | keyboard: true, |
| | | clipboard: true, |
| | | }) |
| | | this.knob = document.createElement('div',false) |
| | | this.knob.style.position = 'absolute' |
| | | document.getElementById('timeDiagram').appendChild(this.knob) |
| | | this.graph.centerContent() |
| | | const stencil = new Addon.Stencil({ |
| | | title: '', |
| | | target: this.graph, |
| | | stencilGraphWidth: 260, |
| | | stencilGraphHeight: 700, |
| | | collapsable: false, |
| | | groups: [ |
| | | { |
| | | title: '图元', |
| | | name: 'group1', |
| | | collapsable: false |
| | | } |
| | | ], |
| | | layoutOptions: { |
| | | columns: 2, |
| | | columnWidth: 130, |
| | | rowHeight: 100, |
| | | }, |
| | | }) |
| | | |
| | | Graph.registerNode( |
| | | 'custom-rect', |
| | | { |
| | |
| | | }, |
| | | true, |
| | | ) |
| | | // 一级网络图的日期文字节点 |
| | | const r5 = this.graph.createNode({ |
| | | shape: 'custom-circle', |
| | | data: { |
| | | dataId: '', |
| | | finishDate: '', |
| | | inspectName: '' |
| | | }, |
| | | label: '阶段', |
| | | }) |
| | | // 二级网络图日期节点 |
| | | const r6 = this.graph.createNode({ |
| | | shape: 'custom-circle1', |
| | | data: { |
| | | dataId: '', |
| | | finishDate: '', |
| | | inspectName: '' |
| | | }, |
| | | }) |
| | | // 二级网络图文字节点 |
| | | const r9 = this.graph.createNode({ |
| | | shape: 'custom-rect' |
| | | }) |
| | | |
| | | const scaleImgCenter = this.graph.createNode({ |
| | | shape: 'image', |
| | | imageUrl: require('@/assets/img/scale/center.jpg'), |
| | | width: 36, |
| | | height: 20, |
| | | data: { |
| | | imagePost: 'center' |
| | | } |
| | | }) |
| | | |
| | | const scaleImgTop = this.graph.createNode({ |
| | | shape: 'image', |
| | | imageUrl: require('@/assets/img/scale/top.jpg'), |
| | | width: 36, |
| | | height: 20, |
| | | data: { |
| | | imagePost: 'top' |
| | | } |
| | | }) |
| | | |
| | | const scaleImgRight = this.graph.createNode({ |
| | | shape: 'image', |
| | | imageUrl: require('@/assets/img/scale/right.jpg'), |
| | | width: 36, |
| | | height: 20, |
| | | data: { |
| | | imagePost: 'right' |
| | | } |
| | | }) |
| | | const scaleImgBottom = this.graph.createNode({ |
| | | shape: 'image', |
| | | imageUrl: require('@/assets/img/scale/bottom.jpg'), |
| | | width: 36, |
| | | height: 20, |
| | | data: { |
| | | imagePost: 'bottom' |
| | | } |
| | | }) |
| | | const scaleImgLeft = this.graph.createNode({ |
| | | shape: 'image', |
| | | imageUrl: require('@/assets/img/scale/left.jpg'), |
| | | width: 36, |
| | | height: 20, |
| | | data: { |
| | | imagePost: 'left' |
| | | } |
| | | }) |
| | | |
| | | // scaleImgTop.setAttribute('crossOrigin', 'Anonymous') |
| | | stencil.load([r5, r6, r9, scaleImgTop, scaleImgCenter, scaleImgRight, scaleImgBottom, scaleImgLeft], 'group1') |
| | | this.graph.bindKey(['meta+c', 'ctrl+c'], () => { |
| | | const cells = this.graph.getSelectedCells() |
| | | if (cells.length) { |
| | | this.graph.copy(cells) |
| | | } |
| | | return false |
| | | }) |
| | | |
| | | this.graph.bindKey(['meta+x', 'ctrl+x'], () => { |
| | | const cells = this.graph.getSelectedCells() |
| | | if (cells.length) { |
| | | this.graph.cut(cells) |
| | | } |
| | | return false |
| | | }) |
| | | // 监听 stencil 的拖拽开始事件 |
| | | this.graph.on('node:embed', ({node, e}) => { |
| | | // 阻止事件冒泡 |
| | | e.stopPropagation() |
| | | console.log(node.shape, 'node node') |
| | | let parent |
| | | let child |
| | | if (node.shape === 'custom-rect') { |
| | | child = node |
| | | } else { |
| | | parent = node |
| | | } |
| | | console.log('parent:' + parent, 'child:' + child) |
| | | // parent.addChild(child); |
| | | }) |
| | | this.graph.bindKey(['meta+v', 'ctrl+v'], () => { |
| | | if (!this.graph.isClipboardEmpty()) { |
| | | const cells = this.graph.paste({offset: 32}) |
| | | this.graph.cleanSelection() |
| | | this.graph.select(cells) |
| | | } |
| | | return false |
| | | }) |
| | | //undo redo |
| | | this.graph.bindKey(['meta+z', 'ctrl+z'], () => { |
| | | if (this.graph.history.canUndo()) { |
| | | this.graph.history.undo() |
| | | } |
| | | return false |
| | | }) |
| | | |
| | | this.graph.bindKey(['meta+shift+z', 'ctrl+shift+z'], () => { |
| | | if (this.graph.history.canRedo()) { |
| | | this.graph.history.redo() |
| | | } |
| | | return false |
| | | }) |
| | | |
| | | // select all |
| | | this.graph.bindKey(['meta+a', 'ctrl+a'], () => { |
| | | const nodes = this.graph.getNodes() |
| | | if (nodes) { |
| | | this.graph.select(nodes) |
| | | } |
| | | }) |
| | | //delete |
| | | this.graph.bindKey('delete', () => { |
| | | const cells = this.graph.getSelectedCells() |
| | | if (cells.length) { |
| | | this.$confirm('是否删除该节点?', '提示', { |
| | | confirmButtonText: '确定', |
| | | cancelButtonText: '取消', |
| | | type: 'warning' |
| | | }).then(() => { |
| | | this.$message({ |
| | | type: 'success', |
| | | message: '删除成功!' |
| | | }) |
| | | this.graph.removeCells(cells) |
| | | }).catch(() => { |
| | | this.$message({ |
| | | type: 'info', |
| | | message: '已取消删除' |
| | | }) |
| | | }) |
| | | } |
| | | }) |
| | | // zoom |
| | | this.graph.bindKey(['ctrl+1', 'meta+1'], () => { |
| | | const zoom = this.graph.zoom() |
| | |
| | | // 单击node节点 |
| | | this.graph.on('node:click', ({node}) => { |
| | | // this.reset() |
| | | node.attr('line/stroke', '#5F95FF') |
| | | node.prop('labels/0', { |
| | | attrs: { |
| | | body: { |
| | | stroke: '#5F95FF', |
| | | }, |
| | | }, |
| | | }) |
| | | }) |
| | | // 控制连接桩显示/隐藏 |
| | | this.graph.on('node:delete', ({view, e}) => { |
| | | e.stopPropagation() |
| | | view.cell.remove() |
| | | if (node.getData().dataId) { |
| | | this.dialogVisible2 = true |
| | | let param = { |
| | | id: node.getData().dataId, |
| | | modelName: node.attr('label/textWrap/text'), |
| | | } |
| | | this.$nextTick(() => { |
| | | this.$refs.modelView.init(param) |
| | | }) |
| | | } |
| | | }) |
| | | |
| | | this.graph.on('node:customevent', ({name, view, e}) => { |
| | |
| | | view.cell.remove() |
| | | } |
| | | }) |
| | | // 双击编辑 |
| | | this.graph.on('cell:dblclick', ({cell, e}) => { |
| | | const isNode = cell.isNode() |
| | | const name = cell.isNode() ? 'node-editor' : 'edge-editor' |
| | | cell.removeTool(name) |
| | | cell.addTools({ |
| | | name, |
| | | args: { |
| | | event: e, |
| | | attrs: { |
| | | backgroundColor: isNode ? '#EFF4FF' : '#FFF', |
| | | text: { |
| | | fontSize: 16, |
| | | fill: '#262626', |
| | | }, |
| | | }, |
| | | }, |
| | | }) |
| | | }) |
| | | |
| | | this.graph.on('node:mouseenter', ({node}) => { |
| | | const container = document.getElementById('container') |
| | | const ports = container.querySelectorAll( |
| | | '.x6-port-body', |
| | | ) |
| | | this.showPorts(ports, true) |
| | | // 鼠标移入edge节点 |
| | | this.graph.on('edge:mouseenter', ({edge,e}) => { |
| | | const style = this.knob.style |
| | | // e.stopPropagation() |
| | | console.log('edge:mouseenter') |
| | | if (e && edge.data) { |
| | | if (edge.getData().status==='F') { |
| | | //console.log(edge.getData(),"eee edge.getData()") |
| | | let startTimes = edge.getData().startTimes |
| | | let endTimes = edge.getData().endTimes |
| | | //console.log(e,'eee') |
| | | const p = this.graph.clientToGraph(e.clientX, e.clientY) |
| | | setTimeout(()=>{ |
| | | style.display = 'block' |
| | | style.left = `${p.x}px` |
| | | style.top = `${p.y}px` |
| | | style.width = 200+ 'px' |
| | | style.height = 80 + 'px' |
| | | style.textAlign = 'center' |
| | | style.background = '#000' |
| | | style.color = '#fff' |
| | | style.lineHeight = (40 + 'px') |
| | | style.zIndex = 100 |
| | | this.knob.innerText = `开始时间:${startTimes}\n结束时间:${endTimes}` |
| | | },0) |
| | | console.log(p,'p p p') |
| | | console.log(style,this.knob,'style style') |
| | | } |
| | | } |
| | | }) |
| | | |
| | | this.graph.on('node:mouseleave', ({node}) => { |
| | | // if (node.hasTool('button-remove')) { |
| | | // node.removeTool('button-remove') |
| | | // } |
| | | const container = document.getElementById('container') |
| | | const ports = container.querySelectorAll( |
| | | '.x6-port-body', |
| | | ) |
| | | this.showPorts(ports, false) |
| | | }) |
| | | |
| | | this.graph.on('edge:mouseenter', ({cell, view}) => { |
| | | // alert(123) |
| | | cell.addTools([ |
| | | { |
| | | name: 'source-arrowhead', |
| | | }, |
| | | { |
| | | name: 'target-arrowhead', |
| | | args: { |
| | | attrs: { |
| | | fill: 'red', |
| | | }, |
| | | }, |
| | | }, |
| | | ]) |
| | | cell.addTools( |
| | | [ |
| | | { |
| | | name: 'segments', |
| | | args: {snapRadius: 20, attrs: {fill: '#444'}} |
| | | } |
| | | ] |
| | | ) |
| | | }) |
| | | |
| | | this.graph.on('edge:mouseleave', ({cell}) => { |
| | | cell.removeTools() |
| | | // 鼠标移出edge节点 |
| | | this.graph.on('edge:mouseleave', ({edge}) => { |
| | | console.log('edge:mouseleave') |
| | | const style = this.knob.style |
| | | style.display = 'none' |
| | | }) |
| | | }, |
| | | async getProductList() { |
| | |
| | | this.simulatList = res.data |
| | | }, |
| | | async onTreeSelected(data) { |
| | | this.dataForm.productId = data.id |
| | | console.log(this.dataForm.productId) |
| | | this.graph.unfreeze() |
| | | if (!this.dataForm.taskModelId) { |
| | | this.$alert("请先选择具体任务") |
| | | return |
| | |
| | | return |
| | | } |
| | | let params = { |
| | | productId: this.dataForm.productId, |
| | | productId: data.id, |
| | | taskId: this.dataForm.taskModelId, |
| | | fzId: this.dataForm.id |
| | | } |
| | | let res = await this.$http.get('/taskReliability/SimulatAssess/getStatus', {params: params}) |
| | | if (res.data !== null) { |
| | | this.diagramJson = JSON.parse(res.data) |
| | | console.log(this.diagramJson, 'this.Diagram json') |
| | | this.graph.fromJSON(this.diagramJson) |
| | | this.graph.centerContent() |
| | | this.graph.zoomToFit() |
| | | this.graph.freeze() |
| | | } else { |
| | | this.graph.fromJSON(this.emptyJson) |
| | | this.graph.centerContent() |
| | | this.graph.zoomToFit() |
| | | this.graph.freeze() |
| | | } |
| | | console.log(res.data) |
| | | }, |
| | | // 获取信息 |
| | |
| | | this.$nextTick(() => { |
| | | this.$refs.ProductModelTree.getProductList() |
| | | }) |
| | | this.init() |
| | | }, |
| | | onTaskSelected(data) { |
| | | console.log(data, ' onProductSelected(data)') |
| | |
| | | this.dataForm.simulatFrequency = result.data.simulatFrequency |
| | | }, |
| | | async getDiagram() { |
| | | this.init() |
| | | this.graph.unfreeze() |
| | | let params = { |
| | | productId: this.dataForm.productId, |
| | | taskId: this.dataForm.taskModelId, |
| | |
| | | let res = await this.$http.get('/taskReliability/SimulatAssess/getStatus', {params: params}) |
| | | if (res.data !== null) { |
| | | this.diagramJson = JSON.parse(res.data) |
| | | // console.log(this.dataForm.content,'this.Diagram content') |
| | | console.log(this.diagramJson, 'this.Diagram json') |
| | | this.graph.fromJSON(this.diagramJson) |
| | | this.graph.centerContent() |
| | |
| | | } |
| | | </script> |
| | | <style> |
| | | #timeDiagram { |
| | | display: flex; |
| | | border: 1px solid #dfe3e8; |
| | | width: 100% !important; |
| | | } |
| | | #timeDiagram .x6-cell.x6-node { |
| | | cursor: inherit; |
| | | } |
| | | .x6-graph-scroller.x6-graph-scroller-pannable { |
| | | width: 100% !important; |
| | | } |
| | | |
| | | .x6-widget-stencil { |
| | | position: relative; |
| | | height: 100%; |
| | | } |
| | | |
| | | .x6-widget-stencil-content { |
| | | position: relative; |
| | | height: 100%; |
| | | } |
| | | </style> |