当前位置: 首页 > news >正文

旅游主题网站怎么做/磁力蜘蛛搜索引擎

旅游主题网站怎么做,磁力蜘蛛搜索引擎,福州市网站建设有限公司,仿网站建设作者简介: Jaked 8年前端工作经验, 主要分享:职业发展方面、前端技术、面试技巧等。 公众号:超哥前端小栈 掘金:https://juejin.im/user/5a5d4522518825732b19d364/posts 接上一篇文章 《「干货」用 Vue Echarts 打造你的专属可…

作者简介:
Jaked 
8年前端工作经验,
主要分享:职业发展方面、前端技术、面试技巧等。
公众号:超哥前端小栈
掘金:https://juejin.im/user/5a5d4522518825732b19d364/posts


 

接上一篇文章 《「干货」用 Vue + Echarts 打造你的专属可视化界面(上)》,今天着重介绍 标记 的用法,来实现下图中的效果。

 

所用的 Echarts 的版本号为:v4.3。v-charts 的版本号为:v1.19.0。

标记的用法有很多,今天要介绍的场景有:折线图、柱状图、折线图 + 柱状图。

 

折线图标记 —— symbol

 

上图中,折线的拐点处,一些 “小圆点”,被替换成了小图标。

要实现这样的效果,需要先理一下原始的需求:

  • 每种标记,代表一种活动类型。

  • 有一些活动会发生在某些时间点,或时间段内,需要在活动发生的日期上标注出该活动的类型。

  • 当同一天有多个活动发生时,采用复合图标,并当展示 tooltip 时,显示当日的每一个活动的信息。

  • tooltip的布局为:首先显示当前日期,中段展示各个活动的图标以及活动名称,最后展示指标名称和对应的数值。

  • 没有活动的日期,拐点处与 tooltip 照常显示原先的样式。

所以,它的完整效果,应该是这样的:

 

要实现这样的效果,需要思考以下几点:

  • 如何通过日期的定向匹配,将活动的图标以“打点”的形式,定在折线拐点处。

  • 图标的大小,要怎么设置?它需要区别于正常的拐点标识。

  • tooltip 的样式要如何改写?还需要兼容没有活动的日期样式。

 

思路解析:

首先,为了做日期的定向匹配,需要设计的数据结构如下:

data: [{id: '1, 1, 3, 2',date: '2019-10-10',name: 'test-name1, test-name2, test-name3, test-name4'},...
]

接下来的这个 核心 属性:symbol 是关键,它其实就是折线上的 拐点

 

symbol 支持的标记类型有:circle、rect、roundRect、triangle、diamond、pin、arrow、none。默认情况下为 emptyCircle,也就是空心的圆。

它还支持链接的格式:'image://http://xxx.xxx.xxx/a/b.png'。此外,如果需要每个数据的图形不一样,可以设置为如下格式的回调函数:

(value: Array|number, params: Object) => string

其中第一个参数 value 为 data 中的数据值。第二个参数 params 是其它的数据项参数。

 

这些正是我们需要的。踩坑亲测:上述回调函数,只有在最新版的 V4.3 中才能正常使用,否则会报错。这也是为何,我在一开始就先强调了 Echarts 的版本问题。具体实现如下:

<ve-line ... :extend="chartExtend"></ve-line>
...// mock 包含标注的数据结构
dataList: [{id: '1, 1, 3, 2',date: '2019-10-10',name: 'test-name1, test-name2, test-name3, test-name4'},...{id: '1',date: '2019-10-17',name: 'test-name1'}
],
...setChartExtend () {this.chartExtend = {series: (v) => {Array.from(v).forEach((e, idx) => {e.symbol = (value, params) => {return getSymbolIcon(params.name, dataList);};e.symbolSize = (value, params) => {return getSymbolSize(params.name, dataList);};});return v;},...};
},getSymbolIcon (date, dataList) {const defaultSymbol = 'circle';if (!dataList || dataList.length === 0) {return defaultSymbol;}// 通过日期匹配,找到对应的标注对象const dataItem = dataList.find(item => item.date === date);const iconUrl = getSymbolUrl(dataItem.id);return iconUrl ? iconUrl : defaultSymbol;
},getSymbolSize (date, dataList) {if (!dataList || dataList.length === 0) {return 4;}// 通过日期匹配,找到对应的标注对象const dataItem = dataList.find(item => item.date === date);return dataItem ? 15 : 4;
},getSymbolUrl (id) {// 这里需要额外先做一层准备工作:将图标按 id 对应图标进行命名,然后传到自家的cdn上// 命名可以像这样:symbol-icon-1.jpg、symbol-icon-2.jpg 等等// 这里拿到标注的id,拼上链接返回即可// 形如:image://http://xxx.xxx.com/symbol-icon-1.jpg// 遇到多个 id 的情况,可以多加一个复合图标来处理,id 可以定为 0
}

 

最后的一个问题,如何改写 tooltip 的样式问题,以做好兼容呢?

之前说到,tooltip 的布局分为三块:日期、标注信息、具体数值。那么我们就以此,来重新绘制 tooltip。

 

 

tooltip 支持 formatter 回调函数,它的返回值类型是 Sting。

// 回调函数格式
(params: Object|Array, ticket: string, callback: (ticket: string, html: string)) => string

日期的信息,可以通过 params[0].axisValue 来获取。

 

获取标注信息的方法,与上述获取图标的思路类似,只是这里需要展示具体的标注类型和名称。

具体的数值,可以通过 params 中的 marker,seriesName,value 等属性获得。具体实现如下:

setChartExtend () {this.chartExtend = {series: (v) => {...},tooltip: {formatter: (params) => {return getTooltipResult(params, dataList);}}};
},getTooltipResult (params, dataList) {const dateResult = params[0].axisValue;// 获取原版 tooltip 的渲染结构const originalResultObj = getOriginalTooltipResult(params);if (!dataList || dataList.length === 0) {return dateResult + originalResultObj.strResult;}const dataItem = dataList.find(item => item.date === date);if (dataItem) {return dateResult +  getSymbolResult(dataItem, originalResultObj.strResult);}return dateResult + originalResultObj.strResult;
},getOriginalTooltipResult (params) {let result = '';params.forEach((param, idx) => {// value 会因为 seriesType 的不同,类型也会有不同let value = Object.prototype.toString.call(param.value) === '[object Array]' ? param.value[1] : param.value;const str = `${param.marker}${param.seriesName}: ${ value }<br>`;result += str;});return {strResult: result};
},getSymbolResult (dataItem, originalResult) {// 将 dataItem 的 id 转为数组的形式,循环渲染输出图标与名称的组合const dataIds = dataItem.id.split(',');const dataNames = dataItem.name.split(',');dataIds.forEach ((id, idx) => {// 通过 id 换取 图标的链接const iconUrl = ...;// 仿照 param.marker 的 style 写法,渲染图标样式const str = `<img src="${iconUrl}" width="11" height="11" style="display: inline-block; margin-right: 4px; margin-left: -1px;">${dataNames[idx]}<br>`;result += str;});return result + originalResult;
}

或许有同学会问 getOriginalTooltipResult 方法返回的值,里面只有一个 strResult,为何要设计为对象?

 

其实是为了方便扩展。例如,可以在日期的后面跟上下方具体数据的值的总计。那就需要通过 getOriginalTooltipResult 方法里的 params 循环,计算出 total,在配合上样式,生成一个 strTotal。

getOriginalTooltipResult (params) {...return {strTotal: strTotal,strResult: result};
}

此外,在实际的业务中,还可能会出现某些线的数值是百分比。那就需要再对 getOriginalTooltipResult 方法做扩展,比如传入一个 options 对象:

getOriginalTooltipResult = (params, options = { isLinePercent: false, isShowTotal: false }) {...
}

至此,折线图标记的渲染,就能完美地呈现了。

 

 

柱状图标记 —— markPoint

很尴尬的一点是:柱状图没有 symbol 属性。也就意味着上面的折线图的那一套,在柱状图中玩不转了。

 

没办法,只能从头查文档,继续找资料。经过一番“摸爬滚打”,终于发现了 markPoint 这个属性。在 markPoint 这个对象里面,可以设置 symbol,这样的话,那么之前搞出来的那一套就没有白费呀?!?

需要注意的是,markPoint 的默认 symbol 为 'pin',就是一个气泡的图标。另外,想要让 markPoint 的标记出现,就必须设置它的 data 属性。我们需要设置 data 里的这样几个属性:

data: [{symbol: '...', // 设置标记的图标链接symbolSize: 15, // 设置标记的大小coord: [index, 0], // x 轴的第 index 个上,打标记symbolOffset: [0, 0] // 将标记定位在 x 轴上},...
]

 

具体的实现代码如下:

<ve-histogram :data="chartData" :extend="chartExtend"></ve-histogram>
...// mock 包含标注的数据结构
dataList: [{id: '1, 1, 3, 2',date: '2019-10-10',name: 'test-name1, test-name2, test-name3, test-name4'},...{id: '1',date: '2019-10-17',name: 'test-name1'}
],
...setChartExtend () {this.chartExtend = {series: (v) => {Array.from(v).forEach((e, idx) => {e.markPoint = {data: getMarkPointData(this.chartData.rows, dataList)};});},...};
},getMarkPointData (rows, dataList) {const results = [];rows.forEach((row, index) => {// 通过日期匹配,找到对应的标注对象const dataItem = dataList.find(item => item.date === row.date);if (dataItem) {results.push({symbol: getSymbolUrl(dataItem.id),symbolSize: 15,coord: [index, 0],symbolOffset: [0, 0]});}});return results;
},getSymbolUrl (id) {// 这里需要额外先做一层准备工作:将图标按 id 对应图标进行命名,然后传到自家的cdn上// 命名可以像这样:symbol-icon-1.jpg、symbol-icon-2.jpg 等等// 这里拿到标注的id,拼上链接返回即可// 形如:image://http://xxx.xxx.com/symbol-icon-1.jpg// 遇到多个 id 的情况,可以多加一个复合图标来处理,id 可以定为 0
}

因为 markPoint 在设置 data 时,取不到日期的数据,所以就需要用到 chartData 中的 rows 了。

 

在 rows 的循环中,如果匹配到当天需要打标记,则往结果数组中存入刚才预设的数据结构,最终返回给 markPoint 的 data,渲染展现。效果如下:

 

tooltip 的实现方法,不受图表的类型影响,是可以通用的,故此处不再赘述。

另外,有的时候,会遇到需要处理柱状图是否堆叠的效果。这会影响 symbolOffset 的定位,为了美观,可以这样处理:对于非堆叠的项,将之往右偏移 50%,将标记居中展示,即 symbolOffset : ['50%', 0]

 

折线图 + 柱状图

最后来个 组合拳,折线图与柱状图的复合型图表结构,像下面这样:

 

 

 

从代码实现上,我们当然可以给每一根符合条件的柱子,和折线的拐点,都打上标记。但在界面设计上,为了美观,我们选择只给折线的拐点打上标记,并且忽略了虚线的拐点。

这样的设计初衷是:标记,只是为了给人提个醒,是为了告诉查阅者,这一天因为发生了某些特殊事件,而导致数据发生了较为明显的变化。所以,由此得到的结论是:每天只要出现一个标记就够了。

具体的实现,其实很简单,只需要在渲染时判断 series 的 type 即可:

setChartExtend () {this.chartExtend = {series: (v) => {Array.from(v).forEach((e, idx) => {if (e.type === 'bar') {// 设置柱状图 markPoint 的方法...}if (e.type === 'line') {// 设置折线图 symbol、symbolSize 的方法...}});},...};
}

 

 

总结

Echarts 可以实现的效果有很多,本篇涉及其中 “标记” 的渲染。在折线图的拐点处,用 symbol 做了匹配化的处理。在柱状图中,因为没有直接的 symbol,转而使用 markPoint 来实现,采用将标记定位在某个维度上的做法。效果都挺不错的。

不过,在后续的使用中,发现了另一个尴尬的情况:在折线图中,当点击图例中的某一项,使其数据隐藏,然后再次点击重新渲染后,发现 symbol 的自定义图标不显示了。


 

作者简介:
Jaked 
8年前端工作经验,
主要分享:职业发展方面、前端技术、面试技巧等。
公众号:超哥前端小栈
掘金:https://juejin.im/user/5a5d4522518825732b19d364/posts

 

本文已经获得Jaked老师授权转发,其他人若有兴趣转载,请直接联系作者授权。

 

 

 

 

 

 

 

 

 

 

 

http://www.lbrq.cn/news/1030429.html

相关文章:

  • 申请个人网站怎么申请/百度推广电话销售好做吗
  • 网站建设项目策划/网址域名大全
  • 免费手机网页网站/友情链接管理系统
  • 深圳企业网站建设公司哪家好/百度图片识别在线识图
  • 软件开发流程详解/西安seo专员
  • wordpress 图片自动加/win10必做的优化
  • 做网站推广/seo搜索引擎优化论文
  • 网站收录少的原因/旅游企业seo官网分析报告
  • 网站开发盈利模式/seo工作内容有哪些
  • 网站域名什么意思/沈阳网站制作推广
  • 上海市建设合同信息表网站/免费发帖的平台有哪些
  • 个人域名怎么做社交网站/蒙牛牛奶推广软文
  • 建设网站的工作步骤是/建站工具有哪些
  • 做网站的规范尺寸/合肥网站
  • 无版权图片做网站/百度seo优化培训
  • 郑州睿网站建设/搜索引擎优化seo专员招聘
  • 泰拳图片做网站用/电脑培训课程
  • 投资网站建设/成都seo专家
  • 有什么做美食的网站/石家庄房价
  • 基金网站开发/推广合作
  • 做网站需要icp/如何创建个人网站免费
  • 多终端响应式网站/宁波seo高级方法
  • 网页设计推荐网站/aso关键词优化工具
  • 重庆石桥铺网站建设/网络推广渠道分类
  • 做微网站的公司哪家好/徐州seo网站推广
  • 大型门户网站设计公司/网页设计与制作步骤
  • 小程序源码之家/广州seo黑帽培训
  • 牙科医院网站源码/外包公司什么意思
  • 做门户网站难吗/百度网页搜索
  • 湖南省人民政府网站集约化建设/常德政府网站
  • 云计算-Docker Compose 实战:从OwnCloud、WordPress、SkyWalking、Redis ,Rabbitmq等服务配置实例轻松搞定
  • AI搜索重构下的GEO优化服务商格局观察
  • 消费级显卡分布式智能体协同:构建高性价比医疗AI互动智能体的理论与实践路径
  • LeetCode 分类刷题:2302. 统计得分小于 K 的子数组数目
  • AuthController类讲解
  • IIS Express中可以同时加载并使用.net4.0和.NET 2.0的 DLL