首页
统计
关于
Search
1
Sealos3.0离线部署K8s集群
1,096 阅读
2
类的加载
746 阅读
3
Spring Cloud OAuth2.0
728 阅读
4
SpringBoot自动装配原理
694 阅读
5
集合不安全问题
591 阅读
笔记
Java
多线程
注解和反射
JVM
JUC
设计模式
Mybatis
Spring
SpringMVC
SpringBoot
MyBatis-Plus
Elastic Search
微服务
Dubbo
Zookeeper
SpringCloud
Nacos
Sentinel
数据库
MySQL
Oracle
PostgreSQL
Redis
MongoDB
工作流
Activiti7
Camunda
消息队列
RabbitMQ
前端
HTML5
CSS
CSS3
JavaScript
jQuery
Vue2
Vue3
Linux
容器
Docker
Kubernetes
Python
FastApi
登录
Search
标签搜索
Java
CSS
mysql
RabbitMQ
JavaScript
Redis
JVM
Mybatis-Plus
Camunda
多线程
CSS3
Python
Spring Cloud
注解和反射
Activiti
工作流
SpringBoot
Mybatis
Spring
html5
蘇阿細
累计撰写
392
篇文章
累计收到
4
条评论
首页
栏目
笔记
Java
多线程
注解和反射
JVM
JUC
设计模式
Mybatis
Spring
SpringMVC
SpringBoot
MyBatis-Plus
Elastic Search
微服务
Dubbo
Zookeeper
SpringCloud
Nacos
Sentinel
数据库
MySQL
Oracle
PostgreSQL
Redis
MongoDB
工作流
Activiti7
Camunda
消息队列
RabbitMQ
前端
HTML5
CSS
CSS3
JavaScript
jQuery
Vue2
Vue3
Linux
容器
Docker
Kubernetes
Python
FastApi
页面
统计
关于
搜索到
392
篇与
的结果
2021-03-18
Docker
一、基本组成镜像(image):docker镜像就好比是一个模板,可以通过这个模板来创建容器服务,tomcat镜像-->run-->tomcat01容器(提供服务),通过这个镜像可以创建多个容器(最终服务或者项目就是运行在容器中)容器(container):docker利用容器技术,独立运行一个或一组应用,通过镜像创建(一个简易的Linux系统)仓库(repository):存放镜像,分为公有和私有二、安装以CentOS 7为例# 卸载原有的docker yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine # 安装工具包 yum install -y yum-utils # 更换镜像源 yum-config-manager \ --add-repo \ http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo # 更新软件源 yum makecache fast # 安装 yum install docker-ce docker-ce-cli containerd.io # 卸载 yum remove docker-ce docker-ce-cli containerd.io rm -rf /var/lib/docker rm -rf /var/lib/containerd # 阿里云镜像加速 sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://xxxx.mirror.aliyuncs.com"] //镜像地址可根据阿里云账号自行配置 } EOF sudo systemctl daemon-reload sudo systemctl restart docker
2021年03月18日
94 阅读
0 评论
0 点赞
2021-03-13
ECharts数据可视化
注:笔记内容来源于黑马Pink老师css:* { margin: 0; padding: 0; box-sizing: border-box; } li { list-style: none; } @font-face { font-family: electronicFont; src: url(../font/DS-DIGIT.TTF); } body { height: 1.25rem; background: url(../images/bg.jpg) no-repeat top center; line-height: 1.15; } header { height: 1.25rem; background: url(../images/head_bg.png) no-repeat; background-size: 100% 100%; } header h1 { font-size: 0.475rem; color: #fff; text-align: center; line-height: 1rem; } header .showTime { position: absolute; right: 0.375rem; top: 0; line-height: 0.9375rem; color: #ffffff; } .mainbox { display: flex; min-width: 1024px; max-width: 1920px; margin: 0 auto; padding: 0.125rem 0.125rem 0; } .mainbox .column { flex: 3; } .mainbox .column:nth-child(2) { flex: 5; margin: 0 0.125rem 0.1875rem; overflow: hidden; } .mainbox .panel { position: relative; height: 3.875rem; border: 0.0125rem solid rgba(25, 186, 139, 0.17); padding: 0 0.1875rem 0.5rem; margin-bottom: 0.1875rem; background: url(../images/line.png); } .mainbox .panel::before { position: absolute; top: 0; left: 0; width: 0.125rem; height: 0.125rem; border-left: 2px solid #02a6b5; border-top: 2px solid #02a6b5; content: ""; } .mainbox .panel::after { position: absolute; top: 0; right: 0; width: 0.125rem; height: 0.125rem; border-right: 2px solid #02a6b5; border-top: 2px solid #02a6b5; content: ""; } .mainbox .panel .panel-footer { position: absolute; bottom: 0; left: 0; width: 100%; } .mainbox .panel .panel-footer::before { position: absolute; left: 0; bottom: 0; width: 0.125rem; height: 0.125rem; border-left: 2px solid #02a6b5; border-bottom: 2px solid #02a6b5; content: ""; } .mainbox .panel .panel-footer::after { position: absolute; bottom: 0; right: 0; width: 0.125rem; height: 0.125rem; border-right: 2px solid #02a6b5; border-bottom: 2px solid #02a6b5; content: ""; } .mainbox .panel h2 { height: 0.6rem; color: #fff; line-height: 0.6rem; text-align: center; font-size: 0.25rem; font-weight: 400; } .mainbox .panel h2 a { margin: 0; color: #fff; text-decoration: none; } .mainbox .panel .chart { height: 3rem; } .no { background: rgba(101, 132, 226, 0.1); padding: 0.1875rem; } .no .no-hd { position: relative; border: 1px solid rgba(25, 186, 139, 0.17); } .no .no-hd::before { position: absolute; top: 0; left: 0; content: ""; width: 30px; height: 10px; border-top: 2px solid #02a6b5; border-left: 2px solid #02a6b5; } .no .no-hd::after { position: absolute; bottom: 0; right: 0; content: ""; width: 30px; height: 10px; border-right: 2px solid #02a6b5; border-bottom: 2px solid #02a6b5; } .no .no-hd ul { display: flex; } .no .no-hd ul li { position: relative; flex: 1; line-height: 1rem; font-size: 0.875rem; color: #ffeb7b; text-align: center; font-family: "electronicFont"; } .no .no-hd ul li::after { content: ""; position: absolute; top: 25%; right: 0; height: 50%; width: 1px; background: rgba(255, 255, 255, 0.7); } .no .no-bd ul { display: flex; } .no .no-bd ul li { flex: 1; line-height: 0.5rem; font-size: 0.225rem; height: 0.5rem; color: rgba(255, 255, 255, 0.7); text-align: center; padding-top: 0.125rem; } .map { position: relative; height: 10.125rem; } .map .map1 { width: 6.475rem; height: 6.475rem; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: url("../images/map.png"); background-size: 100%, 100%; opacity: 0.3; } .map .map2 { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 8.0375rem; height: 8.0375rem; background: url("../images/lbx.png"); background-size: 100%, 100%; animation: rotate1 15s linear infinite; opacity: 0.6; } .map .map3 { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 7.075rem; height: 7.075rem; background: url("../images/jt.png"); background-size: 100%, 100%; animation: rotate2 10s linear infinite; opacity: 0.6; } .map .chart { position: absolute; top: 0; left: 0; width: 100%; height: 10.125rem; } @keyframes rotate1 { form { transform: translate(-50%, -50%) rotate(0deg); } to { transform: translate(-50%, -50%) rotate(360deg); } } @keyframes rotate2 { form { transform: translate(-50%, -50%) rotate(0deg); } to { transform: translate(-50%, -50%) rotate(-360deg); } } @media screen and (max-width: 1024px) { html { font-size: 42px !important; } } @media screen and (min-width: 1920px) { html { font-size: 80px !important; } } /*# sourceMappingURL=index.css.map */js//柱状图1 (function () { //1.实例化对象 let myChart = echarts.init(document.querySelector(".bar .chart")); //2.指定配置项和数据 let option = { color: ['#2f89cf'], tooltip: { trigger: 'axis', axisPointer: { // 坐标轴指示器,坐标轴触发有效 type: 'shadow' // 默认为直线,可选为:'line' | 'shadow' } }, //修改图表大小 grid: { left: '0%', top: '10px', right: '0%', bottom: '4%', containLabel: true }, xAxis: [ { type: 'category', data: ["旅游行业", "教育培训", "游戏行业", "医疗行业", "电商行业", "社交行业", "金融行业"], axisTick: { alignWithLabel: true }, //修改刻度标签相关样式 axisLabel: { color: "rgba(255,255,255,.6)", fontSize: "12" }, //不显示x坐标轴的线条 axisLine: { show: false } } ], yAxis: [ { type: 'value', //修改刻度标签相关样式 axisLabel: { color: "rgba(255,255,255,.6)", fontSize: 12 }, //y轴线条 axisLine: { lineStyle: { color: "rgba(255,255,255,.1)", width: 2 } }, //y轴分割线样式 splitLine: { lineStyle: { color: "rgba(255,255,255,.1)" } } } ], series: [ { name: '直接访问', type: 'bar', barWidth: '35%', data: [200, 300, 300, 900, 1500, 1200, 600], itemStyle: { //修改柱子圆角 barBorderRadius: 5 } } ] }; //3.把配置项给实例对象 myChart.setOption(option); //4.图表自适应 window.addEventListener("resize", function () { myChart.resize(); }) })(); //柱状图2 (function () { //1.实例化对象 let myChart = echarts.init(document.querySelector(".bar2 .chart")); let myColor = ["#1089E7", "#F57474", "#56D0E3", "#F8B448", "#8B78F6"]; //2.指定配置和数据 let option = { grid: { left: '10%', right: '22%', bottom: '10%', //containLabel: true }, xAxis: { //不显示x轴相关信息 show: false }, yAxis: [ { type: 'category', inverse: true, data: ["HTML5", "CSS3", "javascript", "VUE", "NODE"], //不显示y轴的线 axisLine: { show: false }, //不显示刻度 axisTick: { show: false }, //标签文字颜色 axisLabel: { color: "#fff" } }, { data: [702, 350, 610, 793, 664], inverse: true, // 不显示y轴的线 axisLine: { show: false }, // 不显示刻度 axisTick: { show: false }, axisLabel: { textStyle: { fontSize: 12, color: "#fff" } } } ], series: [ { name: '条', type: 'bar', data: [70, 34, 60, 78, 69], yAxisIndex: 0, itemStyle: { barBorderRadius: 20, //柱子颜色 color: function (params) { //params 传进来的是主子对象 //dataIndex 当前柱子的索引 return myColor[params.dataIndex]; } }, //柱子之间的距离 barCategoryGap: 50, //柱子宽度 barWidth: 10, //显示柱子内的文字 label: { show: true, position: "inside", //{c}会自动解析data中对应的数据 formatter: "{c}%" } }, { name: '框', type: 'bar', yAxisIndex: 1, barCategoryGap: 50, barWidth: 15, data: [100, 100, 100, 100, 100], itemStyle: { color: "none", borderColor: "#00c1de", borderWidth: 3, barBorderRadius: 15 } } ] }; //3.把配置给实例对象 myChart.setOption(option); // 4. 图表跟随屏幕自适应 window.addEventListener("resize", function () { myChart.resize(); }) })(); //折线图1 (function () { let yearData = [ { year: "2020", // 年份 data: [ // 两个数组是因为有两条线 [24, 40, 101, 134, 90, 230, 210, 230, 120, 230, 210, 120], [40, 64, 191, 324, 290, 330, 310, 213, 180, 200, 180, 79] ] }, { year: "2021", // 年份 data: [ // 两个数组是因为有两条线 [123, 175, 112, 197, 121, 67, 98, 21, 43, 64, 76, 38], [143, 131, 165, 123, 178, 21, 82, 64, 43, 60, 19, 34] ] } ]; //1.实例化对象 let myChart = echarts.init(document.querySelector(".line .chart")); //2.指定配置 let option = { //修改折线颜色 color: ['#00f2f1', '#ed3f35'], tooltip: { trigger: 'axis' }, //图例组件 legend: { //data: ['新增粉丝', '新增游客'], series有name值时,此处的data不用写 //图例组件,文字颜色 textStyle: { color: '#4c9bfd', }, //这里的10%必须加引号 right: '10%' }, grid: { top: '20%', left: '3%', right: '4%', bottom: '3%', show: true, //显示边框 borderColor: '#012f4a', containLabel: true //包含刻度文字在内 }, xAxis: { type: 'category', boundaryGap: false, data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'], axisTick: { show: false //刻度线 }, axisLabel: { color: '#4c9bfd' }, axisLine: { show: false //轴线 }, boundaryGap: false //轴内间距 }, yAxis: { type: 'value', axisTick: { show: false //刻度线 }, axisLabel: { color: '#4c9bfd' }, splitLine: { lineStyle: { color: '#012f4a' } } }, series: [ { name: '新增粉丝', type: 'line', smooth: true, //折线平滑显示 stack: '总量', data: yearData[0].data[0] }, { name: '新增游客', type: 'line', smooth: true, stack: '总量', data: yearData[0].data[1] } ] }; //3.把配置给实例对象 myChart.setOption(option); //4.图表跟随窗口自适应 window.addEventListener("resize", function () { myChart.resize(); }); //5.点击切换效果 $('.line h2').on('click', 'a', function () { //alert('hello'); //点击a之后,根据当前a的索引号,找到对应的yearData的相关对象 //console.log(yearData[$(this).index()]); let obj = yearData[$(this).index()]; option.series[0].data = obj.data[0]; option.series[1].data = obj.data[1]; //需要重新渲染 myChart.setOption(option); }); })(); //折线图2 (function () { //1.实例化对象 let myChart = echarts.init(document.querySelector(".line2 .chart")); //2.指定配置 let option = { tooltip: { trigger: 'axis', axisPointer: { lineStyle: { color: "#dddc6b" } } }, legend: { top: '0%', textStyle: { color: "rgba(255,255,255,.5)", fontSize: "12" }, }, grid: { left: '10', top: '30', right: '10', bottom: '10', containLabel: true }, xAxis: [ { axisLabel: { textStyle: { color: "rgba(255,255,255,.6)", fontSize: 12 } }, //x轴线颜色 axisLine: { lineStyle: { color: "rgba(255,255,255,.2)", } }, type: 'category', boundaryGap: false, data: ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "26", "28", "29", "30"] }, { axisPointer: { show: false }, axisLine: { show: false }, position: "bottom", offset: 20 } ], yAxis: [ { type: 'value', axisTick: { show: false }, axisLine: { lineStyle: { color: "rgba(255,255,255,.1)" } }, axisLabel: { textStyle: { color: "rgba(255,255,255,.6)", fontSize: 12 } }, //分割线颜色 splitLine: { lineStyle: { color: "rgba(255,255,255,.1)" } } } ], series: [ { name: '播放量', smooth: true, type: 'line', lineStyle: { color: "#0184d5", width: 2 }, areaStyle: { color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ { offset: 0, color: "rgba(1, 132, 213, 0.4)" //渐变色的起始颜色 }, { offset: 0.8, color: "rgba(1, 132, 213, 0.1)" //渐变色结束颜色 } ], false ), shadowColor: "rgba(0, 0, 0, 0.1)" }, //设置拐点为小圆点 symbol: "circle", //拐点大小 symbolSize: 5, //拐点颜色以及边框 itemStyle: { normal: { color: "#0184d5", borderColor: "rgba(221, 220, 107, .1)", borderWidth: 12 } }, //开始不显示拐点,当鼠标经过时才显示 showSymbol: false, data: [30, 40, 30, 40, 30, 40, 30, 60, 20, 40, 30, 40, 30, 40, 30, 40, 30, 60, 20, 40, 30, 40, 30, 40, 30, 40, 20, 60, 50, 40] }, { name: '转发量', type: 'line', stack: '总量', smooth: true, lineStyle: { normal: { color: "#00d887", width: 2 } }, areaStyle: { normal: { color: new echarts.graphic.LinearGradient( 0, 0, 0, 1, [ { offset: 0, color: "rgba(0, 216, 135, 0.4)" }, { offset: 0.8, color: "rgba(0, 216, 135, 0.1)" } ], false ), shadowColor: "rgba(0, 0, 0, 0.1)" } }, //拐点 Symbol: "circle", //拐点大小 SymbolSize: 5, //拐点颜色及边框 itemStyle: { normal: { color: "#00d887", borderColor: "rgba(221, 220, 107, .1)", borderWidth: 12 } }, // 开始不显示拐点, 鼠标经过显示 showSymbol: false, data: [50, 30, 50, 60, 10, 50, 30, 50, 60, 40, 60, 40, 80, 30, 50, 60, 10, 50, 30, 70, 20, 50, 10, 40, 50, 30, 70, 20, 50, 10, 40], } ] }; //3.把配置给实例对象 myChart.setOption(option); //4.图表跟随窗口自适应 window.addEventListener("resize", function () { myChart.resize(); }); })(); //饼图1 (function () { //1.实例化对象 let myChart = echarts.init(document.querySelector(".pie .chart")); //2.指定配置 option = { tooltip: { trigger: 'item', formatter: '{a} <br/>{b}: {c} ({d}%)' }, legend: { //距离底部的距离 0% bottom: "0%", //小图标的宽度和高度 itemWidth: 10, itemHeight: 10, data: ["0岁以下", "20-29岁", "30-39岁", "40-49岁", "50岁以上"], textStyle: { color: "rgba(255,255,255,.5)", fontSize: "12" } }, series: [ { name: '年龄分布', type: 'pie', radius: ['50%', '50%'], //修改内圆半径和外圆半径(百分比是相对于容器来说的) radius: ["40%", "60%"], //不显示标签文字 label: { show: false }, //不显示连线 labelLine: { show: false }, avoidLabelOverlap: false, labelLine: { show: false }, data: [ { value: 1, name: "0岁以下" }, { value: 4, name: "20-29岁" }, { value: 2, name: "30-39岁" }, { value: 2, name: "40-49岁" }, { value: 1, name: "50岁以上" } ], color: [ "#065aab", "#066eab", "#0682ab", "#0696ab", "#06a0ab", ], } ] }; //3.把配置给实例 myChart.setOption(option); //4.图表跟随窗口自适应 window.addEventListener("resize", function() { myChart.resize(); }) })(); //饼图2 (function () { //1.实例化对象 let myChart = echarts.init(document.querySelector(".pie2 .chart")); //2.指定配置 option = { color: ['#006cff', '#60cda0', '#ed8884', '#ff9f7f', '#0096ff', '#9fe6b8', '#32c5e9', '#1d9dff'], tooltip: { trigger: 'item', formatter: '{a} <br/>{b} : {c} ({d}%)' }, legend: { bottom: "0%", itemWidth: 10, itemHeight: 10, textStyle: { color: "rgba(255,255,255,.5)", fontSize: "12" } }, series: [ { name: '地区分布', type: 'pie', radius: ["10%", "70%"], center: ['50%', '50%'], roseType: 'radius', itemStyle: { borderRadius: 5 }, //文本标签控制饼形图文字的相关样式,它是一个对象 label: { fontSize: 10 }, labelLine: { //连接扇形的线段长度 length: 6, //连接文字的线段长度 length2: 8 }, data: [ { value: 20, name: '云南' }, { value: 26, name: '北京' }, { value: 24, name: '山东' }, { value: 25, name: '河北' }, { value: 20, name: '江苏' }, { value: 25, name: '浙江' }, { value: 30, name: '四川' }, { value: 42, name: '湖北' } ] } ] }; //3.把配置给实力 myChart.setOption(option); //4.图表跟随窗口自适应 window.addEventListener("resize", function () { myChart.resize(); }) })(); //飞机地图模块 (function () { let myChart = echarts.init(document.querySelector(".map .chart")); let geoCoordMap = { '上海': [121.4648,31.2891], '东莞': [113.8953,22.901], '东营': [118.7073,37.5513], '中山': [113.4229,22.478], '临汾': [111.4783,36.1615], '临沂': [118.3118,35.2936], '丹东': [124.541,40.4242], '丽水': [119.5642,28.1854], '乌鲁木齐': [87.9236,43.5883], '佛山': [112.8955,23.1097], '保定': [115.0488,39.0948], '兰州': [103.5901,36.3043], '包头': [110.3467,41.4899], '北京': [116.4551,40.2539], '北海': [109.314,21.6211], '南京': [118.8062,31.9208], '南宁': [108.479,23.1152], '南昌': [116.0046,28.6633], '南通': [121.1023,32.1625], '厦门': [118.1689,24.6478], '台州': [121.1353,28.6688], '合肥': [117.29,32.0581], '呼和浩特': [111.4124,40.4901], '咸阳': [108.4131,34.8706], '哈尔滨': [127.9688,45.368], '唐山': [118.4766,39.6826], '嘉兴': [120.9155,30.6354], '大同': [113.7854,39.8035], '大连': [122.2229,39.4409], '天津': [117.4219,39.4189], '太原': [112.3352,37.9413], '威海': [121.9482,37.1393], '宁波': [121.5967,29.6466], '宝鸡': [107.1826,34.3433], '宿迁': [118.5535,33.7775], '常州': [119.4543,31.5582], '广州': [113.5107,23.2196], '廊坊': [116.521,39.0509], '延安': [109.1052,36.4252], '张家口': [115.1477,40.8527], '徐州': [117.5208,34.3268], '德州': [116.6858,37.2107], '惠州': [114.6204,23.1647], '成都': [103.9526,30.7617], '扬州': [119.4653,32.8162], '承德': [117.5757,41.4075], '拉萨': [91.1865,30.1465], '无锡': [120.3442,31.5527], '日照': [119.2786,35.5023], '昆明': [102.9199,25.4663], '杭州': [119.5313,29.8773], '枣庄': [117.323,34.8926], '柳州': [109.3799,24.9774], '株洲': [113.5327,27.0319], '武汉': [114.3896,30.6628], '汕头': [117.1692,23.3405], '江门': [112.6318,22.1484], '沈阳': [123.1238,42.1216], '沧州': [116.8286,38.2104], '河源': [114.917,23.9722], '泉州': [118.3228,25.1147], '泰安': [117.0264,36.0516], '泰州': [120.0586,32.5525], '济南': [117.1582,36.8701], '济宁': [116.8286,35.3375], '海口': [110.3893,19.8516], '淄博': [118.0371,36.6064], '淮安': [118.927,33.4039], '深圳': [114.5435,22.5439], '清远': [112.9175,24.3292], '温州': [120.498,27.8119], '渭南': [109.7864,35.0299], '湖州': [119.8608,30.7782], '湘潭': [112.5439,27.7075], '滨州': [117.8174,37.4963], '潍坊': [119.0918,36.524], '烟台': [120.7397,37.5128], '玉溪': [101.9312,23.8898], '珠海': [113.7305,22.1155], '盐城': [120.2234,33.5577], '盘锦': [121.9482,41.0449], '石家庄': [114.4995,38.1006], '福州': [119.4543,25.9222], '秦皇岛': [119.2126,40.0232], '绍兴': [120.564,29.7565], '聊城': [115.9167,36.4032], '肇庆': [112.1265,23.5822], '舟山': [122.2559,30.2234], '苏州': [120.6519,31.3989], '莱芜': [117.6526,36.2714], '菏泽': [115.6201,35.2057], '营口': [122.4316,40.4297], '葫芦岛': [120.1575,40.578], '衡水': [115.8838,37.7161], '衢州': [118.6853,28.8666], '西宁': [101.4038,36.8207], '西安': [109.1162,34.2004], '贵阳': [106.6992,26.7682], '连云港': [119.1248,34.552], '邢台': [114.8071,37.2821], '邯郸': [114.4775,36.535], '郑州': [113.4668,34.6234], '鄂尔多斯': [108.9734,39.2487], '重庆': [107.7539,30.1904], '金华': [120.0037,29.1028], '铜川': [109.0393,35.1947], '银川': [106.3586,38.1775], '镇江': [119.4763,31.9702], '长春': [125.8154,44.2584], '长沙': [113.0823,28.2568], '长治': [112.8625,36.4746], '阳泉': [113.4778,38.0951], '青岛': [120.4651,36.3373], '韶关': [113.7964,24.7028] }; let XAData = [ [{name:'西安'}, {name:'北京',value:100}], [{name:'西安'}, {name:'上海',value:100}], [{name:'西安'}, {name:'广州',value:100}], [{name:'西安'}, {name:'昆明',value:100}], [{name:'西安'}, {name:'银川',value:100}] ]; let XNData = [ [{name:'西宁'}, {name:'北京',value:100}], [{name:'西宁'}, {name:'上海',value:100}], [{name:'西宁'}, {name:'广州',value:100}], [{name:'西宁'}, {name:'西安',value:100}], [{name:'西宁'}, {name:'银川',value:100}] ]; let YCData = [ [{name:'银川'}, {name:'北京',value:100}], [{name:'银川'}, {name:'广州',value:100}], [{name:'银川'}, {name:'上海',value:100}], [{name:'银川'}, {name:'西安',value:100}], [{name:'银川'}, {name:'西宁',value:100}], ]; let planePath = 'path://M1705.06,1318.313v-89.254l-319.9-221.799l0.073-208.063c0.521-84.662-26.629-121.796-63.961-121.491c-37.332-0.305-64.482,36.829-63.961,121.491l0.073,208.063l-319.9,221.799v89.254l330.343-157.288l12.238,241.308l-134.449,92.931l0.531,42.034l175.125-42.917l175.125,42.917l0.531-42.034l-134.449-92.931l12.238-241.308L1705.06,1318.313z'; //var planePath = 'arrow'; let convertData = function (data) { let res = []; for (let i = 0; i < data.length; i++) { let dataItem = data[i]; let fromCoord = geoCoordMap[dataItem[0].name]; let toCoord = geoCoordMap[dataItem[1].name]; if (fromCoord && toCoord) { res.push({ fromName: dataItem[0].name, toName: dataItem[1].name, coords: [fromCoord, toCoord], value: dataItem[1].value }); } } return res; }; let color = ['#a6c84c', '#ffa022', '#46bee9'];//航线的颜色 let series = []; [['西安', XAData], ['西宁', XNData], ['银川', YCData]].forEach(function (item, i) { series.push({ name: item[0] + ' Top3', type: 'lines', zlevel: 1, effect: { show: true, period: 6, trailLength: 0.7, color: 'red', //arrow箭头的颜色 symbolSize: 3 }, lineStyle: { normal: { color: color[i], width: 0, curveness: 0.2 } }, data: convertData(item[1]) }, { name: item[0] + ' Top3', type: 'lines', zlevel: 2, symbol: ['none', 'arrow'], symbolSize: 10, effect: { show: true, period: 6, trailLength: 0, symbol: planePath, symbolSize: 15 }, lineStyle: { normal: { color: color[i], width: 1, opacity: 0.6, curveness: 0.2 } }, data: convertData(item[1]) }, { name: item[0] + ' Top3', type: 'effectScatter', coordinateSystem: 'geo', zlevel: 2, rippleEffect: { brushType: 'stroke' }, label: { normal: { show: true, position: 'right', formatter: '{b}' } }, symbolSize: function (val) { return val[2] / 8; }, itemStyle: { normal: { color: color[i], }, emphasis: { areaColor: '#2B91B7' } }, data: item[1].map(function (dataItem) { return { name: dataItem[1].name, value: geoCoordMap[dataItem[1].name].concat([dataItem[1].value]) }; }) }); }); let option = { tooltip : { trigger: 'item', formatter:function(params, ticket, callback){ if(params.seriesType=="effectScatter") { return "线路:"+params.data.name+""+params.data.value[2]; }else if(params.seriesType=="lines"){ return params.data.fromName+">"+params.data.toName+"<br />"+params.data.value; }else{ return params.name; } } }, legend: { orient: 'vertical', top: 'bottom', left: 'right', data:['西安 Top3', '西宁 Top3', '银川 Top3'], textStyle: { color: '#fff' }, selectedMode: 'multiple' }, geo: { map: 'china', label: { emphasis: { show: true, color:'#fff' } }, //将地图放大1.2倍 zoom: 1.2, roam: true, itemStyle: { normal: { //地图省份背景颜色 areaColor: "rgba(20, 41, 87, 0.6)", borderColor: '#195BB9', borderWidth: 1, }, emphasis: { areaColor: '#2B91B7' } } }, series: series }; myChart.setOption(option); window.addEventListener("resize", function () { myChart.resize(); }) })();index.html<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>EChart</title> <link rel="stylesheet" href="css/index.css"> </head> <body> <!--头部盒子--> <header> <h1>EChart 数据可视化</h1> <div class="showTime"></div> </header> <script> var t = null; t = setTimeout(time, 1000); function time(){ clearTimeout(t); //清除定时器 dt = new Date(); var y = dt.getFullYear(); var mt = dt.getMonth() + 1; var d = dt.getDate(); var h = dt.getHours(); var m = dt.getMinutes(); var s = dt.getSeconds(); document.querySelector('.showTime').innerHTML = "当前时间:" + y + "-" + mt + "-" + d + " " + h + ":" + m + ":" + s; t = setTimeout(time,1000); //设定定时器,循环运行 } </script> <!--页面主体部分--> <section class="mainbox"> <div class="column"> <div class="panel bar"> <h2>柱状图-就业行业</h2> <div class="chart"></div> <div class="panel-footer"></div> </div> <div class="panel line"> <h2>折线图-人员变化 <a href="javascript:;">2020</a> <a href="javacript:;"> 2021</a></h2> <div class="chart"></div> <div class="panel-footer"></div> </div> <div class="panel pie"> <h2>饼状图-年龄分布</h2> <div class="chart"></div> <div class="panel-footer"></div> </div> </div> <div class="column"> <!--no模块--> <div class="no"> <div class="no-hd"> <ul> <li>123456</li> <li>678910</li> </ul> </div> <div class="no-bd"> <ul> <li>前端需求人数</li> <li>市场供应人数</li> </ul> </div> </div> <!--地图模块--> <div class="map"> <div class="map1"></div> <!--map2在map1的下面,旋转动画会默认压住原来的球体--> <div class="map2"></div> <div class="map3"></div> <div class="chart"></div> </div> </div> <div class="column"> <div class="panel bar2"> <h2>柱状图-技能掌握</h2> <div class="chart"></div> <div class="panel-footer"></div> </div> <div class="panel line2"> <h2>折线图-播放量</h2> <div class="chart"></div> <div class="panel-footer"></div> </div> <div class="panel pie2"> <h2>饼图-地区分布</h2> <div class="chart"></div> <div class="panel-footer"></div> </div> </div> </section> <script src="js/flexible.js"></script> <script src="js/jquery.js"></script> <script src="js/echarts.min.js"></script> <script src="js/china.js"></script> <script src="js/index.js"></script> </body> </html>
2021年03月13日
68 阅读
0 评论
0 点赞
2021-02-23
死锁简要笔记
死锁死锁测试实例:package com.sw.lock; import java.util.concurrent.TimeUnit; /** * @Author suaxi * @Date 2021/2/22 23:48 * 死锁Demo */ public class DeadLockTest { public static void main(String[] args) { String lockA = "lockA"; String lockB = "lockB"; new Thread(new DeadLock(lockA,lockB),"A").start(); new Thread(new DeadLock(lockB,lockA),"B").start(); } } class DeadLock implements Runnable{ private String lockA; private String lockB; public DeadLock(String lockA, String lockB) { this.lockA = lockA; this.lockB = lockB; } @Override public void run() { synchronized (lockA){ System.out.println(Thread.currentThread().getName()+"--->现在的锁是:"+lockA+",想获取的资源是:"+lockB); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (lockB){ System.out.println(Thread.currentThread().getName()+"--->现在的锁是:"+lockB+",想获取的资源是:"+lockA); } } } } 解决思路:1、jps -l查看进程号2、jstack 进程号查看具体的死锁信息
2021年02月23日
85 阅读
0 评论
0 点赞
2021-02-23
自旋锁
自旋锁spinlock自定义自旋锁测试实例package com.sw.lock; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicReference; /** * @Author suaxi * @Date 2021/2/22 23:21 * 自定义自旋锁 */ public class SpinLockTest { AtomicReference<Thread> atomicReference = new AtomicReference<>(); //加锁 public void myLock() { Thread thread = Thread.currentThread(); System.out.println(Thread.currentThread().getName() + "--->myLock()"); //自旋锁 while (!atomicReference.compareAndSet(null, thread)) { } } //解锁 public void myUnlock() { Thread thread = Thread.currentThread(); System.out.println(Thread.currentThread().getName() + "--->myUnlock()"); atomicReference.compareAndSet(thread, null); } //测试 public static void main(String[] args) throws InterruptedException { SpinLockTest lock = new SpinLockTest(); new Thread(() -> { lock.myLock(); try { TimeUnit.SECONDS.sleep(5); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.myUnlock(); } }, "A").start(); TimeUnit.SECONDS.sleep(2); new Thread(() -> { lock.myLock(); try { TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.myUnlock(); } }, "B").start(); /* 执行结果为: A--->myLock() B--->myLock() A--->myUnlock() B--->myUnlock() */ } }
2021年02月23日
55 阅读
0 评论
0 点赞
2021-02-23
可重入锁
可重入锁可重入锁:打开大门的锁之后也就获得了里面两个房间的锁synchronized版可重入锁package com.sw.lock; /** * @Author suaxi * @Date 2021/2/22 23:07 * synchronized版可重入锁 */ public class Test01 { public static void main(String[] args) { Phone phone = new Phone(); new Thread(() ->{ phone.sms(); },"A").start(); new Thread(() ->{ phone.sms(); },"B").start(); } } class Phone{ public synchronized void sms(){ System.out.println(Thread.currentThread().getName()+"--->sms"); call(); } public synchronized void call(){ System.out.println(Thread.currentThread().getName()+"--->call"); } } lock版可重入锁package com.sw.lock; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; /** * @Author suaxi * @Date 2021/2/22 23:07 * lock版可重入锁 */ public class Test02 { public static void main(String[] args) { Phone2 phone = new Phone2(); new Thread(() ->{ phone.sms(); },"A").start(); new Thread(() ->{ phone.sms(); },"B").start(); } } class Phone2{ Lock lock =new ReentrantLock(); public void sms(){ lock.lock(); //lock锁必须配对,否则会产生死锁 try { System.out.println(Thread.currentThread().getName()+"--->sms"); call(); }catch (Exception e){ e.printStackTrace(); }finally { lock.unlock(); } } public void call(){ lock.lock(); try { System.out.println(Thread.currentThread().getName()+"--->call"); }catch (Exception e){ e.printStackTrace(); }finally { lock.unlock(); } } }
2021年02月23日
144 阅读
0 评论
0 点赞
2021-02-21
原子引用
原子引用原子引用解决ABA问题,解决思路:乐观锁package com.sw.cas; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicStampedReference; /** * @Author suaxi * @Date 2021/2/21 21:29 * 原子引用解决ABA问题 */ public class casTest01 { static AtomicStampedReference<Integer> atomicStampedReference = new AtomicStampedReference<>(5, 1); public static void main(String[] args) { new Thread(() ->{ int stamp = atomicStampedReference.getStamp(); System.out.println("A1--->"+stamp); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(atomicStampedReference.compareAndSet(5, 6, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1)); System.out.println("A2--->"+atomicStampedReference.getStamp()); System.out.println(atomicStampedReference.compareAndSet(6, 5, atomicStampedReference.getStamp(), atomicStampedReference.getStamp() + 1)); System.out.println("A3--->"+atomicStampedReference.getStamp()); },"A").start(); new Thread(() ->{ int stamp = atomicStampedReference.getStamp(); System.out.println("B1--->"+stamp); try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(atomicStampedReference.compareAndSet(5, 10, stamp, stamp + 1)); System.out.println("B2--->"+atomicStampedReference.getStamp()); },"B").start(); } } Integer包装类补充:
2021年02月21日
262 阅读
0 评论
0 点赞
2021-02-21
CompareAndSet(CAS)
CompareAndSet(CAS)CASCAS:比较并交换package com.sw.cas; import java.util.concurrent.atomic.AtomicInteger; /** * @Author suaxi * @Date 2021/2/21 20:58 * CAS:比较并交换 */ public class casTest { public static void main(String[] args) { AtomicInteger atomicInteger = new AtomicInteger(2021); //如果达到期望的值,就更新,否则反之 System.out.println(atomicInteger.compareAndSet(2021,666)); //true System.out.println(atomicInteger.get()); //666 } } Unsafe图片来源:狂神说Java缺点:1、循环会耗时2、一次循环只能保证一个共享变量的原子性3、ABA问题ABA问题package com.sw.cas; import java.util.concurrent.atomic.AtomicInteger; /** * @Author suaxi * @Date 2021/2/21 20:58 * CAS:比较并交换 */ public class casTest { public static void main(String[] args) { AtomicInteger atomicInteger = new AtomicInteger(2021); //如果达到期望的值,就更新,否则反之 //捣乱的线程 System.out.println(atomicInteger.compareAndSet(2021,666)); //true System.out.println(atomicInteger.get()); //666 System.out.println(atomicInteger.compareAndSet(666,2021)); System.out.println(atomicInteger.get()); //期望的线程 System.out.println(atomicInteger.compareAndSet(2021, 888)); System.out.println(atomicInteger.get()); } }
2021年02月21日
103 阅读
0 评论
0 点赞
2021-02-21
单例模式
单例模式饿汉式package com.sw.single; /** * @Author suaxi * @Date 2021/2/21 18:57 * 饿汉式单例 */ public class Hungry { private byte[] data1 = new byte[1024 * 1024]; private byte[] data2 = new byte[1024 * 1024]; private byte[] data3 = new byte[1024 * 1024]; private byte[] data4 = new byte[1024 * 1024]; private Hungry(){ } private final static Hungry hungry = new Hungry(); public static Hungry getHungry() { return hungry; } } 懒汉式package com.sw.single; import java.lang.reflect.Constructor; import java.lang.reflect.Field; /** * @Author suaxi * @Date 2021/2/21 18:59 * 懒汉式单例 */ public class Lazy { //通过私有参数保证单例模式的安全 private static boolean flag = false; private Lazy() { synchronized (Lazy.class){ if (flag == false){ flag = true; }else { throw new RuntimeException("不要试图使用反射破环单例模式"); } } System.out.println(Thread.currentThread().getName() + " ok"); } private volatile static Lazy lazy; //双重检测锁模式的 懒汉式单例 DCL懒汉式 public static Lazy getInstance(){ if (lazy == null){ synchronized (Lazy.class){ if (lazy == null){ lazy = new Lazy(); //不是一个原子性操作 /* 不是一个原子性操作,可能存在问题 new 对象的过程: 1、分配内存空间 2、执行构造方法。初始化对象 3、把对象指向这个空间 一般来说的执行过程 123 132 A 可能出现指令重排 B B线程执行时,由于A线程中的指令重排导致的问题,此时Lazy还没有完成构造 解决办法:volatile */ } } } return lazy; } //多线程并发 // public static void main(String[] args) { // for (int i = 0; i < 10; i++) { // new Thread(() ->{ // Lazy.getInstance(); // }).start(); // } // } //反射 可以破环单例模式 public static void main(String[] args) throws Exception { //Lazy instance01 = Lazy.getInstance(); //第一次 //第三次,通过反射获取私有字段flag Field flag = Lazy.class.getDeclaredField("flag"); flag.setAccessible(true); Constructor<Lazy> declaredConstructor = Lazy.class.getDeclaredConstructor(null); declaredConstructor.setAccessible(true); //无视私有构造 //第二次,两个对象都通过以下方式构造,又破坏了三重检测锁的单例模式 Lazy instance01 = declaredConstructor.newInstance(); flag.set(instance01,false); //此处又破坏了 Lazy instance02 = declaredConstructor.newInstance(); System.out.println(instance01); //com.sw.single.Lazy@74a14482 System.out.println(instance02); //com.sw.single.Lazy@1540e19d } /* 1、第一次破环单例模式,通过反射创建instance对象 2、加上三重检测锁,又通过全部使用反射创建对象来破坏(第二次) 3、设置私有变量 flag,通过反射获取私有变量字段,又破坏了单例 */ } 静态内部类package com.sw.single; /** * @Author suaxi * @Date 2021/2/21 19:48 * 静态内部类 */ public class Holder { private Holder(){ } public static Holder getInstance(){ return InnerClass.holder; } public static class InnerClass{ private static final Holder holder = new Holder(); } } 枚举package com.sw.single; import java.lang.reflect.Constructor; /** * @Author suaxi * @Date 2021/2/21 20:10 */ public enum EnumSingle { INSTANCE; public EnumSingle getInstance(){ return INSTANCE; } } class Test{ public static void main(String[] args) throws Exception { EnumSingle instance01 = EnumSingle.INSTANCE; Constructor<EnumSingle> declaredConstructor = EnumSingle.class.getDeclaredConstructor(String.class,int.class); declaredConstructor.setAccessible(true); EnumSingle instance02 = declaredConstructor.newInstance(); //获取空参的反射报错 没有无参构造器 // java.lang.NoSuchMethodException: com.sw.single.EnumSingle.<init>() //EnumSingle.class.getDeclaredConstructor(String.class,int.class); //报错 java.lang.IllegalArgumentException: Cannot reflectively create enum objects //反射不能破坏枚举 System.out.println(instance01 == instance02); } } 注:需通过jad反编译,EnumSingle.class.getDeclaredConstructor(String.class,int.class);反射获取有参构造才能得出java.lang.IllegalArgumentException: Cannot reflectively create enum objects(反射不能破坏枚举),常规的通过反射获取无参构造只会报错java.lang.NoSuchMethodException
2021年02月21日
143 阅读
0 评论
0 点赞
1
...
27
28
29
...
49