d3js 实现水球图

在这里插入图片描述

d3js 源码地址:: http://bl.ocks.org/brattonc/5e5ce9beee483220e2f6

官方提供的代码不能直接用,版本3.x 这是调整后v5能使用的。

<!DOCTYPE html>
<html><head><meta charset='utf-8'><meta http-equiv='X-UA-Compatible' content='ie=edge'><title>7</title><script src="https://d3js.org/d3.v5.min.js"></script><link rel="stylesheet" type="text/css" href="/css.css" />
</head><body><svg id="svg" width="300" height="300" onclick="javascript:gauge.update(NewValue())"></svg><span>点击SVG更新数据</span></body>
<script type='text/javascript'>var gauge = loadLiquidFillGauge("svg", 55, {circleColor: "#FF7777",textColor: "#FF4444",waveTextColor: "#FFAAAA",waveColor: "#FFDDDD",circleThickness: 0.02,circleFillGap: 0,textVertPosition: 0.2,waveAnimateTime: 1000,waveRiseTime: 3000});function NewValue() {if (Math.random() > .5) {return Math.round(Math.random() * 100);}return (Math.random() * 100).toFixed(1);}function loadLiquidFillGauge(elementId, value, config) {config = Object.assign({}, {minValue: 0, // 量规最小值.maxValue: 100, // 量规最大值.circleThickness: 0.05, // 外圆的厚度与半径的百分比.circleFillGap: 0.05, // 外圆与波圆之间的间隙大小与外圆半径的百分比.circleColor: "#178BCA", // 外圆的颜色.waveHeight: 0.05, // 波高与波圆半径的百分比.waveCount: 2, // 每波圈宽度的全波数.waveRiseTime: 1000, // 波从0上升到最终高度所需的时间,以毫秒为单位.waveAnimateTime: 18000, //  一个完整的波进入波圈的时间(以毫秒为单位).waveRise: true, // 控制波浪是否应该从0上升到它的全部高度,或从它的全部高度开始waveHeightScaling: true, // 控制波大小缩放在低和高填充百分比。当真值时,波高在50%填充时达到最大值,在0%和100%填充时达到最小值。这有助于防止波使波圈出现完全满或空时,接近它的最小或最大填充。waveAnimate: true, // 控制波形是滚动还是静态.waveColor: "#178BCA", // 填充波的颜色。waveOffset: 0, // 最初抵消波的量。0 = 无偏移。1 = 一个完整波的偏移量textVertPosition: .5, // 在波圈内显示百分比文本的高度。0 =下,1 =上.textSize: 1, // 要在波圈中显示的文本的相对高度。1 = 50%valueCountUp: true, // 如果为真,则显示的值从0计数到加载时的最终值。如果为false,则显示最终值。displayPercent: true, // 如果为真,值后面会显示%符号。textColor: "#045681", // 当波浪不重叠值文本时的颜色。waveTextColor: "#A4DBf8" // 当波浪与值文本重叠时的颜色.}, config);var gauge = d3.select("#" + elementId);var radius = Math.min(parseInt(gauge.style("width")), parseInt(gauge.style("height"))) / 2;var locationX = parseInt(gauge.style("width")) / 2 - radius;var locationY = parseInt(gauge.style("height")) / 2 - radius;var fillPercent = Math.max(config.minValue, Math.min(config.maxValue, value)) / config.maxValue;var waveHeightScale;if (config.waveHeightScaling) {waveHeightScale = d3.scaleLinear().range([0, config.waveHeight, 0]).domain([0, 50, 100]);} else {waveHeightScale = d3.scaleLinear().range([config.waveHeight, config.waveHeight]).domain([0, 100]);}var textPixels = (config.textSize * radius / 2);var textFinalValue = parseFloat(value).toFixed(2);var textStartValue = config.valueCountUp ? config.minValue : textFinalValue;var percentText = config.displayPercent ? "%" : "";var circleThickness = config.circleThickness * radius;var circleFillGap = config.circleFillGap * radius;var fillCircleMargin = circleThickness + circleFillGap;var fillCircleRadius = radius - fillCircleMargin;var waveHeight = fillCircleRadius * waveHeightScale(fillPercent * 100);var waveLength = fillCircleRadius * 2 / config.waveCount;var waveClipCount = 1 + config.waveCount;var waveClipWidth = waveLength * waveClipCount;// 四舍五入函数,以便在数值累计时始终显示正确的小数点后位数。var textRounder = (value) => Math.round(value);if (parseFloat(textFinalValue) != parseFloat(textRounder(textFinalValue))) {textRounder = (value) => parseFloat(value).toFixed(1);}if (parseFloat(textFinalValue) != parseFloat(textRounder(textFinalValue))) {textRounder = (value) => parseFloat(value).toFixed(2);}// 建立clip wave区域的数据。var data = Array.from({ length: 41 * waveClipCount }, (_, i) => ({ x: i / (40 * waveClipCount), y: (i / (40)) }));// 绘制外圆的比例。var gaugeCircleX = d3.scaleLinear().range([0, 2 * Math.PI]).domain([0, 1]);var gaugeCircleY = d3.scaleLinear().range([0, radius]).domain([0, radius]);// 用于控制剪切路径大小的尺度。var waveScaleX = d3.scaleLinear().range([0, waveClipWidth]).domain([0, 1]);var waveScaleY = d3.scaleLinear().range([0, waveHeight]).domain([0, 1]);// 用于控制裁剪路径位置的刻度。var waveRiseScale = d3.scaleLinear()// 剪辑区域的大小是填充圆的高度+波的高度,所以我们定位剪辑波这样,它将重叠填充圆在所有0%时,并将完全覆盖填充圆在100%。.range([(fillCircleMargin + fillCircleRadius * 2 + waveHeight), (fillCircleMargin - waveHeight)]).domain([0, 1]);var waveAnimateScale = d3.scaleLinear().range([0, waveClipWidth - fillCircleRadius * 2]) // 将夹子区域推一个完整的波,然后弹回来。.domain([0, 1]);// 用于控制文本在量规内的位置的刻度。var textRiseScaleY = d3.scaleLinear().range([fillCircleMargin + fillCircleRadius * 2, (fillCircleMargin + textPixels * 0.7)]).domain([0, 1]);// 在父SVG中居中测量。var gaugeGroup = gauge.append("g").attr('transform', `translate(${locationX},${locationY})`);// 画一个外圆。var gaugeCircleArc = d3.arc()({startAngle: gaugeCircleX(0),endAngle: gaugeCircleX(1),outerRadius: gaugeCircleY(radius),innerRadius: gaugeCircleY(radius - circleThickness),})gaugeGroup.append("path").attr("d", gaugeCircleArc).style("fill", config.circleColor).attr('transform', `translate(${radius},${radius})`);// 波不重叠的文本。var text1 = gaugeGroup.append("text").text(textRounder(textStartValue) + percentText).attr("class", "liquidFillGaugeText").attr("text-anchor", "middle").attr("font-size", textPixels + "px").style("fill", config.textColor).attr('transform', `translate(${radius},${textRiseScaleY(config.textVertPosition)})`);// 剪切波面积。var clipArea = d3.area().x(d => waveScaleX(d.x)).y0(d => waveScaleY(Math.sin(Math.PI * 2 * config.waveOffset * -1 + Math.PI * 2 * (1 - config.waveCount) + d.y * 2 * Math.PI))).y1(d => (fillCircleRadius * 2 + waveHeight));var waveGroup = gaugeGroup.append("defs").append("clipPath").attr("id", "clipWave" + elementId);var wave = waveGroup.append("path").datum(data).attr("d", clipArea).attr("T", 0);// 带有剪切波的内圆。var fillCircleGroup = gaugeGroup.append("g").attr("clip-path", "url(#clipWave" + elementId + ")");fillCircleGroup.append("circle").attr("cx", radius).attr("cy", radius).attr("r", fillCircleRadius).style("fill", config.waveColor);// 波重叠的文本。var text2 = fillCircleGroup.append("text").text(textRounder(textStartValue) + percentText).attr("class", "liquidFillGaugeText").attr("text-anchor", "middle").attr("font-size", textPixels + "px").style("fill", config.waveTextColor).attr('transform', `translate(${radius},${textRiseScaleY(config.textVertPosition)})`);// 把数值加起来。if (config.valueCountUp) {var textTween = function () {var i = d3.interpolate(this.textContent, textFinalValue);return function (t) {this.textContent = textRounder(i(t)) + percentText;}};text1.transition().duration(config.waveRiseTime).tween("text", textTween);text2.transition().duration(config.waveRiseTime).tween("text", textTween);}// 让波浪上升。波和波组是分开的,水平和垂直运动可以独立控制。var waveGroupXPosition = fillCircleMargin + fillCircleRadius * 2 - waveClipWidth;if (config.waveRise) {waveGroup.attr('transform', `translate(${waveGroupXPosition},${waveRiseScale(0)})`).transition().duration(config.waveRiseTime).ease(d3.easeLinear).attr('transform', `translate(${waveGroupXPosition},${waveRiseScale(fillPercent)})`).on("start", function () {// 当wave Rise = true和 wave Animate=false时,这个变换是必要的,以使剪辑波正确定位。如果没有这个,波将无法正确定位,但我们不清楚为什么这是必要的.wave.attr('transform', 'translate(1,0)');});} else {waveGroup.attr('transform', `translate(${waveGroupXPosition},${waveRiseScale(fillPercent)}`);}if (config.waveAnimate) animateWave();function animateWave() {wave.attr('transform', `translate(${waveAnimateScale(wave.attr('T'))},0)`);wave.transition().duration(config.waveAnimateTime * (1 - wave.attr('T'))).ease(d3.easeLinear).attr("transform", `translate(${waveAnimateScale(1)},0)`).attr('T', 1).on('end', function () {wave.attr('T', 0);animateWave();});}function GaugeUpdater() {this.update = function (value) {var newFinalValue = parseFloat(value).toFixed(2);var textRounderUpdater = (value) => Math.round(value);if (parseFloat(newFinalValue) != parseFloat(textRounderUpdater(newFinalValue))) {textRounderUpdater = (value) => parseFloat(value).toFixed(1);}if (parseFloat(newFinalValue) != parseFloat(textRounderUpdater(newFinalValue))) {textRounderUpdater = (value) => parseFloat(value).toFixed(2);}var textTween = function () {var interpolate = d3.interpolate(this.textContent, parseFloat(value).toFixed(2));return function (t) {this.textContent = textRounderUpdater(interpolate(t)) + percentText;}};text1.transition().duration(config.waveRiseTime).tween("text", textTween);text2.transition().duration(config.waveRiseTime).tween("text", textTween);var fillPercent = Math.max(config.minValue, Math.min(config.maxValue, value)) / config.maxValue;var waveHeight = fillCircleRadius * waveHeightScale(fillPercent * 100);var waveRiseScale = d3.scaleLinear()// 剪辑区域的大小是填充圆的高度+波的高度,所以我们定位剪辑波这样,它将重叠填充圆在所有0%时,并将完全覆盖填充圆在100%..range([(fillCircleMargin + fillCircleRadius * 2 + waveHeight), (fillCircleMargin - waveHeight)]).domain([0, 1]);var newHeight = waveRiseScale(fillPercent);var waveScaleX = d3.scaleLinear().range([0, waveClipWidth]).domain([0, 1]);var waveScaleY = d3.scaleLinear().range([0, waveHeight]).domain([0, 1]);var newClipArea;if (config.waveHeightScaling) {newClipArea = d3.area().x(d => waveScaleX(d.x)).y0(d => waveScaleY(Math.sin(Math.PI * 2 * config.waveOffset * -1 + Math.PI * 2 * (1 - config.waveCount) + d.y * 2 * Math.PI))).y1(d => (fillCircleRadius * 2 + waveHeight));} else {newClipArea = clipArea;}var newWavePosition = config.waveAnimate ? waveAnimateScale(1) : 0;wave.transition().duration(0).transition().duration(config.waveAnimate ? (config.waveAnimateTime * (1 - wave.attr('T'))) : (config.waveRiseTime)).ease(d3.easeCircle).attr('d', newClipArea).attr('transform', `translate(${newWavePosition},0)`).attr('T', '1').on("end", function () {if (config.waveAnimate) {wave.attr('transform', `translate(${waveAnimateScale(0)},0)`)animateWave();}});waveGroup.transition().duration(config.waveRiseTime).attr('transform', `translate(${waveGroupXPosition},${newHeight})`)}}return new GaugeUpdater();}
</script></html>

组件版本

<template><div style="width: 100%;height: 300px;" class="p-30"></div>
</template><script>
import * as d3 from "d3";export default {name: 'loadLiquidFillGauge',data() {return {instance: null}},props: {step: { type: [Number, String], default: 0.01 },},mounted() {this.instance = this.loadLiquidFillGauge(this.$el, this.step, {circleThickness: 0.05, // 外圆的厚度与半径的百分比.circleFillGap: 0.05, // 外圆与波圆之间的间隙大小与外圆半径的百分比.circleColor: "#409EFF", // 外圆的颜色.waveHeight: 0.05, // 波高与波圆半径的百分比.waveCount: 2, // 每波圈宽度的全波数.waveRiseTime: 2000, // 波从0上升到最终高度所需的时间,以毫秒为单位.waveAnimateTime: 1000, //  一个完整的波进入波圈的时间(以毫秒为单位).waveColor: "#409EFF", // 填充波的颜色。displayPercent: "ms", // 如果为真,值后面会显示%符号。textColor: "#045681", // 当波浪不重叠值文本时的颜色。waveTextColor: "#fff", // 当波浪与值文本重叠时的颜色.});},methods: {loadLiquidFillGauge(element, value, config) {config = Object.assign({}, {minValue: 0, // 量规最小值.maxValue: 100, // 量规最大值.circleThickness: 0.05, // 外圆的厚度与半径的百分比.circleFillGap: 0.05, // 外圆与波圆之间的间隙大小与外圆半径的百分比.circleColor: "#178BCA", // 外圆的颜色.waveHeight: 0.05, // 波高与波圆半径的百分比.waveCount: 2, // 每波圈宽度的全波数.waveRiseTime: 1000, // 波从0上升到最终高度所需的时间,以毫秒为单位.waveAnimateTime: 18000, //  一个完整的波进入波圈的时间(以毫秒为单位).waveRise: true, // 控制波浪是否应该从0上升到它的全部高度,或从它的全部高度开始waveHeightScaling: true, // 控制波大小缩放在低和高填充百分比。当真值时,波高在50%填充时达到最大值,在0%和100%填充时达到最小值。这有助于防止波使波圈出现完全满或空时,接近它的最小或最大填充。waveAnimate: true, // 控制波形是滚动还是静态.waveColor: "#178BCA", // 填充波的颜色。waveOffset: 0, // 最初抵消波的量。0 = 无偏移。1 = 一个完整波的偏移量textVertPosition: .5, // 在波圈内显示百分比文本的高度。0 =下,1 =上.textSize: .8, // 要在波圈中显示的文本的相对高度。1 = 50%valueCountUp: true, // 如果为真,则显示的值从0计数到加载时的最终值。如果为false,则显示最终值。displayPercent: "%", // 后面会显示%符号。textColor: "#045681", // 当波浪不重叠值文本时的颜色。waveTextColor: "#A4DBf8" // 当波浪与值文本重叠时的颜色.}, config);var gauge = d3.select(element).append('svg').attr('width', '100%').attr('height', '100%');var radius = Math.min(parseInt(gauge.style("width")), parseInt(gauge.style("height"))) / 2;var locationX = parseInt(gauge.style("width")) / 2 - radius;var locationY = parseInt(gauge.style("height")) / 2 - radius;var fillPercent = Math.max(config.minValue, Math.min(config.maxValue, value)) / config.maxValue;var waveHeightScale;if (config.waveHeightScaling) {waveHeightScale = d3.scaleLinear().range([0, config.waveHeight, 0]).domain([0, 50, 100]);} else {waveHeightScale = d3.scaleLinear().range([config.waveHeight, config.waveHeight]).domain([0, 100]);}var textPixels = (config.textSize * radius / 3);var textFinalValue = parseFloat(value).toFixed(2);var textStartValue = config.valueCountUp ? config.minValue : textFinalValue;var percentText = config.displayPercent;var circleThickness = config.circleThickness * radius;var circleFillGap = config.circleFillGap * radius;var fillCircleMargin = circleThickness + circleFillGap;var fillCircleRadius = radius - fillCircleMargin;var waveHeight = fillCircleRadius * waveHeightScale(fillPercent * 100);var waveLength = fillCircleRadius * 2 / config.waveCount;var waveClipCount = 1 + config.waveCount;var waveClipWidth = waveLength * waveClipCount;// 四舍五入函数,以便在数值累计时始终显示正确的小数点后位数。var textRounder = (value) => Math.round(value);if (parseFloat(textFinalValue) != parseFloat(textRounder(textFinalValue))) {textRounder = (value) => parseFloat(value).toFixed(1);}if (parseFloat(textFinalValue) != parseFloat(textRounder(textFinalValue))) {textRounder = (value) => parseFloat(value).toFixed(2);}// 建立clip wave区域的数据。var data = Array.from({ length: 41 * waveClipCount }, (_, i) => ({ x: i / (40 * waveClipCount), y: (i / (40)) }));// 绘制外圆的比例。var gaugeCircleX = d3.scaleLinear().range([0, 2 * Math.PI]).domain([0, 1]);var gaugeCircleY = d3.scaleLinear().range([0, radius]).domain([0, radius]);// 用于控制剪切路径大小的尺度。var waveScaleX = d3.scaleLinear().range([0, waveClipWidth]).domain([0, 1]);var waveScaleY = d3.scaleLinear().range([0, waveHeight]).domain([0, 1]);// 用于控制裁剪路径位置的刻度。var waveRiseScale = d3.scaleLinear()// 剪辑区域的大小是填充圆的高度+波的高度,所以我们定位剪辑波这样,它将重叠填充圆在所有0%时,并将完全覆盖填充圆在100%。.range([(fillCircleMargin + fillCircleRadius * 2 + waveHeight), (fillCircleMargin - waveHeight)]).domain([0, 1]);var waveAnimateScale = d3.scaleLinear().range([0, waveClipWidth - fillCircleRadius * 2]) // 将夹子区域推一个完整的波,然后弹回来。.domain([0, 1]);// 用于控制文本在量规内的位置的刻度。var textRiseScaleY = d3.scaleLinear().range([fillCircleMargin + fillCircleRadius * 2, (fillCircleMargin + textPixels * 0.7)]).domain([0, 1]);// 在父SVG中居中测量。var gaugeGroup = gauge.append("g").attr('transform', `translate(${locationX},${locationY})`);// 画一个外圆。var gaugeCircleArc = d3.arc()({startAngle: gaugeCircleX(0),endAngle: gaugeCircleX(1),outerRadius: gaugeCircleY(radius),innerRadius: gaugeCircleY(radius - circleThickness),})gaugeGroup.append("path").attr("d", gaugeCircleArc).style("fill", config.circleColor).attr('transform', `translate(${radius},${radius})`);// 波不重叠的文本。var text1 = gaugeGroup.append("text").text(textRounder(textStartValue) + percentText).attr("class", "liquidFillGaugeText").attr("text-anchor", "middle").attr("font-size", textPixels + "px").style("fill", config.textColor).attr('transform', `translate(${radius},${textRiseScaleY(config.textVertPosition)})`);// 剪切波面积。var clipArea = d3.area().x(d => waveScaleX(d.x)).y0(d => waveScaleY(Math.sin(Math.PI * 2 * config.waveOffset * -1 + Math.PI * 2 * (1 - config.waveCount) + d.y * 2 * Math.PI))).y1(d => (fillCircleRadius * 2 + waveHeight));var waveGroup = gaugeGroup.append("defs").append("clipPath").attr("id", "clipWave" + 'svg');var wave = waveGroup.append("path").datum(data).attr("d", clipArea).attr("T", 0);// 带有剪切波的内圆。var fillCircleGroup = gaugeGroup.append("g").attr("clip-path", "url(#clipWave" + 'svg' + ")");fillCircleGroup.append("circle").attr("cx", radius).attr("cy", radius).attr("r", fillCircleRadius).style("fill", config.waveColor);// 波重叠的文本。var text2 = fillCircleGroup.append("text").text(textRounder(textStartValue) + percentText).attr("class", "liquidFillGaugeText").attr("text-anchor", "middle").attr("font-size", textPixels + "px").style("fill", config.waveTextColor).attr('transform', `translate(${radius},${textRiseScaleY(config.textVertPosition)})`);// 把数值加起来。if (config.valueCountUp) {var textTween = function () {var i = d3.interpolate(this.textContent, textFinalValue);return function (t) {this.textContent = textRounder(i(t)) + percentText;}};text1.transition().duration(config.waveRiseTime).tween("text", textTween);text2.transition().duration(config.waveRiseTime).tween("text", textTween);}// 让波浪上升。波和波组是分开的,水平和垂直运动可以独立控制。var waveGroupXPosition = fillCircleMargin + fillCircleRadius * 2 - waveClipWidth;if (config.waveRise) {waveGroup.attr('transform', `translate(${waveGroupXPosition},${waveRiseScale(0)})`).transition().duration(config.waveRiseTime).ease(d3.easeLinear).attr('transform', `translate(${waveGroupXPosition},${waveRiseScale(fillPercent)})`).on("start", function () {// 当wave Rise = true和 wave Animate=false时,这个变换是必要的,以使剪辑波正确定位。如果没有这个,波将无法正确定位,但我们不清楚为什么这是必要的.wave.attr('transform', 'translate(1,0)');});} else {waveGroup.attr('transform', `translate(${waveGroupXPosition},${waveRiseScale(fillPercent)}`);}if (config.waveAnimate) animateWave();function animateWave() {wave.attr('transform', `translate(${waveAnimateScale(wave.attr('T'))},0)`);wave.transition().duration(config.waveAnimateTime * (1 - wave.attr('T'))).ease(d3.easeLinear).attr("transform", `translate(${waveAnimateScale(1)},0)`).attr('T', 1).on('end', function () {wave.attr('T', 0);animateWave();});}function GaugeUpdater() {this.update = function (value) {var newFinalValue = parseFloat(value).toFixed(2);var textRounderUpdater = (value) => Math.round(value);if (parseFloat(newFinalValue) != parseFloat(textRounderUpdater(newFinalValue))) {textRounderUpdater = (value) => parseFloat(value).toFixed(1);}if (parseFloat(newFinalValue) != parseFloat(textRounderUpdater(newFinalValue))) {textRounderUpdater = (value) => parseFloat(value).toFixed(2);}var textTween = function () {var interpolate = d3.interpolate(this.textContent, parseFloat(value).toFixed(2));return function (t) {this.textContent = textRounderUpdater(interpolate(t)) + percentText;}};text1.transition().duration(config.waveRiseTime).tween("text", textTween);text2.transition().duration(config.waveRiseTime).tween("text", textTween);var _max = Math.max(config.minValue, Math.min(config.maxValue, value));var fillPercent = (value <= config.maxValue ? _max : 85) / config.maxValue;var waveHeight = fillCircleRadius * waveHeightScale(fillPercent * 100);var waveRiseScale = d3.scaleLinear()// 剪辑区域的大小是填充圆的高度+波的高度,所以我们定位剪辑波这样,它将重叠填充圆在所有0%时,并将完全覆盖填充圆在100%..range([(fillCircleMargin + fillCircleRadius * 2 + waveHeight), (fillCircleMargin - waveHeight)]).domain([0, 1]);var newHeight = waveRiseScale(fillPercent);var waveScaleX = d3.scaleLinear().range([0, waveClipWidth]).domain([0, 1]);var waveScaleY = d3.scaleLinear().range([0, waveHeight]).domain([0, 1]);var newClipArea;if (config.waveHeightScaling) {newClipArea = d3.area().x(d => waveScaleX(d.x)).y0(d => waveScaleY(Math.sin(Math.PI * 2 * config.waveOffset * -1 + Math.PI * 2 * (1 - config.waveCount) + d.y * 2 * Math.PI))).y1(d => (fillCircleRadius * 2 + waveHeight));} else {newClipArea = clipArea;}var newWavePosition = config.waveAnimate ? waveAnimateScale(1) : 0;wave.transition().duration(0).transition().duration(config.waveAnimate ? (config.waveAnimateTime * (1 - wave.attr('T'))) : (config.waveRiseTime)).ease(d3.easeCircle).attr('d', newClipArea).attr('transform', `translate(${newWavePosition},0)`).attr('T', '1').on("end", function () {if (config.waveAnimate) {wave.attr('transform', `translate(${waveAnimateScale(0)},0)`)animateWave();}});waveGroup.transition().duration(config.waveRiseTime).attr('transform', `translate(${waveGroupXPosition},${newHeight})`)}}return new GaugeUpdater();},update(val) {this.instance.update(val);}}//  End
}</script>// 使用该组件
<load-liquid-fill-gauge ref="gauge" step="80" />

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/352424.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

echarts 画动态水球

前言 在对一些需要存放液体的工厂进行开发基于物联网传感器的监控平台时&#xff0c;经常需要监控 该蓄水池当前所处的容量占比为多少。 以达到随时调整其蓄水量的目的。接下来我们看 一下一些常见的水球项目。 有这样的&#xff1a; 这样的&#xff1a; 甚至还有这样的&…

ECHARTS 水球图

转载编辑。 原作者链接地址&#xff1a;https://zhuanlan.zhihu.com/p/25353670?group_id827655855632715776 水球图是一种适合于展现单个百分比数据的图表类型&#xff0c;ECharts 的水球图插件使你能够通过非常简单的配置&#xff0c;实现酷炫的数据展示效果。 第一步&…

echarts 水球图

// ECharts 水球图插件&#xff0c;需要额外插件脚本&#xff0c;参见上方“脚本” // 完整配置参数参见&#xff1a;https://github.com/ecomfe/echarts-liquidfillvar option {series: [{type: liquidFill,data: [0.6, 0.5, 0.4, 0.3],radius: 40%,shape: diamond,center: […

从0到1:如何建立一个大规模多语言代码生成预训练模型

国产AI辅助编程工具CodeGeeX是一个使用AI大模型为基座的辅助编程工具&#xff0c;帮助开发人员更快的编写代码。可以自动完成整个函数的编写&#xff0c;只需要根据注释或Tab按键即可。它已经在Java、JavaScript和Python等二十多种语言上进行了训练&#xff0c;并基于大量公开的…

【Python】打包与发布(Packaging and distributing projects)

以Unix/macOS系统为例。 前提准备&#xff1a;确保pip为最新版本&#xff0c;可使用以下命令来更新pip&#xff1a; python3 -m pip install --upgrade pip一、创建一个简单的项目 我们在目录packaging_tutorial下进行操作。 项目名称为&#xff1a;example_package_wayne。 …

2023国际管理会计教育联盟发展论坛在沪成功召开

2023年5月7日&#xff0c;由教育部中外人文交流中心、国际管理会计教育联盟&#xff08;下称“联盟”&#xff09;主办&#xff0c;中国商业会计学会、上海交通大学安泰经济与管理学院承办的2023国际管理会计教育联盟发展论坛&#xff08;下称“发展论坛”&#xff09;在上海成…

系统架构师之高内聚低耦合

一、概念&#xff1a; 标记耦合&#xff08;Stamp Coupling&#xff09;和数据耦合&#xff08;Data Coupling&#xff09;是软件设计中两种不同的耦合类型&#xff0c;它们之间的区别如下&#xff1a; 标记耦合&#xff1a;标记耦合是指模块之间通过参数传递标记或标识符来进…

怎样把m4a转换成mp3格式?

怎样把m4a转换成mp3格式&#xff1f;大家都知道m4a音频格式兼容性差&#xff0c;这已成为许多小伙伴头疼的问题&#xff0c;因为很多人不会m4a转mp3的方法&#xff0c;从而导致m4a音频无法正常播放。在过去&#xff0c;想把m4a转换成mp3格式确实有一定的难度&#xff0c;但是如…

m4a怎么转换成mp3格式?

最近总有伙伴问我&#xff1a;“小编&#xff0c;m4a怎么转换成mp3格式&#xff1f;有没有什么简单有效的方法”。其实要想把m4a转换成mp3格式&#xff0c;转换工具就是钥匙&#xff0c;有了这把钥匙你就能更快地打开m4a转mp3格式的大门了。所以&#xff0c;选择好转换工具&…

如何快速的把m4a转换成mp3格式

无论是把m4a转换成mp3格式&#xff0c;还是把其他别的格式转换成mp3格式&#xff0c;一直都是有搜索热度的问题。虽然近两年把m4a转换成MP3的解决方法有很多&#xff0c;但是依旧满足不了小伙伴们寻找转换方法的现状。最主要的原因不是大家找不到转换成MP3的方法&#xff0c;而…

怎样把m4a转换mp3格式?

怎样把m4a转换mp3格式&#xff1f;m4a是苹果手机上的录音文件格式&#xff0c;随着苹果手机的广泛普及&#xff0c;m4a音频文件使用也越来越多&#xff0c;有的小伙伴将m4a音频文件转载到电脑上后&#xff0c;会因为兼容性的问题导致m4a文件不能打开播放。由于m4a是苹果公司开发…

m4r是什么文件格式?m4r怎么转成mp3?

你知道m4r是什么文件格式吗&#xff1f;如果你不知道是正常的&#xff0c;因为它真的太少见了&#xff0c;其实m4r是iPhone铃声的一种音频格式&#xff0c;简单的说m4就是音质音频文件的格式&#xff0c;并且实在iPhone手机上使用。如果你是安卓手机&#xff0c;是不能打开这种…

如何将录音m4a转换为mp3格式?

如何将录音m4a转换为mp3格式&#xff1f;前段时间由于工作原因&#xff0c;需要上传录音文件到一个网站上&#xff0c;可是这个录音文件怎么也上传不上去&#xff0c;查看原因后才发现原来网站只支持mp4的音频文件&#xff0c;而我是用苹果手机录音的&#xff0c;录音文件是m4a…

m4a怎么转换mp3格式?详细的步骤

有经常下载歌曲的小伙伴们&#xff0c;一定遇到过m4a格式的音频文件&#xff0c;这种格式的音频文件因为自身适配性的原因&#xff0c;导致很多播放器是无法对其进行正常播放&#xff0c;所以用户要想使用此格式的视频&#xff0c;就不得不把它转成主流格式mp3&#xff0c;这样…

m4a音频转换mp3格式的方法

很多朋友都在问m4a音频转换mp3格式的方法这个问题&#xff0c;小编根据大家的实际要求和诉求在网上寻找了很多的m4a转换成mp3的方法&#xff0c;这些方法都可以将m4a转换成mp3&#xff0c;但是在速度和稳定性方面有所差异。尤其是在使用的软件方面&#xff0c;每个软件中所具备…

m4a格式怎么转换成mp3,非常简单

m4a格式怎么转换成mp3&#xff1f;m4a是一种文件的扩展名&#xff0c;确切的说是一种音频文件格式。 为了区分mpeg-4中的音频和视频文件&#xff0c;苹果率先使用m4a格式替换了mpeg-4中的音频文件扩展名。 因为m4a主要应用于苹果手机&#xff0c;苹果手机的用户量很大&#xff…

如何把m4a转换成mp3?音频格式转换步骤

最近有好多朋友反映自己手机录音机里文件是m4a格式的&#xff0c;那这样m4a格式的音频在音响&#xff0c;播放器或者很多别的软件中都是无法进行播放的&#xff0c;而且m4a格式的音频在传输中还会受到一定的限制&#xff0c;这个时候我们就需要把m4a转换成常用的Mp3音频格式来完…

m4r转mp3格式用什么音频转换器好

经常玩弄铃声制作的童鞋也许比较清楚m4r是什么格式&#xff0c;m4r是iphone铃声的一种音频格式&#xff0c;在国内的一些iPhone铃声资源站或者是苹果iTunes上都是有得下载&#xff0c;不过对于安卓或者非ios系统的手机来说&#xff0c;它们并不支持m4r格式音频&#xff0c;这个…

如何将mp4视频转换成m4r音频

把mp4转换成m4r格式&#xff0c;很明显&#xff0c;mp4是视频格式&#xff0c;m4r是音频格式&#xff0c;视频转音频&#xff01;还可以说成是提取视频中的音频或声音&#xff0c;其实这种需求在用户当中还是有一些的&#xff0c;比如需要提取某部电脑里面某段声音&#xff0c;…

m4s格式转换mp3_高质量音频转换器,如何转换成mp3音频格式

日常生活中&#xff0c;听歌的朋友们肯定少不了在某系歌曲平台下载歌曲&#xff0c;不同的音质或者不同的平台都有自己特有的格式&#xff0c;有时我们想要在出门的时候在手机播放或者开车的时候在车载设备播放歌曲&#xff0c;那么有些播放器会对格式有有求&#xff0c;一般MP…