New next. Js using stomp pits
Juejin. Cn/post / 684490…
1. Add average value auxiliary line – Data Special Label – Custom label to the bar chart
The effect is as follows:
The code in
import React from "react";
import {
G2,
Chart,
Geom,
Axis,
Tooltip,
Coord,
Label,
Legend,
View,
Guide,
Shape,
Facet,
Util
} from "bizcharts";
import {
g2Tooltip, getMinNumber, getMaxNumber
} from "./config";
import { formatW } from ".. /.. /util";
import './GroupedColumn.less'
import DataSet from "@antv/data-set";
const { Line } = Guide;
export default class GroupedColumn extends React.Component {
getAvgNumber = (data = [], key) = > {
if (data.length > 0) {
return data.reduce((pre, next) = > pre + next[key], 0) / data.length;
}
}
render() {
const data = [
{
label: "Monday".series1: 12800.series2: 12260.url: 'http://img2.imgtn.bdimg.com/it/u=571610305, & FM = 26 & gp = 0. 1553276443 JPG'
},
{
label: "Tuesday".series1: 11800.series2: 11300.url: 'http://img2.imgtn.bdimg.com/it/u=571610305, 1553276443 & FM = 26 & gp = 4. JPG'
},
{
label: "Wednesday".series1: 14950.series2: 13900.url: 'http://img2.imgtn.bdimg.com/it/u=571610305, 1553276443 & FM = 26 & gp = 3. JPG'
},
{
label: "Thursday".series1: 14500.series2: 10390.url: 'http://img2.imgtn.bdimg.com/it/u=571610305, 1553276443 & FM = 26 & gp = 2. JPG'
},
{
label: "Friday".series1: 10170.series2: 10100.url: 'http://img2.imgtn.bdimg.com/it/u=571610305, 1553276443 & FM = 26 & gp = 1. JPG'}];const ds = new DataSet();
const dv = ds.createView().source(data);
dv.transform({
type: "fold".fields: ["series1"."series2"].// Expand the field set
key: "type"./ / the key fields
value: "value"./ / the value field
callback: obj= > {
obj.value = [obj.series1, obj.series2];
returnobj; }});const scale = {
type: { formatter: d= > ({ series1: 'thumb up'.series2: 'comments' }[d]) },
value: {
min: getMinNumber('series1', data) > getMinNumber('series2', data) ? getMinNumber('series2', data) : getMinNumber('series1', data),
max: getMaxNumber('series1', data) > getMaxNumber('series2', data) ? getMaxNumber('series1', data) : getMaxNumber('series2', data),
formatter: val= > {
returnformatW(val); }}};var imageMap = {
Wednesday: 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1564465427722&di=531da562d84c2f093a200c0c19d22b0d&i mgtype=0&src=http%3A%2F%2Fpic.90sjimg.com%2Fdesign%2F01%2F35%2F21%2F37%2F5a3c542fb97ba.png'};// Customize the label
const labelConfig = {
htmlTemplate(text, item, index) {
⚠️⚠️ text must be a unique value
const dataItem = data.filter(one= > one.label == text)[0]
return ` <div style="position: relative; top:60px; text-align:center"> <div> <img width='60px' height='60px' src=${dataItem.url}/>
</div>
<div style='width:100px'>${text}</div>
<div style='width:100px'>${dataItem.series1}-${dataItem.series2}</div>
</div>
`}}return<div> <div className='legend-customize'> <div> <div className='block-legend fire'></div> <div> <div className='block-legend Blue '></div> <div> Like </div> </div> <div> comments </div> </div> <Chart height={500} data={DV} scale={scale} padding={[70, 100, 130]} forceFit> <Coord /> <Axis name="label" label={labelConfig} /> <Axis name="value" /> <Tooltip g2-tooltip={g2Tooltip} /> <Geom type="interval" position="label*value" color={'type'} adjust={[ { type: "dodge", marginRatio: 1 / 32 } ]} /> <Geom type="point" position="label*value" size={40} shape={[ ['label', 'type'], function (name, type) { if (type == 'series1') { return ["image", imageMap[name]]; } return ['image', null]; <Guide> <GuideLine content=' GuideLine 'middle={this.getavgnumber (data, 'series1')} /> <GuideLine content=' 50 'middle={this.getavgnumber (data, 'series2')} color='#3AA1FF' /> </Guide> </Chart> </div> ); }} const GuideLine = ({middle, color = '#2fc25b', content = 'average') => {return <Line top start={{label: const GuideLine = ({middle, color = '#2fc25b', content = 'average') => "Monday", value: middle }} end={{ label: "Friday", value: middle }} lineStyle={{ stroke: color, lineDash: [0, 1, 1], lineWidth: 1, }} text={{ position: 'end', style: { fill: color, }, content: content, }} /> }Copy the code
Conclusion: When using a component, do not rely too much on it. When I first started, I always asked if returning raw data was supported. I felt that if I didn’t support it, it would be difficult to deal with, and I ran into a dead end. At this point, I advised developers to think about the result they want, we can change our solution, so that you can get closer to your result
2. About customizing htmlContent
Website bug
Website code
<Tooltip useHtml htmlContent={(title, items) => {
return `<div class="g2-tooltip">
<div class="g2-tooltip-title">${title} </div>
<ul><li>${JSON.stringify(items)}</li></ul>
</div>`}}
/>Copy the code
Customize Tooltip renderings after modification
⚠️ You must manually write CSS, otherwise the custom style will be bug
// class <Tooltip htmlContent={function (title, items) {
const { list = [] } = items[0]
return `<div class='custom-tooltip'<div> '} />// CSS styles. Custom-tooltip {position: absolute; left: 20px; Background: RGBA (24, 24, 24, 0.9); color:#fff;
width: 440px;
height: auto;
border-radius: 3px;
font-size: 13px;
right: 0;
background-size: 100% auto;
background-repeat: no-repeat;
box-shadow: 0px 0px 10px #aeaeae;
z-index: 999;
}Copy the code
Conclusion: When working with a component library, you need to not only use what the component provides internally, but also know what libraries it depends on, as you can see in G2
The custom – the style of the tooltip
3. About the use of maps
Map effect:
The Autonavi API needs to be introduced
<! --> <script SRC ="/ / webapi.amap.com/maps?v=1.3&key=89a0871d1c4bf418cd9ab88c01e3bd5d"></script> <! -- UI component library (version 1.0) --> <script SRC ="/ / webapi.amap.com/ui/1.0/main.js"></script>Copy the code
The map code
import React, { Component } from 'react'const { AMap, AMapUI } = window; import { Chart, Geom, Tooltip, Legend, Guide} from"bizcharts"; import numeral from'numeral'import DataSet from "@antv/data-set"; const constructGeoJSON = (features) => {if(! features)return false; if (Array.isArray(features)) { return { type: 'FeatureCollection', features: [...features], }; } returnfeatures; }; /** const getGeojsonByCode = (adCode = 100000, withSub =)true) => { const { AMapUI } = window; if(! AMapUI) {returnPromise.reject(); } / / document: https://lbs.amap.com/api/javascript-api/reference-amap-ui/geo/district-explorerreturn new Promise((resolve, reject) => { AMapUI.load("ui/geo/DistrictExplorer", DistrictExplorer => { const districtExplorer = new DistrictExplorer(); districtExplorer.loadAreaNode(adcode, (error, areaNode) => { if (error) { reject(); } let res = null; if (withSub) { res = areaNode.getSubFeatures(); } else{ res = areaNode.getParentFeature(); } resolve(constructGeoJSON(res)); }); }); }); }; // Set the following parameters: Page loading Amap and its UI SDK, Reference to HTML page / / 1, the data interface to get through the gold geojson data / / 2, the data processing by the Dataset / / 3, drawing class MapChart extends Component {state = {chinaGeo: null, }componentDidMount() { getGeojsonByCode(100000, true).then(res => { this.setState({ chinaGeo: res, }); }); } processGeoData = (geoData, dataValue) => { const { features } = geoData features.map((one) => { const name = one.properties.name dataValue.map((item) => { if (name.includes(item.name)) { one.value = item.value } }) }) const geoDv = new DataSet.View().source(geoData, { type: 'GeoJSON'});return geoDv; } render() { const area =[ { "key":"10105"."name":"Guangdong"."value":0.1138 }, { "key":"10125"."name":"Sichuan"."value":0.0899 }, { "key":"10102"."name":"Anhui province"."value":0.0695 }, { "key":"10130"."name":"Zhejiang"."value":0.0525 }, { "key":"10112"."name":"Hubei"."value":0.0505 }, { "key":"10124"."name":"Shanghai"."value":0.0495 }, { "key":"10103"."name":"Fujian"."value":0.0484 }, { "key":"10131"."name":"Chongqing"."value":0.0419 }, { "key":"10115"."name":"Jiangsu"."value":0.0402 }, { "key":"10123"."name":"Shaanxi"."value":0.0388 }, { "key":"10121"."name":"Shandong"."value":0.0387 }, { "key":"10109"."name":"Hebei"."value":0.0359 }, { "key":"10116"."name":"Jiangxi"."value":0.0315 }, { "key":"10113"."name":"Hunan"."value":0.0304 }, { "key":"10129"."name":"Yunnan"."value":0.0294 }, { "key":"10101"."name":"Beijing"."value":0.0246 }, { "key":"10104"."name":"Gansu"."value":0.0232 }, { "key":"10114"."name":"Jilin"."value":0.0229 }, { "key":"10107"."name":"Guizhou"."value":0.0223 }, { "key":"10106"."name":"Guangxi"."value":0.0220 }, { "key":"10110"."name":"Henan"."value":0.0190 }, { "key":"10117"."name":"Liaoning"."value":0.0152 }, { "key":"10118"."name":Inner Mongolia."value":0.0142 }, { "key":"10128"."name":"Xinjiang"."value":0.0142 }, { "key":"10111"."name":"Heilongjiang"."value":0.0140 }, { "key":"10126"."name":"Tianjin"."value":0.0122 }, { "key":"10122"."name":"Shanxi"."value":0.0103 }, { "key":"10108"."name":"Hainan"."value":0.0098 }, { "key":"10119"."name":"The ningxia"."value":0.0080 }, { "key":"10120"."name":"Qinghai"."value":0.0052 }, { "key":"10127"."name":"Tibet"."value"}] const {chinaGeo} = this.state;if(! chinaGeo) {return 'Data loading... ' } const data = this.processGeoData(chinaGeo, area); const scale = { latitude: { sync: true, nice: false, }, longitude: { sync: true, nice: false, }, value: { formatter: val => { return numeral(val || 0).format('0.0%')}}}; const { Image } = Guide;return ( <div style={{ position: "relative" }}> <Chart height={500} width={645} scale={scale} data={data} padding={[0, 0, 0, 90]}> <Geom type="polygon" position="longitude*latitude" style={{ lineWidth: 1, stroke: "white" }} // color={['value'['#31c5f8'.'#61d3f8'.'#89dcfd'.'#b0e8f8'.'#d8f3ff']]} color={['value'['#d9f4ff'.'#33c5f6']]} tooltip={['name*value', (name, value) => { return { name: name, value: numeral(value || 0).format('0.0%') } }]} > <Tooltip showTitle={false} /> <Legend position='bottom-left' offsetY={-130} offsetX={-60} slidable={false} width={320} /> </Geom> </Chart> <div style={{ position: "absolute", bottom: 100, right: 0 }}> <img height='58' width=The '42' src={require('.. /img/map-line.png')} /> </div> </div> ); }}export default MapChartCopy the code
4. Add text to the end of the chart
rendering
<Geom type="interval" position="name*value"> // Here is the field after each bar chart <Label content={["name*value", (name, value) => {
return numeral(value || 0).format('0.0%');
}]} />
</Geom>Copy the code
Multiple return a bizcharts.net/products/bi…
<Geom
type="intervalStack"
position="State* number of people"
color={"Age group"}
>
<Label content={["Age * number of people.", (name, value) => {
console.log(name, value)
if(name=='14 to 17 ')
return value;
}]} />
</Geom>Copy the code
Summary: To deal with the problem, think about your purpose, if you write this component how would you deal with the problem? Not wanting is filtering
5. Revise the legend copy into Chinese
The official figure bizcharts.net/products/bi…
Add the following code to cols:
user: { formatter: d => ({ a: 'to modify a', b: 'modify b' }[d]) }Copy the code
Effect picture after addition:
Sum up, pay attention to each small point, one person to modify a little, a bunch of people add up to how much work