繁体   English   中英

D3JS interpolateSpectral

[英]D3JS interpolateSpectral

我不确定我是否了解如何使用 D3 的 interpolateSpectral 来获得我的配色方案。 当我尝试以下我的颜色工作时,问题是我不知道我可能需要多少潜在的颜色,所以我想使用 interpolateSpectral 来获得我的数据集要求的尽可能多的颜色。

当我这样做时

 const color = d3.scaleOrdinal(d3.schemeCategory10);

 g.selectAll('.chart-arc')
                    .data(pie(data))
                    .enter()
                    .append('path')
                    .attr('class', 'chart-arc')
                    .attr('d', arc)
                    .style('fill', d => console.log(color(d.data.label)))
                    .on('mouseover', this.mouseover.bind(this))
                    .on('mousemove', this.mousemove.bind(this))
                    .on('mouseout', this.mouseout.bind(this))
                ;

这些颜色在我可以看到它们记录到我的控制台时起作用。

当我这样做时...

const color = d3.scaleSequential(d3.interpolateSpectral);
     g.selectAll('.chart-arc')
                        .data(pie(data))
                        .enter()
                        .append('path')
                        .attr('class', 'chart-arc')
                        .attr('d', arc)
                        .style('fill', d => console.log(color(d.data.label)))
                        .on('mouseover', this.mouseover.bind(this))
                        .on('mousemove', this.mousemove.bind(this))
                        .on('mouseout', this.mouseout.bind(this))
                    ;

控制台将所有颜色实例记录为未定义。

更新

这是 vue.js/d3js 页面的完整代码。

<template>
    <div>
        <div v-if="!loading" id="chart"></div>
        <div v-if="loading">Loading...</div>
    </div>
</template>

<script>
    import * as d3 from 'd3';
    import axios from "axios";

    export default {
        name: "piechart2",
        data(){
            this.loadData()
                .then((theData) => (
                    this.data = theData,
                        this.createChart
                ))
                .finally(() => (
                    this.loading = false,
                    this.loadChart()
                    ));
            return{
              data: "",
              element: 'body',
              width: 600,
              height: 400,
              loading: true
          }
        },
        methods: {
            loadData: function(){
                return axios.get('http://localhost:8080/mockdata/piemock.json')
                    .then(result => { return result; })
                    .catch(error => { console.error(error); throw error; });
            },
            loadChart: function () {
                let newData = this.data.data.map(
                    obj => {
                        return {
                            value: obj.count,
                            label : obj.label

                        }
                    }
                );
                let newJson = {data: newData, width: this.width, height: this.height, element: this.element}

                var {data, width, height, element} = newJson;

                const svg = d3.select(element)
                    .append('svg')
                    .attr('class', 'chart-svg')
                    .attr('width', width)
                    .attr('height', height)
                ;

                this.tooltip = d3.select(element)
                    .append('div')
                    .attr('class', 'tooltip')
                    .style('display', 'none')
                ;

                // const color = d3.scaleOrdinal(d3.schemeCategory10)
                // ;
                //     console.log(color(1))

                console.log(data.length)

                const color = d3.scaleSequential(d3.interpolateSpectral).domain([0, data.length]);//d3.scaleSequential(d3.interpolateSpectral);

               // console.log(color2(1))

                const r = Math.min(width, height) / 3;
                const arc = d3.arc()
                    .innerRadius(0)
                    .outerRadius(r)
                ;

                const pie = d3.pie()
                    .value(d => d.value)
                ;

                const g = svg.append('g')
                    .attr('transform', `translate(${width / 2},${height / 2})`)
                ;

                g.selectAll('.chart-arc')
                    .data(pie(data))
                    .enter()
                    .append('path')
                    .attr('class', 'chart-arc')
                    .attr('d', arc)
                    .style('fill', d => console.log(color(d.data.label)))
                    .on('mouseover', this.mouseover.bind(this))
                    .on('mousemove', this.mousemove.bind(this))
                    .on('mouseout', this.mouseout.bind(this))
                ;

                const l = svg.append('g')
                    .attr('transform', `translate(0,${height - 20})`);


                const xl = d3.scaleBand()
                    .range([0, width])
                    .padding(0.3)
                    .domain(data.map(d => d.label))
                ;

                const legend = l.selectAll('.chart-legend')
                    .data(color.domain())
                    .enter()
                    .append('g')
                    .attr('class', 'chart-legend')
                    .attr('transform', (d) => `translate(${xl(d)},0)`)
                ;

                legend.append('rect')
                    .attr('width', 12)
                    .attr('height', 12)
                    .style('fill', color)
                ;

                legend.append('text')
                    .attr('x', 20)
                    .attr('y', 10)
                    .text(d => d)
                ;
            },

            mouseover() {
                this.tooltip
                    .style('display', 'inline-block')
                    .style('position', 'absolute')
                ;
            },

            mousemove() {
                this.tooltip
                    .text([d3.event.pageX, d3.event.pageY].join(','))
                    .style('left', d3.event.pageX + 10 + "px")
                    .style('top', d3.event.pageY + 10 + "px")
                ;
            },

            mouseout() {
                this.tooltip
                    .style('display', 'none')
                ;
            },

            render() {
                // move rendering logic down here
            }
        }
    }
</script>

<style>
    .tooltip {
        background-color: rgba(0,0,0,0.75);
        padding: 15px;
        border-radius: 2px;
        font-family: sans-serif;
        color: white;
        pointer-events: none;
        box-shadow: 0 0 5px #999999;
    }

    .chart-svg {
        border: 1px solid #ddd;
    }

    .chart-legend {
        font-family: 'Open Sans', sans-serif;
    }
</style>

这是JSON

[{"label": "Assamese", "count": 13},
  {"label": "Bengali", "count": 83},
  {"label": "Bodo", "count": 1.4},
  {"label": "Dogri", "count": 2.3},
  {"label": "Gujarati", "count": 46},
  {"label": "Hindi", "count": 300},
  {"label": "Kannada", "count": 38},
  {"label": "Kashmiri", "count": 5.5},
  {"label": "Konkani", "count": 5},
  {"label": "Maithili", "count": 20},
  {"label": "Malayalam", "count": 33},
  {"label": "Manipuri", "count": 1.5},
  {"label": "Marathi", "count": 73},
  {"label": "Nepali", "count": 2.9},
  {"label": "Oriya", "count": 33},
  {"label": "Punjabi", "count": 29},
  {"label": "Sanskrit", "count": 0.01},
  {"label": "Santhali", "count": 6.5},
  {"label": "Sindhi", "count": 2.5},
  {"label": "Tamil", "count": 61},
  {"label": "Telugu", "count": 74},
  {"label": "Urdu", "count": 52}]

顺序尺度确实采用两个数值作为输入域( )。

这意味着输入应该是一个数字,并输出一个颜色。

似乎在问题中,尝试使用文本标签作为输入,这导致了问题。

不建议使用顺序色标来映射不相关的值:色标表示值之间的“接近”,并将用于不一定连接/相似的标签。

如果来自d3-scale- schemeSet3的 12 种颜色分类比例schemeSet3不够,可以使用iWantHue 之类的工具生成比例优化具有可区分颜色的机会

如果决定继续使用d3.interpolateSpectral的切片颜色的方法,那么这个 notebook可以作为参考。 它说明了如何使用d3-scale-chromatic方案来映射离散值(将选择菜单切换到Discrete(n)而不是Continuous以查看正在运行的代码)。

方法是将每个标签映射到配色方案的一部分:

// assumption: an array called `labels` has been created, containing the unique label values

let n = labels.length
    , colorbyValue = {}

for (let i = 0; i < n; ++i) {
  colorbyValue[labels[i]] = d3.rgb(d3.interpolateSpectral(i / (n - 1))).hex();
}

// then use with colorByValue[d.data.label]

您缺少域,请尝试以下操作:

const color = d3.scaleSequential(d3.interpolateSpectral).domain([0, data.length]);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM