簡體   English   中英

自定義Google Material條形圖

[英]Customizing Google Material bar Chart

我必須制作一張如圖所示的圖表,它看起來幾乎類似於Google的Material條形圖,但需要進行一些修改。 到目前為止,我還沒有找到一種方法來修改懸停時的顏色,刻度號或線數以及圖表區域的寬度。 有人能幫我嗎 ?

 google.charts.load('current', {'packages':['corechart','bar']}); google.charts.setOnLoadCallback(barChart); function barChart() { var data = new google.visualization.arrayToDataTable([ ['Opening Move', 'Percentage', { role: 'style' }], ["King's pawn (e4)", 44, ' ' ], ["Queen's pawn (d4)", 31, ''], ["Knight to King 3 (Nf3)", 12,''], ["Queen's bishop pawn (c4)", 10,''], ['Other', 3, ''] ]); var options = { width: 520, height: 320, legend: { position: 'none' }, bars: 'horizontal', axes: { x: { 0: { side: 'top', label: 'Percentage', } } }, hAxis: { ticks: [10,20,30] }, bar: { groupWidth: "90%" }, // chartArea: { // width: '78%', // left: '22%' // }, colors:['#c6dbfd','#c6dbfd','#c6dbfd','#c6dbfd','#c6dbfd','#c6dbfd'] }; var chart = new google.charts.Bar(document.getElementById('bar-chart')); chart.draw(data, options); } 
 <script src="https://www.gstatic.com/charts/loader.js"></script> <div id="bar-chart"></div> 

圖表設計

您正在使用“材料條形圖”,目前它具有非常有限的一組功能(如此此處所示 )。

這解釋了為什么報價和圖表區域不起作用。 我創建了一個帶有非材料版本的小提琴: https : //jsfiddle.net/5Lnbbbbw/1/

它是相似的,但是使用:

var chart = new google.visualization.BarChart(document.getElementById('bar-chart'));

代替

var chart = new google.charts.Bar(document.getElementById('bar-chart'));

現在進行懸停:這很困難,因為沒有選項可以管理它。 實際上,您在鼠標懸停和點擊時所看到的就是添加到圖表中的新元素。 它不是通過CSS管理的。

但是,您可以這樣做:

#bar-chart svg g[clip-path] g:not(:first-child) rect:hover {
    fill: blue;
    stroke: black;
    stroke-width: 1;
}

圖表區域是具有clip-path屬性的svg元素g 第一個子項將所有刻度線(垂直線)分組,因此我們不想為其添加css屬性。

請注意,如果刪除刻度線,則可能必須稍微更新css。

如果您想了解更多關於bar的css選項的信息,可以在這里找到更多信息。

我發現此Codepen使用jQuery在圖表上的條形圖中添加了一定百分比。 也許會有所幫助嗎?

http://codepen.io/sharkers/pen/qmrjVe

$(document).ready(function() {
startProdChart(); });

function startProdChart() {
    google.charts.load("current", { packages: ["bar"] });
    google.charts.setOnLoadCallback(drawProdChart);
}

function drawProdChart() {
    //create the main array that we need to fill up
    var prodChart = [];

//create the initial header array and populate with values
var header = ["Month", "Finance Reserve"]; //the static pieces
var prodDiv = $('.the-record[data-type="totals"][data-record="store totals"] .product-labels');
prodDiv.each(function() {
    var prodName = $(this).find(".header-labels .record-label").text();
    header.push(prodName);
});

//push header info into array
prodChart.push(header);

//collect data from each monthly record
var chartData = $('.the-record[data-record="store totals"][data-type="totals"] .record-column span[data-label="income"]');
chartData.each(function() {
    var tempProd = [];
    var chartDate = $(this).parent().data("date"),
        chartXLabels = $(this)
            .closest(".vehicle-labels")
            .find('.header-labels .record-label[data-date="' + chartDate + '"]')
            .text(),
        chartDataTotalIncome = parseInt($(this).text().replace(/\$|,/g, "")),
        chartFinanceTotal = parseInt(
            $(this)
                .closest(".record-holder")
                .find(
                    '.finance-labels .record-column[data-date="' +
                        chartDate +
                        '"] span[data-label="financeamt"]'
                )
                .text()
                .replace(/\$|,/g, "")
        ),
        chartFinancePerc = chartFinanceTotal / chartDataTotalIncome,
        chartProducts = $(this)
            .closest(".record-holder")
            .find(
                '.product-labels .record-column[data-date="' + chartDate + '"] span.amt'
            );

    //if untitled, label 'Averages'
    if (chartXLabels == "") {
        chartXLabels = "Average";
    }

    //push labels and finance numbers in array
    tempProd.push(chartXLabels);
    tempProd.push(chartFinanceTotal);

    //push product totals into array one by one
    chartProducts.each(function() {
        var chartProductsTotal = parseInt($(this).text().replace(/\$|,/g, "")),
            chartProductsPerc =
                parseInt($(this).text().replace(/\$|,/g, "")) / chartDataTotalIncome;
        tempProd.push(chartProductsTotal);
    });

    prodChart.push(tempProd);
});

var data = google.visualization.arrayToDataTable(prodChart);

//set chart options
var options = {
    chart: {
        title: "Total Income Percentage",
        subtitle: "Products and Finance Reserve"
    },
    bars: "vertical",
    vAxis: {
        format: "$#,###",
        textPosition: "inside"
    },
    height: 700,
    series: {
        0: {
            color: "#3eb42f"
        },
        1: {
            color: "#2264ae"
        }
    },
    isStacked: "true"
};

var chart = new google.charts.Bar(
    document.getElementById("monthly-income-chart")
);

chart.draw(data, google.charts.Bar.convertOptions(options));
google.visualization.events.addListener(chart, "ready", drawMoInc); //run the addPercs function after chart ready

function drawMoInc() {
    addPercs("monthly-income-chart");
}

}

//請修改此代碼

//this is a function that will add percentages within the sections of a stacked bar chart
function addPercs(chartId) {
//google material charts have two elements that make up one bar, potentially several 'rect' elements and one 'path', so we use paths to get the number of bars
var thisChart = $("#" + chartId),
    gLast = thisChart.find("svg g:last"), //the last g is where the tooltip shows up, need to insert our new text BEFORE this element
    barPath = thisChart.find("svg g:eq(2) path"), //the third g element is where the paths reside
    pathAmt = barPath.length, //the number of paths will tell us how many bars we have in the chart
    barRect = thisChart.find("svg g:eq(2) rect"), //the third g element is where the rects reside
    rectAmt = barRect.length,
    rectGroup = rectAmt / pathAmt, //find out how many rect sections are in one bar
    rectSelect = 0;

console.log(thisChart.attr("id"));

//create an empty 'g' element, append to the 'svg' element, give it a class, shift it up one so it's second to last
var newTextSvg = document.createElementNS("http://www.w3.org/2000/svg", "g");

thisChart.find("svg").append(newTextSvg);
newTextSvg.setAttribute("class", "newtext");
thisChart.find(".newtext").insertBefore(gLast);

//get the parts of the bar and create percentages
barPath.each(function() {
    var totalRectHeight = 0,
        thisGroup = rectSelect * rectGroup,
        thisSet = rectSelect * rectGroup;

    //get total height of all rects in a single bar
    for (i = 0; i < rectGroup; i++) {
        var thisRectHeight = barRect[thisGroup].getBBox().height;

        totalRectHeight = thisRectHeight + totalRectHeight;
        thisGroup++;
    }

    //get path info
    var pathHeight = barPath[rectSelect].getBBox().height,
        pathWidth = barPath[rectSelect].getBBox().width,
        pathPosX = barPath[rectSelect].getBBox().x,
        pathPosY = barPath[rectSelect].getBBox().y;

    //do some math real quick like
    var totalHeight = pathHeight + totalRectHeight,
        pathPerc = Math.round(pathHeight / totalHeight * 100);

    //get all the rect info within the bar
    for (i = 0; i < rectGroup; i++) {
        var rectHeight = barRect[thisSet].getBBox().height,
            rectWidth = barRect[thisSet].getBBox().width,
            rectPosX = barRect[thisSet].getBBox().x,
            rectPosY = barRect[thisSet].getBBox().y,
            rectPerc = Math.round(rectHeight / totalHeight * 100),
            rectText = document.createTextNode(rectPerc + "%");

        //create new svg text elements for the rect parts of the chart
        if (rectHeight !== 0) {
            var newRectText = document.createElementNS(
                "http://www.w3.org/2000/svg",
                "text"
            );
            newRectText.appendChild(rectText);
            newTextSvg.appendChild(newRectText);
            newRectText.setAttribute("x", rectPosX);
            newRectText.setAttribute("y", rectPosY);
            newRectText.setAttribute(
                "style",
                "cursor: default; user-select: none; -webkit-font-smoothing: antialiased;"
            );
            newRectText.setAttribute("fill", "#ffffff");
            var rectTextWidth = newRectText.getBBox().width,
                rectTextHeight = newRectText.getBBox().height,
                rectOffsetX = rectWidth / 2 - rectTextWidth / 2,
                rectOffsetY = 24;
            if (rectTextHeight + rectOffsetY * 2 >= rectHeight) {
                rectOffsetY = rectHeight / 2 + rectTextHeight / 3.5;
            }

            newRectText.setAttribute("dx", rectOffsetX);
            newRectText.setAttribute("dy", rectOffsetY);
        }
        thisSet++;
    }

    //path vars
    var pathText = document.createTextNode(pathPerc + "%");

    //create a new svg text element for the path parts of the chart
    var newPathText = document.createElementNS(
        "http://www.w3.org/2000/svg",
        "text"
    );
    newPathText.appendChild(pathText);
    newTextSvg.appendChild(newPathText);
    newPathText.setAttribute("x", pathPosX);
    newPathText.setAttribute("y", pathPosY);
    newPathText.setAttribute(
        "style",
        "cursor: default; user-select: none; -webkit-font-smoothing: antialiased;"
    );
    newPathText.setAttribute("fill", "#ffffff");

    //get numbers to set the text position
    var pathTextWidth = newPathText.getBBox().width,
        pathTextHeight = newPathText.getBBox().height,
        pathOffsetX = pathWidth / 2 - pathTextWidth / 2,
        pathOffsetY = 24;
    if (pathTextHeight + pathOffsetY * 2 >= pathHeight) {
        pathOffsetY = pathHeight / 2 + pathTextHeight / 3.5;
    }

    newPathText.setAttribute("dx", pathOffsetX);
    newPathText.setAttribute("dy", pathOffsetY);

    rectSelect++; //go up one
});

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM