我正在尝试不同的图表样式 - 我想知道如何为不同的部分创建这些确切类型的图案纹理图表。
如果是像大/小点镶嵌这样不那么传统的图案,您如何开始创建其中一些特定图案。
或者如果有渐变而不是图案
在这种情况下,馅饼的边缘似乎有轻微的圆形,就好像它堆叠在彼此的顶部并覆盖得更多一样。 d3js 饼图,各个部分具有不同的模式
演示参考,左侧有图例 - 右侧有饼图/半饼图
https://codesandbox.io/p/sandbox/magical-wiles-forked-fvj79p
我当前的构建——普通馅饼
import React from 'react';
import * as d3 from 'd3';
import './PieChart1.scss';
class PieChart extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
this.state = {
data: [],
theme: this.props.theme ? this.props.theme : ['#bde0fe', '#2698f9', '#71bcfd', '#f1f8fe']
};
}
componentDidMount() {
var $this = this.myRef.current;
d3.select($this)
.selectAll('svg')
.remove();
const data = this.props.data;
const width = parseInt(this.props.width, 10),
height = parseInt(this.props.height, 10),
radius = parseInt(this.props.r, 10),
innerradius = parseInt(this.props.ir, 10);
var color = d3.scaleOrdinal().range(this.state.theme);
var arc = d3
.arc()
.outerRadius(radius)
.innerRadius(innerradius);
data.forEach(function(d) {
d.total = +d.value;
});
var pie = d3
.pie()
.sort(null)
.value(function(d) {
return d.total;
});
var svg = d3
.select($this)
.append('svg')
.attr('width', width)
.attr('height', height)
.append('g')
.attr('class', 'piechart')
.attr('transform', 'translate(' + width / 2 + ',' + height / 2 + ')');
var segments = svg.append('g').attr('class', 'segments');
var slices = segments
.selectAll('.arc')
.data(pie(data))
.enter()
.append('g')
.attr('class', 'arc');
slices
.append('path')
.attr('d', arc)
.attr('fill', function(d, i) {
return color(i);
})
.transition()
.attrTween('d', function(d) {
var i = d3.interpolate(d.startAngle+0.1, d.endAngle);
return function(t) {
d.endAngle = i(t);
return arc(d);
}
});
}
render() {
return <div ref={this.myRef} className="PieChart" />;
}
}
export default PieChart;
我在制作图案时见过这个示例 - 如何制作这 4 种图案类型 - 其中一个似乎只是渐变
<!DOCTYPE html>
<html>
<head>
<style>
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div id="hook"></div>
<script type="text/javascript">
// SVG injection:
var svg = d3.select("#hook").append("svg").attr("id", "d3svg")
.attr("width", 120)
.attr("height", 120);
//Pattern injection
var defs = svg.append("defs")
var pattern = defs.append("pattern")
.attr({ id:"hash4_4", width:"8", height:"8", patternUnits:"userSpaceOnUse", patternTransform:"rotate(-45)"})
.append("rect")
.attr({ width:"4", height:"8", transform:"translate(0,0)", fill:"#88AAEE" });
//Shape design
svg.append("g").attr("id","shape")
.append("circle")
.attr({cx:"60",cy:"60",r:"50", fill:"url(#hash4_4)" })
</script>
</body>
</html>
找到这个作为参考 - 但不确定如何在演示中制作这些确切的图案
<script src="https://unpkg.com/[email protected]/dist/d3.min.js"></script>
<script src="https://d3js.org/d3.v4.js"></script>
<svg id="pie" width="300" height="200"> </svg>
<svg id="legend">
<rect x="0" y="0" width="100" height="100"
style="stroke: #000000; fill: url(#pattern0);" />
<rect x="100" y="0" width="100" height="100"
style="stroke: #000000; fill: url(#pattern1);" />
<rect x="200" y="0" width="100" height="100"
style="stroke: #000000; fill: url(#pattern2);" />
</svg>
<script>
var data = [{ year: '2001', value:10 },
{ year: '2002', value:30 },
{ year: '2003', value:60 },
]
var svg = d3.select("svg#pie"),
width = svg.attr("width"),
height = svg.attr("height"),
radius = Math.min(width, height) / 2,
g = svg.append("g").attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var color = d3.scaleOrdinal(['#4daf4a','#377eb8','#ff7f00','#984ea3','#e41a1c']);
// Generate the pie
var pie = d3.pie().value(function(d) {
return d.value;})(data);
// Generate the patterns
var legend = d3.select("svg#legend"),
defs = legend.append("defs");
defs.selectAll("pattern")
.data(pie)
.enter()
.append("pattern")
.attr("id", (d, i) => "pattern" + i)
.attr("patternUnits", "userSpaceOnUse")
.attr("width", 20)
.attr("height", 20)
.attr("patternTransform", (d) => `rotate(${(d.startAngle + d.endAngle) * 90 / Math.PI})`)
.style("fill", (d, i) => color(i))
.append("rect")
.attr("x", 5)
.attr("y", 5)
.attr("width", 10)
.attr("height", 10)
// Generate the arcs
var arc = d3.arc()
.innerRadius(0)
.outerRadius(radius);
//Generate groups
var arcs = g.selectAll("arc")
.data(pie)
.enter()
.append("g")
.attr("class", "arc")
//Draw arc paths
arcs.append("path")
.attr("d", arc)
.attr('stroke', "black")
.attr('stroke-width', '1')
.attr("fill", function(d,i) { return "url(#pattern" + i +")"});
</script>
</script>
9 月 19 日 - 最新版本 - 具有一般模式 - 但不是我们需要的模式或在正确位置的图例。
https://codesandbox.io/p/sandbox/magical-wiles-forked-pmdgrs
import React from "react";
import * as d3 from "d3";
import "./PieChart1.scss";
class PieChart extends React.Component {
constructor(props) {
super(props);
this.myRef = React.createRef();
this.state = {
data: [],
theme: this.props.theme
? this.props.theme
: ["#bde0fe", "#2698f9", "#71bcfd", "#f1f8fe"],
};
}
componentDidMount() {
var $this = this.myRef.current;
d3.select($this).selectAll("svg").remove();
const data = this.props.data;
const width = parseInt(this.props.width, 10),
height = parseInt(this.props.height, 10),
radius = parseInt(this.props.r, 10),
innerradius = parseInt(this.props.ir, 10);
var color = d3.scaleOrdinal().range(this.state.theme);
var arc = d3.arc().outerRadius(radius).innerRadius(innerradius);
data.forEach(function (d) {
d.total = +d.value;
});
var pie = d3
.pie()
.sort(null)
.value(function (d) {
return d.total;
});
var svg = d3
.select($this)
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("class", "piechart")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
// Generate the patterns
var legend = d3.select("svg#legend"),
defs = legend.append("defs");
defs
.selectAll("pattern")
.data(pie(data))
.enter()
.append("pattern")
.attr("id", (d, i) => "pattern" + i)
.attr("patternUnits", "userSpaceOnUse")
.attr("width", 20)
.attr("height", 20)
.attr(
"patternTransform",
(d) => `rotate(${((d.startAngle + d.endAngle) * 90) / Math.PI})`
)
.style("fill", (d, i) => color(i))
.append("rect")
.attr("x", 5)
.attr("y", 5)
.attr("width", 10)
.attr("height", 10);
var segments = svg.append("g").attr("class", "segments");
var slices = segments
.selectAll(".arc")
.data(pie(data))
.enter()
.append("g")
.attr("class", "arc");
slices
.append("path")
.attr("d", arc)
//.attr("fill", function (d, i) {
// return color(i);
//})
.attr("stroke", "black")
.attr("stroke-width", "1")
.attr("fill", function (d, i) {
return "url(#pattern" + i + ")";
})
.transition()
.attrTween("d", function (d) {
var i = d3.interpolate(d.startAngle + 0.1, d.endAngle);
return function (t) {
d.endAngle = i(t);
return arc(d);
};
});
}
render() {
return (
<>
<svg id="legend">
<rect
x="0"
y="0"
width="100"
height="100"
style={{ stroke: "#000000", fill: "url(#pattern0)" }}
/>
<rect
x="100"
y="0"
width="100"
height="100"
style={{ stroke: "#000000", fill: "url(#pattern1)" }}
/>
<rect
x="200"
y="0"
width="100"
height="100"
style={{ stroke: "#000000", fill: "url(#pattern2)" }}
/>
</svg>
<div ref={this.myRef} className="PieChart" />
</>
);
}
}
export default PieChart;
可以从生成图案制作器开始
首先是基本模式
仅限圆圈
https://codepen.io/geoffgraham/pen/aWZdXP——只是标记
我们需要用 js 重新制作 svg
<svg width="100%" height="100%">
<!-- Create mask that we'll use to define a slight gradient -->
<mask maskUnits="userSpaceOnUse" id="fade">
<!-- Here's that slight gradient -->
<linearGradient id="gradient" x1="0" y1="0" x2="0" y2="100%">
<stop offset ="0" style="stop-color: #FFFFFF" />
<stop offset ="1" style="stop-color: #000000" />
</linearGradient>
<!-- The canvas for our mask -->
<rect fill="url(#gradient)" width="100%" height="100%" />
</mask>
<!-- Let's define the pattern -->
<!-- The width and height should be double the circle radius we plan to use -->
<pattern id="pattern-circles" x="0" y="0" width="40" height="40" patternUnits="userSpaceOnUse">
<!-- Now let's draw the circle -->
<!-- We're going to define the `fill` in the CSS for flexible use -->
<circle mask="url(#fade)" cx="20" cy="20" r="20" />
</pattern>
<!-- The canvas with our applied pattern -->
<rect x="0" y="0" width="100%" height="100%" fill="url(#pattern-circles)" />
</svg>
// create svg element:
var svg = d3.select("#circle").append("svg").attr("width", 200).attr("height", 200)
// Add the path using this helper function
svg.append('circle')
.attr('cx', 100)
.attr('cy', 100)
.attr('r', 50)
.attr('stroke', 'black')
.attr('fill', '#69a3b2');
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script>
<div id="circle"></div>
仅限正方形
https://codepen.io/geoffgraham/pen/KmgxxN——只是标记
// create svg element:
var svg = d3.select("#rect").append("svg").attr("width", 800).attr("height", 200)
// Add the path using this helper function
svg.append('rect')
.attr('x', 10)
.attr('y', 120)
.attr('width', 40)
.attr('height', 40)
.attr('stroke', 'black')
.attr('fill', '#69a3b2');
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.8.5/d3.min.js"></script>
<div id="rect"></div>
仅限蜂窝
https://codepen.io/geoffgraham/pen/oWLLvZ——只是标记
仅限立方体
https://codepen.io/geoffgraham/pen/YVWqxG——只是标记
摆动线
https://codepen.io/geoffgraham/pen/xdOVjG——只是标记
打点器